কিউএসস্পটিয়ালআইডেক্সের ফিরিয়ে দেওয়া বৈশিষ্ট্যগুলি কীভাবে দক্ষতার সাথে অ্যাক্সেস করবেন?


9

PyQGIS Cookbook কিভাবে স্থানিক সূচক সেট আপ করার ব্যাখ্যা কিন্তু এটি শুধুমাত্র ব্যবহারের অর্ধেক ব্যাখ্যা করেছেন:

স্থানিক সূচক তৈরি করুন - নিম্নলিখিত কোডটি একটি খালি সূচি তৈরি করে

index = QgsSpatialIndex()

সূচকে বৈশিষ্ট্য যুক্ত করুন - সূচক QgsFeature অবজেক্ট নেয় এবং এটি অভ্যন্তরীণ ডেটা কাঠামোতে যুক্ত করে। আপনি বস্তুটি ম্যানুয়ালি তৈরি করতে পারেন বা সরবরাহকারীর পরবর্তী বৈশিষ্ট্যে পূর্ববর্তী কল থেকে একটি ব্যবহার করতে পারেন ()

index.insertFeature(feat)

একবার স্থানিক সূচক কিছু মান পূরণ করা হয়, আপনি কিছু প্রশ্ন করতে পারেন

# returns array of feature IDs of five nearest features
nearest = index.nearestNeighbor(QgsPoint(25.4, 12.7), 5)

প্রত্যাবর্তিত বৈশিষ্ট্য আইডির সাথে সম্পর্কিত প্রকৃত বৈশিষ্ট্যগুলি পেতে সবচেয়ে কার্যকর পদক্ষেপটি কী?

উত্তর:


12
    # assume a list of feature ids returned from index and a QgsVectorLayer 'lyr'
    fids = [1, 2, 4]
    request = QgsFeatureRequest()
    request.setFilterFids(fids)

    features = lyr.getFeatures(request)
    # can now iterate and do fun stuff:
    for feature in features:
        print feature.id(), feature

    1 <qgis._core.QgsFeature object at 0x000000000E987510>
    2 <qgis._core.QgsFeature object at 0x000000000E987400>
    4 <qgis._core.QgsFeature object at 0x000000000E987510>

ধন্যবাদ! স্নোরফালোরপ্যাগাস উল্লেখ করেছিলেন যে সেট ফিল্টারফিডগুলি তার পোস্ট করা সমাধানের চেয়ে যথেষ্ট ধীর হবে। আপনি এটি নিশ্চিত?
আন্ডার ডার্ক

আমি এটি বড় ফলাফলের সেটগুলিতে ব্যবহার করি নি তাই নিশ্চিত করতে পারছি না।
gsherman

1
আমি নিশ্চিত করি এবং আমার ক্ষেত্রে, rtree QgsSpatialIndex () এর চেয়েও বেশি দ্রুতগতির ( খুব বড় পলিইন স্তরগুলি থেকে প্ল্যানার গ্রাফগুলি নির্মাণের জন্য , পিকিউজিআইএসে শেপলির সাথে মডিউল প্লানারগ্রাফের স্থানান্তরিত করার জন্য But তবে ফিওনা, শেপালি এবং rtree এর সাথে সমাধানটি এখনও রয়েছে) দ্রুততম)
জিন

1
আমি বিশ্বাস করি যে প্রশ্নটি বিভিন্ন সূচক পদ্ধতির গতির চেয়ে প্রত্যাবর্তিত বৈশিষ্ট্য আইডিগুলি থেকে আসল বৈশিষ্ট্যগুলি অর্জন সম্পর্কে about
gesherman

7

ইন বিষয়ের উপর একটি ব্লগ পোস্টে , নাথান উডরো নিম্নলিখিত কোড প্রদান করে:

layer = qgis.utils.iface.activeLayer()

# Select all features along with their attributes
allAttrs = layer.pendingAllAttributesList()
layer.select(allAttrs)
# Get all the features to start
allfeatures = {feature.id(): feature for (feature) in layer}

def noindex():
    for feature in allfeatures.values():
        for f in allfeatures.values():
            touches = f.geometry().touches(feature.geometry())
            # It doesn't matter if we don't return anything it's just an example

def withindex():
    # Build the spatial index for faster lookup.
    index = QgsSpatialIndex()
    map(index.insertFeature, allfeatures.values())

    # Loop each feature in the layer again and get only the features that are going to touch.
    for feature in allfeatures.values():
        ids = index.intersects(feature.geometry().boundingBox())
        for id in ids:
            f = allfeatures[id]
            touches = f.geometry().touches(feature.geometry())
            # It doesn't matter if we don't return anything it's just an example

import timeit
print "With Index: %s seconds " % timeit.timeit(withindex,number=1)
print "Without Index: %s seconds " % timeit.timeit(noindex,number=1)

এটি একটি অভিধান তৈরি করে যাতে আপনি এটির এফআইডি ব্যবহার করে দ্রুত একটি QgsFEature সন্ধান করতে পারবেন।

আমি খুঁজে পেয়েছি যে খুব বড় স্তরগুলির জন্য এটি বিশেষত ব্যবহারিক নয় কারণ এর জন্য প্রচুর স্মৃতি দরকার requires তবে বিকল্পটি (পছন্দসই বৈশিষ্ট্যের এলোমেলো অ্যাক্সেস) layer.getFeatures(QgsFeatureRequest().setFilterFid(fid))তুলনামূলকভাবে খুব ধীর বলে মনে হচ্ছে। আমি নিশ্চিত না যে এটি কেন, কারণ এসডাব্লুআইজি ওজিআর বাইন্ডিংগুলি ব্যবহার করে সমতুল কলটি এর layer.GetFeature(fid)চেয়ে অনেক দ্রুত মনে হচ্ছে।


1
একটি অভিধান ব্যবহার তুলনায় খুব দ্রুত ছিল layer.getFeatures(QgsFeatureRequest().setFilterFid(fid))। আমি 140k বৈশিষ্ট্য সহ একটি স্তরে কাজ করছিলাম, এবং 140k লুকআপের মোট সময়টি বেশ কয়েক মিনিট থেকে সেকেন্ডে চলে গেল।
হাভার্ড টোভাইট

5

তুলনা করার জন্য, কিউজিআইএস, আর্কজিআইএস, পোস্টজিআইএস ইত্যাদি ব্যতীত পাইথন-আরও কার্যকর স্পিটিয়াল যোগদান দেখুন । সমাধান উপস্থাপন ব্যবহার পাইথন মডিউল Fiona, , সুষম এবং rtree (স্থানিক ইনডেক্স)।

পাইকিজিআইএস এবং একই উদাহরণ সহ দুটি স্তর pointএবং polygon:

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

1) একটি স্থানিক সূচক ছাড়া:

polygons = [feature for feature in polygon.getFeatures()]
points = [feature for feature in point.getFeatures()]
for pt in points: 
    point = pt.geometry()
    for pl  in polygons:
        poly = pl.geometry()
        if poly.contains(point):
            print point.asPoint(), poly.asPolygon()
(184127,122472) [[(183372,123361), (184078,123130), (184516,122631),   (184516,122265), (183676,122144), (183067,122570), (183128,123105), (183372,123361)]]
(183457,122850) [[(183372,123361), (184078,123130), (184516,122631), (184516,122265), (183676,122144), (183067,122570), (183128,123105), (183372,123361)]]
(184723,124043) [[(184200,124737), (185368,124372), (185466,124055), (185515,123714), (184955,123580), (184675,123471), (184139,123787), (184200,124737)]]
(182179,124067) [[(182520,125175), (183348,124286), (182605,123714), (182252,123544), (181753,123799), (181740,124627), (182520,125175)]]

2) আর-ট্রি পাইকজিআইজিএস স্থানিক সূচক সহ:

# build the spatial index with all the polygons and not only a bounding box
index = QgsSpatialIndex()
for poly in polygons:
     index.insertFeature(poly)

# intersections with the index 
# indices of the index for the intersections
for pt in points:
    point = pt.geometry()
    for id in index.intersects(point.boundingBox()):
    print id
0
0
1
2

এই সূচকগুলির অর্থ কী?

for i, pt in enumerate(points):
     point = pt.geometry()
     for id in index.intersects(point.boundingBox()):
        print "Point ", i, points[i].geometry().asPoint(), "is in Polygon ", id, polygons[id].geometry().asPolygon()
Point  1 (184127,122472) is in Polygon  0 [[(182520,125175), (183348,124286), (182605,123714), (182252,123544), (181753,123799), (181740,124627), (182520,125175)]]
Point  2 (183457,122850) is in Polygon  0 [[(182520,125175), (183348,124286), (182605,123714), (182252,123544), (181753,123799), (181740,124627), (182520,125175)]]
Point  4 (184723,124043) is in Polygon  1 [[(182520,125175), (183348,124286), (182605,123714), (182252,123544), (181753,123799), (181740,124627), (182520,125175)]]
Point  6 (182179,124067) is in Polygon  2 [[(182520,125175), (183348,124286), (182605,123714), (182252,123544), (181753,123799), (181740,124627), (182520,125175)]]

পাইথনে কিউজিআইএস, আর্কজিআইএস, পোস্টজিআইএস ইত্যাদি ছাড়াই অধিক দক্ষ স্পিটিয়াল যোগ দেওয়ার মতো একই সিদ্ধান্তে :

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

জিআইএস সে-র অন্যান্য উদাহরণ: কিউজিআইএস-এর একটি বিন্দুর নিকটতম লাইনটি কীভাবে খুঁজে পাবেন? [নকল]


সমস্ত অতিরিক্ত ব্যাখ্যার জন্য ধন্যবাদ। মূলত, আপনার সমাধানটি স্নোরফলোরপাগাসের মতো ডিকের পরিবর্তে একটি তালিকা ব্যবহার করে। সুতরাং সত্যিই কোনও স্তর নেই বলে মনে হচ্ছে। বিচ্ছিন্ন বৈশিষ্ট্যগুলি [[আইডি]] ফাংশন ...
আন্ডার ডার্ক

এই ব্যাখ্যা উদ্দেশ্য বিশুদ্ধরূপে জ্যামিতিক হয় এবং এটি একটি layer.getFeatures ([আইডি]) ফাংশন যোগ করা খুব সহজ হিসেবে আরও দক্ষ স্থানিক QGIS, ArcGIS, PostGIS, ইত্যাদি ছাড়া পাইথন যোগদান
জিন

0

দৃশ্যত ভাল পারফরম্যান্স পাওয়ার একমাত্র উপায় হ'ল লেয়ার.জেট ফিচারস () এ কলগুলি এড়ানো বা বান্ডিল করা, এমনকি যদি ফিল্টার কোনও ফিডের মতো সহজ is

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

উত্স: http://nyalldawson.net/2016/10/speeding-up-your-pyqgis-scriptts/

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