Lấy tọa độ và giá trị pixel tương ứng từ GeoTiff bằng python gdal và lưu chúng dưới dạng mảng numpy


10

Làm cách nào tôi có thể có được các tọa độ được chiếu cũng như các giá trị pixel thực tế tại các tọa độ đó từ tệp GeoTiff và sau đó lưu chúng vào một mảng gọn gàng? Tôi có tệp arsenci020l.tif và tọa độ của nó được tính bằng mét. Dưới đây là đầu ra tóm tắt của gdalinfo tôi đã chạy trên nó.

~$ 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)
...

Có một câu hỏi tương tự ở đây về việc lấy tọa độ lat / long từ tiff (Lấy Vĩ độ và Kinh độ từ Tệp GeoTIFF) và câu trả lời cho thấy cách chỉ lấy tọa độ pixel x và y trên cùng bên trái. Tôi cần phải có được TẤT CẢ các tọa độ pixel được chiếu cũng như nhận các giá trị pixel và lưu chúng trong một mảng gọn gàng. Tôi làm nó như thế nào?


Bạn muốn 10366 × 7273 = hơn 75 triệu điểm?
Mike T

@MikeT Tôi nghĩ vậy, tôi thực sự không biết một giải pháp tốt hơn về cách tiếp cận vấn đề mà tôi đang cố gắng giải quyết: Tôi cần tìm tọa độ pixel gần nhất từ ​​bộ dữ liệu này cho từng centroid của khối Hoa Kỳ và sau đó gán giá trị pixel tương ứng với khối đó. Từ khi tìm kiếm xung quanh tôi nhận ra rằng truy vấn cKDTree sẽ giúp tôi với tìm kiếm hàng xóm gần nhất. Hàm này cho thuật toán yêu cầu một "cây" để truy vấn dưới dạng mảng numpy. Để tạo một "cây" Trong tất cả các tọa độ pixel từ bộ dữ liệu này, tôi cần lưu trữ tất cả chúng bằng cách nào đó. Nếu bạn có giải pháp tốt hơn, vui lòng cho tôi biết!
irakhman

Câu trả lời:


7

sẽ thêm dưới dạng nhận xét, nhưng hơi lâu - trong trường hợp bạn muốn sử dụng gdal / ogr trong python - một cái gì đó như thế này có thể hoạt động (được hack cùng với một số mã khác tôi đã - không được kiểm tra!) Điều này cũng cho rằng thay vì tìm ra gần nhất pixel raster đến một centroid đa giác, bạn chỉ cần truy vấn raster tại xy của centroid. tôi không biết sự đánh đổi tốc độ có thể là gì ...

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

Điều này sẽ giúp bạn đi. Các giá trị raster được đọc bằng rasterio và tọa độ trung tâm pixel được chuyển đổi thành Eastings / Northings bằng affine , sau đó được chuyển đổi thành Latitude / Kinh độ bằng pyproj . Hầu hết các mảng có hình dạng giống như raster đầu vào.

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
Khi sử dụng, tôi nhận được thông báo "AttributionError: 'Đối tượng DatasetReader' không có thuộc tính 'affine'" cho dòng "T0 = r.affine"
mitchus

@mitchus Rõ ràng affinechỉ là một bí danh transformvà bí danh đã bị xóa khỏi phiên bản gần đây nhất của rasterio. Tôi đã chỉnh sửa câu trả lời nhưng có vẻ như nó cần được đánh giá ngang hàng vì tôi mới ở đây. :)
Autumnsault

1
Có vẻ như các chỉ mục là sai A.shape, chỉ có hai chiều.
Autumnsault
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.