【问题标题】:Simple calculations for working with lat/lon and km distance?使用纬度/经度和公里距离的简单计算?
【发布时间】:2010-11-18 05:14:13
【问题描述】:

我可以做一个简单的计算,将 km 转换为一个值,我可以添加到 lat 或 lon 浮点数以计算搜索的边界框?它不需要完全准确。

例如:如果给我一个英国伦敦的纬度/经度 (51.5001524, -0.1262362),我想计算从该点向东/向西 25 公里处的纬度,以及向北 25 公里处的经度/在那一点以南,我需要做什么才能将 25 公里转换为小数以添加到上面的值?

我正在寻找一般的经验法则,即:1km == +/- 0.XXX

编辑:

我最初对“lat lon”的搜索没有返回这个结果:

How to calculate the bounding box for a given lat/lng location?

接受的答案似乎足以满足我的要求。

【问题讨论】:

标签: algorithm geometry geolocation


【解决方案1】:

大概的转换是:

  • 纬度:1 度 = 110.574 公里
  • 经度:1 度 = 111.320*cos(纬度)公里

这并不能完全纠正地球的极地变平 - 因为您可能需要使用 WGS84 参考椭球体(用于 GPS 的模型)的更复杂的公式。但是对于您的目的,该错误可能可以忽略不计。

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

警告:请注意,经纬度坐标以度数表示,而大多数(所有?)语言中的 cos 函数通常接受弧度,因此需要 degree to radians conversion。

【讨论】:

  • 你的意思是第二个公式中的 cos(longitude) 吗?
  • 你是怎么想到这个的?我遗漏了一些东西,您能否详细说明经度计算?泰
  • @Odys:如果您要比较位于同一经线(北/南)上的两个点,它们位于一个大圆上,转换因子就是地球的极周长除以360度。但是东西向的测量是不同的,因为(除了赤道)你不是沿着一个“大圆”测量的,所以给定纬度的“周长”更小。校正因子原来是纬度的余弦。
  • 我的解释:cos(0°) = 1 => 因此在赤道计算时没有应用校正因子。那里的经度最宽。 cos(90°) = 0 => 在两极,经度在一点相交。没有距离可以计算。
  • @Stijn:在调用 Math.cos() 之前,您需要将度数转换为弧度。
【解决方案2】:

如果您使用的是 Java、Javascript 或 PHP,那么有一个库可以准确地进行这些计算,使用一些有趣的复杂(但仍然很快)三角函数:

http://www.jstott.me.uk/jcoord/

【讨论】:

【解决方案3】:

感谢 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))

【讨论】:

  • 我认为应该是“lat * pi / 180”
【解决方案4】:

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);

【讨论】:

    【解决方案5】:

    有趣的是,我没有看到提到 UTM 坐标。

    https://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system.

    至少如果您想将 km 添加到同一区域,它应该很简单(在 Python 中:https://pypi.org/project/utm/)

    utm.from_latlon 和 utm.to_latlon。

    【讨论】:

    • 感谢 utm 的链接。令人震惊的是它似乎根本没有文档。
    【解决方案6】:

    为什么不使用正确制定的​​地理空间查询???

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

    https://docs.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
    

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

    如果您已正确实施地理空间索引,您的搜索将比您使用的方法更快

    【讨论】:

    猜你喜欢
    • 2015-10-18
    • 1970-01-01
    • 2013-04-16
    • 1970-01-01
    • 2021-05-10
    • 2019-12-19
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    相关资源
    最近更新 更多