LUNARAVE WEBクリエーターの仕事と休息

アクセスカウンタ

help リーダーに追加 RSS 中心場所を指定して近い順に表示する -EC-CUBE-

<<   作成日時 : 2007/12/19 12:40   >>

トラックバック 0 / コメント 0

以前、オープンソースの"EC-CUBE"を利用した「地図とDBの情報を連携させたシステム」を紹介したが、登録した場所を検索するときに、指定した場所を中心に近い順に表示できないかという要望があり実装することにした。

 地図情報を利用したシステム


考え方としてまず思いつくのが、中心とする指定場所の座標を確保した上でそこから"任意の範囲内"での検索だ。

ここでの"任意の範囲内"というのは半径1Km以内といった距離数の指定となる。

指定場所を中心として距離数を加減算してやれば最大と最小の座標を求めることができる。
しかし、この検索対象範囲は四角形となり、半径1Kmといった円形での検索はさらに複雑化する。

さらに複数の該当箇所があった場合、どちらが中心から近いかを割り出すことも難しい。

 検索対象


これを何とか楽して実装できないかと調べてみたところ、PostgreSQLには空間情報を扱うクラスが存在することがわかった。


今のところMySQLにはこの機能がないようなのでPostgreSQLでの実装に限るが、これを使わない手はない。


まずは中心座標とする場所を格納するテーブルを作成する。
空間情報を利用する場合はInnoDBではなくMyISAMでしか使えない。

そして座標を使うカラムには"geometry"を指定する。
データベースの管理をphpPgAdminで行っている場合は"geometry"が無いこともあるので、その場合は直接SQLを実行させる。


CREATE TABLE 中心場所テーブル名 (
〜中略〜
gpoint geometry,
〜中略〜
) TYPE=MyISAM ;


次にレコードを追加する場合は以下のようにする。


INSERT INTO dtb_landmark ( gpoint )
VALUES ( GeomFromText('POINT(北緯座標,東経座標)') );



これで中心とする場所のデータが格納できたので、そこから検索対象とするデータにも同様に"geometry"の設定と"GeomFromText"によるINSERTを行う。


検索する場合のSQLは以下のようになる。

SELECT * FROM テーブル名 WHERE gpoint @ circle ( point( 中心の北緯座標 , 中心の東経座標 ) , 距離数);



上記の距離数は任意で入力するのだが、0.01で約1Km分の距離数となる。
よって、0.01と入れると半径1Km内にあるものを取得する。


さて、これをEC-CUBEに実装すると以下のような操作画面になる。

まず、管理画面にて中心座標を登録する。

 ランドマーク登録


地図をドラッグすると自動的に座標を取得し、場所の名称を入力できるようにしている。

ここでは"大阪駅"を中心とするデータを一つ作る。


次に、先ほどの中心場所の登録とは別のテーブルに、大阪駅周辺の主な建物を数個登録する。
下の画像ではデータを入力した新しい順に登録データが表示されている。

 登録データ


この状態で先ほど登録した"大阪駅"を中心場所とする検索、またはソートを行うと"大阪駅"を中心に近い順に表示されるようになった。

 近い順


また、試しに"大阪駅"から半径1Kmを超える場所も登録していたが、こちらは検索結果に表示されなかったので距離数の指定も正確に動作しているようだ。


非常に便利な機能がPostgreSQLには実装されている。

地図を使ったWebアプリケーションはまだまだAPIの利用程度にしか収まっていないが、モジュールやソースが出揃ってくれば一般的に使われる日も近い気がする。

設定テーマ

注目テーマ 一覧

月別リンク

トラックバック(0件)

タイトル (本文) ブログ名/日時

トラックバック用URL help


自分のブログにトラックバック記事作成(会員用) help

タイトル
本 文

コメント(0件)

内 容 ニックネーム/日時

コメントする help

ニックネーム
本 文
WEB技術関連
EC-CUBE関連
ソフトウェア関連