Algorithm 找到给定纬度/经度的位置(邮编、城市、州)的最快方法

Algorithm 找到给定纬度/经度的位置(邮编、城市、州)的最快方法,algorithm,geolocation,Algorithm,Geolocation,我需要一个免费(开源)的解决方案,给定lat/lng可以返回壁橱城市/州或zip。mysql不是一个选项,如果可能的话,一个小型的轻量级数据库将是最好的 更新:没有web服务,每天有5000万次访问,即使是最小的插件也会造成伤害,因此添加服务请求会缩短响应时间。我不希望在请求上添加超过200毫秒的时间 我有一个csv格式的数据库,lat/lon/zip/city/state。它只是如何存储,更重要的是如何最快地检索它。它不是开源的,但也许你可以使用谷歌地图API: 另一个线程通过MaxMind推

我需要一个免费(开源)的解决方案,给定lat/lng可以返回壁橱城市/州或zip。mysql不是一个选项,如果可能的话,一个小型的轻量级数据库将是最好的

更新:没有web服务,每天有5000万次访问,即使是最小的插件也会造成伤害,因此添加服务请求会缩短响应时间。我不希望在请求上添加超过200毫秒的时间


我有一个csv格式的数据库,lat/lon/zip/city/state。它只是如何存储,更重要的是如何最快地检索它。

它不是开源的,但也许你可以使用谷歌地图API:


另一个线程通过MaxMind推荐mod_geoip。 它在Apache级别上运行,甚至在到达PHP/.NET/Java之前。

如果你有拉链的长边和宽边以及当前位置,你可以计算半径并找到该圆内的点。如果对每个zipcode范围进行假设边界,则可以加快搜索速度


如果可以使用SQL 2008(standard或express),则可以使用类型。

暴力:将所有数据预加载到数组中。计算当前点与阵列中每个点之间的距离(有一种计算方法使用线性代数而不是三角函数,但我不记得它是什么)以找到最近的点

请在否决投票前阅读此内容:有很多方法可以加速类似这样的暴力搜索,但我发现它们通常不值得这么麻烦。我以前不仅使用过这种方法从纬度/经度查找最近的zip,而且在Windows Mobile应用程序中也使用过这种方法(在该应用程序中,处理能力并不十分强大),并且仍然实现了亚秒的搜索时间。只要您避免使用trig函数,这就不是一个昂贵的过程

更新:通过将zip数据分配到子区域(例如,西北、东南等象限),并将区域ID与每个数据点一起保存,可以加快搜索时间。然后,在搜索中,首先确定当前位置所在的区域,并仅与这些数据点进行比较

为了避免边界错误(例如,当前位置靠近其区域的边缘,但实际上距离相邻区域中的zip最近),区域应在一定程度上重叠。这意味着您的一些zip记录将被复制,因此您的整个数据集将稍大一些。

是一个可以做到这一点的免费web服务。它可以查找地名(“纽约市”、“白金汉宫”),但也可以通过使用

若要使用该服务,请提交POST请求,它将返回XML:

一个小的命令行示例(我模糊了我的Yahoo!应用程序ID;您需要注册自己的应用程序ID):

$curl-X POST-ddocumentContent='GEO:37.386013,-122.082932'-ddocumentType='text/html'-dappid='your_yahoo_app_id'http://wherein.yahooapis.com/v1/document
这将返回一个非常详细的XML文档,其中一部分是:

<type>Town</type>
<name><![CDATA[Los Altos, CA, US]]></name>
城镇
它还包含以下数据:

<type>Zip</type>
<name><![CDATA[94024, Los Altos, CA, US]]></name>
Zip
我没怎么用过Placemaker,但我用过他们的,速度很快。将其与本地
memcached
相结合,用户不知道数据不是本地的。

您应该签出。它们有一个返回XML和/或JSON的API。
此外,您还可以对他们的数据库进行dl操作。

查看geonames.org数据库中的源数据

对于轻型数据库,sqlite是一个不错的选择

geonames也提供web服务,但是如果您想自己做而不需要web调用(听起来好像是这样),那么您将需要一个本地数据库。然后,您只需要进行正确的三角计算,计算出一对lat/lng点之间的大圆距离(google that),然后按距离排序结果。如果要在执行计算之前限制搜索半径,也可以使用边界框或半径


如果您的本地数据库可以是基于SQL的(sqllite3就是这样),那么所有这些加起来就是一个SQL查询,它添加了一系列trig计算来计算“距离”列,也可能是一个类似的“where”子句来限制半径或边界框内的搜索。计算完查询中的距离列后,就可以很容易地按距离排序并添加任何其他您喜欢的条件。如果您了解ruby/rails,并且希望看到一个很好的示例,请查看GeoKit rails插件源代码

使用a来加速最近邻搜索。无论您的平台是什么,都应该有很多免费的实现。

您希望最近的城市离您的源位置有多远?50英里?200英里?500英里?如果两个城市的距离几乎相等,那么如果你的算法选择了更近的一个,这有关系吗?您可以使用此信息帮助加快搜索速度

如果您可以合理地假设距离差很小(~250英里左右可能足够近,可以认为是“小”),并且您的距离计算可能有点“模糊”,那么您可以通过将搜索空间限制在距离源+/-5 lat来优化“蛮力”检查(~70英里/纬度,因此这意味着南北方向的距离为350英里左右),长度为+/-5英里(假设你不是在两极寻找城市,这是从赤道的~350英里到加拿大北部的~100英里)。调整这些范围,使其适合你的问题空间


虽然trig函数有助于精确指示距离,但对于较小的距离,例如这些毕达哥拉斯距离,通常足够接近“最佳猜测”答案,x=69.1*(sourcelat-cityla)和y=53.0*(sourcelong-citylong)。

这是一个非常有趣的问题,答案非常复杂

你提到了检察官
<type>Zip</type>
<name><![CDATA[94024, Los Altos, CA, US]]></name>