使用经度和纬度查找彼此靠近的城市

时间:2011-01-11 19:47:22

标签: php algorithm logic euclidean-distance

我的数据库中的每个用户都与一个城市相关联(具有它的经度和纬度)

我如何找出哪些城市彼此接近?

即。在英格兰,剑桥离伦敦很近。

所以如果我有一个住在剑桥的用户。与他们关系密切的用户将是居住在周边城市的用户,例如伦敦,赫特福德等。

我有什么想法可以解决这个问题?而且,我如何定义接近的内容?即在英国,距离美国的距离要比在美国的距离更近,因为美国更加分散。

想法和建议。另外,您是否知道提供此类功能的任何服务?

由于

6 个答案:

答案 0 :(得分:0)

如果您可以呼叫外部网络服务,则可以使用GeoNames API定位您定义的某个半径范围内的附近城市:

http://www.geonames.org/export/web-services.html

答案 1 :(得分:0)

从城市名称获取坐标称为反向地理编码。谷歌地图有一个很好的Api fot。

还有Geonames项目,您可以获得大量的城市数据库,邮政编码等及其合作伙伴

但是如果你已经有了坐标,那么就可以通过一个简单的计算来获得距离。

棘手的是要获得一个不错的高性能版本。您可能将它存储在mysql数据库中,因此您需要在那里快速完成。

绝对可能。我曾经做过一个包含该代码的项目,我将获取它并在此处发布。

然而,为了加快速度,我建议先在中心坐标周围做一个矩形选择。使用蜂树索引甚至更好的东西,如多维范围搜索,这是非常非常快的。然后在内部,您可以计算有限数据集上的确切距离。 在重新选择的方向之外,方向是如此巨大,以至于不需要如此准确地显示或计算。或者只是展示国家,大陆或类似的东西。

我还在办公室但是当我回到家时,我可以为你取代码。同时,如果您能告诉我如何存储您的数据,那将是一件好事。

编辑:在这里,你有一个看起来正确的功能(我在一个查询中没有功能的情况下做了...)

   CREATE FUNCTION `get_distance_between_geo_locations`(`lat1` FLOAT, `long1` FLOAT, `lat2` FLOAT, `long2` FLOAT)
  RETURNS FLOAT
  LANGUAGE SQL
  DETERMINISTIC
  CONTAINS SQL
  SQL SECURITY DEFINER
  COMMENT ''
BEGIN
DECLARE distance FLOAT DEFAULT -1;
DECLARE earthRadius FLOAT DEFAULT 6371.009;
-- 3958.761 --miles
-- 6371.009 --km
DECLARE axis FLOAT;

IF ((lat1 IS NOT NULL) AND (long1 IS NOT NULL) AND (lat2 IS NOT NULL) AND (long2 IS NOT NULL)) THEN -- bit of protection against bad data

  SET axis = (SIN(RADIANS(lat2-lat1)/2) * SIN(RADIANS(lat2-lat1)/2) + COS(RADIANS(lat1)) * COS(RADIANS(lat2)) * SIN(RADIANS(long2-long1)/2) * SIN(RADIANS(long2-long1)/2));
  SET distance = earthRadius * (2 * ATAN2(SQRT(axis), SQRT(1-axis)));

END IF;

RETURN distance;
END;

我从这里引用了这个:http://sebastian-bauer.ws/en/2010/12/12/geo-koordinaten-mysql-funktion-zur-berechnung-des-abstands.html

这是另一个链接:http://www.andrewseward.co.uk/2010/04/sql-function-to-calculate-distance.html

答案 2 :(得分:0)

最简单的方法是从城市的纬度和经度以及距离(通过将距离转换为经度)计算边界框。

获得该框(最小纬度,最大纬度,最小经度,最大经度)后,查询其纬度和经度位于边界框内的其他城市。这将为您提供一个近似列表,并且应该非常快,因为它将能够使用您在纬度和经度列上可能具有的任何索引。

从那里你可以根据需要使用真实的“球体上的点之间的距离”函数缩小列表。

答案 3 :(得分:0)

您需要空间索引或GIS功能。你用的是什么数据库? MySQL和PostgreSQL都支持GIS,可以使用SQL查询找到N个最近的城市。

答案 4 :(得分:0)

您可能想要考虑的另一个选择是将所有城市放入空间搜索树,如kd树。 Kd树有效地支持最近邻搜索,以及快速搜索给定边界框中的所有点。然后,您可以通过搜索该城市的一些最近邻居来找到附近的城市,然后使用距离这些邻居来获得要搜索的边界框的估计大小。

答案 5 :(得分:0)

检查此主题:

MySQL Great Circle Distance (Haversine formula)

你有一个SQL查询来计算纬度和经度附近的城市。

干杯。