OGR और शेपली का अधिक कुशलता से उपयोग करना? [बन्द है]


29

मैं अपने अजगर कोड को और अधिक कुशल बनाने के बारे में कुछ सुझावों की तलाश कर रहा हूं। आम तौर पर दक्षता मेरे लिए मायने नहीं रखती है, लेकिन मैं अब 1.5 मिलियन से अधिक अंकों के साथ अमेरिकी स्थानों की एक पाठ फ़ाइल के साथ काम कर रहा हूं। दिए गए सेटअप के साथ एक बिंदु पर संचालन चलाने के लिए लगभग 5 सेकंड लग रहे हैं; मुझे इस आंकड़े को नीचे लाने की जरूरत है।

मैं तीन अलग-अलग अजगर जीआईएस पैकेज का उपयोग अंकों पर कुछ अलग संचालन करने और एक नई सीमांकित पाठ फ़ाइल को आउटपुट करने के लिए कर रहा हूं।

  1. मैं एक काउंटी सीमा आकृति को पढ़ने के लिए OGR का उपयोग करता हूं और सीमा ज्यामिति तक पहुंच प्राप्त करता हूं।
  2. यह देखने के लिए कि कोई बिंदु इन काउंटियों में से किसी के भीतर है या नहीं।
  3. यदि यह एक के भीतर है, तो मैं बाउंड्री .dbf से विशेषता जानकारी खींचने के लिए पायथन शेपफाइल लाइब्रेरी का उपयोग करता हूं।
  4. फिर मैं दोनों स्रोतों से एक पाठ फ़ाइल के लिए कुछ जानकारी लिखता हूं।

मुझे संदेह है कि अक्षमता 2-3 स्तरीय लूप होने में निहित है ... निश्चित रूप से नहीं कि इसके बारे में क्या करना है। मैं विशेष रूप से इन 3 पैकेजों में से किसी का उपयोग करने में अनुभवी किसी के साथ मदद की तलाश कर रहा हूं, क्योंकि यह उनमें से किसी का उपयोग करने का मेरा पहला अवसर है।

import os, csv
from shapely.geometry import Point
from shapely.geometry import Polygon
from shapely.wkb import loads
from osgeo import ogr
import shapefile

pointFile = "C:\\NSF_Stuff\\NLTK_Scripts\\Gazetteer_New\\NationalFile_20110404.txt"
shapeFolder = "C:\NSF_Stuff\NLTK_Scripts\Gazetteer_New"
#historicBounds = "C:\\NSF_Stuff\\NLTK_Scripts\\Gazetteer_New\\US_Counties_1860s_NAD"
historicBounds = "US_Counties_1860s_NAD"
writeFile = "C:\\NSF_Stuff\\NLTK_Scripts\\Gazetteer_New\\NewNational_Gazet.txt"

#opens the point file, reads it as a delimited file, skips the first line
openPoints = open(pointFile, "r")
reader = csv.reader(openPoints, delimiter="|")
reader.next()

#opens the write file
openWriteFile = open(writeFile, "w")

#uses Python Shapefile Library to read attributes from .dbf
sf = shapefile.Reader("C:\\NSF_Stuff\\NLTK_Scripts\\Gazetteer_New\\US_Counties_1860s_NAD.dbf")
records = sf.records()
print "Starting loop..."

#This will loop through the points in pointFile    
for row in reader:
    print row
    shpIndex = 0
    pointX = row[10]
    pointY = row[9]
    thePoint = Point(float(pointX), float(pointY))
    #This section uses OGR to read the geometry of the shapefile
    openShape = ogr.Open((str(historicBounds) + ".shp"))
    layers = openShape.GetLayerByName(historicBounds)
    #This section loops through the geometries, determines if the point is in a polygon
    for element in layers:
        geom = loads(element.GetGeometryRef().ExportToWkb())
        if geom.geom_type == "Polygon":
            if thePoint.within(geom) == True:
                print "!!!!!!!!!!!!! Found a Point Within Historic !!!!!!!!!!!!"
                print str(row[1]) + ", " + str(row[2]) + ", " + str(row[5]) + " County, " + str(row[3])
                print records[shpIndex]
                openWriteFile.write((str(row[0]) + "|" + str(row[1]) + "|" + str(row[2]) + "|" + str(row[5]) + "|" + str(row[3]) + "|" + str(row[9]) + "|" + str(row[10]) + "|" + str(records[shpIndex][3]) + "|" + str(records[shpIndex][9]) + "|\n"))
        if geom.geom_type == "MultiPolygon":
            for pol in geom:
                if thePoint.within(pol) == True:
                    print "!!!!!!!!!!!!!!!!! Found a Point Within MultiPolygon !!!!!!!!!!!!!!"
                    print str(row[1]) + ", " + str(row[2]) + ", " + str(row[5]) + " County, " + str(row[3])
                    print records[shpIndex]
                    openWriteFile.write((str(row[0]) + "|" + str(row[1]) + "|" + str(row[2]) + "|" + str(row[5]) + "|" + str(row[3]) + "|" + str(row[9]) + "|" + str(row[10]) + "|" + str(records[shpIndex][3]) + "|" + str(records[shpIndex][9]) + "|\n"))
        shpIndex = shpIndex + 1
    print "finished checking point"
    openShape = None
    layers = None


pointFile.close()
writeFile.close()
print "Done"

3
आप इस पर विचार कर सकते हैं @ कोड की समीक्षा करें: codereview.stackexchange.com
रयानडाल्टन

जवाबों:


21

पहला कदम शेप लूप को पंक्तियों लूप के बाहर ले जाने के लिए होगा, आप शेपफाइल को 1.5 मिलियन बार खोल और बंद कर रहे हैं।

हालांकि ईमानदार होने के लिए मैं PostGIS में पूरी सामग्री भर दूंगा और इसे अनुक्रमित तालिकाओं पर SQL का उपयोग करूँगा।


19

आपके कोड पर एक त्वरित नज़र मन में कुछ अनुकूलन लाती है:

  • स्पष्ट आउटलेर्स को खत्म करने के लिए, बहुभुज के बाउंडिंग बॉक्स / लिफाफे के खिलाफ प्रत्येक बिंदु की जांच करें। आप एक कदम आगे जा सकते हैं और एक बिंदु पर निहित एक बॉक्स की संख्या की गणना कर सकते हैं, अगर यह बिल्कुल एक है, तो इसे और अधिक जटिल ज्यामिति के खिलाफ परीक्षण करने की आवश्यकता नहीं है (अच्छी तरह से, यह वास्तव में होगा यदि यह अधिक में निहित है एक से अधिक, इसे आगे परीक्षण करने की आवश्यकता होगी। आप जटिल मामलों से सरल मामलों को समाप्त करने के लिए दो पास कर सकते हैं)।

  • प्रत्येक बिंदु के माध्यम से लूप करने और पॉलीगॉन के खिलाफ परीक्षण करने के बजाय, पॉलीगॉन के माध्यम से लूप करें और प्रत्येक बिंदु का परीक्षण करें। लोड हो रहा है / ज्यामिति को परिवर्तित करना धीमा है, इसलिए आप इसे यथासंभव कम करना चाहते हैं। इसके अलावा, सीएसवी से पॉइंट्स की एक सूची बनाएं, शुरू में, फिर से इसे प्रति बार कई बार करने से बचने के लिए फिर उस पुनरावृत्ति के अंत में परिणाम को छोड़ दें।

  • स्थानिक रूप से अपने बिंदुओं को अनुक्रमणित करें, जिसमें इसे या तो एक आकृति के रूप में परिवर्तित करना शामिल है, SpatialLite फ़ाइल, या कुछ PostGIS / PostgreSQL डेटाबेस की तरह। इससे यह फायदा है कि ओजीआर जैसे उपकरण आपके लिए अधिकांश काम करने में सक्षम होंगे।

  • आउटपुट को अंत तक न लिखें: प्रिंट () सबसे अच्छे समय में एक महंगा फ़ंक्शन है। इसके बजाय डेटा को एक सूची के रूप में संग्रहीत करें, और मानक पायथन अचार कार्यों या सूची-डंपिंग फ़ंक्शन का उपयोग करके इसे बहुत अंत में लिखें।


5
पहले दो बड़े भुगतान करेंगे। आप शेपली और शेपफाइल के बजाय ओगर का उपयोग करके चीजों को थोड़ा बढ़ा सकते हैं।
20'11

2
"पायथन" और "स्थानिक सूचकांक" से संबंधित किसी भी चीज़ के लिए, Rtree से आगे नहीं देखें क्योंकि यह अन्य आकृतियों के पास आकृतियाँ खोजने में बहुत तेज़ है
माइक टी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.