NumPyなしでOGRポイントの下でGDALラスターのピクセル値を取得しますか?


45

私は、風景全体の野生の花粉媒介者の豊富さの計算モデルに取り組んでいます。モデル自体は完成しており、私は現在、後処理ステップに苦労しています。

次のようなGDAL受粉器供給ラスターがあります(明るい色は、受粉器への訪問回数が多いことを意味します)。

景観上の受粉媒介者の供給を表すグレースケールラスター

そして、ランドスケープ上のサンプル位置を表すポイントのOGRシェープファイルがあります。

ここに画像の説明を入力してください

私はこれらのポイントの下のピクセルでいくつかの分析を実行しようとしていますが、そうするには、ポイントの下のピクセルの値を抽出できる必要があります。

PythonでOGRとGDALのみを使用して、ポイントの下のピクセルの値を抽出することは可能ですか?ReadAsArray()出力ラスターは非常に大きい(メモリに収まるには大きすぎる)ため、ラスター全体をを介してメモリに読み込むことは避けたいと思います。

私はこの投稿に気づきましたが、これは似ていますが、コマンドライン呼び出しが必要です。


2
ReadAsArray()とポイントでの読み取りのみはどうですか?興味のある単一のセルだけを読むのですか?ポイント座標からピクセル空間に変換し、必要なセルを抽出する必要があります。
ジェイローラ

1
gdalsrsinfoのコードを見てください。GDALInvertGeoTransform()を使用して、地理空間とピクセル空間を切り替える方法を示しています。trac.osgeo.org

あなたはPostGISのを使用して気にしない場合は、参照これを。これは非常に高速で、SQL行は1行です。
mlt

この問題に遭遇し、PostGISデータベースにアクセスできる場合は、そのことを覚えておいてください!私はこの特定の問題には関心がなかったので、以下のGDALソリューションがうまくいきました。でもありがとう!
ジェームズ

@kyle状況が変わったかどうかはわかりませんが、GDALInvGeoTransform反転いないように見えますが、これは例です。
mlt

回答:


61

gdal.Datasetまたはgdal.Band ReadRasterメソッドを使用できます。参照GDALOGR APIのチュートリアルと、以下の例を。ReadRasterはnumpyを使用/要求しません。戻り値は生のバイナリデータであり、標準のpython structモジュールを使用して解凍する必要があります。

例:

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

そして、どのようにcsv、テーブル、または他のオブジェクトとして保存できますか?同じ長さのオブジェクトobjetct
gonzalez.ivan90

ここに質問があります、ルーク。ありがとう!gis.stackexchange.com/questions/269603/...
gonzalez.ivan90

行がアサインすることをpx/ pyそのMX /の境界の外に私の嘘場合は間違っているrb、なぜならint(-0.5) == 0。あなたは必要とするfloor(...)、とあなたはどちらのことを確認する必要がありますpx/ pyゼロ未満です(または呼び出す前にそれを行うint()負のインデックス作業(これらは、アレイの他の側面を取得する)ので、)。この問題に対処するきちんとした方法があるかどうか知りたいです。また、回転を正しく処理するために、これらの行をどのように書き直しますか?
naught101
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.