PostGIS'te noktanın çizginin sol veya sağ tarafında olup olmadığını mı tespit ediyorsunuz?


16

Postgis bir linestring tablo ve bir nokta tablo var.

Herhangi bir noktaya en yakın hattı biliyorum. Bilmem gereken şey, bu çizginin hangi "tarafında" olduğu. Sanırım bunu verilen noktadan çizgiye (çizginin en yakın noktası) dik bir çizgi oluşturarak yapmalıyım ve sonra koordinatları karşılaştırmalıyım, ama tam olarak nasıl yapılacağını bilmiyorum ve eğer doğru yolsa, çünkü çizgi yön değiştirir.

Görevimi göstermek için bir resim yaptım.

resim açıklamasını buraya girin

Çizginin kendisi siyahtır, yönü yeşil oklarla gösterilir. Nokta noktaları tablosuna bir "yan" sütun eklemeniz gerekir, böylece kırmızı noktaları "sağ" değeri olmalı ve mavi noktaları "sol" değeri olmalıdır.

Birisi bir noktanın "yan" değerini hesaplamak için bir SQL kodu örneği verebilir mi?

Yanıtlar:


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

Buradaki fikir, en yakın çizgi segmenti arasındaki açıyı ve çizgideki en yakın noktadan noktanıza vektörü hesaplamaktır.

hatta en yakın noktayı bul

select ST_ClosestPoint(line.geom, point.geom)

vektörü noktanıza en yakın noktadan oluşturun

ST_MakeLine(cp.p, point.geom) vec

çizginizin arasında bir vektör oluşturun

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

yol tarifleri arasındaki farkı al

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

Sağ ve sol sıfırdan büyük ve sıfırdan düşük olacaktır.


Teşekkürler, iyi bir çözüm gibi görünüyor, ama * 1.01 bölümünü sevmiyorum. Bu sorguyu daha güvenilir hale getirmek için satırın bir sonraki en yakın noktası seçilebilir mi?
mofoyoda

En yakın segmenti almayı düşünüyordum ama orada böyle bir fonksiyon yok. Ancak bu daha güvenilir bir çözümdür çünkü ST_LineInterpolate yönlendirilmiştir, böylece sadece en yakın olanı değil, hat yönünü bir sonraki noktaya getireceksiniz . Bir sonraki düğümü elde etmek mümkündür, ancak tüm düğümler üzerinde tekrar etmenizi ve hat boyunca veya hatta en yakın noktadan önce olduklarını öğrenmenizi ister.
dmitry.v.kiselev

Merhaba Dmitry. Ne demek istediğimi biliyorsanız, bu çizginin ötesinde bir nokta için işe yarayacak mı? Örneğin, üst sol en kırmızı nokta, 1 cm daha yüksek olsaydı. Bu durumda, en yakın nokta ve nokta orijinal çizgi ile dik açı yapmaz. Bu algoritma bu durumda çalışır mı?
Jenia Ivanov

3
ST_Azimuth(h.vec)- bir sahte koddur. h.vecve h.segçizgilerdir, bu yüzden kesin olmak gerekirseST_Azimuth(ST_StartPoint(h.vec), ST_EndPoint(h.vec))
dmitry.v.kiselev

2
yukarıdaki çözüm, hattın doğu-batı olduğu ve bazı nedenlerden dolayı tam 90 derece rulmana sahip olduğu durumlarda işe yaramıyor gibi görünmektedir.
user7543032
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.