PostGIS  3.0.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 char *asgeojson_point(const LWPOINT *point, char *srs, GBOX *bbox, int precision);
32 static char *asgeojson_line(const LWLINE *line, char *srs, GBOX *bbox, int precision);
33 static char *asgeojson_triangle(const LWTRIANGLE *tri, char *srs, GBOX *bbox, int precision);
34 static char *asgeojson_poly(const LWPOLY *poly, char *srs, GBOX *bbox, int precision);
35 static char *asgeojson_multipoint(const LWMPOINT *mpoint, char *srs, GBOX *bbox, int precision);
36 static char *asgeojson_multiline(const LWMLINE *mline, char *srs, GBOX *bbox, int precision);
37 static char *asgeojson_multipolygon(const LWMPOLY *mpoly, char *srs, GBOX *bbox, int precision);
38 static char *asgeojson_collection(const LWCOLLECTION *col, 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 
48 char *
49 lwgeom_to_geojson(const LWGEOM *geom, char *srs, int precision, int has_bbox)
50 {
51  int type = geom->type;
52  GBOX *bbox = NULL;
53  GBOX tmp;
54 
56 
57  if (has_bbox)
58  {
59  /* Whether these are geography or geometry,
60  the GeoJSON expects a cartesian bounding box */
62  bbox = &tmp;
63  }
64 
65  switch (type)
66  {
67  case POINTTYPE:
68  return asgeojson_point((LWPOINT*)geom, srs, bbox, precision);
69  case LINETYPE:
70  return asgeojson_line((LWLINE*)geom, srs, bbox, precision);
71  case POLYGONTYPE:
72  return asgeojson_poly((LWPOLY*)geom, srs, bbox, precision);
73  case MULTIPOINTTYPE:
74  return asgeojson_multipoint((LWMPOINT*)geom, srs, bbox, precision);
75  case MULTILINETYPE:
76  return asgeojson_multiline((LWMLINE*)geom, srs, bbox, precision);
77  case MULTIPOLYGONTYPE:
78  return asgeojson_multipolygon((LWMPOLY*)geom, srs, bbox, precision);
79  case TRIANGLETYPE:
80  return asgeojson_triangle((LWTRIANGLE *)geom, srs, bbox, precision);
81  case TINTYPE:
82  case COLLECTIONTYPE:
83  return asgeojson_collection((LWCOLLECTION*)geom, srs, bbox, precision);
84  default:
85  lwerror("lwgeom_to_geojson: '%s' geometry type not supported",
86  lwtype_name(type));
87  }
88 
89  /* Never get here */
90  return NULL;
91 }
92 
93 
94 
98 static size_t
100 {
101  int size;
102 
103  size = sizeof("'crs':{'type':'name',");
104  size += sizeof("'properties':{'name':''}},");
105  size += strlen(srs) * sizeof(char);
106 
107  return size;
108 }
109 
110 static size_t
111 asgeojson_srs_buf(char *output, char *srs)
112 {
113  char *ptr = output;
114 
115  ptr += sprintf(ptr, "\"crs\":{\"type\":\"name\",");
116  ptr += sprintf(ptr, "\"properties\":{\"name\":\"%s\"}},", srs);
117 
118  return (ptr-output);
119 }
120 
121 
122 
126 static size_t
128 {
129  int size;
130 
131  if (!hasz)
132  {
133  size = sizeof("\"bbox\":[,,,],");
134  size += 2 * 2 * (OUT_MAX_DIGS_DOUBLE + precision);
135  }
136  else
137  {
138  size = sizeof("\"bbox\":[,,,,,],");
139  size += 2 * 3 * (OUT_MAX_DIGS_DOUBLE + precision);
140  }
141 
142  return size;
143 }
144 
145 static size_t
146 asgeojson_bbox_buf(char *output, GBOX *bbox, int hasz, int precision)
147 {
148  char *ptr = output;
149 
150  if (!hasz)
151  ptr += sprintf(ptr, "\"bbox\":[%.*f,%.*f,%.*f,%.*f],",
152  precision, bbox->xmin, precision, bbox->ymin,
153  precision, bbox->xmax, precision, bbox->ymax);
154  else
155  ptr += sprintf(ptr, "\"bbox\":[%.*f,%.*f,%.*f,%.*f,%.*f,%.*f],",
156  precision, bbox->xmin, precision, bbox->ymin, precision, bbox->zmin,
157  precision, bbox->xmax, precision, bbox->ymax, precision, bbox->zmax);
158 
159  return (ptr-output);
160 }
161 
162 
163 
168 static size_t
169 asgeojson_point_size(const LWPOINT *point, char *srs, GBOX *bbox, int precision)
170 {
171  int size;
172 
173  size = pointArray_geojson_size(point->point, precision);
174  size += sizeof("{'type':'Point',");
175  size += sizeof("'coordinates':}");
176 
177  if ( lwpoint_is_empty(point) )
178  size += 2; /* [] */
179 
180  if (srs) size += asgeojson_srs_size(srs);
181  if (bbox) size += asgeojson_bbox_size(FLAGS_GET_Z(point->flags), precision);
182 
183  return size;
184 }
185 
186 static size_t
187 asgeojson_point_buf(const LWPOINT *point, char *srs, char *output, GBOX *bbox, int precision)
188 {
189  char *ptr = output;
190 
191  ptr += sprintf(ptr, "{\"type\":\"Point\",");
192  if (srs) ptr += asgeojson_srs_buf(ptr, srs);
193  if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(point->flags), precision);
194 
195  ptr += sprintf(ptr, "\"coordinates\":");
196  if ( lwpoint_is_empty(point) )
197  ptr += sprintf(ptr, "[]");
198  ptr += pointArray_to_geojson(point->point, ptr, precision);
199  ptr += sprintf(ptr, "}");
200 
201  return (ptr-output);
202 }
203 
204 static char *
205 asgeojson_point(const LWPOINT *point, char *srs, GBOX *bbox, int precision)
206 {
207  char *output;
208  int size;
209 
210  size = asgeojson_point_size(point, srs, bbox, precision);
211  output = lwalloc(size);
212  asgeojson_point_buf(point, srs, output, bbox, precision);
213  return output;
214 }
215 
220 static size_t
221 asgeojson_triangle_size(const LWTRIANGLE *tri, char *srs, GBOX *bbox, int precision)
222 {
223  int size;
224 
225  size = sizeof("{'type':'Polygon',");
226  if (srs)
227  size += asgeojson_srs_size(srs);
228  if (bbox)
230  size += sizeof("'coordinates':[[]]}");
232 
233  return size;
234 }
235 
236 static size_t
237 asgeojson_triangle_buf(const LWTRIANGLE *tri, char *srs, char *output, GBOX *bbox, int precision)
238 {
239  char *ptr = output;
240 
241  ptr += sprintf(ptr, "{\"type\":\"Polygon\",");
242  if (srs)
243  ptr += asgeojson_srs_buf(ptr, srs);
244  if (bbox)
245  ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(tri->flags), precision);
246  ptr += sprintf(ptr, "\"coordinates\":[[");
247  ptr += pointArray_to_geojson(tri->points, ptr, precision);
248  ptr += sprintf(ptr, "]]}");
249 
250  return (ptr - output);
251 }
252 
253 static char *
254 asgeojson_triangle(const LWTRIANGLE *tri, char *srs, GBOX *bbox, int precision)
255 {
256  char *output;
257  int size;
258 
259  size = asgeojson_triangle_size(tri, srs, bbox, precision);
260  output = lwalloc(size);
261  asgeojson_triangle_buf(tri, srs, output, bbox, precision);
262 
263  return output;
264 }
265 
270 static size_t
271 asgeojson_line_size(const LWLINE *line, char *srs, GBOX *bbox, int precision)
272 {
273  int size;
274 
275  size = sizeof("{'type':'LineString',");
276  if (srs) size += asgeojson_srs_size(srs);
277  if (bbox) size += asgeojson_bbox_size(FLAGS_GET_Z(line->flags), precision);
278  size += sizeof("'coordinates':[]}");
279  size += pointArray_geojson_size(line->points, precision);
280 
281  return size;
282 }
283 
284 static size_t
285 asgeojson_line_buf(const LWLINE *line, char *srs, char *output, GBOX *bbox, int precision)
286 {
287  char *ptr=output;
288 
289  ptr += sprintf(ptr, "{\"type\":\"LineString\",");
290  if (srs) ptr += asgeojson_srs_buf(ptr, srs);
291  if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(line->flags), precision);
292  ptr += sprintf(ptr, "\"coordinates\":[");
293  ptr += pointArray_to_geojson(line->points, ptr, precision);
294  ptr += sprintf(ptr, "]}");
295 
296  return (ptr-output);
297 }
298 
299 static char *
300 asgeojson_line(const LWLINE *line, char *srs, GBOX *bbox, int precision)
301 {
302  char *output;
303  int size;
304 
305  size = asgeojson_line_size(line, srs, bbox, precision);
306  output = lwalloc(size);
307  asgeojson_line_buf(line, srs, output, bbox, precision);
308 
309  return output;
310 }
311 
312 
313 
318 static size_t
319 asgeojson_poly_size(const LWPOLY *poly, char *srs, GBOX *bbox, int precision)
320 {
321  size_t size;
322  uint32_t i;
323 
324  size = sizeof("{\"type\":\"Polygon\",");
325  if (srs) size += asgeojson_srs_size(srs);
326  if (bbox) size += asgeojson_bbox_size(FLAGS_GET_Z(poly->flags), precision);
327  size += sizeof("\"coordinates\":[");
328  for (i=0; i<poly->nrings; i++)
329  {
330  size += pointArray_geojson_size(poly->rings[i], precision);
331  size += sizeof("[]");
332  }
333  size += sizeof(",") * i;
334  size += sizeof("]}");
335 
336  return size;
337 }
338 
339 static size_t
340 asgeojson_poly_buf(const LWPOLY *poly, char *srs, char *output, GBOX *bbox, int precision)
341 {
342  uint32_t i;
343 
344  char *ptr=output;
345 
346  ptr += sprintf(ptr, "{\"type\":\"Polygon\",");
347  if (srs) ptr += asgeojson_srs_buf(ptr, srs);
348  if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(poly->flags), precision);
349  ptr += sprintf(ptr, "\"coordinates\":[");
350  for (i=0; i<poly->nrings; i++)
351  {
352  if (i) ptr += sprintf(ptr, ",");
353  ptr += sprintf(ptr, "[");
354  ptr += pointArray_to_geojson(poly->rings[i], ptr, precision);
355  ptr += sprintf(ptr, "]");
356  }
357  ptr += sprintf(ptr, "]}");
358 
359  return (ptr-output);
360 }
361 
362 static char *
363 asgeojson_poly(const LWPOLY *poly, char *srs, GBOX *bbox, int precision)
364 {
365  char *output;
366  int size;
367 
368  size = asgeojson_poly_size(poly, srs, bbox, precision);
369  output = lwalloc(size);
370  asgeojson_poly_buf(poly, srs, output, bbox, precision);
371 
372  return output;
373 }
374 
375 
376 
381 static size_t
382 asgeojson_multipoint_size(const LWMPOINT *mpoint, char *srs, GBOX *bbox, int precision)
383 {
384  LWPOINT * point;
385  int size;
386  uint32_t i;
387 
388  size = sizeof("{'type':'MultiPoint',");
389  if (srs) size += asgeojson_srs_size(srs);
390  if (bbox) size += asgeojson_bbox_size(FLAGS_GET_Z(mpoint->flags), precision);
391  size += sizeof("'coordinates':[]}");
392 
393  for (i=0; i<mpoint->ngeoms; i++)
394  {
395  point = mpoint->geoms[i];
396  size += pointArray_geojson_size(point->point, precision);
397  }
398  size += sizeof(",") * i;
399 
400  return size;
401 }
402 
403 static size_t
404 asgeojson_multipoint_buf(const LWMPOINT *mpoint, char *srs, char *output, GBOX *bbox, int precision)
405 {
406  LWPOINT *point;
407  uint32_t i;
408  char *ptr=output;
409 
410  ptr += sprintf(ptr, "{\"type\":\"MultiPoint\",");
411  if (srs) ptr += asgeojson_srs_buf(ptr, srs);
412  if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(mpoint->flags), precision);
413  ptr += sprintf(ptr, "\"coordinates\":[");
414 
415  for (i=0; i<mpoint->ngeoms; i++)
416  {
417  if (i) ptr += sprintf(ptr, ",");
418  point = mpoint->geoms[i];
419  ptr += pointArray_to_geojson(point->point, ptr, precision);
420  }
421  ptr += sprintf(ptr, "]}");
422 
423  return (ptr - output);
424 }
425 
426 static char *
427 asgeojson_multipoint(const LWMPOINT *mpoint, char *srs, GBOX *bbox, int precision)
428 {
429  char *output;
430  int size;
431 
432  size = asgeojson_multipoint_size(mpoint, srs, bbox, precision);
433  output = lwalloc(size);
434  asgeojson_multipoint_buf(mpoint, srs, output, bbox, precision);
435 
436  return output;
437 }
438 
439 
440 
445 static size_t
446 asgeojson_multiline_size(const LWMLINE *mline, char *srs, GBOX *bbox, int precision)
447 {
448  LWLINE * line;
449  int size;
450  uint32_t i;
451 
452  size = sizeof("{'type':'MultiLineString',");
453  if (srs) size += asgeojson_srs_size(srs);
454  if (bbox) size += asgeojson_bbox_size(FLAGS_GET_Z(mline->flags), precision);
455  size += sizeof("'coordinates':[]}");
456 
457  for (i=0 ; i<mline->ngeoms; i++)
458  {
459  line = mline->geoms[i];
460  size += pointArray_geojson_size(line->points, precision);
461  size += sizeof("[]");
462  }
463  size += sizeof(",") * i;
464 
465  return size;
466 }
467 
468 static size_t
469 asgeojson_multiline_buf(const LWMLINE *mline, char *srs, char *output, GBOX *bbox, int precision)
470 {
471  LWLINE *line;
472  uint32_t i;
473  char *ptr=output;
474 
475  ptr += sprintf(ptr, "{\"type\":\"MultiLineString\",");
476  if (srs) ptr += asgeojson_srs_buf(ptr, srs);
477  if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(mline->flags), precision);
478  ptr += sprintf(ptr, "\"coordinates\":[");
479 
480  for (i=0; i<mline->ngeoms; i++)
481  {
482  if (i) ptr += sprintf(ptr, ",");
483  ptr += sprintf(ptr, "[");
484  line = mline->geoms[i];
485  ptr += pointArray_to_geojson(line->points, ptr, precision);
486  ptr += sprintf(ptr, "]");
487  }
488 
489  ptr += sprintf(ptr, "]}");
490 
491  return (ptr - output);
492 }
493 
494 static char *
495 asgeojson_multiline(const LWMLINE *mline, char *srs, GBOX *bbox, int precision)
496 {
497  char *output;
498  int size;
499 
500  size = asgeojson_multiline_size(mline, srs, bbox, precision);
501  output = lwalloc(size);
502  asgeojson_multiline_buf(mline, srs, output, bbox, precision);
503 
504  return output;
505 }
506 
507 
508 
513 static size_t
514 asgeojson_multipolygon_size(const LWMPOLY *mpoly, char *srs, GBOX *bbox, int precision)
515 {
516  LWPOLY *poly;
517  int size;
518  uint32_t i, j;
519 
520  size = sizeof("{'type':'MultiPolygon',");
521  if (srs) size += asgeojson_srs_size(srs);
522  if (bbox) size += asgeojson_bbox_size(FLAGS_GET_Z(mpoly->flags), precision);
523  size += sizeof("'coordinates':[]}");
524 
525  for (i=0; i < mpoly->ngeoms; i++)
526  {
527  poly = mpoly->geoms[i];
528  for (j=0 ; j <poly->nrings ; j++)
529  {
530  size += pointArray_geojson_size(poly->rings[j], precision);
531  size += sizeof("[]");
532  }
533  size += sizeof("[]");
534  }
535  size += sizeof(",") * i;
536  size += sizeof("]}");
537 
538  return size;
539 }
540 
541 static size_t
542 asgeojson_multipolygon_buf(const LWMPOLY *mpoly, char *srs, char *output, GBOX *bbox, int precision)
543 {
544  LWPOLY *poly;
545  uint32_t i, j;
546  char *ptr=output;
547 
548  ptr += sprintf(ptr, "{\"type\":\"MultiPolygon\",");
549  if (srs) ptr += asgeojson_srs_buf(ptr, srs);
550  if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(mpoly->flags), precision);
551  ptr += sprintf(ptr, "\"coordinates\":[");
552  for (i=0; i<mpoly->ngeoms; i++)
553  {
554  if (i) ptr += sprintf(ptr, ",");
555  ptr += sprintf(ptr, "[");
556  poly = mpoly->geoms[i];
557  for (j=0 ; j < poly->nrings ; j++)
558  {
559  if (j) ptr += sprintf(ptr, ",");
560  ptr += sprintf(ptr, "[");
561  ptr += pointArray_to_geojson(poly->rings[j], ptr, precision);
562  ptr += sprintf(ptr, "]");
563  }
564  ptr += sprintf(ptr, "]");
565  }
566  ptr += sprintf(ptr, "]}");
567 
568  return (ptr - output);
569 }
570 
571 static char *
572 asgeojson_multipolygon(const LWMPOLY *mpoly, char *srs, GBOX *bbox, int precision)
573 {
574  char *output;
575  int size;
576 
577  size = asgeojson_multipolygon_size(mpoly, srs, bbox, precision);
578  output = lwalloc(size);
579  asgeojson_multipolygon_buf(mpoly, srs, output, bbox, precision);
580 
581  return output;
582 }
583 
584 
585 
590 static size_t
591 asgeojson_collection_size(const LWCOLLECTION *col, char *srs, GBOX *bbox, int precision)
592 {
593  uint32_t i;
594  size_t size;
595  LWGEOM *subgeom;
596 
597  size = sizeof("{'type':'GeometryCollection',");
598  if (srs) size += asgeojson_srs_size(srs);
599  if (bbox) size += asgeojson_bbox_size(FLAGS_GET_Z(col->flags), precision);
600  size += sizeof("'geometries':");
601 
602  for (i=0; i<col->ngeoms; i++)
603  {
604  subgeom = col->geoms[i];
605  size += asgeojson_geom_size(subgeom, NULL, precision);
606  }
607  size += sizeof(",") * i;
608  size += sizeof("]}");
609 
610  return size;
611 }
612 
613 static size_t
614 asgeojson_collection_buf(const LWCOLLECTION *col, char *srs, char *output, GBOX *bbox, int precision)
615 {
616  uint32_t i;
617  char *ptr=output;
618  LWGEOM *subgeom;
619 
620  ptr += sprintf(ptr, "{\"type\":\"GeometryCollection\",");
621  if (srs) ptr += asgeojson_srs_buf(ptr, srs);
622  if (col->ngeoms && bbox) ptr += asgeojson_bbox_buf(ptr, bbox, FLAGS_GET_Z(col->flags), precision);
623  ptr += sprintf(ptr, "\"geometries\":[");
624 
625  for (i=0; i<col->ngeoms; i++)
626  {
627  if (i) ptr += sprintf(ptr, ",");
628  subgeom = col->geoms[i];
629  ptr += asgeojson_geom_buf(subgeom, ptr, NULL, precision);
630  }
631 
632  ptr += sprintf(ptr, "]}");
633 
634  return (ptr - output);
635 }
636 
637 static char *
638 asgeojson_collection(const LWCOLLECTION *col, char *srs, GBOX *bbox, int precision)
639 {
640  char *output;
641  int size;
642 
643  size = asgeojson_collection_size(col, srs, bbox, precision);
644  output = lwalloc(size);
645  asgeojson_collection_buf(col, srs, output, bbox, precision);
646 
647  return output;
648 }
649 
650 
651 
652 static size_t
653 asgeojson_geom_size(const LWGEOM *geom, GBOX *bbox, int precision)
654 {
655  switch (geom->type)
656  {
657  case POINTTYPE:
658  return asgeojson_point_size((LWPOINT *)geom, NULL, bbox, precision);
659  case LINETYPE:
660  return asgeojson_line_size((LWLINE *)geom, NULL, bbox, precision);
661  case TRIANGLETYPE:
662  return asgeojson_triangle_size((LWTRIANGLE *)geom, NULL, bbox, precision);
663  case POLYGONTYPE:
664  return asgeojson_poly_size((LWPOLY *)geom, NULL, bbox, precision);
665  case MULTIPOINTTYPE:
666  return asgeojson_multipoint_size((LWMPOINT *)geom, NULL, bbox, precision);
667  case MULTILINETYPE:
668  return asgeojson_multiline_size((LWMLINE *)geom, NULL, bbox, precision);
669  case MULTIPOLYGONTYPE:
670  return asgeojson_multipolygon_size((LWMPOLY *)geom, NULL, bbox, precision);
671  default:
672  lwerror("GeoJson: geometry not supported.");
673  return 0;
674  }
675 }
676 
677 
678 static size_t
679 asgeojson_geom_buf(const LWGEOM *geom, char *output, GBOX *bbox, int precision)
680 {
681  int type = geom->type;
682  char *ptr=output;
683 
684  switch (type)
685  {
686  case POINTTYPE:
687  ptr += asgeojson_point_buf((LWPOINT*)geom, NULL, ptr, bbox, precision);
688  break;
689 
690  case LINETYPE:
691  ptr += asgeojson_line_buf((LWLINE*)geom, NULL, ptr, bbox, precision);
692  break;
693 
694  case POLYGONTYPE:
695  ptr += asgeojson_poly_buf((LWPOLY*)geom, NULL, ptr, bbox, precision);
696  break;
697 
698  case TRIANGLETYPE:
699  ptr += asgeojson_triangle_buf((LWTRIANGLE *)geom, NULL, ptr, bbox, precision);
700  break;
701 
702  case MULTIPOINTTYPE:
703  ptr += asgeojson_multipoint_buf((LWMPOINT*)geom, NULL, ptr, bbox, precision);
704  break;
705 
706  case MULTILINETYPE:
707  ptr += asgeojson_multiline_buf((LWMLINE*)geom, NULL, ptr, bbox, precision);
708  break;
709 
710  case MULTIPOLYGONTYPE:
711  ptr += asgeojson_multipolygon_buf((LWMPOLY*)geom, NULL, ptr, bbox, precision);
712  break;
713 
714  default:
715  if (bbox) lwfree(bbox);
716  lwerror("GeoJson: geometry not supported.");
717  }
718 
719  return (ptr-output);
720 }
721 
722 static size_t
723 pointArray_to_geojson(POINTARRAY *pa, char *output, int precision)
724 {
725  uint32_t i;
726  char *ptr;
729  char z[OUT_DOUBLE_BUFFER_SIZE];
730 
731  assert ( precision <= OUT_MAX_DOUBLE_PRECISION );
732  ptr = output;
733 
734  /* TODO: rewrite this loop to be simpler and possibly quicker */
735  if (!FLAGS_GET_Z(pa->flags))
736  {
737  for (i=0; i<pa->npoints; i++)
738  {
739  const POINT2D *pt;
740  pt = getPoint2d_cp(pa, i);
741 
746 
747  if ( i ) ptr += sprintf(ptr, ",");
748  ptr += sprintf(ptr, "[%s,%s]", x, y);
749  }
750  }
751  else
752  {
753  for (i=0; i<pa->npoints; i++)
754  {
755  const POINT3D *pt = getPoint3d_cp(pa, i);
756 
763 
764  if ( i ) ptr += sprintf(ptr, ",");
765  ptr += sprintf(ptr, "[%s,%s,%s]", x, y, z);
766  }
767  }
768 
769  return (ptr-output);
770 }
771 
775 static size_t
777 {
778  assert ( precision <= OUT_MAX_DOUBLE_PRECISION );
779  if (FLAGS_NDIMS(pa->flags) == 2)
780  return (OUT_MAX_DIGS_DOUBLE + precision + sizeof(","))
781  * 2 * pa->npoints + sizeof(",[]");
782 
783  return (OUT_MAX_DIGS_DOUBLE + precision + sizeof(",,"))
784  * 3 * pa->npoints + sizeof(",[]");
785 }
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 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 TRIANGLETYPE
Definition: liblwgeom.h:129
void * lwalloc(size_t size)
Definition: lwutil.c:227
#define OUT_MAX_DIGS_DOUBLE
#define OUT_DOUBLE_BUFFER_SIZE
int lwpoint_is_empty(const LWPOINT *point)
#define OUT_MAX_DOUBLE_PRECISION
int lwprint_double(double d, int maxdd, char *buf, size_t bufsize)
Definition: lwprint.c:492
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:91
static const POINT3D * getPoint3d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition: lwinline.h:103
static size_t asgeojson_triangle_size(const LWTRIANGLE *tri, char *srs, GBOX *bbox, int precision)
Triangle Geometry.
static char * asgeojson_line(const LWLINE *line, char *srs, GBOX *bbox, int precision)
static size_t asgeojson_geom_size(const LWGEOM *geom, GBOX *bbox, int precision)
static size_t asgeojson_point_buf(const LWPOINT *point, char *srs, char *output, GBOX *bbox, int precision)
static char * asgeojson_multipoint(const LWMPOINT *mpoint, char *srs, GBOX *bbox, int precision)
static size_t pointArray_geojson_size(POINTARRAY *pa, int precision)
static char * asgeojson_point(const LWPOINT *point, 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 char * asgeojson_multiline(const LWMLINE *mline, char *srs, GBOX *bbox, int precision)
static size_t asgeojson_srs_size(char *srs)
Handle SRS.
Definition: lwout_geojson.c:99
static char * asgeojson_poly(const LWPOLY *poly, char *srs, GBOX *bbox, int precision)
static char * asgeojson_multipolygon(const LWMPOLY *mpoly, char *srs, GBOX *bbox, int precision)
static char * asgeojson_collection(const LWCOLLECTION *col, char *srs, GBOX *bbox, int precision)
static size_t asgeojson_bbox_size(int hasz, int precision)
Handle Bbox.
static size_t asgeojson_point_size(const LWPOINT *point, char *srs, GBOX *bbox, int precision)
Point Geometry.
char * lwgeom_to_geojson(const LWGEOM *geom, char *srs, int precision, int has_bbox)
Takes a GEOMETRY and returns a GeoJson representation.
Definition: lwout_geojson.c:49
static size_t asgeojson_srs_buf(char *output, char *srs)
static size_t asgeojson_triangle_buf(const LWTRIANGLE *tri, char *srs, char *output, GBOX *bbox, int precision)
static size_t asgeojson_bbox_buf(char *output, GBOX *bbox, int hasz, int precision)
static char * asgeojson_triangle(const LWTRIANGLE *tri, char *srs, GBOX *bbox, int precision)
type
Definition: ovdump.py:42
double ymax
Definition: liblwgeom.h:343
double zmax
Definition: liblwgeom.h:345
double xmax
Definition: liblwgeom.h:341
double zmin
Definition: liblwgeom.h:344
double ymin
Definition: liblwgeom.h:342
double xmin
Definition: liblwgeom.h:340
lwflags_t flags
Definition: liblwgeom.h:563
uint32_t ngeoms
Definition: liblwgeom.h:566
LWGEOM ** geoms
Definition: liblwgeom.h:561
uint8_t type
Definition: liblwgeom.h:448
lwflags_t flags
Definition: liblwgeom.h:471
POINTARRAY * points
Definition: liblwgeom.h:469
lwflags_t flags
Definition: liblwgeom.h:535
LWLINE ** geoms
Definition: liblwgeom.h:533
uint32_t ngeoms
Definition: liblwgeom.h:538
lwflags_t flags
Definition: liblwgeom.h:521
uint32_t ngeoms
Definition: liblwgeom.h:524
LWPOINT ** geoms
Definition: liblwgeom.h:519
uint32_t ngeoms
Definition: liblwgeom.h:552
LWPOLY ** geoms
Definition: liblwgeom.h:547
lwflags_t flags
Definition: liblwgeom.h:549
POINTARRAY * point
Definition: liblwgeom.h:457
lwflags_t flags
Definition: liblwgeom.h:459
POINTARRAY ** rings
Definition: liblwgeom.h:505
uint32_t nrings
Definition: liblwgeom.h:510
lwflags_t flags
Definition: liblwgeom.h:507
lwflags_t flags
Definition: liblwgeom.h:483
POINTARRAY * points
Definition: liblwgeom.h:481
double y
Definition: liblwgeom.h:376
double x
Definition: liblwgeom.h:376
double z
Definition: liblwgeom.h:388
double x
Definition: liblwgeom.h:388
double y
Definition: liblwgeom.h:388
lwflags_t flags
Definition: liblwgeom.h:417
uint32_t npoints
Definition: liblwgeom.h:413