假设我有一个接受邮政编码作为参数的 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
编辑:这是谷歌关于计算距离的一个很好的解释。它使用 MySQL 和 PHP,但用于查找最近点的 SQL 在这里也很有用。使用 SQL 而不是 getDistanceFrom 函数进行查询可能会更快。
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,你可能会发现它有一个 postcode 属性。谁知道?
这种查找称为“反向地理定位”。
您需要做的第一件事是将纬度/经度数据从 CLocation 对象转换为度...
在 locationManager 函数中(一旦您收到位置更新就会调用该函数)......
代码:
[lat stringWithFormat:@"%+.6f", myLocation.coordinate.latitude];
[lng stringWithFormat:@"%+.6f", myLocation.coordinate.longitude];
从那里您将 lat 和 lng 字符串发送到后端 Web 服务,如“GeoNames.org”或 Google Maps API ......您可以获得最近的城市或街道地址。
有一个由美国人口普查局制作的数据库——老虎数据库。我相信有可能查找给定纬度/经度的邮政编码。
我敢打赌,如果您搜索Tiger 邮政编码,您可能会找到一些东西。例如,请参见此处。看来 CPAN 上有一个 Perl 模块可以做到这一点,所以这应该不是不可能的。
Google 提供免费的反向地理编码服务。您可以直接使用它,也可以尝试 Temboo SDK,它提供多种语言的便捷访问,包括 Objective C(带有代码示例)。
查看https://www.temboo.com/library/Library/Google/Geocoding/GeocodeByCoordinates/