2010年2月22日月曜日
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用に書き換えるには、どうすべ? また今度。



0 コメント | コメントを書く
Template Design: © 2007 Envy Inc.