PostGIS에서 점이 선의 왼쪽 또는 오른쪽에 있는지 감지합니까?


16

postgis에 선 스트링 테이블과 포인트 테이블이 있습니다.

주어진 지점에 가장 가까운 줄을 알고 있습니다. 내가 알아야 할 것은 그 선의 어느 쪽이 요점인지에 대한 것입니다. 주어진 점에서 선 (선에서 가장 가까운 점)까지 수직선을 만든 다음 좌표를 비교 하여이 작업을 수행해야하지만 그 방법을 정확히 알지 못하며 올바른 방법이라면 선이 방향을 바꾸므로

내 작업을 설명하기 위해 그림을 만들었습니다.

여기에 이미지 설명을 입력하십시오

선 자체는 검은 색이며 방향은 녹색 화살표로 표시됩니다. 포인트 테이블에 "사이드"열을 추가해야합니다. 따라서 빨간색 포인트의 값은 "오른쪽"이고 파란색 포인트의 값은 "왼쪽"입니다.

누군가 포인트의 "측면"값을 계산하는 SQL 코드 예제를 제공 할 수 있습니까?

답변:


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)

따라서 오른쪽과 왼쪽은 0보다 크고 0보다 작습니다.


고마워, 그것은 좋은 해결책처럼 보이지만 * 1.01 부분을 좋아하지 않습니다. 이 쿼리의 신뢰성을 높이기 위해 가장 가까운 라인을 선택할 수 있습니까?
— mofoyoda

가장 가까운 세그먼트를 얻으려고 생각했지만 그러한 기능은 없습니다. 그러나 ST_LineInterpolate가 지정되어 있기 때문에보다 안정적인 솔루션이므로 가장 가까운 지점이 아닌 다음 라인 방향으로 다음 지점 을 얻을 수 있습니다. 실제로 다음 노드를 얻을 수는 있지만 모든 노드를 반복하고 라인을 따라 다음 또는 라인에서 가장 가까운 지점 앞에 있는지 확인해야합니다.
— dmitry.v.kiselev

안녕 드미트리 내가 무슨 뜻인지 알면 선을 넘어서는 점에서 이것이 효과가 있습니까? 예를 들어, 왼쪽 상단의 가장 큰 빨간 점은 1cm 더 높은 경우입니다. 이 경우 closestPoint와 점은 원래 선과 직각을 이루지 않습니다. 이 경우이 알고리즘이 작동합니까?
— Jenia Ivanov

3
ST_Azimuth(h.vec)-의사 코드입니다. h.vec그리고 h.seg라인입니다. 정확하게 말하면ST_Azimuth(ST_StartPoint(h.vec), ST_EndPoint(h.vec))
— dmitry.v.kiselev

2
위의 해결책은 선이 어떤 이유로 든 정확히 90 도의 방위를 갖는 동서 인 경우에는 작동하지 않는 것 같습니다.
— user7543032
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.