PostGIS  2.5.0dev-r@@SVN_REVISION@@

◆ test_lwcurve_linearize()

static void test_lwcurve_linearize ( void  )
static

Definition at line 50 of file cu_lwstroke.c.

References 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_free(), lwgeom_from_text(), lwgeom_reverse_in_place(), lwgeom_same(), lwgeom_to_text(), lwgeom_to_wkt(), and WKT_ISO.

Referenced by lwstroke_suite_setup().

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  /* 3 segment per quadrant */
74  out = lwcurve_linearize(in, 3, toltype, 0);
75  str = lwgeom_to_text(out, 2);
76  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,14 50,50 86,100 100,150 86,186 50,200 0)");
77  lwfree(str);
78  lwgeom_free(out);
79  /* 3.5 segment per quadrant (invalid) */
81  out = lwcurve_linearize(in, 3.5, toltype, 0);
82  CU_ASSERT( out == NULL );
83  ASSERT_STRING_EQUAL(cu_error_msg, "lwarc_linearize: segments per quadrant must be an integer value, got 3.5");
84  lwgeom_free(out);
85  /* -2 segment per quadrant (invalid) */
87  out = lwcurve_linearize(in, -2, toltype, 0);
88  CU_ASSERT( out == NULL );
89  ASSERT_STRING_EQUAL(cu_error_msg, "lwarc_linearize: segments per quadrant must be at least 1, got -2");
90  lwgeom_free(out);
91  /* 0 segment per quadrant (invalid) */
93  out = lwcurve_linearize(in, 0, toltype, 0);
94  CU_ASSERT( out == NULL );
95  ASSERT_STRING_EQUAL(cu_error_msg, "lwarc_linearize: segments per quadrant must be at least 1, got 0");
96  lwgeom_free(out);
97  lwgeom_free(in);
98 
99  /* 1.5 quadrants arc (145 degrees - PI*3/4 radians ) */
100  in = lwgeom_from_text("CIRCULARSTRING(29.2893218813453 70.7106781186548,100 100,200 0)");
101  /* 2 segment per quadrant */
102  out = lwcurve_linearize(in, 2, toltype, 0);
103  str = lwgeom_to_text(out, 2);
104  ASSERT_STRING_EQUAL(str, "LINESTRING(30 70,100 100,170 70,200 0)");
105  lwfree(str);
106  lwgeom_free(out);
107  /* 3 segment per quadrant - non-symmetric */
108  out = lwcurve_linearize(in, 3, toltype, 0);
109  str = lwgeom_to_text(out, 2);
110  ASSERT_STRING_EQUAL(str, "LINESTRING(30 70,74 96,126 96,170 70,196 26,200 0)");
111  lwfree(str);
112  lwgeom_free(out);
113 
114  /* 3 segment per quadrant - symmetric */
115  out = lwcurve_linearize(in, 3, toltype, LW_LINEARIZE_FLAG_SYMMETRIC);
116  str = lwgeom_to_text(out, 2);
117  ASSERT_STRING_EQUAL(str, "LINESTRING(30 70,70 96,116 98,158 80,190 46,200 0)");
118  lwfree(str);
119  lwgeom_free(out);
120 
121 #ifndef SKIP_TEST_RETAIN_ANGLE
122  /* 3 segment per quadrant - symmetric/retain_angle */
123  out = lwcurve_linearize(in, 3, toltype,
126  );
127  str = lwgeom_to_text(out, 2);
128  ASSERT_STRING_EQUAL(str, "LINESTRING(30 70,40 80,86 100,138 92,180 60,200 14,200 0)");
129  lwfree(str);
130  lwgeom_free(out);
131 #endif /* SKIP_TEST_RETAIN_ANGLE */
132 
133  lwgeom_free(in);
134 
135  /***********************************************************
136  *
137  * Maximum deviation tolerance type
138  *
139  ***********************************************************/
140 
142 
143  in = lwgeom_from_text("CIRCULARSTRING(0 0,100 100,200 0)");
144 
145  /* Maximum of 10 units of difference, asymmetric */
146  out = lwcurve_linearize(in, 10, toltype, 0);
147  str = lwgeom_to_text(out, 2);
148  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,38 78,124 98,190 42,200 0)");
149  lwfree(str);
150  lwgeom_free(out);
151  /* Maximum of 0 units of difference (invalid) */
153  out = lwcurve_linearize(in, 0, toltype, 0);
154  CU_ASSERT( out == NULL );
155  ASSERT_STRING_EQUAL(cu_error_msg, "lwarc_linearize: max deviation must be bigger than 0, got 0");
156  /* Maximum of -2 units of difference (invalid) */
158  out = lwcurve_linearize(in, -2, toltype, 0);
159  CU_ASSERT( out == NULL );
160  ASSERT_STRING_EQUAL(cu_error_msg, "lwarc_linearize: max deviation must be bigger than 0, got -2");
161  /* Maximum of 10 units of difference, symmetric */
162  out = lwcurve_linearize(in, 10, toltype, LW_LINEARIZE_FLAG_SYMMETRIC);
163  str = lwgeom_to_text(out, 2);
164  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,30 70,100 100,170 70,200 0)");
165  lwfree(str);
166  lwgeom_free(out);
167  /* Maximum of 20 units of difference, asymmetric */
168  out = lwcurve_linearize(in, 20, toltype, 0);
169  str = lwgeom_to_text(out, 2);
170  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,72 96,184 54,200 0)");
171  lwfree(str);
172  lwgeom_free(out);
173  /* Maximum of 20 units of difference, symmetric */
174  out = lwcurve_linearize(in, 20, toltype, LW_LINEARIZE_FLAG_SYMMETRIC);
175  str = lwgeom_to_text(out, 2);
176  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,50 86,150 86,200 0)");
177  lwfree(str);
178  lwgeom_free(out);
179 
180 #ifndef SKIP_TEST_RETAIN_ANGLE
181  /* Maximum of 20 units of difference, symmetric/retain angle */
182  out = lwcurve_linearize(in, 20, toltype,
185  );
186  str = lwgeom_to_text(out, 2);
187  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,4 28,100 100,196 28,200 0)");
188  lwfree(str);
189  lwgeom_free(out);
190 #endif /* SKIP_TEST_RETAIN_ANGLE */
191 
192  lwgeom_free(in);
193 
194  /*
195  * Clockwise ~90 degrees south-west to north-west quadrants
196  * starting at ~22 degrees west of vertical line
197  *
198  * See https://trac.osgeo.org/postgis/ticket/3772
199  */
201  in = lwgeom_from_text("CIRCULARSTRING(71.96 -65.64,22.2 -18.52,20 50)");
202 
203  /* 4 units of max deviation - symmetric */
204  out = lwcurve_linearize(in, 4, toltype, LW_LINEARIZE_FLAG_SYMMETRIC);
205  str = lwgeom_to_text(out, 2);
206  ASSERT_STRING_EQUAL(str, "LINESTRING(72 -66,34 -38,16 4,20 50)");
207  lwfree(str);
208  lwgeom_free(out);
209  lwgeom_free(in);
210 
211  /*
212  * Clockwise ~90 degrees north-west to south-west quadrants
213  * starting at ~22 degrees west of vertical line
214  *
215  * See https://trac.osgeo.org/postgis/ticket/3772
216  */
218  in = lwgeom_from_text("CIRCULARSTRING(20 50,22.2 -18.52,71.96 -65.64)");
219 
220  /* 4 units of max deviation - symmetric */
221  out = lwcurve_linearize(in, 4, toltype, LW_LINEARIZE_FLAG_SYMMETRIC);
222  str = lwgeom_to_text(out, 2);
223  ASSERT_STRING_EQUAL(str, "LINESTRING(20 50,16 4,34 -38,72 -66)");
224  lwfree(str);
225  lwgeom_free(out);
226 
227  lwgeom_free(in);
228 
229  /***********************************************************
230  *
231  * Maximum angle tolerance type
232  *
233  ***********************************************************/
234 
236 
237  in = lwgeom_from_text("CIRCULARSTRING(0 0,100 100,200 0)");
238 
239  /* Maximum of 45 degrees, asymmetric */
240  out = lwcurve_linearize(in, M_PI / 4.0, toltype, 0);
241  str = lwgeom_to_text(out, 2);
242  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,30 70,100 100,170 70,200 0)");
243  lwfree(str);
244  lwgeom_free(out);
245  /* Maximum of 0 degrees (invalid) */
247  out = lwcurve_linearize(in, 0, toltype, 0);
248  CU_ASSERT( out == NULL );
249  ASSERT_STRING_EQUAL(cu_error_msg, "lwarc_linearize: max angle must be bigger than 0, got 0");
250  /* Maximum of -2 degrees (invalid) */
252  out = lwcurve_linearize(in, -2, toltype, 0);
253  CU_ASSERT( out == NULL );
254  ASSERT_STRING_EQUAL(cu_error_msg, "lwarc_linearize: max angle must be bigger than 0, got -2");
255  /* Maximum of 360 degrees, just return endpoints... */
257  out = lwcurve_linearize(in, M_PI*4, toltype, 0);
258  str = lwgeom_to_text(out, 2);
259  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,200 0)");
260  lwfree(str);
261  lwgeom_free(out);
262  /* Maximum of 70 degrees, asymmetric */
263  out = lwcurve_linearize(in, 70 * M_PI / 180, toltype, 0);
264  str = lwgeom_to_text(out, 2);
265  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,66 94,176 64,200 0)");
266  lwfree(str);
267  lwgeom_free(out);
268  /* Maximum of 70 degrees, symmetric */
269  out = lwcurve_linearize(in, 70 * M_PI / 180, toltype, LW_LINEARIZE_FLAG_SYMMETRIC);
270  str = lwgeom_to_text(out, 2);
271  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,50 86,150 86,200 0)");
272  lwfree(str);
273  lwgeom_free(out);
274 
275 #ifndef SKIP_TEST_RETAIN_ANGLE
276  /* Maximum of 70 degrees, symmetric/retain angle */
277  out = lwcurve_linearize(in, 70 * M_PI / 180, toltype,
280  );
281  str = lwgeom_to_text(out, 2);
282  ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,6 34,100 100,194 34,200 0)");
283  lwfree(str);
284  lwgeom_free(out);
285 #endif /* SKIP_TEST_RETAIN_ANGLE */
286 
287  lwgeom_free(in);
288 
289  /***********************************************************
290  *
291  * Direction neutrality
292  *
293  ***********************************************************/
294 
295  in = lwgeom_from_text("CIRCULARSTRING(71.96 -65.64,22.2 -18.52,20 50)");
296  out = lwcurve_linearize(in, M_PI/4.0,
300  out2 = lwcurve_linearize(in, M_PI/4.0,
304  if ( ! lwgeom_same(out, out2) )
305  {
306  fprintf(stderr, "linearization is not direction neutral:\n");
307  str = lwgeom_to_wkt(out, WKT_ISO, 18, NULL);
308  fprintf(stderr, "OUT1: %s\n", str);
309  lwfree(str);
310  str = lwgeom_to_wkt(out2, WKT_ISO, 18, NULL);
311  fprintf(stderr, "OUT2: %s\n", str);
312  lwfree(str);
313  }
314  CU_ASSERT( lwgeom_same(out, out2) );
315  lwgeom_free(out2);
316  lwgeom_free(out);
317  lwgeom_free(in);
318 }
Tolerance expresses the maximum angle between the radii generating approximation line vertices...
Definition: liblwgeom.h:2222
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
Definition: lwout_wkt.c:675
void lwfree(void *mem)
Definition: lwutil.c:244
void lwgeom_reverse_in_place(LWGEOM *lwgeom)
Reverse vertex order of LWGEOM.
Definition: lwgeom.c:102
#define ASSERT_STRING_EQUAL(o, e)
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1144
Tolerance expresses the maximum distance between an arbitrary point on the curve and the closest poin...
Definition: liblwgeom.h:2214
static char * lwgeom_to_text(const LWGEOM *geom, int prec)
Definition: cu_lwstroke.c:34
#define WKT_ISO
Definition: liblwgeom.h:2074
void cu_error_msg_reset()
static LWGEOM * lwgeom_from_text(const char *str)
Definition: cu_lwstroke.c:26
char lwgeom_same(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2)
geom1 same as geom2 iff
Definition: lwgeom.c:582
Symmetric linearization means that the output vertices would be the same no matter the order of the p...
Definition: liblwgeom.h:2231
Tolerance expresses the number of segments to use for each quarter of circle (quadrant).
Definition: liblwgeom.h:2207
Retain angle instructs the engine to try its best to retain the requested angle between generating ra...
Definition: liblwgeom.h:2251
char cu_error_msg[MAX_CUNIT_ERROR_LENGTH+1]
LWGEOM * lwcurve_linearize(const LWGEOM *geom, double tol, LW_LINEARIZE_TOLERANCE_TYPE type, int flags)
Definition: lwstroke.c:682
Here is the call graph for this function:
Here is the caller graph for this function: