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の中身を出力してみるとこうなる。
どうやらMKPlacemarkのプロパティーは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の情報とFormattedAddressLinesの情報は違いはあるものの、大体似たような文字列が使われているので、フィルタリングすればMKPlacemarkのプロパティーで足りていない部分を判断して取得することができるだろう。
海外を出力させてみたところ、そもそも情報がなかったり必ずしもMKPlacemarkのプロパティーと対応していなかったり・・・と相当苦労しそうだ。
そうなんだー(^^;)
返信削除深いところに入っていたんだねぇ。