この記事は最終更新日から1年以上が経過しています。

関連して以下も参考にしてください

まとめたこと

やりたい事ベースでざっくり分類

  1. 住所(地名) ⇔ 緯度/経度変換
  2. 地図上への位置情報のプロット
  3. 距離計算・ルーティング(緯度経度計算、2点間の距離を計測)

詳しく

住所(地名) ⇔ 緯度/経度変換

住所(地名)→緯度/経度の変換はジオコーディング(Geocoding)と呼ばれる。
(昔はアドレスマッチングとも呼ばれていたらしい)
緯度/経度→住所(地名)の変換は逆ジオコーディング(Reverse Geocoding)アドレスマッチングと呼ばれる。

緯度はlatitude(lat)、経度はlongitude(lng)で各Web/APIドキュメントをみるとよく出てくる。
住所はaddressとかlocationと表現されることが多い。

ジオコーディングをプログラミングから使うときはRuby実装が有名。

オンプレミスでジオコーディングする上での障壁

上記のRuby実装は内部的にGoogle Geocoding APIをキックしている。
利用制限などを回避するため、オンプレミスでジオコーディング対応したくなるが難しい問題が立ちはだかる。

住所名の揺れ対応が難しい
「兵庫県XXX市1-2-3」 と 「ヒョウゴ県xxx市1丁目2番地3号」 を同じ緯度経度としたいが、名寄せ(データクレンジング)して同一視させるのは大変。

そのためのでGoogle Map APIに頼りたくなる
(名寄せについて、有料のプロダクトはあるがOSSは目ぼしいのが無いことも影響)

その他
一方、逆ジオコーディングでは、緯度経度の表記は基本的にブレないので名寄せをほぼ意識しなくて済む。

また、ある地点から半径XXXメートル以内のXXXの関連施設を検索したいといった場合には、2点間の緯度経度から距離を計算して関連施設の属性とともにフィルタリングして取得するクエリを発行することで実現する。

地図上への位置情報のプロット

言うにおよばずGoogle Map APIが有名。
マーカーピンをたてたり、吹き出しを作ったり、エリアに色を塗ったり…
こちらについては各サービスごとのAPIを覚えてJSで作業させる。

距離計算

地球は丸いので、2点間の緯度経度から三角関数で単純に距離を出してはダメらしい。
理由は直線だと地中を通ってしまうことになるから(・・・!!)

以下の記事は上記のことをわかりやすく説明していた

緯度経度から距離の計算はヒュベニの公式というのを用いて簡単に計算できるらしい。
難しそうな数式が並ぶ‥。

通常のアプリであれば、Postgre拡張のPostGISにあるdistance関数などで計算させることが多そう。
以下は「PostGISを使って検索してみる」ということで様々なクエリが記載されてた

ルーティング

実際の道路や高低差を意識した経路選択の話。
アルゴリズム的には最短経路問題になる。

もっと詳しく

ジオコーディング

地名や建物名(例:東京タワー)から緯度・経度を検索すること。
GoogleのGeocodingやYahoo!のジオコーダAPIが有名。
オープンなものとしてはOpen Street Mapというものががある。

GoogleやYahoo!が提供してくれるAPIは、情報が豊富でリッチな機能があり簡単に使えると非常に人気だが、利用回数などの制限がネック。

各サービス特徴メモ

ザックリ読むだけで流れと注意点がわかる。

】Google Geocoding API

無料API
2500回/24時間まで
5回/1秒まで
Googleマップを使わずGeocodingだけ用いるのは規約的にNG。

有償版コースもあり。

】Yahoo!ジオコーダAPI

無料API
50,000回/1日まで

  • アプリケーションの登録は10個まで可能。
  • 午前0:00に利用回数がリセットされる。

OSM(OpenStreetMap)

ユーザ編集型の地図データのこと。
Wikipediaのようにユーザ自身がGPSログをアップロードしたりベクトルデータを編集可能。
ForesquareというWebサービスのバックエンドで使われているみたいです。

OSMの環境構築

利用できるAPI

以下にまとめられていた。
自前サーバを構築もできるが、公開用のサーバがありアクセスが出来る。
OSMのデータにはOverpassというAPIを用いてアクセスするらしい。

利用制限

1日に合計おおよそ1,000,000リクエスト。
余り他のユーザに迷惑をかけないように、ということらしい。

機能

地図をズームしたり、マーカーを立てるなど基本操作は出来る。

その他参考情報

ルーティング

緯度経度からの距離計算では、実際の建物や道路を無視しているので現実的には精度が低い。
そのため、道路や建物の地図情報を元に経路を計算することが必要。

OSRM(Open Source Routing Service)

環境構築

利用API

中を見ると大体やりたいことは網羅している。

serviceDescriptioneg
viaroute最短経路の検索http://{server}/viaroute?loc={lat,lon}&loc={lat,lon}<&loc={lat,lon} ...>
nearest最も近い道路のセグメントを取得http://{server}/nearest?loc={lat,lon}
locate最も近いノードを取得http://{server}/locate?loc={lat,lon}
table距離の組み合わせ計算http://{server}/table?loc={lat,lon}&loc={lat,lon}<&loc={lat,lon} ...>
matchGPS情報から最適のルートを実施http://{server}/match?loc={lat,lon}&t={timestamp}&loc={lat,lon}&t={timestamp}<&loc={lat,lon}&t={timestamp} ...>

OSRMのデータ構造

道路交通情報

OSRMは道路工事や道路渋滞の情報が考慮されていないので、現実には精度が低下する(はず)。
また、車での情報しか存在しなかったため、徒歩を含めたその他の交通期間での移動時間は考慮出来ていない。
(取り込みファイルには.carみたいなサフィックスが付いていたので、徒歩情報も作成すれば対応出来そうではある)

データ取得元

技術要素

GIS

データ型

GeoJSON(Geometry JSON)

GeoJSONを用いれば、緯度経度だけではなく店舗の営業時間や地理情報も設定できるらしいので、地図に独自の情報を付けて付加価値を高めるサービスを作るときは必要になってくるとのこと。

Shape(シェープ)ファイル

GIS業界の標準フォーマットらしいので、国などでDLすると大体このフォーマットになっている。
ShapeファイルからGeoJSONへの変換は調べるとよく出てくる。

PostGIS

他にもPostgreSQLにはPostGISという拡張モジュールがあり、これで距離系のデータが上手く扱える。
ざっくりというと緯度経度を保持するデータ型があり、そこから上手く距離を計算したクエリがかける。

ビジュアライズ

地図情報をD3.jsを用いて描画する先人も。凄い。

まとめ

基本的にGoogleのGeocodingを使えば問題なし。
利用制限に引っかかったらYahooo!のジオコーダAPIを使いましょう。
それすら超過しそうなら自前で準備しましょう