Python gdal का उपयोग करके GeoTiff से निर्देशांक और संगत पिक्सेल मान प्राप्त करें और उन्हें सुपीरियर सरणी के रूप में सहेजें


10

मैं किसी जियो टिफ फ़ाइल के निर्देशांक में अनुमानित निर्देशांक के साथ-साथ वास्तविक पिक्सेल मान कैसे प्राप्त कर सकता हूं और फिर उन्हें एक सुस्पष्ट सरणी में सहेज सकता हूं? मेरे पास arsenci020l.tif फ़ाइल है, और इसके निर्देशांक मीटर में हैं। नीचे gdalinfo का संक्षिप्त उत्पादन है, जिस पर मैं चला था।

~$ gdalinfo arsenci020l.tif 
Driver: GTiff/GeoTIFF
Files: arsenci020l.tif
       arsenci020l.tfw
Size is 10366, 7273
Coordinate System is:
PROJCS["Lambert Azimuthal Equal Area projection with arbitrary plane grid; projection center 100.0 degrees W, 45.0 degrees N",
    GEOGCS["WGS 84",
        DATUM["WGS_1984",
            SPHEROID["WGS 84",6378137,298.257223563,
                AUTHORITY["EPSG","7030"]],
            AUTHORITY["EPSG","6326"]],
        PRIMEM["Greenwich",0],
        UNIT["degree",0.0174532925199433],
        AUTHORITY["EPSG","4326"]],
    PROJECTION["Lambert_Azimuthal_Equal_Area"],
    PARAMETER["latitude_of_center",45],
    PARAMETER["longitude_of_center",-100],
    PARAMETER["false_easting",0],
    PARAMETER["false_northing",0],
    UNIT["metre",1,
        AUTHORITY["EPSG","9001"]]]
Origin = (-6086629.000000000000000,4488761.000000000000000)
Pixel Size = (1000.000000000000000,-1000.000000000000000)
...

टिफ़ (अक्षांश और देशांतर एक GeoTIFF फ़ाइल से प्राप्त करें) से लाटे / लंबे निर्देशांक प्राप्त करने के बारे में यहाँ भी ऐसा ही प्रश्न था और उत्तर में दिखाया गया था कि केवल शीर्ष बाएँ x और y पिक्सेल निर्देशांक कैसे प्राप्त करें। मुझे सभी अनुमानित पिक्सेल निर्देशांक प्राप्त करने की आवश्यकता है और साथ ही पिक्सेल मान प्राप्त करने और उन्हें एक सुस्पष्ट सरणी में सहेजने की आवश्यकता है। मैं यह कैसे कर सकता हूं?


आप 10366 × 7273 = 75 मिलियन से अधिक अंक चाहते हैं?
माइक टी

@ मुझे ऐसा लगता है, मैं वास्तव में समस्या को हल करने के तरीके के बारे में बेहतर समाधान के बारे में नहीं जानता कि मैं हल करने की कोशिश कर रहा हूं: मुझे इस डेटासेट से निकटतम पिक्सेल समन्वय को यूएस ब्लॉक के प्रत्येक सेंट्रोइड में ढूंढना होगा और फिर असाइन करना होगा उस ब्लॉक के अनुरूप पिक्सेल मूल्य। मुझे चारों ओर खोज करने पर पता चला कि cKDTree क्वेरी निकटतम पड़ोसी खोज के साथ मेरी मदद करने जा रही है। एल्गोरिथ्म के लिए फ़ंक्शन फ़ंक्शन एल्गोरिथ्म के लिए "ट्री" के रूप में संख्यात्मक सरणी के लिए पूछता है। "ट्री" बनाने के लिए इस डेटासेट के सभी पिक्सेल निर्देशांक में से, मुझे उन सभी को किसी तरह स्टोर करने की आवश्यकता है। यदि आपके पास एक बेहतर समाधान है, तो कृपया मुझे बताएं!
इरकमान

जवाबों:


7

टिप्पणी के रूप में जोड़ देगा, लेकिन थोड़ा लंबा - अगर आप अजगर के भीतर गेल्ड / ओगर का उपयोग करना चाहते थे - ऐसा कुछ काम कर सकता है (किसी अन्य कोड से एक साथ हैक किया गया था - परीक्षण नहीं किया गया!) यह भी मानता है कि निकटतम खोजने के बजाय। एक बहुभुज केन्द्रक के लिए रेखापुंज पिक्सेल, आप बस केन्द्रक के xy पर रेखापुंज क्वेरी। मुझे नहीं पता कि गति व्यापार क्या हो सकता है ...

from osgeo import gdal,ogr

fc='PathtoYourVector'
rast='pathToYourRaster'

def GetCentroidValue(fc,rast):
    #open vector layer
    drv=ogr.GetDriverByName('ESRI Shapefile') #assuming shapefile?
    ds=drv.Open(fc,True) #open for editing
    lyr=ds.GetLayer(0)

    #open raster layer
    src_ds=gdal.Open(rast) 
    gt=src_ds.GetGeoTransform()
    rb=src_ds.GetRasterBand(1)
    gdal.UseExceptions() #so it doesn't print to screen everytime point is outside grid

    for feat in lyr:
        geom=feat.GetGeometryRef()
        mx=geom.Centroid().GetX()
        my=geom.Centroid().GetY()

        px = int((mx - gt[0]) / gt[1]) #x pixel
        py = int((my - gt[3]) / gt[5]) #y pixel
        try: #in case raster isnt full extent
            structval=rb.ReadRaster(px,py,1,1,buf_type=gdal.GDT_Float32) #Assumes 32 bit int- 'float'
            intval = struct.unpack('f' , structval) #assume float
            val=intval[0]
        except:
            val=-9999 #or some value to indicate a fail

       feat.SetField('YOURFIELD',val)
       lyr.SetFeature(feat)

    src_ds=None
    ds=None

GetCentroidValue(fc,rast)

14

यह आपको जाना चाहिए। रेखापुंज मानों का उपयोग कर पाठ किया जाता है rasterio , और पिक्सेल केंद्र निर्देशांकों का उपयोग कर Eastings / Northings में बदल दिए जाते affine है, जो तब का उपयोग कर अक्षांश / देशांतर में बदल दिए जाते pyproj । अधिकांश सरणियों में इनपुट रेखापुंज के समान आकार होता है।

import rasterio
import numpy as np
from affine import Affine
from pyproj import Proj, transform

fname = '/path/to/your/raster.tif'

# Read raster
with rasterio.open(fname) as r:
    T0 = r.transform  # upper-left pixel corner affine transform
    p1 = Proj(r.crs)
    A = r.read()  # pixel values

# All rows and columns
cols, rows = np.meshgrid(np.arange(A.shape[2]), np.arange(A.shape[1]))

# Get affine transform for pixel centres
T1 = T0 * Affine.translation(0.5, 0.5)
# Function to convert pixel row/column index (from 0) to easting/northing at centre
rc2en = lambda r, c: (c, r) * T1

# All eastings and northings (there is probably a faster way to do this)
eastings, northings = np.vectorize(rc2en, otypes=[np.float, np.float])(rows, cols)

# Project all longitudes, latitudes
p2 = Proj(proj='latlong',datum='WGS84')
longs, lats = transform(p1, p2, eastings, northings)

1
इसका उपयोग करते समय, मुझे "Att0Error: 'DatasetReader' ऑब्जेक्ट" T0 = r.affine "लाइन के लिए कोई विशेषता 'affine' नहीं है
mitchus

@ मिचस जाहिरा तौर पर के affineलिए सिर्फ एक उपनाम है transform, और उपनाम को रास्टरियो के सबसे हाल के संस्करण से हटा दिया गया है। मैंने उत्तर को संपादित किया, लेकिन ऐसा लगता है कि जब मैं यहां नया हूं तब से इसे सहकर्मी की समीक्षा करने की आवश्यकता है। :)
शरद ऋतु

1
यह भी दिखता है कि इंडेक्स गलत हैं A.shape, जिसके केवल दो आयाम हैं।
शरद ऋतु
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.