पृष्ठभूमि
एक ज्ञात बिंदु से, मुझे मल्टीलाइन स्ट्रेस की तालिका के खिलाफ निकटतम "दृश्य परिधि" स्थापित करने की आवश्यकता है, जैसा कि आरेख पर दिखाया गया है।
मैंने इस साइट को कई शब्दों (जैसे न्यूनतम बढ़त, न्यूनतम परिधि, निकटतम पड़ोसी, क्लिप, बहुभुज, दृश्यता, स्नैप, कट नोड्स, रे-ट्रेस, बाढ़ भरण, आंतरिक सीमा, मार्ग, अवतल पतवार) के साथ खोजा है लेकिन कोई भी पिछला प्रश्न नहीं मिल सकता है जो इस परिदृश्य से मेल खाता हो।
आरेख
- हरा वृत्त ज्ञात बिंदु है।
- काली रेखाएँ मल्टीलाइन स्ट्रीम्स हैं।
- ग्रे लाइनें ज्ञात बिंदु से एक रेडियल स्वीप का संकेत हैं।
- रेड पॉइंट रेडियल स्वीप और मल्टीलाइनस्ट्रेस के निकटतम चौराहे हैं।
पैरामीटर
- प्वाइंट कभी मल्टीलाइनस्ट्रेस को इंटरसेक्ट नहीं करेगा।
- प्वाइंट हमेशा मल्टीलाइनस्ट्रीम के भीतर नाममात्र केंद्रित होगा।
- मल्टीलाइनस्ट्रेस कभी भी पॉइंट को पूरी तरह से नहीं घेरता है, इसलिए परिधि एक मल्टीलाइनरिंग होगी।
- इसमें लगभग 1,000 मल्टीलाइनस्ट्रेस (आमतौर पर लगभग 100 बिंदुओं की एक पंक्ति वाली) वाली तालिका होगी।
कार्यप्रणाली पर विचार किया
- ज्ञात बिंदु से लाइनों की एक श्रृंखला का निर्माण करके एक रेडियल स्वीप को अंडरटेक करें (पर, कहते हैं, 1 डिग्री वेतन वृद्धि)।
- मल्टीलाइन स्ट्रिंग्स के साथ प्रत्येक रेडियल स्वीप लाइन के निकटतम चौराहे बिंदु को स्थापित करें।
- जब रेडियल स्वीप लाइनों में से कोई भी मल्टीलाइनस्ट्रेस के साथ इंटरसेक्ट नहीं होता है, तो यह परिधि में एक अंतर को दर्शाता है जिसे परिधि मल्टीलाइन स्ट्रेन निर्माण में समायोजित किया जाएगा।
सारांश
जब भी यह तकनीक निकटतम चौराहों को खोजेगी, यह आवश्यक रूप से रेडियल स्वीप के संकल्प पर निर्भर सभी निकटतम परिधि नोड बिंदुओं को नहीं पाएगा। क्या सभी परिधि बिंदुओं को स्थापित करने के लिए कोई वैकल्पिक विधि सुझा सकता है या किसी प्रकार की बफरिंग, सेक्टरिंग या ऑफसेटिंग के साथ रेडियल स्वीप तकनीक को पूरक कर सकता है?
सॉफ्टवेयर
मेरी प्राथमिकता समाधान के लिए स्पैटियालाइट और / या शेपली का उपयोग करना है लेकिन किसी भी सुझाव का स्वागत करना होगा जिसे ओपन सोर्स सॉफ़्टवेयर का उपयोग करके लागू किया जा सकता है।
संपादित करें: वर्किंग सॉल्यूशन (@gene द्वारा उत्तर पर आधारित)
from shapely.geometry import Point, LineString, mapping, shape
from shapely.ops import cascaded_union
from shapely import affinity
import fiona
sweep_res = 10 # sweep resolution (degrees)
focal_pt = Point(0, 0) # radial sweep centre point
sweep_radius = 100.0 # sweep radius
# create the radial sweep lines
line = LineString([(focal_pt.x,focal_pt.y), \
(focal_pt.x, focal_pt.y + sweep_radius)])
sweep_lines = [affinity.rotate(line, i, (focal_pt.x, focal_pt.y)) \
for i in range(0, 360, sweep_res)]
radial_sweep = cascaded_union(sweep_lines)
# load the input lines and combine them into one geometry
input_lines = fiona.open("input_lines.shp")
input_shapes = [shape(f['geometry']) for f in input_lines]
all_input_lines = cascaded_union(input_shapes)
perimeter = []
# traverse each radial sweep line and check for intersection with input lines
for radial_line in radial_sweep:
inter = radial_line.intersection(all_input_lines)
if inter.type == "MultiPoint":
# radial line intersects at multiple points
inter_dict = {}
for inter_pt in inter:
inter_dict[focal_pt.distance(inter_pt)] = inter_pt
# save the nearest intersected point to the sweep centre point
perimeter.append(inter_dict[min(inter_dict.keys())])
if inter.type == "Point":
# radial line intersects at one point only
perimeter.append(inter)
if inter.type == "GeometryCollection":
# radial line doesn't intersect, so skip
pass
# combine the nearest perimeter points into one geometry
solution = cascaded_union(perimeter)
# save the perimeter geometry
schema = {'geometry': 'MultiPoint', 'properties': {'test': 'int'}}
with fiona.open('perimeter.shp', 'w', 'ESRI Shapefile', schema) as e:
e.write({'geometry':mapping(solution), 'properties':{'test':1}})