トップ  > web開発  > 位置情報  > 記事

No.2332 GoogleStaticMapsAPIを使ってPHPで携帯に、スクロール出来る地図を表示する。

Google Static Maps APIを使うと、
地図を画像として切り出せるので、携帯でも使えるのですが、
画像だけ表示されても、スクロール出来ないとあまり実用的ではありません。
そこで、よくある、← → ↑ ↓のリンクをつけて
スクロール出来るようにしてみました。

http://www.netflowers.co.jp/map_mobile.php?lat=34.819533&lng=137.732836

いい感じ!
これで、GoogleMapを使った、携帯用サービスを色々作れそうです。

仕組みは少しずつ緯度経度をずらして移動しているのですが、
ズームレベルによってずらす量が変わってくるので、結構複雑な計算が必要です。

誰かの役にたつかもしれないのでさらしてみます。
ソースコードは、

<?

//GOOGLE API KEY
define("GOOGLE_MAP_API_KEY","ABQIAAAA2kAO3WQCS6Ln-isUJSg-TRSHuy3caWQsgPOO9HzzRn2Ro8VLhRTj_0Q6dtr-c5iHTmFlbhcC1Jz4mw");

//マークを打つ位置
$lat = htmlspecialchars($_GET["lat"]);
$lng = htmlspecialchars($_GET["lng"]);

if($lat == ""){
  $lat = "34.819533";
}
if($lng == ""){
  $lng = "137.732836";
}

//地図の中心
$c_lat = htmlspecialchars($_GET["c_lat"]);
$c_lng = htmlspecialchars($_GET["c_lng"]);

if($c_lat == ""){
  $c_lat = $lat;
}
if($c_lng == ""){
  $c_lng = $lng;
}

//縮尺率
$z = htmlspecialchars($_GET["z"]);
if($z ==""){
  $z = 15;
}

//移動後の位置を計算
$top = adjust($c_lng,$c_lat,0,-100,$z);
$bottom = adjust($c_lng,$c_lat,0,100,$z);
$left = adjust($c_lng,$c_lat,-100,0,$z);
$right = adjust($c_lng,$c_lat,100,0,$z);

/*
  function adjust
 
  $x:中心の経度
  $y:中心の緯度
  $deltaX:ずらしたい距離(ピクセル単位)
  $deltaY:ずらしたい距離(ピクセル単位)
  $z:ズーム
 
  戻り値
  array("x"=>"移動後の経度","y"=>"移動後の緯度");
*/
function adjust($x,$y,$deltaX,$deltaY,$z){
  $offset=268435456;
  $radius=$offset / pi();
  $xy = array(  "x"=>((round(round($offset + $radius * $x * pi()/180)+($deltaX << (21-$z))) - $offset) / $radius) * 180 / pi(),
                "y"=>(pi() / 2 - 2 * atan(exp((round(round($offset - $radius * log((1 + sin($y * pi() / 180))/(1 - sin($y * pi() / 180))) / 2)+($deltaY << (21-$z))) - $offset) / $radius))) * 180 / pi()
              );
  return $xy;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=Shift_JIS">
<title>Google Map</title>
</head>
<body>
<center>
<br>
<img src="http://maps.google.com/staticmap?center=<?=$c_lat?>,<?=$c_lng?>&zoom=<?=$z?>&size=220x220&maptype=mobile&markers=<?=$lat?>,<?=$lng?>&key=<?=GOOGLE_MAP_API_KEY?>" />
<br />
<a href="map_mobile.php?lat=<?=$lat?>&lng=<?=$lng?>&c_lat=<?=$left["y"]?>&c_lng=<?=$left["x"]?>&z=<?=$z?>" accesskey="4">4:←</a>
<a href="map_mobile.php?lat=<?=$lat?>&lng=<?=$lng?>&c_lat=<?=$top["y"]?>&c_lng=<?=$top["x"]?>&z=<?=$z?>" accesskey="2">2:↑</a>
<a href="map_mobile.php?lat=<?=$lat?>&lng=<?=$lng?>&c_lat=<?=$bottom["y"]?>&c_lng=<?=$bottom["x"]?>&z=<?=$z?>" accesskey="8">8:↓</a>
<a href="map_mobile.php?lat=<?=$lat?>&lng=<?=$lng?>&c_lat=<?=$right["y"]?>&c_lng=<?=$right["x"]?>&z=<?=$z?>" accesskey="6">6:→</a>
<br />
<?if($z > 0){?>
<a href="map_mobile.php?lat=<?=$lat?>&lng=<?=$lng?>&c_lat=<?=$c_lat?>&c_lng=<?=$c_lng?>&z=<?=$z-1?>" accesskey="1">1:広域</a>
<?}?>
<?if($z < 18){?>
<a href="map_mobile.php?lat=<?=$lat?>&lng=<?=$lng?>&c_lat=<?=$c_lat?>&c_lng=<?=$c_lng?>&z=<?=$z+1?>" accesskey="3">3:詳細</a>
<?}?>
</center>
</body>
</html>


元ネタは、http://www.polyarc.us/adjust.js
をPHP用に書き換えました。



地図移動させる場合の緯度経度計算についてAdd Star

| 11:48 | 地図移動させる場合の緯度経度計算について - American Life in the Summertime を含むブックマーク はてなブックマーク - 地図移動させる場合の緯度経度計算について - American Life in the Summertime

まさに文系SE/PGの弱点がまざまざと…

Google Static Maps API(v1/V2)を使う際、やはりGoogle Maps APIのように地図がスクロールできないのがネックとなる。

そこで、移動後の緯度経度を計算して、リンクを作ることになるのだが…



サンプルに…というか、参考になりそうなところをあれこれ探してみた。

Google Static Maps APIを使ってPHPで携帯に、スクロール出来る地図を表示する。 ネットに花を咲かせましょう。 会社作りました。

ここにあるのはhttp://www.polyarc.us/adjust.js*1PHPに置き換えたもの。

$offset=268435456;

これって意味不明と思ったら、Google Maps関連の英語のblogでも同じような数字を使ってた。

2の28乗だっけ?

Chief Technical Officer - Google Static Mapsの画像サイズと経度・緯度

ここにはこんな式が出てくる。

[東へ移動したときの中心経度]=

  (180 + [元の中心経度] - [画像幅] / 256 * 180 / 2^[ズームレベル]) mod 360 - 180

[南へ移動したときの中心緯度]=

  (90 + [元の中心緯度] - [画像高さ] / 256 * 85 / 2^[ズームレベル]) mod 180 - 90

Chief Technical Officer - Google Static Mapsの画像サイズと経度・緯度

さらにこんなのも見つけた。

ケンタローの開発日記: Google Static Maps API で表示域の範囲を求める方法

//地図尺度
$myzoom=13;
//中心座標
$mylat=36.060923;
$mylng=136.500556;
//出力画像サイズに合わせて画像の端から端の距離を以下のように求めます。
//端から端の距離(latlng単位) = 画像幅 / ( 2^地図尺度  )
//サイズ 240x180     pow:PHPのべき算
$langex=240/pow(2,$myzoom);
$langey=180/pow(2,$myzoom);
// 以下の結果を1000000分の1で丸め処理して下さい。
// 中心点に距離を加算して表示地図のレンジを算出します。
//丸め関数を用意しましょう
$lattop = round(($mylat + $langey/2)*1000000)/1000000;
$latbtm = round(($mylat - $langey/2)*1000000)/1000000;
$lngtop = round(($mylng + $langex/2)*1000000)/1000000;
$lngbtm = round(($mylng - $langex/2)*1000000)/1000000;
ケンタローの開発日記: Google Static Maps API で表示域の範囲を求める方法

実際には表示されている範囲を求めて、その範囲内のマーカーをデータベースから拾っているようです。

最後の二つを比較して試してみたけど、実感としては、最後のケンタローの開発日記: Google Static Maps API で表示域の範囲を求める方法がシンプルだし、いいかな?

Chief Technical Officer - Google Static Mapsの画像サイズと経度・緯度の計算式をPHPに置き換えてみたけど(間違っているかもしれない)、南北と東西の移動幅の差がちょっと気になった。試したズームレベルによって誤差が出ているのかもしれないが…


他にも情報があれば、誰かコメントとか欲しい(けど、誰かにこれを読まれている気がしない)。


これも距離検索と同様、Google本体から情報が出ないかなぁ?


そもそもIPで制限がガッチリあるから、ケータイでバチバチ移動されても困るから、実装の必要はなかったりするのかな?


引用元

更新:2010/04/23 22:53 カテゴリ: web開発  > 位置情報 ▲トップ

FuelPHP

Mac

web開発

プロマネ

マネタイズ

プレゼン

webサービス運用

webサービス

Linux

サーバ管理

MySQL

ソース・開発

svn・git

PHP

HTML・CSS

JavaScript

ツール, ライブラリ

ビジネス

テンプレート

負荷・チューニング

Windows

メール

メール・手紙文例

CodeIgniter

オブジェクト指向

UI・フロントエンド

cloud

マークアップ・テキスト

Flash

デザイン

DBその他

Ruby

PostgreSQL

ユーティリティ・ソフト

Firefox

ハードウェア

Google

symfony

OpenPNE全般

OpenPNE2

Hack(賢コツ)

OpenPNE3

リンク

個人開発

その他

未確認

KVS

ubuntu

Android

負荷試験

オープンソース

社会

便利ツール

マネー

Twig

食品宅配

WEB設計

オーディオ

一般常識

アプリ開発

サイトマップ

うずら技術ブログ

たませんSNS

rss2.0