PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ test_lwcurve_linearize()

static void test_lwcurve_linearize ( void  )
static

Definition at line 50 of file cu_lwstroke.c.

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}
static LWGEOM * lwgeom_from_text(const char *str)
Definition cu_lwstroke.c:26
static char * lwgeom_to_text(const LWGEOM *geom, int prec)
Definition cu_lwstroke.c:34
void cu_error_msg_reset()
char cu_error_msg[MAX_CUNIT_ERROR_LENGTH+1]
#define ASSERT_INT_EQUAL(o, e)
#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:2398
@ LW_LINEARIZE_TOLERANCE_TYPE_SEGS_PER_QUAD
Tolerance expresses the number of segments to use for each quarter of circle (quadrant).
Definition liblwgeom.h:2383
@ 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:2390
char lwgeom_same(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2)
geom1 same as geom2 iff
Definition lwgeom.c:619
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1246
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
Definition lwout_wkt.c:708
uint32_t lwgeom_count_vertices(const LWGEOM *geom)
Count the total number of vertices in any LWGEOM.
Definition lwgeom.c:1337
@ 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:2407
@ 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:2427
void lwfree(void *mem)
Definition lwutil.c:248
#define WKT_ISO
Definition liblwgeom.h:2219
LWGEOM * lwcurve_linearize(const LWGEOM *geom, double tol, LW_LINEARIZE_TOLERANCE_TYPE type, int flags)
Definition lwstroke.c:838
void lwgeom_reverse_in_place(LWGEOM *lwgeom)
Reverse vertex order of LWGEOM.
Definition lwgeom.c:131
#define str(s)

References ASSERT_INT_EQUAL, ASSERT_STRING_EQUAL, cu_error_msg, cu_error_msg_reset(), LW_LINEARIZE_FLAG_RETAIN_ANGLE, LW_LINEARIZE_FLAG_SYMMETRIC, LW_LINEARIZE_TOLERANCE_TYPE_MAX_ANGLE, LW_LINEARIZE_TOLERANCE_TYPE_MAX_DEVIATION, LW_LINEARIZE_TOLERANCE_TYPE_SEGS_PER_QUAD, lwcurve_linearize(), lwfree(), lwgeom_count_vertices(), lwgeom_free(), lwgeom_from_text(), lwgeom_reverse_in_place(), lwgeom_same(), lwgeom_to_text(), lwgeom_to_wkt(), str, and WKT_ISO.

Referenced by lwstroke_suite_setup().

Here is the call graph for this function:
Here is the caller graph for this function: