|
|||||
|
対象: ジオコーディング(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]
|
|||||