0

我有一个数据库,其中填充了我选择的特定位置。对于每个位置,我将提供经度和纬度。

我想获取我网站访问者的 geoIP(在 maxmind.com 等数据库中匹配的给定 IP 的经度和纬度)。使用 geoIP,我想从我的位置数据库表中找到离访问者最近的位置。

我花了很多时间试图弄清楚如何以有效的方式完成这项工作。我不希望这个过程对每个访客来说都是昂贵的。该过程不必精确,只要足够精确即可。如果它给用户萨克拉门托而不是旧金山,这会更正确,那没关系。只要错误程度足够小,不会打扰大多数用户。如果算法给出的位置完全与他们所在的地方无关,比如芝加哥(当他们住在加利福尼亚时),那就不行了。

话虽如此,有什么解决方案?

以下是我的一些想法:

1

使用勾股定理求平面中两点之间的距离。唯一的问题是地球不在平面坐标系上,而是在球形坐标系上。因此,我需要一种将地理位置数据(经纬度)转换为 X 和 Y 坐标的方法。然后我可以运行一个 SQL 查询,找到最短的记录,该记录使用以下distance方法计算:sqrt(abs(locationX - geoIpX)^2 + abs(locationY - geoIpY)^2)

我不确定这是否是一个合理的解决方案。如果是,那么请为我平滑粗糙的边缘,以便我可以实现它。

2

找出一个使用经度和纬度差异的算法。例如,首先找到经度与 geoIP 的经度最近的位置,然后从该集合中找到纬度与 geoIP 的纬度最近的位置。刚才描述的算法的唯一问题是误差幅度可能很大. 例如,加利福尼亚州的一个城市距离 geoIP 经度 3 度,而加拿大经度的一个城市距离地理 IP 的距离为 2 度,会发生什么情况是,这条经线将用于查找最近的纬度,可能只有加拿大的城市。尽管加拿大的纬度比加利福尼亚城市的纬度高得多,但用户将看到与加拿大人而不是加利福尼亚人相关的数据,这将是一个太大的错误。但是,也许对这个算法有一些修改可以解决这个问题?

后记

谢谢阅读。非常感谢所有解决方案和帮助!:)

4

3 回答 3

1

您可以使用Haversine 公式。 http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL

为了优化搜索,您可以提供最大、最小坐标对于最大最小坐标,您可以使用服务器端函数进行处理,或者您可以使用存储过程来计算最大最小坐标的示例:

$minLng = $lng-($distance/(abs(cos(rad2deg($lat))*69)));
$maxLng = $lng+($distance/(abs(cos(rad2deg($lat))*69)));
$minLat = $lat-($distance/69);
$maxLat = $lat+($distance/69);

mysql + php:

$select = "3956 * 2 * ASIN(SQRT(POWER(SIN((initial.pin_lat - " . $destination.lat . ") * pi()/180 / 2), 2) +COS(" .
        "initial.pin_lat * pi()/180) * COS(" . $destination.lat . " * pi()/180) *POWER(SIN((" .
        "initial.pin_lng - " . $destination.long . ") * pi()/180 / 2),2))) as distance_to_destination";

然后在 have 子句中使用这个 distance_to_destination 或在 where 子句中使用 select

缩小搜索范围

$where =         $destination.long." between "
        . $minLng . " and " . $maxLng . " and ".$destination.lat." between " . $minLat . " and "
        . $maxLat . " having distance < " . $prefered_distance 
于 2015-07-22T07:38:06.630 回答
0

您需要Haversine 公式。由于该计算涉及三角函数,因此它往往有点昂贵。

您可能会考虑将部分数据复制到支持内置地理位置搜索的配套技术。MySQL 不太擅长这种类型的搜索,但其他一些工具却很擅长。

例如,Sphinx Search 支持地理距离搜索:


MySQL 确实支持空间索引,但仅在 MyISAM 表中。避免使用 MyISAM 表的原因有很多。

于 2013-08-01T01:15:37.123 回答
0

mysql 和其他数据库一样好。您可以使用空间索引。我写了一个用怪物曲线解决空间索引的 php 类。你可以在 phpclasses 下载我的希尔伯特曲线包。它还使用 Mercantor 投影,我使用它非常成功。其他数据库具有本机支持,但您可以自己在几个小时内完成。

于 2013-08-01T01:33:12.737 回答