Google Mapsの逆ジオコーディングAPI,基本的な知識3つ

最近本業と関係ないことばかりメモっている気がする.研究しろよM2.

Google Mapに緯度経度から地名を引くことができる逆ジオコーディングAPIがあることを以前書いたxml/kml/JSON/csv形式のいずれかをoutputパラメータで指定する.
Google Maps JavaScript API V2 Services - Google Maps JavaScript API v2 (Deprecated) — Google Developers
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">
...

これに関して少しメモ書き.

(1)複数の逆ジオコーディング候補が(だいたい)精度の高い順に返る

Placemark p1,p2,p3...みたいな感じで候補が幾つか返ってくる.んでAccuracyを見ると,各Placemarkがどの程度の精度なのかを知ることができる.一般にAccuracyの高い順にplacemark idが振られているよう.

参考:Googleの逆ジオコーディングをためしてみた | クレコ

Accuracy 詳しさ
0 どこそこ
1 国レベル
2 州、都道府県レベル
3 カウンティレベル
4 市町村レベル
5 郵便番号レベル
6 道レベル
7 交差点レベル
8 街区レベル
9 ビル名、店名

Accuracyが高いからと言って,必ずしも上位のplacemarkが下位のものより優れているとも言い切れない.たとえば以下のような場合,「国道471号線」と「岐阜県飛騨市神岡町数河」のどちらが情報として有用かどうかはアプリケーションによるだろう.

<?xml version="1.0" encoding="UTF-8" ?>
<kml xmlns="http://earth.google.com/kml/2.0"><Response>
  <name>36.300000,137.350000</name>
  <Status>
    <code>200</code>
    <request>geocode</request>
  </Status>
  <Placemark id="p1">

    <address>日本, 国道471号線</address>
    <AddressDetails Accuracy="6" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>JP</CountryNameCode><CountryName>日本</CountryName><Thoroughfare><ThoroughfareName>国道471号線</ThoroughfareName></Thoroughfare><AddressLine>国道471号線</AddressLine></Country></AddressDetails>
    <ExtendedData>
      <LatLonBox north="36.3024520" south="36.2961567" east="137.3537382" west="137.3474430" />
    </ExtendedData>
    <Point><coordinates>137.3506452,36.2996171,0</coordinates></Point>

  </Placemark>
  <Placemark id="p2">
    <address>日本, 岐阜県飛騨市神岡町数河</address>
    <AddressDetails Accuracy="4" 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></DependentLocality></Locality></AdministrativeArea></Country></AddressDetails>
    <ExtendedData>
      <LatLonBox north="36.3086871" south="36.2933460" east="137.3659242" west="137.3265872" />

    </ExtendedData>
    <Point><coordinates>137.3364505,36.3007880,0</coordinates></Point>
  </Placemark>

(2)海や南極に対しては602を返す

海上や南極の座標を投げると,602(G_GEO_UNKNOWN_ADDRESS)が返ってくる.残念ながら海の名前とかは出してくれない.カスピ海とか大きな湖でも同様.琵琶湖程度のサイズだと近場の陸地にヒットするけど.

(3)でも海岸沿いだとAccuracy=1(つまり国名レベル)の結果を返す


こういう陸地に近い場所を指定すると

<?xml version="1.0" encoding="UTF-8" ?>
<kml xmlns="http://earth.google.com/kml/2.0"><Response>
  <name>36.600000,136.500000</name>
  <Status>
    <code>200</code>
    <request>geocode</request>
  </Status>
  <Placemark id="p1">

    <address>日本</address>
    <AddressDetails Accuracy="1" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>JP</CountryNameCode><CountryName>日本</CountryName></Country></AddressDetails>
    <ExtendedData>
      <LatLonBox north="44.8679299" south="26.4661367" east="154.6445259" west="121.8613221" />
    </ExtendedData>
    <Point><coordinates>138.2529240,36.2048240,0</coordinates></Point>
  </Placemark>

</Response></kml>

こんな感じで日本、とだけ返ってくる.領海を計算しているのかと思いきや,そんなにきっちり判定しているようにも見えない*1.とりあえず「陸地に近いと国名のみ返す」、あるいは「Accuracy=1がPlacemark=p1にセットされて返ってきた場合は,海岸あたりを指定している可能性がある」という感じ(きっちりとは検証していないが).

人工衛星botの場合

人工衛星bot(@XI_V)の場合は、衛星の現在地をAPIに投げて国名だけ返ってきた場合には,陸地が近いと判断しAccuracy>3の結果が得られるまで近傍を探索するようにしている(その場合つぶやきは「現在地:日本 福岡県福岡市近海」のような表現になる).なんせ秒速7kmで飛んでいるので、精度に固執するよりも具体的な地名をつぶやくことを重視したほうが面白いだろうという判断.あとは海の名前も欲しかったので,こちらはローカルに以下のようなデータセットを200行ほど持っておき,APIから602が返ってきたときにはこの中から最も近い座標を参照している.

49.8 141.64 日本海
51.12 141.59 日本海
35.76 135.7 日本海
34.5 129.7 対馬海峡
33.87 128.75 対馬海峡
34.7 123.44 黄海
37.125 125.15 黄海
39.13 124.84 黄海
34.23 123 黄海
31.31 125.02 東シナ海
29.61 128.54 東シナ海
30.06 131.13 太平洋
28.92 130.34 太平洋
27.8 129.46 太平洋

世界中の海に対してデータを用意するのは骨が折れるけど,現在は日本近海でしか撮影,運用を行わないのでとくに問題無い.海の名前まで出してくれる逆ジオコーディングサービスが欲しい.

*1:日本の場合領海は原則的に基線から12海里=22.2kmだけど、逆ジオコーディングで日本周辺をざっと見ると陸地から12kmくらいに国名を表示する判定の境目があるようだ