PostGIS का उपयोग करके सड़क चौराहों की पहचान करना


17

मैं यह पहचानने की कोशिश कर रहा हूं कि सड़कें एक-दूसरे को कैसे काटती हैं, और इस चौराहे पर एक बिंदु बनाने के लिए, चौराहे को सूचीबद्ध करने वाली सड़कों की संख्या के साथ।

यहाँ छवि विवरण दर्ज करें

मैं सोच रहा था कि क्या इसे प्राप्त करने के लिए ST_NumPoints का उपयोग करने का कोई तरीका था, लेकिन मैं यह पता नहीं लगा सकता कि मुझे क्या करना चाहिए। मैंने जो कुछ किया है वह बिंदुओं की एक तालिका बनाना है जहां पंक्तियाँ निम्नलिखित कोड का उपयोग करती हैं:

CREATE TABLE test_points as
SELECT      
    ST_Intersection(a.geom, b.geom),
    a.gid
FROM
    roads as a,
    roads as b
WHERE
    ST_Touches(a.geom, b.geom);

यदि मैं इसे सड़कों के नमूने पर चलाता हूं तो मुझे निम्नलिखित ग्रिड मिलते हैं (सड़कों को चित्रण के लिए दिखाया गया है):

यहाँ छवि विवरण दर्ज करें

यदि मैं किसी एक बिंदु का निरीक्षण करता हूं, तो मैं देखता हूं कि एक-दूसरे के ऊपर ढेर सारे बिंदु हैं:

यहाँ छवि विवरण दर्ज करें

यहां GID सड़क आईडी है, लेकिन मुझे समझ नहीं आता कि कुछ बिंदु क्यों हैं। मैं एक केंद्रीय सड़क चौराहे के लिए गिने जाने वाले 4 बिंदुओं को समझ सकता हूं, लेकिन यहां 12 बिंदु सूचीबद्ध हैं। क्या PostGIS में यह गणना करने का एक बेहतर तरीका है?

जवाबों:


21

यदि आप समूह बनाते हैं, तो आपको केवल अनन्य अंक प्राप्त करने चाहिए।

CREATE TABLE test_points as
SELECT      
    ST_Intersection(a.geom, b.geom),
    Count(Distinct a.gid)
FROM
    roads as a,
    roads as b
WHERE
    ST_Touches(a.geom, b.geom)
    AND a.gid != b.gid
GROUP BY
    ST_Intersection(a.geom, b.geom)
;

बस एक सूचना, ज्यामिति द्वारा समूहीकरण का परिणाम ज्यामिति के bbox द्वारा समूहीकरण में होता है, केवल ज्यामिति से नहीं। अंकों के साथ काम करते समय कोई फर्क नहीं पड़ता। हां तकरीबन। बॉक्स में उस बिंदु की तुलना में कम सटीकता होती है जो सिद्धांत में दो बिंदुओं को एक साथ समूहीकृत करने के लिए नेतृत्व कर सकता है जो समान नहीं हैं।
निकोलस एवेन

धन्यवाद @ NicklasAvén। Bbox की तुलना कितनी सटीक है? मुझे उम्मीद है कि यह इस उपयोग के मामले के लिए पर्याप्त होगा।
UnderDark

1
साभार @underdark क्या आप जानते हैं कि मैं उन पंक्तियों की संख्या कैसे गिन सकता हूं जो अंतरंग हैं? मैंने COUNT()इस तरह के कुछ संयोजनों की कोशिश की है COUNT(ST_Touches(..))और COUNT(ST_Intersection(..))यह सभी मानों के अनुसार काम नहीं करता है 12
djq

@underdark, हां यह बिल्कुल पर्याप्त है, यही कारण है कि मैंने "सिद्धांत रूप में" लिखा है। बॉक्स फ्लोट 4 में है और बिंदु का निर्देशांक दोहरी सटीकता में है। तो बॉक्स ST_Point (1.000001,1.0) और ST_Point (1.000002,1.0) के लिए समान दिखेगा (कम से कम मेरे सिस्टम पर, मैंने अभी-अभी कोशिश की है। यह एक साथ बिंदुओं को समूहित करता है)। बॉक्स और वास्तविक ज्यामिति के बीच का अंतर कुछ समय के लिए देव-सूची में व्यवधान रहा है।
निकोलस एवेन

देखें @AlexOs ने संशोधन का सुझाव दिया gis.stackexchange.com/a/151277/3195
मार्टिन एफ

6

यह एक छोटी सी चाल है जितना आप उम्मीद कर सकते हैं। ऐसा इसलिए है क्योंकि जोड़े से अधिक के लिए संबंधों का विश्लेषण करने का कोई अच्छा तरीका नहीं है। आप एक फ़ंक्शन में तीन लाइनें नहीं डाल सकते हैं और पूछ सकते हैं कि क्या वे सभी इंटरसेक्ट करते हैं।

लेकिन, कम से कम एक दृष्टिकोण पहले क्रॉसिंग को खोजने के लिए हो सकता है, फिर जांचें कि प्रत्येक क्रॉसिंग पर कितनी सड़कें छू रही हैं (यह सभी एक ही क्वेरी में किया जा सकता है)।

यदि आपकी सड़कें एक-दूसरे से पूरी तरह से जुड़ती हैं, और एक क्रॉसिंग से गुजरने वाली सड़कें नहीं हैं, तो आप ऐसा कुछ कर सकते हैं (परीक्षण नहीं किया गया):
भूल गए समूह खंड (अभी भी परीक्षण नहीं किया गया) के साथ संपादित किया गया :

SELECT distinct_crosspoints.geom as crossing, array_agg(roads.gid), count(*) FROM
  (SELECT DISTINCT (geom) geom FROM 
    (SELECT ST_Intersection(a.geom, b.geom) geom 
     FROM roads a, roads b 
     WHERE ST_Intersects(a.geom, b.geom)
    ) all_crosspoints
   ) distinct_crosspoints
   ,roads 
 WHERE ST_Intersects(distinct_crosspoints.geom, roads.geom)
 GROUP BY distinct_crosspoints.geom;

यदि सड़कों को ठीक से नहीं जोड़ा गया है और / या कुछ सड़कें एक क्रॉसिंग से गुजरती हैं तो यह अधिक जटिल है।

HTH

Nicklas


हाय @ निकल्स, मैं इसे चलाने में सक्षम नहीं हूं। दो आंतरिक खंड ठीक काम करते हैं; क्या मुझे distinct_crosspoints ,roadsअपने तालिका नाम ( roads_test) के साथ प्रतिस्थापित करना चाहिए ? मैंने कोशिश की थी लेकिन फिर geomअस्पष्ट होने के बारे में एक त्रुटि मिली ।
djq

1
@celenius, क्षमा करें, मैं समूह खंड को भूल गया था। मैं यह भी देखता हूं कि आपको एक अतिरिक्त स्तर पर अलग रखने की आवश्यकता नहीं है। आप इसे सीधे चौराहे पर रख सकते हैं। ध्यान दें कि डिस्टिंक में समूह के रूप में एक ही व्यवहार है, जो कि अंडरडार्क जवाब के तहत चर्चा के अनुसार है।
निकलस एवेन

क्वेरी को चलाने के लिए मैंने Nicklas के उत्तर में dif_crosspoints.geom को जोड़ा। अब मेरे लिए काम करता है।
फ्रैंक

1
 CREATE TABLE test_points as
    SELECT      
        ST_Intersection(a.geom, b.geom),
        Count(Distinct a.gid)
    FROM
        roads as a,
        roads as b
    WHERE
        ST_Touches(a.geom, b.geom)
        AND a.gid < b.gid   /* !!! Changed "!=" for "<"  */
    GROUP BY
        ST_Intersection(a.geom, b.geom)
    ;

यदि रेखा A (id 1) रेखा B (id 2) को पार करती है तो यह हमारे लिए आवश्यक प्रतिच्छेदन बिंदु है। लेकिन रेखा B भी इसी बिंदु पर रेखा A को पार करती है। लेकिन हमें दो बार इस बिंदु की आवश्यकता नहीं है। इसलिए मैं a.gid < b.gid इसके बजाय उपयोग कर रहा हूंa.gid != b.gid

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