使用经纬度和千米距离进行简单计算?

150

有没有一种简单的计算方法,可以将公里转换成一个值,我可以将其添加到纬度或经度浮点数中,以计算搜索的边界框?它不需要完全准确。

例如:如果我获得了伦敦(英国)的纬度/经度(51.5001524,-0.1262362),并且我想计算东/西距该点25公里的纬度将是多少,以及该点北/南距离25公里的经度将是多少,我需要做什么才能将25公里转换为小数以添加到上述值中?

我正在寻找一个通用的经验法则,即:1公里== +/- 0.XXX

编辑:

我的原始搜索“lat lon”没有返回此结果:

如何计算给定纬度/经度位置的边界框?

被接受的答案似乎符合我的要求。


可能是重复的问题,参考如何计算给定经纬度位置的边界框? - Stephen Kennedy
6个回答

279

大致转换如下:

  • 纬度:1度 = 110.574千米
  • 经度:1度 = 111.320*cos(纬度)千米

这并没有完全考虑地球的极地扁平 - 对于此,您可能需要使用更复杂的公式来使用WGS84参考椭球体(GPS使用的模型)进行校正。但是对于您的目的而言,误差可能可以忽略不计。

来源:http://en.wikipedia.org/wiki/Latitude

注意:请注意,cos函数在大多数(全部?)语言中通常接受弧度制,因此需要进行度到弧度的转换


1
你是怎么想出这个的?我有点不明白,能否详细说明一下经度计算的部分?谢谢。 - Odys
5
如果你在比较两个位于同一经线(南北方向)上的点,则它们位于一个大圆上,转换因子只需将地球极圆周长除以360度。但对于东西方向的测量,情况则不同,因为(除了赤道以外)你不是沿着“大圆”测量,所以在给定纬度处的“周长”较小。修正因子实际上就是该纬度的余弦值。 - Jim Lewis
18
我的翻译:我的解释:cos(0°) = 1 => 因此,在赤道计算时不需要应用校正因子。那里的经度最宽广。cos(90°) = 0 => 在极点,经线汇聚成一点。没有距离需计算。 - Krisztián Balla
5
在调用 Math.cos() 函数之前,您需要将角度转换为弧度。 - Jim Lewis
2
这个近似有名称和参考文献吗? - Rafnuss
显示剩余8条评论

5
如果您正在使用Java、Javascript或PHP,那么有一个库可以精确地进行这些计算,该库使用了一些有趣但仍然快速的三角学方法: http://www.jstott.me.uk/jcoord/

该网站现在拥有了图书馆。 - midfield99
6
链接已经失效! - chatzich
对于 PHP,您可以使用此分支:https://github.com/dvdoug/PHPCoord - dearsina
有 https://github.com/xni06/JCoord(Java)和 http://www.jstott.me.uk/jscoord/(Javascript) - undefined

5

感谢Jim Lewis提供的出色答案,我想通过我的Swift函数来说明这个解决方案:

func getRandomLocation(forLocation location: CLLocation, withOffsetKM offset: Double) -> CLLocation {
        let latDistance = (Double(arc4random()) / Double(UInt32.max)) * offset * 2.0 - offset
        let longDistanceMax = sqrt(offset * offset - latDistance * latDistance)
        let longDistance = (Double(arc4random()) / Double(UInt32.max)) * longDistanceMax * 2.0 - longDistanceMax
        
        let lat: CLLocationDegrees = location.coordinate.latitude + latDistance / 110.574
        let lng: CLLocationDegrees = location.coordinate.longitude + longDistance / (111.320 * cos(lat * .pi / 180))
        return CLLocation(latitude: lat, longitude: lng)
    }

在这个转换距离的函数中,我使用以下公式:
latDistance / 110.574
longDistance / (111.320 * cos(lat * .pi / 180))

5
我认为应该是 "lat * pi / 180"。 - magamig

1

2
感谢提供utm的链接。令人震惊的是,它似乎没有任何文档资料。 - Westworld

1

http://www.jstott.me.uk/jcoord/ - 使用这个库

            LatLng lld1 = new LatLng(40.718119, -73.995667);
            LatLng lld2 = new LatLng(51.499981, -0.125313);
            Double distance = lld1.distance(lld2);
            Log.d(TAG, "Distance in kilometers " + distance);

0

我希望您能使用正确的地理空间查询方法?

这是STContains地理空间函数的SQL Server参考页面:

https://learn.microsoft.com/en-us/sql/t-sql/spatial-geography/stcontains-geography-data-type?view=sql-server-ver15

或者,如果您不想使用框和弧度转换,您可以始终使用距离函数来查找所需的点:
DECLARE @CurrentLocation geography; 
SET @CurrentLocation  = geography::Point(12.822222, 80.222222, 4326)

SELECT * , Round (GeoLocation.STDistance(@CurrentLocation ),0) AS Distance FROM [Landmark]
WHERE GeoLocation.STDistance(@CurrentLocation )<= 2000 -- 2 Km

几乎所有的数据库都应该有类似的功能。

如果您正确实现了地理空间索引,您的搜索速度将比您目前使用的方法快得多。


1
请花点时间阅读[编辑帮助](//stackoverflow.com/editing-help)中的内容。在Stack Overflow上进行格式设置与其他网站不同。 - Dharman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接