如何对单个 PostGIS 栅格 table 中的所有波段进行平均?
How can I average all bands in a single PostGIS raster table?
我在启用 postgis 的 postgres 数据库中的单个栅格 table 中有 1 年的每日气候数据。它有 365 个波段(每天一个)。我如何平均所有波段以获得每个像素的单个年度平均值?我尝试了 ST_Union,但它 returns 所有波段,或者我没有正确使用它:
select rid, st_union(rast, 'MEAN')
from climate_table
group by rid;
我找到了使用 ST_DumpAsPolygons 的解决方法,但它非常慢。任何建议表示赞赏。 (此外,我无法相信“乐队”还不是标签,而且我没有足够的声誉来创建它!)
根据the documentation,他的函数ST_Union()
需要一组栅格。您有一个包含许多波段的栅格。
您可以使用 ST_Union
,但您必须将数据转换为一组栅格,其中每个栅格首先包含一个波段。
这是一个测试用例:
-- Create a table and add a row with an empty raster:
CREATE TABLE r_src(rid integer primary key, rast raster);
INSERT INTO r_src values(1,ST_MakeEmptyRaster(4,4,0,0,1));
-- Add two band layers to this raster one with value 10 for each point,
-- the other with value 4 for each point.
UPDATE r_src
SET rast = ST_AddBand(rast,'4BUI'::text,10)
WHERE rid = 1;
UPDATE r_src
SET rast = ST_AddBand(rast,'4BUI'::text,4)
WHERE rid = 1;
-- check what we have
SELECT (rmd).width, (rmd).height, (rmd).numbands
FROM (SELECT ST_MetaData(rast) As rmd
FROM r_src WHERE rid = 1) AS foo;
-- 4| 4| 2 --ok
-- output rasterdata in hex for both bands:
SELECT ST_AsHexWKB(rast) As rastbin FROM r_src WHERE rid=1;
-- output rasterdata for the 2nd band (note the '...040404' point values
-- compared to '...0A0A0A' if you select the band at idx 1
SELECT ST_AsHexWKB(ST_Band(rast,2))FROM r_src WHERE rid = 1;
-- now step by step...
-- src is the single rast in our source table,
-- in extracted this is joined with a generated series
-- for each value in the series a new raster is returned
-- containing the band at that index:
WITH src AS (SELECT rast FROM r_src WHERE rid = 1),
extracted AS (SELECT ST_Band(src.rast,ser.idx)
FROM src
JOIN generate_series(1,2) AS ser(idx ) ON true)
SELECT * FROM extracted;
-- outputs 2 rows with one raster each, and each raster containing one band
-- now aggreagating these:
WITH src AS (SELECT rast FROM r_src WHERE rid = 1),
extracted AS (SELECT ST_Band(src.rast,ser.idx) AS r_day
FROM src
JOIN generate_series(1,2) AS ser(idx ) ON true)
SELECT ST_Union(r_day,1,'MEAN') FROM extracted;
-- outputs one row with the resulting raster holding one band
-- that band contains the 'MEAN' point values '...070707'
我用你 linked 的数据集检查了这个,并使用 raster2pgsql
将它导入到 postgres 中。由于它的大小,我决定将它拆分为 100x100 的图块并得到一个包含 45 行的 table。现在要转换整个栅格,我使用了以下语句:
CREATE TABLE averages AS
WITH extracted AS (SELECT src.rid , ST_Band(src.rast,ser.idx) AS r_day
FROM rastertest src
JOIN generate_series(1,365) AS ser(idx ) ON true)
SELECT rid, ST_Union(r_day,1,'MEAN') AS rast
FROM extracted
GROUP BY rid;
这将创建一个新的 table 平均值,仅包含平均值。
我在启用 postgis 的 postgres 数据库中的单个栅格 table 中有 1 年的每日气候数据。它有 365 个波段(每天一个)。我如何平均所有波段以获得每个像素的单个年度平均值?我尝试了 ST_Union,但它 returns 所有波段,或者我没有正确使用它:
select rid, st_union(rast, 'MEAN')
from climate_table
group by rid;
我找到了使用 ST_DumpAsPolygons 的解决方法,但它非常慢。任何建议表示赞赏。 (此外,我无法相信“乐队”还不是标签,而且我没有足够的声誉来创建它!)
根据the documentation,他的函数ST_Union()
需要一组栅格。您有一个包含许多波段的栅格。
您可以使用 ST_Union
,但您必须将数据转换为一组栅格,其中每个栅格首先包含一个波段。
这是一个测试用例:
-- Create a table and add a row with an empty raster:
CREATE TABLE r_src(rid integer primary key, rast raster);
INSERT INTO r_src values(1,ST_MakeEmptyRaster(4,4,0,0,1));
-- Add two band layers to this raster one with value 10 for each point,
-- the other with value 4 for each point.
UPDATE r_src
SET rast = ST_AddBand(rast,'4BUI'::text,10)
WHERE rid = 1;
UPDATE r_src
SET rast = ST_AddBand(rast,'4BUI'::text,4)
WHERE rid = 1;
-- check what we have
SELECT (rmd).width, (rmd).height, (rmd).numbands
FROM (SELECT ST_MetaData(rast) As rmd
FROM r_src WHERE rid = 1) AS foo;
-- 4| 4| 2 --ok
-- output rasterdata in hex for both bands:
SELECT ST_AsHexWKB(rast) As rastbin FROM r_src WHERE rid=1;
-- output rasterdata for the 2nd band (note the '...040404' point values
-- compared to '...0A0A0A' if you select the band at idx 1
SELECT ST_AsHexWKB(ST_Band(rast,2))FROM r_src WHERE rid = 1;
-- now step by step...
-- src is the single rast in our source table,
-- in extracted this is joined with a generated series
-- for each value in the series a new raster is returned
-- containing the band at that index:
WITH src AS (SELECT rast FROM r_src WHERE rid = 1),
extracted AS (SELECT ST_Band(src.rast,ser.idx)
FROM src
JOIN generate_series(1,2) AS ser(idx ) ON true)
SELECT * FROM extracted;
-- outputs 2 rows with one raster each, and each raster containing one band
-- now aggreagating these:
WITH src AS (SELECT rast FROM r_src WHERE rid = 1),
extracted AS (SELECT ST_Band(src.rast,ser.idx) AS r_day
FROM src
JOIN generate_series(1,2) AS ser(idx ) ON true)
SELECT ST_Union(r_day,1,'MEAN') FROM extracted;
-- outputs one row with the resulting raster holding one band
-- that band contains the 'MEAN' point values '...070707'
我用你 linked 的数据集检查了这个,并使用 raster2pgsql
将它导入到 postgres 中。由于它的大小,我决定将它拆分为 100x100 的图块并得到一个包含 45 行的 table。现在要转换整个栅格,我使用了以下语句:
CREATE TABLE averages AS
WITH extracted AS (SELECT src.rid , ST_Band(src.rast,ser.idx) AS r_day
FROM rastertest src
JOIN generate_series(1,365) AS ser(idx ) ON true)
SELECT rid, ST_Union(r_day,1,'MEAN') AS rast
FROM extracted
GROUP BY rid;
这将创建一个新的 table 平均值,仅包含平均值。