PostGIS  2.4.9dev-r@@SVN_REVISION@@
cu_split.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * http://postgis.net
5  *
6  * Copyright (C) 2011-2015 Sandro Santilli <strk@kbt.io>
7  *
8  * This is free software; you can redistribute and/or modify it under
9  * the terms of the GNU General Public Licence. See the COPYING file.
10  *
11  **********************************************************************/
12 
13 #include "CUnit/Basic.h"
14 #include "cu_tester.h"
15 
16 #include "liblwgeom.h"
17 #include "liblwgeom_internal.h"
18 
20 {
21  LWLINE *line;
22  LWPOINT *point;
23  LWMLINE *coll;
24  int ret;
25 
26  /* Because i don't trust that much prior tests... ;) */
28 
30  CU_ASSERT_EQUAL(coll->ngeoms, 0);
31 
32  line = lwgeom_as_lwline(lwgeom_from_wkt("LINESTRING(0 0,5 5, 10 0)",
34  CU_ASSERT(line != NULL);
35 
37  "POINT(0 0)",
39  ret = lwline_split_by_point_to(line, point, coll);
40  CU_ASSERT_EQUAL(ret, 1);
41  CU_ASSERT_EQUAL(coll->ngeoms, 0);
42  lwpoint_free(point);
43 
45  "POINT(10 0)",
47  ret = lwline_split_by_point_to(line, point, coll);
48  CU_ASSERT_EQUAL(ret, 1);
49  CU_ASSERT_EQUAL(coll->ngeoms, 0);
50  lwpoint_free(point);
51 
53  "POINT(5 0)",
55  ret = lwline_split_by_point_to(line, point, coll);
56  CU_ASSERT_EQUAL(ret, 0);
57  CU_ASSERT_EQUAL(coll->ngeoms, 0);
58  lwpoint_free(point);
59 
61  "POINT(5 5)",
63  ret = lwline_split_by_point_to(line, point, coll);
64  CU_ASSERT_EQUAL(ret, 2);
65  CU_ASSERT_EQUAL(coll->ngeoms, 2);
66  lwpoint_free(point);
67 
69  "POINT(2 2)",
71  ret = lwline_split_by_point_to(line, point, coll);
72  CU_ASSERT_EQUAL(ret, 2);
73  CU_ASSERT_EQUAL(coll->ngeoms, 4);
74  lwpoint_free(point);
75 
77  lwline_free(line);
78 }
79 
80 static void test_lwgeom_split(void)
81 {
82  LWGEOM *geom, *blade, *ret;
83  char *wkt, *in_wkt;
84 
85  geom = lwgeom_from_wkt(
86 "MULTILINESTRING((-5 -2,0 0),(0 0,10 10))",
88  CU_ASSERT(geom != NULL);
89  blade = lwgeom_from_wkt(
90  "POINT(0 0)",
92  CU_ASSERT(blade != NULL);
93  ret = lwgeom_split(geom, blade);
94  CU_ASSERT(ret != NULL);
95  wkt = lwgeom_to_ewkt(ret);
96  in_wkt = "GEOMETRYCOLLECTION(LINESTRING(-5 -2,0 0),LINESTRING(0 0,10 10))";
97  if (strcmp(in_wkt, wkt))
98  fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt);
99  CU_ASSERT_STRING_EQUAL(wkt, in_wkt);
100  lwfree(wkt);
101  lwgeom_free(ret);
102  lwgeom_free(geom);
103  lwgeom_free(blade);
104 
105  /* See #1311 */
106  geom = lwgeom_from_wkt(
107  "LINESTRING(0 0,10 0,20 4,0 3)",
109  CU_ASSERT(geom != NULL);
110  blade = lwgeom_from_wkt("POINT(10 0)", LW_PARSER_CHECK_NONE);
111  ret = lwgeom_split(geom, blade);
112  CU_ASSERT(ret != NULL);
113  wkt = lwgeom_to_ewkt(ret);
114  in_wkt = "GEOMETRYCOLLECTION(LINESTRING(0 0,10 0),LINESTRING(10 0,20 4,0 3))";
115  if (strcmp(in_wkt, wkt))
116  fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt);
117  CU_ASSERT_STRING_EQUAL(wkt, in_wkt);
118  lwfree(wkt);
119  lwgeom_free(ret);
120  lwgeom_free(geom);
121  lwgeom_free(blade);
122 
123  /* See #2528 (1) -- memory leak test, needs valgrind to check */
124  geom = lwgeom_from_wkt("SRID=1;LINESTRING(0 1,10 1)", LW_PARSER_CHECK_NONE);
125  CU_ASSERT(geom != NULL);
126  blade = lwgeom_from_wkt("LINESTRING(7 0,7 3)", LW_PARSER_CHECK_NONE);
127  ret = lwgeom_split(geom, blade);
128  CU_ASSERT(ret != NULL);
129  wkt = lwgeom_to_ewkt(ret);
130  in_wkt = "SRID=1;GEOMETRYCOLLECTION(LINESTRING(0 1,7 1),LINESTRING(7 1,10 1))";
131  if (strcmp(in_wkt, wkt))
132  fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt);
133  CU_ASSERT_STRING_EQUAL(wkt, in_wkt);
134  lwfree(wkt);
135  lwgeom_free(ret);
136  lwgeom_free(geom);
137  lwgeom_free(blade);
138 
139  /* See #2528 (2) -- memory leak test, needs valgrind to check */
140  geom = lwgeom_from_wkt("SRID=1;POLYGON((0 1, 10 1, 10 10, 0 10, 0 1))", LW_PARSER_CHECK_NONE);
141  CU_ASSERT(geom != NULL);
142  blade = lwgeom_from_wkt("LINESTRING(7 0,7 20)", LW_PARSER_CHECK_NONE);
143  ret = lwgeom_split(geom, blade);
144  CU_ASSERT(ret != NULL);
145  wkt = lwgeom_to_ewkt(ret);
146  in_wkt = "SRID=1;GEOMETRYCOLLECTION(POLYGON((7 1,0 1,0 10,7 10,7 1)),POLYGON((7 10,10 10,10 1,7 1,7 10)))";
147  if (strcmp(in_wkt, wkt))
148  fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt);
149  CU_ASSERT_STRING_EQUAL(wkt, in_wkt);
150  lwfree(wkt);
151  lwgeom_free(ret);
152  lwgeom_free(geom);
153  lwgeom_free(blade);
154 
155  /* Split line by multiline */
156  geom = lwgeom_from_wkt("LINESTRING(0 0, 10 0)", LW_PARSER_CHECK_NONE);
157  CU_ASSERT_FATAL(geom != NULL);
158  blade = lwgeom_from_wkt("MULTILINESTRING((1 1,1 -1),(2 1,2 -1,3 -1,3 1))",
160  ret = lwgeom_split(geom, blade);
161  if ( ! ret ) printf("%s", cu_error_msg);
162  CU_ASSERT_FATAL(ret != NULL);
163  wkt = lwgeom_to_ewkt(ret);
164  CU_ASSERT_FATAL(wkt != NULL);
165  in_wkt = "GEOMETRYCOLLECTION(LINESTRING(0 0,1 0),LINESTRING(1 0,2 0),LINESTRING(2 0,3 0),LINESTRING(3 0,10 0))";
166  if (strcmp(in_wkt, wkt))
167  fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt);
168  CU_ASSERT_STRING_EQUAL(wkt, in_wkt);
169  lwfree(wkt);
170  lwgeom_free(ret);
171  lwgeom_free(geom);
172  lwgeom_free(blade);
173 
174  /* Split line by polygon (boundary) */
175  geom = lwgeom_from_wkt("LINESTRING(0 0, 10 0)", LW_PARSER_CHECK_NONE);
176  CU_ASSERT_FATAL(geom != NULL);
177  blade = lwgeom_from_wkt(
178 "POLYGON((1 -2,1 1,2 1,2 -1,3 -1,3 1,11 1,11 -2,1 -2))",
180  ret = lwgeom_split(geom, blade);
181  if ( ! ret ) printf("%s", cu_error_msg);
182  CU_ASSERT_FATAL(ret != NULL);
183  wkt = lwgeom_to_ewkt(ret);
184  CU_ASSERT_FATAL(wkt != NULL);
185  in_wkt = "GEOMETRYCOLLECTION(LINESTRING(0 0,1 0),LINESTRING(1 0,2 0),LINESTRING(2 0,3 0),LINESTRING(3 0,10 0))";
186  if (strcmp(in_wkt, wkt))
187  fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt);
188  CU_ASSERT_STRING_EQUAL(wkt, in_wkt);
189  lwfree(wkt);
190  lwgeom_free(ret);
191  lwgeom_free(geom);
192  lwgeom_free(blade);
193 
194  /* Split line by EMPTY polygon (boundary) */
195  geom = lwgeom_from_wkt("LINESTRING(0 0, 10 0)", LW_PARSER_CHECK_NONE);
196  CU_ASSERT_FATAL(geom != NULL);
197  blade = lwgeom_from_wkt("POLYGON EMPTY", LW_PARSER_CHECK_NONE);
198  ret = lwgeom_split(geom, blade);
199  if ( ! ret ) printf("%s", cu_error_msg);
200  CU_ASSERT_FATAL(ret != NULL);
201  wkt = lwgeom_to_ewkt(ret);
202  CU_ASSERT_FATAL(wkt != NULL);
203  in_wkt = "GEOMETRYCOLLECTION(LINESTRING(0 0,10 0))";
204  if (strcmp(in_wkt, wkt))
205  fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt);
206  CU_ASSERT_STRING_EQUAL(wkt, in_wkt);
207  lwfree(wkt);
208  lwgeom_free(ret);
209  lwgeom_free(geom);
210  lwgeom_free(blade);
211 
212  /* Split line by multipolygon (boundary) */
213  geom = lwgeom_from_wkt("LINESTRING(0 0, 10 0)", LW_PARSER_CHECK_NONE);
214  CU_ASSERT_FATAL(geom != NULL);
215  blade = lwgeom_from_wkt(
216 "MULTIPOLYGON(((1 -1,1 1,2 1,2 -1,1 -1)),((3 -1,3 1,11 1,11 -1,3 -1)))",
218  ret = lwgeom_split(geom, blade);
219  if ( ! ret ) printf("%s", cu_error_msg);
220  CU_ASSERT_FATAL(ret != NULL);
221  wkt = lwgeom_to_ewkt(ret);
222  CU_ASSERT_FATAL(wkt != NULL);
223  in_wkt = "GEOMETRYCOLLECTION(LINESTRING(0 0,1 0),LINESTRING(1 0,2 0),LINESTRING(2 0,3 0),LINESTRING(3 0,10 0))";
224  if (strcmp(in_wkt, wkt))
225  fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt);
226  CU_ASSERT_STRING_EQUAL(wkt, in_wkt);
227  lwfree(wkt);
228  lwgeom_free(ret);
229  lwgeom_free(geom);
230  lwgeom_free(blade);
231 
232  /* Split line by multipoint */
233  geom = lwgeom_from_wkt("LINESTRING(0 0, 10 0)", LW_PARSER_CHECK_NONE);
234  CU_ASSERT_FATAL(geom != NULL);
235  blade = lwgeom_from_wkt("MULTIPOINT(2 0,8 0,4 0)", LW_PARSER_CHECK_NONE);
236  ret = lwgeom_split(geom, blade);
237  if ( ! ret ) printf("%s", cu_error_msg);
238  CU_ASSERT_FATAL(ret != NULL);
239  wkt = lwgeom_to_ewkt(ret);
240  CU_ASSERT_FATAL(wkt != NULL);
241  in_wkt = "GEOMETRYCOLLECTION(LINESTRING(8 0,10 0),LINESTRING(0 0,2 0),LINESTRING(4 0,8 0),LINESTRING(2 0,4 0))";
242  if (strcmp(in_wkt, wkt))
243  fprintf(stderr, "\nExp: %s\nObt: %s\n", in_wkt, wkt);
244  CU_ASSERT_STRING_EQUAL(wkt, in_wkt);
245  lwfree(wkt);
246  lwgeom_free(ret);
247  lwgeom_free(geom);
248  lwgeom_free(blade);
249 
250  /* See #3401 -- robustness issue */
251  geom = lwgeom_from_wkt("LINESTRING(-180 0,0 0)", LW_PARSER_CHECK_NONE);
252  CU_ASSERT(geom != NULL);
253  blade = lwgeom_from_wkt("POINT(-20 0)", LW_PARSER_CHECK_NONE);
254  ret = lwgeom_split(geom, blade);
255  CU_ASSERT(ret != NULL);
256  {
257  LWCOLLECTION *split = lwgeom_as_lwcollection(ret);
258  LWLINE *l1, *l2;
259  POINT2D pt;
260  CU_ASSERT(split != NULL);
261  l1 = lwgeom_as_lwline(split->geoms[0]);
262  CU_ASSERT(l1 != NULL);
263  getPoint2d_p(l1->points, 1, &pt);
264  ASSERT_DOUBLE_EQUAL(pt.x, -20);
265  ASSERT_DOUBLE_EQUAL(pt.y, 0);
266  l2 = lwgeom_as_lwline(split->geoms[1]);
267  CU_ASSERT(l2 != NULL);
268  getPoint2d_p(l2->points, 0, &pt);
269  ASSERT_DOUBLE_EQUAL(pt.x, -20);
270  ASSERT_DOUBLE_EQUAL(pt.y, 0);
271  }
272  lwgeom_free(ret);
273  lwgeom_free(geom);
274  lwgeom_free(blade);
275 }
276 
277 
278 /*
279 ** Used by test harness to register the tests in this file.
280 */
281 void split_suite_setup(void);
283 {
284  CU_pSuite suite = CU_add_suite("split", NULL, NULL);
287 }
void lwfree(void *mem)
Definition: lwutil.c:244
char * lwgeom_to_ewkt(const LWGEOM *lwgeom)
Return an alloced string.
Definition: lwgeom.c:518
void lwpoint_free(LWPOINT *pt)
Definition: lwpoint.c:213
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1099
void lwline_free(LWLINE *line)
Definition: lwline.c:76
LWGEOM * lwgeom_from_wkt(const char *wkt, const char check)
Definition: lwin_wkt.c:904
LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
Definition: lwgeom.c:129
LWMLINE * lwmline_construct_empty(int srid, char hasz, char hasm)
Definition: lwmline.c:38
int ngeoms
Definition: liblwgeom.h:481
#define LW_PARSER_CHECK_NONE
Definition: liblwgeom.h:2013
double x
Definition: liblwgeom.h:328
void cu_error_msg_reset()
LWGEOM ** geoms
Definition: liblwgeom.h:509
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:188
#define PG_ADD_TEST(suite, testfunc)
void split_suite_setup(void)
Definition: cu_split.c:282
static void test_lwline_split_by_point_to(void)
Definition: cu_split.c:19
double y
Definition: liblwgeom.h:328
int getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point)
Definition: lwgeom_api.c:347
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition: lwgeom.c:138
LWCOLLECTION * lwgeom_as_lwcollection(const LWGEOM *lwgeom)
Definition: lwgeom.c:192
void lwcollection_free(LWCOLLECTION *col)
Definition: lwcollection.c:340
#define ASSERT_DOUBLE_EQUAL(o, e)
char cu_error_msg[MAX_CUNIT_ERROR_LENGTH+1]
static void test_lwgeom_split(void)
Definition: cu_split.c:80
This library is the generic geometry handling section of PostGIS.
int lwline_split_by_point_to(const LWLINE *ln, const LWPOINT *pt, LWMLINE *to)
Split a line by a point and push components to the provided multiline.
LWGEOM * lwgeom_split(const LWGEOM *lwgeom_in, const LWGEOM *blade_in)
POINTARRAY * points
Definition: liblwgeom.h:422