PostGIS  3.1.6dev-r@@SVN_REVISION@@
liblwgeom/cunit/cu_misc.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * http://postgis.net
5  * Copyright 2008 Paul Ramsey
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 <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include "CUnit/Basic.h"
16 
17 #include "liblwgeom_internal.h"
18 #include "cu_tester.h"
19 
20 
21 static void test_misc_simplify(void)
22 {
23  LWGEOM *geom;
24  LWGEOM *geom2d;
25  char *wkt_out;
26 
27  geom = lwgeom_from_wkt("LINESTRING(0 0,0 10,0 51,50 20,30 20,7 32)", LW_PARSER_CHECK_NONE);
28  geom2d = lwgeom_simplify(geom, 2, LW_FALSE);
29  wkt_out = lwgeom_to_ewkt(geom2d);
30  CU_ASSERT_STRING_EQUAL("LINESTRING(0 0,0 51,50 20,30 20,7 32)",wkt_out);
31  lwgeom_free(geom);
32  lwgeom_free(geom2d);
33  lwfree(wkt_out);
34 
35  geom = lwgeom_from_wkt("MULTILINESTRING((0 0,0 10,0 51,50 20,30 20,7 32))", LW_PARSER_CHECK_NONE);
36  geom2d = lwgeom_simplify(geom, 2, LW_FALSE);
37  wkt_out = lwgeom_to_ewkt(geom2d);
38  CU_ASSERT_STRING_EQUAL("MULTILINESTRING((0 0,0 51,50 20,30 20,7 32))",wkt_out);
39  lwgeom_free(geom);
40  lwgeom_free(geom2d);
41  lwfree(wkt_out);
42 
43  geom = lwgeom_from_wkt("POLYGON((0 0,1 1,1 3,0 4,-2 3,-1 1,0 0))", LW_PARSER_CHECK_NONE);
44  geom2d = lwgeom_simplify(geom, 1, LW_FALSE);
45  wkt_out = lwgeom_to_ewkt(geom2d);
46  CU_ASSERT_STRING_EQUAL("POLYGON((0 0,0 4,-2 3,0 0))", wkt_out);
47  lwgeom_free(geom);
48  lwgeom_free(geom2d);
49  lwfree(wkt_out);
50 }
51 
52 static void test_misc_count_vertices(void)
53 {
54  LWGEOM *geom;
55  int count;
56 
57  geom = lwgeom_from_wkt("GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(0 0,1 1),POLYGON((0 0,0 1,1 0,0 0)),CIRCULARSTRING(0 0,0 1,1 1),CURVEPOLYGON(CIRCULARSTRING(0 0,0 1,1 1)))", LW_PARSER_CHECK_NONE);
59  CU_ASSERT_EQUAL(count,13);
60  lwgeom_free(geom);
61 
62  geom = lwgeom_from_wkt("GEOMETRYCOLLECTION(CIRCULARSTRING(0 0,0 1,1 1),POINT(0 0),CURVEPOLYGON(CIRCULARSTRING(0 0,0 1,1 1,1 0,0 0)))", LW_PARSER_CHECK_NONE);
64  CU_ASSERT_EQUAL(count,9);
65  lwgeom_free(geom);
66 
67  geom = lwgeom_from_wkt("CURVEPOLYGON((0 0,1 0,0 1,0 0),CIRCULARSTRING(0 0,1 0,1 1,1 0,0 0))", LW_PARSER_CHECK_NONE);
69  CU_ASSERT_EQUAL(count,9);
70  lwgeom_free(geom);
71 
72 
73  geom = lwgeom_from_wkt("POLYGON((0 0,1 0,0 1,0 0))", LW_PARSER_CHECK_NONE);
75  CU_ASSERT_EQUAL(count,4);
76  lwgeom_free(geom);
77 
78  geom = lwgeom_from_wkt("CURVEPOLYGON((0 0,1 0,0 1,0 0),CIRCULARSTRING(0 0,1 0,1 1,1 0,0 0))", LW_PARSER_CHECK_NONE);
80  CU_ASSERT_EQUAL(count,9);
81  lwgeom_free(geom);
82 }
83 
84 static void test_misc_area(void)
85 {
86  LWGEOM *geom;
87  double area;
88 
89  geom = lwgeom_from_wkt("LINESTRING EMPTY", LW_PARSER_CHECK_ALL);
90  area = lwgeom_area(geom);
91  CU_ASSERT_DOUBLE_EQUAL(area, 0.0, 0.0001);
92  lwgeom_free(geom);
93 }
94 
95 static void test_misc_wkb(void)
96 {
97  static char *wkb = "010A0000000200000001080000000700000000000000000000C00000000000000000000000000000F0BF000000000000F0BF00000000000000000000000000000000000000000000F03F000000000000F0BF000000000000004000000000000000000000000000000000000000000000004000000000000000C00000000000000000010200000005000000000000000000F0BF00000000000000000000000000000000000000000000E03F000000000000F03F00000000000000000000000000000000000000000000F03F000000000000F0BF0000000000000000";
99  char *str = lwgeom_to_wkt(geom, WKB_ISO, 8, 0);
100  CU_ASSERT_STRING_EQUAL(str, "CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0))");
101  lwfree(str);
102  lwgeom_free(geom);
103 
104 }
105 
106 
107 static void test_grid(void)
108 {
109  gridspec grid;
110  static char *wkt = "MULTIPOLYGON(((0 0, 10 0, 10 10, 0 10, 0 0)))";
112  LWGEOM *geomgrid;
113  char *str;
114 
115  grid.ipx = grid.ipy = 0;
116  grid.xsize = grid.ysize = 20;
117 
118  geomgrid = lwgeom_grid(geom, &grid);
119  str = lwgeom_to_ewkt(geomgrid);
120  CU_ASSERT_STRING_EQUAL(str, "MULTIPOLYGON EMPTY");
121  lwfree(str);
122  lwgeom_free(geom);
123  lwgeom_free(geomgrid);
124 }
125 
126 static void do_grid_test(const char *wkt_in, const char *wkt_out, double size)
127 {
128  char *wkt_result, *wkt_norm;
129  gridspec grid;
132  wkt_norm = lwgeom_to_ewkt(go);
133  memset(&grid, 0, sizeof(gridspec));
134  grid.xsize = grid.ysize = grid.zsize = grid.msize = size;
135  lwgeom_grid_in_place(g, &grid);
136  wkt_result = lwgeom_to_ewkt(g);
137  // printf("%s ==%ld==> %s == %s\n", wkt_in, lround(size), wkt_result, wkt_out);
138  CU_ASSERT_STRING_EQUAL(wkt_result, wkt_norm);
139  lwfree(wkt_result);
140  lwfree(wkt_norm);
141  lwgeom_free(g);
142  lwgeom_free(go);
143 }
144 
145 static void test_grid_in_place(void)
146 {
147  do_grid_test(
148  "POINT ZM (5.1423999999 5.1423999999 5.1423999999 5.1423999999)",
149  "POINT(5.1424 5.1424 5.1424 5.1424)",
150  0.0001
151  );
152  do_grid_test(
153  "MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)))",
154  "MULTIPOLYGON EMPTY",
155  20
156  );
157  do_grid_test(
158  "MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)))",
159  "MULTIPOLYGON(((0 0,10 0,10 10, 0 10,0 0)))",
160  1
161  );
162  do_grid_test(
163  "LINESTRING(0 0,1 1, 2 2, 3 3, 4 4, 5 5)",
164  "LINESTRING(0 0,2 2,4 4)",
165  2
166  );
167  do_grid_test(
168  "MULTIPOINT(0 0,1 1, 2 2, 3 3, 4 4, 5 5)",
169  /* This preserves current behaviour, but is probably not right */
170  "MULTIPOINT(0 0,0 0,2 2,4 4,4 4,4 4)",
171  2
172  );
173  do_grid_test(
174  "MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(4 4, 4 5, 5 5, 5 4, 4 4)))",
175  "MULTIPOLYGON(((0 0,10 0,10 10, 0 10,0 0)))",
176  2
177  );
178  do_grid_test(
179  "MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(4 4, 4 5, 5 5, 5 4, 4 4)))",
180  "MULTIPOLYGON EMPTY",
181  20
182  );
183  do_grid_test(
184  "POINT Z (5 5 5)",
185  "POINT(0 0 0)",
186  20
187  );
188 }
189 
190 static void test_clone(void)
191 {
192  static char *wkt = "GEOMETRYCOLLECTION(MULTIPOLYGON(((0 0, 10 0, 10 10, 0 10, 0 0))),POINT(1 1),LINESTRING(2 3,4 5))";
194  LWGEOM *geom2;
195 
196  /* Free in "backwards" order */
197  geom2 = lwgeom_clone(geom1);
198  lwgeom_free(geom1);
199  lwgeom_free(geom2);
200 
201  /* Free in "forewards" order */
202  geom1 = lwgeom_from_wkt(wkt, LW_PARSER_CHECK_ALL);
203  geom2 = lwgeom_clone(geom1);
204  lwgeom_free(geom2);
205  lwgeom_free(geom1);
206 }
207 
208 static void test_lwmpoint_from_lwgeom(void)
209 {
210  /* This cast is so ugly, we only want to do it once. And not even that. */
211  LWGEOM* (*to_points)(LWGEOM*) = (LWGEOM* (*)(LWGEOM*)) &lwmpoint_from_lwgeom;
212 
213  do_fn_test(to_points, "MULTIPOLYGON (EMPTY)", "MULTIPOINT EMPTY");
214  do_fn_test(to_points, "POINT (30 10)", "MULTIPOINT ((30 10))");
215  do_fn_test(to_points, "LINESTRING Z (30 10 4,10 30 5,40 40 6)", "MULTIPOINT Z (30 10 4,10 30 5, 40 40 6)");
216  do_fn_test(to_points, "POLYGON((35 10,45 45,15 40,10 20,35 10),(20 30,35 35,30 20,20 30))", "MULTIPOINT(35 10,45 45,15 40,10 20,35 10,20 30,35 35,30 20,20 30)");
217  do_fn_test(to_points, "MULTIPOINT M (10 40 1,40 30 2,20 20 3,30 10 4)", "MULTIPOINT M (10 40 1,40 30 2,20 20 3,30 10 4)");
218  do_fn_test(to_points, "COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0))", "MULTIPOINT(0 0, 2 0, 2 1, 2 3, 4 3, 4 3, 4 5, 1 4, 0 0)");
219  do_fn_test(to_points, "TIN(((80 130,50 160,80 70,80 130)),((50 160,10 190,10 70,50 160)))", "MULTIPOINT (80 130, 50 160, 80 70, 80 130, 50 160, 10 190, 10 70, 50 160)");
220 }
221 
222 static void test_gbox_serialized_size(void)
223 {
224  lwflags_t flags = lwflags(0, 0, 0);
225  CU_ASSERT_EQUAL(gbox_serialized_size(flags),16);
226  FLAGS_SET_BBOX(flags, 1);
227  CU_ASSERT_EQUAL(gbox_serialized_size(flags),16);
228  FLAGS_SET_Z(flags, 1);
229  CU_ASSERT_EQUAL(gbox_serialized_size(flags),24);
230  FLAGS_SET_M(flags, 1);
231  CU_ASSERT_EQUAL(gbox_serialized_size(flags),32);
232  FLAGS_SET_GEODETIC(flags, 1);
233  CU_ASSERT_EQUAL(gbox_serialized_size(flags),24);
234 }
235 
236 
237 
238 /*
239 ** Used by the test harness to register the tests in this file.
240 */
241 void misc_suite_setup(void);
243 {
244  CU_pSuite suite = CU_add_suite("miscellaneous", NULL, NULL);
247  PG_ADD_TEST(suite, test_misc_area);
248  PG_ADD_TEST(suite, test_misc_wkb);
249  PG_ADD_TEST(suite, test_grid);
251  PG_ADD_TEST(suite, test_clone);
254 }
size_t gbox_serialized_size(lwflags_t flags)
Return the number of bytes necessary to hold a GBOX of this dimension in serialized form.
Definition: gbox.c:440
static void test_lwmpoint_from_lwgeom(void)
static void test_clone(void)
static void test_misc_area(void)
void misc_suite_setup(void)
static void do_grid_test(const char *wkt_in, const char *wkt_out, double size)
static void test_misc_simplify(void)
static void test_grid_in_place(void)
static void test_misc_wkb(void)
static void test_gbox_serialized_size(void)
static void test_misc_count_vertices(void)
static void test_grid(void)
void do_fn_test(LWGEOM *(*transfn)(LWGEOM *), char *input_wkt, char *expected_wkt)
#define PG_ADD_TEST(suite, testfunc)
#define LW_PARSER_CHECK_ALL
Definition: liblwgeom.h:2086
LWGEOM * lwgeom_simplify(const LWGEOM *igeom, double dist, int preserve_collapsed)
Simplification.
Definition: lwgeom.c:1847
#define LW_FALSE
Definition: liblwgeom.h:108
#define WKB_ISO
Definition: liblwgeom.h:2146
LWGEOM * lwgeom_from_hexwkb(const char *hexwkb, const char check)
Definition: lwin_wkb.c:858
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1138
#define LW_PARSER_CHECK_NONE
Definition: liblwgeom.h:2085
uint16_t lwflags_t
Definition: liblwgeom.h:313
#define FLAGS_SET_BBOX(flags, value)
Definition: liblwgeom.h:188
char * lwgeom_to_ewkt(const LWGEOM *lwgeom)
Return an alloced string.
Definition: lwgeom.c:548
double lwgeom_area(const LWGEOM *geom)
Definition: lwgeom.c:1862
uint32_t lwgeom_count_vertices(const LWGEOM *geom)
Count the total number of vertices in any LWGEOM.
Definition: lwgeom.c:1229
void lwfree(void *mem)
Definition: lwutil.c:242
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
Definition: lwout_wkt.c:704
LWGEOM * lwgeom_clone(const LWGEOM *lwgeom)
Clone LWGEOM object.
Definition: lwgeom.c:474
LWGEOM * lwgeom_from_wkt(const char *wkt, const char check)
Definition: lwin_wkt.c:905
LWMPOINT * lwmpoint_from_lwgeom(const LWGEOM *g)
Definition: lwmpoint.c:93
#define FLAGS_SET_GEODETIC(flags, value)
Definition: liblwgeom.h:189
lwflags_t lwflags(int hasz, int hasm, int geodetic)
Construct a new flags bitmask.
Definition: lwutil.c:471
#define FLAGS_SET_M(flags, value)
Definition: liblwgeom.h:187
#define FLAGS_SET_Z(flags, value)
Definition: liblwgeom.h:186
LWGEOM * lwgeom_grid(const LWGEOM *lwgeom, const gridspec *grid)
Definition: lwgeom.c:2244
void lwgeom_grid_in_place(LWGEOM *lwgeom, const gridspec *grid)
Definition: lwgeom.c:2143
#define str(s)
int count
Definition: genraster.py:57
double zsize
Definition: liblwgeom.h:1373
double ysize
Definition: liblwgeom.h:1372
double xsize
Definition: liblwgeom.h:1371
double ipx
Definition: liblwgeom.h:1367
double msize
Definition: liblwgeom.h:1374
double ipy
Definition: liblwgeom.h:1368
Snap-to-grid.
Definition: liblwgeom.h:1366