পাইথনে দক্ষতার সাথে একাধিক বহুভুজের ছেদ পাওয়া


12

আমি একাধিক বহুভুজের ছেদ পেতে চাই। পাইথনের shapelyপ্যাকেজটি ব্যবহার করে, intersectionফাংশনটি ব্যবহার করে দুটি বহুভুজের ছেদ খুঁজে পেতে পারি । একাধিক বহুভুজের ছেদ পাওয়ার জন্য কি একই রকম কার্যকর কার্যকারিতা রয়েছে?

আমার অর্থটি বোঝার জন্য এখানে একটি কোড স্নিপেট দেওয়া হয়েছে:

from shapely.geometry import Point

coord1 = ( 0,0 )
point1 = Point(coord1)
circle1 = point1.buffer(1)

coord2 = ( 1,1 )
point2 = Point(coord2)
circle2 = point2.buffer(1)

coord3 = ( 1,0 )
point3 = Point(coord3)
circle3 = point3.buffer(1) 

দুটি চেনাশোনাগুলির একটি ছেদ পাওয়া যায় circle1.intersection(circle2)। আমি তিনটি বৃত্তের ছেদটি দ্বারা খুঁজে পেতে পারি circle1.intersection(circle2).intersection(circle3)। যাইহোক, এই পদ্ধতির বহু সংখ্যক বহুভুজের পক্ষে বিক্রয়যোগ্য নয় কারণ এর জন্য ক্রমবর্ধমান আরও কোডের প্রয়োজন। আমি এমন একটি ফাংশন চাই যা একটি বহুবিধ সংখ্যা নির্বিচারে নেয় এবং তাদের ছেদটি ফেরত দেয়।


আমি ভাবছি হয়ত এর অভিধানগুলি আমদানি সংমিশ্রণগুলি ব্যবহার করার সময় কোনও অভিধানে কর্ডগুলি সঞ্চয় করে এটির মধ্য দিয়ে লুপ করুন। আমি শীঘ্রই পোস্ট করব
জিগি

"তাদের ছেদগুলি" বলতে কী বোঝ? আপনি সব ক্ষেত্র থাকে যেগুলো অন্তত এক অন্য বহুভুজ, অথবা ক্ষেত্র থাকে যেগুলো ছেদ করে মানে কি সব ইনপুট ছেদ?
jpmc26

আমি বলতে চাই সমস্ত বহুভুজের ছেদটি অন্তত একটি নয়।
বিভক্ত 21

আপনার উপরে এটি স্পষ্ট করা উচিত (সম্ভবত একটি উদাহরণ আউটপুট সহ)। আমি মোটামুটি নিশ্চিত হয়েছি বেশিরভাগ উত্তর আপনার ইচ্ছামতো আচরণ করে না । (এবং বেশিরভাগ উত্তরদাতারা যে ভুল
ধারণাটি পেয়েছেন

1
@ jpmc26 আমি আমার উত্তরে সবেমাত্র একটি আপডেট যুক্ত করেছি যেখানে rtree ব্যবহৃত হয়। পদ্ধতির এখন আরও দক্ষ এবং স্কেলযোগ্য। আশাকরি এটা সাহায্য করবে!
আন্তোনিও ফ্যালকিয়ানো

উত্তর:


7

একটি সম্ভাব্য পদ্ধতির মধ্যে বহুভুজগুলির জোড়গুলির সংমিশ্রণ, তাদের ছেদগুলি এবং অবশেষে ক্যাসকেড ইউনিয়নের মাধ্যমে সমস্ত ছেদগুলির সংযোগ বিবেচনা করা যেতে পারে (যেমন প্রস্তাবিত এখানে ):

from shapely.geometry import Point
from shapely.ops import cascaded_union
from itertools import combinations

circles = [
    Point(0,0).buffer(1),
    Point(1,0).buffer(1),
    Point(1,1).buffer(1),
]

intersection = cascaded_union(
    [a.intersection(b) for a, b in combinations(circles, 2)]
)
print intersection

প্রচুর জ্যামিতির (তিনটি বৃত্তের ক্ষেত্রে নয়) মোকাবেলা করার জন্য আরও দক্ষ পদ্ধতির একটি Rtree এর মতো একটি স্থানিক সূচক ব্যবহার করা উচিত :

from shapely.geometry import Point
from shapely.ops import cascaded_union
from rtree import index

circles = [
    Point(0,0).buffer(1),
    Point(1,0).buffer(1),
    Point(1,1).buffer(1),
]
intersections = []
idx = index.Index()

for pos, circle in enumerate(circles):
    idx.insert(pos, circle.bounds)

for circle in circles:
    merged_circles = cascaded_union([circles[pos] for pos in idx.intersection(circle.bounds) if circles[pos] != circle])
    intersections.append(circle.intersection(merged_circles))

intersection = cascaded_union(intersections)
print intersection

আমি বিশ্বাস করি না এটি ওপি যা চায় তা করে। এটি এমন অঞ্চলগুলিকে ফিরিয়ে দেয় যা কমপক্ষে ২ টি বহুভুজ কভার করে, যেখানে ওপি কেবলমাত্র সেটের সমস্ত বহুভুজ দ্বারা আচ্ছাদিত অঞ্চলগুলি সন্ধান করছে । মন্তব্য স্পষ্টতা দেখুন।
jpmc26

3

পুনরাবৃত্তি বা পুনরাবৃত্তি কেন ব্যবহার করবেন না? কিছুটা এইরকম :

from shapely.geometry import Point

def intersection(circle1, circle2):
    return circle1.intersection(circle2)

coord1 = ( 0,0 )
point1 = Point(coord1)
circle1 = point1.buffer(1)

coord2 = ( 1,1 )
point2 = Point(coord2)    
circle2 = point2.buffer(1)


coord3 = ( 1,0 )
point3 = Point(coord3)
circle3 = point3.buffer(1)
circles = [circle1, circle2, circle3]
intersectionResult = None

for j, circle  in enumerate(circles[:-1]):

    #first loop is 0 & 1
    if j == 0:
        circleA = circle
        circleB = circles[j+1]
     #use the result if the intersection
    else:
        circleA = intersectionResult
        circleB = circles[j+1]
    intersectionResult = intersection(circleA, circleB)

result= intersectionResult

2

এই কোডটি শট দিন। ধারণাটিতে এটি বেশ সহজ এবং আমি বিশ্বাস করি আপনি যা সন্ধান করছেন তা আপনাকে পেয়ে যায়।

from shapely.geometry import Point
from itertools import combinations
dic ={}
dic['coord1']=Point(0,0).buffer(1)
dic['coord2']=Point(1,1).buffer(1)
dic['coord3']=Point(1,0).buffer(1)
inter = {k[0]+v[0]:k[1].intersection(v[1]) for k,v in combinations(dic.items(),2)}
print inter

এবং আপনি যদি আউটপুটটি শেফফাইল ব্যবহার ফিয়োনা হিসাবে সঞ্চয় করতে চান:

from shapely.geometry import Point,mapping
import fiona
from itertools import combinations
schema = {'geometry': 'Polygon', 'properties': {'Place': 'str'}}
dic ={}
dic['coord1']=Point(0,0).buffer(1)
dic['coord2']=Point(1,1).buffer(1)
dic['coord3']=Point(1,0).buffer(1)
inter = {k[0]+v[0]:k[1].intersection(v[1]) for k,v in combinations(dic.items(),2)}
print inter
with fiona.open(r'C:\path\abid', "w", "ESRI Shapefile", schema) as output:
    for x,y in inter.items():
        output.write({'properties':{'Place':x},'geometry':mapping(y)})

এই ফলাফল -

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


3
আমি বিশ্বাস করি না এটি ওপি যা চায় তা করে। এটি এমন অঞ্চলগুলিকে ফিরিয়ে দেয় যা কমপক্ষে ২ টি বহুভুজ কভার করে, যেখানে ওপি কেবলমাত্র সেটের সমস্ত বহুভুজ দ্বারা আচ্ছাদিত অঞ্চলগুলি সন্ধান করছে । মন্তব্য স্পষ্টতা দেখুন। অতিরিক্তভাবে, kএবং vআপনার dictবোধগম্যতে পরিবর্তনশীল নামের জন্য দুর্বল পছন্দ । এই ভেরিয়েবলগুলি প্রতিটি dic.items()কী-মূল্যের জোড় নয়, এর বিভিন্ন উপাদানকে বোঝায় । এরকম কিছু a, bকম বিভ্রান্তিকর হবে।
jpmc26

1
ওহ ঠিক আছে হ্যাঁ আমি কী বোঝাতে
চাইছিলাম

এবং আমার কে, ভি পছন্দগুলি সম্পর্কে ভালভাবে বিবেচনা করা হয়েছে - কোনও অভিধানের মধ্য দিয়ে লুপ করার সময় আমি কেবল স্বয়ংক্রিয়ভাবে কে, ভি ব্যবহার
করি..এটি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.