शेडलाइन का उपयोग करके एक लाइनस्ट्रीमिंग में व्यक्तिगत लाइन सेगमेंट को वेल्ड करें


13

मैं अजगर में शेपली का उपयोग कर रहा हूं और मुझे वस्तुओं MultiLineStringका एक गुच्छा दिया गया है Linestring। मैं गारंटी दे सकता हूं कि सभी LineStringवस्तुएं केवल 2 कोने वाली सरल रेखाएं हैं और वे सभी एक पंक्ति (कोई शाखाएं) का हिस्सा नहीं हैं।

मैं "कनेक्ट-द-डॉट्स" चाहता हूं और एक सिंगल बनाता हूं LineString। क्या मुझे इसके लिए एक पुनरावर्ती वेल्डिंग विधि लिखने की आवश्यकता है या क्या कोई तेज़ तरीका है?

जवाबों:


20

आप उपयोग कर सकते हैं shapelys ' ops.linemergeयह पूरा करने के:

from shapely import geometry, ops

# create three lines
line_a = geometry.LineString([[0,0], [1,1]])
line_b = geometry.LineString([[1,1], [1,0]])
line_c = geometry.LineString([[1,0], [2,0]])

# combine them into a multi-linestring
multi_line = geometry.MultiLineString([line_a, line_b, line_c])
print(multi_line)  # prints MULTILINESTRING ((0 0, 1 1), (1 1, 2 2), (2 2, 3 3))

# you can now merge the lines
merged_line = ops.linemerge(multi_line)
print(merged_line)  # prints LINESTRING (0 0, 1 1, 2 2, 3 3)

# if your lines aren't contiguous
line_a = geometry.LineString([[0,0], [1,1]])
line_b = geometry.LineString([[1,1], [1,0]])
line_c = geometry.LineString([[2,0], [3,0]])

# combine them into a multi-linestring
multi_line = geometry.MultiLineString([line_a, line_b, line_c])
print(multi_line)  # prints MULTILINESTRING ((0 0, 1 1), (1 1, 1 0), (2 0, 3 0))

# note that it will now merge only the contiguous portions into a component of a new multi-linestring
merged_line = ops.linemerge(multi_line)
print(merged_line)  # prints MULTILINESTRING ((0 0, 1 1, 1 0), (2 0, 3 0))

मैं कैसे जान सकता हूं कि किस लिनेस्ट्रिंग का विलय किया गया था? मैं एक सूची प्राप्त करना चाहता हूं जैसे: मर्ज किया गया = [[line_a, line_b], [line_c]]
james

आप अपनी व्यक्तिगत लाइनों की एक सूची के माध्यम से लूप कर सकते हैं और यह जांच सकते हैं कि क्या नई विलय contains()से अलग-अलग लाइनें हैं। जो सम्‍मिलित नहीं होते वे विलीन नहीं होते। उदाहरण के लिए merged_line.contains(line_a)जो एक बूलियन TrueयाFalse
गीतोलो

बहुत बहुत धन्यवाद। यदि आप मर्ज किए गए_लाइन में रेखा समाहित करते हैं, तो आप कैसे जांच करेंगे?
जेम्स

1
आह, मुझे समझ नहीं आया कि ".contains (line_a)" एक पूर्व-लिखित कार्य था। उत्तम। आपका बहुत बहुत धन्यवाद !
जेम्स

1
क्षमा करें, आपको फिर से परेशान करने के लिए ... लेकिन क्या आप जानते हैं कि कौन रेखाएं "घनिष्ठ" (एक दूसरे से एक निश्चित अधिकतम दूरी के भीतर) विलय कर सकती हैं? मैं पूछ रहा हूं क्योंकि मैं कई लाइनें देख रहा हूं जिन्हें विलय कर दिया जाना चाहिए, लेकिन उनके बीच एक छोटी सी गैब के कारण उनका विलय नहीं हो रहा है।
जेम्स

2

मुझे लगता है कि आप इसे शेपली के साथ मिलकर कर सकते हैं।

ऐसा लगता है कि यह इनपुट के रूप में लाइनों की सूची ले सकता है और उन्हें मर्ज कर सकता है। मैंने पहले 'बहुभुज' विधि का उपयोग किया था और यह लाइनों की एक सूची लेती है।

यहाँ डॉक्टर पर एक नज़र डालें: http://toblerity.org/shapely/manual.html#shapely.ops.linlinerge


1
क्या आप जानते हैं कि उन लाइनों को कैसे मिलाया जाता है जो "करीब" हैं (एक दूसरे से एक अधिकतम अधिकतम दूरी के भीतर)?
जेम्स

polygonize_full कुछ बेहतर काम करता है, लेकिन मुझे कुछ अजीब datastructures नतीजतन
danuker

1

shapely.ops.linemerge()मेरी कुछ लाइनों के लिए असफल रहा, इसलिए मुझे इसे मैन्युअल रूप से करना पड़ा। यह उन पंक्तियों के लिए विफल हो जाता है जो अपने आप को "वापस" करते हैं, अर्थात, एक से अधिक बार एक ही बिंदु से गुजरना। मेरे मामले के लिए, मुझे पता है कि लाइनें सही क्रम में हैं इसलिए उन्हें विलय करने के लिए एक छोटा सा कार्य लिखना आसान था।

from shapely.geometry import LineString
from typing import List


def merge_lines(lines: List[LineString]) -> LineString:
    last = None
    points = []
    for line in merged_line:
        current = line.coords[0]

        if last is None:
            points.extend(line.coords)
        else:
            if last == current:
                points.extend(line.coords[1:])
            else:
                print('Skipping to merge {} {}'.format(last, current))
                return None
        last = line.coords[-1]
    return LineString(points)

आशा है कि यह किसी की मदद करता है


0

shapely.ops.linemergeकाम करता है अगर लाइनें सन्निहित हैं ("युक्तियां" घटक लाइनों के "पूंछ" के साथ मेल खाती हैं), लेकिन अगर वे गैर-संक्रामक हैं (यदि युक्तियों और पूंछ के बीच एक अंतर है) तो यह एक और मल्टीलाइनरिंग लौटाता है। यदि आपकी घटक रेखाएँ अच्छी तरह से क्रमबद्ध हैं (अगली पंक्ति की शुरुआत के पास एक पंक्ति समाप्त हो रही है) लेकिन एक टिप-टू-टेल गैप है, तो आप निर्देशांक निकाल सकते हैं और उनका उपयोग करके एक नई सरल रेखा बना सकते हैं। यह दृष्टिकोण अधिक जटिल सबलाइन्स (यानी दो से अधिक बिंदुओं वाली सबलाइन्स) से बनी बहु-लाइनों के लिए भी काम करता है।

import shapely

# Make a MultiLineString to use for the example
inlines = shapely.geometry.MultiLineString(
    [shapely.geometry.LineString([(0,0),(0,0.9)]), 
     shapely.geometry.LineString([(0,1),(1,1)])]
)

# Put the sub-line coordinates into a list of sublists
outcoords = [list(i.coords) for i in inlines]

# Flatten the list of sublists and use it to make a new line
outline = shapely.geometry.LineString([i for sublist in outcoords for i in sublist])
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.