【外部APIまとめ】4つの地点取得系APIの特徴と限界を知る

# 目的
現在地を元にランダムに地点`（市区町村）`を指定して提案するアプリケーションの作成を考えている。外部APIを利用して現在地に近い市区町村を取得できないか調べたい。また、現在地から提案する地点までの距離も取得したい。APIには4つほど候補があるため、各APIの特徴（リクエスト・レスポンスの中身）と限界をまとめたい。

# 4つのAPIの候補

- RESAS-API
- GeoDB Cities
- Google Maps Distance Matrix API
- Google Places API Web Service

## RESAS-API

市区町村の情報を取得できるが、国内の情報のみ。市区町村の位置情報はレスポンスされない。

## GeoDB Cities

国内だけでなく国外の都市情報を取得できる。都市名だけでなく緯度経度を取得できるほか、特定の緯度経度をリクエストし、近い地点の都市情報を取得することも可。ただし、`languageCode`で`ja`を指定すれば日本語で結果が返ってくるはずだが、400エラーが返ってくる（おそらく日本語は未対応？）。また、`City Distance`を使用すれば、都市間の距離を返すことも可能。

## Google Maps Distance Matrix API

開始地点と終了地点を指定することで、距離と到着までの時間を算出することが可能。「現在地の緯度経度」を「開始地点」に、「地点」を「終了地点」に設定すれば、現在地から提案する地点までの距離を算出することができる。

## Google Places API Web Service

施設名がレスポンスで返却される。
	
## 対応表

|API名|料金|機能|国内対応|国外対応|備考|
|---|---|---|---|---|---|
|RESAS-API|無料|市区町村|◯|✕||
|GeoDB Cities|$10-25/月|市区町村|◯|◯|区の情報も取得できる|
|Google Maps Distance Matrix API|$5/1000回|距離算出|◯|◯|時間も算出可|
|Google Places API Web Service|$20/1000回|施設|◯|◯||

# 結論：地点名・緯度経度は「GeoDB Cities」で、現在地からの距離は「Google Maps Distance Matrix API」で取得

- `RESAS-API`は市区町村の情報を取得できるが、位置情報が取得できないのでNG。また、`Google Places API Web Service`は市区町村ではなく施設名を取得するAPIなのでNG。
- `GeoDB Cities`を使えば、特定の緯度経度（現在地等）を元に市区町村名を返す動きを実装できる。また、現在地から特定の地点までの距離は`Google Maps Distance Matrix API`の利用で算出可能。
- 一方、`GeoDB Cities`は日本語対応がされていないようなので、別途対応が必要。

# RESAS-API

## 機能の種類
- 都道府県一覧
- 市区町村一覧

## リクエスト
### 都道府県一覧
なし
### 市区町村一覧
- `prefCode`：都道府県コード

### レスポンス例
```都道府県一覧.json
    {
        "message": null,
        "result": [{
            "prefCode": 1,
            "prefName": "北海道"
        }, {
            "prefCode": 2,
            "prefName": "青森県"
        }
        }]
    }
```

```市区町村一覧.json
    {
        "message": null,
        "result": [{
            "prefCode": 1,
            "cityCode": "01100",
            "cityName": "札幌市",
            "bigCityFlag": "2"
        }, {
            "prefCode": 1,
            "cityCode": "01101",
            "cityName": "札幌市中央区",
            "bigCityFlag": "1"
        }
        }]
    }
```

# GeoDB Cities

## 機能の種類

- Cities
- City Distance

## リクエスト

### Cities
- `limit`：取得する結果の最大数
- `countryIds`：国コード
- `includeDeleted`：削除済みとマークされた都市を含めるかどうか
- `minPopulation`：最少人口数
- `namePrefix`：名前がこの接頭辞で始まる都市を表示
- `location`：緯度 / 経度
- `radius`：検索する半径
- `distanceUnit`：使用する距離の単位：MI | KM
- `offset`：The zero-ary offset into the results
- `excludedCountryId`：入力された国以外の都市を検索
- `sort`：結果をソートする方法（±SORT_FIELD,±SORT_FIELD where SORT_FIELD = countryCode | elevation | name | population）
- `timeZoneIds`：指定のタイムゾーンの都市を検索
- `asciiMode`：ASCII文字を使用して結果を表示するかどうか
- `languageCode`：指定の言語で検索結果を表示
- `hateoasMode`：HATEOAS（レスポンスに関連するリソースのURLを含める規約）を含むかどうか
- `types`：これらのタイプの都市のみ（コンマ区切り）表示：CITY | ADM2

### City Distance

- `fromCityId`：街からの距離
- `cityid`：都市ID
- `distanceUnit`：距離の単位：KM | MI (デフォルト)

## レスポンス例
```Cities.json
{3 items
    "data":[5 items
    0:{10 items
    "id":69551
    "type":"CITY"
    "city":"Abashiri"
    "name":"Abashiri"
    "country":"Japan"
    "countryCode":"JP"
    "region":"Hokkaidō Prefecture"
    "regionCode":"01"
    "latitude":44.02127
    "longitude":144.26971
}
```

```City_Distance.json
{1 item
    "data":13.8
}
```

# Google Maps Distance Matrix API
## リクエスト
### 必須
- `origins`：移動距離と移動時間を計算するための開始点。
- `destinations`：移動距離と移動時間を計算するための終点として使用する1つ以上の場所。
- `key`：アプリケーションのAPIキー。

### オプション（抜粋）
- `mode`：輸送モード。
- `language`：結果を返す言語。
- `region`：国コード。

## レスポンス例

```json
{
    "status": "OK",
    "origin_addresses": ["Vancouver, BC, Canada", "Seattle, État de Washington, États-Unis"],
    "destination_addresses": ["San Francisco, Californie, États-Unis", "Victoria, BC, Canada"],
    "rows": [{
        "elements": [{
            "status": "OK",
            "duration": {
                "value": 340110,
                "text": "3 jours 22 heures"
            },
            "distance": {
                "value": 1734542,
                "text": "1 735 km"
            }
        }]
    }]
}
```

# Google Places API Web Service
## 機能の種類
- Nearby Search requests
## リクエスト
### 必須
- `key`：APIキー。
- `location`：場所情報を取得する緯度/経度。
- `radius`：場所の結果を返す距離をメートル単位で定義（最大半径50km）。

### Option（抜粋）
- `keyword`：検索用のキーワード。
- `language`：結果を返す言語。
- `minprice`および`maxprice`：価格帯。
- `opennow`：営業中のみに絞るかどうか。

## レスポンス例

```Nearby_Search_requests.json
{
    "html_attributions": [],
    "results": [{
        "geometry": {
            "location": {
                "lat": -33.870775,
                "lng": 151.199025
            }
        },
        "icon": "http://maps.gstatic.com/mapfiles/place_api/icons/travel_agent-71.png",
        "id": "21a0b251c9b8392186142c798263e289fe45b4aa",
        "name": "Rhythmboat Cruises",
        "opening_hours": {
            "open_now": true
        },
        "photos": [{
            "height": 270,
            "html_attributions": [],
            "photo_reference": "CnRnAAAAF-LjFR1ZV93eawe1cU_3QNMCNmaGkowY7CnOf-kcNmPhNnPEG9W979jOuJJ1sGr75rhD5hqKzjD8vbMbSsRnq_Ni3ZIGfY6hKWmsOf3qHKJInkm4h55lzvLAXJVc-Rr4kI9O1tmIblblUpg2oqoq8RIQRMQJhFsTr5s9haxQ07EQHxoUO0ICubVFGYfJiMUPor1GnIWb5i8",
            "width": 519
        }],
        "place_id": "ChIJyWEHuEmuEmsRm9hTkapTCrk",
        "reference": "CoQBdQAAAFSiijw5-cAV68xdf2O18pKIZ0seJh03u9h9wk_lEdG-cP1dWvp_QGS4SNCBMk_fB06YRsfMrNkINtPez22p5lRIlj5ty_HmcNwcl6GZXbD2RdXsVfLYlQwnZQcnu7ihkjZp_2gk1-fWXql3GQ8-1BEGwgCxG-eaSnIJIBPuIpihEhAY1WYdxPvOWsPnb2-nGb6QGhTipN0lgaLpQTnkcMeAIEvCsSa0Ww",
        "types": ["travel_agency", "restaurant", "food", "establishment"],
        "vicinity": "Pyrmont Bay Wharf Darling Dr, Sydney"
    }],
    "status": "OK"
}
```

# 参照

- [GeoDB Cities：ドキュメント (wirefreethought) | Rakuten RapidAPI](https://api.rakuten.net/wirefreethought/api/geodb-cities?endpoint=5978313be4b06b85e4b0da1e)
- [Place Search  |  Places API  |  Google Developers](https://developers.google.com/places/web-service/search#PlaceSearchRequests)
- [RESAS-API - 地域経済分析システム（RESAS）のAPI提供情報](https://opendata.resas-portal.go.jp/)
- [Developer Guide  |  Distance Matrix API  |  Google Developers](https://developers.google.com/maps/documentation/distance-matrix/intro)