]> granicus.if.org Git - postgis/commitdiff
Addition of C-based ST_MinPossibleValue to replace the existing ST_MinPossibleVal...
authorBborie Park <bkpark at ucdavis.edu>
Fri, 16 Dec 2011 01:11:21 +0000 (01:11 +0000)
committerBborie Park <bkpark at ucdavis.edu>
Fri, 16 Dec 2011 01:11:21 +0000 (01:11 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@8436 b70326c6-7e19-0410-871a-916f4a2858ee

raster/rt_pg/rt_pg.c
raster/rt_pg/rtpostgis.sql.in.c
raster/rt_pg/rtpostgis_drop.sql.in.c
raster/scripts/plpgsql/st_clip.sql
raster/scripts/plpgsql/st_mapalgebra.sql
raster/scripts/plpgsql/st_mapalgebra_optimized.sql
raster/scripts/plpgsql/st_mapalgebrafctngb.sql
raster/scripts/plpgsql/st_minpossibleval.sql [deleted file]
raster/test/regress/rt_utility.sql
raster/test/regress/rt_utility_expected

index e2e5e36838df53d9141cac4488c773cc5f7394ac..8a60e873f82256863b78319fa27660055f6261d4 100644 (file)
@@ -142,6 +142,7 @@ static char *rtpg_getSRTextSPI(int srid);
 Datum RASTER_lib_version(PG_FUNCTION_ARGS);
 Datum RASTER_lib_build_date(PG_FUNCTION_ARGS);
 Datum RASTER_gdal_version(PG_FUNCTION_ARGS);
+Datum RASTER_minPossibleValue(PG_FUNCTION_ARGS);
 
 /* Input/output and format conversions */
 Datum RASTER_in(PG_FUNCTION_ARGS);
@@ -569,6 +570,49 @@ Datum RASTER_gdal_version(PG_FUNCTION_ARGS)
        PG_RETURN_POINTER(result);
 }
 
+PG_FUNCTION_INFO_V1(RASTER_minPossibleValue);
+Datum RASTER_minPossibleValue(PG_FUNCTION_ARGS)
+{
+       text *pixeltypetext = NULL;
+       char *pixeltypechar = NULL;
+       rt_pixtype pixtype = PT_END;
+       double pixsize = 0;
+
+       if (PG_ARGISNULL(0))
+               PG_RETURN_NULL();
+
+       pixeltypetext = PG_GETARG_TEXT_P(0);
+       pixeltypechar = text_to_cstring(pixeltypetext);
+
+       pixtype = rt_pixtype_index_from_name(pixeltypechar);
+       if (pixtype == PT_END) {
+               elog(ERROR, "RASTER_minPossibleValue: Invalid pixel type: %s", pixeltypechar);
+               PG_RETURN_NULL();
+       }
+
+       pixsize = rt_pixtype_get_min_value(pixtype);
+
+       /*
+               correct pixsize of unsigned pixel types
+               example: for PT_8BUI, the value is CHAR_MIN but if char is signed, 
+                       the value returned is -127 instead of 0.
+       */
+       switch (pixtype) {
+               case PT_1BB:
+               case PT_2BUI:
+               case PT_4BUI:
+               case PT_8BUI:
+               case PT_16BUI:
+               case PT_32BUI:
+                       pixsize = 0;
+                       break;
+               default:
+                       break;
+       }
+
+       PG_RETURN_FLOAT8(pixsize);
+}
+
 /**
  * Input is a string with hex chars in it.
  * Convert to binary and put in the result
index 21ffbfe6ba0229c5dd0b5f99e800f7adf27cf994..c1921cd20c223f6194fff1b4ec39d6b102795a7c 100644 (file)
@@ -2768,34 +2768,16 @@ CREATE OR REPLACE FUNCTION st_raster2worldcoordy(rast raster, yr int)
     LANGUAGE 'plpgsql' IMMUTABLE STRICT;
 
 -----------------------------------------------------------------------
--- ST_MinPossibleVal(pixeltype text)
+-- ST_MinPossibleValue(pixeltype text)
 -- Return the smallest value for a given pixeltyp.
 -- Should be called like this:
--- SELECT ST_MinPossibleVal(ST_BandPixelType(rast, band))
+-- SELECT ST_MinPossibleValue(ST_BandPixelType(rast, band))
 -----------------------------------------------------------------------
-CREATE OR REPLACE FUNCTION ST_MinPossibleVal(pixeltype text)
-    RETURNS float8 AS
-    $$
-    DECLARE
-        newval int := 0;
-    BEGIN
-        newval := CASE
-            WHEN pixeltype = '1BB' THEN 0
-            WHEN pixeltype = '2BUI' THEN 0
-            WHEN pixeltype = '4BUI' THEN 0
-            WHEN pixeltype = '8BUI' THEN 0
-            WHEN pixeltype = '8BSI' THEN -128
-            WHEN pixeltype = '16BUI' THEN 0
-            WHEN pixeltype = '16BSI' THEN -32768
-            WHEN pixeltype = '32BUI' THEN 0
-            WHEN pixeltype = '32BSI' THEN -2147483648
-            WHEN pixeltype = '32BF' THEN -2147483648 -- Could not find a function returning the smallest real yet
-            WHEN pixeltype = '64BF' THEN -2147483648 -- Could not find a function returning the smallest float8 yet
-        END;
-        RETURN newval;
-    END;
-    $$
-    LANGUAGE 'plpgsql';
+
+CREATE OR REPLACE FUNCTION st_minpossiblevalue(pixeltype text)
+       RETURNS double precision
+       AS 'MODULE_PATHNAME', 'RASTER_minPossibleValue'
+       LANGUAGE 'C' IMMUTABLE STRICT;
 
 -----------------------------------------------------------------------
 -- Raster Outputs
@@ -3526,7 +3508,7 @@ CREATE OR REPLACE FUNCTION ST_Clip(rast raster, band int, geom geometry, nodata
             bandend := band;
         END IF;
         newpixtype := ST_BandPixelType(rast, bandstart);
-        newnodata := coalesce(nodata, ST_BandNodataValue(rast, bandstart), ST_MinPossibleVal(newpixtype));
+        newnodata := coalesce(nodata, ST_BandNodataValue(rast, bandstart), ST_MinPossibleValue(newpixtype));
         newextent := CASE WHEN trimraster THEN 'INTERSECTION' ELSE 'FIRST' END;
 
 --RAISE NOTICE 'newextent=%', newextent;
@@ -3543,7 +3525,7 @@ CREATE OR REPLACE FUNCTION ST_Clip(rast raster, band int, geom geometry, nodata
 --RAISE NOTICE 'bandi=%', bandi;
             -- for each band we must determine the nodata value
             newpixtype := ST_BandPixelType(rast, bandi);
-            newnodata := coalesce(nodata, ST_BandNodataValue(sourceraster, bandi), ST_MinPossibleVal(newpixtype));
+            newnodata := coalesce(nodata, ST_BandNodataValue(sourceraster, bandi), ST_MinPossibleValue(newpixtype));
             sourceraster := ST_SetBandNodataValue(sourceraster, bandi, newnodata);
             newrast := ST_AddBand(newrast, ST_MapAlgebraExpr(sourceraster, bandi, geomrast, 1, 'rast1', newpixtype, newextent));
         END LOOP;
index aec8add3693da39eac155c56f247b59170760e74..6413854e5eebfd4f30ebd8404f4a61aff18fa3a1 100644 (file)
@@ -330,3 +330,6 @@ DROP FUNCTION IF EXISTS st_intersects(raster, raster);
 -- functions have changed dramatically
 DROP FUNCTION IF EXISTS st_intersection(rast raster, band integer, geom geometry);
 DROP FUNCTION IF EXISTS st_intersection(rast raster, geom geometry);
+
+-- function was renamed
+DROP FUNCTION IF EXISTS st_minpossibleval(text);
index 056ef56399ddf7e0da2c27acebf60d0f3cf3715c..1c68c810e7a42e5d015f62bd88a97d7877d342a2 100644 (file)
@@ -79,7 +79,7 @@ CREATE OR REPLACE FUNCTION ST_Clip(rast raster, band int, geom geometry, nodata
             bandend := band;
         END IF;
         newpixtype := ST_BandPixelType(rast, bandstart);
-        newnodata := coalesce(nodata, ST_BandNodataValue(rast, bandstart), ST_MinPossibleVal(newpixtype));
+        newnodata := coalesce(nodata, ST_BandNodataValue(rast, bandstart), ST_MinPossibleValue(newpixtype));
         newextent := CASE WHEN trimraster THEN 'INTERSECTION' ELSE 'FIRST' END;
         
 --RAISE NOTICE 'newextent=%', newextent;
@@ -96,7 +96,7 @@ CREATE OR REPLACE FUNCTION ST_Clip(rast raster, band int, geom geometry, nodata
 --RAISE NOTICE 'bandi=%', bandi;
             -- for each band we must determine the nodata value
             newpixtype := ST_BandPixelType(rast, bandi);
-            newnodata := coalesce(nodata, ST_BandNodataValue(sourceraster, bandi), ST_MinPossibleVal(newpixtype));
+            newnodata := coalesce(nodata, ST_BandNodataValue(sourceraster, bandi), ST_MinPossibleValue(newpixtype));
             sourceraster := ST_SetBandNodataValue(sourceraster, bandi, newnodata);
             newrast := ST_AddBand(newrast, ST_MapAlgebraExpr(sourceraster, bandi, geomrast, 1, 'rast1', newpixtype, newextent));
         END LOOP;
index 358ce4173a70700c05db913b8cc86c9cb260eee7..9369e2129adb49859b8055251acca6dfbca235fe 100644 (file)
@@ -82,12 +82,12 @@ CREATE OR REPLACE FUNCTION ST_MapAlgebra(rast raster, band integer, expression t
 
         -- Check for notada value
         newnodatavalue := ST_BandNodataValue(rast, band);
-        IF newnodatavalue IS NULL OR newnodatavalue < ST_MinPossibleVal(newpixeltype) OR newnodatavalue > (-ST_MinPossibleVal(newpixeltype) - 1) THEN
+        IF newnodatavalue IS NULL OR newnodatavalue < ST_MinPossibleValue(newpixeltype) OR newnodatavalue > (-ST_MinPossibleValue(newpixeltype) - 1) THEN
             RAISE NOTICE 'ST_MapAlgebra: Source raster do not have a nodata value or is out of range for the new raster pixeltype, nodata value for new raster set to the min value possible';
-            newnodatavalue := ST_MinPossibleVal(newpixeltype);
+            newnodatavalue := ST_MinPossibleValue(newpixeltype);
         END IF;
         -- We set the initial value of the future band to nodata value. 
-        -- If nodatavalue is null then the raster will be initialise to ST_MinPossibleVal 
+        -- If nodatavalue is null then the raster will be initialise to ST_MinPossibleValue 
         -- but all the values should be recomputed anyway.
         newinitialvalue := newnodatavalue;
 
@@ -758,7 +758,7 @@ CREATE OR REPLACE FUNCTION ST_MapAlgebra(rast1 raster,
             newnodatavalue := rast2nodataval;
         ELSE
             RAISE NOTICE 'ST_MapAlgebra: Both source rasters do not have a nodata value, nodata value for new raster set to the minimum value possible';
-            newnodatavalue := ST_MinPossibleVal(newrast);
+            newnodatavalue := ST_MinPossibleValue(newrast);
         END IF;
         
         -------------------------------------------------------------------
index 9b72a188a08b7e52fed30d2f9f51cdd24f5aa1b0..a1f4bef48e1603d5cfd686be201e958f97e6707f 100644 (file)
@@ -510,7 +510,7 @@ RAISE NOTICE 'ST_MapAlgebra2 000';
             newnodatavalue := rast1nodataval;\r
         ELSE\r
             RAISE NOTICE 'ST_MapAlgebra: Both source rasters do not have a nodata value, nodata value for new raster set to the minimum value possible';\r
-            newnodatavalue := ST_MinPossibleVal(newrast);\r
+            newnodatavalue := ST_MinPossibleValue(newrast);\r
         END IF;\r
          \r
         upnodatanodataexpr := upper(nodatanodataexpr);\r
index 8d053b186f18128cac0dd04dca0da82dd792196a..0e0599ee7d9c61a51f45c595df0abe190b1b128d 100644 (file)
@@ -8,7 +8,7 @@
 --
 -- Helper method to get the smallest value in a raster, based on the pixeltype.
 --
-CREATE OR REPLACE FUNCTION ST_MinPossibleVal(pixeltype text)
+CREATE OR REPLACE FUNCTION ST_MinPossibleValue(pixeltype text)
     RETURNS float8 AS
     $$
     DECLARE
@@ -114,13 +114,13 @@ CREATE OR REPLACE FUNCTION ST_MapAlgebraFctNgb(rast raster, band integer, pixelt
 
         -- Check for notada value
         newnodatavalue := ST_BandNodataValue(rast, band);
-        IF newnodatavalue IS NULL OR newnodatavalue < ST_MinPossibleVal(newpixeltype) OR newnodatavalue > (-ST_MinPossibleVal(newpixeltype) - 1) THEN
+        IF newnodatavalue IS NULL OR newnodatavalue < ST_MinPossibleValue(newpixeltype) OR newnodatavalue > (-ST_MinPossibleValue(newpixeltype) - 1) THEN
             RAISE NOTICE 'ST_MapAlgebraFctNgb: Source raster does not have a nodata value or is out of range for the new raster pixeltype, nodata value for new raster set to the min value possible';
-            newnodatavalue := ST_MinPossibleVal(newpixeltype);
+            newnodatavalue := ST_MinPossibleValue(newpixeltype);
         END IF;
 
         -- We set the initial value of the future band to nodata value. 
-        -- If nodatavalue is null then the raster will be initialise to ST_MinPossibleVal 
+        -- If nodatavalue is null then the raster will be initialise to ST_MinPossibleValue 
         -- but all the values should be recomputed anyway.
         newinitialvalue := newnodatavalue;
 
diff --git a/raster/scripts/plpgsql/st_minpossibleval.sql b/raster/scripts/plpgsql/st_minpossibleval.sql
deleted file mode 100644 (file)
index 5af03a5..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
------------------------------------------------------------------------\r
--- ST_MinPossibleVal\r
--- Return the smallest value for a given pixeltyp. \r
--- Should be called like this:\r
--- SELECT ST_MinPossibleVal(ST_BandPixelType(rast, band))\r
------------------------------------------------------------------------\r
-CREATE OR REPLACE FUNCTION ST_MinPossibleVal(pixeltype text)\r
-    RETURNS float8 AS\r
-    $$\r
-    DECLARE\r
-        newval int := 0;\r
-    BEGIN\r
-        newval := CASE \r
-            WHEN pixeltype = '1BB' THEN 0\r
-            WHEN pixeltype = '2BUI' THEN 0\r
-            WHEN pixeltype = '4BUI' THEN 0\r
-            WHEN pixeltype = '8BUI' THEN 0\r
-            WHEN pixeltype = '8BSI' THEN -128\r
-            WHEN pixeltype = '16BUI' THEN 0\r
-            WHEN pixeltype = '16BSI' THEN -32768\r
-            WHEN pixeltype = '32BUI' THEN 0\r
-            WHEN pixeltype = '32BSI' THEN -2147483648\r
-            WHEN pixeltype = '32BF' THEN -2147483648 -- Could not find a function returning the smallest real yet\r
-            WHEN pixeltype = '64BF' THEN -2147483648 -- Could not find a function returning the smallest float8 yet\r
-        END;\r
-        RETURN newval;\r
-    END;\r
-    $$\r
-    LANGUAGE 'plpgsql';\r
index 646f9fe9495cb6e792566fc2c4723b3f91e493b4..d8edb82839f3b34435ef51c22539931af272d07d 100644 (file)
@@ -238,3 +238,18 @@ SELECT 'test 10.3', id, name
     FROM rt_utility_test
     WHERE st_raster2worldcoordy(rast, 1)::numeric != ipy::numeric;
     
+-----------------------------------------------------------------------
+-- Test 11 - st_minpossiblevalue(pixtype text)
+-----------------------------------------------------------------------
+
+SELECT 'test 11.1', st_minpossiblevalue('1BB') = 0.;
+SELECT 'test 11.2', st_minpossiblevalue('2BUI') = 0.;
+SELECT 'test 11.3', st_minpossiblevalue('4BUI') = 0.;
+SELECT 'test 11.4', st_minpossiblevalue('8BUI') = 0.;
+SELECT 'test 11.5', st_minpossiblevalue('8BSI') < 0.;
+SELECT 'test 11.6', st_minpossiblevalue('16BUI') = 0.;
+SELECT 'test 11.7', st_minpossiblevalue('16BSI') < 0.;
+SELECT 'test 11.8', st_minpossiblevalue('32BUI') = 0.;
+SELECT 'test 11.9', st_minpossiblevalue('32BSI') < 0.;
+SELECT 'test 11.10', st_minpossiblevalue('32BF') < 0.;
+SELECT 'test 11.11', st_minpossiblevalue('64BF') < 0.;
index 7c9f61ff0b9c7cda058280e6dd6a1bc420272f53..b9d96bd4e35461a6b5555f7cede432d82b9726c2 100644 (file)
@@ -2,3 +2,14 @@ ERROR:  Attempting to compute raster coordinate on a raster with rotation provid
 ERROR:  Attempting to compute raster coordinate on a raster with rotation providing y only. A x must also be provided
 ERROR:  Attempting to compute raster coordinates on a raster with rotation providing X only. A Y coordinate must also be provided
 ERROR:  Attempting to compute raster coordinates on a raster with rotation providing Y only. An X coordinate must also be provided
+test 11.1|t
+test 11.2|t
+test 11.3|t
+test 11.4|t
+test 11.5|t
+test 11.6|t
+test 11.7|t
+test 11.8|t
+test 11.9|t
+test 11.10|t
+test 11.11|t