トップ  > メモ一覧  > カテゴリ「位置情報」の絞り込み結果 : 9件

9件中 1 〜 9 表示  1 

No.4011【引用】■MySQL5.6で新しく追加された地理空間データ(GIS)の検索を実装してみた


■ MySQL5.6 で新しく追加された 地理 空間データ( GIS )の検索を実装してみた
MySQL 5.6登場!! 新機能 速攻レビュー - 漢(オトコ)のコンピュータ道
を見ていたら、 MySQL5.6 の 新機能 の1つとして、こんな紹介が。

OpenGIS
ジオメトリデータの比較において、これまでは MBR (minimum bounding rectangle ≒ 近似的な長方形)に基づいた比較しか出来なかったのだが、ジオメトリの正確な形に基づいた比較ができるバージョンの 関数 が追加された。例えば MBR バージョンのContains()に対して、ST_Contains(...

引用元

更新:2011/08/22 10:04 カテゴリ: web開発  > 位置情報 ▲トップ

No.2648 GIS-GW等で通信経路での詐称を検証する方法

GIS-GW等で通信経路での詐称を検証する方法

方々よりノウハウを記事にして共有してくれと突かれていたので、遅くなりましたが記事化します。

その前に1つだけエクスキューズしておくと、小山さんの記事あたり

位置詐称を許さないここギコねねさん

とか書かれてますけど、別に許さないつもりはなくて...確かにGeoPlatFormAPIのような位置取得APIや、GIS-GWのような位置流通 APIの双方で詐称を検証する方法とか事ある毎に口にしてるんですけども、これは「何が何でも詐称を許さない」からそうしてるわけではなくて、それぞれ理 由(それも異なる理由)がありまして、

  • 位置取得APIについては、社内用に作っている方がメイン用途をエンタテイメント分野としているので、そちらでは否が応でも「詐称は許さないようにせざるを得ない」のですね。
    だから自分の方はこだわってるだけで、別にそういう用途に使う事を想定していないのであれば、たとえば携帯から位置を取って地図を表示するだけのサイトに 詐称対策が必要とも思えないし、詐称対策してないとAPIとして無意味、などという事は全くありません。
    その意味では、GeoPlatFormAPIを紹介した記事で、「が、ちょっと甘い」等と、詐称対策がされてないとダメという印象の表現をしてしまったのは、全く適切ではありませんでした...スンマセン。
  • GIS-GWの方は、私がこだわっているというよりも、GIS-GWメンバによってGIS-GW上に期待されていることの方が、詐称対策を必要としている、というのが個人的印象です。
    全くの個人的には、ケータイ位置情報サイト間で情報を流通する際に、それほど詐称対策が必要とは思えない(他のサイトで取った位置情報をGETで流されて きて、それを元にエリアを盗った!等と認めるようなエンタメサイトも考えにくいし。まあ、将来的に位置情報のGET持ち回りでなくブロードキャスト等が実 現されたら話は別なのですが)し、サイト間で流通させたい位置情報としては、単にケータイデバイスで直接取得したもんだけではなく、地図で微修正したりし たもんも含まれるだろうから、そこに詐称対策を盛り込む必要はほとんど感じていなくて、別に経緯度をGETにつけて流すだけの緩いもんでいいんじゃない の?と思ってたんだけど。
    そしたら、他のGIS-GWのメンバの方から、位置情報の信頼度も流通したいよね(たとえば、doodleは本当にその場にいる人しか発言させないらしい ので)、果てはユーザのユーザID情報までパラメータとして引き渡したいよね、みたいなGIS-GWへの要望が挙がってきた。
    そこまで情報を保証したり、センシティブな情報を流そうと思ってるなら、詐称対策せずにGETでただ流してたら相当やばいよね、ということで「詐称対策し なきゃ」とこだわっているわけでして、個人的信念よりは他者要望に基づいて必要性を主張しているような感じです。

まあ、どう言ったところで位置情報詐称検証法にこだわっていることは事実なのですが、別にいろんなユースケースがあるにも関わらず、その必要性も考慮せず に脳みそ筋肉的に、「位置情報詐称を考慮していない位置APIなんてクソだよクソ」的なことをここギコは考えている、と思われるのも嫌なので、一応エクス キューズをば。

で、本題。

位置情報詐称検出といっても、別に難しいことをかんがえているわけではなくて、ほんまにはてな認証APIやLivedoor認証API、Wassr認証APIなんかの発送パクってるだけ。
要するに、ユーザのID情報と1対1で紐付いた秘密鍵を発行して、その秘密鍵をベースに詐称検出用のシグニチャをデータに付加してやるだけのこと。
例えば、GIS-GWのインタフェースの現状仕様は、Serendi(ID:SE)からdoodle(ID:DO)に対し、経緯度と取得時間の情報を送ってやろうとすれば、SerendiからGIS-GWへの遷移は

http://ja.gisgw.com/gw?s=SE&d=DO&lat=35.8264&lon=139.6920&t=20070828120413

みたいなURLになるわけだけど、これを詐称検証可能にしてやろうと思えば、上記の赤の部分全体を、Serendi/GIS-GW間で共有している秘密鍵を使ってHMAC_SHA1ダイジェストを取ってやった値を、クエリ末尾に付加してやればよい。

http://ja.gisgw.com/gw?s=SE&d=DO&lat=35.8264&lon=139.6920&t=20070828120413&sig={赤字部分のSerendi秘密鍵でのhmac sha1 hexdigest}

みたいにすればよいだけ。
これを受け取った側でも、同様に秘密鍵を使い赤部分のダイジェストを取ってやって、一致していれば詐称なし、一致していなければ詐称あり、という感じにすればよい。

GIS-GWは上記を受け取った場合、doodleに位置情報を転送するわけだけど、これについても同様にシグニチャを付加すればよい。
ただし、今度は使う秘密鍵が、doodle/GIS-GW間で共有している秘密鍵になる点だけが異なる。

http://doodle.st/gw?s=SE&d=DO&lat=35.8264&lon=139.6920&t=20070828120413&sig={赤字部分のdoodle秘密鍵でのhmac sha1 hexdigest}

みたいな感じ。

実際問題これだけの話で、そんなたいした話ではない。
基本、位置流通APIだけでなく、位置取得APIでも、ほぼ同じやり方で詐称検出はできる。
けど、まあこちらでも作ってていくつかのベストプラクティス?的なのもあるので、それを補足しておくと、

  • 赤字で書いた部分のデータ文字列のシグニチャをとる場合だけど、上記の例だと全部ASCIIデータなので問題ないけど、マル チバイトデータ等URLエスケープ対象文字が混ざる場合、URLエスケープ後のデータでシグニチャを取ると、URLエスケープの微妙な揺らぎ(スペース は+にするのが常道と思いますが、%20にされる場合も少なくない、等)のためにシグニチャがずれてしまうことがありそう。
    シグニチャを取る際のデータはURLエスケープ前のバイナリデータとするのが吉かなと思う。
  • 本仕様で検出できるのは、URL上のデータに詐称がないかだけ。
    例えば、上記URLでlat=35.8264がlat=34.8264に変更されれば検出できるけれど、「シグニチャまで含めたこのURLセット」を、別のユーザに転送されたり、或いは別の日時に再利用されたりといったことは検出できない。
    よって、そういった部分までケアしようと思えば、シグニチャを取る対象のデータの中に、時刻依存やユーザ依存のデータ(ユーザIDとか、ユーザIDを GETで流すのがやばければUAとか?)を埋め込んでおき、URLの詐称検証とは別に、時刻妥当性やユーザ妥当性を判断する必要がある。
  • 位置詐称対策シグニチャを埋め込んでいるデータに対し、下流でシグニチャを外すのは問題ないけど、対策のされていない元データに対して、下流でシグニチャを埋め込むのは絶対ダメ。
    たとえば上の例で、doodleは詐称対策されたデータを望んでいるからといって、Serendi→GIS-GW間は無検証で送られてきたデータに対し、GIS-GW→doodle間にシグニチャを埋め込むのはやってはいけない。
    でないといくらGIS-GW→doodle間は検証できても、その上のSerendi→GIS-GW間でいくらでも詐称できてしまうので、何を信用していいのか判らなくなる。

みたいなところでしょうか。

でも、これは飽くまで詐称を検出できるかどうかの話なので、通信路の秘密みたいな話になるとまた別の話、というかGETでできるの?みたいな感じになる。
GIS-GWとしてはできればあまり重い仕様にしたくない、GET程度の軽い仕様がいいということなので、それでできる範囲は範囲のライトな仕様でおいて おくとして、でも一方でユーザID情報みたいなのも流したいという要望もあるので、そうなるとGETなんかで流して本当にいいのかな?みたいな感じもして る。
そのレベルになってくると、超重くなってくるけど先日アイデンティティ飲み会で知ったSAMLを応用するとか、そういうレベルの話になるんじゃないか、という感じがしている。

引用元

更新:2010/06/09 11:01 カテゴリ: 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開発  > 位置情報 ▲トップ

No.2326 Where2.0:空間DBのPostGISおよびGeoRSSとKMLについて

Where2.0:空間DBのPostGISおよびGeoRSSとKMLについて

icon June 15, 2006 4:47 PM

Where2.0参加中のフナミタカオです。 15分刻みのプレゼンテーションで1日目から、もう濃密な内容。僕自身地図に関してはまだまだ初心者なのですが、つわものの皆様にいろいろ教えてもらいました。
有用な情報ということで、2つほど紹介させていただきます。

  1. SQLで緯度経度を用いて、検索するにはどうするか?
  2. GeoRSSとKMLはどう違う?

SQLで緯度経度を用いて、検索するにはどうするか?

今、たたみラボはデータベースとして、MySQLを利用しています。
たとえば宿引きというじゃらんnetに掲載されているホテル・宿の情報をGoogleMaps上にマッピングしているデモがありますが、このデモでは、各ホテル・宿ごとに、名称、住所、緯度経度を保持しています。フィールドは簡略していますがこのテーブルをYadoとしましょう。

  名称(name) 住所(address) 緯度(latitude) 経度(longitude)
  たたみホテル 東京都千代田区丸の内1-1 35.68546583314841 139.76240158081055
  かちどき旅館 東京都中央区勝どき1-13-1 35.66092259369664 139.77527618408203

イメージは↑このようになります。
さて、ここで問題はある特定の位置から、近い順に10件宿を抽出したいときにどうするかです。

現状の実装

現状では、どうやって、この問題を解決しているかというと、特定の点からの距離を、緯度、経度に換算して、緯度と経度をそれぞれ、範囲指定でクエリをしています。ことばでいうと難しいですが、SQL的には

SELECT * FROM Yado Where latitude> 35.685 and latitude < 35.686 and longitude>139.762 and longitude<139.777 
dist.jpg

このようにすることで、(ほぼ)正方形の領域内にある、ホテル・宿が抽出できますが、距離順にはソートできていません。ある範囲に入っているだけ。なので、検索結果を1件づつ、ループをまわして距離を測定し、その距離をもって、ソートしています。
検索結果が少ないうちはこれでもいいのですが、近い順で10件とりたいとか、近い順でページングしたいとかになると、どんどん距離を広げていく必要があり、パフォーマンス的にも、コーディング的にも負荷が高いなあと思っていました。

解決の方法

では、そうすればいいかということで、オライリーの本の販売コーナーがあったのですが、Web Mapping Illustrated の本の前に座っていた、その本のTyler Mitchellさんに大胆にも質問しました。(聞いたときは著者だとおもっていなかった)。お答えは、「PostGISを使うといいよ」とのこと。だれ もが考えることらしく、解決法はWeb Mappingにも書かれていました。
MySQLで何とかならないのかと聞いてみたのですが、できなくはないがたいへんとのことで、どうも地図をやるなら、データベースはPostGISというのがスタンダードのようです。そして、その直後、この本を翻訳した森さんに会場でお会いし、なんと、日本語版=入門Webマッピング―自分で作るオリジナルのデジタル地図 はできたてのほやほやということをお伺いしました。

Web Mapping Illustrated 入門Webマッピング―自分で作るオリジナルのデジタル地図
PostGISを使用すると、フィールドにストアする形式として空間オブジェクトが利用できるようなる。そして、この空間オブジェクトに対して、検索やインデックスの生成ができるようになるようです。
たとえば

 SELECT * FROM GEOTABLE WHERE GEOM && Distance(GeometryFromText('POINT(1000 1000)',-1),GEOM) < 100;

こんな感じ(本当に感じなので、まだためせていません)入門Webマッピング―自分で作るオリジナルのデジタル地図を読んでから試してみようとおもいます。

GeoRSSとKMLはどう違う?

どちらも場所を記述するためのXMLベースのフォーマットですが、両者の違いはなにかを一言でいうと

  • GeoRSS:場所の座標をあらわすシンプルなフォーマット。
  • KML:座標のみならず、付加情報(オーバーレイ、モデリング、関連情報等々)なんでもはいる。

ということ。KMLはGMLを素にKeyhole社が作成したフォーマット。今ではGoogleがMapsとEearthで採用しているため、デファクトスタンダードを目指しているようです。

Google Maps も Google Earth も Google 社内でスクラッチから作られたわけではなく、元々はそれぞれ買収した Where 2 Technologies(2004年8月)、Keyhole(2004年10月)のプロダクトだ。
http://earthhopper.seesaa.net/article/5904152.html

KMLのKはKeyholeのKということですね。
このKML何人かの方にお伺いしたのですが、結構受け入れら手いる印象でした。なんといっても、Googleが推進しているわけですので、デファクトとして安心してとかってもよさそうです。
あと、GeoTagというのがりますが、これはGeoRSSよりももっシンプル(XMLでさえない)ので、記述が簡単です、Flikerで採用されています。

GeoRSSサンプル

Simple

<georss:point>45.256 -71.92</georss:point>
GML
<georss:where>
<gml:Point>
<gml:pos>45.256 -71.92</gml:pos>
</gml:Point>

</georss:where>

引用元 :http://georss.org/

KMLサンプル

<?xml version="1.0" encoding="UTF-8"?>
 <kml xmlns="http://earth.google.com/kml/2.0">
 <Placemark>
   <description>Tethered to the ground by a customizable tail</description>
   <name>Tethethed placemark</name>
   <LookAt>
     <longitude>-122.0856375356631</longitude>
     <latitude>37.42240551227282</latitude>
     <range>305.8880792294568</range>
     <tilt>46.72425699662645</tilt>
     <heading>49.06133439171233</heading>
   </LookAt>
   <visibility>0</visibility>
   <Style>
     <IconStyle>
       <Icon>
         <href>root://icons/palette-3.png</href>
         <x>96</x>
         <y>160</y>
         <w>32</w>
         <h>32</h>
       </Icon>
     </IconStyle>
   </Style>
   <Point>
     <extrude>1</extrude>
     <altitudeMode>relativeToGround</altitudeMode>
     <coordinates>-122.0856204541786,37.42244015321688,50</coordinates>
   </Point>
 </Placemark>
 </kml>
引用元:http://www.keyhole.com/kml/kml_tut.html#placemarks


GeoTagサンプル

<geo:lat>46.1</geo:lat>
<geo:long>124</geo:long> 

 

 

TRACKBACK URL

COMMENTS

PostGISというのは
http://www.postgis.org/
のことですよね?

PostgreSQLの最新版では、
幾何データ型と幾何データ演算子が普通に実装されてます
のでもはやPostGISに頼る必要もないと思います。

June 15, 2006 7:22 PM by watanabe  

watanabeさんコメントどうもありがとうございます。

幾何学演算子幾何データ型
http://www.postgresql.jp/document/pg803doc/html/datatype-geometric.html#DATATYPE-GEO-TABLE

幾何関数と演算子
http://www.postgresql.jp/document/pg803doc/html/functions-geometry.html

とかを眺めています。
PostgreSQL自体、初めてなので、いろいと試してみます。使い方のサンプルとか載っているページがあれば、ぜひご紹介ください

引用元

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

No.2324 PHPとMySQLで地点検索-GoogleMapsAPI

PHPとMySQLで地点検索 - Google Maps API

色々調べてみると、なんか面倒な雰囲気で、さっそく挫折しそう。

Creating a Store Locator with PHP, MySQL & Google Maps - Google Maps API - Google Code
http://code.google.com/intl/ja/apis/maps/articles/phpsqlsearch.html


ググってて出てきたのが上のサイト。ま、Googleからの情報ですけど。

PHPとMySQLでっていうのはいいね。
見てみると、緯度経度をそれぞれFLOATで持つんだね。

CREATE TABLE `markers` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`name` VARCHAR( 60 ) NOT NULL ,
`address` VARCHAR( 80 ) NOT NULL ,
`lat` FLOAT( 10, 6 ) NOT NULL ,
`lng` FLOAT( 10, 6 ) NOT NULL
) ENGINE = MYISAM ;


で、ある地点(の緯度経度)から距離を出して、指定した半径(キロメートルorマイル)内のものをピックアップするというSQLがこれ。
SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance FROM markers HAVING distance < 25 ORDER BY distance LIMIT 0 , 20;

実際にPHPでやると、こう。
$query = sprintf("SELECT address, name, lat, lng, ( 3959 * acos( cos( radians('%s') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('%s') ) + sin( radians('%s') ) * sin( radians( lat ) ) ) ) AS distance FROM markers HAVING distance < '%s' ORDER BY distance LIMIT 0 , 20",
mysql_real_escape_string($center_lat),
mysql_real_escape_string($center_lng),
mysql_real_escape_string($center_lat),
mysql_real_escape_string($radius));
$result = mysql_query($query);


この場合25マイル未満ってこと。ちなみにキロメートルでやるなら3959を6371に置き換えること。

中心となる地点はJavaScriptで取得して、GETでパラメタを送るようだ。

実際に使う場合は画面遷移も必要だし、POSTするだろうから、随分変更点が出てきそう。
とはいえ、緯度経度をFLOATで持っててもOKなら、SQLiteでもなんとかならんかな?


忘れないように、ここにメモしておこう。


メモだけじゃなく、実際にやってみた。
とりあえずコピペして動くかどうかテスト。

環境はXAMPP Lite Windows版で、version 1.7.1。古いのかどうか判りません。

とりあえずデータベースを付属のphpMyAdminから作成した。当然UTF-8ね。
テーブルも、記事にある通りに作る。GUIで作れるけど、SQL文をコピペして作成。
次はデータのインポート…と思ったけど、CSVファイルをインポート出来ないの? インポートする形式のところに上記サイトで見たようなCSVという項目がない!
困った…と思ったら、INSERT文を羅列したファイルが用意されてた。抜かりないな。

さて、データベースの準備は完了。あとはファイルをコピペして作成するだけ。

データベース情報を格納したphpsqlsearch_dbinfo.php、検索ロジックと検索結果をXMLで吐き出すphpsqlsearch_genxml.php、HTMLファイルのphpsqlsearch_map.htmlの三つ。
さすがにphpsqlsearch_dbinfo.phpだけは環境に合わせて書き換えて、保存。当然UTF-8。

出来ました。

お手本サイトどおり、mountain view caで検索すると、ちゃーんとマーカーが出てくる(マウンテンビューで検索してもOKなのはさすがだね)。

var searchUrl = 'phpsqlsearch_genxml.php?lat=' + center.lat() + '&lng=' + center.lng() + '&radius=' + radius;

入力した地名から緯度経度を取得して、プルダウンで選択した距離をGETでPHPファイルに送ってるだけ。

最終的に作る(かもしれない)のは検索結果を一覧表示するパターンなので、値をhiddenの項目にでもぶっこんでsubmit()するのがいいかな?(地図を併記する必要がなければ、だけど)
地図や詳細情報を表示するための個別ページは、地点のIDをGETパラメタにでも入れて作るのでいいかな?(是非ブクマしてください!といわんばかりに)

あとは…
郵便番号から検索するパターンか。入力された郵便番号を中心に、一定の範囲を区切って検索するか。どの程度までがリアリティのある範囲なのか、難しいところかな。
郵便番号での周辺検索の範囲って、みんなどうしてるんだろう??

今気づいたけど、これ、version2のコードなんだね。
version3用に書き換えるには、どうすべ? また今度。

引用元

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

No.2317 ウノウのライブラリ:Geomobilejp_Converter - Manual

Geomobilejp_Converter - Manual

概要

Geomobilejp_Converterはモバイル端末のGPS機能で送信される情報を想定した、緯度経度フォーマット、測地系の相互変換ライブラリです。また、同梱されているGeomobilejp_IAreaを使用すると、緯度経度からオープンiエリアのエリアコードやエリア名を取得することができます。

同梱されているサンプルプログラム、Geomobilejp_Converter/sample/mobile_page_sample.phpにここで説明するコードのすべてが利用されていますので、実装の参考になるでしょう。

PHPのバージョン5で動作します。

緯度経度の変換

Geomobilejp_Converterを生成する

Geomobilejp_Converterクラスを生成します。第1引数に「緯度」、第2引数に「経度」、第3引数に測定した「測地系」を渡します。緯度経度のフォーマットは、度単位(degree)と度分秒単位(dms)に対応しています。

require_once '/path/to/Geomobilejp/Converter.php';

$converter = new Geomobilejp_Converter('35.21.03.340', '138.34.45.725', 'wgs84');

フォーマットを変換する

緯度経度を度単位(degree)と度分秒単位(dms)に相互変換することができます。

require_once '/path/to/Geomobilejp/Converter.php';

$converter = new Geomobilejp_Converter('35.21.03.340', '138.34.45.725', 'wgs84');
$converter = $converter->format('degree');

echo $converter->getLatitude() . "\n";    // 35.350928
echo $converter->getLongitude() . "\n";   // 138.579368

測地系を変換する

測地系を世界測地系(WGS84)と日本測地系(Tokyo)と日本測地系2000(JGD2000)に相互変換することができます。

require_once '/path/to/Geomobilejp/Converter.php';

$converter = new Geomobilejp_Converter('35.21.03.340', '138.34.45.725', 'wgs84');
$converter = $converter->convert('tokyo');

echo $converter->getLatitude() . "\n";    // 35.20.51.663
echo $converter->getLongitude() . "\n";   // 138.34.56.905

フォーマットと測地系を変換する

フォーマットの変換と測地系の変換は、Geomobilejp_Converterクラスのインスタンスが返ってきますので、相互変換を組み合わせることができます。

require_once '/path/to/Geomobilejp/Converter.php';

$converter = new Geomobilejp_Converter('34.700695', '135.495243', 'wgs84');
$converter = $converter->convert('tokyo')->format('dms');

echo $converter->getLatitude() . "\n";    // 34.41.50.830
echo $converter->getLongitude() . "\n";   // 135.29.53.007

オープンiエリアを取得

iエリアデータファイルを準備する

docomoの提供するオープンiエリアのエリアコードとエリア名を緯度経度から取得することができます。この機能を利用するためには、まずdocomo サイトで公開されているiエリアデータファイルを取得して次のようにデータファイルを作成してください。尚、PHPの内部エンコーディングはUTF-8であることを想定しています。

# iエリアデータファイルを取得します。
$ wget http://www.nttdocomo.co.jp/binary/archive/service/imode/make/content/iarea/iareadata.lzh

# iエリアデータファイルを展開します(lhaコマンドがない場合は適宜他の方法で展開してください)。
$ lha e iareadata.lzh

# iエリアデータファイルから1つのPHPデータファイルを作成します。
$ cd ./Geomobilejp_Converter/tools
$ php ./create_iareadata.php ../../iareadata

# 作成されたファイルをGeomobilejp/IAreaディレクトリに移動します。
$ mv ./iareadata.php ../lib/Geomobilejp/IArea/

緯度経度からiエリアコードとiエリア名を取得する

iエリアデータファイルの準備ができるとGeomobilejp_IAreaを使用して、緯度経度からiエリアコードとiエリア名を取得することができます。

require_once '/path/to/Geomobilejp/Converter.php';
require_once '/path/to/Geomobilejp/IArea.php';

$converter = new Geomobilejp_Converter('34.700695', '135.495243', 'wgs84');
$area = Geomobilejp_IArea::seekArea($converter);

echo $area->getIAreaCode() . "\n";    // 17202
echo $area->getName() . "\n";         // 大阪駅/阪急梅田駅周辺

iエリアが見つからなかった場合、Geomobilejp_IArea::seekAreaはnullを返します。

キャリアの差

パラメータの差を吸収する

docomo、au、SoftBank、WILLCOMのGPS機能で送信される緯度経度情報は、パラメータ名やフォーマットに違いがあります。 User-Agentによる判定を行って、各違いを吸収する必要があります。Geomobilejp_Converterにはこれらの差をパラメータがあ るかどうかのみを単純に判定して吸収するGeomobilejp_Mobileが同梱されています。他のUser-Agentを判定するライブラリを使用 する場合には不要ですが、役に立つようであればご利用ください。

require_once '/path/to/Geomobilejp/Mobile.php';

$mobile = new Geomobilejp_Mobile();

if ($mobile->hasParameter()) {

    echo $mobile->getLatitude() . "\n";    // N35.44.33.150
    echo $mobile->getLongitude() . "\n";   // E135.22.33.121
    echo $mobile->getDatum() . "\n";       // wgs84

}

HTMLのGPSタグを出し分ける

docomo、au、SoftBank、WILLCOMではそれぞれGPS機能を使用するためのHTML表記がありますが、 Geomobilejp_Converterにはこの差を吸収する機能は実装されていません。実際には Geomobilejp_Converter/sample/mobile_page_sample.phpに表記しているような各キャリア用のHTML をUser-Agentを判定して出し分ける必要があります

引用元

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

No.2315 GeoFormAPIユーザーズガイド

 

GeoForm API ユーザーズガイド

GeoForm API ユーザーズガイド



端末の種類を意識せず、モバイル端末の位置情報を統一されたインターフェースで取得できます。

API 呼出時に、

  • モバイル端末のユーザエージェント (UA)
  • API から位置情報を取得する URI

を指定すると、戻り先 URI にて位置情報を取得することができます。

デフォルトでは各 UA に応じ、簡易位置情報フォーム (zone)、GPS フォーム (gps)のうち、 最適なもの 1 つ (最も精度が高く位置情報を取得できる取得方法) を指定されたフォーマットで返却します。

引用元

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

No.2313 ■au:GPS携帯位置情報の取得について

 ■ au: GPS携帯 位置情報の取得 について

auのGPS携帯 では、2つの位置情報取得方法があるようです。ひとつは、基地局から位置情報を取得する方法(簡易位置情報)。もうひとつはGPS衛星から位置情報を取得する方法です。これらでは携帯の種類と位置情報の精度にちがいがあるようです。
KDDI au の技術情報では、基地局からの取得方法しか公開されていないようですが、こちらで確認したところ、前者の方法だと位置情報の精度に問題があるため、後者の方法で構築する必要があります。

  • 簡易位置情報パラメーターの取得方法
    まずは、au携帯からどのようなパラメータが送信されているかを、実際確認してみます。
    • 次のソースをコピーし、test.phpの名前で保存し、自分のサーバへアップロードします。"myserver"の箇所を自分のサーバ名へ変更してください。
      <?
      echo "<p>au携帯/位置情報パラメータの取得</p>";
      echo "<a href=device:location?url=http://myserver/info.php>位置情報取得テスト</a>";
      echo "<br>";
      ?>
    •  

    • 次のソースをコピーし、info.phpの名前で保存し、自分のサーバへアップロードします。
      <?

      echo "位置情報取得テスト<br>";

      echo getenv("HTTP_USER_AGENT")."<br>";
      echo "datum:".$_GET["datum"]."<br>";
      echo "unit:".$_GET["unit"]."<br>";
      echo "lat:".$_GET["lat"]."<br>";
      echo "lon:".$_GET["lon"]."<br>";

      ?>
    •  

    • この2つのファイルの階層

      http://myserver/

      • test.php
      • m.php
    • 携帯電話のwebから、アップロードしたアドレス http://myserver/test.php へアクセスします。
      (テスト画面 ⇒ http://www.yaskey.cside.tv/mapserver/GPS_test/ ※このURLを携帯からアクセスすると以下と同様の内容が表示されます)

      リンク先の「位置情報取得テスト」をクリックします。
      au携帯/位置情報パラメータの取得

      位置情報取得テスト

       

    • GPS情報を通知します。よろしいですか」と表示されますので、「1 はい」をクリックします。
      GPS情報を通知します。
      よろしいですか
      1 はい
      2 いいえ

       

    • すると次の位置情報が表示されます。
      位置情報取得テスト
      KDDI-xxxx
      UP.Browser/x.x.x.x.x
      (GUI) MMP/2.0
      datum:tokyo
      unit:dms
      lat:xx.xx.xx.xx
      lon:yy.yy.yy.yy

      表示された情報の内容

      • KDDI-xxxx UP.Browser/x.x.x.x.x (GUI) MMP/2.0 携帯のユーザーエージェントです。詳細はKDDIのページを参照
      • datum:tokyo
      • unit:dms
      • lat:yy.yy.yy.yy
      • lon:xx.xx.xx.xx
    • au のパタメータ仕様参照先: au 技術情報 > パタメータ仕様
      引数名 内容 備考
      datum 測地系
      以下の2つの測地系の中から使用している測地系を示す。
      ・wgs84 WGS84系
      GPS測量で算出される座標系。数回の改定により現在ではITRF座標系と実用上の差異はなくなっている。
      ・tokyo 日本測地系
      測量法施行令第2条で定められた日本標準の測地系。
      引数内容としては"tokyo"という表示になるが、実際の測地系はWGS84系のデータを使用。
      世界測地系を使用しているため、MapServer/PROJの指定は4326を使用します。
      unit 座標系
      以下2つの座標系の中から使用している座標系を示す。
      degree 度単位
      ・dms 度分秒単位 (ただし、秒の小数点以下は10進表記)
      本サービスでは「dms:度分秒単位」のみ。
      MapServerでは degree度単位に変換して使用する必要あり
      lat 座標系
      以下2つの座標系の中から使用している座標系を示す。
      記述例 35.43.25.38
      35:度 -90 (南緯) ~ 90 (北緯)
      43:分 0 ~ 59
      25:秒 0 ~ 59
      38:秒小数点 2桁(1/100)までを記載
      緯度Y
      MapServerでは北緯 45.4353483度 という形式に変換して使用する必要あり
      lon 経度
      座標系に則した表記方法で経度を記述する。符号つきの度で表し、東経を+ (または省略) 西経を-とする。
      記述例 135.43.25.38
      135:度 -180 (西経) ~ 180 (東経)
      43:分 0 ~ 59
      25:秒 0 ~ 59
      38:秒小数点 2桁(1/100)までを記載
      経度X
      MapServerでは東経 135.4353483度 という形式に変換して使用する必要あり
    • この位置情報に関するパラメータを、携帯から受け取ることににより、その地点の情報が表示される仕組みとなっています。

       


     

  • GPS位置情報パラメータの取得方法
    先程の位置情報は、au基地局から送信される位置情報でしたが、これでは精度があまり高くありません。そこでGPSによる位置情報の取得方法とそのパラメーターを取得する方法を試してみます。基本的には、先程の方法と同じです。
    • 先程の test.php に次の行を追加し、自分のサーバへアップロードします。"myserver"の箇所を自分のサーバ名へ変更してください。
      <?
      echo "<p>au携帯/位置情報パラメータの取得</p>";
      echo "<a href=device:location?url=http://myserver/info.php>簡易位置情報 の取得</a>";
      echo "<a href=device:gpsone?url=http://myserver/gpsinfo.php&amp;ver=1&amp;datum=0&amp;unit=0>GPS位置情報 の取得</a>";//この1行を追加する
      echo "<br>";
      ?>
    •  

    • 次のソースをコピーし、gpsinfo.phpの名前で保存し、自分のサーバへアップロードします。
      <HTML>
      <TITLE>gps</TITLE>
      <BODY>
      <?
      $datum=$_GET["datum"];
      $unit =$_GET["unit"];
      $lat=$_GET["lat"];
      $lon=$_GET["lon"];
      chop($lat);//文字列の最後から空白文字を削除する
      chop($lon);
      $lat_s = explode(".", $lat);//ピリオド区切りで配列へデータを格納する
      $lon_s = explode(".", $lon);

      //取得した位置情報を経度緯度 dms 度分秒単位 で表示
      echo "$lat_s[0]度$lat_s[1]分$lat_s[2]秒$lat_s[3]<BR>";
      echo "$lon_s[0]度$lon_s[1]分$lon_s[2]秒$lon_s[3]<BR>";

      //degree 度単位で表示する
      $lat_deg=$lat_s[0]+$lat_s[1]/60+$lat_s[2]/3600+$lat_s[3]/360000;
      $lon_deg=$lon_s[0]+$lon_s[1]/60+$lon_s[2]/3600+$lon_s[3]/360000;
      echo "degree: $lat_deg<BR>\n";
      echo "degree: $lon_deg<BR>\n";

      //経度緯度以外の情報を表示する
      echo "GPSv ver: ".$_GET["ver"]."m<BR> \n";
      echo "高度 alt: ".$_GET["alt"]."m<BR> \n";
      echo "長軸半径誤差 smaj:".$_GET["smaj"]."<BR> \n";
      echo "短軸半径誤差 smin:".$_GET["smin"]."<BR> \n";
      echo "誤差楕円長軸角度 majaa 度:".$_GET["majaa"]."<BR> \n";
      echo "高度誤差 vert: ".$_GET["vert"]."<BR> \n";
      echo "測位方法 fm: ".$_GET["fm"]."(fixed mode 数字の意味不明)<BR> \n";
      ?>
      </body>
      </HTML>

         

    • 携帯電話のwebから、アップロードしたアドレス http://myserver/test.php へアクセスします。

      dms度分秒単位データからdegree度単位のデータへ変換

引用元

更新:2010/04/21 19:16 カテゴリ: web開発  > 位置情報 ▲トップ

No.2310 PHPとMySQLで携帯サイトを開発しているのですが、iエリアやGPS機能を用いて経度緯...

PHPとMySQLで携帯サイトを開発しているのですが、iエリアやGPS機能を用いて経度緯...

search_question_xさん

PHPとMySQLで携帯サイトを開発しているのですが、iエリアやGPS機能を用いて経度緯度を取得して現在地から近い順にデータを並べ替えるにはどのようにしたらよいのでしょうか?(DBに10進数の経度緯度を保持)

iエリアやGPSからの経度緯度の取得はできる状態です。あとは近い順にデータの一覧を表示したいのです。その際に、距離も表示しようと考えています。どうかみなさんのお知恵を貸してください

補足
実際に検索は行い、一通りのサイトは拝見しました。できれば、実際のソース等で教えていただければうれしく思います。要は近い順に並べるというのは例えば135.11111と13.22222という経度と緯度を取得したら、DBからどのようにOrderbyを実行すれば近い順に並ぶのでしょうか?
 

違反報告

ベストアンサーに選ばれた回答

joseph_joey_tribbianiさん

面白そうな質問だね。答えを知らなかったから、僕も今回はじめて考えてみたんだ。。。だからベストなやり方じゃないかもだけど、、僕の考えたやり方は 「区域」 と 「並べ替え」 なんだ。

【ステップ1】 区域 で絞り込む
まず、地図を たとえば 0.1°単位 (距離だと11kmぐらい) の方眼紙で荒っぽく 区域 に分ける。プログラムでは 区域 は 緯度 と 経度 の 2次元配列 で表す。データを登録するときは、この 2次元配列 に データを登録しておく。こうしておけば、同じ 区域 に属する 地点同士 は 遠くても せいぜい 約16km 圏内に限定されるよね。もちろん GPS の地点 もどこかの 区域 に属することになるよね。

~こんなイメージだよぉ~

$区域[0][0] = array (データ1, データ2, データ3, ..., データ11)
$区域[0][1] = array (データ12)
$区域[0][2] = array ()
$区域[1][0] = array (データ13, データ14)


GPS地点の区域 … $区域 [(int) (GPS緯度 / 0.1)] [(int) (GPS経度 / 0.1)]


【ステップ2】 距離で並べ替え
同じ区域に属する全部の地点データについて、二点間の距離を求める関数 (※1) をつかって GPS の地点との距離が近い順で並べ替える。もしも、同じ区域に属するデータが存在しなかったら、その区域に隣接する周囲 8 つの区域について、並べ替えを実行する。

(※1) 距離を求める関数は自分で作るんだけどね。簡単なのでよければ 3平方の定理 でもいいだろうし、本格的なものなら球面上の距離を求めてもいいね。

こんな感じでどだろう

joseph_joey_tribbiani

引用元

更新:2010/04/21 17:12 カテゴリ: web開発  > 位置情報 ▲トップ
9件中 1 〜 9 表示  1 

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