在PostGIS中检测点是在线的左侧还是右侧?


16

我在postgis中有一个线串表和一个点​​表。

我知道最接近任何给定点的线。我需要知道的是那条线的哪一侧。我想我必须通过创建从给定点到该线的垂直线(该线上的最接近点)然后比较坐标来做到这一点,但是我不知道该怎么做,如果这是正确的方法,因为线改变了方向。

我做了一张照片来说明我的任务。

在此处输入图片说明

该线本身为黑色,其方向以绿色箭头显示。我需要在点表中添加一个“侧”列,以便红点的值应为“ right”,蓝点的值应为“ left”。

有人可以给出一个计算点的“边”值的SQL代码示例吗?

Answers:


12
select (ST_Azimuth(h.vec) - ST_Azimuth(h.seg))
from (
    select 
        ST_MakeLine(cp.p, point.geom) vec,
        ST_MakeLine(cp.p, 
            ST_LineInterpolatePoint(
                line.geom, 
                ST_LineLocatePoint(line.geom, cp.p) * 1.01)
        ) seg
        from (
            select 
                ST_ClosestPoint(line.geom, point.geom)
        ) p as cp
    ) as h

因此,其想法是计算最接近的线段与从最接近的点到您的点的向量之间的角度。

得到一条线上的最近点

select ST_ClosestPoint(line.geom, point.geom)

从最接近的点创建矢量

ST_MakeLine(cp.p, point.geom) vec

在您的行中创建一个向量

ST_MakeLine(
    --original point
    cp.p, 
    --find a point next to the closest point on line
    ST_LineInterpolatePoint(line.geom, 
         ST_LineLocatePoint(line.geom, cp.p) * 1.01)) seg

得到方向之间的差异

ST_Azimuth(h.vec) - ST_Azimuth(h.seg)

因此左右将大于零且小于零。


谢谢,这似乎是一个不错的解决方案,但我不喜欢* 1.01部分。可以选择线的下一个最接近的点以使此查询更可靠吗?
mofoyoda

我本来想获得最接近的细分市场,但是我们没有这种功能。但这是更可靠的解决方案,因为ST_LineInterpolate是定向的,因此您将获得直线方向上的下一个点,而不仅仅是最近的点。可以获取实际的下一个节点,但是它会敦促您遍历所有节点并找出它们是沿着该线的下一个节点还是位于该线上的最近点之前。
dmitry.v.kiselev

嗨,德米特里。如果您知道我的意思,那么这是否可以超出范围?例如,最左上的红点(如果高1厘米)。在这种情况下,最接近的点和该点将不会与原始线成直角。在这种情况下,该算法会起作用吗?
Jenia Ivanov

3
ST_Azimuth(h.vec)-是伪代码。h.vec并且h.seg是线条,因此准确地说,应该像是ST_Azimuth(ST_StartPoint(h.vec), ST_EndPoint(h.vec))
dmitry.v.kiselev,2016年

2
由于某些原因,在直线东西方向成90度角的情况下,上述解决方案似乎不起作用。
user7543032 '17
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.