名前

ST_MapAlgebra — コールバック関数版 - ひとつ以上の入力ラスタ、バンドインデクスとひとつのユーザ定義コールバック関数から、ひとつのバンドからなるラスタを返します。

概要

raster ST_MapAlgebra(rastbandarg[] rastbandargset, regprocedure callbackfunc, text pixeltype=NULL, text extenttype=INTERSECTION, raster customextent=NULL, integer distancex=0, integer distancey=0, text[] VARIADIC userargs=NULL);

raster ST_MapAlgebra(raster rast, integer[] nband, regprocedure callbackfunc, text pixeltype=NULL, text extenttype=FIRST, raster customextent=NULL, integer distancex=0, integer distancey=0, text[] VARIADIC userargs=NULL);

raster ST_MapAlgebra(raster rast, integer nband, regprocedure callbackfunc, text pixeltype=NULL, text extenttype=FIRST, raster customextent=NULL, integer distancex=0, integer distancey=0, text[] VARIADIC userargs=NULL);

raster ST_MapAlgebra(raster rast1, integer nband1, raster rast2, integer nband2, regprocedure callbackfunc, text pixeltype=NULL, text extenttype=INTERSECTION, raster customextent=NULL, integer distancex=0, integer distancey=0, text[] VARIADIC userargs=NULL);

説明

ひとつ以上の入力ラスタ、バンドインデクスとひとつのユーザ定義コールバック関数から、ひとつのバンドからなるラスタを返します。

rast,rast1,rast2, rastbandargset

地図代数処理が行われるラスタです。

rastbandargsetによって、多数のラスタと多数のバンドにおいて地図代数処理が使用できます。1番目の形式の例を見て下さい。

nband, nband1, nband2

処理を行うラスタのバンド番号です。nbandはバンドを示す整数スカラまたは整数配列です。2ラスタ/2バンドの場合では、nband1はrast1のバンド、nband2はrast2のバンドです。

callbackfunc

callbackfunc引数は、SQLまたはPL/pgSQL関数の名前とシグニチャでなければならず、regprocedureにキャストしなければなりません。PL/pgSQL関数の例は次の通りです。

CREATE OR REPLACE FUNCTION sample_callbackfunc(value double precision[][][], position integer[][], VARIADIC userargs text[])
        RETURNS double precision
        AS $$
        BEGIN
                RETURN 0;
        END;
        $$ LANGUAGE 'plpgsql' IMMUTABLE;
                                                                        

callbackfuncは、みっつの引数を持たなければなりません。すなわち、3次元倍精度浮動小数点数配列、2次元整数配列、VARIADICの1次元文字列配列です。1番目の引数valueは、全ての入力ラスタからの値(倍精度浮動小数点数)の配列です。3次元(1始まり)は、ラスタ番号、行、列です。2番目の引数positionは、出力ラスタと入力ラスタからのピクセル位置の集合です。ひとつめの次元(0はじまりです)はラスタ番号です。ひとつめの次元が0の場合に指される位置は、出力ラスタのピクセル位置です。ふたつめの次元は、XとYからなるふたつの要素を持ちます。3番目の引数userargsはユーザ定義関数特有の引数としてそのまま渡されます。

regprocedure引数をSQL関数に渡すには、完全な関数シグネチャが求められます。regprocedureへのキャストが必要です。上のPL/pgSQL関数を引数として渡すには、引数のSQLは次のようにします。

'sample_callbackfunc(double precision[], integer[], text[])'::regprocedure
                                                                        

引数は関数名、引数の型を含み、関数名と引数を引用符で括り、regprocedureにキャストすることになりますのでご注意下さい。

pixeltype

pixeltypeを渡した場合には、新しいラスタのひとつのバンドが、そのピクセルタイプになります。pixeltypeにNULLを渡したり指定しなかった場合には、新しいラスタのピクセルタイプは、ひとつめのラスタ(extenttypeがINTERSECTION, UNION, FIRST, CUSTOMの場合)か、適切なラスタ(extenttypeがSECOND, LASTの場合)の指定したバンドと同じピクセルタイプになります。疑問を感じたら常にpixeltypeを渡します。

出力ラスタのピクセルタイプは、必ずST_BandPixelTypeに挙げられたもののひとつになるか、省略されるか、NULLに設定されます。

extenttype

INTERSECTION (デフォルト), UNION, FIRST (ひとつのラスタを取る形式でのデフォルト), SECOND, LAST, CUSTOMのいずれかになります。

customextent

extentypeがCUSTOMである場合には、ラスタはcustomextentで提供されます。1番目の形式の例4をご覧下さい。

distancex

参照セルからのピクセル単位の距離です。結果として得られる行列の幅は2*distancex + 1となります。指定しない場合には、参照セルが対象となります(0の距離の近隣ピクセル)。

distancey

参照セルからのピクセル単位の距離です。結果として得られる行列の幅は2*distancey + 1となります。指定しない場合には、参照セルが対象となります(0の距離の近隣ピクセル)。

userargs

callbackfuncの3番目の引数はvariadic text配列です。全ての文字列引数は指定されたcallbackfuncにそのまま渡され、userargs引数に含まれます。

[注記]

VARIADICキーワードに関する詳細情報については、PostgreSQL文書とQuery Language (SQL) Functions(訳注: 日本語版 問い合わせ言語(SQL)関数)の"SQL Functions with Variable Numbers of Arguments"節を参照して下さい。

[注記]

callbackfuncへのtext[]引数は必須ですが、コールバック関数に引数を渡すべきか渡すべきでないかの選択を十分に考慮しなければならないものでもありません。

1番目の形式では、多数のラスタやバンドで地図代数演算が使えるようになるためのrastbandarg配列を受け付けます。1番目の形式の例をご覧下さい。

2番目と3番目の形式では、ひとつのラスタのけるひとつ以上のバンドでの演算を行います。2番目の形式と3番目の形式の例をご覧下さい。

4番目の形式では、ふたつのラスタ内のひとつずつのバンドでの演算を行います。4番目の形式の例をご覧下さい。

初出: 2.1.0

例: 1番目の形式

ひとつのラスタ、ひとつのバンド

WITH foo AS (
        SELECT 1 AS rid, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0) AS rast
)
SELECT
        ST_MapAlgebra(
                ARRAY[ROW(rast, 1)]::rastbandarg[],
                'sample_callbackfunc(double precision[], int[], text[])'::regprocedure
        ) AS rast
FROM foo
                                        

ひとつのラスタ、複数のバンド

WITH foo AS (
        SELECT 1 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0), 2, '8BUI', 10, 0), 3, '32BUI', 100, 0) AS rast
)
SELECT
        ST_MapAlgebra(
                ARRAY[ROW(rast, 3), ROW(rast, 1), ROW(rast, 3), ROW(rast, 2)]::rastbandarg[],
                'sample_callbackfunc(double precision[], int[], text[])'::regprocedure
        ) AS rast
FROM foo
                                        

複数のラスタ、複数のバンド

WITH foo AS (
        SELECT 1 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0), 2, '8BUI', 10, 0), 3, '32BUI', 100, 0) AS rast UNION ALL
        SELECT 2 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 1, 1, -1, 0, 0, 0), 1, '16BUI', 2, 0), 2, '8BUI', 20, 0), 3, '32BUI', 300, 0) AS rast
)
SELECT
        ST_MapAlgebra(
                ARRAY[ROW(t1.rast, 3), ROW(t2.rast, 1), ROW(t2.rast, 3), ROW(t1.rast, 2)]::rastbandarg[],
                'sample_callbackfunc(double precision[], int[], text[])'::regprocedure
        ) AS rast
FROM foo t1
CROSS JOIN foo t2
WHERE t1.rid = 1
        AND t2.rid = 2
                                        

近隣ピクセルを併用したカバレッジのタイルの完全な例です。クエリはPostgreSQL 9,1以上でのみ動作します。

WITH foo AS (
        SELECT 0 AS rid, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0) AS rast UNION ALL
        SELECT 1, ST_AddBand(ST_MakeEmptyRaster(2, 2, 2, 0, 1, -1, 0, 0, 0), 1, '16BUI', 2, 0) AS rast UNION ALL
        SELECT 2, ST_AddBand(ST_MakeEmptyRaster(2, 2, 4, 0, 1, -1, 0, 0, 0), 1, '16BUI', 3, 0) AS rast UNION ALL

        SELECT 3, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, -2, 1, -1, 0, 0, 0), 1, '16BUI', 10, 0) AS rast UNION ALL
        SELECT 4, ST_AddBand(ST_MakeEmptyRaster(2, 2, 2, -2, 1, -1, 0, 0, 0), 1, '16BUI', 20, 0) AS rast UNION ALL
        SELECT 5, ST_AddBand(ST_MakeEmptyRaster(2, 2, 4, -2, 1, -1, 0, 0, 0), 1, '16BUI', 30, 0) AS rast UNION ALL

        SELECT 6, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, -4, 1, -1, 0, 0, 0), 1, '16BUI', 100, 0) AS rast UNION ALL
        SELECT 7, ST_AddBand(ST_MakeEmptyRaster(2, 2, 2, -4, 1, -1, 0, 0, 0), 1, '16BUI', 200, 0) AS rast UNION ALL
        SELECT 8, ST_AddBand(ST_MakeEmptyRaster(2, 2, 4, -4, 1, -1, 0, 0, 0), 1, '16BUI', 300, 0) AS rast
)
SELECT
        t1.rid,
        ST_MapAlgebra(
                ARRAY[ROW(ST_Union(t2.rast), 1)]::rastbandarg[],
                'sample_callbackfunc(double precision[], int[], text[])'::regprocedure,
                '32BUI',
                'CUSTOM', t1.rast,
                1, 1
        ) AS rast
FROM foo t1
CROSS JOIN foo t2
WHERE t1.rid = 4
        AND t2.rid BETWEEN 0 AND 8
        AND ST_Intersects(t1.rast, t2.rast)
GROUP BY t1.rid, t1.rast
                                        

前の例である近隣ピクセルを併用したカバレッジのタイルに似ていますがPostgreSQL 9.0で動作します。

WITH src AS (
        SELECT 0 AS rid, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0) AS rast UNION ALL
        SELECT 1, ST_AddBand(ST_MakeEmptyRaster(2, 2, 2, 0, 1, -1, 0, 0, 0), 1, '16BUI', 2, 0) AS rast UNION ALL
        SELECT 2, ST_AddBand(ST_MakeEmptyRaster(2, 2, 4, 0, 1, -1, 0, 0, 0), 1, '16BUI', 3, 0) AS rast UNION ALL

        SELECT 3, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, -2, 1, -1, 0, 0, 0), 1, '16BUI', 10, 0) AS rast UNION ALL
        SELECT 4, ST_AddBand(ST_MakeEmptyRaster(2, 2, 2, -2, 1, -1, 0, 0, 0), 1, '16BUI', 20, 0) AS rast UNION ALL
        SELECT 5, ST_AddBand(ST_MakeEmptyRaster(2, 2, 4, -2, 1, -1, 0, 0, 0), 1, '16BUI', 30, 0) AS rast UNION ALL

        SELECT 6, ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, -4, 1, -1, 0, 0, 0), 1, '16BUI', 100, 0) AS rast UNION ALL
        SELECT 7, ST_AddBand(ST_MakeEmptyRaster(2, 2, 2, -4, 1, -1, 0, 0, 0), 1, '16BUI', 200, 0) AS rast UNION ALL
        SELECT 8, ST_AddBand(ST_MakeEmptyRaster(2, 2, 4, -4, 1, -1, 0, 0, 0), 1, '16BUI', 300, 0) AS rast
)
WITH foo AS (
        SELECT
                t1.rid,
                ST_Union(t2.rast) AS rast
        FROM src t1
        JOIN src t2
                ON ST_Intersects(t1.rast, t2.rast)
                AND t2.rid BETWEEN 0 AND 8
        WHERE t1.rid = 4
        GROUP BY t1.rid
), bar AS (
        SELECT
                t1.rid,
                ST_MapAlgebra(
                        ARRAY[ROW(t2.rast, 1)]::rastbandarg[],
                        'raster_nmapalgebra_test(double precision[], int[], text[])'::regprocedure,
                        '32BUI',
                        'CUSTOM', t1.rast,
                        1, 1
                ) AS rast
        FROM src t1
        JOIN foo t2
                ON t1.rid = t2.rid 
)
SELECT
        rid,
        (ST_Metadata(rast)),
        (ST_BandMetadata(rast, 1)),
        ST_Value(rast, 1, 1, 1)
FROM bar;
                                        

例: 2番目の形式と3番目の形式

ひとつのラスタ、複数のバンド

WITH foo AS (
        SELECT 1 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0), 2, '8BUI', 10, 0), 3, '32BUI', 100, 0) AS rast
)
SELECT
        ST_MapAlgebra(
                rast, ARRAY[3, 1, 3, 2]::integer[],
                'sample_callbackfunc(double precision[], int[], text[])'::regprocedure
        ) AS rast
FROM foo
                                        

ひとつのラスタ、ひとつのバンド

WITH foo AS (
        SELECT 1 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0), 2, '8BUI', 10, 0), 3, '32BUI', 100, 0) AS rast
)
SELECT
        ST_MapAlgebra(
                rast, 2,
                'sample_callbackfunc(double precision[], int[], text[])'::regprocedure
        ) AS rast
FROM foo
                                        

例: 4番目の形式

ふたつのラスタ、ふたつのバンド

WITH foo AS (
        SELECT 1 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0), 2, '8BUI', 10, 0), 3, '32BUI', 100, 0) AS rast UNION ALL
        SELECT 2 AS rid, ST_AddBand(ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(2, 2, 0, 1, 1, -1, 0, 0, 0), 1, '16BUI', 2, 0), 2, '8BUI', 20, 0), 3, '32BUI', 300, 0) AS rast
)
SELECT
        ST_MapAlgebra(
                t1.rast, 2,
                t2.rast, 1,
                'sample_callbackfunc(double precision[], int[], text[])'::regprocedure
        ) AS rast
FROM foo t1
CROSS JOIN foo t2
WHERE t1.rid = 1
        AND t2.rid = 2
                                        

関連情報

rastbandarg, ST_Union, ST_MapAlgebra