পাইকিজিআইএস-এ একটি লুপে একটি স্থানিক জিজ্ঞাসা করা


9

আমি যা করার চেষ্টা করছি: পয়েন্ট শেফফিলের মধ্য দিয়ে লুপ করুন এবং বহুভুজের মধ্যে পড়ে এমন প্রতিটি পয়েন্ট নির্বাচন করুন ।

নিম্নলিখিত কোডটি একটি বইয়ের মধ্যে পাওয়া একটি স্থানিক প্রশ্নের উদাহরণ দ্বারা অনুপ্রাণিত:

mitte_path = r"D:\PythonTesting\SelectByLocation\mitte.shp"
punkte_path = r"D:\PythonTesting\SelectByLocation\punkte.shp"

polygon = QgsVectorLayer(mitte_path, 'Mitte', 'ogr')
points = QgsVectorLayer(punkte_path, 'Berlin Punkte', 'ogr')

QgsMapLayerRegistry.instance().addMapLayer(polygon)
QgsMapLayerRegistry.instance().addMapLayer(points)

polyFeatures = polygon.getFeatures()

pointsCount = 0

for poly_feat in polyFeatures:
    polyGeom = poly_feat.geometry()
    pointFeatures = points.getFeatures(QgsFeatureRequest().setFilterRect(polyGeom.boundingBox()))
    for point_feat in pointFeatures:
        points.select(point_feat.id())
        pointsCount += 1

print 'Total:',pointsCount

এটি কাজ করে, এবং এটি ডেটাসেটগুলি নির্বাচন করে, তবে সমস্যাটি হ'ল এটি বাউন্ডিং বাক্স দ্বারা নির্বাচন করে , সুতরাং স্পষ্টতই পয়েন্টগুলি আমি ফিরিয়ে আনতে আগ্রহী না:

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

আমি কিউগিস ব্যবহার না করে বহুভুজের মধ্যে কেবলমাত্র ফিরে আসা পয়েন্টগুলি সম্পর্কে যেতে পারি: সিলেক্টলিওকেশন ?

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

উত্তর:


10

আপনি একটি বিশেষ ফাংশন প্রয়োজন হবে না (যেমন: "সত্যজিতের কাস্টিং"), সবকিছু (PyQGIS হয় রয়েছে () মধ্যে PyQGIS জ্যামিতি হ্যান্ডলিং )

polygons = [feature for feature in polygons.getFeatures()]
points = [feature for feature in points.getFeatures()]
for pt in points: 
     point = pt.geometry() # only and not pt.geometry().asPolygon() 
     for pol in polygons:
        poly = pol.geometry()
        if poly.contains(point):
             print "ok" 

বা এক লাইনে

 polygons = [feature for feature in polygons.getFeatures()]
 points = [feature for feature in points.getFeatures()]
 resulting = [pt for pt in points for poly in polygons if poly.geometry().contains(pt.geometry())]
 print len(resulting)
 ...

আপনি সরাসরি ব্যবহার করতে পারেন

[pt.geometry().asPoint() for pt in points for poly in polygons if poly.geometry().contains(pt.geometry())]

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



5

আপনি "রে কাস্টিং" অ্যালগরিদম ব্যবহার করতে পারেন যা আমি পাইকিজিআইএস-এর সাথে ব্যবহারের জন্য সামান্য মানিয়ে নিয়েছি:

def point_in_poly(point,poly):
    x = point.x()
    y = point.y()

    n = len(poly)
    inside = False

    p1x,p1y = poly[0]
    for i in range(n+1):
        p2x,p2y = poly[i % n]
        if y > min(p1y,p2y):
            if y <= max(p1y,p2y):
                if x <= max(p1x,p2x):
                    if p1y != p2y:
                        xints = (y-p1y)*(p2x-p1x)/(p2y-p1y)+p1x
                    if p1x == p2x or x <= xints:
                        inside = not inside
        p1x,p1y = p2x,p2y

    return inside

## Test
mapcanvas = iface.mapCanvas()

layers = mapcanvas.layers()

#For polygon 
polygon = [feature.geometry().asPolygon() 
            for feature in layers[1].getFeatures()]

points = [feat.geometry().asPoint() 
           for feat in layers[0].getFeatures()]

## Call the function with the points and the polygon
count = [0]*(layers[1].featureCount())

for point in points:
    i = 0
    for feat in polygon:
        if point_in_poly(point, feat[0]) == True:
            count[i] += 1
        i += 1

print count

এই পরিস্থিতিতে প্রয়োগ করা:

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

পাইথন কনসোলে ফলাফলটি ছিল:

[2, 2]

এটা কাজ করেছে.

সম্পাদনা নোট:

জিনের আরও সংক্ষিপ্ত প্রস্তাব সহ কোড :

mapcanvas = iface.mapCanvas()

layers = mapcanvas.layers()

count = [0]*(layers[1].featureCount())

polygon = [feature
           for feature in layers[1].getFeatures()]

points = [feature
          for feature in layers[0].getFeatures()]

for point in points:

    i = 0

    geo_point = point.geometry()

    for pol in polygon:
        geo_pol = pol.geometry()

        if geo_pol.contains(geo_point):
            count[i] += 1
        i += 1

print count

দুর্দান্ত রেফারেন্স এবং দুর্দান্ত উত্তর! আমি সবেমাত্র পোস্ট করেছি এমনটিকে আমি চিহ্নিত করব, তবে এটি সমাধান হিসাবে, যেমন এটি প্রয়োগ করা কিছুটা সহজ। যদিও আপনাকে প্রচুর পরিমাণে পুরষ্কার দেওয়া উচিত। আমার কাছ থেকে +1, অবশ্যই।
ব্রিটিশ স্টিল

আপনাকে নির্দিষ্ট করার দরকার নেই if geo_pol.contains(geo_point) == True:কারণ এটি if geo_pol.contains(geo_point)(সর্বদা সত্য)
জেন

3

সহকর্মীর কাছ থেকে কিছু পরামর্শ নিয়ে অবশেষে এটি () এর মধ্যে ব্যবহার করে কাজ করতে পেলাম।

সাধারণ যুক্তি

  1. বহুভুজের বৈশিষ্ট্য পান
  2. পয়েন্ট বৈশিষ্ট্য পেতে
  3. বহুভুজ ফাইল থেকে প্রতিটি বৈশিষ্ট্য লুপ এবং প্রতিটি জন্য:
    • জ্যামিতি পান
    • সমস্ত পয়েন্ট মাধ্যমে লুপ
      • একক পয়েন্টের জ্যামিতি পান
      • জ্যামিতি বহুভুজের জ্যামিতির মধ্যে থাকলে পরীক্ষা করুন

কোডটি এখানে:

mitte_path = r"D:\PythonTesting\SelectByLocation\mitte.shp"
punkte_path = r"D:\PythonTesting\SelectByLocation\punkte.shp"

poly = QgsVectorLayer(mitte_path, 'Mitte', 'ogr')
points = QgsVectorLayer(punkte_path, 'Berlin Punkte', 'ogr')

QgsMapLayerRegistry.instance().addMapLayer(poly)
QgsMapLayerRegistry.instance().addMapLayer(points)

polyFeatures = poly.getFeatures()
pointFeatures = points.getFeatures()

pointCounter = 0

for polyfeat in polyFeatures:
    polyGeom = polyfeat.geometry()
    for pointFeat in pointFeatures:
        pointGeom = pointFeat.geometry()
        if pointGeom.within(polyGeom):
            pointCounter += 1
            points.select(pointFeat.id())

print 'Total',pointCounter

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

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


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