NumPy के बिना OGR बिंदु के तहत GDAL रेखापुंज का पिक्सेल मान प्राप्त करना?


45

मैं एक परिदृश्य भर में जंगली परागणकों की बहुतायत के कम्प्यूटेशनल मॉडल पर काम कर रहा हूं। मॉडल स्वयं पूरा हो गया है, और मैं अब पोस्ट-प्रोसेसिंग कदम के साथ संघर्ष कर रहा हूं।

मेरे पास मेरा GDAL परागणकर्ता आपूर्ति रास्टर है जो कुछ इस तरह दिखता है (हल्के रंग का मतलब पिक्सेल में उच्च परागकण यात्रा है):

एक परिदृश्य पर परागण आपूर्ति का प्रतिनिधित्व करते हुए ग्रेस्केल रास्टर

और मेरे पास परिदृश्य पर नमूना स्थानों का प्रतिनिधित्व करने वाले अंकों का एक ओजीआर आकार है:

यहाँ छवि विवरण दर्ज करें

मैं इन बिंदुओं के तहत पिक्सेल पर कुछ विश्लेषण चलाने की कोशिश कर रहा हूं, लेकिन ऐसा करने के लिए, मुझे एक बिंदु के तहत पिक्सेल के मूल्य को निकालने में सक्षम होने की आवश्यकता है।

क्या पायथन के माध्यम से केवल OGR और GDAL का उपयोग करके एक बिंदु के तहत पिक्सेल का मूल्य निकालना संभव है? मैं पूरे रैस्टर को मेमोरी में पढ़ने से बचना पसंद करूंगा ReadAsArray(), क्योंकि मेरे आउटपुट रैस्टर बहुत, बहुत बड़े (मेमोरी में फिट होने के लिए बहुत बड़े) हैं।

मैंने इस पोस्ट पर ध्यान दिया , जो समान है, लेकिन कमांड-लाइन कॉल की आवश्यकता है।


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

1
Gdalsrsinfo के लिए कोड को देखें, यह आपको दिखाता है कि GDALInvertGeoTransform () का उपयोग कैसे करें और भौगोलिक स्थान और पिक्सेल स्थान के बीच स्विच करें: trac.osgeo.org/gdal/browser/trunk/gdal/apps/gdalsrsinfo.cpp

आप PostGIS का उपयोग कर कोई आपत्ति नहीं है, देखना यह । यह बहुत तेज़ है और सिर्फ 1 SQL लाइन है।
18 सितंबर को

अगर मुझे इस समस्या का सामना करना पड़ता है और PostGIS डेटाबेस तक पहुंच है तो मैं इसे ध्यान में रखूंगा! मैं इस विशेष समस्या के लिए नहीं था, इसलिए नीचे GDAL समाधान चाल है। हालांकि धन्यवाद!
जेम्स

@ काइल मुझे नहीं पता कि चीजें बदल गई हैं, लेकिन ऐसा लग रहा है कि यह GDALInvGeoTransform नहीं है उलटा है और यह एक उदाहरण है
एमटीटी

जवाबों:


61

आप गदल.डैटसेट या गदल का उपयोग कर सकते हैं। और रीड रीडस्टर विधि। देखें GDAL और OGR एपीआई ट्यूटोरियल और नीचे दिए गए उदाहरण। ReadRaster का उपयोग नहीं करता है / इसके लिए आवश्यक नहीं है, वापसी मान कच्चा बाइनरी डेटा है और मानक अजगर संरचना मॉड्यूल का उपयोग करके इसे अनपैक करने की आवश्यकता है ।

एक उदाहरण:

from osgeo import gdal,ogr
import struct

src_filename = '/tmp/test.tif'
shp_filename = '/tmp/test.shp'

src_ds=gdal.Open(src_filename) 
gt=src_ds.GetGeoTransform()
rb=src_ds.GetRasterBand(1)

ds=ogr.Open(shp_filename)
lyr=ds.GetLayer()
for feat in lyr:
    geom = feat.GetGeometryRef()
    mx,my=geom.GetX(), geom.GetY()  #coord in map units

    #Convert from map to pixel coordinates.
    #Only works for geotransforms with no rotation.
    px = int((mx - gt[0]) / gt[1]) #x pixel
    py = int((my - gt[3]) / gt[5]) #y pixel

    structval=rb.ReadRaster(px,py,1,1,buf_type=gdal.GDT_UInt16) #Assumes 16 bit int aka 'short'
    intval = struct.unpack('h' , structval) #use the 'short' format code (2 bytes) not int (4 bytes)

    print intval[0] #intval is a tuple, length=1 as we only asked for 1 pixel value

वैकल्पिक रूप से, चूंकि आपने उपयोग नहीं करने का कारण दिया था, इसलिए उपयोग numpyकरने में पूरे सरणी को पढ़ने से बचने के लिए ReadAsArray(), नीचे एक उदाहरण है जो उपयोग करता है numpyऔर पूरे रेखापुंज को नहीं पढ़ता है।

from osgeo import gdal,ogr
import struct

src_filename = '/tmp/test.tif'
shp_filename = '/tmp/test.shp'

src_ds=gdal.Open(src_filename) 
gt=src_ds.GetGeoTransform()
rb=src_ds.GetRasterBand(1)

ds=ogr.Open(shp_filename)
lyr=ds.GetLayer()
for feat in lyr:
    geom = feat.GetGeometryRef()
    mx,my=geom.GetX(), geom.GetY()  #coord in map units

    #Convert from map to pixel coordinates.
    #Only works for geotransforms with no rotation.
    px = int((mx - gt[0]) / gt[1]) #x pixel
    py = int((my - gt[3]) / gt[5]) #y pixel

    intval=rb.ReadAsArray(px,py,1,1)
    print intval[0] #intval is a numpy array, length=1 as we only asked for 1 pixel value

और आप सीएसवी, टेबल या अन्य ऑब्जेक्ट के रूप में कैसे बचा सकते हैं? निर्देशांक की समान लंबाई वाली एक वस्तु
gonzalez.ivan90

यहाँ सवाल है, ल्यूक का। धन्यवाद! gis.stackexchange.com/questions/269603/…
gonzalez.ivan90

लाइनों जो असाइन px/ pyगलत हैं उस मामले में एमएक्स / मेरे झूठ की सीमा से बाहर है rb, क्योंकि int(-0.5) == 0। आप की जरूरत है floor(...), और फिर आप की जाँच करने के कि न तो की जरूरत है px/ pyशून्य से कम हैं (या कॉल करने से पहले यह करना int()क्योंकि नकारात्मक सूचकांक काम (वे सरणी के दूसरे पक्ष प्राप्त)),। मुझे यह जानना अच्छा लगेगा कि क्या इस समस्या से निपटने के लिए कोई रास्ता है। इसके अलावा, आप उन पंक्तियों को फिर से कैसे लिखेंगे ताकि वे घुमावों से सही तरीके से निपट सकें?
naught101
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.