名前

ST_MapAlgebraFct — 2バンド版 - 2つの入力バンドに対する妥当なPostgreSQL関数で形成された、指定したピクセルタイプの1バンドのラスタを生成します。バンドを指定しない場合には、1と仮定します。"extenttype"のデフォルトはINTERSECTIONです。

概要

raster ST_MapAlgebraFct(raster rast1, raster rast2, regprocedure tworastuserfunc, text pixeltype=same_as_rast1, text extenttype=INTERSECTION, text[] VARIADIC userargs);

raster ST_MapAlgebraFct(raster rast1, integer band1, raster rast2, integer band2, regprocedure tworastuserfunc, text pixeltype=same_as_rast1, text extenttype=INTERSECTION, text[] VARIADIC userargs);

説明

[警告]

ST_MapAlgebraFct は2.1.0で非推奨になりました。代わりにST_MapAlgebraを使います。

2つの入力ラスタ(rast1, rast2)に対してtworastuserfuncで指定される妥当なPostgreSQL関数で形成されるラスタを返します。 band1またはband2が指定されていない場合には、1と仮定します。新しいラスタは、元のラスタと同じ地理参照、幅、高さを持ちますが、ひとつのバンドしか持ちません。

pixeltypeが渡された場合には、新しいラスタはそのピクセルタイプのバンドを持ちます。pixelteypeとしてNULLが渡されたりピクセルタイプを指定しない場合には、新しいラスタはrast1の入力バンドと同じピクセルタイプになります。

tworastuserfunc引数はSQL関数またはPL/pgSQL関数のシグネチャで、regprocedureにキャストします。大変単純で本当に使えないPL/pgSQL関数の例を挙げます。

CREATE OR REPLACE FUNCTION simple_function_for_two_rasters(pixel1 FLOAT, pixel2 FLOAT, pos INTEGER[], VARIADIC args TEXT[])
    RETURNS FLOAT
    AS $$ BEGIN
        RETURN 0.0;
    END; $$
    LANGUAGE 'plpgsql' IMMUTABLE;

The tworastuserfunctworastuserfuncは3または4の引数を受け付けます。すなわち、倍精度浮動小数点数、倍精度浮動小数点数、任意の整数配列、VARIADIC文字列配列です。第1引数はrast1のラスタセルごとの値です(ラスタのデータ型に関係なく)。第2引数はrast2のラスタセルごとの値です。第3引数は現在の処理セルの位置で、'{x,y}'であらわされます。第4引数は、ST_MapAlgebraFctへのパラメータの残っているもの全てがtworastuserfuncに渡されることを示します。

regprodedure引数をSQL関数に渡す際は完全な関数シグネチャとregprodedure型へのキャストが求められます。上のPL/pgSQL関数を引数に取るには、引数のSQLは次のようにします。

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

引数は関数名、引数の型を含み、名前と引数型全体に対して引用符でくくり、regprocedureにキャストしていることに注意して下さい。

tworastuserfuncの第3引数はvariadic text配列です。どのST_MapAlgebraFctにもついてくる全ての文字列引数は、指定されたtworastuserfuncに、そのまま渡されて、userargs引数内に入ります。

[注記]

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

[注記]

tworastuserfuncへのtext[]引数は、あらゆる引数を処理のためにユーザ関数に渡すかどうかの選択にかかわらず求められます。

初出: 2.0.0

例: 別個のバンドとしてキャンバス上にラスタをオーバレイする

-- ユーザ関数の定義 --
CREATE OR REPLACE FUNCTION raster_mapalgebra_union(
        rast1 double precision,
        rast2 double precision,
    pos integer[],
        VARIADIC userargs text[]
)
        RETURNS double precision
        AS $$
        DECLARE
        BEGIN
                CASE
                        WHEN rast1 IS NOT NULL AND rast2 IS NOT NULL THEN
                                RETURN ((rast1 + rast2)/2.);
                        WHEN rast1 IS NULL AND rast2 IS NULL THEN
                                RETURN NULL;
                        WHEN rast1 IS NULL THEN
                                RETURN rast2;
                        ELSE
                                RETURN rast1;
                END CASE;

                RETURN NULL;
        END;
        $$ LANGUAGE 'plpgsql' IMMUTABLE COST 1000;

-- ラスタの試験テーブルを用意します
DROP TABLE IF EXISTS map_shapes;
CREATE TABLE map_shapes(rid serial PRIMARY KEY, rast raster, bnum integer, descrip text);
INSERT INTO map_shapes(rast,bnum, descrip)
WITH mygeoms 
    AS ( SELECT 2 As bnum, ST_Buffer(ST_Point(90,90),30) As geom, 'circle' As descrip
            UNION ALL
            SELECT 3 AS bnum, 
                ST_Buffer(ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'), 15) As geom, 'big road' As descrip
            UNION ALL
            SELECT 1 As bnum, 
                ST_Translate(ST_Buffer(ST_GeomFromText('LINESTRING(60 50,150 150,150 50)'), 8,'join=bevel'), 10,-6) As geom, 'small road' As descrip
            ),
   -- ジオメトリと1対1に対応するキャンバスを定義
   canvas
    AS ( SELECT ST_AddBand(ST_MakeEmptyRaster(250, 
        250, 
        ST_XMin(e)::integer, ST_YMax(e)::integer, 1, -1, 0, 0 ) , '8BUI'::text,0) As rast
        FROM (SELECT ST_Extent(geom) As e,
                    Max(ST_SRID(geom)) As srid 
                    from mygeoms 
                    ) As foo
            )
-- キャンバスとアラインメントの合ったラスタを返します
SELECT ST_AsRaster(m.geom, canvas.rast, '8BUI', 240) As rast, bnum, descrip
                FROM mygeoms AS m CROSS JOIN canvas
UNION ALL 
SELECT canvas.rast, 4, 'canvas'
FROM canvas;

-- 1バンド版の地図代数関数の実行とST_AddBandで集めます
INSERT INTO map_shapes(rast,bnum,descrip)
SELECT ST_AddBand(ST_AddBand(rasts[1], rasts[2]),rasts[3]), 4, 'map bands overlay fct union (canvas)'
        FROM (SELECT ARRAY(SELECT ST_MapAlgebraFct(m1.rast, m2.rast, 
                        'raster_mapalgebra_union(double precision, double precision, integer[], text[])'::regprocedure, '8BUI', 'FIRST')
                FROM map_shapes As m1 CROSS JOIN map_shapes As m2
                        WHERE m1.descrip = 'canvas' AND m2.descrip <> 'canvas' ORDER BY m2.bnum) As rasts) As foo;
                                        

バンドオーバレイ(キャンバス)の図(赤:小さい道 緑:円、青:大きな道)

追加引数を取るユーザ定義関数

CREATE OR REPLACE FUNCTION raster_mapalgebra_userargs(
        rast1 double precision,
        rast2 double precision,
    pos integer[],
        VARIADIC userargs text[]
)
        RETURNS double precision
        AS $$
        DECLARE
        BEGIN
                CASE
                        WHEN rast1 IS NOT NULL AND rast2 IS NOT NULL THEN
                                RETURN least(userargs[1]::integer,(rast1 + rast2)/2.);
                        WHEN rast1 IS NULL AND rast2 IS NULL THEN
                                RETURN userargs[2]::integer;
                        WHEN rast1 IS NULL THEN
                                RETURN greatest(rast2,random()*userargs[3]::integer)::integer;
                        ELSE
                                RETURN greatest(rast1, random()*userargs[4]::integer)::integer;
                END CASE;

                RETURN NULL;
        END;
        $$ LANGUAGE 'plpgsql' VOLATILE COST 1000;
        
SELECT ST_MapAlgebraFct(m1.rast, 1, m1.rast, 3,
                        'raster_mapalgebra_userargs(double precision, double precision, integer[], text[])'::regprocedure,
                                '8BUI', 'INTERSECT', '100','200','200','0') 
                FROM map_shapes As m1
                        WHERE m1.descrip = 'map bands overlay fct union (canvas)'; 
                                        

追加引数を持つユーザ定義関数と同じラスタからの異なるバンド

関連情報

ST_MapAlgebraExpr, ST_BandPixelType, ST_GeoReference, ST_SetValue