GDAL का उपयोग करते हुए पायथन में प्रति आकृति को विभाजित करना?


15

क्या अजगर में प्रति फीचर शेपफाइल को विभाजित करना संभव है? (सबसे अच्छा एक समाधान होगा जहां मैं डिस्क के बजाय मेमोरी में परिणामी वेक्टर वस्तुओं को अस्थायी रूप से सहेज सकता हूं)।

कारण: मैं आकार के कई अलग-अलग उपसमुच्चय के साथ गाल्ड रैस्टेसलाइयर फ़ंक्शन का उपयोग करना चाहता हूं। फ़ंक्शन को osgeo.ogr.Layer ऑब्जेक्ट की आवश्यकता होती है।


mkay, मैंने थोड़ी बहुत कोशिश की और यह निम्नलिखित के रूप में काम कर सकता है। आप निम्नलिखित के अनुसार प्रति परत गदल परत वस्तुओं की ज्यामिति प्राप्त कर सकते हैं।

#  Load shape into gdal
shapefile=str(vectorPath)
layer_source = ogr.Open(shapefile)
lyr = layer_source.GetLayer(0)
for i in range(0,lyr.GetFeatureCount()):
     feat = lyr.GetFeature(i)
     ge = feat.geometry()

अब मुझे सिर्फ यह जानना है कि इस ज्यामिति के आधार पर एक osgeo.ogr.layer ऑब्जेक्ट कैसे बनाया जाए।


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

जवाबों:


7

एक शुद्ध GDAL समाधान के साथ अपने प्रश्न का उत्तर देने का दूसरा प्रयास ठीक है।

सबसे पहले, GDAL (जियोस्पेशियल डेटा एब्स्ट्रक्शन लाइब्रेरी) मूल रूप से रेखापुंज भू-स्थानिक डेटा के साथ काम करने के लिए सिर्फ एक पुस्तकालय था, जबकि अलग ओजीआर पुस्तकालय वेक्टर डेटा के साथ काम करने का इरादा था। हालाँकि, दो पुस्तकालयों को अब आंशिक रूप से विलय कर दिया गया है, और आम तौर पर GDAL के संयुक्त नाम के तहत एक साथ डाउनलोड और इंस्टॉल किया जाता है। तो समाधान वास्तव में OGR के अंतर्गत आता है। आपके पास यह आपके प्रारंभिक कोड में है, इसलिए मुझे लगता है कि आप यह जानते थे, लेकिन यह याद रखना महत्वपूर्ण है कि टिप्स और संकेत खोजते समय।

वेक्टर लेयर से डेटा पढ़ने के लिए, आप प्रारंभिक कोड ठीक हैं:

from osgeo import ogr
shapefile = ogr.Open(shapefile)
layer = shapefile.GetLayer(0)

for i in range(layer.GetFeatureCount()):
    feature = layer.GetFeature(i)
    name = feature.GetField("NAME")
    geometry = feature.GetGeometryRef()
    print i, name, geometry.GetGeometryName()

इससे पहले कि हम इसे शेपफाइल (या किसी अन्य वेक्टर डेटा सेट) पर लिख सकें, हमें एक नई सुविधा बनाने की आवश्यकता है। एक नई सुविधा बनाने के लिए, हमें सबसे पहले जरूरत है: - एक ज्यामिति - एक सुविधा परिभाषा, जिसमें संभवतः फ़ील्ड परिभाषाएं शामिल होंगी एक खाली ज्यामिति ऑब्जेक्ट बनाने के लिए ज्यामिति निर्माता Og.Geometry () का उपयोग करें। परिभाषित करें कि प्रत्येक प्रकार (बिंदु, रेखा, बहुभुज, आदि) के लिए ज्यामिति अलग तरीके से क्या है। उदाहरण के लिए:

point = ogr.Geometry(ogr.wkbPoint)
point.AddPoint(10,20)

या

line = ogr.Geometry(ogr.wkbLineString)
line.AddPoint(10,10)
line.AddPoint(20,20)
line.SetPoint(0,30,30) #(10,10) -> (30,30)

फ़ील्ड परिभाषा के लिए

fieldDefn = ogr.FieldDefn('id', ogr.OFTInteger)

अब आप अपनी वेक्टर लेयर बना सकते हैं। इस उदाहरण में, एक वर्ग बहुभुज:

#create simple square polygon shapefile:
from osgeo import ogr
driver = ogr.GetDriverByName('ESRI Shapefile')

datasource = driver.CreateDataSource('YOUR_PATH')
layer = datasource.CreateLayer('layerName',geom_type=ogr.wkbPolygon)

#create polygon object:
myRing = ogr.Geometry(type=ogr.wkbLinearRing)
myRing.AddPoint(0.0, 0.0)     #LowerLeft
myRing.AddPoint(0.0, 10.0)    #UpperLeft
myRing.AddPoint(10.0, 10.0)   #UpperRight
myRing.AddPoint(10.0, 0.0)    #Lower Right
myRing.AddPoint(0.0, 0.0)     #close ring
myPoly = ogr.Geometry(type=ogr.wkbPolygon)
myPoly.AddGeometry(myRing)
print ('Polygon area =',myPoly.GetArea())  #returns correct area of 100.0

#create feature object with point geometry type from layer object:
feature = ogr.Feature( layer.GetLayerDefn())
feature.SetGeometry(myPoly)
layer.CreateFeature(feature)

#flush memory - very important
feature.Destroy()
datasource.Destroy()

धन्यवाद डैन! मैंने एक अलग दृष्टिकोण लिया और मेरा QGIS- प्लगइन पहले से ही कार्य करने योग्य है (रास्टर डेटा के स्थानिक प्रश्नों के बारे में)। विभाजन के बजाय, मैंने अंतर्निहित रेखापुंज का सबसेट बनाया। आप मेरे ब्लॉग पर एक उपयोग मामला पा सकते हैं ( smallurl.com/cy6hs9q )। आपका उत्तर मूल प्रश्न को हल करता है, अगर मैं विभाजित करना चाहता हूं और अस्थायी रूप से वेक्टर सुविधाओं को बचा सकता हूं।
कर्लेव

5

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

name     = layer.name()
provider = layer.dataProvider()
feat     = QgsFeature()

# Now we can loop through all the defined features
while provider.nextFeature(feat):

    # Get layer attributes               
    attrs = feat.attributeMap()
    for (k,attr) in attrs.iteritems():
        if k == 0:
            attrOne = attr.toString()
        elif k == 1:
            attrTwo = attr.toString()
        ...

    # Gets the geometry of the feature
    geom = feat.geometry()

    # Get the coordinates of the whole line [or use asPoint()]                    
    line = geom.asPolyline()
        # all points in the line
        for point in line:
            lat = point[0]
            lon = point[1]
            # Add these to a QgsGeometry
            your_Own_QgsGeometry.add...

ऐसा लगता है कि यह आपकी परतों से प्रत्येक सुविधाओं को प्राप्त करने के लिए उपयोगी हो सकता है।

दूसरी परत पर लिखना यहाँ से बहुत जटिल नहीं होना चाहिए। इस तरह से कुछ सिद्धांत में काम करना चाहिए:

# New layer name
filename = "myNewLayer.shp"

# define fields for feature attributes
fields   = { 0 : QgsField("attrOne", QVariant.String),
             1 : QgsField("attrTwo", QVariant.String),
             2 : QgsField("...", QVariant.Int) }

# Create coordinate reference system as WGS84
crs    = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.PostgisCrsId)

# Create the vector layer
writer = QgsVectorFileWriter(filename, "CP1250", fields, QGis.WKBLineString, crs)

# Create some features
feat = QgsFeature()
feat.addAttribute(0, QVariant(runway))
feat.addAttribute(1, QVariant(arriveDepart))
feat.addAttribute(2, QVariant(subTrack))

# Add your geometry
feat.setGeometry(your_Own_QgsGeometry)

# Add the features
writer.addFeature(feat)

# Add it to QGIS project
self.iface.addVectorLayer(filename, "MyLayerName", "ogr")

यहां से आपको प्रत्येक फीचर का डेटा प्राप्त करने में सक्षम होना चाहिए और नई सुविधाओं को एक नई परत पर लिखना चाहिए।

सज्जन


धन्यवाद। आपके कोड के भाग उपयोगी होंगे, यदि मैं अपनी आकृतियों में विशेषताएँ लिखना चाहता हूँ। हालांकि जैसा कि मैंने ऊपर उल्लेख किया है कि मैं केवल गदल (विशेष रूप से गाल्ड.राइजलाइफंक्शन) का उपयोग कर रहा हूं और जब तक कोई नहीं जानता कि कैसे एक QgsVectorLayer ऑब्जेक्ट को गाल्ड ऑब्जेक्ट में बदलना और इसके विपरीत, यह सवाल अभी भी अनसुलझा है।
Curlew

आपने उल्लेख नहीं किया कि आपको QGIS के साथ ऐसा करने की आवश्यकता है। आपका प्रारंभिक उदाहरण सादे वेनिला ओगर प्रतीत होता है।
डेविडएफ

मैं क्यूजीआईएस में ऐसा करना चाहता हूं (मुझे क्यूजीआईएस प्लगइन के लिए एक फ़ंक्शन के रूप में इसकी आवश्यकता है), लेकिन क्यूजीआईएस.कोर मॉड्यूल पर भरोसा किए बिना। इसलिए मुझे सादे ओगर में समाधान की आवश्यकता है। Dan ने उत्तर दिया क्योंकि मैंने एक अन्य पोस्ट में उल्लेख किया है कि यह कोड एक QGIS प्लगइन के लिए है।
Curlew
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.