PostGIS  2.2.8dev-r@@SVN_REVISION@@
cu_raster_geometry.c
Go to the documentation of this file.
1 /*
2  * PostGIS Raster - Raster Types for PostGIS
3  * http://trac.osgeo.org/postgis/wiki/WKTRaster
4  *
5  * Copyright (C) 2012-2013 Regents of the University of California
6  * <bkpark@ucdavis.edu>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  *
22  */
23 
24 #include "CUnit/Basic.h"
25 #include "cu_tester.h"
26 
27 static void test_raster_envelope() {
28  rt_raster raster = NULL;
29  rt_envelope rtenv;
30 
31  /* width = 0, height = 0 */
32  raster = rt_raster_new(0, 0);
33  CU_ASSERT(raster != NULL);
34 
35  rt_raster_set_offsets(raster, 0.5, 0.5);
36  rt_raster_set_scale(raster, 1, -1);
37 
38  CU_ASSERT_EQUAL(rt_raster_get_envelope(raster, &rtenv), ES_NONE);
39  CU_ASSERT_DOUBLE_EQUAL(rtenv.MinX, 0.5, DBL_EPSILON);
40  CU_ASSERT_DOUBLE_EQUAL(rtenv.MaxX, 0.5, DBL_EPSILON);
41  CU_ASSERT_DOUBLE_EQUAL(rtenv.MinY, 0.5, DBL_EPSILON);
42  CU_ASSERT_DOUBLE_EQUAL(rtenv.MaxY, 0.5, DBL_EPSILON);
43  cu_free_raster(raster);
44 
45  /* width = 0 */
46  raster = rt_raster_new(0, 5);
47  CU_ASSERT(raster != NULL);
48 
49  rt_raster_set_offsets(raster, 0.5, 0.5);
50  rt_raster_set_scale(raster, 1, -1);
51 
52  CU_ASSERT_EQUAL(rt_raster_get_envelope(raster, &rtenv), ES_NONE);
53  CU_ASSERT_DOUBLE_EQUAL(rtenv.MinX, 0.5, DBL_EPSILON);
54  CU_ASSERT_DOUBLE_EQUAL(rtenv.MaxX, 0.5, DBL_EPSILON);
55  CU_ASSERT_DOUBLE_EQUAL(rtenv.MinY, -4.5, DBL_EPSILON);
56  CU_ASSERT_DOUBLE_EQUAL(rtenv.MaxY, 0.5, DBL_EPSILON);
57  cu_free_raster(raster);
58 
59  /* height = 0 */
60  raster = rt_raster_new(5, 0);
61  CU_ASSERT(raster != NULL);
62 
63  rt_raster_set_offsets(raster, 0.5, 0.5);
64  rt_raster_set_scale(raster, 1, -1);
65 
66  CU_ASSERT_EQUAL(rt_raster_get_envelope(raster, &rtenv), ES_NONE);
67  CU_ASSERT_DOUBLE_EQUAL(rtenv.MinX, 0.5, DBL_EPSILON);
68  CU_ASSERT_DOUBLE_EQUAL(rtenv.MaxX, 5.5, DBL_EPSILON);
69  CU_ASSERT_DOUBLE_EQUAL(rtenv.MinY, 0.5, DBL_EPSILON);
70  CU_ASSERT_DOUBLE_EQUAL(rtenv.MaxY, 0.5, DBL_EPSILON);
71  cu_free_raster(raster);
72 
73  /* normal raster */
74  raster = rt_raster_new(5, 5);
75  CU_ASSERT(raster != NULL);
76 
77  rt_raster_set_offsets(raster, 0.5, 0.5);
78  rt_raster_set_scale(raster, 1, -1);
79 
80  CU_ASSERT_EQUAL(rt_raster_get_envelope(raster, &rtenv), ES_NONE);
81  CU_ASSERT_DOUBLE_EQUAL(rtenv.MinX, 0.5, DBL_EPSILON);
82  CU_ASSERT_DOUBLE_EQUAL(rtenv.MaxX, 5.5, DBL_EPSILON);
83  CU_ASSERT_DOUBLE_EQUAL(rtenv.MinY, -4.5, DBL_EPSILON);
84  CU_ASSERT_DOUBLE_EQUAL(rtenv.MaxY, 0.5, DBL_EPSILON);
85  cu_free_raster(raster);
86 }
87 
89  rt_raster raster = NULL;
90  LWGEOM *env = NULL;
91  LWPOLY *poly = NULL;
92  POINTARRAY *ring = NULL;
93  POINT4D pt;
94 
95  /* NULL raster */
96  CU_ASSERT_EQUAL(rt_raster_get_envelope_geom(NULL, &env), ES_NONE);
97  CU_ASSERT(env == NULL);
98 
99  /* width = 0, height = 0 */
100  raster = rt_raster_new(0, 0);
101  CU_ASSERT(raster != NULL);
102 
103  CU_ASSERT_EQUAL(rt_raster_get_envelope_geom(raster, &env), ES_NONE);
104  CU_ASSERT_EQUAL(env->type, POINTTYPE);
105  lwgeom_free(env);
106  cu_free_raster(raster);
107 
108  /* width = 0 */
109  raster = rt_raster_new(0, 256);
110  CU_ASSERT(raster != NULL);
111 
112  CU_ASSERT_EQUAL(rt_raster_get_envelope_geom(raster, &env), ES_NONE);
113  CU_ASSERT_EQUAL(env->type, LINETYPE);
114  lwgeom_free(env);
115  cu_free_raster(raster);
116 
117  /* height = 0 */
118  raster = rt_raster_new(256, 0);
119  CU_ASSERT(raster != NULL);
120 
121  CU_ASSERT_EQUAL(rt_raster_get_envelope_geom(raster, &env), ES_NONE);
122  CU_ASSERT_EQUAL(env->type, LINETYPE);
123  lwgeom_free(env);
124  cu_free_raster(raster);
125 
126  /* normal raster */
127  raster = rt_raster_new(5, 5);
128  CU_ASSERT(raster != NULL);
129 
130  rt_raster_set_offsets(raster, 0.5, 0.5);
131  rt_raster_set_scale(raster, 1, -1);
132 
133  CU_ASSERT_EQUAL(rt_raster_get_envelope_geom(raster, &env), ES_NONE);
134  poly = lwgeom_as_lwpoly(env);
135  CU_ASSERT_EQUAL(poly->srid, rt_raster_get_srid(raster));
136  CU_ASSERT_EQUAL(poly->nrings, 1);
137 
138  ring = poly->rings[0];
139  CU_ASSERT(ring != NULL);
140  CU_ASSERT_EQUAL(ring->npoints, 5);
141 
142  getPoint4d_p(ring, 0, &pt);
143  CU_ASSERT_DOUBLE_EQUAL(pt.x, 0.5, DBL_EPSILON);
144  CU_ASSERT_DOUBLE_EQUAL(pt.y, 0.5, DBL_EPSILON);
145 
146  getPoint4d_p(ring, 1, &pt);
147  CU_ASSERT_DOUBLE_EQUAL(pt.x, 5.5, DBL_EPSILON);
148  CU_ASSERT_DOUBLE_EQUAL(pt.y, 0.5, DBL_EPSILON);
149 
150  getPoint4d_p(ring, 2, &pt);
151  CU_ASSERT_DOUBLE_EQUAL(pt.x, 5.5, DBL_EPSILON);
152  CU_ASSERT_DOUBLE_EQUAL(pt.y, -4.5, DBL_EPSILON);
153 
154  getPoint4d_p(ring, 3, &pt);
155  CU_ASSERT_DOUBLE_EQUAL(pt.x, 0.5, DBL_EPSILON);
156  CU_ASSERT_DOUBLE_EQUAL(pt.y, -4.5, DBL_EPSILON);
157 
158  getPoint4d_p(ring, 4, &pt);
159  CU_ASSERT_DOUBLE_EQUAL(pt.x, 0.5, DBL_EPSILON);
160  CU_ASSERT_DOUBLE_EQUAL(pt.y, 0.5, DBL_EPSILON);
161 
162  lwgeom_free(env);
163  cu_free_raster(raster);
164 }
165 
166 static void test_raster_convex_hull() {
167  rt_raster raster = NULL;
168  LWGEOM *hull = NULL;
169  LWPOLY *poly = NULL;
170  POINTARRAY *ring = NULL;
171  POINT4D pt;
172 
173  /* NULL raster */
174  CU_ASSERT_EQUAL(rt_raster_get_convex_hull(NULL, &hull), ES_NONE);
175  CU_ASSERT(hull == NULL);
176 
177  /* width = 0, height = 0 */
178  raster = rt_raster_new(0, 0);
179  CU_ASSERT(raster != NULL);
180 
181  CU_ASSERT_EQUAL(rt_raster_get_convex_hull(raster, &hull), ES_NONE);
182  CU_ASSERT_EQUAL(hull->type, POINTTYPE);
183  lwgeom_free(hull);
184  cu_free_raster(raster);
185 
186  /* width = 0 */
187  raster = rt_raster_new(0, 256);
188  CU_ASSERT(raster != NULL);
189 
190  CU_ASSERT_EQUAL(rt_raster_get_convex_hull(raster, &hull), ES_NONE);
191  CU_ASSERT_EQUAL(hull->type, LINETYPE);
192  lwgeom_free(hull);
193  cu_free_raster(raster);
194 
195  /* height = 0 */
196  raster = rt_raster_new(256, 0);
197  CU_ASSERT(raster != NULL);
198 
199  CU_ASSERT_EQUAL(rt_raster_get_convex_hull(raster, &hull), ES_NONE);
200  CU_ASSERT_EQUAL(hull->type, LINETYPE);
201  lwgeom_free(hull);
202  cu_free_raster(raster);
203 
204  /* normal raster */
205  raster = rt_raster_new(256, 256);
206  CU_ASSERT(raster != NULL);
207 
208  rt_raster_set_offsets(raster, 0.5, 0.5);
209  rt_raster_set_scale(raster, 1, 1);
210  rt_raster_set_skews(raster, 4, 5);
211 
212  CU_ASSERT_EQUAL(rt_raster_get_convex_hull(raster, &hull), ES_NONE);
213  poly = lwgeom_as_lwpoly(hull);
214  CU_ASSERT_EQUAL(poly->srid, rt_raster_get_srid(raster));
215  CU_ASSERT_EQUAL(poly->nrings, 1);
216 
217  ring = poly->rings[0];
218  CU_ASSERT(ring != NULL);
219  CU_ASSERT_EQUAL(ring->npoints, 5);
220 
221  getPoint4d_p(ring, 0, &pt);
222  CU_ASSERT_DOUBLE_EQUAL(pt.x, 0.5, DBL_EPSILON);
223  CU_ASSERT_DOUBLE_EQUAL(pt.y, 0.5, DBL_EPSILON);
224 
225  getPoint4d_p(ring, 1, &pt);
226  CU_ASSERT_DOUBLE_EQUAL(pt.x, 256.5, DBL_EPSILON);
227  CU_ASSERT_DOUBLE_EQUAL(pt.y, 1280.5, DBL_EPSILON);
228 
229  getPoint4d_p(ring, 2, &pt);
230  CU_ASSERT_DOUBLE_EQUAL(pt.x, 1280.5, DBL_EPSILON);
231  CU_ASSERT_DOUBLE_EQUAL(pt.y, 1536.5, DBL_EPSILON);
232 
233  getPoint4d_p(ring, 3, &pt);
234  CU_ASSERT_DOUBLE_EQUAL(pt.x, 1024.5, DBL_EPSILON);
235  CU_ASSERT_DOUBLE_EQUAL(pt.y, 256.5, DBL_EPSILON);
236 
237  getPoint4d_p(ring, 4, &pt);
238  CU_ASSERT_DOUBLE_EQUAL(pt.x, 0.5, DBL_EPSILON);
239  CU_ASSERT_DOUBLE_EQUAL(pt.y, 0.5, DBL_EPSILON);
240 
241  lwgeom_free(hull);
242  cu_free_raster(raster);
243 }
244 
245 static char *
246 lwgeom_to_text(const LWGEOM *lwgeom) {
247  char *wkt;
248  size_t wkt_size;
249 
250  wkt = lwgeom_to_wkt(lwgeom, WKT_ISO, DBL_DIG, &wkt_size);
251 
252  return wkt;
253 }
254 
255 static void test_raster_surface() {
256  rt_raster rast;
257  rt_band band;
258  const int maxX = 5;
259  const int maxY = 5;
260  int x, y;
261  char *wkt = NULL;
262  LWMPOLY *mpoly = NULL;
263  int err;
264 
265  rast = rt_raster_new(maxX, maxY);
266  CU_ASSERT(rast != NULL);
267 
268  rt_raster_set_offsets(rast, 0, 0);
269  rt_raster_set_scale(rast, 1, -1);
270 
271  band = cu_add_band(rast, PT_32BUI, 1, 0);
272  CU_ASSERT(band != NULL);
273 
274  for (y = 0; y < maxY; y++) {
275  for (x = 0; x < maxX; x++) {
276  rt_band_set_pixel(band, x, y, 1, NULL);
277  }
278  }
279 
280  err = rt_raster_surface(rast, 0, &mpoly);
281  CU_ASSERT_EQUAL(err, ES_NONE);
282  CU_ASSERT(mpoly != NULL);
283  wkt = lwgeom_to_text(lwmpoly_as_lwgeom(mpoly));
284  CU_ASSERT_STRING_EQUAL(wkt, "MULTIPOLYGON(((0 0,0 -5,5 -5,5 0,0 0)))");
285  rtdealloc(wkt);
286  lwmpoly_free(mpoly);
287  mpoly = NULL;
288 
289  /* 0,0 NODATA */
290  rt_band_set_pixel(band, 0, 0, 0, NULL);
291 
292  err = rt_raster_surface(rast, 0, &mpoly);
293  CU_ASSERT_EQUAL(err, ES_NONE);
294  CU_ASSERT(mpoly != NULL);
295  wkt = lwgeom_to_text(lwmpoly_as_lwgeom(mpoly));
296  CU_ASSERT_STRING_EQUAL(wkt, "MULTIPOLYGON(((1 0,1 -1,0 -1,0 -5,4 -5,5 -5,5 0,1 0)))");
297  rtdealloc(wkt);
298  lwmpoly_free(mpoly);
299  mpoly = NULL;
300 
301  /* plus 1,1 NODATA */
302  rt_band_set_pixel(band, 1, 1, 0, NULL);
303 
304  err = rt_raster_surface(rast, 0, &mpoly);
305  CU_ASSERT_EQUAL(err, ES_NONE);
306  CU_ASSERT(mpoly != NULL);
307  wkt = lwgeom_to_text(lwmpoly_as_lwgeom(mpoly));
308  CU_ASSERT_STRING_EQUAL(wkt, "MULTIPOLYGON(((1 0,1 -1,0 -1,0 -5,4 -5,5 -5,5 0,1 0),(1 -1,1 -2,2 -2,2 -1,1 -1)))");
309  rtdealloc(wkt);
310  lwmpoly_free(mpoly);
311  mpoly = NULL;
312 
313  /* plus 2,2 NODATA */
314  rt_band_set_pixel(band, 2, 2, 0, NULL);
315 
316  err = rt_raster_surface(rast, 0, &mpoly);
317  CU_ASSERT_EQUAL(err, ES_NONE);
318  CU_ASSERT(mpoly != NULL);
319  wkt = lwgeom_to_text(lwmpoly_as_lwgeom(mpoly));
320 #if POSTGIS_GEOS_VERSION >= 33
321  CU_ASSERT_STRING_EQUAL(wkt, "MULTIPOLYGON(((1 -1,1 0,5 0,5 -5,4 -5,0 -5,0 -1,1 -1),(1 -1,1 -2,2 -2,2 -1,1 -1),(2 -2,2 -3,3 -3,3 -2,2 -2)))");
322 #else
323  CU_ASSERT_STRING_EQUAL(wkt, "MULTIPOLYGON(((1 0,1 -1,0 -1,0 -5,4 -5,5 -5,5 0,1 0),(1 -1,1 -2,2 -2,2 -3,3 -3,3 -2,2 -2,2 -1,1 -1)))");
324 #endif
325  rtdealloc(wkt);
326  lwmpoly_free(mpoly);
327  mpoly = NULL;
328 
329  /* plus 3,3 NODATA */
330  rt_band_set_pixel(band, 3, 3, 0, NULL);
331 
332  err = rt_raster_surface(rast, 0, &mpoly);
333  CU_ASSERT_EQUAL(err, ES_NONE);
334  CU_ASSERT(mpoly != NULL);
335  wkt = lwgeom_to_text(lwmpoly_as_lwgeom(mpoly));
336 #if POSTGIS_GEOS_VERSION >= 33
337  CU_ASSERT_STRING_EQUAL(wkt, "MULTIPOLYGON(((1 -1,1 0,5 0,5 -5,4 -5,0 -5,0 -1,1 -1),(1 -1,1 -2,2 -2,2 -1,1 -1),(2 -2,2 -3,3 -3,3 -2,2 -2),(3 -3,3 -4,4 -4,4 -3,3 -3)))");
338 #else
339  CU_ASSERT_STRING_EQUAL(wkt, "MULTIPOLYGON(((1 0,1 -1,0 -1,0 -5,4 -5,5 -5,5 0,1 0),(1 -1,1 -2,2 -2,2 -3,3 -3,3 -4,4 -4,4 -3,3 -3,3 -2,2 -2,2 -1,1 -1)))");
340 #endif
341  rtdealloc(wkt);
342  lwmpoly_free(mpoly);
343  mpoly = NULL;
344 
345  /* plus 4,4 NODATA */
346  rt_band_set_pixel(band, 4, 4, 0, NULL);
347 
348  err = rt_raster_surface(rast, 0, &mpoly);
349  CU_ASSERT_EQUAL(err, ES_NONE);
350  CU_ASSERT(mpoly != NULL);
351  wkt = lwgeom_to_text(lwmpoly_as_lwgeom(mpoly));
352  CU_ASSERT_STRING_EQUAL(wkt, "MULTIPOLYGON(((4 -4,4 -5,0 -5,0 -1,1 -1,1 -2,2 -2,2 -3,3 -3,3 -4,4 -4)),((1 -1,1 0,5 0,5 -4,4 -4,4 -3,3 -3,3 -2,2 -2,2 -1,1 -1)))");
353  rtdealloc(wkt);
354  lwmpoly_free(mpoly);
355  mpoly = NULL;
356 
357  /* a whole lot more NODATA */
358  rt_band_set_pixel(band, 4, 0, 0, NULL);
359  rt_band_set_pixel(band, 3, 1, 0, NULL);
360  rt_band_set_pixel(band, 1, 3, 0, NULL);
361  rt_band_set_pixel(band, 0, 4, 0, NULL);
362 
363  err = rt_raster_surface(rast, 0, &mpoly);
364  CU_ASSERT_EQUAL(err, ES_NONE);
365  CU_ASSERT(mpoly != NULL);
366  wkt = lwgeom_to_text(lwmpoly_as_lwgeom(mpoly));
367  CU_ASSERT_STRING_EQUAL(wkt, "MULTIPOLYGON(((1 -4,2 -4,2 -3,3 -3,3 -4,4 -4,4 -5,3 -5,1 -5,1 -4)),((1 -4,0 -4,0 -1,1 -1,1 -2,2 -2,2 -3,1 -3,1 -4)),((3 -2,4 -2,4 -1,5 -1,5 -4,4 -4,4 -3,3 -3,3 -2)),((3 -2,2 -2,2 -1,1 -1,1 0,4 0,4 -1,3 -1,3 -2)))");
368  rtdealloc(wkt);
369  lwmpoly_free(mpoly);
370  mpoly = NULL;
371 
372  cu_free_raster(rast);
373 }
374 
375 static void test_raster_perimeter() {
376  rt_raster rast;
377  rt_band band;
378  const int maxX = 5;
379  const int maxY = 5;
380  int x, y;
381  char *wkt = NULL;
382  LWGEOM *geom = NULL;
383  int err;
384 
385  rast = rt_raster_new(maxX, maxY);
386  CU_ASSERT(rast != NULL);
387 
388  rt_raster_set_offsets(rast, 0, 0);
389  rt_raster_set_scale(rast, 1, -1);
390 
391  band = cu_add_band(rast, PT_32BUI, 1, 0);
392  CU_ASSERT(band != NULL);
393 
394  for (y = 0; y < maxY; y++) {
395  for (x = 0; x < maxX; x++) {
396  rt_band_set_pixel(band, x, y, 1, NULL);
397  }
398  }
399 
400  err = rt_raster_get_perimeter(rast, -1, &geom);
401  CU_ASSERT_EQUAL(err, ES_NONE);
402  CU_ASSERT(geom != NULL);
403  wkt = lwgeom_to_text(geom);
404  CU_ASSERT_STRING_EQUAL(wkt, "POLYGON((0 0,5 0,5 -5,0 -5,0 0))");
405  rtdealloc(wkt);
406  lwgeom_free(geom);
407  geom = NULL;
408 
409  /* row 0 is NODATA */
410  rt_band_set_pixel(band, 0, 0, 0, NULL);
411  rt_band_set_pixel(band, 1, 0, 0, NULL);
412  rt_band_set_pixel(band, 2, 0, 0, NULL);
413  rt_band_set_pixel(band, 3, 0, 0, NULL);
414  rt_band_set_pixel(band, 4, 0, 0, NULL);
415 
416  err = rt_raster_get_perimeter(rast, 0, &geom);
417  CU_ASSERT_EQUAL(err, ES_NONE);
418  CU_ASSERT(geom != NULL);
419  wkt = lwgeom_to_text(geom);
420  CU_ASSERT_STRING_EQUAL(wkt, "POLYGON((0 -1,5 -1,5 -5,0 -5,0 -1))");
421  rtdealloc(wkt);
422  lwgeom_free(geom);
423  geom = NULL;
424 
425  /* column 4 is NODATA */
426  /* pixel 4, 0 already set to NODATA */
427  rt_band_set_pixel(band, 4, 1, 0, NULL);
428  rt_band_set_pixel(band, 4, 2, 0, NULL);
429  rt_band_set_pixel(band, 4, 3, 0, NULL);
430  rt_band_set_pixel(band, 4, 4, 0, NULL);
431 
432  err = rt_raster_get_perimeter(rast, 0, &geom);
433  CU_ASSERT_EQUAL(err, ES_NONE);
434  CU_ASSERT(geom != NULL);
435  wkt = lwgeom_to_text(geom);
436  CU_ASSERT_STRING_EQUAL(wkt, "POLYGON((0 -1,4 -1,4 -5,0 -5,0 -1))");
437  rtdealloc(wkt);
438  lwgeom_free(geom);
439  geom = NULL;
440 
441  /* row 4 is NODATA */
442  rt_band_set_pixel(band, 0, 4, 0, NULL);
443  rt_band_set_pixel(band, 1, 4, 0, NULL);
444  rt_band_set_pixel(band, 2, 4, 0, NULL);
445  rt_band_set_pixel(band, 3, 4, 0, NULL);
446  /* pixel 4, 4 already set to NODATA */
447 
448  err = rt_raster_get_perimeter(rast, 0, &geom);
449  CU_ASSERT_EQUAL(err, ES_NONE);
450  CU_ASSERT(geom != NULL);
451  wkt = lwgeom_to_text(geom);
452  CU_ASSERT_STRING_EQUAL(wkt, "POLYGON((0 -1,4 -1,4 -4,0 -4,0 -1))");
453  rtdealloc(wkt);
454  lwgeom_free(geom);
455  geom = NULL;
456 
457  /* column 0 is NODATA */
458  /* pixel 0, 0 already set to NODATA*/
459  rt_band_set_pixel(band, 0, 1, 0, NULL);
460  rt_band_set_pixel(band, 0, 2, 0, NULL);
461  rt_band_set_pixel(band, 0, 3, 0, NULL);
462  /* pixel 0, 4 already set to NODATA*/
463 
464  err = rt_raster_get_perimeter(rast, 0, &geom);
465  CU_ASSERT_EQUAL(err, ES_NONE);
466  CU_ASSERT(geom != NULL);
467  wkt = lwgeom_to_text(geom);
468  CU_ASSERT_STRING_EQUAL(wkt, "POLYGON((1 -1,4 -1,4 -4,1 -4,1 -1))");
469  rtdealloc(wkt);
470  lwgeom_free(geom);
471  geom = NULL;
472 
473  /* columns 1 and 3 are NODATA */
474  /* pixel 1, 0 already set to NODATA */
475  rt_band_set_pixel(band, 1, 1, 0, NULL);
476  rt_band_set_pixel(band, 1, 2, 0, NULL);
477  rt_band_set_pixel(band, 1, 3, 0, NULL);
478  /* pixel 1, 4 already set to NODATA */
479  /* pixel 3, 0 already set to NODATA */
480  rt_band_set_pixel(band, 3, 1, 0, NULL);
481  rt_band_set_pixel(band, 3, 2, 0, NULL);
482  rt_band_set_pixel(band, 3, 3, 0, NULL);
483  /* pixel 3, 4 already set to NODATA */
484 
485  err = rt_raster_get_perimeter(rast, 0, &geom);
486  CU_ASSERT_EQUAL(err, ES_NONE);
487  CU_ASSERT(geom != NULL);
488  wkt = lwgeom_to_text(geom);
489  CU_ASSERT_STRING_EQUAL(wkt, "POLYGON((2 -1,3 -1,3 -4,2 -4,2 -1))");
490  rtdealloc(wkt);
491  lwgeom_free(geom);
492  geom = NULL;
493 
494  /* more pixels are NODATA */
495  rt_band_set_pixel(band, 2, 1, 0, NULL);
496  rt_band_set_pixel(band, 2, 3, 0, NULL);
497 
498  err = rt_raster_get_perimeter(rast, 0, &geom);
499  CU_ASSERT_EQUAL(err, ES_NONE);
500  CU_ASSERT(geom != NULL);
501  wkt = lwgeom_to_text(geom);
502  CU_ASSERT_STRING_EQUAL(wkt, "POLYGON((2 -2,3 -2,3 -3,2 -3,2 -2))");
503  rtdealloc(wkt);
504  lwgeom_free(geom);
505  geom = NULL;
506 
507  /* second band */
508  band = cu_add_band(rast, PT_32BUI, 1, 0);
509  CU_ASSERT(band != NULL);
510 
511  for (y = 0; y < maxY; y++) {
512  for (x = 0; x < maxX; x++) {
513  rt_band_set_pixel(band, x, y, 1, NULL);
514  }
515  }
516 
517  err = rt_raster_get_perimeter(rast, -1, &geom);
518  CU_ASSERT_EQUAL(err, ES_NONE);
519  CU_ASSERT(geom != NULL);
520  wkt = lwgeom_to_text(geom);
521  CU_ASSERT_STRING_EQUAL(wkt, "POLYGON((0 0,5 0,5 -5,0 -5,0 0))");
522  rtdealloc(wkt);
523  lwgeom_free(geom);
524  geom = NULL;
525 
526  cu_free_raster(rast);
527 }
528 
530  rt_raster rast;
531  rt_band band;
532  uint32_t x, y;
533  const int maxX = 10;
534  const int maxY = 10;
535  LWPOLY *poly = NULL;
536 
537  rast = rt_raster_new(maxX, maxY);
538  CU_ASSERT(rast != NULL);
539 
540  band = cu_add_band(rast, PT_32BUI, 1, 0);
541  CU_ASSERT(band != NULL);
542 
543  for (x = 0; x < maxX; x++) {
544  for (y = 0; y < maxY; y++) {
545  rt_band_set_pixel(band, x, y, 1, NULL);
546  }
547  }
548 
549  rt_band_set_pixel(band, 0, 0, 0, NULL);
550  rt_band_set_pixel(band, 3, 0, 0, NULL);
551  rt_band_set_pixel(band, 6, 0, 0, NULL);
552  rt_band_set_pixel(band, 9, 0, 0, NULL);
553  rt_band_set_pixel(band, 1, 2, 0, NULL);
554  rt_band_set_pixel(band, 4, 2, 0, NULL);
555  rt_band_set_pixel(band, 7, 2, 0, NULL);
556  rt_band_set_pixel(band, 2, 4, 0, NULL);
557  rt_band_set_pixel(band, 5, 4, 0, NULL);
558  rt_band_set_pixel(band, 8, 4, 0, NULL);
559  rt_band_set_pixel(band, 0, 6, 0, NULL);
560  rt_band_set_pixel(band, 3, 6, 0, NULL);
561  rt_band_set_pixel(band, 6, 6, 0, NULL);
562  rt_band_set_pixel(band, 9, 6, 0, NULL);
563  rt_band_set_pixel(band, 1, 8, 0, NULL);
564  rt_band_set_pixel(band, 4, 8, 0, NULL);
565  rt_band_set_pixel(band, 7, 8, 0, NULL);
566 
567  poly = rt_raster_pixel_as_polygon(rast, 1, 1);
568  CU_ASSERT(poly != NULL);
569  lwpoly_free(poly);
570 
571  cu_free_raster(rast);
572 }
573 
574 /* register tests */
575 void raster_geometry_suite_setup(void);
577 {
578  CU_pSuite suite = CU_add_suite("raster_geometry", NULL, NULL);
585 }
586 
double x
Definition: liblwgeom.h:336
#define LINETYPE
Definition: liblwgeom.h:71
static void test_raster_envelope_geom()
double MinY
Definition: librtcore.h:179
static void test_raster_surface()
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
Definition: lwout_wkt.c:655
raster
Be careful!! Zeros function&#39;s input parameter can be a (height x width) array, not (width x height): ...
Definition: rtrowdump.py:121
int npoints
Definition: liblwgeom.h:355
double MaxY
Definition: librtcore.h:180
double MaxX
Definition: librtcore.h:178
void rt_raster_set_skews(rt_raster raster, double skewX, double skewY)
Set skews about the X and Y axis.
Definition: rt_raster.c:168
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1050
band
Definition: ovdump.py:57
LWPOLY * lwgeom_as_lwpoly(const LWGEOM *lwgeom)
Definition: lwgeom.c:125
rt_errorstate rt_raster_get_convex_hull(rt_raster raster, LWGEOM **hull)
Get raster&#39;s convex hull.
Definition: rt_geometry.c:822
void cu_free_raster(rt_raster raster)
rt_band cu_add_band(rt_raster raster, rt_pixtype pixtype, int hasnodata, double nodataval)
rt_errorstate rt_raster_surface(rt_raster raster, int nband, LWMPOLY **surface)
Get a raster as a surface (multipolygon).
Definition: rt_geometry.c:355
void lwmpoly_free(LWMPOLY *mpoly)
Definition: lwmpoly.c:40
static void test_raster_convex_hull()
#define WKT_ISO
Definition: liblwgeom.h:1939
void lwpoly_free(LWPOLY *poly)
Definition: lwpoly.c:79
void rt_raster_set_scale(rt_raster raster, double scaleX, double scaleY)
Set scale in projection units.
Definition: rt_raster.c:137
void rt_raster_set_offsets(rt_raster raster, double x, double y)
Set insertion points in projection units.
Definition: rt_raster.c:199
#define PG_ADD_TEST(suite, testfunc)
static void test_raster_pixel_as_polygon()
static void test_raster_envelope()
static void test_raster_perimeter()
POINTARRAY ** rings
Definition: liblwgeom.h:441
LWPOLY * rt_raster_pixel_as_polygon(rt_raster raster, int x, int y)
Get a raster pixel as a polygon.
Definition: rt_geometry.c:629
rt_errorstate rt_raster_get_envelope_geom(rt_raster raster, LWGEOM **env)
Get raster&#39;s envelope as a geometry.
Definition: rt_geometry.c:689
int nrings
Definition: liblwgeom.h:439
int32_t rt_raster_get_srid(rt_raster raster)
Get raster&#39;s SRID.
Definition: rt_raster.c:356
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
Definition: rt_raster.c:48
void rtdealloc(void *mem)
Definition: rt_context.c:186
int32_t srid
Definition: liblwgeom.h:438
double MinX
Definition: librtcore.h:177
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:70
uint8_t type
Definition: liblwgeom.h:380
rt_errorstate rt_band_set_pixel(rt_band band, int x, int y, double val, int *converted)
Set single pixel&#39;s value.
Definition: rt_band.c:841
rt_errorstate rt_raster_get_perimeter(rt_raster raster, int nband, LWGEOM **perimeter)
Get raster perimeter.
Definition: rt_geometry.c:182
double y
Definition: liblwgeom.h:336
void raster_geometry_suite_setup(void)
static char * lwgeom_to_text(const LWGEOM *lwgeom)
LWGEOM * lwmpoly_as_lwgeom(const LWMPOLY *obj)
Definition: lwgeom.c:204
rt_errorstate rt_raster_get_envelope(rt_raster raster, rt_envelope *env)
Get raster&#39;s envelope.
Definition: rt_raster.c:873
int getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point)
Definition: lwgeom_api.c:231