使用 ST_Reclass 选择特定值范围内的像素
关于此栅格的问题经常出现在 PostGIS 邮件列表和 Stack Overflow 上,最佳答案通常涉及经常被遗忘的 ST_Reclass
函数,该函数自 PostGIS 2.0 起就已存在。人们通常求助于速度更慢但更灵活的 ST_MapAlgebra
,或者将栅格转储为像素值多边形,然后使用 WHERE val > 90 过滤它们,而 ST_Reclass
执行相同操作,但速度快几个数量级。
问题类似于以下内容
我的这个栅格测量的是波段 1 中像素值中氨的污染水平,我想按 0 低、1 中、2 高对污染进行分级。然后,我想查找此污染的面积或对其执行其他疯狂的几何操作。
基本策略是将栅格简化为一个更简单的栅格,其中包含 0、1、2,其中 0 最终被标记为 nodata
。然后,将 0(或你选择的任何数字)标记为 nodata
。最后,你将得到一个相当简单的栅格,该栅格易于矢量化或保留为栅格并进行统计。
因此,例如,这里我们使用 ST_Reclass 将所有像素值 >= 0 且 <= 90 重新分类为 0,>90 < 100 重新分类为 1,100 到 1000 重新分类为 2。最后一个参数使值 0 表示 nodata
。
SELECT ST_Reclass(rast, 1,
'[0-90]:0,(90-100):1,[100-1000):2',
'4BUI', 0) As rast
FROM sometable
WHERE filename = '123.tif';
将为你提供一组新的栅格,其中包含像素值 1、2 和 nodata
。
现在,问题的下一部分是,你如何在这一新集合上执行几何操作,例如在这种情况下计算每个毒性水平区域的质心
WITH cgeoms AS ( SELECT ST_DumpAsPolygons(
ST_Reclass(rast, 1,
'[0-90]:0,(90-100):1,[100-1000):2',
'4BUI', 0), 1
) AS gval
FROM sometable
WHERE filename = '123.tif' )
SELECT ST_Centroid(
ST_Union( (gval).geom ) ) As geom,
(gval).val
FROM cgeoms
GROUP BY (gval).val;
您还可以使用 ST_Histogram
和 ST_ValueCount
等函数执行许多统计,因此您不必诉诸于矢量化栅格来对其执行基本统计。