Goalist Developers Blog

【GoogleMapsAPI】Javaで住所から緯度経度を取得する

こんにちは。ゴーリスト開発の飯尾です。

住所から緯度経度を割り出そ〜というときにはどうしたものか。

国交省のデータを使うという手もありますが
田舎は詳細データなくてちょっと精度がこころもとないし、
表記ぶれにも弱くて使いづらいところがあります。

そこで天下のGoogle御大よ
GoogleMapsAPIのジオコーダーを使うとかんたんに詳細な緯度経度を取得できます。

そんなわけでJavaで住所から緯度経度を取得する方法のメモです。

手順

  1. APIキーを取得
  2. GoogleMapsAPIのJavaクライアントライブラリを入れる
  3. つかう

説明

1. APIキーを取得

以下リンクからはじまり
キーの取得、認証  |  Google Maps Geocoding API  |  Google Developers

「キーを取得する」ボタンをポチッとな
f:id:y-iio:20171012184920p:plain

てきとうなプロジェクト名で登録
f:id:y-iio:20171012185007p:plain

取得完了
f:id:y-iio:20171012185113p:plain

やったね

2. GoogleMapsAPIのJavaクライアントライブラリを入れる

公式がライブラリ出しているので遠慮なく使わしてもらう

Google マップ ウェブサービスのクライアント ライブラリ  |  Google マップ ウェブサービス API  |  Google Developers

github.com

GradleプロジェクトなんでMavenからひっぱってきました

build.gradle

dependencies {
    compile 'com.google.maps:google-maps-services:0.2.2'
    compile 'org.slf4j:slf4j-nop:1.7.25'
}

3. つかう

雑だけどこんなんでいけるんじゃないか

public class Geocoder {

    private static GeoApiContext context = new GeoApiContext.Builder()
            .apiKey("YOUR_API_KEY") // さっき取得したAPIキー
            .build();

    public static void main(String[] args) {
        GeocodingResult[] resluts = getResults("東京都千代田区神田須田町1-18");
        if (results != null && results.length > 0) {
            LatLng latLng = results[0].geometry.location; // とりあえず一番上のデータを使う
            System.out.println("緯度 : " + latLng.lat);
            System.out.println("経度 : " + latLng.lng);
        }
    }

    public static GeocodingResult[] getResults(String address) throws ApiException, InterruptedException, IOException {
        GeocodingApiRequest req = GeocodingApi.newRequest(context)
                .address(address)
                // .components(ComponentFilter.country("JP"))
                .language("ja");

        try {
            GeocodingResult[] results = req.await();
            if (results == null || results.length == 0) {
                // ZERO_RESULTSはresults.length==0の空配列がsuccessful扱いで返ってくるっぽい
                System.out.println("zero results.");
            }
            return results;
        } catch (ApiException e) {
            // ZERO_RESULTS以外のApiExceptionはこっちで
            System.out.println("geocode failed.");
            System.out.println(e);
            return null;
        } catch (Exception e) {
            System.out.println("error.");
            System.out.println(e);
            return null;
        }
    }

}

所感

きになったところ

その1

ステータスコードZERO_RESULTSのときは
ApiExceptionにひっかからないで空の配列が返ってくるっぽかった

その2

GeocodingApiRequest でコンポーネントフィルタかけてリザルトを国内のみに限定したら
.components(ComponentFilter.country("JP"))のところ)
ヘンテコな住所送った時にZERO_RESULTSにならずに
「日本」のジオコード結果が返ってきてしまって不便だったのでコメントアウトしている…

よいところ

その1

リザルトオブジェクトとか用意してくれてるのがうれし〜

その2

プレミアムプランのときの認証が楽
リクエストURL署名までしてくれるのがうれし〜

一言

快適なジオコーディングでQOLをあげていく( ◜◡^)

おわり