ST_MapAlgebraFct — 2 波段版本 - 通过在提供的 2 个输入栅格波段和像素类型上应用有效的 PostgreSQL 函数来创建新的单波段栅格。 如果未指定波段,则假定为波段 1。 如果未指定,范围类型默认为 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 (callback function version)(回调函数版本)代替。 |
创建一个新的单波段栅格,该栅格是通过对输入栅格 rast1、rast2 应用由tworastuserfunc 指定的有效 PostgreSQL 函数而形成的。 如果未指定 band1 或 band2,则假定为 band 1。 新栅格将具有与原始栅格相同的地理参考、宽度和高度,但只有一个波段。
如果传入pixeltype,则新栅格将具有该像素类型的波段。 如果将像素类型传递为 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;
Tworastuserfunc 可以接受三个或四个参数:一个双精度值、一个双精度值、一个可选的整数数组和一个可变文本数组。 第一个参数是 rast1 中单个栅格像元的值(无论栅格数据类型如何)。 第二个参数是 rast2 中的单个栅格像元值。 第三个参数是当前处理单元的位置,格式为“{x,y}”。 第四个参数指示ST_MapAlgebraFct 的所有剩余参数均应传递给tworastuserfunc。
将 regprodedure 参数传递给 SQL 函数需要传递完整的函数签名,然后转换为 regprocedure 类型。 要将上述示例 PL/pgSQL 函数作为参数传递,参数的 SQL 为:
'simple_function(double precision, double precision, integer[], text[])'::regprocedure
请注意,参数包含函数名称、函数参数类型、名称和参数类型周围的引号以及对 regprocedure 的强制转换。
Tworastuserfunc 的第四个参数是可变文本数组。 任何 ST_MapAlgebraFct 调用的所有尾随文本参数都会传递到指定的tworastuserfunc,并包含在 userargs 参数中。
|
|
|
有关 VARIADIC 关键字的更多信息,请参阅 PostgreSQL 文档和查询语言 (SQL) 函数的“具有可变参数数量的 SQL 函数”部分。 |
|
|
|
无论您是否选择将任何参数传递给用户函数进行处理,text[] 参数在 |
可用性: 2.0.0
The deprecated two-raster callback form can often be expressed with the modern two-raster ST_MapAlgebra (callback function version) expression variant. This build-time example renders two input rasters and their averaged overlap.
WITH canvas AS (
SELECT ST_AddBand(
ST_MakeEmptyRaster(80, 80, 0, 80, 1, -1, 0, 0, 0),
1, '8BUI', 0, 0
) AS rast
), inputs AS (
SELECT
ST_AsRaster(ST_Buffer(ST_Point(30, 40), 25), rast, '8BUI', 80, 0)
AS raster_1,
ST_AsRaster(ST_Buffer(ST_Point(50, 40), 25), rast, '8BUI', 220, 0)
AS raster_2
FROM canvas
), variants AS (
SELECT 'raster 1' AS title, raster_1 AS rendered FROM inputs
UNION ALL
SELECT 'raster 2', raster_2 FROM inputs
UNION ALL
SELECT 'averaged', ST_MapAlgebra(
raster_1, 1,
raster_2, 1,
'([rast1] + [rast2]) / 2',
'8BUI',
'UNION'
) FROM inputs
)
SELECT title, ST_AsPNG(rendered) AS image
FROM variants
ORDER BY title DESC;
title | image ----------+------------------------- raster 2 | PNG image, 50 x 50 pixels raster 1 | PNG image, 50 x 50 pixels averaged | PNG image, 70 x 50 pixels
Define our user defined function.
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;
Prepare a test table of rasters.
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
),
-- define our canvas to be 1 to 1 pixel to geometry
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
)
-- return our rasters aligned with our canvas
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;
Map algebra on single-band rasters and then collect the result with 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;
A compact, executable callback example. The source rasters and their averaged overlap are rendered at build time.
CREATE OR REPLACE FUNCTION pg_temp.raster_average(
value_1 double precision,
value_2 double precision,
position integer[],
VARIADIC userargs text[]
) RETURNS double precision
LANGUAGE SQL IMMUTABLE
AS 'SELECT COALESCE(($1 + $2) / 2.0, $1, $2)';
WITH canvas AS (
SELECT ST_AddBand(
ST_MakeEmptyRaster(80, 80, 0, 80, 1, -1, 0, 0, 0),
1, '8BUI', 0, 0
) AS rast
), inputs AS (
SELECT
ST_AsRaster(ST_Buffer(ST_Point(30, 40), 25), rast, '8BUI', 80, 0)
AS raster_1,
ST_AsRaster(ST_Buffer(ST_Point(50, 40), 25), rast, '8BUI', 220, 0)
AS raster_2
FROM canvas
), variants AS (
SELECT 'raster 1' AS title, raster_1 AS rendered FROM inputs
UNION ALL
SELECT 'raster 2', raster_2 FROM inputs
UNION ALL
SELECT 'averaged', ST_MapAlgebraFct(
raster_1,
raster_2,
'pg_temp.raster_average(double precision,double precision,integer[],text[])'::regprocedure,
'8BUI',
'UNION'
) FROM inputs
)
SELECT title, ST_AsPNG(rendered) AS image
FROM variants
ORDER BY title DESC;
title | image ----------+--------------------------- raster 2 | PNG image, 50 x 50 pixels raster 1 | PNG image, 50 x 50 pixels averaged | PNG image, 70 x 50 pixels
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)';
The generated callback figure above demonstrates the raster alignment and overlap used by this variant; the exact callback result remains available as text.