]> granicus.if.org Git - postgis/commitdiff
Modified ST_Neighborhood and underlying functions to return 2D double
authorBborie Park <bkpark at ucdavis.edu>
Tue, 22 May 2012 17:05:45 +0000 (17:05 +0000)
committerBborie Park <bkpark at ucdavis.edu>
Tue, 22 May 2012 17:05:45 +0000 (17:05 +0000)
precision array.  This allows the output to be readily passed onto the
ST_xxx4ma functions.

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

raster/rt_core/rt_api.c
raster/rt_core/rt_api.h
raster/rt_pg/rt_pg.c
raster/rt_pg/rtpostgis.sql.in.c
raster/test/core/testapi.c
raster/test/regress/rt_neighborhood_expected

index 0f9d3051ad83120497e4f62c4382a297e98d00c2..f0bc93dcafa55dfbb8a6362f15f7ad2cd2b5e34f 100644 (file)
@@ -1030,6 +1030,116 @@ rt_pixtype_get_min_value(rt_pixtype pixtype) {
        }
 }
 
+/*- rt_pixel ----------------------------------------------------------*/
+
+/*
+ * Convert an array of rt_pixel objects to two 2D arrays of value and NODATA
+ *
+ * @param npixel: array of rt_pixel objects
+ * @param count: number of elements in npixel
+ * @param x: the column of the center pixel (0-based)
+ * @param y: the line of the center pixel (0-based)
+ * @param distance: the number of pixels around the center pixel
+ * @param value: pointer to pointer for 2D value array
+ * @param nodata: pointer to pointer for 2D NODATA array
+ *
+ * @return 0 on error, otherwise the X/Y axis length of value and NODATA 
+ */
+int rt_pixel_set_to_array(
+       rt_pixel npixel, int count,
+       int x, int y,
+       uint16_t distance,
+       double ***value,
+       int ***nodata
+) {
+       uint32_t i;
+       uint32_t j;
+       uint32_t length = 0;
+       double **values = NULL;
+       int **nodatas = NULL;
+       int zero[2] = {0};
+       int _x;
+       int _y;
+
+       assert(npixel != NULL);
+       assert(count > 0);
+
+       /* length */
+       length = distance * 2 + 1;
+       RASTER_DEBUGF(4, "length = %d", length);
+
+       /* establish 2D arrays */
+       values = rtalloc(sizeof(double *) * length);
+       nodatas = rtalloc(sizeof(int *) * length);
+
+       if (values == NULL || nodatas == NULL) {
+               rterror("rt_pixel_set_to_array: Unable to allocate memory for 2D array");
+               return 0;
+       }
+
+       /* initialize */
+       for (i = 0; i < length; i++) {
+               values[i] = rtalloc(sizeof(double) * length);
+               nodatas[i] = rtalloc(sizeof(int) * length);
+
+               if (values[i] == NULL || nodatas[i] == NULL) {
+                       rterror("rt_pixel_set_to_array: Unable to allocate memory for dimension of 2D array");
+
+                       if (values[i] == NULL) {
+                               for (j = 0; j < i; j++) {
+                                       rtdealloc(values[j]);
+                                       rtdealloc(nodatas[j]);
+                               }
+                       }
+                       else {
+                               for (j = 0; j <= i; j++) {
+                                       rtdealloc(values[j]);
+                                       if (j < i)
+                                               rtdealloc(nodatas[j]);
+                               }
+                       }
+
+                       rtdealloc(values);
+                       rtdealloc(nodatas);
+                       
+                       return 0;
+               }
+
+               /* set values to 0 */
+               memset(values[i], 0, sizeof(double) * length);
+
+               /* set nodatas to 1 */
+               for (j = 0; j < length; j++)
+                       nodatas[i][j] = 1;
+       }
+
+       /* get zero, zero of grid */
+       zero[0] = x - distance;
+       zero[1] = y - distance;
+
+       /* populate 2D arrays */
+       for (i = 0; i < count; i++) {
+               if (npixel[i].nodata)
+                       continue;
+
+               _x = npixel[i].x - zero[0];
+               _y = npixel[i].y - zero[1];
+
+               RASTER_DEBUGF(4, "absolute x,y: %d x %d", npixel[i].x, npixel[i].y);
+               RASTER_DEBUGF(4, "relative x,y: %d x %d", _x, _y);
+
+               values[_x][_y] = npixel[i].value;
+               nodatas[_x][_y] = 0;
+
+               RASTER_DEBUGF(4, "(x, y, nodata, value) = (%d, %d, %d, %f)", _x, _y, nodatas[_x][_y], values[_x][_y]);
+       }
+
+       *value = &(*values);
+       *nodata = &(*nodatas);
+
+       return length;
+}
+
 /*- rt_band ----------------------------------------------------------*/
 
 /**
@@ -2269,17 +2379,17 @@ int rt_band_get_nearest_pixel(
                                                /* no NODATA, set to minimum possible value */
                                                if (!band->hasnodata)
                                                        pixval = minval;
+                                               /* has NODATA, use NODATA */
                                                else
                                                        pixval = band->nodataval;
                                                RASTER_DEBUGF(4, "NODATA pixel outside band extent: (x, y, val) = (%d, %d, %f)", _x, _y, pixval);
                                        }
                                        else {
-                                               err = rt_band_get_pixel(
+                                               if (rt_band_get_pixel(
                                                        band,
                                                        _x, _y,
                                                        &pixval
-                                               );
-                                               if (err < 0) {
+                                               ) < 0) {
                                                        rterror("rt_band_get_nearest_pixel: Unable to get pixel value");
                                                        if (count) rtdealloc(*npixels);
                                                        return -1;
@@ -2313,6 +2423,7 @@ int rt_band_get_nearest_pixel(
                                                npixel = &((*npixels)[count - 1]);
                                                npixel->x = _x;
                                                npixel->y = _y;
+                                               npixel->nodata = 0;
                                                npixel->value = pixval;
                                        }
 
index 9e2182c3932ae2552319c13cea2cb8566b97fc4e..9fcba016a0e8222baa7d851ce4f2f3d1fad5e449 100644 (file)
@@ -308,6 +308,29 @@ rt_pixtype rt_pixtype_index_from_name(const char* pixname);
  */
 double rt_pixtype_get_min_value(rt_pixtype pixtype);
 
+/*- rt_pixel ----------------------------------------------------------*/
+
+/*
+ * Convert an array of rt_pixel objects to two 2D arrays of value and NODATA
+ *
+ * @param npixel: array of rt_pixel objects
+ * @param count: number of elements in npixel
+ * @param x: the column of the center pixel (0-based)
+ * @param y: the line of the center pixel (0-based)
+ * @param distance: the number of pixels around the center pixel
+ * @param value: pointer to pointer for 2D value array
+ * @param nodata: pointer to pointer for 2D NODATA array
+ *
+ * @return 0 on error, otherwise the X/Y axis length of value and NODATA 
+ */
+int rt_pixel_set_to_array(
+       rt_pixel npixel, int count,
+       int x, int y,
+       uint16_t distance,
+       double ***value,
+       int ***nodata
+);
+
 /*- rt_band ----------------------------------------------------------*/
 
 /**
@@ -1663,6 +1686,8 @@ struct rt_band_t {
 struct rt_pixel_t {
        int x; /* column */
        int y; /* line */
+
+       uint8_t nodata;
        double value;
 };
 
index 52480a0fa0cf201f55bf01b1d4d7799e9a80ebdf..390a335f14cfdbbfc8d102a619a9a99a6b162414 100644 (file)
@@ -2560,178 +2560,240 @@ Datum RASTER_nearestValue(PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1(RASTER_neighborhood);
 Datum RASTER_neighborhood(PG_FUNCTION_ARGS)
 {
-       FuncCallContext *funcctx;
-       TupleDesc tupdesc;
+       rt_pgraster *pgraster = NULL;
+       rt_raster raster = NULL;
+       rt_band band = NULL;
+       int bandindex = 1;
+       int num_bands = 0;
+       int x = 0;
+       int y = 0;
+       int _x = 0;
+       int _y = 0;
+       int distance = 0;
+       bool exclude_nodata_value = TRUE;
+       double pixval;
 
-       int call_cntr;
-       int max_calls;
+       rt_pixel npixels = NULL;
+       int count;
+       int length;
+       double **value2D = NULL;
+       int **nodata2D = NULL;
 
-       rt_pixel npixel1 = NULL;
-       rt_pixel npixel2 = NULL;
+       int i = 0;
+       int j = 0;
+       int k = 0;
+       Datum *value1D = NULL;
+       bool *nodata1D = NULL;
+       int dim[2] = {0};
+       int lbound[2] = {1, 1};
+       ArrayType *mdArray = NULL;
 
-       if (SRF_IS_FIRSTCALL()) {
-               MemoryContext oldcontext;
+       int16 typlen;
+       bool typbyval;
+       char typalign;
 
-               rt_pgraster *pgraster = NULL;
-               rt_raster raster = NULL;
-               rt_band band = NULL;
-               int bandindex = 1;
-               int num_bands = 0;
-               int x = 0;
-               int y = 0;
-               int distance = 0;
-               bool exclude_nodata_value = TRUE;
+       /* pgraster is null, return nothing */
+       if (PG_ARGISNULL(0))
+               PG_RETURN_NULL();
+       pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
 
-               int count;
+       raster = rt_raster_deserialize(pgraster, FALSE);
+       if (!raster) {
+               elog(ERROR, "RASTER_neighborhood: Could not deserialize raster");
+               PG_RETURN_NULL();
+       }
 
-               /* create a function context for cross-call persistence */
-               funcctx = SRF_FIRSTCALL_INIT();
+       /* band index is 1-based */
+       if (!PG_ARGISNULL(1))
+               bandindex = PG_GETARG_INT32(1);
+       num_bands = rt_raster_get_num_bands(raster);
+       if (bandindex < 1 || bandindex > num_bands) {
+               elog(NOTICE, "Invalid band index (must use 1-based). Returning NULL");
+               rt_raster_destroy(raster);
+               PG_RETURN_NULL();
+       }
 
-               /* switch to memory context appropriate for multiple function calls */
-               oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
+       /* pixel column, 1-based */
+       x = PG_GETARG_INT32(2);
+       _x = x - 1;
 
-               /* pgraster is null, return nothing */
-               if (PG_ARGISNULL(0)) {
-                       MemoryContextSwitchTo(oldcontext);
-                       SRF_RETURN_DONE(funcctx);
-               }
-               pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       /* pixel row, 1-based */
+       y = PG_GETARG_INT32(3);
+       _y = y - 1;
 
-               raster = rt_raster_deserialize(pgraster, FALSE);
-               if (!raster) {
-                       elog(ERROR, "RASTER_neighborhood: Could not deserialize raster");
-                       MemoryContextSwitchTo(oldcontext);
-                       SRF_RETURN_DONE(funcctx);
-               }
+       /* distance */
+       distance = PG_GETARG_INT32(4);
+       if (distance < 1) {
+               elog(NOTICE, "Invalid value for distance (must be greater than zero). Returning NULL");
+               rt_raster_destroy(raster);
+               PG_RETURN_NULL();
+       }
+       distance = (uint16_t) distance;
 
-               /* band index is 1-based */
-               if (!PG_ARGISNULL(1))
-                       bandindex = PG_GETARG_INT32(1);
-               num_bands = rt_raster_get_num_bands(raster);
-               if (bandindex < 1 || bandindex > num_bands) {
-                       elog(NOTICE, "Invalid band index (must use 1-based). Returning NULL");
-                       rt_raster_destroy(raster);
-                       MemoryContextSwitchTo(oldcontext);
-                       SRF_RETURN_DONE(funcctx);
-               }
+       /* exclude_nodata_value flag */
+       if (!PG_ARGISNULL(5))
+               exclude_nodata_value = PG_GETARG_BOOL(5);
+
+       /* get band */
+       band = rt_raster_get_band(raster, bandindex - 1);
+       if (!band) {
+               elog(NOTICE, "Could not find band at index %d. Returning NULL", bandindex);
+               rt_raster_destroy(raster);
+               PG_RETURN_NULL();
+       }
 
-               /* pixel column, 1-based */
-               x = PG_GETARG_INT32(2);
+       /* get neighborhood */
+       count = rt_band_get_nearest_pixel(
+               band,
+               _x, _y,
+               distance,
+               exclude_nodata_value,
+               &npixels
+       );
+       /* error or no neighbors */
+       if (count < 1) {
+               /* error */
+               if (count < 0)
+                       elog(NOTICE, "Unable to get the pixel's neighborhood for band at index %d", bandindex);
+               /* no neighbors */
+               else
+                       elog(NOTICE, "Pixel has no neighbors for band at distance %d", distance);
+                       
+               rt_band_destroy(band);
+               rt_raster_destroy(raster);
 
-               /* pixel row, 1-based */
-               y = PG_GETARG_INT32(3);
+               PG_RETURN_NULL();
+       }
 
-               /* distance */
-               distance = PG_GETARG_INT32(4);
-               if (distance < 1) {
-                       elog(NOTICE, "Invalid value for distance (must be greater than zero). Returning NULL");
+       /* get pixel's value */
+       if (
+               (_x >= 0 && _x < rt_band_get_width(band)) &&
+               (_y >= 0 && _y < rt_band_get_height(band))
+       ) {
+               if (rt_band_get_pixel(
+                       band,
+                       _x, _y,
+                       &pixval
+               ) < 0) {
+                       elog(NOTICE, "Unable to get the pixel of band at index %d. Returning NULL", bandindex);
+                       rt_band_destroy(band);
                        rt_raster_destroy(raster);
-                       MemoryContextSwitchTo(oldcontext);
-                       SRF_RETURN_DONE(funcctx);
+                       PG_RETURN_NULL();
                }
+       }
+       /* outside band extent, set to NODATA */
+       else {
+               /* has NODATA, use NODATA */
+               if (rt_band_get_hasnodata_flag(band))
+                       pixval = rt_band_get_nodata(band);
+               /* no NODATA, use min possible value */
+               else
+                       pixval = rt_band_get_min_value(band);
+       }
+       POSTGIS_RT_DEBUGF(4, "pixval: %f", pixval);
 
-               /* exclude_nodata_value flag */
-               if (!PG_ARGISNULL(5))
-                       exclude_nodata_value = PG_GETARG_BOOL(5);
+       /* add pixel to neighborhood */
+       if (
+               !exclude_nodata_value || (
+                       exclude_nodata_value &&
+                       (rt_band_get_hasnodata_flag(band) != FALSE) && (
+                               FLT_NEQ(pixval, rt_band_get_nodata(band)) &&
+                               (rt_band_clamped_value_is_nodata(band, pixval) != 1)
+                       )
+               )
+       ) {
+               count++;
+               npixels = (rt_pixel) repalloc(npixels, sizeof(struct rt_pixel_t) * count);
+               if (npixels == NULL) {
+                       elog(ERROR, "RASTER_neighborhood: Unable to reallocate memory for neighborhood");
 
-               /* get band */
-               band = rt_raster_get_band(raster, bandindex - 1);
-               if (!band) {
-                       elog(NOTICE, "Could not find band at index %d. Returning NULL", bandindex);
+                       rt_band_destroy(band);
                        rt_raster_destroy(raster);
-                       MemoryContextSwitchTo(oldcontext);
-                       SRF_RETURN_DONE(funcctx);
-               }
 
-               /* get neighborhood */
-               count = rt_band_get_nearest_pixel(
-                       band,
-                       x - 1, y - 1,
-                       (uint16_t) distance,
-                       exclude_nodata_value,
-                       &npixel1
-               );
-               rt_band_destroy(band);
-               rt_raster_destroy(raster);
-               /* error or no neighbors */
-               if (count < 1) {
-                       /* error */
-                       if (count < 0)
-                               elog(NOTICE, "Unable to get the pixel's neighborhood for band at index %d", bandindex);
-                       /* no neighbors */
-                       else
-                               elog(NOTICE, "Pixel has no neighbors for band at distance %d", distance);
-                               
-                       MemoryContextSwitchTo(oldcontext);
-                       SRF_RETURN_DONE(funcctx);
+                       PG_RETURN_NULL();
                }
 
-               /* Store needed information */
-               funcctx->user_fctx = npixel1;
-
-               /* total number of tuples to be returned */
-               funcctx->max_calls = count;
-
-               /* Build a tuple descriptor for our result type */
-               if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) {
-                       ereport(ERROR, (
-                               errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                               errmsg(
-                                       "function returning record called in context "
-                                       "that cannot accept type record"
-                               )
-                       ));
-               }
+               npixels[count - 1].x = _x;
+               npixels[count - 1].y = _y;
+               npixels[count - 1].nodata = 0;
+               npixels[count - 1].value = pixval;
+       }
 
-               BlessTupleDesc(tupdesc);
-               funcctx->tuple_desc = tupdesc;
+       /* free unnecessary stuff */
+       rt_band_destroy(band);
+       rt_raster_destroy(raster);
 
-               MemoryContextSwitchTo(oldcontext);
+       /* convert set of rt_pixel to 2D array */
+       length = rt_pixel_set_to_array(
+               npixels, count,
+               _x, _y,
+               distance,
+               &value2D,
+               &nodata2D
+       );
+       pfree(npixels);
+       if (!length) {
+               elog(NOTICE, "Unable to create 2D array of neighborhood");
+               PG_RETURN_NULL();
        }
 
-       /* stuff done on every call of the function */
-       funcctx = SRF_PERCALL_SETUP();
+       /* dimensions of the PG array */
+       dim[0] = length;
+       dim[1] = length;
 
-       call_cntr = funcctx->call_cntr;
-       max_calls = funcctx->max_calls;
-       tupdesc = funcctx->tuple_desc;
-       npixel2 = funcctx->user_fctx;
+       /* 1D arrays for values and nodata from 2D arrays */
+       value1D = palloc(sizeof(Datum) * length * length);
+       nodata1D = palloc(sizeof(bool) * length * length);
 
-       /* do when there is more left to send */
-       if (call_cntr < max_calls) {
-               int values_length = 3;
-               Datum values[values_length];
-               bool *nulls = NULL;
-               HeapTuple tuple;
-               Datum result;
+       if (value1D == NULL || nodata1D == NULL) {
+               elog(ERROR, "RASTER_neighborhood: Unable to allocate memory for return 2D array");
 
-               POSTGIS_RT_DEBUGF(3, "Result %d", call_cntr);
+               for (i = 0; i < length; i++) {
+                       pfree(value2D[i]);
+                       pfree(nodata2D[i]);
+               }
+               pfree(value2D);
+               pfree(nodata2D);
 
-               nulls = palloc(sizeof(bool) * values_length);
-               memset(nulls, FALSE, values_length);
+               PG_RETURN_NULL();
+       }
 
-               /* x,y are 0-based, make 1-based for end users */
-               values[0] = Int64GetDatum(npixel2[call_cntr].x + 1);
-               values[1] = Int64GetDatum(npixel2[call_cntr].y + 1);
-               values[2] = Float8GetDatum(npixel2[call_cntr].value);
+       /* copy values from 2D arrays to 1D arrays */
+       k = 0;
+       for (i = 0; i < length; i++) {
+               for (j = 0; j < length; j++) {
+                       nodata1D[k] = (bool) nodata2D[i][j];
+                       if (!nodata1D[k])
+                               value1D[k] = Float8GetDatum(value2D[i][j]);
+                       else
+                               value1D[k] = PointerGetDatum(NULL);
 
-               /* build a tuple */
-               tuple = heap_form_tuple(tupdesc, values, nulls);
+                       k++;
+               }
+       }
 
-               /* make the tuple into a datum */
-               result = HeapTupleGetDatum(tuple);
+       /* no more need for 2D arrays */
+       for (i = 0; i < length; i++) {
+               pfree(value2D[i]);
+               pfree(nodata2D[i]);
+       }
+       pfree(value2D);
+       pfree(nodata2D);
 
-               /* clean up */
-               pfree(nulls);
+       /* info about the type of item in the multi-dimensional array (float8). */
+       get_typlenbyvalalign(FLOAT8OID, &typlen, &typbyval, &typalign);
 
-               SRF_RETURN_NEXT(funcctx, result);
-       }
-       /* do when there is no more left */
-       else {
-               pfree(npixel2);
-               SRF_RETURN_DONE(funcctx);
-       }
+       mdArray = construct_md_array(
+               value1D, nodata1D,
+               2, dim, lbound,
+               FLOAT8OID,
+               typlen, typbyval, typalign
+       );
+
+       pfree(value1D);
+       pfree(nodata1D);
 
+       PG_RETURN_ARRAYTYPE_P(mdArray);
 }
 
 /**
index 7e8fcc59998229e14555d0957084d654df098070..d2033660962f4a940e699a25a2f71aa3e4469a30 100644 (file)
@@ -3540,11 +3540,9 @@ CREATE OR REPLACE FUNCTION st_neighborhood(
        rast raster, band integer,
        ix integer, iy integer,
        distance integer,
-       exclude_nodata_value boolean DEFAULT TRUE,
-       OUT x integer, OUT y integer,
-       OUT val double precision
+       exclude_nodata_value boolean DEFAULT TRUE
 )
-       RETURNS SETOF record
+       RETURNS double precision[][]
        AS 'MODULE_PATHNAME', 'RASTER_neighborhood'
        LANGUAGE 'C' IMMUTABLE STRICT;
 
@@ -3552,27 +3550,24 @@ CREATE OR REPLACE FUNCTION st_neighborhood(
        rast raster,
        ix integer, iy integer,
        distance integer,
-       exclude_nodata_value boolean DEFAULT TRUE,
-       OUT x integer, OUT y integer,
-       OUT val double precision
+       exclude_nodata_value boolean DEFAULT TRUE
 )
-       RETURNS SETOF record
-       AS $$ SELECT x, y, val FROM st_neighborhood($1, 1, $2, $3, $4, $5) $$
+       RETURNS double precision[][]
+       AS $$ SELECT st_neighborhood($1, 1, $2, $3, $4, $5) $$
        LANGUAGE 'SQL' IMMUTABLE STRICT;
 
 CREATE OR REPLACE FUNCTION st_neighborhood(
        rast raster, band integer,
        pt geometry,
        distance integer,
-       exclude_nodata_value boolean DEFAULT TRUE,
-       OUT x integer, OUT y integer,
-       OUT val double precision
+       exclude_nodata_value boolean DEFAULT TRUE
 )
-       RETURNS SETOF record
+       RETURNS double precision[][]
        AS $$
        DECLARE
                wx int;
                wy int;
+               rtn double precision[][];
        BEGIN
                IF (st_geometrytype($3) != 'ST_Point') THEN
                        RAISE EXCEPTION 'Attempting to get the neighbor of a pixel with a non-point geometry';
@@ -3580,15 +3575,14 @@ CREATE OR REPLACE FUNCTION st_neighborhood(
                wx := st_x($3);
                wy := st_y($3);
 
-               RETURN QUERY
-                       SELECT x, y, val
-                       FROM st_neighborhood(
-                               $1, $2,
-                               st_world2rastercoordx(rast, wx, wy),
-                               st_world2rastercoordy(rast, wx, wy),
-                               $4,
-                               $5
-                       );
+               SELECT st_neighborhood(
+                       $1, $2,
+                       st_world2rastercoordx(rast, wx, wy),
+                       st_world2rastercoordy(rast, wx, wy),
+                       $4,
+                       $5
+               ) INTO rtn;
+               RETURN rtn;
        END;
        $$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
 
@@ -3596,12 +3590,10 @@ CREATE OR REPLACE FUNCTION st_neighborhood(
        rast raster,
        pt geometry,
        distance integer,
-       exclude_nodata_value boolean DEFAULT TRUE,
-       OUT x integer, OUT y integer,
-       OUT val double precision
+       exclude_nodata_value boolean DEFAULT TRUE
 )
-       RETURNS SETOF record
-       AS $$ SELECT x, y, val FROM st_neighborhood($1, 1, $2, $3, $4) $$
+       RETURNS double precision[][]
+       AS $$ SELECT st_neighborhood($1, 1, $2, $3, $4) $$
        LANGUAGE 'SQL' IMMUTABLE STRICT;
 
 ------------------------------------------------------------------------------
index 1baebb1773e14411b5884335b37062ec40ae320a..492e085de55ddf49a077fd8a615f631ce4477870 100644 (file)
@@ -2598,6 +2598,10 @@ static void testNearestPixel() {
        const int maxY = 10;
        rt_pixel npixels = NULL;
 
+       int length;
+       double **value;
+       int **nodata;
+
        rast = rt_raster_new(maxX, maxY);
        assert(rast);
 
@@ -2734,6 +2738,24 @@ static void testNearestPixel() {
                &npixels
        );
        CHECK((rtn == 2));
+
+       length = rt_pixel_set_to_array(
+               npixels, rtn,
+               -1, 1, 
+               1,
+               &value,
+               &nodata
+       );
+       CHECK((length == 3));
+
+       for (x = 0; x < length; x++) {
+               rtdealloc(nodata[x]);
+               rtdealloc(value[x]);
+       }
+
+       rtdealloc(nodata);
+       rtdealloc(value);
+
        if (rtn)
                rtdealloc(npixels);
 
index 0f0011d614776abfae11f3e18ceacaeaf436458a..36b8ca1e2c719d9ea9be5520a79a1c3d86d9506e 100644 (file)
@@ -1,91 +1,12 @@
 NOTICE:  table "raster_neighborhood" does not exist, skipping
-(1,2,1)
-(2,2,1)
-(2,1,1)
-(2,1,1)
-(3,1,1)
-(1,3,1)
-(3,3,1)
-(1,2,1)
-(3,2,1)
-(4,4,1)
-(5,4,1)
-(6,4,1)
-(4,6,1)
-(5,6,1)
-(6,6,1)
-(4,5,1)
-(4,4,1)
-(5,4,1)
-(6,4,1)
-(4,6,1)
-(5,6,1)
-(6,6,1)
-(4,5,1)
-(3,3,1)
-(4,3,1)
-(6,3,1)
-(7,3,1)
-(3,7,1)
-(5,7,1)
-(6,7,1)
-(3,4,1)
-(3,6,1)
-(7,4,1)
-(7,5,1)
-(7,6,1)
-(10,10,1)
+{{NULL,NULL,NULL},{NULL,NULL,1},{NULL,1,1}}
+{{NULL,1,1},{1,1,NULL},{1,1,1}}
+{{1,1,1},{1,1,1},{1,NULL,1}}
+{{1,1,NULL,1,1},{1,1,1,1,NULL},{NULL,1,1,1,1},{1,1,NULL,1,1},{1,1,1,1,NULL}}
+{{1,NULL,NULL},{NULL,NULL,NULL},{NULL,NULL,NULL}}
 NOTICE:  Pixel has no neighbors for band at distance 1
 NOTICE:  Pixel has no neighbors for band at distance 1
-(1,3,1)
-(1,2,1)
+{{NULL,NULL,NULL},{NULL,NULL,NULL},{NULL,1,1}}
 NOTICE:  Pixel has no neighbors for band at distance 1
 NOTICE:  Pixel has no neighbors for band at distance 3
-(-10,2,0)
-(-9,2,0)
-(-8,2,0)
-(-10,4,0)
-(-9,4,0)
-(-8,4,0)
-(-10,3,0)
-(-8,3,0)
-(-11,1,0)
-(-10,1,0)
-(-9,1,0)
-(-8,1,0)
-(-7,1,0)
-(-11,5,0)
-(-10,5,0)
-(-9,5,0)
-(-8,5,0)
-(-7,5,0)
-(-11,2,0)
-(-11,3,0)
-(-11,4,0)
-(-7,2,0)
-(-7,3,0)
-(-7,4,0)
-(-12,0,0)
-(-11,0,0)
-(-10,0,0)
-(-9,0,0)
-(-8,0,0)
-(-7,0,0)
-(-6,0,0)
-(-12,6,0)
-(-11,6,0)
-(-10,6,0)
-(-9,6,0)
-(-8,6,0)
-(-7,6,0)
-(-6,6,0)
-(-12,1,0)
-(-12,2,0)
-(-12,3,0)
-(-12,4,0)
-(-12,5,0)
-(-6,1,0)
-(-6,2,0)
-(-6,3,0)
-(-6,4,0)
-(-6,5,0)
+{{0,0,0,0,0,0,0},{0,0,0,0,0,0,0},{0,0,0,0,0,0,0},{0,0,0,0,0,0,0},{0,0,0,0,0,0,0},{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}}