fix parse cleanup of reclassarg and add unit tests
authorBborie Park <bkpark at ucdavis.edu>
Sat, 7 Dec 2013 14:18:20 +0000 (14:18 +0000)
committerBborie Park <bkpark at ucdavis.edu>
Sat, 7 Dec 2013 14:18:20 +0000 (14:18 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@12152 b70326c6-7e19-0410-871a-916f4a2858ee

NEWS
raster/rt_core/rt_geometry.c
raster/rt_core/rt_mapalgebra.c
raster/rt_pg/rtpg_internal.c
raster/rt_pg/rtpg_internal.h
raster/rt_pg/rtpg_mapalgebra.c
raster/test/regress/rt_reclass.sql
raster/test/regress/rt_reclass_expected

diff --git a/NEWS b/NEWS
index 5fc780261ec6323dfd41d1e0f79dba3ff3743d2a..ea4f67af2bfb4e8d99c327fbba466d431f08e0bc 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -34,6 +34,7 @@ PostGIS 2.2.0
   - #2540, Change GUC name for GDAL_DATA to postgis.gdal_datapath
   - #2552, Fix handling of NULL raster in ST_AsTIFF, ST_AsPNG
            and ST_AsJPEG
+  - #2555, Fix parsing issue of range arguments of ST_Reclass
 
  * Code refactoring *
 
index 42cc5c0bdb20ff3385adeae2d65ce6644e795510..6f571b1071fa20d437f3e3f1f106b3b7125c2580 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "librtcore.h"
 #include "librtcore_internal.h"
+#include "rt_serialize.h"
 
 /******************************************************************************
 * rt_raster_perimeter()
index 91e3c6315185cc220da919bd43d2c036a1826f33..e2ab63e9d3ed2894dd1be17db33f09eca98324f4 100644 (file)
@@ -241,6 +241,7 @@ rt_band_reclass(
                                RASTER_DEBUGF(3, "Cannot get value at %d, %d", x, y);
                                continue;
                        }
+                       RASTER_DEBUGF(4, "(x, y, ov, isnodata) = (%d, %d, %f, %d)", x, y, ov, isnodata);
 
                        do {
                                do_nv = 0;
index 17d89e4c851bdc546ff775e91584b15167b69d72..297399350dd261329f666a18cd2af3353b9f2945 100644 (file)
@@ -258,6 +258,27 @@ rtpg_trim(const char *input) {
        return rtn;
 }
 
+/*
+ * reverse string search function from
+ * http://stackoverflow.com/a/1634398
+ */
+char *
+rtpg_strrstr(const char *s1, const char *s2) {
+       int s1len = strlen(s1);
+       int s2len = strlen(s2);
+       char *s;
+
+       if (s2len > s1len)
+               return NULL;
+
+       s = (char *) (s1 + s1len - s2len);
+       for (; s >= s1; --s)
+               if (strncmp(s, s2, s2len) == 0)
+                       return s;
+
+       return NULL;
+}
+
 char*
 rtpg_getSR(int srid) {
        int i = 0;
index 58773f90c7c25985058b7d179108b123f11fcc16..d344a18b93e515876d211d7b9bb1db60359cc777 100644 (file)
@@ -61,6 +61,9 @@ rtpg_removespaces(char *str);
 char *
 rtpg_trim(const char* input);
 
+char *
+rtpg_strrstr(const char *s1, const char *s2);
+
 char *
 rtpg_getSR(int srid);
 
index fe71eb20bd7465209574d91665b9c2331d84fe4d..8b126d744384e999c5caa36bc03e4366edb71bf8 100644 (file)
@@ -3316,7 +3316,7 @@ Datum RASTER_reclass(PG_FUNCTION_ARGS) {
                PG_RETURN_NULL();
        }
        numBands = rt_raster_get_num_bands(raster);
-       POSTGIS_RT_DEBUGF(3, "RASTER_reclass: %d possible bands to be reclassified", n);
+       POSTGIS_RT_DEBUGF(3, "RASTER_reclass: %d possible bands to be reclassified", numBands);
 
        /* process set of reclassarg */
        POSTGIS_RT_DEBUG(3, "RASTER_reclass: Processing Arg 1 (reclassargset)");
@@ -3422,9 +3422,9 @@ Datum RASTER_reclass(PG_FUNCTION_ARGS) {
                        PG_RETURN_POINTER(pgrtn);
                }
                expr = text_to_cstring(exprtext);
-               POSTGIS_RT_DEBUGF(5, "RASTER_reclass: expr (raw) %s", expr);
+               POSTGIS_RT_DEBUGF(4, "RASTER_reclass: expr (raw) %s", expr);
                expr = rtpg_removespaces(expr);
-               POSTGIS_RT_DEBUGF(5, "RASTER_reclass: expr (clean) %s", expr);
+               POSTGIS_RT_DEBUGF(4, "RASTER_reclass: expr (clean) %s", expr);
 
                /* split string to its components */
                /* comma (,) separating rangesets */
@@ -3443,11 +3443,11 @@ Datum RASTER_reclass(PG_FUNCTION_ARGS) {
                }
 
                /* set of reclass expressions */
-               POSTGIS_RT_DEBUGF(5, "RASTER_reclass: %d possible expressions", comma_n);
+               POSTGIS_RT_DEBUGF(4, "RASTER_reclass: %d possible expressions", comma_n);
                exprset = palloc(comma_n * sizeof(rt_reclassexpr));
 
                for (a = 0, j = 0; a < comma_n; a++) {
-                       POSTGIS_RT_DEBUGF(5, "RASTER_reclass: map %s", comma_set[a]);
+                       POSTGIS_RT_DEBUGF(4, "RASTER_reclass: map %s", comma_set[a]);
 
                        /* colon (:) separating range "src" and "dst" */
                        colon_set = rtpg_strsplit(comma_set[a], ":", &colon_n);
@@ -3470,7 +3470,7 @@ Datum RASTER_reclass(PG_FUNCTION_ARGS) {
                        exprset[j] = palloc(sizeof(struct rt_reclassexpr_t));
 
                        for (b = 0; b < colon_n; b++) {
-                               POSTGIS_RT_DEBUGF(5, "RASTER_reclass: range %s", colon_set[b]);
+                               POSTGIS_RT_DEBUGF(4, "RASTER_reclass: range %s", colon_set[b]);
 
                                /* dash (-) separating "min" and "max" */
                                dash_set = rtpg_strsplit(colon_set[b], "-", &dash_n);
@@ -3582,11 +3582,11 @@ Datum RASTER_reclass(PG_FUNCTION_ARGS) {
                                                        }
                                                }
                                        }
-                                       POSTGIS_RT_DEBUGF(5, "RASTER_reclass: exc_val %d inc_val %d", exc_val, inc_val);
+                                       POSTGIS_RT_DEBUGF(4, "RASTER_reclass: exc_val %d inc_val %d", exc_val, inc_val);
 
                                        /* remove interval flags */
                                        dash_set[c] = rtpg_chartrim(dash_set[c], "()[]");
-                                       POSTGIS_RT_DEBUGF(5, "RASTER_reclass: min/max (char) %s", dash_set[c]);
+                                       POSTGIS_RT_DEBUGF(4, "RASTER_reclass: min/max (char) %s", dash_set[c]);
 
                                        /* value from string to double */
                                        errno = 0;
@@ -3605,10 +3605,18 @@ Datum RASTER_reclass(PG_FUNCTION_ARGS) {
                                                SET_VARSIZE(pgrtn, pgrtn->size);
                                                PG_RETURN_POINTER(pgrtn);
                                        }
-                                       POSTGIS_RT_DEBUGF(5, "RASTER_reclass: min/max (double) %f", val);
+                                       POSTGIS_RT_DEBUGF(4, "RASTER_reclass: min/max (double) %f", val);
 
                                        /* strsplit removes dash (a.k.a. negative sign), compare now to restore */
-                                       junk = strstr(colon_set[b], dash_set[c]);
+                                       if (c < 1)
+                                               junk = strstr(colon_set[b], dash_set[c]);
+                                       else
+                                               junk = rtpg_strrstr(colon_set[b], dash_set[c]);
+                                       POSTGIS_RT_DEBUGF(
+                                               4,
+                                               "(colon_set[%d], dash_set[%d], junk) = (%s, %s, %s)",
+                                               b, c, colon_set[b], dash_set[c], junk
+                                       );
                                        /* not beginning of string */
                                        if (junk != colon_set[b]) {
                                                /* prior is a dash */
@@ -3624,7 +3632,7 @@ Datum RASTER_reclass(PG_FUNCTION_ARGS) {
                                                        }
                                                }
                                        }
-                                       POSTGIS_RT_DEBUGF(5, "RASTER_reclass: min/max (double) %f", val);
+                                       POSTGIS_RT_DEBUGF(4, "RASTER_reclass: min/max (double) %f", val);
 
                                        /* src */
                                        if (b < 1) {
index f4753b1294e94a020d9c552b4b7b7ace958863f7..e5a3cb8cc3fd81a518343c2b97ebbeca123ff7b8 100644 (file)
@@ -168,3 +168,29 @@ FROM (
                ROW(2, '-10000--100]:50-1,(-100-1000]:150-50,(1000-10000]:254-150', '8BUI', 0)
        ) AS rast
 ) AS t;
+
+-- ticket #2555
+SELECT
+       ST_Value(rast, 1, 2, 2),
+       ST_Value(rast, 1, 3, 3),
+       ST_Value(rast, 1, 4, 4)
+FROM (
+       SELECT ST_Reclass(
+               ST_SetValues(
+                       ST_AddBand(
+                               ST_MakeEmptyRaster(5, 5, 10, 10, 2, 2, 0, 0, 0),
+                               1, '32BF', 1, -9999
+                       ),
+                       1, 1, 1,
+                       ARRAY[
+                               [1, 1, 1, 1, 1],
+                               [1, 9000, 1, 1, 1],
+                               [1, 1, -9000, 1, 1],
+                               [1, 1, 1, 9000, 1],
+                               [1, 1, 1, 1, 1]
+                       ]::double precision[]
+               ),
+
+               1, '[-9000-9000]:[-900-900]', '32BF'
+       ) AS rast
+) AS t;
index f7e608070f0f407a99be98e2fb4251c1e569b177..a41735d17cd9288b1bd6ffbe130f6990dbb40f1b 100644 (file)
@@ -8,3 +8,4 @@ NOTICE:  Invalid argument for reclassargset. Invalid expression of reclassexpr f
 3.1415901184082|2.71828007698059|0
 NOTICE:  Invalid argument for reclassargset. Invalid band index (must use 1-based) for reclassarg of index 0 . Returning original raster
 3.1415901184082|2.71828007698059|0
+900|-900|900