ジオポの地図表示で住所を出したかったので逆ジオコーディング(緯度・経度から住所を取り出すこと)をGoogleのAPI使ってやってみました。
まず基本
Google MapsのAPIと違って、日本語での情報が少ない(マニュアル)けど、
Error 404 (Not Found)!!1
URLはこのサンプルみたいにして、HTTP GETでXMLが取得できる。
リクエストパラメーター
ll | 緯度・経度(qでもいいと思う。違いがわからないよ><) |
output | xml、kml、cvs、json |
key | Google maps APIキー |
hl | 言語(日本語だとja、英語ならen)。住所記述方法にも影響 |
oe | 文字エンコード |
レスポンス(XMLをsimple_xmlでパースした場合)
$parsed_xml ->Response->Status->code | ステータスコード |
$parsed_xml ->Response->Placemark | Arrayで結果が複数入る |
以下 Placemark[0]が親とする | |
AddressDetails[‘Accuracy’] | 精度。後述 |
address | 住所。言語によって記述方法が変化。日本語だと[県][市][町] って具合だけど、英語だと [Street], [City], [Prefecture] あと、住所には国名が含まれる。 |
AddressDetails->Country ->CountryNameCode | 国のコード。JP |
AddressDetails->Country ->CountryName | 日本 |
AddressDetails->Country ->AdministrativeArea ->AdministrativeAreaName | 東京都 |
AddressDetails->Country ->AdministrativeArea ->Locality ->LocalityName | 渋谷区 |
AddressDetails->Country ->AdministrativeArea ->Locality ->DependentLocality ->DependentLocalityName | 渋谷 |
AddressDetails->Country ->AdministrativeArea ->Locality ->DependentLocality ->Thoroughfare ->ThoroughfareName | 1丁目26 |
AddressDetails->Country ->AdministrativeArea ->Locality ->DependentLocality ->PostalCode ->PostalCodeNumber | 日本だと取れない。アメリカだけかな? |
基本的に詳細な住所ほど、先頭にくるのでPlacemark[0]を見れればokとか考えていたらハマった。
なぜか道路の名前を返す、素敵なリバースジオコーダ-
ときどき、住所がとれなくて変だな?っておもってよくみると「国道1号」みたいに道の名前が配列の先頭にきてた。他にも郵便番号がとれたりする。
そんな道の名前なんか知りたくないので、どうするかというと、Accuracyで判別してやる。
Accuracy
精度値 | 説明 |
0 | どこそこ |
1 | 国レベル |
2 | 州、都道府県レベル |
3 | カウンティレベル |
4 | 市町村レベル |
5 | 郵便番号レベル |
6 | 道レベル |
7 | 交差点レベル |
8 | 街区レベル |
9 | ビル名、店名 |
つまり、Accuracyが5とか6のはいらない子なので、ループ回してcontinueとかでスキップすればいい。
これだけに注意しておけば、世界中の逆ジオコーディングがお手軽にできるので、Google APIはとっても魅力的。あと、住所ってそんなに頻繁に変わらないのでキャッシュしておくのは必須かと。
僕は、多言語対応させるために、ジオポコード(バイナリvarcharに注意)と言語をキーにしてキャッシュするようにしました。
住所の記述方法の切り分けは、日本式がそのままくっつける、アメリカ式は反転してから’, ‘をつけて生成みたいな形。
$address = array (); if ($location['scale'] >= 6) { $address[] = $reverse_geocode['administrative_area_name']; $address[] = $reverse_geocode['locality_name']; $address[] = $reverse_geocode['dependent_locality_name']; $address[] = $reverse_geocode['thoroughfare_name']; } elseif ($location['scale'] >= 4) { $address[] = $reverse_geocode['administrative_area_name']; $address[] = $reverse_geocode['locality_name']; $address[] = $reverse_geocode['dependent_locality_name']; } elseif ($location['scale'] >= 2) { $address[] = $reverse_geocode['administrative_area_name']; $address[] = $reverse_geocode['locality_name']; } else { $address[] = $reverse_geocode['administrative_area_name']; } // 日本式とアメリカ式の住所表記 if ($this->config->item('language_min') == 'ja') { $result = implode($address); } else { $address = array_reverse($address); $result = implode(', ', $address); }
ソースにすると↑。ジオポの縮尺が曖昧になっていく度に、住所も曖昧になる。