xcode 经纬度中点与线之间的最小距离
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20231258/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Minimum distance between a point and a line in latitude, longitude
提问by Azam
I have a line with two points in latitude and longitude
A: 3.222895, 101.719751
B: 3.227511, 101.724318
我有一条经纬度有两点的线
A: 3.222895, 101.719751
B: 3.227511, 101.724318
and 1 point
C: 3.224972, 101.722932
和 1 点
C: 3.224972, 101.722932
How can I calculate minimum distance between point C and a line consists of point A and B? It will be convenient if you can provide the calculation and objective-c code too. The distance is around 89 meters (using ruler in Google Earth).
如何计算点 C 和由点 A 和 B 组成的线之间的最小距离?如果你也提供计算和objective-c代码会很方便。距离约为 89 米(使用 Google 地球中的标尺)。
回答by Azam
Thanks to mimi and this great article http://www.movable-type.co.uk/scripts/latlong.htmlbut they don't give the whole picture. Here is a detail one. All this points are collected using Google Earth using Placemark to mark the locations. Make sure lat/long are set to decimal degrees in Preferences.
感谢 mimi 和这篇很棒的文章http://www.movable-type.co.uk/scripts/latlong.html但他们没有给出全貌。这是一个细节。所有这些点都是使用 Google Earth 收集的,使用 Placemark 来标记位置。确保在首选项中将纬度/经度设置为十进制度数。
lat A = 3.222895
lon A = 101.719751
lat B = 3.222895
lon B = 101.719751
lat C = 3.224972
lon C = 101.722932
Earth radius, R = 6371
1. First you have to find the bearing from A to C and A to B.
Bearing formula
1.首先你要找到从A到C和A到B的
轴承。轴承公式
bearingAC = atan2( sin(Δλ)*cos(φ?), cos(φ?)*sin(φ?) ? sin(φ?)*cos(φ?)*cos(Δλ) )
bearingAB = atan2( sin(Δλ)*cos(φ?), cos(φ?)*sin(φ?) ? sin(φ?)*cos(φ?)*cos(Δλ) )
φ is latitude, λ is longitude, R is earth radius
φ是纬度,λ是经度,R是地球半径
2. Find A to C distance using spherical law of cosines
2. 使用余弦球定律求 A 到 C 的距离
distanceAC = acos( sin(φ?)*sin(φ?) + cos(φ?)*cos(φ?)*cos(Δλ) )*R
3. Find cross-track distance
3. 查找交叉轨道距离
distance = asin(sin(distanceAC/ R) * sin(bearingAC ? bearing AB)) * R
Objective-C code
Objective-C 代码
double lat1 = 3.227511;
double lon1 = 101.724318;
double lat2 = 3.222895;
double lon2 = 101.719751;
double lat3 = 3.224972;
double lon3 = 101.722932;
double y = sin(lon3 - lon1) * cos(lat3);
double x = cos(lat1) * sin(lat3) - sin(lat1) * cos(lat3) * cos(lat3 - lat1);
double bearing1 = radiansToDegrees(atan2(y, x));
bearing1 = 360 - ((bearing1 + 360) % 360);
double y2 = sin(lon2 - lon1) * cos(lat2);
double x2 = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lat2 - lat1);
double bearing2 = radiansToDegrees(atan2(y2, x2));
bearing2 = 360 - ((bearing2 + 360) % 360);
double lat1Rads = degreesToRadians(lat1);
double lat3Rads = degreesToRadians(lat3);
double dLon = degreesToRadians(lon3 - lon1);
double distanceAC = acos(sin(lat1Rads) * sin(lat3Rads)+cos(lat1Rads)*cos(lat3Rads)*cos(dLon)) * 6371;
double min_distance = fabs(asin(sin(distanceAC/6371)*sin(degreesToRadians(bearing1)-degreesToRadians(bearing2))) * 6371);
NSLog(@"bearing 1: %g", bearing1);
NSLog(@"bearing 2: %g", bearing2);
NSLog(@"distance AC: %g", distanceAC);
NSLog(@"min distance: %g", min_distance);
Actually there's a library for this. You can find it here https://github.com/100grams/CoreLocationUtils
实际上有一个图书馆。你可以在这里找到它https://github.com/100grams/CoreLocationUtils
回答by Azam
Calculate bearing for each: C to A , and C to B:
计算每个方位:C 到 A 和 C 到 B:
var y = Math.sin(dLon) * Math.cos(lat2);
var x = Math.cos(lat1)*Math.sin(lat2) -
Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
var brng = Math.atan2(y, x).toDeg();
dLon= lon2-lon1;
dLon=lon2-lon1;
Calculate cross-track distance:
计算交叉轨道距离:
var dXt = Math.asin(Math.sin(distance_CB/R)*Math.sin(bearing_CA-bearing_CB)) * R;
R is the radius of earth, dXt is the minimum distance you wanted to calculate.
R 是地球的半径,dXt 是您要计算的最小距离。
回答by cffk
Code to carry out this calculation is posted at here. This implements an accurate solution in terms of ellipsoidal geodesics. For the basic geodesic calculations, you can use GeographicLibor the port of these algorithms to C which are included in version 4.9.0 of PROJ.4. This C interface is documented here.
执行此计算的代码发布在此处。这在椭球测地线方面实现了准确的解决方案。对于基本的测地线计算,您可以使用 GeographicLib或这些算法到 C 的端口,这些算法包含在 PROJ.4 的4.9.0版本中。此 C 接口记录在此处。
Here's the result of compiling and running intercept.cpp:
下面是编译和运行intercept.cpp的结果:
$ echo 3.222895 101.719751 3.227511 101.724318 3.224972 101.722932 | ./intercept
Initial guess 3.225203 101.7220345
Increment 0.0003349040566247297 0.0003313413822354505
Increment -4.440892098500626e-16 0
Increment 0 0
...
Final result 3.225537904056624 101.7223658413822
Azimuth to A1 -135.1593040635131
Azimuth to A2 44.84069593652217
Azimuth to B1 134.8406959363608
Distance to line is 88.743m:
到线的距离是 88.743m:
$ echo 3.224972 101.722932 3.225537904056624 101.7223658413822 | GeodSolve -i
-45.15927221 -45.15930407 88.743
回答by Martin Koubek
See post here: https://stackoverflow.com/a/33343505/4083623
请参阅此处的帖子:https: //stackoverflow.com/a/33343505/4083623
For distance up to a few thousands meters I would simplify the issue from sphere to plane. Then, the issue is pretty simply as a easy triangle calculation can be used:
对于长达几千米的距离,我会简化从球体到平面的问题。然后,问题很简单,因为可以使用简单的三角形计算:
We have points A and B and look for a distance X to line AB. Then:
我们有点 A 和 B,并寻找到线 AB 的距离 X。然后:
Location a;
Location b;
Location x;
double ax = a.distanceTo(x);
double alfa = (Math.abs(a.bearingTo(b) - a.bearingTo(x))) / 180
* Math.PI;
double distance = Math.sin(alfa) * ax;
回答by David Lin
If you know how to calculate the distance of two points, get the distances between each two points, you get AB, AC, and BC. You want to know the closest distance between point C and line AB.
如果你知道如何计算两点的距离,得到每两个点之间的距离,你就会得到 AB、AC 和 BC。您想知道点 C 和线 AB 之间的最近距离。
First get the value of P
首先得到P的值
P=(AB+BC+AC)/2
Using P, you need to get S
使用P,你需要得到S
S=SQRT((P(P-AC)(P-AB)(P-AC))
SQRT means square root. Then you get what you want by
SQRT 表示平方根。然后你得到你想要的
2*S/AB

