]> granicus.if.org Git - postgis/commitdiff
ST_MakeEmptyCoverage (David Zwarg, ainomieli)
authorRegina Obe <lr@pcorp.us>
Mon, 21 Aug 2017 02:06:40 +0000 (02:06 +0000)
committerRegina Obe <lr@pcorp.us>
Mon, 21 Aug 2017 02:06:40 +0000 (02:06 +0000)
Closes #2249 for PostGIS 2.4.0

git-svn-id: http://svn.osgeo.org/postgis/trunk@15562 b70326c6-7e19-0410-871a-916f4a2858ee

NEWS
doc/reference_raster.xml
raster/rt_pg/rtpostgis.sql.in
raster/test/regress/Makefile.in
raster/test/regress/rt_makeemptycoverage.sql [new file with mode: 0644]
raster/test/regress/rt_makeemptycoverage_expected [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 04f9a8784e85637de51378930b43b698f716c12f..c66b2b69802546063fb3eb41b16688caa8a7e892 100644 (file)
--- 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 *
 
index ac4e41c2d85924304d3b2a9b28fbd24002261cd2..4d49c25441caee2274efd1cae1d5e03d2f3747a4 100644 (file)
@@ -1962,6 +1962,72 @@ WHERE rid=35;
                        </refsection>
                </refentry>
 
+        <refentry id="RT_ST_MakeEmptyCoverage">
+                  <refnamediv>
+                    <refname>ST_MakeEmptyCoverage</refname>
+                    <refpurpose>Cover georeferenced area with a grid of empty raster tiles.</refpurpose>
+                  </refnamediv>
+
+                  <refsynopsisdiv>
+                    <funcsynopsis>
+                      <funcprototype>
+                        <funcdef>raster <function>ST_MakeEmptyCoverage</function></funcdef>
+                        <paramdef><type>integer </type> <parameter>tilewidth</parameter></paramdef>
+                        <paramdef><type>integer </type> <parameter>tileheight</parameter></paramdef>
+                        <paramdef><type>integer </type> <parameter>width</parameter></paramdef>
+                        <paramdef><type>integer </type> <parameter>height</parameter></paramdef>
+                        <paramdef><type>double precision </type> <parameter>upperleftx</parameter></paramdef>
+                        <paramdef><type>double precision </type> <parameter>upperlefty</parameter></paramdef>
+                        <paramdef><type>double precision </type> <parameter>scalex</parameter></paramdef>
+                        <paramdef><type>double precision </type> <parameter>scaley</parameter></paramdef>
+                        <paramdef><type>double precision </type> <parameter>skewx</parameter></paramdef>
+                        <paramdef><type>double precision </type> <parameter>skewy</parameter></paramdef>
+                        <paramdef choice="opt"><type>integer </type> <parameter>srid=unknown</parameter></paramdef>
+                      </funcprototype>
+                    </funcsynopsis>
+                  </refsynopsisdiv>
+
+                  <refsection>
+                    <title>Description</title>
+
+                    <para>Create a set of raster tiles with <xref linkend="RT_ST_MakeEmptyRaster" />. Grid dimension is <varname>width</varname> &amp; <varname>height</varname>. Tile dimension is <varname>tilewidth</varname> &amp; <varname>tileheight</varname>. The covered georeferenced area is from upper left corner (<varname>upperleftx</varname>, <varname>upperlefty</varname>) to lower right corner (<varname>upperleftx</varname>  <varname>width</varname> * <varname>scalex</varname>, <varname>upperlefty</varname>  <varname>height</varname> * <varname>scaley</varname>).</para>
+
+                    <para>Availability: 2.4.0 </para>
+                  </refsection>
+
+                  <refsection>
+                    <title>Examples Basic</title>
+                    <para>Create 16 tiles in a 4x4 grid to cover the WGS84 area from upper left corner (22, 77) to lower right corner (55, 33).</para>
+                    <programlisting><![CDATA[SELECT (ST_MetaData(tile)).* FROM ST_MakeEmptyCoverage(1, 1, 4, 4, 22, 33, (55 - 22)/(4)::float, (33 - 77)/(4)::float, 0., 0., 4326) tile;
+
+ upperleftx | upperlefty | width | height | scalex | scaley | skewx | skewy | srid | numbands 
+-------------------------------------------------------------------------------------
+         22 |         33 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
+      30.25 |         33 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
+       38.5 |         33 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
+      46.75 |         33 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
+         22 |         22 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
+      30.25 |         22 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
+       38.5 |         22 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
+      46.75 |         22 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
+         22 |         11 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
+      30.25 |         11 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
+       38.5 |         11 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
+      46.75 |         11 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
+         22 |          0 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
+      30.25 |          0 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
+       38.5 |          0 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0
+      46.75 |          0 |     1 |      1 |   8.25 |    -11 |     0 |     0 | 4326 |        0]]></programlisting>
+                  </refsection>
+
+                  <refsection>
+                    <title>See Also</title>
+                    <para>
+                      <xref linkend="RT_ST_MakeEmptyRaster" />
+                    </para>
+                  </refsection>
+        </refentry>
+
                <refentry id="RT_ST_MakeEmptyRaster">
                        <refnamediv>
                                <refname>ST_MakeEmptyRaster</refname>
index e862d1d065f8751694521df5e20bdb693f5b38f0..07517fb30e9f523ffcb457371a92f6f2184b045f 100644 (file)
@@ -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
 -------------------------------------------------------------------
index 9853ab00c959eab2a386c289f562326968fd9dd8..e5a40793b72746beff327e86bc0983129ada5aea 100644 (file)
@@ -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 (file)
index 0000000..dbe0030
--- /dev/null
@@ -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 (file)
index 0000000..e458a54
--- /dev/null
@@ -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)