计算点与两条经度/纬度的虚拟线之间的距离


14

请参考示例和相应的图像。

我想实现以下操作:提供两个位置(纬度/经度),其中示出了如下面。据此,将绘制一条虚拟线,然后计算该线与C之间的距离(在任何测量中)。

画画

目前,我已经在Google Maps API v3中实现了这一目标,但也希望能够以我选择的语言在后台进行。任何提示/想法将不胜感激!


AB是大圆线吗?
Kirk Kuykendall

@柯克,不,AB只是一条直线
囚犯

@Michael,那是一个有趣的观点。我将不得不看看它!
囚犯

@囚犯@柯克从字面上看,一条“直线”将穿过地球的表面。通常,它向后向表面的径向投影实际上将是一个大圆的一部分(使用球形地球模型)。
ub

1
@Prisoner这是一条非常有用的额外信息!是的,你是对的。您仍然必须补偿以下事实:与南北方向相比,使用(纬度,经度)会使东西方距离微分失真。正如@Jose建议的那样,投影坐标。这可以很简单,只需将经度乘以平均纬度的余弦,然后假装您在欧几里得平面上即可。
ub

Answers:


6
def get_perp( X1, Y1, X2, Y2, X3, Y3):
    """************************************************************************************************ 
    Purpose - X1,Y1,X2,Y2 = Two points representing the ends of the line segment
              X3,Y3 = The offset point 
    'Returns - X4,Y4 = Returns the Point on the line perpendicular to the offset or None if no such
                        point exists
    '************************************************************************************************ """
    XX = X2 - X1 
    YY = Y2 - Y1 
    ShortestLength = ((XX * (X3 - X1)) + (YY * (Y3 - Y1))) / ((XX * XX) + (YY * YY)) 
    X4 = X1 + XX * ShortestLength 
    Y4 = Y1 + YY * ShortestLength
    if X4 < X2 and X4 > X1 and Y4 < Y2 and Y4 > Y1:
        return X4,Y4
    return None

最短的长度是您需要的距离,除非我弄错了?


是的,我正在寻找从C到线段的最短距离。这是数学运算的结果吗?
囚犯

1
它确实工作得很好,我在以下各项中通过了三点(A,B,C):i.imgur.com/bK9oB.jpg然后它返回了X的经纬度
囚犯

1
@Hairy,最后一件事,我将如何修改它以使其到达最近的点(而不仅仅是线),因此,如果我将其放到越过线的点上,我将如何获取它来检查到线的距离。点?
囚犯

1
@Hairy良好的开始,但是None当存在合法的解决方案时,此代码似乎经常返回。问题在于最后一个条件假设X1 <X2和Y1 <Y2,这不能总是得到保证。需要对两者之间进行更好的测试。
ub

1
@Hairy听起来您和@prisoner之间的交流很有成效。我想强调,我与可能发生的投票或观点变更没有任何关系(甚至没有任何控制权),我的评论仅是为了帮助您改善答复。
ub

11

也许我让它变得太复杂了,但是您想要的是点到线的距离。这是沿着AB的点的距离,该点将AB与C连接起来,并与AB正交。垂直于AB的向量为

v=[x2-x1, -(y2-y1)] # Point A is [x1,y1] Point B is [x2,y2]

(我已经使用方括号定义了一个向量或两个元素的数组)。C [xp,yp]与点A之间的距离为

u=[x1-xp, y1-xp]

线和C之间的距离只是u在v上的投影。如果我们假设mod(v)= 1(只需对其进行归一化),则

distance = u*v = abs( (x2-x1)*(y1-yp) - (x1-xp)*(y2-y1) )

唯一的麻烦是您可能想确保坐标不是WGS84纬度/经度对,而是投影的(或使用大地坐标)。您可以为此使用OGRProj4


3
顺便说一下,+ 300万个伪点,因为它们不使用三角函数。当他们应该关注此问题时,太多的人退出了ArcTan:en.wikipedia.org/wiki/Dot_product
Herb

@Jose,感谢您的回复!我正在使用Google Maps API的经纬度。数学部分对我来说还很陌生,所以我将尝试一下,看看我能想到什么。数学有什么建议吗?例如[x2-x1,-(y2-y1)],这意味着什么?
囚犯

我为此添加了一个简短的编辑。基本上,这是一个数组符号,但是如果将坐标存储在变量x1,x2,y1,y2和xp,yp中,则只需要写出我提供的最后一个方程式的右侧即可。这是非常有效了C,Java,JS,巨蟒等代码:)
圣何塞

1
@Jose您正在计算从C到AB 线的距离。基于该图,我认为OP希望从C到线段 AB 的距离。这需要额外的工作来检查C在AB线上的投影是否在A和B之间。在后一种情况下,请使用两个长度CA和CB中较短的一个。
ub

1
@Prisoner主要区别是一条线永远延伸(仅由方向矢量和一个点或两个点定义),而A和B之间的线段是A和B之间的无限线的位B(长度有限)
何塞(Jose

4

对于所有这些数学也有些反感,我会从另一个角度来考虑它。我将其设置为“实际”行,而不是虚拟行,然后使用现有工具。

如果A和B共享一个属性,则可以通过画一条线将它们连接起来(Kosmo GIS有一个可以从点创建线的工具,我相信也有一个QGIS插件)。有了线条后,“ C”点图层上的“近”功能将为您提供到线条的距离。让软件为您处理数学!


感谢您的评论,但Hairy胜过这个!
囚犯

1
(+1)你说得很对。众所周知,计算几何算法很难在实践中完全正确(正如我们从到目前为止提供的所有代码中可以看到的那样,这是有用的和说明性的,但尚未完全起作用)。通常,使用高级GIS程序是确保您得到期望的答案的正确选择(前提是您信任GIS ;-)。
ub

1

如果您在android上使用Java,则只有库函数的一行

import static com.google.maps.android.PolyUtil.distanceToLine;

distanceToLine:

public static double distanceToLine(LatLng p, LatLng start,LatLng end)

计算点p和线段起点之间的球面距离。

参数:p-要测量的点

start-线段的起点

end-线段的末端

返回:以米为单位的距离(假设球形地球)

只需将库添加到您的

dependencies {
    compile 'com.google.maps.android:android-maps-utils:0.5+'
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.