November 12, 2008
携帯GPSの緯度、経度情報から「文字の住所」を引くのが逆ジオコーディング(リバースジオコーディング)
Google Maps apiに新たに追加された逆ジオコーディングは、モバツイッターのイマココにとっては待ってました!的なサービスで、公開されたことを聞きつけたその日に組み込んだのですが、どうも取れない住所があるとのことで、多くの人の力を借りてテストしているので、ここに公開しておきます。
まずこんな感じのURLに、latとlonに緯度と経度をそれぞれ渡してGoogleに問い合わせる。
http://maps.google.com/maps/geo?output=xml&oe=utf-8&ll=${lat}%2C${lon}&key=${apikey}
すると、まぁ普通は、こんな感じのレスポンスが返ってくるわけですよ。
<kml xmlns="http://earth.google.com/kml/2.0"><Response>
<name>xx.xxxxx,xxxx.xxxxxx</name>
<Status>
<code>200</code>
<request>geocode</request>
</Status><Placemark id="p1">
<address>Japan東京都渋谷区宇田川町40?5</address>
<AddressDetails Accuracy="8" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
<Country>
<CountryNameCode>JP</CountryNameCode>
<CountryName>Japan</CountryName>
<AdministrativeArea>
<AdministrativeAreaName>東京都</AdministrativeAreaName>
<Locality><LocalityName>渋谷区</LocalityName>
<DependentLocality>
<DependentLocalityName>宇田川町</DependentLocalityName>
</DependentLocality>
</Locality></AdministrativeArea></Country>
</AddressDetails>
<Point><coordinates>xx.xxx.,xxxxxx</coordinates>
</Point>
</Placemark>
<Placemark id="p2">
<address>Japanジーンズメイト・渋谷東急ハンズ前店</address>
<AddressDetails Accuracy="9" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
<Country>
<CountryNameCode>JP</CountryNameCode>
<CountryName>Japan</CountryName>
</Country>
</AddressDetails>
<Point>
<coordinates>xxxx,xxx,xxxx</coordinates>
</Point>
</Placemark>
・
・
・
故にこんな感じの関数でさくっと住所を取ってました。
require_once "HTTP/Request.php";
$api_url ="http://maps.google.com/maps/geo?output=xml&oe=utf-8&ll=${lat}%2C${lon}&key=${apikey}";$req =& new HTTP_Request($api_url);
if (!PEAR::isError($req->sendRequest())) {
$ret = $req->getResponseBody();
}else{
return false;
}
if (isset($ret)){
try{
$areas = new SimpleXMLElement($ret);
}catch(Exception $e){}
}
if (!isset($areas) || !$areas || $areas->Error){
return false;
}if (isset($areas->Response->Placemark->AddressDetails->Country->AdministrativeArea->AdministrativeAreaName)){
$pref = strval($areas->Response->Placemark->AddressDetails->Country->AdministrativeArea->AdministrativeAreaName);
}else{
$pref = '';
}
if (isset($areas->Response->Placemark->AddressDetails->Country->AdministrativeArea->Locality->LocalityName)){
$city = strval($areas->Response->Placemark->AddressDetails->Country->AdministrativeArea->Locality->LocalityName);
}else{
$city = '';
}if (isset($areas->Response->Placemark->AddressDetails->Country->AdministrativeArea->Locality->DependentLocality->DependentLocalityName)){
$town = strval($areas->Response->Placemark->AddressDetails->Country->AdministrativeArea->Locality->DependentLocality->DependentLocalityName);
}else{
$town = '';
}
if (isset($areas->Response->Placemark->AddressDetails->Country->AdministrativeArea->Locality->Thoroughfare->ThoroughfareName)){
$town = strval($areas->Response->Placemark->AddressDetails->Country->AdministrativeArea->Locality->Thoroughfare->ThoroughfareName);
}else{
$town = '';
}
if (isset($areas->Response->Placemark->AddressDetails->Country->AdministrativeArea->Locality->DependentLocality->Thoroughfare->ThoroughfareName)){
$number = strval($areas->Response->Placemark->AddressDetails->Country->AdministrativeArea->Locality->DependentLocality->Thoroughfare->ThoroughfareName);
}else{
$number = '';
}$loc_data = array(
'lat'=>$lat,
'lon'=>$lon,
'pref'=>$pref ,
'city'=>$city,
'town'=>$town,
'number'=>$number);return $loc_data;
そしたらうまく表示されない場所があるとのこと。
そのためモバツイユーザーの方にご協力を仰いで、うまくいかない情報を教えてもらって、どんな情報が返ってきてるのか調べてみました。
まず、ダメなのはこんな感じ。
<?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://earth.google.com/kml/2.0"> <Response> <name>xxxx.xxxxx,xxx.xxxx</name> <Status> <code>200</code> <request>geocode</request> </Status> <Placemark id="p1"> <address>Japan阪神高速13号東大阪線</address> <AddressDetails Accuracy="6" xmlns="urn:oasis:names:tc:ciqxsdschema:xAL:2.0"> <Country> <CountryNameCode>JP</CountryNameCode> <CountryName>Japan</CountryName> <AddressLine>阪神高速13号東大阪線</AddressLine> </Country> </AddressDetails> <ExtendedData> <LatLonBox xmlns="http://maps.google.com/geo?output=kml"> <north>xx.xxxx</north> <south>xx.xxxx</south> <east>xx.xxxx</east> <west>xx.xxxx</west> </LatLonBox> </ExtendedData> <Point> <coordinates>xx.xxxx</coordinates> </Point> </Placemark> </Response> </kml>
は、阪神高速・・・・。
高速道路が捕捉されてしまうと、道路が優先されるらしい。
更に、最悪のケースだと、
<?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://earth.google.com/kml/2.0"> <Response> <name>xxxx,xxxxx</name> <Status> <code>200</code> <request>geocode</request> </Status> <Placemark id="p1"> <address>Japan東北自動車道</address> <AddressDetails Accuracy="6" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"> <Country> <CountryNameCode>JP</CountryNameCode> <CountryName>Japan</CountryName> <AddressLine>東北自動車道</AddressLine> </Country> </AddressDetails> <Point> <coordinates>xxxx,xxxx,0</coordinates> </Point> </Placemark> </Response> </kml>
東北自動車道ってどんな長さだよ。
高速道路が取れるのはそれはそれで嬉しいケースもあるでしょうが、できれば住所の付属情報に高速道路をぶら下げて欲しいところだし、何よりイマココでは嬉しくないので、結局、こういう情報が返ってきた場合は、他のサービスに取りに行かざるを得ない状況です。
(あんたはカーナビかいな。首都高の下にある道走ってたら高速乗っちゃってるーみたいな)
逆ジオコーディングは、以前は主に個人の方がご提供されていて、モバツイッターでもinvcoderというサービスを使わせていただいていたのですが、ある時期から連続で500エラーが出まくりになって、うわーこりゃ、どこかのサービスが負荷かけまくってるんだろうなぁとか思ってたのですが、残念ながらGoogleがダメだったら、invcoderに問い合わせて、それがダメなら、シリウスラボさんの逆ジオコーディングサービスに問い合わせに行くみたいな状態に戻っちゃいました。
一番近いの緯度経度情報を抽出するロジックのコードさえあれば自分で作るんですが。。(数式見たけど、難しくて意味がわからん)
ということで、低コストに利用可能な逆ジオコーディングの決定版もない状態、なのかな?!
##ていうかドキュメントも読まずに組み込んだので実はそうならないための引数とかあったらごめんなさい。
使いづらいには変わりないというオチですが、複数情報がとれるようですねー
検証されている方の日記がありました。
GoogleMapsAPI の逆ジオコーダー機能 ~続編~|創業日記
http://fairyware.jp/weblog/2008/11/googlemapsapi_2.html