कैसे कोण की गणना करने के लिए जिस पर दो लाइनें PostGIS में प्रतिच्छेद करती हैं?


19

मैं दो लाइनों के बीच के कोण की गणना करना चाहता हूं जहां वे PostGIS में अंतर करते हैं।

PostGIS में कोण की गणना के लिए प्रारंभिक बिंदु हो रहा है ST_Azimuth - लेकिन यह है कि इनपुट के रूप में अंक लेता है। मेरा पहला विचार अन्तर्विभाजक लाइनों के अंत बिंदुओं को लेना और उन पर एक अजीमुथ गणना करना था। यह काफी अच्छा नहीं है, क्योंकि ज्यादातर लाइन की विशेषताएं सीधी नहीं हैं, और मुझे चौराहे पर कोण में दिलचस्पी है। तो मैं एक नेस्टेड ऑपरेशन के साथ आया था जो निम्नलिखित चरणों से गुजरता है:

  1. दो पंक्ति सुविधा तालिकाओं के बीच के सभी चौराहों को पहचानें।
  2. चौराहे बिंदु के आसपास एक बहुत छोटा बफर बनाएं
  3. उन बिंदुओं को पहचानें जहां रेखा की विशेषताएं बफर बाहरी को काटती हैं (पहला बिंदु लेने पर अगर एक से अधिक हैं - मुझे वास्तव में केवल इस बात में दिलचस्पी है कि क्या कोण 0, 90 या 180 डिग्री के करीब है)
  4. उन दो बिंदुओं के लिए ST_Azimuth की गणना करें।

पूर्ण एसक्यूएल यहाँ पोस्ट करने के लिए लंबा है, लेकिन अगर आप रुचि रखते हैं, तो मैंने इसे यहाँ प्रस्तुत किया । (वैसे, क्या बयानों के साथ नीचे जाने वाले सभी क्षेत्रों को ले जाने की तुलना में बेहतर तरीका है?)

परिणाम सही नहीं लगते हैं, इसलिए मैं स्पष्ट रूप से कुछ गलत कर रहा हूं:

आउटपुट उदाहरण 1 आउटपुट उदाहरण 2

EDIT I ​​की गणना EPSG: 3785 में की गई है और परिणाम थोड़े अलग हैं लेकिन फिर भी सही नहीं हैं:

3785 # 1 में आउटपुट 3785 # 2 में आउटपुट

मेरा सवाल है कि इस प्रक्रिया में खामियां कहां हैं। क्या मैं गलत समझ रहा हूं कि ST_Azimuth क्या करता है? क्या कोई सीआरएस मुद्दा है? कुछ और पूरी तरह से? या शायद ऐसा करने के लिए एक बहुत, बहुत सरल तरीका है?


1
मूल सीआरएस क्या था? कोण की गणना एक अनुरूप प्रक्षेपण के साथ की जानी चाहिए - असंसाधित लैट / लंबे (SRID = 4326) के साथ नहीं।
माइक टी

यह EPSG था: 4326 मूल रूप से समन्वय करता है, मैंने ST_Translate को केवल 100% शामिल किया है सुनिश्चित करें कि सभी प्रसंस्करण एक ही CRS में किया जाएगा। मैं एक अनुरूप प्रक्षेपण की कोशिश करूंगा, धन्यवाद।
मावेक्सेल

मैं गणनाओं को ईपीएसजी: 3785 से छुटकारा देता हूं और इससे फर्क पड़ता है - मैं नए परिणाम दिखाने के लिए प्रश्न में संशोधन करूंगा - लेकिन परिणाम अभी भी वास्तविक कोण को प्रतिबिंबित नहीं करता है।
mvexel

जवाबों:


12

मुझे एपिफनी थी। बल्कि सांसारिक है। मैं सही कोण की गणना करने के लिए PostGIS के लिए एक आवश्यक जानकारी को छोड़ रहा था।

मैं जो गणना कर रहा था वह केवल दो बिंदुओं के बीच का कोण था जो छोटे बफर बाहरी को काट रहा था। चौराहे के कोण की गणना करने के लिए, मुझे बफर बाहरी पर दोनों बिंदुओं के बीच के दोनों कोणों की गणना करने और दो पंक्ति सुविधाओं के चौराहे बिंदु की आवश्यकता है और उन्हें घटाएं।

मैंने पूर्ण एसक्यूएल को अपडेट किया है , लेकिन यहां मुख्य बिट है:

SELECT
    ...
    abs
    (
        round
        (
            degrees
            (
            ST_Azimuth
            (
                points.point2,
                points.intersection
            )
            -
            ST_Azimuth
            (
                points.point1,
                points.intersection
            )
        )::decimal % 180.0
        ,2
    )
)
AS angle
...
FROM
points 

1
मैं बफ़र पॉइंट के कोण के बारे में सोच रहा था कि आपस में तालमेल बिठाएँ, लेकिन मुझे विस्तार में जाने का कोई समय नहीं है। एक अन्य पहलू कोणीय इकाइयाँ हैं। आपको डिग्रियों में परिणाम प्राप्त करने के लिए परिणाम को ST_Azimuth से रेडियन में 180.0 / pi () तक गुणा करना होगा।
माइक टी

हां धन्यवाद, मैं उस के लिए PostgreSQL डिग्री () फ़ंक्शन का उपयोग करता हूं।
मुवेक्सेल

क्लीवर। (मुझे यह भी नहीं पता था कि अब तक एक डिग्री फ़ंक्शन था।) यह सब तर्क एक फ़ंक्शन कॉल में लपेटना अच्छा होगा, लेकिन मुझे यह कल्पना करने में कठिनाई हो रही है कि यह कैसे काम करेगा, अर्थात ST_IntersectionAngle(...?
माइक टी

मुझे वास्तव में आश्चर्य हुआ कि यह पोस्टजीआईएस फ़ंक्शन नहीं है। इस पर आपकी प्रतिक्रिया के लिए धन्यवाद।
मुवेक्सेल

2

मुझे हाल ही में एक ही चीज़ की गणना करनी थी, लेकिन एक सरल और संभावित तेज़ दृष्टिकोण पर निर्णय लिया।

दिगंश गणना के लिए अतिरिक्त बिंदुओं को खोजने के लिए, मैं अभी ST_Line_Locate_Point और ST_Line_Interpolate_Point का उपयोग करके चौराहे के पीछे की लंबाई (या दुर्लभ स्थिति में ऐसा होता है कि लाइन के बहुत शुरुआत में ऐसा होता है) की जाँच करें।

abs(degrees( 
  ST_Azimuth (
    intersection, 
    ST_Line_Interpolate_Point(
      line1, 
      abs(ST_Line_Locate_Point(line1, intersection) - 0.0001)
    )
  )
  -
  ST_Azimuth (
    intersection, 
    ST_Line_Interpolate_Point(
      line2, 
      abs(ST_Line_Locate_Point(line2, intersection) - 0.0001)
    )
  )
))

पर्मियाड मनमाना था और अधिक सुसंगत परिणामों के लिए एक पूर्ण ऑफसेट का उपयोग करना बेहतर होगा। उदाहरण के लिए पहले से 20 मीटर की जाँच करें, आप क्रमशः 0.0001 20/ST_Length(line1)और बदलेंगे 20/ST_Length(line2)

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