]> granicus.if.org Git - postgis/commitdiff
Added rt_raster_within_distance() and regression tests
authorBborie Park <bkpark at ucdavis.edu>
Wed, 25 Jul 2012 03:35:36 +0000 (03:35 +0000)
committerBborie Park <bkpark at ucdavis.edu>
Wed, 25 Jul 2012 03:35:36 +0000 (03:35 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@10111 b70326c6-7e19-0410-871a-916f4a2858ee

raster/rt_core/rt_api.c
raster/rt_core/rt_api.h
raster/test/core/testapi.c

index ce5b22cc26a42d6b99fd22bffdae3fcd5e4a3779..c0d3def85134637d2746bba942e98628f2f11c07 100644 (file)
@@ -11780,6 +11780,95 @@ int rt_raster_coveredby(
        );
 }
 
+/**
+ * Return zero if error occurred in function.
+ * Parameter contains returns non-zero if rast1 is within a distance of rast2
+ *
+ * @param rast1 : the first raster whose band will be tested
+ * @param nband1 : the 0-based band of raster rast1 to use
+ *   if value is less than zero, bands are ignored.
+ *   if nband1 gte zero, nband2 must be gte zero
+ * @param rast2 : the second raster whose band will be tested
+ * @param nband2 : the 0-based band of raster rast2 to use
+ *   if value is less than zero, bands are ignored
+ *   if nband2 gte zero, nband1 must be gte zero
+ * @param dwithin : non-zero value if rast1 is within a distance of rast2
+ *
+ * @return if zero, an error occurred in function
+ */
+int rt_raster_within_distance(
+       rt_raster rast1, int nband1,
+       rt_raster rast2, int nband2,
+       double distance,
+       int *dwithin
+) {
+       LWGEOM *surface1 = NULL;
+       LWGEOM *surface2 = NULL;
+       double mindist = 0;
+       int rtn = 0;
+
+       RASTER_DEBUG(3, "Starting");
+
+       assert(NULL != rast1);
+       assert(NULL != rast2);
+
+       if (nband1 < 0 && nband2 < 0) {
+               nband1 = -1;
+               nband2 = -1;
+       }
+       else {
+               assert(nband1 >= 0 && nband1 < rt_raster_get_num_bands(rast1));
+               assert(nband2 >= 0 && nband2 < rt_raster_get_num_bands(rast2));
+       }
+
+       /* initialize to zero, false result */
+       *dwithin = 0;
+
+       /* same srid */
+       if (rt_raster_get_srid(rast1) != rt_raster_get_srid(rast2)) {
+               rterror("rt_raster_distance_within: The two rasters provided have different SRIDs");
+               return 0;
+       }
+
+       /* distance cannot be less than zero */
+       if (distance < 0) {
+               rterror("rt_raster_distance_within: Distance cannot be less than zero");
+               return 0;
+       }
+
+       /* get LWMPOLY of each band */
+       surface1 = lwmpoly_as_lwgeom(rt_raster_surface(rast1, nband1, &rtn));
+       if (!rtn) {
+               rterror("rt_raster_distance_within: Unable to get surface of the specified band from the first raster");
+               return 0;
+       }
+       surface2 = lwmpoly_as_lwgeom(rt_raster_surface(rast2, nband2, &rtn));
+       if (!rtn) {
+               rterror("rt_raster_distance_within: Unable to get surface of the specified band from the second raster");
+               lwgeom_free(surface1);
+               return 0;
+       }
+
+       /* either surface is NULL, test is false */
+       if (surface1 == NULL || surface2 == NULL) {
+               if (surface1 != NULL) lwgeom_free(surface1);
+               if (surface2 != NULL) lwgeom_free(surface2);
+               return 1;
+       }
+
+       /* get the min distance between the two surfaces */
+       mindist = lwgeom_mindistance2d_tolerance(surface1, surface2, distance);
+
+       lwgeom_free(surface1);
+       lwgeom_free(surface2);
+
+       /* if distance >= mindist, true */
+       if (FLT_EQ(mindist, distance) || distance > mindist)
+               *dwithin = 1;
+
+       return 1;
+}
+
 /*
  * Return zero if error occurred in function.
  * Paramter aligned returns non-zero if two rasters are aligned
index 73d04660c66e77870cdd1f8a11d71ed9fb9b46e4..1c963ebc177840f85f173ca053bb184ddc6d902c 100644 (file)
@@ -1599,6 +1599,29 @@ int rt_raster_coveredby(
        int *coveredby
 );
 
+/**
+ * Return zero if error occurred in function.
+ * Parameter contains returns non-zero if rast1 is within a distance of rast2
+ *
+ * @param rast1 : the first raster whose band will be tested
+ * @param nband1 : the 0-based band of raster rast1 to use
+ *   if value is less than zero, bands are ignored.
+ *   if nband1 gte zero, nband2 must be gte zero
+ * @param rast2 : the second raster whose band will be tested
+ * @param nband2 : the 0-based band of raster rast2 to use
+ *   if value is less than zero, bands are ignored
+ *   if nband2 gte zero, nband1 must be gte zero
+ * @param dwithin : non-zero value if rast1 is within a distance of rast2
+ *
+ * @return if zero, an error occurred in function
+ */
+int rt_raster_within_distance(
+       rt_raster rast1, int nband1,
+       rt_raster rast2, int nband2,
+       double distance,
+       int *dwithin
+);
+
 /*
  * Return zero if error occurred in function.
  * Paramter aligned returns non-zero if two rasters are aligned
index 56f85e667842f0a977c87809e1c7f5aef4a09d4a..ecbf7105aaaa54ca6ce4a96694ea7279c580b872 100644 (file)
@@ -5461,6 +5461,564 @@ static void testCoveredBy() {
        deepRelease(rast1);
 }
 
+static void testDWithin() {
+       rt_raster rast1;
+       rt_raster rast2;
+       rt_band band1;
+       rt_band band2;
+       double nodata;
+       int rtn;
+       int result;
+
+       /*
+               rast1
+
+               (-1, -1)
+                                               +-+-+
+                                               |1|1|
+                                               +-+-+
+                                               |1|1|
+                                               +-+-+
+                                                               (1, 1)
+       */
+       rast1 = rt_raster_new(2, 2);
+       assert(rast1);
+       rt_raster_set_offsets(rast1, -1, -1);
+
+       band1 = addBand(rast1, PT_8BUI, 1, 0);
+       CHECK(band1);
+       rt_band_set_nodata(band1, 0);
+       rtn = rt_band_set_pixel(band1, 0, 0, 1);
+       rtn = rt_band_set_pixel(band1, 0, 1, 1);
+       rtn = rt_band_set_pixel(band1, 1, 0, 1);
+       rtn = rt_band_set_pixel(band1, 1, 1, 1);
+
+       nodata = rt_band_get_nodata(band1);
+       CHECK_EQUALS(nodata, 0);
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast1, 0,
+               0.,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result == 1));
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast1, 0,
+               -1.,
+               &result
+       );
+       CHECK((rtn == 0));
+
+       /*
+               rast2
+
+               (0, 0)
+                                               +-+-+
+                                               |1|1|
+                                               +-+-+
+                                               |1|1|
+                                               +-+-+
+                                                               (2, 2)
+       */
+       rast2 = rt_raster_new(2, 2);
+       assert(rast2);
+
+       band2 = addBand(rast2, PT_8BUI, 1, 0);
+       CHECK(band2);
+       rt_band_set_nodata(band2, 0);
+       rtn = rt_band_set_pixel(band2, 0, 0, 1);
+       rtn = rt_band_set_pixel(band2, 0, 1, 1);
+       rtn = rt_band_set_pixel(band2, 1, 0, 1);
+       rtn = rt_band_set_pixel(band2, 1, 1, 1);
+
+       nodata = rt_band_get_nodata(band2);
+       CHECK_EQUALS(nodata, 0);
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               0.,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result == 1));
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               1.,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result == 1));
+
+       rtn = rt_raster_within_distance(
+               rast1, -1,
+               rast2, -1,
+               2.,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result == 1));
+
+       /*
+               rast2
+
+               (0, 0)
+                                               +-+-+
+                                               |0|1|
+                                               +-+-+
+                                               |1|1|
+                                               +-+-+
+                                                               (2, 2)
+       */
+       rtn = rt_band_set_pixel(band2, 0, 0, 0);
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               0.,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result == 1));
+
+       /*
+               rast2
+
+               (0, 0)
+                                               +-+-+
+                                               |1|0|
+                                               +-+-+
+                                               |1|1|
+                                               +-+-+
+                                                               (2, 2)
+       */
+       rtn = rt_band_set_pixel(band2, 0, 0, 1);
+       rtn = rt_band_set_pixel(band2, 1, 0, 0);
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               0.,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result == 1));
+
+       /*
+               rast2
+
+               (0, 0)
+                                               +-+-+
+                                               |0|0|
+                                               +-+-+
+                                               |0|1|
+                                               +-+-+
+                                                               (2, 2)
+       */
+       rtn = rt_band_set_pixel(band2, 0, 0, 0);
+       rtn = rt_band_set_pixel(band2, 1, 0, 0);
+       rtn = rt_band_set_pixel(band2, 0, 1, 0);
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               0,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result == 1));
+
+       /*
+               rast2
+
+               (0, 0)
+                                               +-+-+
+                                               |0|0|
+                                               +-+-+
+                                               |0|0|
+                                               +-+-+
+                                                               (2, 2)
+       */
+       rtn = rt_band_set_pixel(band2, 0, 0, 0);
+       rtn = rt_band_set_pixel(band2, 1, 0, 0);
+       rtn = rt_band_set_pixel(band2, 0, 1, 0);
+       rtn = rt_band_set_pixel(band2, 1, 1, 0);
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               0,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result != 1));
+
+       /*
+               rast2
+
+               (2, 0)
+                                               +-+-+
+                                               |1|1|
+                                               +-+-+
+                                               |1|1|
+                                               +-+-+
+                                                               (4, 2)
+       */
+       rt_raster_set_offsets(rast2, 2, 0);
+
+       rtn = rt_band_set_pixel(band2, 0, 0, 1);
+       rtn = rt_band_set_pixel(band2, 1, 0, 1);
+       rtn = rt_band_set_pixel(band2, 0, 1, 1);
+       rtn = rt_band_set_pixel(band2, 1, 1, 1);
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               0,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result != 1));
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               1.1,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result == 1));
+
+       /*
+               rast2
+
+               (0.1, 0.1)
+                                               +-+-+
+                                               |1|1|
+                                               +-+-+
+                                               |1|1|
+                                               +-+-+
+                                                               (0.9, 0.9)
+       */
+       rt_raster_set_offsets(rast2, 0.1, 0.1);
+       rt_raster_set_scale(rast2, 0.4, 0.4);
+
+       rtn = rt_band_set_pixel(band2, 0, 0, 1);
+       rtn = rt_band_set_pixel(band2, 1, 0, 1);
+       rtn = rt_band_set_pixel(band2, 0, 1, 1);
+       rtn = rt_band_set_pixel(band2, 1, 1, 1);
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               0,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result == 1));
+
+       /*
+               rast2
+
+               (-0.1, 0.1)
+                                               +-+-+
+                                               |1|1|
+                                               +-+-+
+                                               |1|1|
+                                               +-+-+
+                                                               (0.9, 0.9)
+       */
+       rt_raster_set_offsets(rast2, -0.1, 0.1);
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               0,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result == 1));
+
+       deepRelease(rast2);
+
+       /*
+               rast2
+
+               (0, 0)
+                                               +-+-+-+
+                                               |1|1|1|
+                                               +-+-+-+
+                                               |1|1|1|
+                                               +-+-+-+
+                                               |1|1|1|
+                                               +-+-+-+
+                                                                       (3, 3)
+       */
+       rast2 = rt_raster_new(3, 3);
+       assert(rast2);
+
+       band2 = addBand(rast2, PT_8BUI, 1, 0);
+       CHECK(band2);
+       rt_band_set_nodata(band2, 0);
+       rtn = rt_band_set_pixel(band2, 0, 0, 1);
+       rtn = rt_band_set_pixel(band2, 0, 1, 1);
+       rtn = rt_band_set_pixel(band2, 0, 2, 1);
+       rtn = rt_band_set_pixel(band2, 1, 0, 1);
+       rtn = rt_band_set_pixel(band2, 1, 1, 1);
+       rtn = rt_band_set_pixel(band2, 1, 2, 1);
+       rtn = rt_band_set_pixel(band2, 2, 0, 1);
+       rtn = rt_band_set_pixel(band2, 2, 1, 1);
+       rtn = rt_band_set_pixel(band2, 2, 2, 1);
+
+       nodata = rt_band_get_nodata(band2);
+       CHECK_EQUALS(nodata, 0);
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               0,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result == 1));
+
+       /*
+               rast2
+
+               (-2, -2)
+                                               +-+-+-+
+                                               |1|1|1|
+                                               +-+-+-+
+                                               |1|1|1|
+                                               +-+-+-+
+                                               |1|1|1|
+                                               +-+-+-+
+                                                                       (1, 1)
+       */
+       rt_raster_set_offsets(rast2, -2, -2);
+
+       rtn = rt_band_set_pixel(band2, 0, 0, 1);
+       rtn = rt_band_set_pixel(band2, 0, 1, 1);
+       rtn = rt_band_set_pixel(band2, 0, 2, 1);
+       rtn = rt_band_set_pixel(band2, 1, 0, 1);
+       rtn = rt_band_set_pixel(band2, 1, 1, 1);
+       rtn = rt_band_set_pixel(band2, 1, 2, 1);
+       rtn = rt_band_set_pixel(band2, 2, 0, 1);
+       rtn = rt_band_set_pixel(band2, 2, 1, 1);
+       rtn = rt_band_set_pixel(band2, 2, 2, 1);
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               0,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result == 1));
+
+       /*
+               rast2
+
+               (-2, -2)
+                                               +-+-+-+
+                                               |0|1|1|
+                                               +-+-+-+
+                                               |1|0|1|
+                                               +-+-+-+
+                                               |1|1|0|
+                                               +-+-+-+
+                                                                       (1, 1)
+       */
+       rtn = rt_band_set_pixel(band2, 0, 0, 0);
+       rtn = rt_band_set_pixel(band2, 0, 1, 1);
+       rtn = rt_band_set_pixel(band2, 0, 2, 1);
+       rtn = rt_band_set_pixel(band2, 1, 0, 1);
+       rtn = rt_band_set_pixel(band2, 1, 1, 0);
+       rtn = rt_band_set_pixel(band2, 1, 2, 1);
+       rtn = rt_band_set_pixel(band2, 2, 0, 1);
+       rtn = rt_band_set_pixel(band2, 2, 1, 1);
+       rtn = rt_band_set_pixel(band2, 2, 2, 0);
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               0,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result == 1));
+
+       /*
+               rast2
+
+               (-2, -2)
+                                               +-+-+-+
+                                               |0|1|1|
+                                               +-+-+-+
+                                               |1|0|0|
+                                               +-+-+-+
+                                               |1|0|0|
+                                               +-+-+-+
+                                                                       (1, 1)
+       */
+       rtn = rt_band_set_pixel(band2, 0, 0, 0);
+       rtn = rt_band_set_pixel(band2, 0, 1, 1);
+       rtn = rt_band_set_pixel(band2, 0, 2, 1);
+       rtn = rt_band_set_pixel(band2, 1, 0, 1);
+       rtn = rt_band_set_pixel(band2, 1, 1, 0);
+       rtn = rt_band_set_pixel(band2, 1, 2, 0);
+       rtn = rt_band_set_pixel(band2, 2, 0, 1);
+       rtn = rt_band_set_pixel(band2, 2, 1, 0);
+       rtn = rt_band_set_pixel(band2, 2, 2, 0);
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               0,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result == 1));
+
+       /*
+               rast2
+
+               (-2, -2)
+                                               +-+-+-+
+                                               |0|1|0|
+                                               +-+-+-+
+                                               |1|0|0|
+                                               +-+-+-+
+                                               |0|0|0|
+                                               +-+-+-+
+                                                                       (1, 1)
+       */
+       rtn = rt_band_set_pixel(band2, 0, 0, 0);
+       rtn = rt_band_set_pixel(band2, 0, 1, 1);
+       rtn = rt_band_set_pixel(band2, 0, 2, 0);
+       rtn = rt_band_set_pixel(band2, 1, 0, 1);
+       rtn = rt_band_set_pixel(band2, 1, 1, 0);
+       rtn = rt_band_set_pixel(band2, 1, 2, 0);
+       rtn = rt_band_set_pixel(band2, 2, 0, 0);
+       rtn = rt_band_set_pixel(band2, 2, 1, 0);
+       rtn = rt_band_set_pixel(band2, 2, 2, 0);
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               0,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result == 1));
+
+       /*
+               rast2
+
+               (-10, -1)
+                                               +-+-+-+
+                                               |1|1|1|
+                                               +-+-+-+
+                                               |1|1|1|
+                                               +-+-+-+
+                                               |1|1|1|
+                                               +-+-+-+
+                                                                       (-7, 2)
+       */
+       rt_raster_set_offsets(rast2, -10, -1);
+
+       rtn = rt_band_set_pixel(band2, 0, 0, 1);
+       rtn = rt_band_set_pixel(band2, 0, 1, 1);
+       rtn = rt_band_set_pixel(band2, 0, 2, 1);
+       rtn = rt_band_set_pixel(band2, 1, 0, 1);
+       rtn = rt_band_set_pixel(band2, 1, 1, 1);
+       rtn = rt_band_set_pixel(band2, 1, 2, 1);
+       rtn = rt_band_set_pixel(band2, 2, 0, 1);
+       rtn = rt_band_set_pixel(band2, 2, 1, 1);
+       rtn = rt_band_set_pixel(band2, 2, 2, 1);
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               5,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result != 1));
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               6,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result == 1));
+
+       deepRelease(rast2);
+
+       /* skew tests */
+       /* rast2 (skewed by -0.5, 0.5) */
+       rast2 = rt_raster_new(3, 3);
+       assert(rast2);
+       rt_raster_set_skews(rast2, -0.5, 0.5);
+
+       band2 = addBand(rast2, PT_8BUI, 1, 0);
+       CHECK(band2);
+       rt_band_set_nodata(band2, 0);
+       rtn = rt_band_set_pixel(band2, 0, 0, 1);
+       rtn = rt_band_set_pixel(band2, 0, 1, 2);
+       rtn = rt_band_set_pixel(band2, 0, 2, 3);
+       rtn = rt_band_set_pixel(band2, 1, 0, 1);
+       rtn = rt_band_set_pixel(band2, 1, 1, 2);
+       rtn = rt_band_set_pixel(band2, 1, 2, 3);
+       rtn = rt_band_set_pixel(band2, 2, 0, 1);
+       rtn = rt_band_set_pixel(band2, 2, 1, 2);
+       rtn = rt_band_set_pixel(band2, 2, 2, 3);
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               0,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result == 1));
+
+       /* rast2 (skewed by -1, 1) */
+       rt_raster_set_skews(rast2, -1, 1);
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               0,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result == 1));
+
+       /* rast2 (skewed by 1, -1) */
+       rt_raster_set_skews(rast2, 1, -1);
+
+       rtn = rt_raster_within_distance(
+               rast1, 0,
+               rast2, 0,
+               0,
+               &result
+       );
+       CHECK((rtn != 0));
+       CHECK((result == 1));
+
+       deepRelease(rast2);
+       deepRelease(rast1);
+}
+
 static void testAlignment() {
        rt_raster rast1;
        rt_raster rast2;
@@ -6425,6 +6983,10 @@ main()
                testCoveredBy();
                printf("OK\n");
 
+               printf("Testing rt_raster_within_distance... ");
+               testDWithin();
+               printf("OK\n");
+
                printf("Testing rt_raster_same_alignment... ");
                testAlignment();
                printf("OK\n");