得到当前点,距离和方位的纬度/长度

Dav*_*d M 62 python gis distance latitude-longitude

给定lat/long中的现有点,(以KM表示)和方位(以度数转换为弧度)的距离,我想计算新的纬度/经度.这个网站反复出现,但我无法让这个公式为我工作.

采用上述链接的公式为:

lat2 = asin(sin(lat1)*cos(d/R) + cos(lat1)*sin(d/R)*cos(?))

lon2 = lon1 + atan2(sin(?)*sin(d/R)*cos(lat1), cos(d/R)?sin(lat1)*sin(lat2))
Run Code Online (Sandbox Code Playgroud)

上述公式适用于MSExcel,其中 -

asin          = arc sin()   
d             = distance (in any unit)   
R             = Radius of the earth (in the same unit as above)  
and hence d/r = is the angular distance (in radians)  
atan2(a,b)    = arc tan(b/a)  
? is the bearing (in radians, clockwise from north);  
Run Code Online (Sandbox Code Playgroud)

这是我在Python中获得的代码.

import math

R = 6378.1 #Radius of the Earth
brng = 1.57 #Bearing is 90 degrees converted to radians.
d = 15 #Distance in km

#lat2  52.20444 - the lat result I'm hoping for
#lon2  0.36056 - the long result I'm hoping for.

lat1 = 52.20472 * (math.pi * 180) #Current lat point converted to radians
lon1 = 0.14056 * (math.pi * 180) #Current long point converted to radians

lat2 = math.asin( math.sin(lat1)*math.cos(d/R) +
             math.cos(lat1)*math.sin(d/R)*math.cos(brng))

lon2 = lon1 + math.atan2(math.sin(brng)*math.sin(d/R)*math.cos(lat1),
                     math.cos(d/R)-math.sin(lat1)*math.sin(lat2))

print(lat2)
print(lon2)
Run Code Online (Sandbox Code Playgroud)

我明白了

lat2 = 0.472492248844 
lon2 = 79.4821662373
Run Code Online (Sandbox Code Playgroud)

Dav*_*d M 65

需要将弧度的答案转换回度数.工作代码如下:

import math

R = 6378.1 #Radius of the Earth
brng = 1.57 #Bearing is 90 degrees converted to radians.
d = 15 #Distance in km

#lat2  52.20444 - the lat result I'm hoping for
#lon2  0.36056 - the long result I'm hoping for.

lat1 = math.radians(52.20472) #Current lat point converted to radians
lon1 = math.radians(0.14056) #Current long point converted to radians

lat2 = math.asin( math.sin(lat1)*math.cos(d/R) +
     math.cos(lat1)*math.sin(d/R)*math.cos(brng))

lon2 = lon1 + math.atan2(math.sin(brng)*math.sin(d/R)*math.cos(lat1),
             math.cos(d/R)-math.sin(lat1)*math.sin(lat2))

lat2 = math.degrees(lat2)
lon2 = math.degrees(lon2)

print(lat2)
print(lon2)
Run Code Online (Sandbox Code Playgroud)

  • 我试试这个,但只是返回相同的起点? (4认同)
  • 谢谢,[在 Kotlin 中实现了那个片段](https://gist.github.com/vs-krasnov/a06421cdeb1668f3f3510cbfc2149c23)。 (3认同)
  • 感谢您在 C# 中实现了一个代码片段 https://gist.github.com/BicycleMark/3e1a2152febaa2935e4c8cfcea7e061b (3认同)
  • 我使用以下方法验证了代码输出:https://www.fcc.gov/media/radio/find-terminal-cooperatives (2认同)

ell*_*t42 28

geopy库支持这一点:

import geopy
from geopy.distance import VincentyDistance

# given: lat1, lon1, b = bearing in degrees, d = distance in kilometers

origin = geopy.Point(lat1, lon1)
destination = VincentyDistance(kilometers=d).destination(origin, b)

lat2, lon2 = destination.latitude, destination.longitude
Run Code Online (Sandbox Code Playgroud)

通过/sf/answers/317185921/找到

  • 请注意,自 v2.0.0 以来,API 已发生变化。而是使用“geopy.distance.geodesic”:/sf/answers/4400672111/ (2认同)

Pet*_*ter 11

回答可能有点迟,但在测试其他答案后,看起来它们无法正常工作.这是我们用于系统的PHP代码.四面八方工作.

PHP代码:

lat1 =以度为单位的起点纬度

long1 =以度为单位的起点经度

d = KM的距离

angle =以度为单位

function get_gps_distance($lat1,$long1,$d,$angle)
{
    # Earth Radious in KM
    $R = 6378.14;

    # Degree to Radian
    $latitude1 = $lat1 * (M_PI/180);
    $longitude1 = $long1 * (M_PI/180);
    $brng = $angle * (M_PI/180);

    $latitude2 = asin(sin($latitude1)*cos($d/$R) + cos($latitude1)*sin($d/$R)*cos($brng));
    $longitude2 = $longitude1 + atan2(sin($brng)*sin($d/$R)*cos($latitude1),cos($d/$R)-sin($latitude1)*sin($latitude2));

    # back to degrees
    $latitude2 = $latitude2 * (180/M_PI);
    $longitude2 = $longitude2 * (180/M_PI);

    # 6 decimal for Leaflet and other system compatibility
   $lat2 = round ($latitude2,6);
   $long2 = round ($longitude2,6);

   // Push in array and get back
   $tab[0] = $lat2;
   $tab[1] = $long2;
   return $tab;
 }
Run Code Online (Sandbox Code Playgroud)

  • “6,378.14公里”似乎是地球的最大半径。平均值约为“6,371.0公里”,这可以使计算更加准确。 (3认同)
  • 看起来不错,但我认为请求者想要用 python 编写的东西。错误的? (2认同)

not*_*bit 10

这个问题被称为大地测量研究中的直接问题.

这确实是一个非常受欢迎的问题,也是导致混淆的常见问题.原因是大多数人都在寻找一个简单而直截了当的答案.但没有,因为大多数人提出这个问题并没有提供足够的信息,只是因为他们不知道:

  1. 地球不是一个完美的球体,因为它被它的杆子弄平/压缩
  2. 因为(1)地球没有恒定的半径,R.看到这里.
  3. 地球不是非常光滑(高度变化)等.
  4. 由于构造板块运动,地理点的纬度/经度位置每年可能会改变几毫米(至少).

因此,根据您所需的精度,在各种几何模型中使用的许多不同的假设会有不同的应用.因此,要回答这个问题,您需要考虑您希望获得结果的准确性.

一些例子:

  • 我只是寻找距离最近几公里的近似位置,以便在N | S之间的小距离(< 100 km).(地球是平面模型.)latitudes0-70 deg
  • 我想要一个在全球任何地方都很好的答案,但只能精确到几米
  • 我想要一个有效的超精确定位,直到nanometers[nm]的原子尺度.
  • 我想要的答案非常快速,易于计算,而且计算量不大.

因此,您可以选择使用哪种算法.此外,每种编程语言都有自己的实现或"包"乘以模型数量和模型开发人员的特定需求.出于所有实际目的,忽略任何其他语言是javascript值得的,因为它本质上非常类似于伪代码.因此,它可以很容易地转换为任何其他语言,只需要很小的改动.

然后主要模型是:

  • Euclidian/Flat earth model:适用于约10公里以下的极短距离
  • Spherical model:适用于较大的纵向距离,但纬度差异较小.热门型号:
    • Haversine:[km]刻度上的仪表精度,非常简单的代码.
  • Ellipsoidal models:在任何纬度/经度和距离上最准确,但仍然是一个数值近似值,取决于您需要的精度.一些流行的模型是:

参考文献:


kod*_*sha 9

我将 Brad 的答案移植到 vanilla JS 答案,没有 Bing 地图依赖

https://jsfiddle.net/kodisha/8a3hcjtd/

    // ----------------------------------------
    // Calculate new Lat/Lng from original points
    // on a distance and bearing (angle)
    // ----------------------------------------
    let llFromDistance = function(latitude, longitude, distance, bearing) {
      // taken from: https://stackoverflow.com/a/46410871/13549 
      // distance in KM, bearing in degrees
    
      const R = 6378.1; // Radius of the Earth
      const brng = bearing * Math.PI / 180; // Convert bearing to radian
      let lat = latitude * Math.PI / 180; // Current coords to radians
      let lon = longitude * Math.PI / 180;
    
      // Do the math magic
      lat = Math.asin(Math.sin(lat) * Math.cos(distance / R) + Math.cos(lat) * Math.sin(distance / R) * Math.cos(brng));
      lon += Math.atan2(Math.sin(brng) * Math.sin(distance / R) * Math.cos(lat), Math.cos(distance / R) - Math.sin(lat) * Math.sin(lat));
    
      // Coords back to degrees and return
      return [(lat * 180 / Math.PI), (lon * 180 / Math.PI)];
    
    }
    
    let pointsOnMapCircle = function(latitude, longitude, distance, numPoints) {
      const points = [];
      for (let i = 0; i <= numPoints - 1; i++) {
        const bearing = Math.round((360 / numPoints) * i);
        console.log(bearing, i);
        const newPoints = llFromDistance(latitude, longitude, distance, bearing);
        points.push(newPoints);
      }
      return points;
    }
    
    const points = pointsOnMapCircle(41.890242042122836, 12.492358982563019, 0.2, 8);
    let geoJSON = {
      "type": "FeatureCollection",
      "features": []
    };
    points.forEach((p) => {
      geoJSON.features.push({
        "type": "Feature",
        "properties": {},
        "geometry": {
          "type": "Point",
          "coordinates": [
            p[1],
            p[0]
          ]
        }
      });
    });
    
    document.getElementById('res').innerHTML = JSON.stringify(geoJSON, true, 2);
Run Code Online (Sandbox Code Playgroud)

此外,我添加了geoJSON导出,因此您可以简单地将生成的 geoJSON 粘贴到:http://geojson.io/#map=17/41.89017/12.49171以立即查看结果。

结果: geoJSON 截图


Pli*_*lva 6

使用 geopy 的快速方法

from geopy import distance
#distance.distance(unit=15).destination((lat,lon),bering) 
#Exemples
distance.distance(nautical=15).destination((-24,-42),90) 
distance.distance(miles=15).destination((-24,-42),90)
distance.distance(kilometers=15).destination((-24,-42),90) 
Run Code Online (Sandbox Code Playgroud)

  • 没有说明您用于计算的方法,答案基本上是无用的。 (2认同)
  • @not2qubit 无论 @plinio-bueno-andrade-silva 是否意识到,`geopy.distance.distance 目前使用测地线。` [geopy](https://geopy.readthedocs.io/en/latest/#module-geopy.距离)更具体地说,默认使用的椭球模型是 WGS-84 椭球,“这是全球最准确的”。 (2认同)