2

I have a raster table with index created by raster2pgsql

CREATE TABLE tbl (rid serial PRIMARY KEY, rast raster);
CREATE INDEX ON tbl USING gist (st_convexhull(rast));

I can see the best way to fetch a single point value is

SELECT ST_Value(rast, :point) FROM tbl WHERE ST_ConvexHull(rast) ~ :point;

However, given the structure and the functions I can see, it's not obvious how to best fetch e.g. 1000 point values at once. Neither from a single tile, not if they span across tiles.

I had an initial try with MULTIPOINT geometry, but they don't work with ST_Value, and I didn't know where to start with the WHERE clause.

2 Answers 2

3

This should trivially be

SELECT ST_Value(r.rast, pt.geom)
FROM   <raster> AS r
JOIN   <points> AS pt
  ON   ST_Intersects(r.rast, pt.geom)
;

where <points> can be any table expression you can think of.

7
  • This decides to use a Seq Scan instead of the index in various cases, which destroys the performance. For example, if <points> is st_dump. Any idea how to solve this?
    – OrangeDog
    Commented Jun 11, 2021 at 12:52
  • Actually, it doesn't use the index for multiple points at all, so this is pretty bad.
    – OrangeDog
    Commented Jun 11, 2021 at 13:28
  • ST_Dump results themselves are never covered by an index, nor any other derived geometries (unless covered by a functional index). ST_Intersects is supposed to use the index on rast only, and the planner may deem a Seq scan to be more efficient in cases when it expects to have to scan more than a percentage of the table. Update statistics may help: VACUUM ANALYZE <raster_table>;.
    – geozelot
    Commented Jun 11, 2021 at 14:21
  • o fix this it should be ST_Intersects(ST_ConvexHull(r.rast), pt.geom). Then it uses the index regardless of the structure and cardinality of <points>
    – OrangeDog
    Commented Jun 11, 2021 at 15:17
  • You're welcome to update my answer! I cannot check the structure of a PostGIS raster table right now; is there a functional index on ST_ConvexHull on the raster table? If not, the only index usable is that of <points>, which can never be the result of a geometry dump, or any dynamic or derived geometry (except another functional index for the latter).
    – geozelot
    Commented Jun 11, 2021 at 15:22
1

To account for repeated points, boundaries, and overlapping or missing rasters, this was my final solution:

SELECT (array_agg(ST_Value(r.rast, pt.geom) ORDER BY r.rid DESC)
        FILTER ( WHERE ST_Value(r.rast, pt.geom) IS NOT NULL ))[1] 
FROM tbl AS r 
  RIGHT JOIN ST_Dump(:multipoint) AS pt 
  ON ST_ConvexHull(r.rast) ~ pt.geom
GROUP BY pt.path;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.