PostGIS  2.5.7dev-r@@SVN_REVISION@@
cu_out_geojson.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * http://postgis.net
5  * Copyright 2010 Olivier Courtin <olivier.courtin@oslandia.com>
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 static void do_geojson_test(char * in, char * out, char * srs, int precision, int has_bbox)
21 {
22  LWGEOM *g;
23  char * h;
24 
26  h = lwgeom_to_geojson(g, srs, precision, has_bbox);
27 
28  if (strcmp(h, out))
29  fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", in, h, out);
30 
31  CU_ASSERT_STRING_EQUAL(h, out);
32 
33  lwgeom_free(g);
34  lwfree(h);
35 }
36 
37 
38 static void do_geojson_unsupported(char * in, char * out)
39 {
40  LWGEOM *g;
41  char *h;
42 
44  h = lwgeom_to_geojson(g, NULL, 0, 0);
45 
46  if (strcmp(cu_error_msg, out))
47  fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n",
48  in, cu_error_msg, out);
49 
50  CU_ASSERT_STRING_EQUAL(out, cu_error_msg);
52 
53  lwfree(h);
54  lwgeom_free(g);
55 }
56 
57 
58 static void out_geojson_test_precision(void)
59 {
60  /* 0 precision, i.e a round */
62  "POINT(1.1111111111111 1.1111111111111)",
63  "{\"type\":\"Point\",\"coordinates\":[1,1]}",
64  NULL, 0, 0);
65 
66  /* 3 digits precision */
68  "POINT(1.1111111111111 1.1111111111111)",
69  "{\"type\":\"Point\",\"coordinates\":[1.111,1.111]}",
70  NULL, 3, 0);
71 
72  /* 9 digits precision */
74  "POINT(1.2345678901234 1.2345678901234)",
75  "{\"type\":\"Point\",\"coordinates\":[1.23456789,1.23456789]}",
76  NULL, 9, 0);
77 
78  /* huge data */
80  "POINT(1E300 -1E300)",
81  "{\"type\":\"Point\",\"coordinates\":[1e+300,-1e+300]}",
82  NULL, 0, 0);
83 
84  /* huge precision, see http://trac.osgeo.org/postgis/ticket/2052 */
86  "POINT(1 2)",
87  "{\"type\":\"Point\",\"coordinates\":[1,2]}",
88  NULL, 100, 0);
89 
90  /* double precision, see http://trac.osgeo.org/postgis/ticket/2051 */
92  "POINT(59.99 -59.99)",
93  "{\"type\":\"Point\",\"coordinates\":[59.99,-59.99]}",
94  NULL, 15, 0);
95 
96  /* small numbers */
97  /* NOTE: precision of 300 will be converted to max precision (15)
98  * and being there no significant digit within that range
99  * only zeroes will be returned
100  * See http://trac.osgeo.org/postgis/ticket/2051#comment:11
101  */
102  do_geojson_test("POINT(1E-300 -2E-200)",
103  "{\"type\":\"Point\",\"coordinates\":[0,0]}",
104  NULL,
105  300,
106  0);
107 }
108 
109 
110 static void out_geojson_test_dims(void)
111 {
112  /* 3D */
114  "POINT(0 1 2)",
115  "{\"type\":\"Point\",\"coordinates\":[0,1,2]}",
116  NULL, 0, 0);
117 
118  /* 3DM */
120  "POINTM(0 1 2)",
121  "{\"type\":\"Point\",\"coordinates\":[0,1]}",
122  NULL, 0, 0);
123 
124  /* 4D */
126  "POINT(0 1 2 3)",
127  "{\"type\":\"Point\",\"coordinates\":[0,1,2]}",
128  NULL, 0, 0);
129 }
130 
131 
132 static void out_geojson_test_srid(void)
133 {
134  /* Linestring */
136  "LINESTRING(0 1,2 3,4 5)",
137  "{\"type\":\"LineString\",\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}},\"coordinates\":[[0,1],[2,3],[4,5]]}",
138  "EPSG:4326", 0, 0);
139 
140  /* Polygon */
142  "POLYGON((0 1,2 3,4 5,0 1))",
143  "{\"type\":\"Polygon\",\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}},\"coordinates\":[[[0,1],[2,3],[4,5],[0,1]]]}",
144  "EPSG:4326", 0, 0);
145 
146  /* Polygon - with internal ring */
148  "POLYGON((0 1,2 3,4 5,0 1),(6 7,8 9,10 11,6 7))",
149  "{\"type\":\"Polygon\",\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}},\"coordinates\":[[[0,1],[2,3],[4,5],[0,1]],[[6,7],[8,9],[10,11],[6,7]]]}",
150  "EPSG:4326", 0, 0);
151 
152  /* Multiline */
154  "MULTILINESTRING((0 1,2 3,4 5),(6 7,8 9,10 11))",
155  "{\"type\":\"MultiLineString\",\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}},\"coordinates\":[[[0,1],[2,3],[4,5]],[[6,7],[8,9],[10,11]]]}",
156  "EPSG:4326", 0, 0);
157 
158  /* MultiPolygon */
160  "MULTIPOLYGON(((0 1,2 3,4 5,0 1)),((6 7,8 9,10 11,6 7)))",
161  "{\"type\":\"MultiPolygon\",\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}},\"coordinates\":[[[[0,1],[2,3],[4,5],[0,1]]],[[[6,7],[8,9],[10,11],[6,7]]]]}",
162  "EPSG:4326", 0, 0);
163 
164  /* GeometryCollection */
166  "GEOMETRYCOLLECTION(POINT(0 1),LINESTRING(2 3,4 5))",
167  "{\"type\":\"GeometryCollection\",\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}},\"geometries\":[{\"type\":\"Point\",\"coordinates\":[0,1]},{\"type\":\"LineString\",\"coordinates\":[[2,3],[4,5]]}]}",
168  "EPSG:4326", 0, 0);
169 
170  /* Empty GeometryCollection */
172  "GEOMETRYCOLLECTION EMPTY",
173  "{\"type\":\"GeometryCollection\",\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}},\"geometries\":[]}",
174  "EPSG:4326", 0, 0);
175 }
176 
177 static void out_geojson_test_bbox(void)
178 {
179  /* Linestring */
181  "LINESTRING(0 1,2 3,4 5)",
182  "{\"type\":\"LineString\",\"bbox\":[0,1,4,5],\"coordinates\":[[0,1],[2,3],[4,5]]}",
183  NULL, 0, 1);
184 
185  /* Polygon */
187  "POLYGON((0 1,2 3,4 5,0 1))",
188  "{\"type\":\"Polygon\",\"bbox\":[0,1,4,5],\"coordinates\":[[[0,1],[2,3],[4,5],[0,1]]]}",
189  NULL, 0, 1);
190 
191  /* Polygon - with internal ring */
193  "POLYGON((0 1,2 3,4 5,0 1),(6 7,8 9,10 11,6 7))",
194  "{\"type\":\"Polygon\",\"bbox\":[0,1,4,5],\"coordinates\":[[[0,1],[2,3],[4,5],[0,1]],[[6,7],[8,9],[10,11],[6,7]]]}",
195  NULL, 0, 1);
196 
197  /* Multiline */
199  "MULTILINESTRING((0 1,2 3,4 5),(6 7,8 9,10 11))",
200  "{\"type\":\"MultiLineString\",\"bbox\":[0,1,10,11],\"coordinates\":[[[0,1],[2,3],[4,5]],[[6,7],[8,9],[10,11]]]}",
201  NULL, 0, 1);
202 
203  /* MultiPolygon */
205  "MULTIPOLYGON(((0 1,2 3,4 5,0 1)),((6 7,8 9,10 11,6 7)))",
206  "{\"type\":\"MultiPolygon\",\"bbox\":[0,1,10,11],\"coordinates\":[[[[0,1],[2,3],[4,5],[0,1]]],[[[6,7],[8,9],[10,11],[6,7]]]]}",
207  NULL, 0, 1);
208 
209  /* GeometryCollection */
211  "GEOMETRYCOLLECTION(LINESTRING(0 1,-1 3),LINESTRING(2 3,4 5))",
212  "{\"type\":\"GeometryCollection\",\"bbox\":[-1,1,4,5],\"geometries\":[{\"type\":\"LineString\",\"coordinates\":[[0,1],[-1,3]]},{\"type\":\"LineString\",\"coordinates\":[[2,3],[4,5]]}]}",
213  NULL, 0, 1);
214 
215  /* Empty GeometryCollection */
217  "GEOMETRYCOLLECTION EMPTY",
218  "{\"type\":\"GeometryCollection\",\"geometries\":[]}",
219  NULL, 0, 1);
220 }
221 
222 static void out_geojson_test_geoms(void)
223 {
224  /* Linestring */
226  "LINESTRING(0 1,2 3,4 5)",
227  "{\"type\":\"LineString\",\"coordinates\":[[0,1],[2,3],[4,5]]}",
228  NULL, 0, 0);
229 
230  /* Polygon */
232  "POLYGON((0 1,2 3,4 5,0 1))",
233  "{\"type\":\"Polygon\",\"coordinates\":[[[0,1],[2,3],[4,5],[0,1]]]}",
234  NULL, 0, 0);
235 
236  /* Polygon - with internal ring */
238  "POLYGON((0 1,2 3,4 5,0 1),(6 7,8 9,10 11,6 7))",
239  "{\"type\":\"Polygon\",\"coordinates\":[[[0,1],[2,3],[4,5],[0,1]],[[6,7],[8,9],[10,11],[6,7]]]}",
240  NULL, 0, 0);
241 
242  /* Multiline */
244  "MULTILINESTRING((0 1,2 3,4 5),(6 7,8 9,10 11))",
245  "{\"type\":\"MultiLineString\",\"coordinates\":[[[0,1],[2,3],[4,5]],[[6,7],[8,9],[10,11]]]}",
246  NULL, 0, 0);
247 
248  /* MultiPolygon */
250  "MULTIPOLYGON(((0 1,2 3,4 5,0 1)),((6 7,8 9,10 11,6 7)))",
251  "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[0,1],[2,3],[4,5],[0,1]]],[[[6,7],[8,9],[10,11],[6,7]]]]}",
252  NULL, 0, 0);
253 
254  /* GeometryCollection */
256  "GEOMETRYCOLLECTION(POINT(0 1),LINESTRING(2 3,4 5))",
257  "{\"type\":\"GeometryCollection\",\"geometries\":[{\"type\":\"Point\",\"coordinates\":[0,1]},{\"type\":\"LineString\",\"coordinates\":[[2,3],[4,5]]}]}",
258  NULL, 0, 0);
259 
260  /* Empty GeometryCollection */
262  "GEOMETRYCOLLECTION EMPTY",
263  "{\"type\":\"GeometryCollection\",\"geometries\":[]}",
264  NULL, 0, 0);
265 
266  /* Nested GeometryCollection */
268  "GEOMETRYCOLLECTION(POINT(0 1),GEOMETRYCOLLECTION(LINESTRING(2 3,4 5)))",
269  "GeoJson: geometry not supported.");
270 
271  /* CircularString */
273  "CIRCULARSTRING(-2 0,0 2,2 0,0 2,2 4)",
274  "lwgeom_to_geojson: 'CircularString' geometry type not supported");
275 
276  /* CompoundCurve */
278  "COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1))",
279  "lwgeom_to_geojson: 'CompoundCurve' geometry type not supported");
280 
281  /* CurvePolygon */
283  "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))",
284  "lwgeom_to_geojson: 'CurvePolygon' geometry type not supported");
285 
286  /* MultiCurve */
288  "MULTICURVE((5 5,3 5,3 3,0 3),CIRCULARSTRING(0 0,2 1,2 2))",
289  "lwgeom_to_geojson: 'MultiCurve' geometry type not supported");
290 
291  /* MultiSurface */
293  "MULTISURFACE(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)),((7 8,10 10,6 14,4 11,7 8)))",
294  "lwgeom_to_geojson: 'MultiSurface' geometry type not supported");
295 }
296 
297 /*
298 ** Used by test harness to register the tests in this file.
299 */
300 void out_geojson_suite_setup(void);
301 void out_geojson_suite_setup(void)
302 {
303  CU_pSuite suite = CU_add_suite("geojson_output", NULL, NULL);
307  PG_ADD_TEST(suite, out_geojson_test_bbox);
308  PG_ADD_TEST(suite, out_geojson_test_geoms);
309 }
static uint8_t precision
Definition: cu_in_twkb.c:25
static void out_geojson_test_dims(void)
static void do_geojson_unsupported(char *in, char *out)
static void out_geojson_test_precision(void)
static void do_geojson_test(char *in, char *out, char *srs, int precision, int has_bbox)
static void out_geojson_test_srid(void)
void cu_error_msg_reset()
char cu_error_msg[MAX_CUNIT_ERROR_LENGTH+1]
void out_geojson_suite_setup(void)
#define PG_ADD_TEST(suite, testfunc)
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1144
#define LW_PARSER_CHECK_NONE
Definition: liblwgeom.h:2005
void lwfree(void *mem)
Definition: lwutil.c:244
LWGEOM * lwgeom_from_wkt(const char *wkt, const char check)
Definition: lwin_wkt.c:904
char * lwgeom_to_geojson(const LWGEOM *geo, char *srs, int precision, int has_bbox)
Takes a GEOMETRY and returns a GeoJson representation.
Definition: lwout_geojson.c:48