Edited at

初めて地図周りの技術に触れた時に作ったまとめ資料

More than 3 years have passed since last update.

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




まとめたこと

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


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

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

  3. 距離計算・ルーティング(緯度経度計算、2点間の距離を計測)


詳しく


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

住所(地名)→緯度/経度の変換はジオコーディング(Geocoding)と呼ばれる。

(昔はアドレスマッチングとも呼ばれていたらしい)

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

緯度はlatitude(lat)、経度はlongitude(lng)で各Web/APIドキュメントをみるとよく出てくる。

住所はaddressとかlocationと表現されることが多い。

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


Ruby geocoderがすごい

http://blog.mogya.com/2013/10/ruby-geocoder.html



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

上記のRuby実装は内部的にGoogle Geocoding APIをキックしている。

利用制限などを回避するため、オンプレミスでジオコーディング対応したくなるが難しい問題が立ちはだかる。

住所名の揺れ対応が難しい

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

そのためのでGoogle Map APIに頼りたくなる

(名寄せについて、有料のプロダクトはあるがOSSは目ぼしいのが無いことも影響)

名寄せ手法

以下の「Geocodingで自前のGISデータを作ってみよう 」は名寄せについて参考になる

https://codeiq.jp/magazine/2014/05/8400/

名寄せしなくて良い場合

住所の完全一致前提でシステム要件的に許容できれば国交省のデータを使うのがてっとり早い

http://qiita.com/laqiiz/items/842fe2a32e80bac92364

その他

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

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


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

言うにおよばずGoogle Map APIが有名。

マーカーピンをたてたり、吹き出しを作ったり、エリアに色を塗ったり…

こちらについては各サービスごとのAPIを覚えてJSで作業させる。


距離計算

地球は丸いので、2点間の緯度経度から三角関数で単純に距離を出してはダメらしい。

理由は直線だと地中を通ってしまうことになるから(・・・!!)

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


ジオグラフィ型というものがある - Qiita


緯度経度から距離の計算はヒュベニの公式というのを用いて簡単に計算できるらしい。

難しそうな数式が並ぶ‥。


http://yamadarake.jp/trdi/report000001.html


通常のアプリであれば、Postgre拡張のPostGISにあるdistance関数などで計算させることが多そう。

以下は「PostGISを使って検索してみる」ということで様々なクエリが記載されてた


https://sites.google.com/site/pcchatnetoiles/home/postgis/postgis-2



ルーティング

実際の道路や高低差を意識した経路選択の話。

アルゴリズム的には最短経路問題になる。


もっと詳しく


ジオコーディング

地名や建物名(例:東京タワー)から緯度・経度を検索すること。

GoogleのGeocodingやYahoo!のジオコーダAPIが有名。

オープンなものとしてはOpen Street Mapというものががある。

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


各サービス特徴メモ

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


各種ジオコーディングapiの罠と対処法

http://treeapps.hatenablog.com/entry/2012/11/17/%E5%90%84%E7%A8%AE%E3%82%B8%E3%82%AA%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0api%E3%81%AE%E7%BD%A0%E3%81%A8%E5%AF%BE%E5%87%A6%E6%B3%95



】Google Geocoding API

無料API

2500回/24時間まで

5回/1秒まで

Googleマップを使わずGeocodingだけ用いるのは規約的にNG。

有償版コースもあり。


https://developers.google.com/maps/documentation/geocoding/?hl=ja#Limits



】Yahoo!ジオコーダAPI

無料API

50,000回/1日まで


  • アプリケーションの登録は10個まで可能。

  • 午前0:00に利用回数がリセットされる。


http://developer.yahoo.co.jp/appendix/rate.html



OSM(OpenStreetMap)

ユーザ編集型の地図データのこと。

Wikipediaのようにユーザ自身がGPSログをアップロードしたりベクトルデータを編集可能。

ForesquareというWebサービスのバックエンドで使われているみたいです。


OSMの環境構築


利用できるAPI

以下にまとめられていた。

自前サーバを構築もできるが、公開用のサーバがありアクセスが出来る。

OSMのデータにはOverpassというAPIを用いてアクセスするらしい。


[OpenStreetMap] Overpass APIで地点検索 - Qiita

http://qiita.com/taku/items/f3c6ed375a2461551d7c



利用制限

1日に合計おおよそ1,000,000リクエスト。

余り他のユーザに迷惑をかけないように、ということらしい。


機能

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


その他参考情報

地図サービスの王Googleマップをじわじわと追いかけるOpenStreetMap - Gigazine

└ GoogleMapの有料化に伴いOSMにユーザが大量引っ越ししたとのこと

世界がOpenStreetMapを必要とする理由 - Qiita

└ 地図情報を特定の企業に独占させることの危険性

OpenStreetMap Japan

└ 日本語での情報提供や相互互助の支援を行っているサイト

  └ 定期的にマッピングパーティを行っている


ルーティング

緯度経度からの距離計算では、実際の建物や道路を無視しているので現実的には精度が低い。

そのため、道路や建物の地図情報を元に経路を計算することが必要。


OSRM(Open Source Routing Service)

有名ドコロにOSRMがある。

C++で実装されており、OSM(Open Street Map)のデータを利用している。

http://project-osrm.org/


環境構築

以前、インストール作業を以下にまとめた。

オープンソース地図アプリ(OSRM)のインストール - Qiita


利用API

OSRMのWeb/APIは以下のWikiに。

https://github.com/Project-OSRM/osrm-backend/wiki/Server-api

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

service
Description
eg

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} ...>

match
GPS情報から最適のルートを実施
http://{server}/match?loc={lat,lon}&t={timestamp}&loc={lat,lon}&t={timestamp}<&loc={lat,lon}&t={timestamp} ...>


OSRMのデータ構造

インストール時に作成するデータの説明は以下のWiki参照。

https://github.com/Project-OSRM/osrm-backend/wiki/Running-OSRM

グラフ情報については以下以下のWiki参照。

https://github.com/Project-OSRM/osrm-backend/wiki/Graph-representation


道路交通情報

OSRMは道路工事や道路渋滞の情報が考慮されていないので、現実には精度が低下する(はず)。

また、車での情報しか存在しなかったため、徒歩を含めたその他の交通期間での移動時間は考慮出来ていない。

(取り込みファイルには.carみたいなサフィックスが付いていたので、徒歩情報も作成すれば対応出来そうではある)

ちなみに日本で渋滞情報を取得しようとするとVICS(ビックスと読む)(Vehicle Information and Communication System)が有名。

http://vics.or.jp/about/index.html


データ取得元

国土数値情報 行政区域データ(shape形式)

http://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N03.html

国土交通省 国土情報課 位置情報参照サービス(CSV形式)

http://nlftp.mlit.go.jp/isj/

データの地番、街区、住所表示などの基礎知識は以下を参考に。

http://www.pasco.co.jp/recommend/word/word082/

https://ja.wikipedia.org/wiki/%E4%BD%8F%E6%89%80#.E6.97.A5.E6.9C.AC.E3.81.AB.E3.81.8A.E3.81.91.E3.82.8B.E4.BD.8F.E6.89.80.E3.81.AE.E8.A1.A8.E8.A8.98


技術要素


GIS

GISとは地理情報システム(GIS:Geographic Information System)のことで、地理的情報を視覚的に表示させる技術の総称とのこと。

http://www.gsi.go.jp/GIS/whatisgis.html

このページが簡単でわかりやすい。

http://www.gis.jacic.or.jp/gis/gakushu/whatisgis/whatisgis1.html


データ型


GeoJSON(Geometry JSON)

GeoJSON は様々な地理的データ構造を持つフォーマットで、最近GithubやGoogleでも利用できるようになっているデファクトスタンダードな存在。

仕様は (http://s.kitazaki.name/docs/geojson-spec-ja.html) で定義されている。

以下は簡単にGeoJSONについて説明してくれている。

http://blog.qaramell.com/?p=8191

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


Shape(シェープ)ファイル

「図形情報と属性情報をもった地図データファイル」が集まったデータファイル。

下記が詳しい。

http://www.pasco.co.jp/recommend/word/word028/

GIS業界の標準フォーマットらしいので、国などでDLすると大体このフォーマットになっている。

ShapeファイルからGeoJSONへの変換は調べるとよく出てくる。


PostGIS

他にもPostgreSQLにはPostGISという拡張モジュールがあり、これで距離系のデータが上手く扱える。

ざっくりというと緯度経度を保持するデータ型があり、そこから上手く距離を計算したクエリがかける。

PostGISのクエリでできることは下記でざっくりつかめる。

http://lets.postgresql.jp/documents/tutorial/PostGIS/1/

Oracleも11gリリース2からジオメトリ型データというのを使えるとのこと。

https://www.infoscoop.org/blogjp/2015/01/21/tutorial_for_geodb/


ビジュアライズ

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


D3.jsとOpen Data〜その1地図を描画する



まとめ

基本的にGoogleのGeocodingを使えば問題なし。

利用制限に引っかかったらYahooo!のジオコーダAPIを使いましょう。

それすら超過しそうなら自前で準備しましょう