パラメーターとして郵便番号を受け入れる Web サービス API があるとしますが、GPS 座標 (緯度、経度) にしかアクセスできません。座標が属する郵便番号を動的に検索するにはどうすればよいですか?
私は iPhone でこの作業を行っているので、ドキュメントで見落としている CoreLocation API 内でこれを行う簡単な方法があることを願っています。
このページは、米国内のすべての郵便番号のデータベース (csv) を緯度と経度とともに提供します。 http://zips.sourceforge.net/
ファイルは 500k 展開されています。データの最初の数行は次のとおりです。
"35004", "AL", " 33.606379", " -86.50249", "Moody", "Alabama"
"35005", "AL", " 33.592585", " -86.95969", "Adamsville", "Alabama"
"35006", "AL", " 33.451714", " -87.23957", "Adger", "Alabama"
このデータをローカル データベースにダンプします。Haversine 式を使用して、座標とデータベース内の座標を比較し、最も近い点を見つけます。CoreLocation には、使用できる関数 getDistanceFrom があります。
- (CLLocationDistance)getDistanceFrom:(const CLLocation *)location
このページには、c の Haversine 関数と zips データベースに関する情報があります。
http://www.jaimerios.com/?p=39
編集:距離の計算に関するGoogleからの優れた説明があります。MySQL と PHP を使用しますが、最も近い点を見つけるための SQL もここで役立ちます。getDistanceFrom 関数よりも、SQL を使用してクエリを実行する方がおそらく高速です。
http://code.google.com/support/bin/answer.py?answer=87134&topic=11364
座標 37, -122 から半径 25 マイル以内にある最も近い 20 か所を見つける:
SELECT id, ( 3959 * acos( cos( radians(37) )
* cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) )
+ sin( radians(37) ) * sin( radians( lat ) ) ) )
AS distance FROM markers HAVING distance < 25
ORDER BY distance LIMIT 0 , 20;
マイルではなくキロメートルで検索するには、3959 を 6371 に置き換えます。
もし私があなたなら、3.0 SDK のリバース ジオコーダーのドキュメントをチェックしてみます。そこに何があるかはわかりませんが、たとえば、リバース ジオコードが placeMark を返していることがわかり、SDK でその placeMark を調べると、郵便番号プロパティがあることがわかるかもしれません。知るか?
この種のルックアップは、「リバース ジオロケーション」と呼ばれます。
最初に行う必要があるのは、緯度/経度データを CLocation オブジェクトから度に変換することです...
locationManager 関数 (ロケーションの更新を受け取ると呼び出されます)...
コード:
[lat stringWithFormat:@"%+.6f", myLocation.coordinate.latitude];
[lng stringWithFormat:@"%+.6f", myLocation.coordinate.longitude];
そこから緯度と経度の文字列を「GeoNames.org」や Google Maps API などのバックエンド Web サービスに送信すると、最も近い都市または番地の住所を取得できます。
Google は無料のリバース ジオコーディング サービスを提供しています。直接使用することも、Objective C (コード サンプル付き) を含む複数の言語で便利にアクセスできる Temboo SDK を試すこともできます。
https://www.temboo.com/library/Library/Google/Geocoding/GeocodeByCoordinates/をご覧ください。