यह पता लगाना कि क्या पोस्ट जीआईएस में लाइन के बाईं या दाईं ओर बिंदु है?


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 भाग पसंद नहीं है। क्या इस क्वेरी को अधिक विश्वसनीय बनाने के लिए रेखा के अगले निकटतम बिंदु को चुना जा सकता है?
मोफयोडा

मैं निकटतम सेगमेंट प्राप्त करने के बारे में सोच रहा था लेकिन हमारे पास ऐसा कोई कार्य नहीं था। लेकिन यह अधिक विश्वसनीय समाधान है क्योंकि ST_LineInterpolate का निर्देशन किया जाता है, इसलिए आपको केवल पास ही नहीं, रेखा की दिशा में अगला बिंदु मिलेगा । यह वास्तविक अगले नोड प्राप्त करना संभव है, लेकिन यह आपको सभी नोड्स पर पुनरावृत्ति करने और यह पता लगाने का आग्रह करेगा कि क्या वे लाइन के बगल में या लाइन पर निकटतम बिंदु से पहले हैं।
dmitry.v.kiselev

हाय दिमित्री। क्या यह उस बिंदु के लिए काम करेगा जो लाइन से परे है यदि आप जानते हैं कि मेरा क्या मतलब है। उदाहरण के लिए, शीर्ष ने सबसे लाल डॉट छोड़ा, अगर यह 1 सेमी अधिक था। उस स्थिति में, निकटतम लाइन और बिंदु मूल रेखा के साथ एक समकोण नहीं बनाएंगे। क्या यह एल्गोरिथ्म उस मामले में काम करेगा?
जेनिया इवानोव

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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.