MKReverseGeocoderでより精度の高い住所情報はMKPlacemark.addressDictionaryにあった!
先日MKReverseGeocoderの精度は決して高くなさそうだと書いたが、それは間違いだった。
琴線探査: iPhoneアプリでのより高精度な逆ジオコーディングを求めて・・・
より精度の高い住所情報は、MKPlacemark.addressDictionary.FormattedAddressLinesから取得できるとわかった。
日本中の色々な場所を出力させてみたが、国内の場合はMKPlacemarkの情報とFormattedAddressLinesの情報は違いはあるものの、大体似たような文字列が使われているので、フィルタリングすればMKPlacemarkのプロパティーで足りていない部分を判断して取得することができるだろう。
海外を出力させてみたところ、そもそも情報がなかったり必ずしもMKPlacemarkのプロパティーと対応していなかったり・・・と相当苦労しそうだ。
琴線探査: iPhoneアプリでのより高精度な逆ジオコーディングを求めて・・・
より精度の高い住所情報は、MKPlacemark.addressDictionary.FormattedAddressLinesから取得できるとわかった。
/**
*
* MKPlacemark.addressDictionaryから取得するFormattedAddressLinesを
* 一行の文字列として返す
*
*/
- (NSString *)getFormattedAddressLineFromPlacemark:(MKPlacemark *)pm {
//最終的な住所文字列
NSString *line = @"";
//まずはMKPlacemarkのプロパティーを出力
NSLog(@"MKPlacemark出力 thoroughfare=%@ subThoroughfare=%@ locality=%@ subLocality=%@ administrativeArea=%@ subAdministrativeArea=%@ postalCode=%@ country=%@ countryCode=%@",
pm.thoroughfare, pm.subThoroughfare, pm.locality, pm.subLocality,
pm.administrativeArea, pm.subAdministrativeArea, pm.postalCode,
pm.country, pm.countryCode);
//より詳細な住所はMKPlacemark.addressDictionaryに隠されている
NSDictionary *dict = pm.addressDictionary;
//for (id key in dict) {
// NSLog(@"key=%@ value=%@", key, [dict objectForKey:key]);
//}
//FormattedAddressLinesを一行の文字列に連結
//ドキュメントには明記されているところが見当たらないがFormattedAddressLinesは配列で返って来るらしい
NSArray *lines = [dict valueForKey:@"FormattedAddressLines"];
for (int i = 0; i < lines.count; i++) {
line = [line stringByAppendingFormat:@"%@ ", [lines objectAtIndex:i]];
}
//上で出力したプロパティーと比較して、こちらにだけ存在する情報があるとわかる
//(郵便番号や住所の末尾「-3」)
NSLog(@"%@:FormattedAddressLines出力 lines.count=%d", line, lines.count);
return line;
}
例えば、位置を国会議事堂として逆ジオコーディングを行い、その結果のMKPlacemarkをこのメソッドを使って出力するとこうなる。
MKPlacemarkのプロパティーの出力をFormattedAddressLines出力にできるだけ似せて書くとこうなる。MKPlacemark出力 thoroughfare=1丁目 subThoroughfare=7 locality=千代田区 subLocality=永田町 administrativeArea=東京都 subAdministrativeArea=(null) postalCode=(null) country=日本 countryCode=JP 日本 〒100-0014 東京都千代田区永田町1丁目7−1 :FormattedAddressLines出力 lines.count=2
日本 東京都千代田区永田町1丁目7つまり、FormattedAddressLines出力に比べて郵便番号「〒100-0014」と番地レベルの「−1」の部分の情報が抜け落ちていることがわかる。 上のコードではコメントされているが、addressDictionaryの中身を出力してみるとこうなる。
key=Street value=1丁目 7
key=State value=東京都
key=CountryCode value=JP
key=FormattedAddressLines value=(
"¥U65e5¥U672c",
"¥U3012100-0014 ¥U6771¥U4eac¥U90fd¥U5343¥U4ee3¥U7530¥U533a¥U6c38¥U7530¥U753¥Uff11¥U4e01¥U76ee¥Uff17¥U2212¥Uff11"
)
key=City value=千代田区
key=SubThoroughfare value=7
key=Country value=日本
key=Thoroughfare value=1丁目
key=SubLocality value=永田町どうやらMKPlacemarkのプロパティーはaddressDictionaryの中身を適当に展開したものが入っているようだ。日本中の色々な場所を出力させてみたが、国内の場合はMKPlacemarkの情報とFormattedAddressLinesの情報は違いはあるものの、大体似たような文字列が使われているので、フィルタリングすればMKPlacemarkのプロパティーで足りていない部分を判断して取得することができるだろう。
海外を出力させてみたところ、そもそも情報がなかったり必ずしもMKPlacemarkのプロパティーと対応していなかったり・・・と相当苦労しそうだ。
そうなんだー(^^;)
返信削除深いところに入っていたんだねぇ。