PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
cu_iterator.c
Go to the documentation of this file.
1/**********************************************************************
2 *
3 * PostGIS - Spatial Types for PostgreSQL
4 * http://postgis.net
5 * Copyright 2015 Daniel Baston
6 *
7 * This is free software; you can redistribute and/or modify it under
8 * the terms of the GNU General Public Licence. See the COPYING file.
9 *
10 **********************************************************************/
11
12#include "CUnit/Basic.h"
13#include "cu_tester.h"
14
15#include "../liblwgeom_internal.h"
16
17char* inputs[] =
18{
19 "POINT (17 253)",
20 "POINT Z (17 253 018)",
21 "TRIANGLE ((0 0, 10 0, 10 10, 0 0))",
22 "LINESTRING (17 253, -44 28, 33 11, 26 44)",
23 "LINESTRING M (17 253 0, -44 28 1, 33 11 2, 26 44 3)",
24 "POLYGON((26426 65078,26531 65242,26075 65136,26096 65427,26426 65078))",
25 "MULTIPOINT ((1 1), (1 1))",
26 "MULTILINESTRING Z ((1 1 0, 2 2 0), (3 3 1, 4 4 1))",
27 "MULTIPOLYGON (((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 1 2, 2 2, 2 1, 1 1)), ((20 20, 20 30, 30 30, 20 20)))",
28 "POINT EMPTY",
29 "LINESTRING M EMPTY",
30 "POLYGON Z EMPTY",
31 "GEOMETRYCOLLECTION EMPTY",
32 "GEOMETRYCOLLECTION (MULTIPOINT ((14 80), (22 12)))",
33 "GEOMETRYCOLLECTION (POINT (3 7), LINESTRING (0 0, 14 3), GEOMETRYCOLLECTION(POINT (2 8)))",
34 "GEOMETRYCOLLECTION (POINT (3 7), GEOMETRYCOLLECTION(MULTIPOINT ((2 8))))",
35 "GEOMETRYCOLLECTION (POINT (3 7), GEOMETRYCOLLECTION(LINESTRING (2 8, 4 3), POLYGON EMPTY, MULTIPOINT ((2 8), (17 3), EMPTY)))",
36 "CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3)",
37 "COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0))",
38 "MULTICURVE((0 0, 5 5),CIRCULARSTRING(4 0, 4 4, 8 4))",
39 "CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0)), LINESTRING (0.1 0.1, 0.3 0.1, 0.3 0.3, 0.1 0.1) )",
40 "MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(0 0, 4 0, 4 4, 0 4, 0 0),(1 1, 3 3, 3 1, 1 1)),((10 10, 14 12, 11 10, 10 10),(11 11, 11.5 11, 11 11.5, 11 11)))",
41 "POLYHEDRALSURFACE( ((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)), ((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)), ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)), ((1 1 0, 1 1 1, 1 0 1, 1 0 0, 1 1 0)), ((0 1 0, 0 1 1, 1 1 1, 1 1 0, 0 1 0)), ((0 0 1, 1 0 1, 1 1 1, 0 1 1, 0 0 1)) )",
42 "TIN(((80 130,50 160,80 70,80 130)),((50 160,10 190,10 70,50 160)), ((80 70,50 160,10 70,80 70)),((120 160,120 190,50 160,120 160)), ((120 190,10 190,50 160,120 190)))"
43};
44
45static uint32_t
47{
48 POINT4D p;
49 uint32_t count = 0;
51
52 while (lwpointiterator_has_next(it))
53 {
54 CU_ASSERT_TRUE(lwpointiterator_next(it, &p));
55 count++;
56 }
57
59
60 return count;
61}
62
63static void
65{
66 char* types_visited = lwalloc(NUMTYPES * sizeof(char));
67 memset(types_visited, LW_FALSE, NUMTYPES * sizeof(char));
68
69 uint32_t i;
70 for (i = 0; i < sizeof(inputs)/sizeof(char*); i++)
71 {
73 types_visited[lwgeom_get_type(input)] = LW_TRUE;
74
75 uint32_t itercount = count_points_using_iterator(input);
76
77 CU_ASSERT_EQUAL(lwgeom_count_vertices(input), itercount);
78
79 lwgeom_free(input);
80 }
81
82 /* Assert that every valid LWGEOM type has been tested */
83 for (i = 1; i < NUMTYPES; i++)
84 {
85 CU_ASSERT_TRUE(types_visited[i]);
86 }
87
88 lwfree(types_visited);
89}
90
91static void
93{
96
97 POINT4D p;
98 p.x = 3.2;
99 p.y = 4.8;
100
101 CU_ASSERT_EQUAL(LW_FAILURE, lwpointiterator_modify_next(it, &p));
102
103 lwgeom_free(input);
105}
106
107static void
109{
110 uint32_t i;
111 uint32_t j = 0;
112
113 for (i = 0; i < sizeof(inputs)/sizeof(char*); i++)
114 {
118
119 while (lwpointiterator_has_next(it1))
120 {
121 /* Make up a coordinate, assign it to the next spot in it1,
122 * read it from it2 to verify that it was assigned correctly. */
123 POINT4D p1, p2;
124 p1.x = sqrt(j++);
125 p1.y = sqrt(j++);
126 p1.z = sqrt(j++);
127 p1.m = sqrt(j++);
128
129 CU_ASSERT_TRUE(lwpointiterator_modify_next(it1, &p1));
130 CU_ASSERT_TRUE(lwpointiterator_next(it2, &p2));
131
132 CU_ASSERT_EQUAL(p1.x, p2.x);
133 CU_ASSERT_EQUAL(p1.y, p2.y);
134
135 if (lwgeom_has_z(input))
136 CU_ASSERT_EQUAL(p1.z, p2.z);
137
138 if (lwgeom_has_m(input))
139 CU_ASSERT_EQUAL(p1.m, p2.m);
140 }
141
142 lwgeom_free(input);
143
146 }
147}
148
149static void
151{
152 LWGEOM* g = lwgeom_from_wkt("GEOMETRYCOLLECTION (POINT (3 7), GEOMETRYCOLLECTION(LINESTRING (2 8, 4 3), POLYGON EMPTY, MULTIPOINT ((2 8), (17 3), EMPTY)))", LW_PARSER_CHECK_NONE);
153
155 lwpointiterator_next(it, NULL);
156 lwpointiterator_next(it, NULL);
157
159 lwgeom_free(g);
160}
161
162static void
164{
165 uint32_t i = 0;
166 LWGEOM* g = lwgeom_from_wkt("GEOMETRYCOLLECTION (POINT (3 7), GEOMETRYCOLLECTION(LINESTRING (2 8, 4 3), POLYGON EMPTY, MULTIPOINT ((2 8), (17 3), EMPTY)))", LW_PARSER_CHECK_NONE);
169
170 /* Flip the coordinates of the 3rd point */
171 while(lwpointiterator_has_next(it1))
172 {
173 if (i == 2)
174 {
175 POINT4D p;
176 double tmp;
177
178 lwpointiterator_peek(it1, &p);
179 tmp = p.x;
180 p.x = p.y;
181 p.y = tmp;
182
184 }
185 else
186 {
187 lwpointiterator_next(it1, NULL);
188 }
189 i++;
190 }
191 CU_ASSERT_EQUAL(5, i); /* Every point was visited */
193
194 /* Verify that the points are as expected */
195 POINT2D points[] =
196 {
197 { .x = 3, .y = 7 },
198 { .x = 2, .y = 8 },
199 { .x = 3, .y = 4 },
200 { .x = 2, .y = 8 },
201 { .x = 17, .y = 3}
202 };
203
204 for (i = 0; lwpointiterator_has_next(it2); i++)
205 {
206 POINT4D p;
207
208 lwpointiterator_next(it2, &p);
209
210 CU_ASSERT_EQUAL(p.x, points[i].x);
211 CU_ASSERT_EQUAL(p.y, points[i].y);
212 }
213
215 lwgeom_free(g);
216}
217
218static void
220{
221 uint32_t i = 0;
222 LWGEOM* g = lwgeom_from_wkt("GEOMETRYCOLLECTION (POLYGON ((0 0, 0 10, 10 10, 0 10, 0 0), (1 1, 1 2, 2 2, 2 1, 1 1)), MULTIPOINT((4 4), (3 3)))", LW_PARSER_CHECK_NONE);
223
224 POINT2D points[] = { {.x = 0, .y = 0},
225 {.x = 0, .y = 10},
226 {.x = 10, .y = 10},
227 {.x = 0, .y = 10},
228 {.x = 0, .y = 0},
229 {.x = 1, .y = 1},
230 {.x = 1, .y = 2},
231 {.x = 2, .y = 2},
232 {.x = 2, .y = 1},
233 {.x = 1, .y = 1},
234 {.x = 4, .y = 4},
235 {.x = 3, .y = 3}
236 };
237
239 POINT4D p;
240
241 for (i = 0; lwpointiterator_has_next(it); i++)
242 {
243 CU_ASSERT_EQUAL(LW_SUCCESS, lwpointiterator_next(it, &p));
244 CU_ASSERT_EQUAL(p.x, points[i].x);
245 CU_ASSERT_EQUAL(p.y, points[i].y);
246 }
247
249 lwgeom_free(g);
250}
251
252/*
253** Used by test harness to register the tests in this file.
254*/
255void iterator_suite_setup(void);
257{
258 CU_pSuite suite = CU_add_suite("iterator", NULL, NULL);
265}
static void test_cannot_modify_read_only(void)
Definition cu_iterator.c:92
char * inputs[]
Definition cu_iterator.c:17
void iterator_suite_setup(void)
static void test_no_memory_leaked_when_iterator_is_partially_used(void)
static void test_point_count(void)
Definition cu_iterator.c:64
static void test_mixed_rw_access(void)
static void test_modification(void)
static uint32_t count_points_using_iterator(LWGEOM *g)
Definition cu_iterator.c:46
static void test_ordering(void)
#define PG_ADD_TEST(suite, testfunc)
#define LW_FALSE
Definition liblwgeom.h:94
#define LW_FAILURE
Definition liblwgeom.h:96
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1246
#define LW_PARSER_CHECK_NONE
Definition liblwgeom.h:2149
LWPOINTITERATOR * lwpointiterator_create(const LWGEOM *g)
Create a new LWPOINTITERATOR over supplied LWGEOM*.
Definition lwiterator.c:243
int lwpointiterator_next(LWPOINTITERATOR *s, POINT4D *p)
Attempts to assign the next point in the iterator to p, and advances the iterator to the next point.
Definition lwiterator.c:210
LWPOINTITERATOR * lwpointiterator_create_rw(LWGEOM *g)
Create a new LWPOINTITERATOR over supplied LWGEOM* Supports modification of coordinates during iterat...
Definition lwiterator.c:252
#define LW_SUCCESS
Definition liblwgeom.h:97
int lwpointiterator_peek(LWPOINTITERATOR *s, POINT4D *p)
Attempts to assigns the next point in the iterator to p.
Definition lwiterator.c:193
void lwpointiterator_destroy(LWPOINTITERATOR *s)
Free all memory associated with the iterator.
Definition lwiterator.c:268
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition lwgeom.c:962
void * lwalloc(size_t size)
Definition lwutil.c:227
uint32_t lwgeom_count_vertices(const LWGEOM *geom)
Count the total number of vertices in any LWGEOM.
Definition lwgeom.c:1337
int lwpointiterator_modify_next(LWPOINTITERATOR *s, const POINT4D *p)
Attempts to replace the next point int the iterator with p, and advances the iterator to the next poi...
Definition lwiterator.c:224
void lwfree(void *mem)
Definition lwutil.c:248
int lwpointiterator_has_next(LWPOINTITERATOR *s)
Returns LW_TRUE if there is another point available in the iterator.
Definition lwiterator.c:202
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:93
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
Definition lwgeom.c:969
#define NUMTYPES
Definition liblwgeom.h:118
LWGEOM * lwgeom_from_wkt(const char *wkt, const char check)
Definition lwin_wkt.c:940
static uint32_t lwgeom_get_type(const LWGEOM *geom)
Return LWTYPE number.
Definition lwinline.h:141
double y
Definition liblwgeom.h:390
double x
Definition liblwgeom.h:390
double m
Definition liblwgeom.h:414
double x
Definition liblwgeom.h:414
double z
Definition liblwgeom.h:414
double y
Definition liblwgeom.h:414