সুন্দরভাবে ব্যবহার করে পয়েন্টে নিকটতম লাইন বিভাগগুলি সন্ধান করছেন?


17

পটভূমি

একটি পরিচিত পয়েন্ট থেকে, ডায়াগ্রামের মতো দেখানো হয়েছে, মাল্টলাইনস্ট্রিংয়ের একটি টেবিলের বিপরীতে আমার নিকটতম কাছের "দৃশ্যমান পরিধি" স্থাপন করতে হবে।

আমি এই সাইটটি বেশ কয়েকটি শর্তাদি (যেমন সর্বনিম্ন প্রান্ত, ন্যূনতম পরিধি, নিকটতম প্রতিবেশী, ক্লিপ, বহুভুজ, দৃশ্যমানতা, স্ন্যাপ, কাটা নোড, রে-ট্রেস, বন্যা ভরাট, অভ্যন্তরীণ সীমানা, রাউটিং, অবতল হাল) সহ অনুসন্ধান করেছি এই দৃশ্যের সাথে মেলে এমন কোনও পূর্ববর্তী প্রশ্ন খুঁজে পাচ্ছে না।

নকশা

  • সবুজ বৃত্ত পরিচিত পয়েন্ট।
  • কৃষ্ণ রেখাগুলি হ'ল পরিচিত মাল্টিলাইনস্ট্রিংস।
  • ধূসর রেখাগুলি জানা পয়েন্ট থেকে রেডিয়াল সুইপের একটি ইঙ্গিত।
  • লাল পয়েন্টগুলি রেডিয়াল সুইপ এবং মাল্টিলাইনস্ট্রিংয়ের নিকটতম ছেদ হয়।

এখানে চিত্র বর্ণনা লিখুন

পরামিতি

  • পয়েন্টটি মাল্টিলাইনস্ট্রিংগুলি কখনও ছেদ করবে না।
  • পয়েন্টটি সর্বদা নামীকরণটি মাল্টলাইনস্ট্রিংয়ের মধ্যে থাকবে tered
  • মাল্টলাইন স্ট্রিংস কখনই পয়েন্টটি পুরোপুরি সংযুক্ত করে না, সুতরাং পরিধিটি একটি মাল্টলাইনস্ট্রিং হবে।
  • প্রায় এক হাজার মাল্টলাইনস্ট্রিংস (সাধারণত প্রায় এক পয়েন্টের একক লাইন থাকে) সমেত একটি টেবিল থাকবে।

পদ্ধতি বিবেচনা করা হয়

  • পরিচিত পয়েন্ট থেকে (বলুন, 1 ডিগ্রি বর্ধিত) একটি লাইন তৈরি করে রেডিয়াল সুইপ করুন।
  • মাল্টলাইনস্ট্রিংসের সাহায্যে প্রতিটি রেডিয়াল সুইপ লাইনের নিকটতম ছেদ বিন্দু স্থাপন করুন।
  • যখন কোনও রেডিয়াল সুইপ লাইন মাল্টলাইনস্ট্রিংয়ের কোনওটির সাথে ছেদ না করে, তখন এটি ঘের মধ্যে ব্যবধানকে চিহ্নিত করে যা ঘের মাল্টিলাইনস্ট্রিং নির্মাণে সংযুক্ত করা হবে।

সারসংক্ষেপ

যদিও এই কৌশলটি নিকটতম ছেদগুলি খুঁজে পাবে, এটি প্রয়োজনীয়ভাবে রেডিয়াল সুইপের রেজোলিউশনের উপর নির্ভর করে সমস্ত নিকটস্থ পেরিমিটার নোড পয়েন্টগুলি খুঁজে পাবে না। সমস্ত পেরিমিটার পয়েন্ট স্থাপন বা রেফিয়াল সুইপ কৌশলটি বাফারিং, সেক্টরিং বা অফসেটের কোনও ফর্ম দিয়ে পরিপূরক হিসাবে বিকল্প বিকল্প পদ্ধতির সুপারিশ করতে পারেন কেউ?

সফটওয়্যার

আমার পছন্দটি স্পাটিএলাইট এবং / অথবা সমাধানের জন্য শেপলি ব্যবহার করা তবে ওপেন সোর্স সফ্টওয়্যার ব্যবহার করে প্রয়োগ করা যেতে পারে এমন কোনও পরামর্শকে স্বাগত জানাই।

সম্পাদনা: কার্যনির্বাহী সমাধান (@ জেনের উত্তরের ভিত্তিতে)

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}})

সাধারণত একটি রেডিয়াল সুইপের কোনও অর্থবহ "রেজোলিউশন" থাকে না: এটি একটি "ইভেন্ট" থেকে পরের ক্রমানুসারে স্ক্যান করে, যেখানে ইভেন্টগুলি পলাইনগুলির মূল নোড এবং তাদের পারস্পরিক ছেদগুলির অন্তর্ভুক্ত থাকে (যা মূলটির চারপাশে ঝাড়ফুঁক করার সময় গতিশীলভাবে পাওয়া যায়) নোড)। এর আউটপুট পুরোপুরি নির্ভুল হবে।
হোবল

উত্তর:


17

আমি আপনার উদাহরণটি শেফফিল দিয়ে পুনরুত্পাদন করেছি।

আপনার সমস্যা সমাধানের জন্য আপনি শেপলি এবং ফায়োনা ব্যবহার করতে পারেন ।

1) আপনার সমস্যা (একটি সুন্দর সঙ্গে Point):

এখানে চিত্র বর্ণনা লিখুন

2) একটি স্বেচ্ছাচারী রেখা দিয়ে শুরু (পর্যাপ্ত দৈর্ঘ্য সহ):

from shapely.geometry import Point, LineString
line = LineString([(point.x,point.y),(final_pt.x,final_pt.y)])

এখানে চিত্র বর্ণনা লিখুন

৩) শেডলি.এফটিটি.আরোটেট ব্যবহার করে রেডিয়ি তৈরি করুন (বিন্দু থেকে লাইনটি ঘোরানো, মাইক টুউজের উত্তরটি পাইথন, সুদৃশ্য লাইব্রেরিতে দেখুন: শেপ বহুভুজের উপর অ্যাফাইন অপারেশন করা কি সম্ভব? ):

from shapely import affinity
# Rotate i degrees CCW from origin at point (step 10°)
radii= [affinity.rotate(line, i, (point.x,point.y)) for i in range(0,360,10)]

এখানে চিত্র বর্ণনা লিখুন

৪) এখন, একাধিক লাইনের স্ট্রিং পেতে সুদৃশ্য : ক্যাসকেড_উনিয়ন (বা সুদৃশ্য: unary_union ) ব্যবহার করুন:

from shapely.ops import cascaded_union
mergedradii = cascaded_union(radii)
print mergedradii.type
MultiLineString

5) মূল লাইনগুলির সাথে একই (শেফফাইল)

import fiona
from shapely.geometry import shape
orlines = fiona.open("orlines.shp")
shapes = [shape(f['geometry']) for f in orlines]
mergedlines = cascaded_union(shapes)
print mergedlines.type
MultiLineString

6) দুটি বহুগুণমিতির মধ্যে ছেদটি গণনা করা হয় এবং ফলাফলটি একটি শেফফাইলে সংরক্ষণ করা হয়:

 points =  mergedlines.intersection(mergedradii)
 print points.type
 MultiPoint
 from shapely.geometry import mapping
 schema = {'geometry': 'MultiPoint','properties': {'test': 'int'}}
 with fiona.open('intersect.shp','w','ESRI Shapefile', schema) as e:
      e.write({'geometry':mapping(points), 'properties':{'test':1}})

ফলাফল:

এখানে চিত্র বর্ণনা লিখুন

)) তবে সমস্যা, আপনি যদি এএ আর ব্যাসার্ধ ব্যবহার করেন তবে ফলাফলটি ভিন্ন:

এখানে চিত্র বর্ণনা লিখুন

8) এবং আপনি যদি নিজের ফলাফল পেতে চান তবে আপনাকে ব্যাসার্ধের মূল বিন্দু থেকে সবচেয়ে কম দূরত্বের সাথে কেবলমাত্র পয়েন্টটি নির্বাচন করতে হবে:

points_ok = []
for line in mergeradii:
   if line.intersects(mergedlines):
       if line.intersection(mergedlines).type == "MultiPoint":
          # multiple points: select the point with the minimum distance
          a = {}
          for pt in line.intersection(merged):
              a[point.distance(pt)] = pt
          points_ok.append(a[min(a.keys())])
       if line.intersection(mergedlines).type == "Point":
          # ok, only one intersection
          points_ok.append(line.intersection(mergedlines))
solution = cascaded_union(points_ok)
schema = {'geometry': 'MultiPoint','properties': {'test': 'int'}}
with fiona.open('intersect3.shp','w','ESRI Shapefile', schema) as e:
     e.write({'geometry':mapping(solution), 'properties':{'test':1}})

সর্বশেষ ফলাফল:

এখানে চিত্র বর্ণনা লিখুন

আমি আশা করি এটি আপনি চান


1
চমত্কার উত্তর - শেফফিলের মাধ্যমে ইনপুট / আউটপুট জন্য ফিওনা ব্যবহারের ক্ষেত্রে বিশেষভাবে তথ্যপূর্ণ। আমি আমার প্রশ্নের সাথে কিছু কোড যুক্ত করেছি যা আপনার উত্তরটি ব্যবহার করে এবং intersectionপ্রয়োজনীয় গণনার পরিমাণ হ্রাস করতে এটি সংশোধন করেছে - আপনাকে ধন্যবাদ।
মরিচা মাগু 21
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.