Google Maps APIで逆ジオコーディング

座標情報(緯度経度とか)を住所に変換することを逆ジオコーディングと言うらしい.ちょっとbotに使いたいので,Google Maps APIで遊んでみる.

Google Maps JavaScript API V2 Services - Google Maps JavaScript API v2 (Deprecated) — Google Developers

たとえばこんなリクエストを投げる.

http://maps.google.com/maps/geo?ll=35,135&output=xml&key=GOOGLE_MAPS_API_KEY&hl=ja&oe=UTF8
=の部分に緯度,経度を入れるだけ.何かこんなXMLが返ってきた.
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
  <Response>
    <name>35.000000,135.000000</name>
    <Status>
      <code>200</code>
      <request>geocode</request>
    </Status>
    <Placemark id="p1">
      <address>日本, 〒677-0024 兵庫県西脇市上比延町334</address>
      <AddressDetails Accuracy="8" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
        <Country>
          <CountryNameCode>JP</CountryNameCode>
          <CountryName>日本</CountryName>
          <AdministrativeArea>
            <AdministrativeAreaName>兵庫県</AdministrativeAreaName>
            <Locality>
              <LocalityName>西脇市</LocalityName>
              <DependentLocality>
                <DependentLocalityName>上比延町</DependentLocalityName>
                <Thoroughfare>
                  <ThoroughfareName>334</ThoroughfareName>
                </Thoroughfare>
              </DependentLocality>
            </Locality>
          </AdministrativeArea>
        </Country>
      </AddressDetails>
      <ExtendedData>
        <LatLonBox north="35.0030836" south="34.9967884" east="135.0019028" west="134.9956076" />
      </ExtendedData>
      <Point>
        <coordinates>134.9987552,34.9999360,0</coordinates>
      </Point>
    </Placemark>
    <Placemark id="p2">
      <address>〒677-0024</address>
      <AddressDetails Accuracy="5" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
...

んで,C#でこれを使ってみる.

using System.Xml;
using System.Xml.XPath;

namespace APITest
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load("http://maps.google.com/maps/geo?ll=35,135&output=xml&key=GOOGLE_MAPS_API_KEY&hl=ja&oe=UTF8");
            // ここですぐint statuscode = int.Parse(doc.DocumentElement.SelectSingleNode("//code").InnerText)とはできない!

            XmlNamespaceManager nmr = new XmlNamespaceManager(doc.NameTable);
            nmr.AddNamespace("p", "http://earth.google.com/kml/2.0");
            nmr.AddNamespace("n", "urn:oasis:names:tc:ciq:xsdschema:xAL:2.0");
 
            int statuscode = int.Parse(doc.DocumentElement.SelectSingleNode("//p:code",nmr).InnerText);
            string country = doc.DocumentElement.SelectSingleNode("//n:CountryName",nmr).InnerText;
        }
    }
}

SelectSingleNodeはxPathを引数にして要素を抽出できる関数だけど,今回のレスポンスみたくxmlnsで名前空間が指定されている場合はXmlNamespaceManagerであらかじめ登録したプレフィックスを追加してやる必要がある.xPathもSystem.Xmlまわりも理解が足りなくてたいへんアレだけど,これに例外処理を付け加えて取り敢えず動くものがでけた.
ちなみに海上とか,住所を特定できないような場所を投げると602が返ってくる.その他のステータスコードGoogle Maps JavaScript API V2 Reference - Google Maps JavaScript API v2 (Deprecated) — Google Developersに.

参考:
名前空間を指定してXPathを実行する。(XmlNamespaceManager, XmlReader, XPathDocument, XPathNavigator, Evaluate) - いろいろ備忘録日記