PostGIS  2.4.9dev-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 
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 
323  rtdealloc(wkt);
324  lwmpoly_free(mpoly);
325  mpoly = NULL;
326 
327  /* plus 3,3 NODATA */
328  rt_band_set_pixel(band, 3, 3, 0, NULL);
329 
330  err = rt_raster_surface(rast, 0, &mpoly);
331  CU_ASSERT_EQUAL(err, ES_NONE);
332  CU_ASSERT(mpoly != NULL);
333  wkt = lwgeom_to_text(lwmpoly_as_lwgeom(mpoly));
334 
335  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)))");
336 
337  rtdealloc(wkt);
338  lwmpoly_free(mpoly);
339  mpoly = NULL;
340 
341  /* plus 4,4 NODATA */
342  rt_band_set_pixel(band, 4, 4, 0, NULL);
343 
344  err = rt_raster_surface(rast, 0, &mpoly);
345  CU_ASSERT_EQUAL(err, ES_NONE);
346  CU_ASSERT(mpoly != NULL);
347  wkt = lwgeom_to_text(lwmpoly_as_lwgeom(mpoly));
348  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)))");
349  rtdealloc(wkt);
350  lwmpoly_free(mpoly);
351  mpoly = NULL;
352 
353  /* a whole lot more NODATA */
354  rt_band_set_pixel(band, 4, 0, 0, NULL);
355  rt_band_set_pixel(band, 3, 1, 0, NULL);
356  rt_band_set_pixel(band, 1, 3, 0, NULL);
357  rt_band_set_pixel(band, 0, 4, 0, NULL);
358 
359  err = rt_raster_surface(rast, 0, &mpoly);
360  CU_ASSERT_EQUAL(err, ES_NONE);
361  CU_ASSERT(mpoly != NULL);
362  wkt = lwgeom_to_text(lwmpoly_as_lwgeom(mpoly));
363  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)))");
364  rtdealloc(wkt);
365  lwmpoly_free(mpoly);
366  mpoly = NULL;
367 
368  cu_free_raster(rast);
369 }
370 
371 static void test_raster_perimeter() {
372  rt_raster rast;
373  rt_band band;
374  const int maxX = 5;
375  const int maxY = 5;
376  int x, y;
377  char *wkt = NULL;
378  LWGEOM *geom = NULL;
379  int err;
380 
381  rast = rt_raster_new(maxX, maxY);
382  CU_ASSERT(rast != NULL);
383 
384  rt_raster_set_offsets(rast, 0, 0);
385  rt_raster_set_scale(rast, 1, -1);
386 
387  band = cu_add_band(rast, PT_32BUI, 1, 0);
388  CU_ASSERT(band != NULL);
389 
390  for (y = 0; y < maxY; y++) {
391  for (x = 0; x < maxX; x++) {
392  rt_band_set_pixel(band, x, y, 1, NULL);
393  }
394  }
395 
396  err = rt_raster_get_perimeter(rast, -1, &geom);
397  CU_ASSERT_EQUAL(err, ES_NONE);
398  CU_ASSERT(geom != NULL);
399  wkt = lwgeom_to_text(geom);
400  CU_ASSERT_STRING_EQUAL(wkt, "POLYGON((0 0,5 0,5 -5,0 -5,0 0))");
401  rtdealloc(wkt);
402  lwgeom_free(geom);
403  geom = NULL;
404 
405  /* row 0 is NODATA */
406  rt_band_set_pixel(band, 0, 0, 0, NULL);
407  rt_band_set_pixel(band, 1, 0, 0, NULL);
408  rt_band_set_pixel(band, 2, 0, 0, NULL);
409  rt_band_set_pixel(band, 3, 0, 0, NULL);
410  rt_band_set_pixel(band, 4, 0, 0, NULL);
411 
412  err = rt_raster_get_perimeter(rast, 0, &geom);
413  CU_ASSERT_EQUAL(err, ES_NONE);
414  CU_ASSERT(geom != NULL);
415  wkt = lwgeom_to_text(geom);
416  CU_ASSERT_STRING_EQUAL(wkt, "POLYGON((0 -1,5 -1,5 -5,0 -5,0 -1))");
417  rtdealloc(wkt);
418  lwgeom_free(geom);
419  geom = NULL;
420 
421  /* column 4 is NODATA */
422  /* pixel 4, 0 already set to NODATA */
423  rt_band_set_pixel(band, 4, 1, 0, NULL);
424  rt_band_set_pixel(band, 4, 2, 0, NULL);
425  rt_band_set_pixel(band, 4, 3, 0, NULL);
426  rt_band_set_pixel(band, 4, 4, 0, NULL);
427 
428  err = rt_raster_get_perimeter(rast, 0, &geom);
429  CU_ASSERT_EQUAL(err, ES_NONE);
430  CU_ASSERT(geom != NULL);
431  wkt = lwgeom_to_text(geom);
432  CU_ASSERT_STRING_EQUAL(wkt, "POLYGON((0 -1,4 -1,4 -5,0 -5,0 -1))");
433  rtdealloc(wkt);
434  lwgeom_free(geom);
435  geom = NULL;
436 
437  /* row 4 is NODATA */
438  rt_band_set_pixel(band, 0, 4, 0, NULL);
439  rt_band_set_pixel(band, 1, 4, 0, NULL);
440  rt_band_set_pixel(band, 2, 4, 0, NULL);
441  rt_band_set_pixel(band, 3, 4, 0, NULL);
442  /* pixel 4, 4 already set to NODATA */
443 
444  err = rt_raster_get_perimeter(rast, 0, &geom);
445  CU_ASSERT_EQUAL(err, ES_NONE);
446  CU_ASSERT(geom != NULL);
447  wkt = lwgeom_to_text(geom);
448  CU_ASSERT_STRING_EQUAL(wkt, "POLYGON((0 -1,4 -1,4 -4,0 -4,0 -1))");
449  rtdealloc(wkt);
450  lwgeom_free(geom);
451  geom = NULL;
452 
453  /* column 0 is NODATA */
454  /* pixel 0, 0 already set to NODATA*/
455  rt_band_set_pixel(band, 0, 1, 0, NULL);
456  rt_band_set_pixel(band, 0, 2, 0, NULL);
457  rt_band_set_pixel(band, 0, 3, 0, NULL);
458  /* pixel 0, 4 already set to NODATA*/
459 
460  err = rt_raster_get_perimeter(rast, 0, &geom);
461  CU_ASSERT_EQUAL(err, ES_NONE);
462  CU_ASSERT(geom != NULL);
463  wkt = lwgeom_to_text(geom);
464  CU_ASSERT_STRING_EQUAL(wkt, "POLYGON((1 -1,4 -1,4 -4,1 -4,1 -1))");
465  rtdealloc(wkt);
466  lwgeom_free(geom);
467  geom = NULL;
468 
469  /* columns 1 and 3 are NODATA */
470  /* pixel 1, 0 already set to NODATA */
471  rt_band_set_pixel(band, 1, 1, 0, NULL);
472  rt_band_set_pixel(band, 1, 2, 0, NULL);
473  rt_band_set_pixel(band, 1, 3, 0, NULL);
474  /* pixel 1, 4 already set to NODATA */
475  /* pixel 3, 0 already set to NODATA */
476  rt_band_set_pixel(band, 3, 1, 0, NULL);
477  rt_band_set_pixel(band, 3, 2, 0, NULL);
478  rt_band_set_pixel(band, 3, 3, 0, NULL);
479  /* pixel 3, 4 already set to NODATA */
480 
481  err = rt_raster_get_perimeter(rast, 0, &geom);
482  CU_ASSERT_EQUAL(err, ES_NONE);
483  CU_ASSERT(geom != NULL);
484  wkt = lwgeom_to_text(geom);
485  CU_ASSERT_STRING_EQUAL(wkt, "POLYGON((2 -1,3 -1,3 -4,2 -4,2 -1))");
486  rtdealloc(wkt);
487  lwgeom_free(geom);
488  geom = NULL;
489 
490  /* more pixels are NODATA */
491  rt_band_set_pixel(band, 2, 1, 0, NULL);
492  rt_band_set_pixel(band, 2, 3, 0, NULL);
493 
494  err = rt_raster_get_perimeter(rast, 0, &geom);
495  CU_ASSERT_EQUAL(err, ES_NONE);
496  CU_ASSERT(geom != NULL);
497  wkt = lwgeom_to_text(geom);
498  CU_ASSERT_STRING_EQUAL(wkt, "POLYGON((2 -2,3 -2,3 -3,2 -3,2 -2))");
499  rtdealloc(wkt);
500  lwgeom_free(geom);
501  geom = NULL;
502 
503  /* second band */
504  band = cu_add_band(rast, PT_32BUI, 1, 0);
505  CU_ASSERT(band != NULL);
506 
507  for (y = 0; y < maxY; y++) {
508  for (x = 0; x < maxX; x++) {
509  rt_band_set_pixel(band, x, y, 1, NULL);
510  }
511  }
512 
513  err = rt_raster_get_perimeter(rast, -1, &geom);
514  CU_ASSERT_EQUAL(err, ES_NONE);
515  CU_ASSERT(geom != NULL);
516  wkt = lwgeom_to_text(geom);
517  CU_ASSERT_STRING_EQUAL(wkt, "POLYGON((0 0,5 0,5 -5,0 -5,0 0))");
518  rtdealloc(wkt);
519  lwgeom_free(geom);
520  geom = NULL;
521 
522  cu_free_raster(rast);
523 }
524 
526  rt_raster rast;
527  rt_band band;
528  uint32_t x, y;
529  const int maxX = 10;
530  const int maxY = 10;
531  LWPOLY *poly = NULL;
532 
533  rast = rt_raster_new(maxX, maxY);
534  CU_ASSERT(rast != NULL);
535 
536  band = cu_add_band(rast, PT_32BUI, 1, 0);
537  CU_ASSERT(band != NULL);
538 
539  for (x = 0; x < maxX; x++) {
540  for (y = 0; y < maxY; y++) {
541  rt_band_set_pixel(band, x, y, 1, NULL);
542  }
543  }
544 
545  rt_band_set_pixel(band, 0, 0, 0, NULL);
546  rt_band_set_pixel(band, 3, 0, 0, NULL);
547  rt_band_set_pixel(band, 6, 0, 0, NULL);
548  rt_band_set_pixel(band, 9, 0, 0, NULL);
549  rt_band_set_pixel(band, 1, 2, 0, NULL);
550  rt_band_set_pixel(band, 4, 2, 0, NULL);
551  rt_band_set_pixel(band, 7, 2, 0, NULL);
552  rt_band_set_pixel(band, 2, 4, 0, NULL);
553  rt_band_set_pixel(band, 5, 4, 0, NULL);
554  rt_band_set_pixel(band, 8, 4, 0, NULL);
555  rt_band_set_pixel(band, 0, 6, 0, NULL);
556  rt_band_set_pixel(band, 3, 6, 0, NULL);
557  rt_band_set_pixel(band, 6, 6, 0, NULL);
558  rt_band_set_pixel(band, 9, 6, 0, NULL);
559  rt_band_set_pixel(band, 1, 8, 0, NULL);
560  rt_band_set_pixel(band, 4, 8, 0, NULL);
561  rt_band_set_pixel(band, 7, 8, 0, NULL);
562 
563  poly = rt_raster_pixel_as_polygon(rast, 1, 1);
564  CU_ASSERT(poly != NULL);
565  lwpoly_free(poly);
566 
567  cu_free_raster(rast);
568 }
569 
570 /* register tests */
571 void raster_geometry_suite_setup(void);
573 {
574  CU_pSuite suite = CU_add_suite("raster_geometry", NULL, NULL);
581 }
582 
double x
Definition: liblwgeom.h:352
#define LINETYPE
Definition: liblwgeom.h:86
static void test_raster_envelope_geom()
double MinY
Definition: librtcore.h:167
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:669
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:371
double MaxY
Definition: librtcore.h:168
double MaxX
Definition: librtcore.h:166
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:1099
band
Definition: ovdump.py:57
LWPOLY * lwgeom_as_lwpoly(const LWGEOM *lwgeom)
Definition: lwgeom.c:174
rt_errorstate rt_raster_get_convex_hull(rt_raster raster, LWGEOM **hull)
Get raster&#39;s convex hull.
Definition: rt_geometry.c:803
unsigned int uint32_t
Definition: uthash.h:78
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:53
static void test_raster_convex_hull()
#define WKT_ISO
Definition: liblwgeom.h:2083
void lwpoly_free(LWPOLY *poly)
Definition: lwpoly.c:174
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:457
LWPOLY * rt_raster_pixel_as_polygon(rt_raster raster, int x, int y)
Get a raster pixel as a polygon.
Definition: rt_geometry.c:610
rt_errorstate rt_raster_get_envelope_geom(rt_raster raster, LWGEOM **env)
Get raster&#39;s envelope as a geometry.
Definition: rt_geometry.c:670
int nrings
Definition: liblwgeom.h:455
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:454
double MinX
Definition: librtcore.h:165
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:85
uint8_t type
Definition: liblwgeom.h:396
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:352
void raster_geometry_suite_setup(void)
static char * lwgeom_to_text(const LWGEOM *lwgeom)
LWGEOM * lwmpoly_as_lwgeom(const LWMPOLY *obj)
Definition: lwgeom.c:253
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:122