対象: ジオコーディング(Swift)ある地点の緯度、及び経度から住所等の馴染みのある情報を得る逆ジオコーディング(リバースジオコーディング)はCLGeocoderを使えば簡単にできる。CLGeocoderを使うためには、まずCoreLocationをimportする必要がある。 import CoreLocation それからCLGeocoderのインスタンスを生成し、逆ジオコーディングしたい位置情報をCLLocationにしてreverseGeocodeLocationメソッドに渡してリクエストするだけである。reverseGeocodeLocationメソッドに渡すハンドラには、逆ジオコーディングされた結果がCLPlacemarkの配列として返されるので、その最初の要素を参照すれば良い。 let geocoder = CLGeocoder() // 千葉駅 let location = CLLocation(latitude: 35.613203, longitude: 140.113544) geocoder.reverseGeocodeLocation(location) { (placemarks, error) in if let placemarks = placemarks { if let pm = placemarks.first { print("name: \(pm.name ?? "")") print("isoCountryCode: \(pm.isoCountryCode ?? "")") print("country: \(pm.country ?? "")") print("postalCode: \(pm.postalCode ?? "")") print("administrativeArea: \(pm.administrativeArea ?? "")") print("subAdministrativeArea: \(pm.subAdministrativeArea ?? "")") print("locality: \(pm.locality ?? "")") print("subLocality: \(pm.subLocality ?? "")") print("thoroughfare: \(pm.thoroughfare ?? "")") print("subThoroughfare: \(pm.subThoroughfare ?? "")") if let region = pm.region { print("region: \(region)") } if let timeZone = pm.timeZone { print("timeZone: \(timeZone)") } print("inlandWater: \(pm.inlandWater ?? "")") print("ocean: \(pm.ocean ?? "")") if let areasOfInterest = pm.areasOfInterest { print("areasOfInterest: \(areasOfInterest)") } } } } これを2018年1月にiOS 11で実行した結果が以下になる。いくつか関東のランドマーク的な場所を逆ジオコーディングしてみたが、国内だとnameには"〒"付きの郵便番号しか返ってこないようだ。 name: 〒260-0031 isoCountryCode: JP country: 日本 postalCode: 260-0031 administrativeArea: 千葉県 subAdministrativeArea: locality: 千葉市中央区 subLocality: 新千葉 thoroughfare: 新千葉1丁目 subThoroughfare: 1 region: CLCircularRegion (identifier:'<+35.61320300,+140.11354400> radius 70.87', center:<+35.61320300,+140.11354400>, radius:70.87m) timeZone: Asia/Tokyo (current) inlandWater: ocean: しかし、同じ座標を2019年5月にiOS 12で逆ジオコーディングしてみたところ、以下のようにnameには郵便番号ではなく普通の住所が返ってきた。subThoroughfareも以前に実行した場合と変わっている。iOS 11の別端末でも同じように住所が返ってきたので、iOSが新しくなった結果というわけではないようだ。 name: 新千葉1丁目1-1 isoCountryCode: JP country: 日本 postalCode: 260-0031 administrativeArea: 千葉県 subAdministrativeArea: locality: 千葉市中央区 subLocality: 新千葉 thoroughfare: 新千葉1丁目 subThoroughfare: 1-1 region: CLCircularRegion (identifier:'<+35.61320300,+140.11354400> radius 70.87', center:<+35.61320300,+140.11354400>, radius:70.87m) timeZone: Asia/Tokyo (current) inlandWater: ocean: 更に、例えば東京ディズニーランド等では特定のnameが返ってくるようになった。2019年5月現在、他に上野恩賜公園、東京スカイツリータウン等が特定のnameを返すことが確認できた。結果から察するに、特定のregionの範囲内の座標であれば、それと関連付けられたnameが返ってくるのではないだろうか。 name: 東京ディズニーランド isoCountryCode: JP country: 日本 postalCode: 279-0031 administrativeArea: 千葉県 subAdministrativeArea: locality: 浦安市 subLocality: 舞浜 thoroughfare: subThoroughfare: region: CLCircularRegion (identifier:'<+35.63290299,+139.88039500> radius 141.74', center:<+35.63290299,+139.88039500>, radius:141.74m) timeZone: Asia/Tokyo (current) inlandWater: ocean: areasOfInterest: ["東京ディズニーランド"] 因みに、iOS 11以降はreverseGeocodeLocationメソッドでLocaleを指定できるようになったので、"en_US"を指定してApple Park辺りの座標を逆ジオコーディングすると、以下のような結果が得られた。nameには"Apple Park"が返ってきている。 // Apple Park let location = CLLocation(latitude: 37.334902, longitude: -122.008872) // Localeでen_USを指定 geocoder.reverseGeocodeLocation(location, preferredLocale: Locale(identifier: "en_US")) { (placemarks, error) in // 処理は同じ } name: Apple Park isoCountryCode: US country: United States postalCode: 95014 administrativeArea: CA subAdministrativeArea: Santa Clara locality: Cupertino subLocality: Pruneridge Tantau thoroughfare: subThoroughfare: region: CLCircularRegion (identifier:'<+37.33490199,-122.00887200> radius 141.73', center:<+37.33490199,-122.00887200>, radius:141.73m) timeZone: America/Los_Angeles (fixed) inlandWater: ocean: areasOfInterest: ["Apple Park"] 住所からその地点の緯度、及び経度の情報を求める正ジオコーディングもCLGeoCoderを使えば簡単にできる。ジオコーディングしたい住所情報をCLLocationにしてgeocodeAddressStringメソッドに渡してリクエストするだけである。geocodeAddressStringメソッドに渡すハンドラには、ジオコーディングされた結果がCLPlacemarkの配列として返されるので、その要素を参照すれば良い。 ただし、正ジオコーディングの場合、住所情報から解決される座標が1つとは限らないことに注意する必要がある。geocodeAddressStringメソッドは、住所以外に例えば"〒260-0031"のような郵便番号、"千葉駅"等もジオコーディングできるようだ。 let geocoder = CLGeocoder() // 千葉駅 let place = "新千葉1丁目1-1" geocoder.geocodeAddressString(place) { (placemarks, error) in if let placemarks = placemarks { print("placemarks.count: \(placemarks.count)") for pm in placemarks { if let location = pm.location { print("latitude: \(location.coordinate.latitude)") print("longitude: \(location.coordinate.longitude)") } } } } placemarks.count: 1 latitude: 35.6128988 longitude: 140.1136959
(2018/01/28) () ジオコーディング結果の最新情報、正ジオコーディング情報追記。
Copyright© 2004-2019 モバイル開発系(K) All rights reserved.
[Home]
|