กำลังตรวจสอบว่าจุดอยู่ทางด้านซ้ายหรือด้านขวาของบรรทัดใน PostGIS หรือไม่


16

ฉันมีตารางย้อนหลังและตารางคะแนนในโพสต์จิส

ฉันรู้ว่าใกล้ที่สุดถึงจุดใดก็ตาม สิ่งที่ฉันต้องรู้คือจุดที่ "ด้าน" ของเส้นนั้นคืออะไร ฉันเดาว่าฉันต้องทำอย่างนั้นโดยการสร้างเส้นตั้งฉากจากจุดที่กำหนดไปยังบรรทัด (จุดที่ใกล้ที่สุดในบรรทัด) แล้วเปรียบเทียบพิกัด แต่ฉันไม่รู้วิธีการทำเช่นนั้นและถ้ามันเป็นวิธีที่เหมาะสม เนื่องจากการเปลี่ยนแปลงของเส้นเป็นทิศทาง

ฉันทำรูปภาพเพื่ออธิบายงานของฉัน

ป้อนคำอธิบายรูปภาพที่นี่

เส้นนั้นเป็นสีดำทิศทางของมันจะแสดงด้วยลูกศรสีเขียว ฉันต้องเพิ่มคอลัมน์ "ด้าน" ลงในตารางจุดดังนั้นจุดสีแดงควรมีค่า "ถูกต้อง" และจุดสีน้ำเงินควรมีค่า "ซ้าย"

ใครสามารถให้ตัวอย่างรหัส 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)

ดังนั้นทางขวาและซ้ายจะมากกว่าศูนย์และต่ำกว่าศูนย์


ขอบคุณดูเหมือนเป็นทางออกที่ดี แต่ฉันไม่ชอบ * 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

2
การแก้ปัญหาข้างต้นดูเหมือนจะไม่ทำงานในกรณีที่สายตะวันออก - ตะวันตกมีทิศทาง 90 องศาด้วยเหตุผลบางอย่าง
user7543032
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.