From: Regina Obe Date: Mon, 21 Aug 2017 02:06:40 +0000 (+0000) Subject: ST_MakeEmptyCoverage (David Zwarg, ainomieli) X-Git-Tag: 2.4.0beta1~49 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1a4769f31354977450fd2734f380933815e20069;p=postgis ST_MakeEmptyCoverage (David Zwarg, ainomieli) Closes #2249 for PostGIS 2.4.0 git-svn-id: http://svn.osgeo.org/postgis/trunk@15562 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/NEWS b/NEWS index 04f9a8784..c66b2b698 100644 --- a/NEWS +++ b/NEWS @@ -14,8 +14,9 @@ PostGIS 2.4.0 - #3753, Gist penalty speed improvements for 2d and nd points (Darafei Praliaskouski) - #3677, ST_FrechetDistance (Shinichi Sugiyama) - - Most aggregates (raster and geometry), + - Most aggregates (raster and geometry), and all stable / immutable (raster and geometry) marked as parallel safe + - #2249, ST_MakeEmptyCoverage for raster (David Zwarg, ainomieli) * Enhancements * diff --git a/doc/reference_raster.xml b/doc/reference_raster.xml index ac4e41c2d..4d49c2544 100644 --- a/doc/reference_raster.xml +++ b/doc/reference_raster.xml @@ -1962,6 +1962,72 @@ WHERE rid=35; + + + ST_MakeEmptyCoverage + Cover georeferenced area with a grid of empty raster tiles. + + + + + + raster ST_MakeEmptyCoverage + integer tilewidth + integer tileheight + integer width + integer height + double precision upperleftx + double precision upperlefty + double precision scalex + double precision scaley + double precision skewx + double precision skewy + integer srid=unknown + + + + + + Description + + Create a set of raster tiles with . Grid dimension is width & height. Tile dimension is tilewidth & tileheight. The covered georeferenced area is from upper left corner (upperleftx, upperlefty) to lower right corner (upperleftx width * scalex, upperlefty height * scaley). + + Availability: 2.4.0 + + + + Examples Basic + Create 16 tiles in a 4x4 grid to cover the WGS84 area from upper left corner (22, 77) to lower right corner (55, 33). + + + + + See Also + + + + + + ST_MakeEmptyRaster diff --git a/raster/rt_pg/rtpostgis.sql.in b/raster/rt_pg/rtpostgis.sql.in index e862d1d06..07517fb30 100644 --- a/raster/rt_pg/rtpostgis.sql.in +++ b/raster/rt_pg/rtpostgis.sql.in @@ -8836,6 +8836,61 @@ BEGIN END; $$ LANGUAGE 'plpgsql' VOLATILE STRICT; + +-- Availability: 2.4.0 +CREATE OR REPLACE FUNCTION st_makeemptycoverage(tilewidth int, tileheight int, width int, height int, upperleftx float8, upperlefty float8, scalex float8, scaley float8, skewx float8, skewy float8, srid int4 DEFAULT 0) + RETURNS SETOF RASTER AS $$ + DECLARE + ulx double precision; -- upper left x of raster + uly double precision; -- upper left y of raster + rw int; -- raster width (may change at edges) + rh int; -- raster height (may change at edges) + x int; -- x index of coverage + y int; -- y index of coverage + template raster; -- an empty template raster, where each cell + -- represents a tile in the coverage + minY double precision; + maxX double precision; + BEGIN + template := @extschema@.ST_MakeEmptyRaster( + ceil(width::float8/tilewidth)::int, + ceil(height::float8/tileheight)::int, + upperleftx, + upperlefty, + tilewidth * scalex, + tileheight * scaley, + tileheight * skewx, + tilewidth * skewy, + srid + ); + + FOR y IN 1..st_height(template) LOOP + maxX := @extschema@.ST_RasterToWorldCoordX(template, 1, y) + width * scalex; + FOR x IN 1..st_width(template) LOOP + minY := @extschema@.ST_RasterToWorldCoordY(template, x, 1) + height * scaley; + uly := @extschema@.ST_RasterToWorldCoordY(template, x, y); + IF uly + (tileheight * scaley) < minY THEN + --raise notice 'uly, minY: %, %', uly, minY; + rh := ceil((minY - uly)/scaleY)::int; + ELSE + rh := tileheight; + END IF; + + ulx := @extschema@.ST_RasterToWorldCoordX(template, x, y); + IF ulx + (tilewidth * scalex) > maxX THEN + --raise notice 'ulx, maxX: %, %', ulx, maxX; + rw := ceil((maxX - ulx)/scaleX)::int; + ELSE + rw := tilewidth; + END IF; + + RETURN NEXT @extschema@.ST_MakeEmptyRaster(rw, rh, ulx, uly, scalex, scaley, skewx, skewy, srid); + END LOOP; + END LOOP; + END; + $$ LANGUAGE 'plpgsql' IMMUTABLE _PARALLEL; + + ------------------------------------------------------------------- -- Debugging ------------------------------------------------------------------- diff --git a/raster/test/regress/Makefile.in b/raster/test/regress/Makefile.in index 9853ab00c..e5a40793b 100644 --- a/raster/test/regress/Makefile.in +++ b/raster/test/regress/Makefile.in @@ -109,6 +109,7 @@ TEST_UTILITY = \ rt_gdalwarp \ rt_asraster \ rt_dumpvalues \ + rt_makeemptycoverage \ rt_createoverview TEST_MAPALGEBRA = \ diff --git a/raster/test/regress/rt_makeemptycoverage.sql b/raster/test/regress/rt_makeemptycoverage.sql new file mode 100644 index 000000000..dbe00308a --- /dev/null +++ b/raster/test/regress/rt_makeemptycoverage.sql @@ -0,0 +1,10 @@ +-- make an empty coverage with equal tiles (all 5x5) +select '1', st_metadata(st_makeemptycoverage(5, 5, 10, 10, 0, 0, 1, -1, 0, 0, 0)); +-- make an empty coverage with unequal coverage (4x4, 3x4, 4x3, 3x3) +select '2', st_metadata(st_makeemptycoverage(4, 4, 7, 7, 0, 0, 1, -1, 0, 0, 0)); +-- make an empty coverage with equal coverage and scaled +select '3', st_metadata(st_makeemptycoverage(5, 5, 10, 10, 0, 0, 2, -2, 0, 0, 0)); +-- make an empty coverage with unequal coverage and scaled +select '4', st_metadata(st_makeemptycoverage(6, 6, 10, 10, 0, 0, 3, -3, 0, 0, 0)); +-- make an empty coverage with equal coverage and rotated +select '5', st_metadata(st_makeemptycoverage(5, 5, 10, 10, 0, 0, 0.707106781186548, -0.707106781186548, -0.707106781186548, -0.707106781186548, 0)); diff --git a/raster/test/regress/rt_makeemptycoverage_expected b/raster/test/regress/rt_makeemptycoverage_expected new file mode 100644 index 000000000..e458a54e1 --- /dev/null +++ b/raster/test/regress/rt_makeemptycoverage_expected @@ -0,0 +1,20 @@ +1|(0,0,5,5,1,-1,0,0,0,0) +1|(5,0,5,5,1,-1,0,0,0,0) +1|(0,-5,5,5,1,-1,0,0,0,0) +1|(5,-5,5,5,1,-1,0,0,0,0) +2|(0,0,4,4,1,-1,0,0,0,0) +2|(4,0,3,4,1,-1,0,0,0,0) +2|(0,-4,4,3,1,-1,0,0,0,0) +2|(4,-4,3,3,1,-1,0,0,0,0) +3|(0,0,5,5,2,-2,0,0,0,0) +3|(10,0,5,5,2,-2,0,0,0,0) +3|(0,-10,5,5,2,-2,0,0,0,0) +3|(10,-10,5,5,2,-2,0,0,0,0) +4|(0,0,6,6,3,-3,0,0,0,0) +4|(18,0,4,6,3,-3,0,0,0,0) +4|(0,-18,6,4,3,-3,0,0,0,0) +4|(18,-18,4,4,3,-3,0,0,0,0) +5|(0,0,5,5,0.707106781186548,-0.707106781186548,-0.707106781186548,-0.707106781186548,0,0) +5|(3.53553390593274,-3.53553390593274,5,5,0.707106781186548,-0.707106781186548,-0.707106781186548,-0.707106781186548,0,0) +5|(-3.53553390593274,-3.53553390593274,5,5,0.707106781186548,-0.707106781186548,-0.707106781186548,-0.707106781186548,0,0) +5|(0,-7.07106781186548,5,5,0.707106781186548,-0.707106781186548,-0.707106781186548,-0.707106781186548,0,0)