psycopg2を使用してラスターデータをpostgisからPythonにダウンロードする


13

pythonにnumpy配列として取得したいpostgresテーブルにラスターデータがあります。データベースに接続するためにpsycopg2を使用しています。データをダウンロードすることはできますが、文字列(おそらくシリアル化されたバイナリ)として返されます。

この文字列を取得してnumpy配列に変換する方法を知っている人はいますか?

st_astiffを使用してhexファイルをダウンロードしてxxdを使用するなど、ラスターをダウンロードする他のオプションを検討しましたが、うまくいきませんでした。「rt_raster_to_gdal:出力GDALドライバーを読み込めませんでした」というエラーが表示され続け、ドライバーを有効にできる環境変数を設定する権限がありません。

TL、DR:ラスターデータをnumpy配列にインポートする(Pythonを使用)。

回答:


14

rt_raster_to_gdal:出力GDALドライバーをロードできませんでした

ST_AsTIFFの最初のエラーについては、GDALドライバーを有効にする必要がありますが、デフォルトではPostGIS 2.1では有効になっていません。これを行う方法については、マニュアル参照してください。たとえば、次のようにWindowsコンピューターに環境変数を設定しています。

POSTGIS_GDAL_ENABLED_DRIVERS=GTiff PNG JPEG GIF XYZ DTED USGSDEM AAIGrid

PostGISで確認できます:

SELECT short_name, long_name
FROM ST_GDALDrivers();

PostGISからNumpy

GDALがNumpy配列に読み込むために、出力を仮想メモリGeoTIFFファイルにエクスポートできます。GDALで使用される仮想ファイルのヒントについては、このブログ投稿を参照してください。

import os
import psycopg2
from osgeo import gdal

# Adjust this to connect to a PostGIS database
conn = psycopg2.connect(...)
curs = conn.cursor()

# Make a dummy table with raster data
curs.execute("""\
    SELECT ST_AsRaster(ST_Buffer(ST_Point(1, 5), 10), 10, 10, '8BUI', 1) AS rast
    INTO TEMP mytable;
""")

# Use a virtual memory file, which is named like this
vsipath = '/vsimem/from_postgis'

# Download raster data into Python as GeoTIFF, and make a virtual file for GDAL
curs.execute("SELECT ST_AsGDALRaster(rast, 'GTiff') FROM mytable;")
gdal.FileFromMemBuffer(vsipath, bytes(curs.fetchone()[0]))

# Read first band of raster with GDAL
ds = gdal.Open(vsipath)
band = ds.GetRasterBand(1)
arr = band.ReadAsArray()

# Close and clean up virtual memory file
ds = band = None
gdal.Unlink(vsipath)

print(arr)  # this is a 2D numpy array

ラスタライズされたバッファーポイントを表示します。

[[0 0 0 1 1 1 1 0 0 0]
 [0 1 1 1 1 1 1 1 1 0]
 [0 1 1 1 1 1 1 1 1 0]
 [1 1 1 1 1 1 1 1 1 1]
 [1 1 1 1 1 1 1 1 1 1]
 [1 1 1 1 1 1 1 1 1 1]
 [1 1 1 1 1 1 1 1 1 1]
 [0 1 1 1 1 1 1 1 1 0]
 [0 1 1 1 1 1 1 1 1 0]
 [0 0 0 1 1 1 1 0 0 0]]

この例では「GTiff」形式を使用しましたが、他の形式の方が適している場合があります。たとえば、低速のインターネット接続で転送する必要がある大きなラスターがある場合は、「PNG」を使用して圧縮してみてください。


それはとても役に立ちます。
ジョンパウエル

非常に役立ちます。ありがとう!エラー:rt_raster_to_gdal:出力GDALドライバーをロードできませんでしたが、回避策があると思います。再度、感謝します!
マヤンク・アガーウォール

@MayankAgarwalは、rt_raster_to_gdalエラーの回答を更新しました。
マイクT

6

質問は、gdalドライバーを有効にせずにpostgisラスターテーブルから読み取ることができるかどうかだと思います。Pythonのすべてのものと同じように、できます!

ラスター結果をWKBinaryとして選択してください。

St_AsBinary(rast)...を選択します

以下のスクリプトを使用して、WKBinaryをPythonイメージ形式に解読します。opencvは任意の数の画像バンドを処理するため、opencvを好みますが、1バンドまたは3バンドがより一般的な場合はPIL / lowを使用できます。

今のところバイト画像のみを処理していますが、他のデータ型に拡張するのは比較的簡単です。

これが役立つことを願っています。

インポート構造
numpyをnpとしてインポートする
cv2をインポート

#WKBヘッダーを解読する関数
def wkbHeader(raw):
    #http://trac.osgeo.org/postgis/browser/trunk/raster/doc/RFC2-WellKnownBinaryFormatを参照

    ヘッダー= {}

    header ['endianess'] = struct.unpack( 'B'、raw [0])[0]
    header ['version'] = struct.unpack( 'H'、raw [1:3])[0]
    header ['nbands'] = struct.unpack( 'H'、raw [3:5])[0]
    header ['scaleX'] = struct.unpack( 'd'、raw [5:13])[0]
    header ['scaleY'] = struct.unpack( 'd'、raw [13:21])[0]
    header ['ipX'] = struct.unpack( 'd'、raw [21:29])[0]
    header ['ipY'] = struct.unpack( 'd'、raw [29:37])[0]
    header ['skewX'] = struct.unpack( 'd'、raw [37:45])[0]
    header ['skewY'] = struct.unpack( 'd'、raw [45:53])[0]
    header ['srid'] = struct.unpack( 'i'、raw [53:57])[0]
    header ['width'] = struct.unpack( 'H'、raw [57:59])[0]
    header ['height'] = struct.unpack( 'H'、raw [59:61])[0]

    ヘッダーを返す

#WKBラスターデータを解読する関数 
def wkbImage(raw):
    h = wkbHeader(raw)
    img = []#画像バンドを保存する配列
    offset = 61#ヘッダーの未加工の長さ(バイト)
    範囲内のi(h ['nbands']):
        #このバンドのピクセルタイプを決定
        pixtype = struct.unpack( 'B'、raw [offset])[0] >> 4
        #今のところ、符号なしバイトのみを処理します
        pixtype == 4:の場合
            band = np.frombuffer(raw、dtype = 'uint8'、count = h ['width'] * h ['height']、offset = offset + 1)
            img.append((np.reshape(band、((h ['height']、h ['width'])))))
            オフセット=オフセット+ 2 + h ['width'] * h ['height']
        #すること:他のデータ型を処理する 

    return cv2.merge(tuple(img))


それはとても役に立ちます。私はconda環境でgdalに多くの問題を抱えていましたが、このアプローチは初めて機能しました。また、構造を少し掘り下げてみることができてうれしいです。
ジョンパウエル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.