You're right, using ST_Intersection
slows down your query noticeable.
Instead of using ST_Intersection
it is better to clip (ST_Clip
) your raster with the polygons (your fields) and dump the result as polygons (ST_DumpAsPolygons
). So every raster cell will be converted into a little polygon rectangle with distinct values.
For receiving min, max or mean from the dumps you can use the same statements.
This query should do the trick:
SELECT
toid,
Min((gv).val) As MinElevation,
Max((gv).val) As MaxElevation,
Sum(ST_Area((gv).geom) * (gv).val) / Sum(ST_Area((gv).geom)) as MeanElevation
FROM (
SELECT
toid,
ST_DumpAsPolygons(ST_Clip(rast, 1, geom, true)) AS gv
FROM topo_area_su_region,dem
WHERE ST_Intersects(rast, geom)) AS foo
GROUP BY toid
ORDER BY toid;
In the statement ST_Clip
you define the raster, the raster band (=1), the polygon and if the crop should be TRUE or FALSE.
Besides you can use avg((gv).val)
to calculate the mean value.
EDIT
The result of your approach is the more exact, but the slower one. The results of the combination of ST_Clip
and ST_DumpAsPolygons
are ignoring the raster cells that are intersecting with less than 50% (or 51%) of their size.
These two screen shots from a CORINE Land Use intersection show the difference. First picture with ST_Intersection
, second one with ST_Clip
and ST_DumpAsPolygons
.
Best Answer
You are comparing each station to each census block and for each one returning all but one census block.
To fix this you need to union your stations together and then find the disjoint polygons.