কিউজিআইএস, আর্কজিআইএস, পোস্টজিআইএস ইত্যাদি ব্যতীত পাইথনগুলিতে আরও দক্ষ স্পেশিয়াল যোগদান করুন


31

আমি এখানে উদাহরণের মতো একটি স্থানিক যোগদানের চেষ্টা করছি: "অবস্থান অনুসারে অ্যাট্রিবিউটসে যোগ দেওয়ার" অজগর বিকল্প আছে কি? । যাইহোক, এই পদ্ধতির সত্যই অদক্ষ / ধীর বলে মনে হচ্ছে। এমনকি সামান্য 250 পয়েন্ট সহ এটি চালাতে প্রায় 2 মিনিট সময় লাগে এবং এটি> 1000 পয়েন্ট সহ শেফফাইলে পুরোপুরি ব্যর্থ হয়। একটি ভাল পদ্ধতির আছে কি? আমি আর্কজিআইএস, কিউজিআইএস ইত্যাদি ব্যবহার না করে পাইথনে পুরোপুরি এটি করতে চাই

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

কোডটি রূপান্তর করার চেষ্টা করছি। 9 নং লাইনে আমি একটি ত্রুটি পেয়েছি:

poly['properties']['score'] += point['properties']['score']

যা বলে:

প্রকারের ত্রুটি: + =: 'ননটাইপ' এবং 'ফ্লোট' এর জন্য অসমর্থিত অপরেন্দ্র প্রকার (গুলি)।

যদি আমি "+" "কে" = "দিয়ে প্রতিস্থাপন করি তবে তা ঠিকঠাক চলতে পারে তবে ক্ষেত্রগুলির সমষ্টি হয় না। আমি এগুলি পূর্ণসংখ্যা হিসাবে তৈরি করার চেষ্টা করেছি তবে সেটিও ব্যর্থ হয়।

with fiona.open(poly_shp, 'r') as n: 
  with fiona.open(point_shp,'r') as s:
    outSchema = {'geometry': 'Polygon','properties':{'region':'str','score':'float'}}
    with fiona.open (out_shp, 'w', 'ESRI Shapefile', outSchema, crs) as output:
        for point in s:
            for poly in n:
                if shape(point['geometry']).within(shape(poly['geometry'])):  
                    poly['properties']['score']) += point['properties']['score'])
                    output.write({
                        'properties':{
                            'region':poly['properties']['NAME'],
                            'score':poly['properties']['score']},
                        'geometry':poly['geometry']})

আমি মনে করি আপনার এখান থেকে আপনার দ্বিতীয় প্রশ্নটি সম্পাদনা করা উচিত যাতে এটি আমার মনে করা বিষয়টির দিকে মনোযোগ কেন্দ্রীভূত থাকে আপনার কাছে আরও গুরুত্বপূর্ণ প্রশ্ন। অন্যটি আলাদাভাবে গবেষণা / জিজ্ঞাসা করা যেতে পারে।
পলিজিও

উত্তর:


37

ফিওনা পাইথন অভিধানগুলি ফেরত দেয় এবং আপনি poly['properties']['score']) += point['properties']['score'])অভিধানের সাহায্যে ব্যবহার করতে পারবেন না ।

মাইক টি দ্বারা প্রদত্ত রেফারেন্সগুলি ব্যবহার করে সংশ্লেষ বিশিষ্টতার উদাহরণ:

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

# read the shapefiles 
import fiona
from shapely.geometry import shape
polygons = [pol for pol in fiona.open('poly.shp')]
points = [pt for pt in fiona.open('point.shp')]
# attributes of the polygons
for poly in polygons:
   print poly['properties'] 
OrderedDict([(u'score', 0)])
OrderedDict([(u'score', 0)])
OrderedDict([(u'score', 0)])

# attributes of the points
for pt in points:
    print i['properties']
 OrderedDict([(u'score', 1)]) 
 .... # (same for the 8 points)

এখন, আমরা একটি স্থানিক সূচক সহ বা ছাড়াই দুটি পদ্ধতি ব্যবহার করতে পারি:

1) ছাড়া

# iterate through points 
for i, pt in enumerate(points):
     point = shape(pt['geometry'])
     #iterate through polygons
     for j, poly in enumerate(polygons):
        if point.within(shape(poly['geometry'])):
             # sum of attributes values
             polygons[j]['properties']['score'] = polygons[j]['properties']['score'] + points[i]['properties']['score']

২) আর-ট্রি ইনডেক্সের সাথে (আপনি পাইর্রি বা rtree ব্যবহার করতে পারেন )

# Create the R-tree index and store the features in it (bounding box)
 from rtree import index
 idx = index.Index()
 for pos, poly in enumerate(polygons):
       idx.insert(pos, shape(poly['geometry']).bounds)

#iterate through points
for i,pt in enumerate(points):
  point = shape(pt['geometry'])
  # iterate through spatial index
  for j in idx.intersection(point.coords[0]):
      if point.within(shape(multi[j]['geometry'])):
            polygons[j]['properties']['score'] = polygons[j]['properties']['score'] + points[i]['properties']['score']

দুটি সমাধানের সাথে ফলাফল:

for poly in polygons:
   print poly['properties']    
 OrderedDict([(u'score', 2)]) # 2 points in the polygon
 OrderedDict([(u'score', 1)]) # 1 point in the polygon
 OrderedDict([(u'score', 1)]) # 1 point in the polygon

পার্থক্য কি ?

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

পরে:

schema = fiona.open('poly.shp').schema
with fiona.open ('output.shp', 'w', 'ESRI Shapefile', schema) as output:
    for poly in polygons:
        output.write(poly)

আরও যেতে, ওজিআর , শেপলি , ফিয়োনার সাথে আর্ট্রি স্পেসিয়াল ইনডেক্সিং ব্যবহারটি দেখুন


15

অতিরিক্তভাবে - জিওপ্যান্ডগুলি এখন rtreeনির্ভরতা হিসাবে অন্তর্ভুক্ত রয়েছে, গিথুব রেপো দেখুন

সুতরাং, উপরের সমস্ত (খুব সুন্দর) কোড অনুসরণ না করে আপনি কেবল কিছু করতে পারেন:

import geopandas
from geopandas.tools import sjoin
point = geopandas.GeoDataFrame.from_file('point.shp') # or geojson etc
poly = geopandas.GeoDataFrame.from_file('poly.shp')
pointInPolys = sjoin(point, poly, how='left')
pointSumByPoly = pointInPolys.groupby('PolyGroupByField')['fields', 'in', 'grouped', 'output'].agg(['sum'])

এই স্নাজি কার্যকারিতা পেতে প্রথমে সি-লাইব্রেরি লাইপোস্যাটিআইল্যান্ডেক্স ইনস্টল করতে ভুলবেন না

সম্পাদনা: প্যাকেজ আমদানি সংশোধন করা হয়েছে


আমি ছাপ অধীনে rtreeছিল wasচ্ছিক। এর অর্থ এই নয় যে rtreeআপনার libspatialindexসি-লাইব্রেরির পাশাপাশি ইনস্টল করা দরকার ?
কুয়ানব

এটি কিছুক্ষণ হয়ে গেছে তবে আমি মনে করি আমি rtreeযখন প্রথম ইনস্টল করার পরে গিথুব থেকে স্বয়ংক্রিয়ভাবে জিওপান্ডা ইনস্টল libspatialindexকরেছি ... তারা বেশ কিছুটা বড় রিলিজ করেছে তাই আমি নিশ্চিত যে জিনিসগুলি কিছুটা বদলেছে
ক্লেটনশ্রুস

9

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

এখানে বা এখানে উদাহরণ দেখুন ।

'এসইউএম' সম্পর্কিত আপনার প্রশ্নের দ্বিতীয় অংশটি dictকী হিসাবে বহুভুজ আইডি ব্যবহার করে জনসংখ্যা জমানোর জন্য একটি অবজেক্ট ব্যবহার করুন। যদিও, পোস্টজিআইএস দিয়ে এই ধরণের জিনিসটি আরও সুন্দরভাবে করা হয়।


আপনাকে ধন্যবাদ @ মাইক টি ... ডিক্ট অবজেক্ট বা পোস্টজিআইএস ব্যবহার করা দুর্দান্ত পরামর্শ। আমি এখনও কিছুটা বিভ্রান্ত যেখানে আমি আমার কোডে আর্ট্রি অন্তর্ভুক্ত করতে পারি, তবে (উপরের কোডটি অন্তর্ভুক্ত)।
jburrfischer

1

এই ওয়েব পৃষ্ঠাটি দেখায় যে শেপিলির আরও ব্যয়বহুল প্রশ্নের মধ্যে বাউন্ডিং বক্স পয়েন্ট-ইন-বহুভুজ অনুসন্ধান কীভাবে ব্যবহার করতে হয়।

http://rexdouglass.com/fast-spatial-joins-in-python-with-a-spatial-index/


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

আপনি যদি 'আর' মোডে পাড়াটি খোলেন তবে এটি কেবল পঠনযোগ্য। উভয় শেফফাইলে কি মাঠের জনসংখ্যা রয়েছে? কোন লাইন # ত্রুটি ছুড়েছে? শুভকামনা।
ক্লিভিস

আবার আপনাকে ধন্যবাদ ক্লেউইস ... আমি উপরে আমার কোড যুক্ত করেছি এবং ত্রুটিটি ব্যাখ্যা করেছি। এছাড়াও, আমি চারপাশে আর্ট্রি নিয়ে খেলছি এবং আমি এখনও কিছুটা বিভ্রান্ত হয়েছি যেখানে আমি উপরের কোডটিতে এটি যুক্ত করব। এমন বিরক্তির জন্য দুঃখিত।
jburrfischer

এটি চেষ্টা করুন, মনে হয় কোনও অন্তর্ের সাথে কোনওটি যোগ করা ত্রুটির কারণ নয়। বহু_স্কোর = বহু ['বৈশিষ্ট্য'] [['স্কোর']) পয়েন্ট_স্কোর = পয়েন্ট ['বৈশিষ্ট্য'] ['স্কোর']) যদি পয়েন্ট_স্কোর: যদি পলি_স্কোর বহু ['বৈশিষ্ট্য'] ['স্কোর']) + = পয়েন্ট_স্কোর অন্য: বহু ['বৈশিষ্ট্য'] ['স্কোর']) = পয়েন্ট_স্কোর
ক্লিওস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.