PostGIS  3.0.6dev-r@@SVN_REVISION@@
cu_lwstroke.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * http://postgis.net
5  *
6  * Copyright (C) 2017 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 <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <math.h> /* for M_PI */
17 #include "CUnit/Basic.h"
18 #include "CUnit/CUnit.h"
19 
20 #include "liblwgeom_internal.h"
21 #include "cu_tester.h"
22 
23 /* #define SKIP_TEST_RETAIN_ANGLE 1 */
24 
25 
26 static LWGEOM* lwgeom_from_text(const char *str)
27 {
30  return NULL;
31  return r.geom;
32 }
33 
34 static char* lwgeom_to_text(const LWGEOM *geom, int prec)
35 {
36  gridspec grid;
37  LWGEOM *gridded;
38  char *wkt;
39 
40  memset(&grid, 0, sizeof(gridspec));
41  grid.xsize = prec;
42  grid.ysize = prec;
43  gridded = lwgeom_grid(geom, &grid);
44 
45  wkt = lwgeom_to_wkt(gridded, WKT_ISO, 15, NULL);
46  lwgeom_free(gridded);
47  return wkt;
48 }
49 
50 static void test_lwcurve_linearize(void)
51 {
52  LWGEOM *in;
53  LWGEOM *out, *out2;
54  char *str;
55  int toltype;
56 
57  /***********************************************************
58  *
59  * Segments per quadrant tolerance type
60  *
61  ***********************************************************/
62 
64 
65  /* 2 quadrants arc (180 degrees, PI radians) */
66  in = lwgeom_from_text("CIRCULARSTRING(0 0,100 100,200 0)");
67  /* 2 segment per quadrant */
68  out = lwcurve_linearize(in, 2, toltype, 0);
69  str = lwgeom_to_text(out, 2);
70  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,30 70,100 100,170 70,200 0)");
71  lwfree(str);
72  lwgeom_free(out);
73 
74  /* 3 segment per quadrant */
75  out = lwcurve_linearize(in, 3, toltype, 0);
76  str = lwgeom_to_text(out, 2);
77  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,14 50,50 86,100 100,150 86,186 50,200 0)");
78  lwfree(str);
79  lwgeom_free(out);
80  /* 3.5 segment per quadrant (invalid) */
82  out = lwcurve_linearize(in, 3.5, toltype, 0);
83  CU_ASSERT( out == NULL );
84  ASSERT_STRING_EQUAL(cu_error_msg, "lwarc_linearize: segments per quadrant must be an integer value, got 3.5");
85  lwgeom_free(out);
86  /* -2 segment per quadrant (invalid) */
88  out = lwcurve_linearize(in, -2, toltype, 0);
89  CU_ASSERT( out == NULL );
90  ASSERT_STRING_EQUAL(cu_error_msg, "lwarc_linearize: segments per quadrant must be at least 1, got -2");
91  lwgeom_free(out);
92  /* 0 segment per quadrant (invalid) */
94  out = lwcurve_linearize(in, 0, toltype, 0);
95  CU_ASSERT( out == NULL );
96  ASSERT_STRING_EQUAL(cu_error_msg, "lwarc_linearize: segments per quadrant must be at least 1, got 0");
97  lwgeom_free(out);
98  lwgeom_free(in);
99 
100  /* 1.5 quadrants arc (145 degrees - PI*3/4 radians ) */
101  in = lwgeom_from_text("CIRCULARSTRING(29.2893218813453 70.7106781186548,100 100,200 0)");
102  /* 2 segment per quadrant */
103  out = lwcurve_linearize(in, 2, toltype, 0);
104  str = lwgeom_to_text(out, 2);
105  ASSERT_STRING_EQUAL(str, "LINESTRING(30 70,100 100,170 70,200 0)");
106  lwfree(str);
107  lwgeom_free(out);
108  /* 3 segment per quadrant - non-symmetric */
109  out = lwcurve_linearize(in, 3, toltype, 0);
110  str = lwgeom_to_text(out, 2);
111  ASSERT_STRING_EQUAL(str, "LINESTRING(30 70,74 96,126 96,170 70,196 26,200 0)");
112  lwfree(str);
113  lwgeom_free(out);
114 
115  /* 3 segment per quadrant - symmetric */
116  out = lwcurve_linearize(in, 3, toltype, LW_LINEARIZE_FLAG_SYMMETRIC);
117  str = lwgeom_to_text(out, 2);
118  ASSERT_STRING_EQUAL(str, "LINESTRING(30 70,70 96,116 98,158 80,190 46,200 0)");
119  lwfree(str);
120  lwgeom_free(out);
121 
122 #ifndef SKIP_TEST_RETAIN_ANGLE
123  /* 3 segment per quadrant - symmetric/retain_angle */
124  out = lwcurve_linearize(in, 3, toltype,
127  );
128  str = lwgeom_to_text(out, 2);
129  ASSERT_STRING_EQUAL(str, "LINESTRING(30 70,40 80,86 100,138 92,180 60,200 14,200 0)");
130  lwfree(str);
131  lwgeom_free(out);
132 #endif /* SKIP_TEST_RETAIN_ANGLE */
133 
134  lwgeom_free(in);
135 
136  /* 10 segments per quadrant (circular) */
137  in = lwgeom_from_text("CIRCULARSTRING(0 0,1 0,0 0)");
138  // out = lwcurve_linearize(in, 10, toltype, 0);
139  out = lwcurve_linearize(in, 10, toltype, 0);
140  // printf("OUT: %s\n", lwgeom_to_wkt(out, WKT_EXTENDED, 5, NULL));
142  lwgeom_free(out);
143  lwgeom_free(in);
144 
145  /***********************************************************
146  *
147  * Maximum deviation tolerance type
148  *
149  ***********************************************************/
150 
152 
153  in = lwgeom_from_text("CIRCULARSTRING(0 0,100 100,200 0)");
154 
155  /* Maximum of 10 units of difference, asymmetric */
156  out = lwcurve_linearize(in, 10, toltype, 0);
157  str = lwgeom_to_text(out, 2);
158  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,38 78,124 98,190 42,200 0)");
159  lwfree(str);
160  lwgeom_free(out);
161  /* Maximum of 0 units of difference (invalid) */
163  out = lwcurve_linearize(in, 0, toltype, 0);
164  CU_ASSERT( out == NULL );
165  ASSERT_STRING_EQUAL(cu_error_msg, "lwarc_linearize: max deviation must be bigger than 0, got 0");
166  /* Maximum of -2 units of difference (invalid) */
168  out = lwcurve_linearize(in, -2, toltype, 0);
169  CU_ASSERT( out == NULL );
170  ASSERT_STRING_EQUAL(cu_error_msg, "lwarc_linearize: max deviation must be bigger than 0, got -2");
171  /* Maximum of 10 units of difference, symmetric */
172  out = lwcurve_linearize(in, 10, toltype, LW_LINEARIZE_FLAG_SYMMETRIC);
173  str = lwgeom_to_text(out, 2);
174  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,30 70,100 100,170 70,200 0)");
175  lwfree(str);
176  lwgeom_free(out);
177  /* Maximum of 20 units of difference, asymmetric */
178  out = lwcurve_linearize(in, 20, toltype, 0);
179  str = lwgeom_to_text(out, 2);
180  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,72 96,184 54,200 0)");
181  lwfree(str);
182  lwgeom_free(out);
183  /* Maximum of 20 units of difference, symmetric */
184  out = lwcurve_linearize(in, 20, toltype, LW_LINEARIZE_FLAG_SYMMETRIC);
185  str = lwgeom_to_text(out, 2);
186  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,50 86,150 86,200 0)");
187  lwfree(str);
188  lwgeom_free(out);
189 
190 #ifndef SKIP_TEST_RETAIN_ANGLE
191  /* Maximum of 20 units of difference, symmetric/retain angle */
192  out = lwcurve_linearize(in, 20, toltype,
195  );
196  str = lwgeom_to_text(out, 2);
197  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,4 28,100 100,196 28,200 0)");
198  lwfree(str);
199  lwgeom_free(out);
200 #endif /* SKIP_TEST_RETAIN_ANGLE */
201 
202  lwgeom_free(in);
203 
204  /*
205  * Clockwise ~90 degrees south-west to north-west quadrants
206  * starting at ~22 degrees west of vertical line
207  *
208  * See https://trac.osgeo.org/postgis/ticket/3772
209  */
211  in = lwgeom_from_text("CIRCULARSTRING(71.96 -65.64,22.2 -18.52,20 50)");
212 
213  /* 4 units of max deviation - symmetric */
214  out = lwcurve_linearize(in, 4, toltype, LW_LINEARIZE_FLAG_SYMMETRIC);
215  str = lwgeom_to_text(out, 2);
216  ASSERT_STRING_EQUAL(str, "LINESTRING(72 -66,34 -38,16 4,20 50)");
217  lwfree(str);
218  lwgeom_free(out);
219  lwgeom_free(in);
220 
221  /*
222  * Clockwise ~90 degrees north-west to south-west quadrants
223  * starting at ~22 degrees west of vertical line
224  *
225  * See https://trac.osgeo.org/postgis/ticket/3772
226  */
228  in = lwgeom_from_text("CIRCULARSTRING(20 50,22.2 -18.52,71.96 -65.64)");
229 
230  /* 4 units of max deviation - symmetric */
231  out = lwcurve_linearize(in, 4, toltype, LW_LINEARIZE_FLAG_SYMMETRIC);
232  str = lwgeom_to_text(out, 2);
233  ASSERT_STRING_EQUAL(str, "LINESTRING(20 50,16 4,34 -38,72 -66)");
234  lwfree(str);
235  lwgeom_free(out);
236 
237  /* max deviation bigger than twice the radius
238  * we really only want to make sure NOT to enter
239  * an infinite loop here.
240  * See https://trac.osgeo.org/postgis/ticket/4031
241  */
242  out = lwcurve_linearize(in, 500, toltype, LW_LINEARIZE_FLAG_SYMMETRIC);
243  str = lwgeom_to_text(out, 2);
244  ASSERT_STRING_EQUAL(str, "LINESTRING(20 50,22 -18,72 -66)");
245  lwfree(str);
246  lwgeom_free(out);
247 
248  lwgeom_free(in);
249 
250  /*
251  * ROBUSTNESS: big radius, small tolerance
252  * See https://trac.osgeo.org/postgis/ticket/4058
253  * NOTE: we are really only interested in not entering
254  * an infinite loop here
255  */
257  in = lwgeom_from_text("CIRCULARSTRING("
258  "2696000.553 1125699.831999999936670, "
259  "2695950.552000000141561 1125749.833000000100583, "
260  "2695865.195999999996275 1125835.189000)");
261  out = lwcurve_linearize(in, 0.0001, toltype, 0);
262  str = lwgeom_to_text(out, 2);
263  ASSERT_STRING_EQUAL(str, "LINESTRING(2696000 1125700,2695932 1125768,2695866 1125836)");
264  lwfree(str);
265  lwgeom_free(out);
266  out = lwcurve_linearize(in, 0.0001, toltype, LW_LINEARIZE_FLAG_SYMMETRIC);
267  str = lwgeom_to_text(out, 2);
268  ASSERT_STRING_EQUAL(str, "LINESTRING(2696000 1125700,2695932 1125768,2695866 1125836)");
269  lwfree(str);
270  lwgeom_free(out);
271 #ifndef SKIP_TEST_RETAIN_ANGLE
272  out = lwcurve_linearize(in, 0.0001, toltype,
275  );
276  str = lwgeom_to_text(out, 2);
277  ASSERT_STRING_EQUAL(str, "LINESTRING(2696000 1125700,2695932 1125768,2695866 1125836)");
278  lwfree(str);
279  lwgeom_free(out);
280 #endif /* SKIP_TEST_RETAIN_ANGLE */
281  lwgeom_free(in);
282 
283  /***********************************************************
284  *
285  * Maximum angle tolerance type
286  *
287  ***********************************************************/
288 
290 
291  in = lwgeom_from_text("CIRCULARSTRING(0 0,100 100,200 0)");
292 
293  /* Maximum of 45 degrees per segment, asymmetric */
294  out = lwcurve_linearize(in, M_PI / 4.0, toltype, 0);
295  str = lwgeom_to_text(out, 2);
296  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,30 70,100 100,170 70,200 0)");
297  lwfree(str);
298  lwgeom_free(out);
299  /* Maximum of 0 degrees per segment (invalid) */
301  out = lwcurve_linearize(in, 0, toltype, 0);
302  CU_ASSERT( out == NULL );
303  ASSERT_STRING_EQUAL(cu_error_msg, "lwarc_linearize: max angle must be bigger than 0, got 0");
304  /* Maximum of -2 degrees per segment (invalid) */
306  out = lwcurve_linearize(in, -2, toltype, 0);
307  CU_ASSERT( out == NULL );
308  ASSERT_STRING_EQUAL(cu_error_msg, "lwarc_linearize: max angle must be bigger than 0, got -2");
309  /* Maximum of 360 degrees per segment, just return minimum of two segments... */
311  out = lwcurve_linearize(in, M_PI*4, toltype, 0);
312  str = lwgeom_to_text(out, 2);
313  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,100 100,200 0)");
314  lwfree(str);
315  lwgeom_free(out);
316  /* Maximum of 70 degrees per segment, asymmetric */
317  out = lwcurve_linearize(in, 70 * M_PI / 180, toltype, 0);
318  str = lwgeom_to_text(out, 2);
319  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,66 94,176 64,200 0)");
320  lwfree(str);
321  lwgeom_free(out);
322  /* Maximum of 70 degrees per segment, symmetric */
323  out = lwcurve_linearize(in, 70 * M_PI / 180, toltype, LW_LINEARIZE_FLAG_SYMMETRIC);
324  str = lwgeom_to_text(out, 2);
325  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,50 86,150 86,200 0)");
326  lwfree(str);
327  lwgeom_free(out);
328 
329 #ifndef SKIP_TEST_RETAIN_ANGLE
330  /* Maximum of 70 degrees, symmetric/retain angle */
331  out = lwcurve_linearize(in, 70 * M_PI / 180, toltype,
334  );
335  str = lwgeom_to_text(out, 2);
336  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,6 34,100 100,194 34,200 0)");
337  lwfree(str);
338  lwgeom_free(out);
339 #endif /* SKIP_TEST_RETAIN_ANGLE */
340 
341  lwgeom_free(in);
342 
343  /***********************************************************
344  *
345  * Direction neutrality
346  *
347  ***********************************************************/
348 
349  in = lwgeom_from_text("CIRCULARSTRING(71.96 -65.64,22.2 -18.52,20 50)");
350  out = lwcurve_linearize(in, M_PI/4.0,
354  out2 = lwcurve_linearize(in, M_PI/4.0,
358  if ( ! lwgeom_same(out, out2) )
359  {
360  fprintf(stderr, "linearization is not direction neutral:\n");
361  str = lwgeom_to_wkt(out, WKT_ISO, 18, NULL);
362  fprintf(stderr, "OUT1: %s\n", str);
363  lwfree(str);
364  str = lwgeom_to_wkt(out2, WKT_ISO, 18, NULL);
365  fprintf(stderr, "OUT2: %s\n", str);
366  lwfree(str);
367  }
368  CU_ASSERT( lwgeom_same(out, out2) );
369  lwgeom_free(out2);
370  lwgeom_free(out);
371  lwgeom_free(in);
372 }
373 
374 static void test_unstroke()
375 {
376  LWGEOM *in, *out;
377  char *str;
378 
379  /* It would be nice if this example returned two arcs (it's the intersection of two circles)
380  but it looks like the intersection itself is too sloppy in generating the derived point
381  to accurately reconstruct the circles.
382  in = lwgeom_from_text("POLYGON((0.5 0,0.471177920604846 -0.292635483024192,0.38581929876693 -0.574025148547634,0.247204418453818 -0.833355349529403,0.0606601717798223 -1.06066017177982,-5.44089437167602e-17 -1.11044268820754,-0.0606601717798188 -1.06066017177982,-0.247204418453816 -0.833355349529406,-0.385819298766929 -0.574025148547639,-0.471177920604845 -0.292635483024197,-0.5 -4.84663372329776e-15,-0.471177920604847 0.292635483024187,-0.385819298766932 0.57402514854763,-0.247204418453821 0.833355349529398,-0.0606601717798256 1.06066017177982,3.45538806345173e-16 1.11044268820754,0.0606601717798183 1.06066017177982,0.247204418453816 0.833355349529407,0.385819298766929 0.574025148547638,0.471177920604845 0.292635483024196,0.5 0))");
383  out = lwgeom_unstroke(in);
384  str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
385  printf("%s\n", str);
386  ASSERT_STRING_EQUAL(str, "CIRCULARSTRING(-1 0,0 1,0 -1)");
387  lwgeom_free(in);
388  lwgeom_free(out);
389  lwfree(str);
390  */
391 
392  in = lwgeom_from_text("CIRCULARSTRING(-1 0,0 1,0 -1)");
393  out = lwgeom_stroke(in,8);
394  lwgeom_free(in);
395  in = out;
396  out = lwgeom_unstroke(in);
397  str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
398  // printf("%s\n", str);
399  ASSERT_STRING_EQUAL(str, "CIRCULARSTRING(-1 0,0.70710678 0.70710678,0 -1)");
400  lwgeom_free(in);
401  lwgeom_free(out);
402  lwfree(str);
403 
404  in = lwgeom_from_text("COMPOUNDCURVE(CIRCULARSTRING(-1 0,0 1,0 -1),(0 -1,-1 -1))");
405  out = lwgeom_stroke(in,8);
406  lwgeom_free(in);
407  in = out;
408  out = lwgeom_unstroke(in);
409  str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
410  // printf("%s\n", str);
411  ASSERT_STRING_EQUAL(str, "COMPOUNDCURVE(CIRCULARSTRING(-1 0,0.70710678 0.70710678,0 -1),(0 -1,-1 -1))");
412  lwgeom_free(in);
413  lwgeom_free(out);
414  lwfree(str);
415 
416  in = lwgeom_from_text("COMPOUNDCURVE((-3 -3,-1 0),CIRCULARSTRING(-1 0,0 1,0 -1),(0 -1,0 -1.5,0 -2),CIRCULARSTRING(0 -2,-1 -3,1 -3),(1 -3,5 5))");
417  out = lwgeom_stroke(in,8);
418  lwgeom_free(in);
419  in = out;
420  out = lwgeom_unstroke(in);
421  str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
422  // printf("%s\n", str);
424  str,
425  "COMPOUNDCURVE((-3 -3,-1 0),CIRCULARSTRING(-1 0,0.70710678 "
426  "0.70710678,0 -1),(0 -1,0 -1.5,0 -2),CIRCULARSTRING(0 "
427  "-2,-0.70710678 -3.70710678,1 -3),(1 -3,5 5))");
428  lwgeom_free(in);
429  lwgeom_free(out);
430  lwfree(str);
431 
432  in = lwgeom_from_text("COMPOUNDCURVE(CIRCULARSTRING(-1 0,0 1,0 -1),CIRCULARSTRING(0 -1,-1 -2,1 -2))");
433  out = lwgeom_stroke(in,8);
434  lwgeom_free(in);
435  in = out;
436  out = lwgeom_unstroke(in);
437  str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
438  // printf("%s\n", str);
440  str,
441  "COMPOUNDCURVE(CIRCULARSTRING(-1 0,0.70710678 0.70710678,0 "
442  "-1),CIRCULARSTRING(0 -1,-0.70710678 -2.70710678,1 -2))");
443  lwgeom_free(in);
444  lwgeom_free(out);
445  lwfree(str);
446 
447  in = lwgeom_from_text("COMPOUNDCURVE((0 0, 1 1), CIRCULARSTRING(1 1, 2 2, 3 1), (3 1, 4 4))");
448  out = lwgeom_stroke(in,8);
449  lwgeom_free(in);
450  in = out;
451  out = lwgeom_unstroke(in);
452  str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
453  ASSERT_STRING_EQUAL(str, "COMPOUNDCURVE((0 0,1 1),CIRCULARSTRING(1 1,2 2,3 1),(3 1,4 4))");
454  lwgeom_free(in);
455  lwgeom_free(out);
456  // printf("%s\n", str);
457  lwfree(str);
458 
459  // See http://trac.osgeo.org/postgis/ticket/2425
460  // and http://trac.osgeo.org/postgis/ticket/2420
461  in = lwgeom_from_text("LINESTRING(0 0,10 0,10 10,0 10,0 0)");
462  out = lwgeom_unstroke(in);
463  str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
464  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,10 0,10 10,0 10,0 0)");
465  lwgeom_free(in);
466  lwgeom_free(out);
467  lwfree(str);
468 
469  in = lwgeom_from_text("LINESTRING(10 10,0 10,0 0,10 0)");
470  out = lwgeom_unstroke(in);
471  str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
472  ASSERT_STRING_EQUAL(str, "LINESTRING(10 10,0 10,0 0,10 0)");
473  // printf("%s\n", str);
474  lwgeom_free(in);
475  lwgeom_free(out);
476  lwfree(str);
477 
478  in = lwgeom_from_text("LINESTRING(0 0,10 0,10 10,0 10)");
479  out = lwgeom_unstroke(in);
480  str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
481  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,10 0,10 10,0 10)");
482  // printf("%s\n", str);
483  lwgeom_free(in);
484  lwgeom_free(out);
485  lwfree(str);
486 
487  // See http://trac.osgeo.org/postgis/ticket/2412
488  in = lwgeom_from_text("LINESTRING(0 0, 1 1)");
489  out = lwgeom_unstroke(in);
490  str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
491  // printf("%s\n", str);
492  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,1 1)");
493  lwgeom_free(in);
494  lwgeom_free(out);
495  lwfree(str);
496 
497  in = lwgeom_from_text("GEOMETRYCOLLECTION(LINESTRING(10 10,10 11),LINESTRING(10 11,11 11),LINESTRING(11 11,10 10))");
498  out = lwgeom_stroke(in,8);
499  lwgeom_free(in);
500  in = out;
501  out = lwgeom_unstroke(in);
502  str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
503  ASSERT_STRING_EQUAL(str, "GEOMETRYCOLLECTION(LINESTRING(10 10,10 11),LINESTRING(10 11,11 11),LINESTRING(11 11,10 10))");
504  lwgeom_free(in);
505  lwgeom_free(out);
506  lwfree(str);
507 
508  in = lwgeom_from_text("GEOMETRYCOLLECTION(LINESTRING(4 4,4 8),CIRCULARSTRING(4 8,6 10,8 8),LINESTRING(8 8,8 4))");
509  out = lwgeom_stroke(in,8);
510  lwgeom_free(in);
511  in = out;
512  out = lwgeom_unstroke(in);
513  str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
514  // printf("%s\n", str);
515  ASSERT_STRING_EQUAL(str, "GEOMETRYCOLLECTION(LINESTRING(4 4,4 8),CIRCULARSTRING(4 8,6 10,8 8),LINESTRING(8 8,8 4))");
516  lwgeom_free(in);
517  lwgeom_free(out);
518  lwfree(str);
519 }
520 
521 /*
522 ** Used by the test harness to register the tests in this file.
523 */
524 void lwstroke_suite_setup(void);
526 {
527  CU_pSuite suite = CU_add_suite("lwstroke", NULL, NULL);
529  PG_ADD_TEST(suite, test_unstroke);
530 }
char * r
Definition: cu_in_wkt.c:24
static void test_unstroke()
Definition: cu_lwstroke.c:374
static char * lwgeom_to_text(const LWGEOM *geom, int prec)
Definition: cu_lwstroke.c:34
static void test_lwcurve_linearize(void)
Definition: cu_lwstroke.c:50
static LWGEOM * lwgeom_from_text(const char *str)
Definition: cu_lwstroke.c:26
void lwstroke_suite_setup(void)
Definition: cu_lwstroke.c:525
void cu_error_msg_reset()
char cu_error_msg[MAX_CUNIT_ERROR_LENGTH+1]
#define ASSERT_INT_EQUAL(o, e)
#define PG_ADD_TEST(suite, testfunc)
#define ASSERT_STRING_EQUAL(o, e)
@ LW_LINEARIZE_TOLERANCE_TYPE_MAX_ANGLE
Tolerance expresses the maximum angle between the radii generating approximation line vertices,...
Definition: liblwgeom.h:2278
@ LW_LINEARIZE_TOLERANCE_TYPE_SEGS_PER_QUAD
Tolerance expresses the number of segments to use for each quarter of circle (quadrant).
Definition: liblwgeom.h:2263
@ LW_LINEARIZE_TOLERANCE_TYPE_MAX_DEVIATION
Tolerance expresses the maximum distance between an arbitrary point on the curve and the closest poin...
Definition: liblwgeom.h:2270
char lwgeom_same(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2)
geom1 same as geom2 iff
Definition: lwgeom.c:573
#define LW_FAILURE
Definition: liblwgeom.h:110
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1138
LWGEOM * lwcurve_linearize(const LWGEOM *geom, double tol, LW_LINEARIZE_TOLERANCE_TYPE type, int flags)
Definition: lwstroke.c:826
#define LW_PARSER_CHECK_NONE
Definition: liblwgeom.h:2060
LWGEOM * lwgeom_unstroke(const LWGEOM *geom)
Definition: lwstroke.c:1259
LWGEOM * lwgeom_stroke(const LWGEOM *geom, uint32_t perQuad)
Definition: lwstroke.c:859
int lwgeom_parse_wkt(LWGEOM_PARSER_RESULT *parser_result, char *wktstr, int parse_flags)
Parse a WKT geometry string into an LWGEOM structure.
uint32_t lwgeom_count_vertices(const LWGEOM *geom)
Count the total number of vertices in any LWGEOM.
Definition: lwgeom.c:1229
@ LW_LINEARIZE_FLAG_SYMMETRIC
Symmetric linearization means that the output vertices would be the same no matter the order of the p...
Definition: liblwgeom.h:2287
@ LW_LINEARIZE_FLAG_RETAIN_ANGLE
Retain angle instructs the engine to try its best to retain the requested angle between generating ra...
Definition: liblwgeom.h:2307
void lwfree(void *mem)
Definition: lwutil.c:242
#define WKT_ISO
Definition: liblwgeom.h:2130
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
Definition: lwout_wkt.c:676
LWGEOM * lwgeom_grid(const LWGEOM *lwgeom, const gridspec *grid)
Definition: lwgeom.c:2245
void lwgeom_reverse_in_place(LWGEOM *lwgeom)
Reverse vertex order of LWGEOM.
Definition: lwgeom.c:102
#define str(s)
double ysize
Definition: liblwgeom.h:1347
double xsize
Definition: liblwgeom.h:1346
Snap-to-grid.
Definition: liblwgeom.h:1341
Parser result structure: returns the result of attempting to convert (E)WKT/(E)WKB to LWGEOM.
Definition: liblwgeom.h:2068