PostGIS  3.1.6dev-r@@SVN_REVISION@@
lwout_geojson.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * http://postgis.net
5  *
6  * PostGIS is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * PostGIS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with PostGIS. If not, see <http://www.gnu.org/licenses/>.
18  *
19  **********************************************************************
20  *
21  * Copyright 2001-2003 Refractions Research Inc.
22  * Copyright 2009-2010 Olivier Courtin <olivier.courtin@oslandia.com>
23  *
24  **********************************************************************/
25 
26 
27 #include "liblwgeom_internal.h"
28 #include <string.h> /* strlen */
29 #include <assert.h>
30 
31 static lwvarlena_t *asgeojson_point(const LWPOINT *point, const char *srs, GBOX *bbox, int precision);
32 static lwvarlena_t *asgeojson_line(const LWLINE *line, const char *srs, GBOX *bbox, int precision);
33 static lwvarlena_t *asgeojson_triangle(const LWTRIANGLE *tri, const char *srs, GBOX *bbox, int precision);
34 static lwvarlena_t *asgeojson_poly(const LWPOLY *poly, const char *srs, GBOX *bbox, int precision);
35 static lwvarlena_t *asgeojson_multipoint(const LWMPOINT *mpoint, const char *srs, GBOX *bbox, int precision);
36 static lwvarlena_t *asgeojson_multiline(const LWMLINE *mline, const char *srs, GBOX *bbox, int precision);
37 static lwvarlena_t *asgeojson_multipolygon(const LWMPOLY *mpoly, const char *srs, GBOX *bbox, int precision);
38 static lwvarlena_t *asgeojson_collection(const LWCOLLECTION *col, const char *srs, GBOX *bbox, int precision);
39 static size_t asgeojson_geom_size(const LWGEOM *geom, GBOX *bbox, int precision);
40 static size_t asgeojson_geom_buf(const LWGEOM *geom, char *output, GBOX *bbox, int precision);
41 
42 static size_t pointArray_to_geojson(POINTARRAY *pa, char *buf, int precision);
44 
49 lwgeom_to_geojson(const LWGEOM *geom, const char *srs, int precision, int has_bbox)
50 {
51  int type = geom->type;
52  GBOX *bbox = NULL;
53  GBOX tmp = {0};
54 
55  if (has_bbox)
56  {
57  /* Whether these are geography or geometry,
58  the GeoJSON expects a cartesian bounding box */
60  bbox = &tmp;
61  }
62 
63  switch (type)
64  {
65  case POINTTYPE:
66  return asgeojson_point((LWPOINT*)geom, srs, bbox, precision);
67  case LINETYPE:
68  return asgeojson_line((LWLINE*)geom, srs, bbox, precision);
69  case POLYGONTYPE:
70  return asgeojson_poly((LWPOLY*)geom, srs, bbox, precision);
71  case MULTIPOINTTYPE:
72  return asgeojson_multipoint((LWMPOINT*)geom, srs, bbox, precision);
73  case MULTILINETYPE:
74  return asgeojson_multiline((LWMLINE*)geom, srs, bbox, precision);
75  case MULTIPOLYGONTYPE:
76  return asgeojson_multipolygon((LWMPOLY*)geom, srs, bbox, precision);
77  case TRIANGLETYPE:
78  return asgeojson_triangle((LWTRIANGLE *)geom, srs, bbox, precision);
79  case TINTYPE:
80  case COLLECTIONTYPE:
81  return asgeojson_collection((LWCOLLECTION*)geom, srs, bbox, precision);
82  default:
83  lwerror("lwgeom_to_geojson: '%s' geometry type not supported",
84  lwtype_name(type));
85  }
86 
87  /* Never get here */
88  return NULL;
89 }
90 
91 
92 
96 static size_t
97 asgeojson_srs_size(const char *srs)
98 {
99  int size;
100 
101  size = sizeof("'crs':{'type':'name',");
102  size += sizeof("'properties':{'name':''}},");
103  size += strlen(srs) * sizeof(char);
104 
105  return size;
106 }
107 
108 static size_t
109 asgeojson_srs_buf(char *output, const char *srs)
110 {
111  char *ptr = output;
112 
113  ptr += sprintf(ptr, "\"crs\":{\"type\":\"name\",");
114  ptr += sprintf(ptr, "\"properties\":{\"name\":\"%s\"}},", srs);
115 
116  return (ptr-output);
117 }
118 
119 
120 
124 static size_t
126 {
127  int size;
128 
129  if (!hasz)
130  {
131  size = sizeof("\"bbox\":[,,,],");
132  size += 2 * 2 * (OUT_MAX_BYTES_DOUBLE + precision);
133  }
134  else
135  {
136  size = sizeof("\"bbox\":[,,,,,],");
137  size += 2 * 3 * (OUT_MAX_BYTES_DOUBLE + precision);
138  }
139 
140  return size;
141 }
142 
143 static size_t
144 asgeojson_bbox_buf(char *output, GBOX *bbox, int hasz, int precision)
145 {
146  char *ptr = output;
147 
148  if (!hasz)
149  ptr += sprintf(ptr, "\"bbox\":[%.*f,%.*f,%.*f,%.*f],",
150  precision, bbox->xmin, precision, bbox->ymin,
151  precision, bbox->xmax, precision, bbox->ymax);
152  else
153  ptr += sprintf(ptr, "\"bbox\":[%.*f,%.*f,%.*f,%.*f,%.*f,%.*f],",
154  precision, bbox->xmin, precision, bbox->ymin, precision, bbox->zmin,
155  precision, bbox->xmax, precision, bbox->ymax, precision, bbox->zmax);
156 
157  return (ptr-output);
158 }
159 
160 
161 
166 static size_t
167 asgeojson_point_size(const LWPOINT *point, const char *srs, GBOX *bbox, int precision)
168 {
169  int size;
170 
171  size = pointArray_geojson_size(point->point, precision);
172  size += sizeof("{'type':'Point',");
173  size += sizeof("'coordinates':}");
174 
175  if ( lwpoint_is_empty(point) )
176  size += 2; /* [] */
177 
178  if (srs) size += asgeojson_srs_size(srs);
179  if (bbox) size += asgeojson_bbox_size(FLAGS_GET_Z(point->flags), precision);
180 
181  return size;
182 }
183 
184 static size_t
185 asgeojson_point_buf(const LWPOINT *point, const char *srs, char *output, GBOX *bbox, int precision)
186 {
187  char *ptr = output;
188 
189  ptr += sprintf(ptr, "{\"type\":\"Point\",");
190  if (srs) ptr += asgeojson_srs_buf(ptr, srs);
191  if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(point->flags), precision);
192 
193  ptr += sprintf(ptr, "\"coordinates\":");
194  if ( lwpoint_is_empty(point) )
195  ptr += sprintf(ptr, "[]");
196  ptr += pointArray_to_geojson(point->point, ptr, precision);
197  ptr += sprintf(ptr, "}");
198 
199  return (ptr-output);
200 }
201 
202 static lwvarlena_t *
203 asgeojson_point(const LWPOINT *point, const char *srs, GBOX *bbox, int precision)
204 {
205  uint32_t size = asgeojson_point_size(point, srs, bbox, precision);
206  lwvarlena_t *output = (lwvarlena_t *)lwalloc(size + LWVARHDRSZ);
207  size = asgeojson_point_buf(point, srs, output->data, bbox, precision);
208  LWSIZE_SET(output->size, size + LWVARHDRSZ);
209  return output;
210 }
211 
216 static size_t
217 asgeojson_triangle_size(const LWTRIANGLE *tri, const char *srs, GBOX *bbox, int precision)
218 {
219  int size;
220 
221  size = sizeof("{'type':'Polygon',");
222  if (srs)
223  size += asgeojson_srs_size(srs);
224  if (bbox)
226  size += sizeof("'coordinates':[[]]}");
228 
229  return size;
230 }
231 
232 static size_t
233 asgeojson_triangle_buf(const LWTRIANGLE *tri, const char *srs, char *output, GBOX *bbox, int precision)
234 {
235  char *ptr = output;
236 
237  ptr += sprintf(ptr, "{\"type\":\"Polygon\",");
238  if (srs)
239  ptr += asgeojson_srs_buf(ptr, srs);
240  if (bbox)
241  ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(tri->flags), precision);
242  ptr += sprintf(ptr, "\"coordinates\":[[");
243  ptr += pointArray_to_geojson(tri->points, ptr, precision);
244  ptr += sprintf(ptr, "]]}");
245 
246  return (ptr - output);
247 }
248 
249 static lwvarlena_t *
250 asgeojson_triangle(const LWTRIANGLE *tri, const char *srs, GBOX *bbox, int precision)
251 {
252  uint32_t size = asgeojson_triangle_size(tri, srs, bbox, precision);
253  lwvarlena_t *output = (lwvarlena_t *)lwalloc(size + LWVARHDRSZ);
254  size = asgeojson_triangle_buf(tri, srs, output->data, bbox, precision);
255  LWSIZE_SET(output->size, size + LWVARHDRSZ);
256  return output;
257 }
258 
263 static size_t
264 asgeojson_line_size(const LWLINE *line, const char *srs, GBOX *bbox, int precision)
265 {
266  int size;
267 
268  size = sizeof("{'type':'LineString',");
269  if (srs) size += asgeojson_srs_size(srs);
270  if (bbox) size += asgeojson_bbox_size(FLAGS_GET_Z(line->flags), precision);
271  size += sizeof("'coordinates':[]}");
272  size += pointArray_geojson_size(line->points, precision);
273 
274  return size;
275 }
276 
277 static size_t
278 asgeojson_line_buf(const LWLINE *line, const char *srs, char *output, GBOX *bbox, int precision)
279 {
280  char *ptr=output;
281 
282  ptr += sprintf(ptr, "{\"type\":\"LineString\",");
283  if (srs) ptr += asgeojson_srs_buf(ptr, srs);
284  if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(line->flags), precision);
285  ptr += sprintf(ptr, "\"coordinates\":[");
286  ptr += pointArray_to_geojson(line->points, ptr, precision);
287  ptr += sprintf(ptr, "]}");
288 
289  return (ptr-output);
290 }
291 
292 static lwvarlena_t *
293 asgeojson_line(const LWLINE *line, const char *srs, GBOX *bbox, int precision)
294 {
295  uint32_t size = asgeojson_line_size(line, srs, bbox, precision);
296  lwvarlena_t *output = (lwvarlena_t *)lwalloc(size + LWVARHDRSZ);
297  size = asgeojson_line_buf(line, srs, output->data, bbox, precision);
298  LWSIZE_SET(output->size, size + LWVARHDRSZ);
299  return output;
300 }
301 
302 
303 
308 static size_t
309 asgeojson_poly_size(const LWPOLY *poly, const char *srs, GBOX *bbox, int precision)
310 {
311  size_t size;
312  uint32_t i;
313 
314  size = sizeof("{\"type\":\"Polygon\",");
315  if (srs) size += asgeojson_srs_size(srs);
316  if (bbox) size += asgeojson_bbox_size(FLAGS_GET_Z(poly->flags), precision);
317  size += sizeof("\"coordinates\":[");
318  for (i=0; i<poly->nrings; i++)
319  {
320  size += pointArray_geojson_size(poly->rings[i], precision);
321  size += sizeof("[]");
322  }
323  size += sizeof(",") * i;
324  size += sizeof("]}");
325 
326  return size;
327 }
328 
329 static size_t
330 asgeojson_poly_buf(const LWPOLY *poly, const char *srs, char *output, GBOX *bbox, int precision)
331 {
332  uint32_t i;
333 
334  char *ptr=output;
335 
336  ptr += sprintf(ptr, "{\"type\":\"Polygon\",");
337  if (srs) ptr += asgeojson_srs_buf(ptr, srs);
338  if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(poly->flags), precision);
339  ptr += sprintf(ptr, "\"coordinates\":[");
340  for (i=0; i<poly->nrings; i++)
341  {
342  if (i) ptr += sprintf(ptr, ",");
343  ptr += sprintf(ptr, "[");
344  ptr += pointArray_to_geojson(poly->rings[i], ptr, precision);
345  ptr += sprintf(ptr, "]");
346  }
347  ptr += sprintf(ptr, "]}");
348 
349  return (ptr-output);
350 }
351 
352 static lwvarlena_t *
353 asgeojson_poly(const LWPOLY *poly, const char *srs, GBOX *bbox, int precision)
354 {
355  uint32_t size = asgeojson_poly_size(poly, srs, bbox, precision);
356  lwvarlena_t *output = (lwvarlena_t *)lwalloc(size + LWVARHDRSZ);
357  size = asgeojson_poly_buf(poly, srs, output->data, bbox, precision);
358  LWSIZE_SET(output->size, size + LWVARHDRSZ);
359  return output;
360 }
361 
362 
363 
368 static size_t
369 asgeojson_multipoint_size(const LWMPOINT *mpoint, const char *srs, GBOX *bbox, int precision)
370 {
371  LWPOINT * point;
372  int size;
373  uint32_t i;
374 
375  size = sizeof("{'type':'MultiPoint',");
376  if (srs) size += asgeojson_srs_size(srs);
377  if (bbox) size += asgeojson_bbox_size(FLAGS_GET_Z(mpoint->flags), precision);
378  size += sizeof("'coordinates':[]}");
379 
380  for (i=0; i<mpoint->ngeoms; i++)
381  {
382  point = mpoint->geoms[i];
383  size += pointArray_geojson_size(point->point, precision);
384  }
385  size += sizeof(",") * i;
386 
387  return size;
388 }
389 
390 static size_t
391 asgeojson_multipoint_buf(const LWMPOINT *mpoint, const char *srs, char *output, GBOX *bbox, int precision)
392 {
393  LWPOINT *point;
394  uint32_t i;
395  char *ptr=output;
396 
397  ptr += sprintf(ptr, "{\"type\":\"MultiPoint\",");
398  if (srs) ptr += asgeojson_srs_buf(ptr, srs);
399  if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(mpoint->flags), precision);
400  ptr += sprintf(ptr, "\"coordinates\":[");
401 
402  for (i=0; i<mpoint->ngeoms; i++)
403  {
404  if (i) ptr += sprintf(ptr, ",");
405  point = mpoint->geoms[i];
406  ptr += pointArray_to_geojson(point->point, ptr, precision);
407  }
408  ptr += sprintf(ptr, "]}");
409 
410  return (ptr - output);
411 }
412 
413 static lwvarlena_t *
414 asgeojson_multipoint(const LWMPOINT *mpoint, const char *srs, GBOX *bbox, int precision)
415 {
416  uint32_t size = asgeojson_multipoint_size(mpoint, srs, bbox, precision);
417  lwvarlena_t *output = (lwvarlena_t *)lwalloc(size + LWVARHDRSZ);
418  size = asgeojson_multipoint_buf(mpoint, srs, output->data, bbox, precision);
419  LWSIZE_SET(output->size, size + LWVARHDRSZ);
420  return output;
421 }
422 
423 
424 
429 static size_t
430 asgeojson_multiline_size(const LWMLINE *mline, const char *srs, GBOX *bbox, int precision)
431 {
432  LWLINE * line;
433  int size;
434  uint32_t i;
435 
436  size = sizeof("{'type':'MultiLineString',");
437  if (srs) size += asgeojson_srs_size(srs);
438  if (bbox) size += asgeojson_bbox_size(FLAGS_GET_Z(mline->flags), precision);
439  size += sizeof("'coordinates':[]}");
440 
441  for (i=0 ; i<mline->ngeoms; i++)
442  {
443  line = mline->geoms[i];
444  size += pointArray_geojson_size(line->points, precision);
445  size += sizeof("[]");
446  }
447  size += sizeof(",") * i;
448 
449  return size;
450 }
451 
452 static size_t
453 asgeojson_multiline_buf(const LWMLINE *mline, const char *srs, char *output, GBOX *bbox, int precision)
454 {
455  LWLINE *line;
456  uint32_t i;
457  char *ptr=output;
458 
459  ptr += sprintf(ptr, "{\"type\":\"MultiLineString\",");
460  if (srs) ptr += asgeojson_srs_buf(ptr, srs);
461  if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(mline->flags), precision);
462  ptr += sprintf(ptr, "\"coordinates\":[");
463 
464  for (i=0; i<mline->ngeoms; i++)
465  {
466  if (i) ptr += sprintf(ptr, ",");
467  ptr += sprintf(ptr, "[");
468  line = mline->geoms[i];
469  ptr += pointArray_to_geojson(line->points, ptr, precision);
470  ptr += sprintf(ptr, "]");
471  }
472 
473  ptr += sprintf(ptr, "]}");
474 
475  return (ptr - output);
476 }
477 
478 static lwvarlena_t *
479 asgeojson_multiline(const LWMLINE *mline, const char *srs, GBOX *bbox, int precision)
480 {
481  uint32_t size = asgeojson_multiline_size(mline, srs, bbox, precision);
482  lwvarlena_t *output = (lwvarlena_t *)lwalloc(size + LWVARHDRSZ);
483  size = asgeojson_multiline_buf(mline, srs, output->data, bbox, precision);
484  LWSIZE_SET(output->size, size + LWVARHDRSZ);
485  return output;
486 }
487 
488 
489 
494 static size_t
495 asgeojson_multipolygon_size(const LWMPOLY *mpoly, const char *srs, GBOX *bbox, int precision)
496 {
497  LWPOLY *poly;
498  int size;
499  uint32_t i, j;
500 
501  size = sizeof("{'type':'MultiPolygon',");
502  if (srs) size += asgeojson_srs_size(srs);
503  if (bbox) size += asgeojson_bbox_size(FLAGS_GET_Z(mpoly->flags), precision);
504  size += sizeof("'coordinates':[]}");
505 
506  for (i=0; i < mpoly->ngeoms; i++)
507  {
508  poly = mpoly->geoms[i];
509  for (j=0 ; j <poly->nrings ; j++)
510  {
511  size += pointArray_geojson_size(poly->rings[j], precision);
512  size += sizeof("[]");
513  }
514  size += sizeof("[]");
515  }
516  size += sizeof(",") * i;
517  size += sizeof("]}");
518 
519  return size;
520 }
521 
522 static size_t
523 asgeojson_multipolygon_buf(const LWMPOLY *mpoly, const char *srs, char *output, GBOX *bbox, int precision)
524 {
525  LWPOLY *poly;
526  uint32_t i, j;
527  char *ptr=output;
528 
529  ptr += sprintf(ptr, "{\"type\":\"MultiPolygon\",");
530  if (srs) ptr += asgeojson_srs_buf(ptr, srs);
531  if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(mpoly->flags), precision);
532  ptr += sprintf(ptr, "\"coordinates\":[");
533  for (i=0; i<mpoly->ngeoms; i++)
534  {
535  if (i) ptr += sprintf(ptr, ",");
536  ptr += sprintf(ptr, "[");
537  poly = mpoly->geoms[i];
538  for (j=0 ; j < poly->nrings ; j++)
539  {
540  if (j) ptr += sprintf(ptr, ",");
541  ptr += sprintf(ptr, "[");
542  ptr += pointArray_to_geojson(poly->rings[j], ptr, precision);
543  ptr += sprintf(ptr, "]");
544  }
545  ptr += sprintf(ptr, "]");
546  }
547  ptr += sprintf(ptr, "]}");
548 
549  return (ptr - output);
550 }
551 
552 static lwvarlena_t *
553 asgeojson_multipolygon(const LWMPOLY *mpoly, const char *srs, GBOX *bbox, int precision)
554 {
555  uint32_t size = asgeojson_multipolygon_size(mpoly, srs, bbox, precision);
556  lwvarlena_t *output = (lwvarlena_t *)lwalloc(size + LWVARHDRSZ);
557  size = asgeojson_multipolygon_buf(mpoly, srs, output->data, bbox, precision);
558  LWSIZE_SET(output->size, size + LWVARHDRSZ);
559  return output;
560 }
561 
562 
563 
568 static size_t
569 asgeojson_collection_size(const LWCOLLECTION *col, const char *srs, GBOX *bbox, int precision)
570 {
571  uint32_t i;
572  size_t size;
573  LWGEOM *subgeom;
574 
575  size = sizeof("{'type':'GeometryCollection',");
576  if (srs) size += asgeojson_srs_size(srs);
577  if (bbox) size += asgeojson_bbox_size(FLAGS_GET_Z(col->flags), precision);
578  size += sizeof("'geometries':");
579 
580  for (i=0; i<col->ngeoms; i++)
581  {
582  subgeom = col->geoms[i];
583  size += asgeojson_geom_size(subgeom, NULL, precision);
584  }
585  size += sizeof(",") * i;
586  size += sizeof("]}");
587 
588  return size;
589 }
590 
591 static size_t
592 asgeojson_collection_buf(const LWCOLLECTION *col, const char *srs, char *output, GBOX *bbox, int precision)
593 {
594  uint32_t i;
595  char *ptr=output;
596  LWGEOM *subgeom;
597 
598  ptr += sprintf(ptr, "{\"type\":\"GeometryCollection\",");
599  if (srs) ptr += asgeojson_srs_buf(ptr, srs);
600  if (col->ngeoms && bbox) ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(col->flags), precision);
601  ptr += sprintf(ptr, "\"geometries\":[");
602 
603  for (i=0; i<col->ngeoms; i++)
604  {
605  if (i) ptr += sprintf(ptr, ",");
606  subgeom = col->geoms[i];
607  ptr += asgeojson_geom_buf(subgeom, ptr, NULL, precision);
608  }
609 
610  ptr += sprintf(ptr, "]}");
611 
612  return (ptr - output);
613 }
614 
615 static lwvarlena_t *
616 asgeojson_collection(const LWCOLLECTION *col, const char *srs, GBOX *bbox, int precision)
617 {
618  uint32_t size = asgeojson_collection_size(col, srs, bbox, precision);
619  lwvarlena_t *output = (lwvarlena_t *)lwalloc(size + LWVARHDRSZ);
620  size = asgeojson_collection_buf(col, srs, output->data, bbox, precision);
621  LWSIZE_SET(output->size, size + LWVARHDRSZ);
622  return output;
623 }
624 
625 
626 
627 static size_t
628 asgeojson_geom_size(const LWGEOM *geom, GBOX *bbox, int precision)
629 {
630  switch (geom->type)
631  {
632  case POINTTYPE:
633  return asgeojson_point_size((LWPOINT *)geom, NULL, bbox, precision);
634  case LINETYPE:
635  return asgeojson_line_size((LWLINE *)geom, NULL, bbox, precision);
636  case TRIANGLETYPE:
637  return asgeojson_triangle_size((LWTRIANGLE *)geom, NULL, bbox, precision);
638  case POLYGONTYPE:
639  return asgeojson_poly_size((LWPOLY *)geom, NULL, bbox, precision);
640  case MULTIPOINTTYPE:
641  return asgeojson_multipoint_size((LWMPOINT *)geom, NULL, bbox, precision);
642  case MULTILINETYPE:
643  return asgeojson_multiline_size((LWMLINE *)geom, NULL, bbox, precision);
644  case MULTIPOLYGONTYPE:
645  return asgeojson_multipolygon_size((LWMPOLY *)geom, NULL, bbox, precision);
646  default:
647  lwerror("GeoJson: geometry not supported.");
648  return 0;
649  }
650 }
651 
652 
653 static size_t
654 asgeojson_geom_buf(const LWGEOM *geom, char *output, GBOX *bbox, int precision)
655 {
656  int type = geom->type;
657  char *ptr=output;
658 
659  switch (type)
660  {
661  case POINTTYPE:
662  ptr += asgeojson_point_buf((LWPOINT*)geom, NULL, ptr, bbox, precision);
663  break;
664 
665  case LINETYPE:
666  ptr += asgeojson_line_buf((LWLINE*)geom, NULL, ptr, bbox, precision);
667  break;
668 
669  case POLYGONTYPE:
670  ptr += asgeojson_poly_buf((LWPOLY*)geom, NULL, ptr, bbox, precision);
671  break;
672 
673  case TRIANGLETYPE:
674  ptr += asgeojson_triangle_buf((LWTRIANGLE *)geom, NULL, ptr, bbox, precision);
675  break;
676 
677  case MULTIPOINTTYPE:
678  ptr += asgeojson_multipoint_buf((LWMPOINT*)geom, NULL, ptr, bbox, precision);
679  break;
680 
681  case MULTILINETYPE:
682  ptr += asgeojson_multiline_buf((LWMLINE*)geom, NULL, ptr, bbox, precision);
683  break;
684 
685  case MULTIPOLYGONTYPE:
686  ptr += asgeojson_multipolygon_buf((LWMPOLY*)geom, NULL, ptr, bbox, precision);
687  break;
688 
689  default:
690  if (bbox) lwfree(bbox);
691  lwerror("GeoJson: geometry not supported.");
692  }
693 
694  return (ptr-output);
695 }
696 
697 static size_t
698 pointArray_to_geojson(POINTARRAY *pa, char *output, int precision)
699 {
700  char *ptr = output;
701 
702  if (!FLAGS_GET_Z(pa->flags))
703  {
704  for (uint32_t i = 0; i < pa->npoints; i++)
705  {
706  if (i)
707  {
708  *ptr = ',';
709  ptr++;
710  }
711  const POINT2D *pt = getPoint2d_cp(pa, i);
712 
713  *ptr = '[';
714  ptr++;
715  ptr += lwprint_double(pt->x, precision, ptr);
716  *ptr = ',';
717  ptr++;
718  ptr += lwprint_double(pt->y, precision, ptr);
719  *ptr = ']';
720  ptr++;
721  }
722  }
723  else
724  {
725  for (uint32_t i = 0; i < pa->npoints; i++)
726  {
727  if (i)
728  {
729  *ptr = ',';
730  ptr++;
731  }
732 
733  const POINT3D *pt = getPoint3d_cp(pa, i);
734  *ptr = '[';
735  ptr++;
736  ptr += lwprint_double(pt->x, precision, ptr);
737  *ptr = ',';
738  ptr++;
739  ptr += lwprint_double(pt->y, precision, ptr);
740  *ptr = ',';
741  ptr++;
742  ptr += lwprint_double(pt->z, precision, ptr);
743  *ptr = ']';
744  ptr++;
745  }
746  }
747  *ptr = '\0';
748 
749  return (ptr-output);
750 }
751 
755 static size_t
757 {
758  if (FLAGS_NDIMS(pa->flags) == 2)
759  return (OUT_MAX_BYTES_DOUBLE + precision + sizeof(",")) * 2 * pa->npoints + sizeof(",[]");
760 
761  return (OUT_MAX_BYTES_DOUBLE + precision + sizeof(",,")) * 3 * pa->npoints + sizeof(",[]");
762 }
static uint8_t precision
Definition: cu_in_twkb.c:25
int lwgeom_calculate_gbox_cartesian(const LWGEOM *lwgeom, GBOX *gbox)
Calculate the 2-4D bounding box of a geometry.
Definition: gbox.c:740
#define COLLECTIONTYPE
Definition: liblwgeom.h:122
#define LWVARHDRSZ
Definition: liblwgeom.h:325
#define MULTILINETYPE
Definition: liblwgeom.h:120
#define LINETYPE
Definition: liblwgeom.h:117
#define MULTIPOINTTYPE
Definition: liblwgeom.h:119
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:116
#define FLAGS_GET_Z(flags)
Definition: liblwgeom.h:179
#define TINTYPE
Definition: liblwgeom.h:130
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:121
void lwfree(void *mem)
Definition: lwutil.c:242
#define FLAGS_NDIMS(flags)
Definition: liblwgeom.h:193
#define POLYGONTYPE
Definition: liblwgeom.h:118
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:216
#define LWSIZE_SET(varsize, len)
Definition: liblwgeom.h:339
#define TRIANGLETYPE
Definition: liblwgeom.h:129
void * lwalloc(size_t size)
Definition: lwutil.c:227
#define OUT_MAX_BYTES_DOUBLE
int lwpoint_is_empty(const LWPOINT *point)
int lwprint_double(double d, int maxdd, char *buf)
Definition: lwprint.c:463
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition: lwinline.h:101
static const POINT3D * getPoint3d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT3D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition: lwinline.h:113
static size_t asgeojson_srs_buf(char *output, const char *srs)
static size_t asgeojson_geom_size(const LWGEOM *geom, GBOX *bbox, int precision)
static size_t asgeojson_point_buf(const LWPOINT *point, const char *srs, char *output, GBOX *bbox, int precision)
static lwvarlena_t * asgeojson_multipolygon(const LWMPOLY *mpoly, const char *srs, GBOX *bbox, int precision)
static size_t pointArray_geojson_size(POINTARRAY *pa, int precision)
static lwvarlena_t * asgeojson_triangle(const LWTRIANGLE *tri, const char *srs, GBOX *bbox, int precision)
static size_t asgeojson_srs_size(const char *srs)
Handle SRS.
Definition: lwout_geojson.c:97
static lwvarlena_t * asgeojson_point(const LWPOINT *point, const char *srs, GBOX *bbox, int precision)
static size_t asgeojson_geom_buf(const LWGEOM *geom, char *output, GBOX *bbox, int precision)
static size_t pointArray_to_geojson(POINTARRAY *pa, char *buf, int precision)
static size_t asgeojson_point_size(const LWPOINT *point, const char *srs, GBOX *bbox, int precision)
Point Geometry.
static lwvarlena_t * asgeojson_poly(const LWPOLY *poly, const char *srs, GBOX *bbox, int precision)
static lwvarlena_t * asgeojson_line(const LWLINE *line, const char *srs, GBOX *bbox, int precision)
static size_t asgeojson_triangle_size(const LWTRIANGLE *tri, const char *srs, GBOX *bbox, int precision)
Triangle Geometry.
lwvarlena_t * lwgeom_to_geojson(const LWGEOM *geom, const char *srs, int precision, int has_bbox)
Takes a GEOMETRY and returns a GeoJson representation.
Definition: lwout_geojson.c:49
static lwvarlena_t * asgeojson_multipoint(const LWMPOINT *mpoint, const char *srs, GBOX *bbox, int precision)
static size_t asgeojson_bbox_size(int hasz, int precision)
Handle Bbox.
static lwvarlena_t * asgeojson_collection(const LWCOLLECTION *col, const char *srs, GBOX *bbox, int precision)
static size_t asgeojson_triangle_buf(const LWTRIANGLE *tri, const char *srs, char *output, GBOX *bbox, int precision)
static size_t asgeojson_bbox_buf(char *output, GBOX *bbox, int hasz, int precision)
static lwvarlena_t * asgeojson_multiline(const LWMLINE *mline, const char *srs, GBOX *bbox, int precision)
type
Definition: ovdump.py:42
double ymax
Definition: liblwgeom.h:371
double zmax
Definition: liblwgeom.h:373
double xmax
Definition: liblwgeom.h:369
double zmin
Definition: liblwgeom.h:372
double ymin
Definition: liblwgeom.h:370
double xmin
Definition: liblwgeom.h:368
lwflags_t flags
Definition: liblwgeom.h:591
uint32_t ngeoms
Definition: liblwgeom.h:594
LWGEOM ** geoms
Definition: liblwgeom.h:589
uint8_t type
Definition: liblwgeom.h:476
lwflags_t flags
Definition: liblwgeom.h:499
POINTARRAY * points
Definition: liblwgeom.h:497
lwflags_t flags
Definition: liblwgeom.h:563
LWLINE ** geoms
Definition: liblwgeom.h:561
uint32_t ngeoms
Definition: liblwgeom.h:566
lwflags_t flags
Definition: liblwgeom.h:549
uint32_t ngeoms
Definition: liblwgeom.h:552
LWPOINT ** geoms
Definition: liblwgeom.h:547
uint32_t ngeoms
Definition: liblwgeom.h:580
LWPOLY ** geoms
Definition: liblwgeom.h:575
lwflags_t flags
Definition: liblwgeom.h:577
POINTARRAY * point
Definition: liblwgeom.h:485
lwflags_t flags
Definition: liblwgeom.h:487
POINTARRAY ** rings
Definition: liblwgeom.h:533
uint32_t nrings
Definition: liblwgeom.h:538
lwflags_t flags
Definition: liblwgeom.h:535
lwflags_t flags
Definition: liblwgeom.h:511
POINTARRAY * points
Definition: liblwgeom.h:509
double y
Definition: liblwgeom.h:404
double x
Definition: liblwgeom.h:404
double z
Definition: liblwgeom.h:416
double x
Definition: liblwgeom.h:416
double y
Definition: liblwgeom.h:416
lwflags_t flags
Definition: liblwgeom.h:445
uint32_t npoints
Definition: liblwgeom.h:441
uint32_t size
Definition: liblwgeom.h:321
char data[]
Definition: liblwgeom.h:322