名稱

ST_MapAlgebraExpr — 雙柵格波段版本:建立一個新的單波段柵格,該柵格通過將有效的 PostgreSQL 代數運算應用於兩個輸入柵格波段,並使用提供的像素類型形成。如果未指定波段編號,則假設每個柵格的波段 1。產生的柵格將在由第一個柵格定義的網格上對齊(比例、傾斜和像素角),並且其範圍由 "extenttype" 參數定義。"extenttype" 的值可以是:INTERSECTION、UNION、FIRST、SECOND。

概要

raster ST_MapAlgebraExpr(raster rast1, raster rast2, text expression, text pixeltype=same_as_rast1_band, text extenttype=INTERSECTION, text nodata1expr=NULL, text nodata2expr=NULL, double precision nodatanodataval=NULL);

raster ST_MapAlgebraExpr(raster rast1, integer band1, raster rast2, integer band2, text expression, text pixeltype=same_as_rast1_band, text extenttype=INTERSECTION, text nodata1expr=NULL, text nodata2expr=NULL, double precision nodatanodataval=NULL);

描述

[Warning]

ST_MapAlgebraExpr 自 2.1.0 版起已棄用。請改用 ST_MapAlgebra (表達式版本)

建立一個新的單波段柵格,該柵格通過將有效的 PostgreSQL 代數運算應用於由兩個輸入柵格波段 rast1、(rast2) 的 expression 定義的兩個波段。如果未指定 band1band2,則假設為波段 1。產生的柵格將在由第一個柵格定義的網格上對齊(比例、傾斜和像素角)。產生的柵格將具有由 extenttype 參數定義的範圍。

expression

一個涉及兩個柵格和 PostgreSQL 定義的函數/運算符的 PostgreSQL 代數表達式,當像素相交時將定義像素值。例如:(([rast1] + [rast2])/2.0)::integer

pixeltype

輸出柵格的結果像素類型。必須是 ST_BandPixelType 中列出的其中一個,或者保留或設定為 NULL。如果未傳入或設定為 NULL,則預設為第一個柵格的像素類型。

extenttype

控制結果柵格的範圍

  1. INTERSECTION - 新柵格的範圍是兩個柵格的交集。這是預設值。

  2. UNION - 新柵格的範圍是兩個柵格的聯集。

  3. FIRST - 新柵格的範圍與第一個柵格的範圍相同。

  4. SECOND - 新柵格的範圍與第二個柵格的範圍相同。

nodata1expr

一個僅涉及 rast2 或常數的代數表達式,用於定義當 rast1 的像素為 nodata 值且空間對應的 rast2 像素有值時要傳回的內容。

nodata2expr

一個僅涉及 rast1 或常數的代數表達式,用於定義當 rast2 的像素為 nodata 值且空間對應的 rast1 像素有值時要傳回的內容。

nodatanodataval

當空間對應的 rast1 和 rast2 像素均為 nodata 值時要傳回的數值常數。

如果傳入了 pixeltype,則新柵格將具有該像素類型的波段。如果 pixeltype 傳入 NULL 或未指定像素類型,則新柵格波段將具有與輸入 rast1 波段相同的像素類型。

使用術語 [rast1.val] [rast2.val] 來表示原始柵格波段的像素值,並使用 [rast1.x][rast1.y] 等來表示像素的欄/列位置。

可用性:2.0.0

範例:2 個波段的交集和聯集

從我們的原始柵格建立一個新的 1 波段柵格,該柵格是原始柵格波段模數 2 的函數。

--Create a cool set of rasters --
DROP TABLE IF EXISTS fun_shapes;
CREATE TABLE fun_shapes(rid serial PRIMARY KEY, fun_name text, rast raster);

-- Insert some cool shapes around Boston in Massachusetts state plane meters --
INSERT INTO fun_shapes(fun_name, rast)
VALUES ('ref', ST_AsRaster(ST_MakeEnvelope(235229, 899970, 237229, 901930,26986),200,200,'8BUI',0,0));

INSERT INTO fun_shapes(fun_name,rast)
WITH ref(rast) AS (SELECT rast FROM fun_shapes WHERE fun_name = 'ref' )
SELECT 'area' AS fun_name, ST_AsRaster(ST_Buffer(ST_SetSRID(ST_Point(236229, 900930),26986), 1000),
            ref.rast,'8BUI', 10, 0) As rast
FROM ref
UNION ALL
SELECT 'rand bubbles',
            ST_AsRaster(
            (SELECT ST_Collect(geom)
    FROM (SELECT ST_Buffer(ST_SetSRID(ST_Point(236229 + i*random()*100, 900930 + j*random()*100),26986), random()*20) As geom
            FROM generate_series(1,10) As i, generate_series(1,10) As j
            ) As foo ), ref.rast,'8BUI', 200, 0)
FROM ref;

--map them -
SELECT  ST_MapAlgebraExpr(
        area.rast, bub.rast, '[rast2.val]', '8BUI', 'INTERSECTION', '[rast2.val]', '[rast1.val]') As interrast,
        ST_MapAlgebraExpr(
            area.rast, bub.rast, '[rast2.val]', '8BUI', 'UNION', '[rast2.val]', '[rast1.val]') As unionrast
FROM
  (SELECT rast FROM fun_shapes WHERE
 fun_name = 'area') As area
CROSS JOIN  (SELECT rast
FROM fun_shapes WHERE
 fun_name = 'rand bubbles') As bub
                    

地圖代數交集

地圖代數聯集

範例:將柵格覆蓋在畫布上作為單獨的波段

-- we use ST_AsPNG to render the image so all single band ones look grey --
WITH mygeoms
    AS ( SELECT 2 As bnum, ST_Buffer(ST_Point(1,5),10) As geom
            UNION ALL
            SELECT 3 AS bnum,
                ST_Buffer(ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'), 10,'join=bevel') As geom
            UNION ALL
            SELECT 1 As bnum,
                ST_Buffer(ST_GeomFromText('LINESTRING(60 50,150 150,150 50)'), 5,'join=bevel') As geom
            ),
   -- define our canvas to be 1 to 1 pixel to geometry
   canvas
    AS (SELECT ST_AddBand(ST_MakeEmptyRaster(200,
        200,
        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
            ),
   rbands AS (SELECT ARRAY(SELECT ST_MapAlgebraExpr(canvas.rast, ST_AsRaster(m.geom, canvas.rast, '8BUI', 100),
                 '[rast2.val]', '8BUI', 'FIRST', '[rast2.val]', '[rast1.val]') As rast
                FROM mygeoms AS m CROSS JOIN canvas
                ORDER BY m.bnum) As rasts
                )
          SELECT rasts[1] As rast1 , rasts[2] As rast2, rasts[3] As rast3, ST_AddBand(
                    ST_AddBand(rasts[1],rasts[2]), rasts[3]) As final_rast
            FROM rbands;
                    

rast1

rast2

rast3

final_rast

範例:將選定地塊的 2 米邊界覆蓋在航空影像上

-- Create new 3 band raster composed of first 2 clipped bands, and overlay of 3rd band with our geometry
-- This query took 3.6 seconds on PostGIS windows 64-bit install
WITH pr AS
-- Note the order of operation: we clip all the rasters to dimensions of our region
(SELECT ST_Clip(rast,ST_Expand(geom,50) ) As rast, g.geom
    FROM aerials.o_2_boston AS r INNER JOIN
-- union our parcels of interest so they form a single geometry we can later intersect with
        (SELECT ST_Union(ST_Transform(geom,26986)) AS geom
          FROM landparcels WHERE pid IN('0303890000', '0303900000')) As g
        ON ST_Intersects(rast::geometry, ST_Expand(g.geom,50))
),
-- we then union the raster shards together
-- ST_Union on raster is kinda of slow but much faster the smaller you can get the rasters
-- therefore we want to clip first and then union
prunion AS
(SELECT ST_AddBand(NULL, ARRAY[ST_Union(rast,1),ST_Union(rast,2),ST_Union(rast,3)] ) As clipped,geom
FROM pr
GROUP BY geom)
-- return our final raster which is the unioned shard with
-- with the overlay of our parcel boundaries
-- add first 2 bands, then mapalgebra of 3rd band + geometry
SELECT ST_AddBand(ST_Band(clipped,ARRAY[1,2])
    , ST_MapAlgebraExpr(ST_Band(clipped,3), ST_AsRaster(ST_Buffer(ST_Boundary(geom),2),clipped, '8BUI',250),
     '[rast2.val]', '8BUI', 'FIRST', '[rast2.val]', '[rast1.val]') ) As rast
FROM prunion;
                    

藍線是選定地塊的邊界