第11章 使用 PostGIS ST_ValueCount 获取栅格像素值统计
获取栅格的不同像素值及像素值统计
PostGIS raster 的函数非常多,做同一件事可能至少有 10 种方法,而且性能差异可能很大。假设你有一个栅格,或者只关心栅格中的某块感兴趣区域——比如高程栅格,想了解该区域内有哪些不同的像素值。你可能会想到用 ST_Value 函数,但有一个高效得多的选择:ST_ValueCount。
ST_ValueCount 是 PostGIS 2.0+ 提供的众多栅格统计函数之一。它是一个集合返回函数,每行返回两个值:像素值(value),以及栅格中该值的像素数量(count)。它还有若干变体,支持按指定像素值过滤。
本文灵感来自 stackexchange 上的这个问题:How can I extract all distinct values from a PostGIS Raster?
示例
获取所有栅格瓦片 band 1 的不同像素值列表
指定波段编号是可选的,不指定时默认为 1。
不过我习惯显式写出来,因为我经常处理多波段栅格。这里我用的是名为 dem 的数字高程数据表。
SELECT DISTINCT (pvc).value FROM (SELECT ST_ValueCount(dem.rast,1) As pvc FROM dem) As f ORDER BY (pvc).value;
如果你用的是 PostgreSQL 9.3+,可以借助 LATERAL 子句把查询写得更简洁(LATERAL 关键字在大多数情况下可以省略,所以可以写成这样):
SELECT DISTINCT (pvc).value FROM dem, ST_ValueCount(dem.rast,1) As pvc ORDER BY (pvc).value;
获取感兴趣区域 band 1 的像素值列表及像素总数
如果数据覆盖范围很大,你很可能只关心某个特定区域,而不是手头的几百万个瓦片。
你可能还想知道在该区域内每个值出现了多少次。
这时就需要把 ST_Clip 和 ST_Intersects 组合起来用。
这里我用的是 9.3 的 LATERAL 简写形式:
SELECT (pvc).value, SUM((pvc).count) As tot_pix FROM dem INNER JOIN ST_GeomFromText('LINESTRING(-87.627 41.8819, -87.629 41.8830)' , 4326) As geom ON ST_Intersects(dem.rast, geom), ST_ValueCount(ST_Clip(dem.rast,geom),1) As pvc GROUP BY (pvc).value ORDER BY (pvc).value;