क्यूजीआईएस के साथ पायथन का उपयोग करके क्रॉसिंग प्राप्त करने के लिए लाइनों का इरादा?


10

मेरे पास बस लाइनों का प्रतिनिधित्व करने वाली लाइनों का एक सेट है। कुछ लाइनें ओवरलैप हो रही हैं और वही सड़कें ले रही हैं।

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

मैं नोड्स निकालने में सक्षम हूं। यहां छवि विवरण दर्ज करें

हालाँकि मुझे इस तरह से केवल क्रॉसिंग निकालने में दिलचस्पी है: यहां छवि विवरण दर्ज करें

मैं यह कैसे कर सकता हूँ? मैं क्यूजीआईएस या पायथन के साथ तरीकों की तलाश कर रहा हूं।

मैंने GDAL पायथन से चौराहे की विधि की कोशिश की, लेकिन यह मूल रूप से मुझे केवल वर्टिकल लौटाता है।

लाइन चौराहे विधि QGIS से मुझे क्रॉसिंग लौटाता है यदि दो लाइनों को पार। हालाँकि इस मामले में कि दो बस लाइनें एक ही सड़क पर उनके मार्ग का बहुत भाग जाती हैं, इससे मुझे वे बिंदु नहीं मिलते जहाँ वे विलय करते हैं।


क्या आपने QGIS में लाइन चौराहे के उपकरण की कोशिश की है: वेक्टर विश्लेषण उपकरण> लाइन अंतर्संबंध ... यह आपको एक पंक्ति के अंत और शुरुआती नोड्स नहीं देगा, लेकिन सभी चौराहों।
जकॉब

हाँ, मैंने इस बारे में प्रश्न में लिखा था।
ustroetz

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

उसके आधार पर, जो मुझे लगता है कि आप चाहते हैं पाने के लिए, आपको दोनों विधियों का उपयोग करना पड़ सकता है। क्रॉसिंग (लाइन / लाइन = बिंदु) प्राप्त करें और फिर ओवरलैप (लाइन / लाइन = लाइन) प्राप्त करें और उन ओवरलैप लाइनों के लिए स्टार्ट / एंड नोड निकालें। उन सभी बिंदुओं / नोड्स होने चाहिए जिन्हें आप खोज रहे हैं।
क्रिस डब्ल्यू

जवाबों:


21

नोड्स:

आप दो चीजें चाहते हैं, पॉलीलाइन के अंत बिंदु (मध्यवर्ती नोड्स के बिना) और चौराहे के बिंदु। एक अतिरिक्त समस्या है, कुछ पॉलीलाइन अंत बिंदु भी चौराहे बिंदु हैं:

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

एक समाधान पायथन और मॉड्यूल शेपली और फियोना का उपयोग करना है

1) आकृति पढ़ें:

from shapely.geometry import Point, shape
import fiona
lines = [shape(line['geometry']) for line in fiona.open("your_shapefile.shp")]

2) लाइनों के अंत बिंदुओं का पता लगाएं ( एक पॉलीलाइन के अंत अंक कैसे प्राप्त करेंगे? )

endpts = [(Point(list(line.coords)[0]), Point(list(line.coords)[-1])) for line  in lines]
# flatten the resulting list to a simple list of points
endpts= [pt for sublist in endpts  for pt in sublist] 

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

3) चौराहों की गणना करें ( itertools मॉड्यूल के साथ परत में ज्यामितीय जोड़े के माध्यम से पुनरावृत्ति )। कुछ चौराहों का परिणाम मल्टीपॉइंट हैं और हम अंकों की एक सूची चाहते हैं:

import itertools
inters = []
for line1,line2 in  itertools.combinations(lines, 2):
  if  line1.intersects(line2):
    inter = line1.intersection(line2)
    if "Point" == inter.type:
        inters.append(inter)
    elif "MultiPoint" == inter.type:
        inters.extend([pt for pt in inter])
    elif "MultiLineString" == inter.type:
        multiLine = [line for line in inter]
        first_coords = multiLine[0].coords[0]
        last_coords = multiLine[len(multiLine)-1].coords[1]
        inters.append(Point(first_coords[0], first_coords[1]))
        inters.append(Point(last_coords[0], last_coords[1]))
    elif "GeometryCollection" == inter.type:
        for geom in inter:
            if "Point" == geom.type:
                inters.append(geom)
            elif "MultiPoint" == geom.type:
                inters.extend([pt for pt in geom])
            elif "MultiLineString" == geom.type:
                multiLine = [line for line in geom]
                first_coords = multiLine[0].coords[0]
                last_coords = multiLine[len(multiLine)-1].coords[1]
                inters.append(Point(first_coords[0], first_coords[1]))
                inters.append(Point(last_coords[0], last_coords[1]))

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

4) अंत बिंदुओं और चौराहों के बिंदुओं के बीच डुप्लिकेट को हटा दें (जैसा कि आप आंकड़ों में देख सकते हैं)

result = endpts.extend([pt for pt in inters  if pt not in endpts])

5) परिणामी आकृति को बचाएं

from shapely.geometry import mapping
# schema of the shapefile
schema = {'geometry': 'Point','properties': {'test': 'int'}}
# creation of the shapefile
with fiona.open('result.shp','w','ESRI Shapefile', schema) as output:
    for i, pt in enumerate(result):
        output.write({'geometry':mapping(pt), 'properties':{'test':i}})

अंतिम परिणाम:

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

रेखा खंड

यदि आप नोड्स के बीच के सेगमेंट भी चाहते हैं, तो आपको अपने शेपफाइल को "प्लानेराइज" करने की जरूरत है ( प्लेनर ग्राफ , कोई किनारा एक-दूसरे को पार न करें)। यह Shapely के unary_union फ़ंक्शन द्वारा किया जा सकता है

from shapely.ops import unary_union
graph = unary_union(lines)

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


विस्तृत उत्तर के लिए @gene धन्यवाद। मैंने उस हिस्से को संपादित किया जहां वह विभिन्न ज्यामितीय प्रकारों के ऊपर जाता है। मेरे मामले में चौराहा भी लाइनों, ज्यामिति, आदि को लौटाता है, लेकिन यह इनपुट डेटा पर निर्भर करता है। मैं अपने प्रश्न में पर्याप्त स्पष्ट नहीं था।
ustroetz

बहुत बढ़िया जवाब। क्या मैं यह जोड़ सकता हूं कि निम्न कार्य करना आवश्यक नहीं है: result = endpts.extend([pt for pt in inters if pt not in endpts])क्योंकि ऐसा प्रतीत होता है कि .extendविधि संशोधित होती है endptresult = Noneउस ऑपरेशन के बाद मेरे मामले में । यह वह endptsपरिणाम है जो समाप्त हो गया है
user32882
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.