source: trunk/liblwgeom/lwout_geojson.c @ 5311

Last change on this file since 5311 was 5311, checked in by colivier, 6 years ago

Fix #441. And introduce a change in behaviour: if geometryCollection and bbox, not sub geoms bbox are provided anymore

  • Property svn:keywords set to Id
File size: 18.4 KB
Line 
1/**********************************************************************
2 * $Id: lwout_geojson.c 5311 2010-02-22 22:04:18Z colivier $
3 *
4 * PostGIS - Spatial Types for PostgreSQL
5 * http://postgis.refractions.net
6 * Copyright 2001-2003 Refractions Research Inc.
7 * Copyright 2009-2010 Olivier Courtin <olivier.courtin@oslandia.com>
8 *
9 * This is free software; you can redistribute and/or modify it under
10 * the terms of hte GNU General Public Licence. See the COPYING file.
11 *
12 **********************************************************************/
13
14#include "liblwgeom.h"
15#include <math.h>       /* fabs */
16#include <string.h>     /* strlen */
17
18static char *asgeojson_point(LWPOINT *point, char *srs, BOX3D *bbox, int precision);
19static char *asgeojson_line(LWLINE *line, char *srs, BOX3D *bbox, int precision);
20static char *asgeojson_poly(LWPOLY *poly, char *srs, BOX3D *bbox, int precision);
21static char * asgeojson_multipoint(LWGEOM_INSPECTED *insp, char *srs, BOX3D *bbox, int precision);
22static char * asgeojson_multiline(LWGEOM_INSPECTED *insp, char *srs, BOX3D *bbox, int precision);
23static char * asgeojson_multipolygon(LWGEOM_INSPECTED *insp, char *srs, BOX3D *bbox, int precision);
24static char * asgeojson_collection(LWGEOM_INSPECTED *insp, char *srs, BOX3D *bbox, int precision);
25static size_t asgeojson_inspected_size(LWGEOM_INSPECTED *insp, BOX3D *bbox, int precision);
26static size_t asgeojson_inspected_buf(LWGEOM_INSPECTED *insp, char *output, BOX3D *bbox, int precision);
27
28static size_t pointArray_to_geojson(POINTARRAY *pa, char *buf, int precision);
29static size_t pointArray_geojson_size(POINTARRAY *pa, int precision);
30
31/**
32 * Takes a GEOMETRY and returns a GeoJson representation
33 */
34char *
35lwgeom_to_geojson(uchar *geom, char *srs, int precision, int has_bbox)
36{
37        int type;
38        LWPOINT *point;
39        LWLINE *line;
40        LWPOLY *poly;
41        LWGEOM_INSPECTED *insp;
42        BOX3D * bbox = NULL;
43        char * ret = NULL;
44
45        type = lwgeom_getType(geom[0]);
46
47        if (has_bbox) bbox = compute_serialized_box3d(geom);
48
49        switch (type)
50        {
51        case POINTTYPE:
52                point = lwpoint_deserialize(geom);
53                ret = asgeojson_point(point, srs, bbox, precision);
54                break;
55
56        case LINETYPE:
57                line = lwline_deserialize(geom);
58                ret = asgeojson_line(line, srs, bbox, precision);
59                break;
60
61        case POLYGONTYPE:
62                poly = lwpoly_deserialize(geom);
63                ret = asgeojson_poly(poly, srs, bbox, precision);
64                break;
65
66        case MULTIPOINTTYPE:
67                insp = lwgeom_inspect(geom);
68                ret = asgeojson_multipoint(insp, srs, bbox, precision);
69                break;
70
71        case MULTILINETYPE:
72                insp = lwgeom_inspect(geom);
73                ret = asgeojson_multiline(insp, srs, bbox, precision);
74                break;
75
76        case MULTIPOLYGONTYPE:
77                insp = lwgeom_inspect(geom);
78                ret = asgeojson_multipolygon(insp, srs, bbox, precision);
79                break;
80
81        case COLLECTIONTYPE:
82                insp = lwgeom_inspect(geom);
83                ret = asgeojson_collection(insp, srs, bbox, precision);
84                break;
85
86        default:
87                if (bbox)
88                {
89                        lwfree(bbox);
90                        bbox = NULL;
91                }
92                lwerror("lwgeom_to_geojson: '%s' geometry type not supported",
93                        lwgeom_typename(type));
94        }
95
96        if (bbox)
97        {
98                lwfree(bbox);
99                bbox = NULL;
100        }
101
102        return ret;
103}
104
105
106
107/**
108 * Handle SRS
109 */
110static size_t
111asgeojson_srs_size(char *srs)
112{
113        int size;
114
115        size = sizeof("'crs':{'type':'name',");
116        size += sizeof("'properties':{'name':''}},");
117        size += strlen(srs) * sizeof(char);
118
119        return size;
120}
121
122static size_t
123asgeojson_srs_buf(char *output, char *srs)
124{
125        char *ptr = output;
126
127        ptr += sprintf(ptr, "\"crs\":{\"type\":\"name\",");
128        ptr += sprintf(ptr, "\"properties\":{\"name\":\"%s\"}},", srs);
129
130        return (ptr-output);
131}
132
133
134
135/**
136 * Handle Bbox
137 */
138static size_t
139asgeojson_bbox_size(int hasz, int precision)
140{
141        int size;
142
143        if (!hasz)
144        {
145                size = sizeof("\"bbox\":[,,,],");
146                size += 2 * 2 * (OUT_MAX_DIGS_DOUBLE + precision);
147        }
148        else
149        {
150                size = sizeof("\"bbox\":[,,,,,],");
151                size += 2 * 3 * (OUT_MAX_DIGS_DOUBLE + precision);
152        }
153
154        return size;
155}
156
157static size_t
158asgeojson_bbox_buf(char *output, BOX3D *bbox, int hasz, int precision)
159{
160        char *ptr = output;
161
162        if (!hasz)
163                ptr += sprintf(ptr, "\"bbox\":[%.*f,%.*f,%.*f,%.*f],",
164                               precision, bbox->xmin, precision, bbox->ymin,
165                               precision, bbox->xmax, precision, bbox->ymax);
166        else
167                ptr += sprintf(ptr, "\"bbox\":[%.*f,%.*f,%.*f,%.*f,%.*f,%.*f],",
168                               precision, bbox->xmin, precision, bbox->ymin, precision, bbox->zmin,
169                               precision, bbox->xmax, precision, bbox->ymax, precision, bbox->zmax);
170
171        return (ptr-output);
172}
173
174
175
176/**
177 * Point Geometry
178 */
179
180static size_t
181asgeojson_point_size(LWPOINT *point, char *srs, BOX3D *bbox, int precision)
182{
183        int size;
184
185        size = pointArray_geojson_size(point->point, precision);
186        size += sizeof("{'type':'Point',");
187        size += sizeof("'coordinates':}");
188
189        if (srs) size += asgeojson_srs_size(srs);
190        if (bbox) size += asgeojson_bbox_size(TYPE_HASZ(point->type), precision);
191
192        return size;
193}
194
195static size_t
196asgeojson_point_buf(LWPOINT *point, char *srs, char *output, BOX3D *bbox, int precision)
197{
198        char *ptr = output;
199
200        ptr += sprintf(ptr, "{\"type\":\"Point\",");
201        if (srs) ptr += asgeojson_srs_buf(ptr, srs);
202        if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, TYPE_HASZ(point->type), precision);
203
204        ptr += sprintf(ptr, "\"coordinates\":");
205        ptr += pointArray_to_geojson(point->point, ptr, precision);
206        ptr += sprintf(ptr, "}");
207
208        return (ptr-output);
209}
210
211static char *
212asgeojson_point(LWPOINT *point, char *srs, BOX3D *bbox, int precision)
213{
214        char *output;
215        int size;
216
217        size = asgeojson_point_size(point, srs, bbox, precision);
218        output = lwalloc(size);
219        asgeojson_point_buf(point, srs, output, bbox, precision);
220        return output;
221}
222
223
224
225/**
226 * Line Geometry
227 */
228
229static size_t
230asgeojson_line_size(LWLINE *line, char *srs, BOX3D *bbox, int precision)
231{
232        int size;
233
234        size = sizeof("{'type':'LineString',");
235        if (srs) size += asgeojson_srs_size(srs);
236        if (bbox) size += asgeojson_bbox_size(TYPE_HASZ(line->type), precision);
237        size += sizeof("'coordinates':[]}");
238        size += pointArray_geojson_size(line->points, precision);
239
240        return size;
241}
242
243static size_t
244asgeojson_line_buf(LWLINE *line, char *srs, char *output, BOX3D *bbox, int precision)
245{
246        char *ptr=output;
247
248        ptr += sprintf(ptr, "{\"type\":\"LineString\",");
249        if (srs) ptr += asgeojson_srs_buf(ptr, srs);
250        if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, TYPE_HASZ(line->type), precision);
251        ptr += sprintf(ptr, "\"coordinates\":[");
252        ptr += pointArray_to_geojson(line->points, ptr, precision);
253        ptr += sprintf(ptr, "]}");
254
255        return (ptr-output);
256}
257
258static char *
259asgeojson_line(LWLINE *line, char *srs, BOX3D *bbox, int precision)
260{
261        char *output;
262        int size;
263
264        size = asgeojson_line_size(line, srs, bbox, precision);
265        output = lwalloc(size);
266        asgeojson_line_buf(line, srs, output, bbox, precision);
267
268        return output;
269}
270
271
272
273/**
274 * Polygon Geometry
275 */
276
277static size_t
278asgeojson_poly_size(LWPOLY *poly, char *srs, BOX3D *bbox, int precision)
279{
280        size_t size;
281        int i;
282
283        size = sizeof("{\"type\":\"Polygon\",");
284        if (srs) size += asgeojson_srs_size(srs);
285        if (bbox) size += asgeojson_bbox_size(TYPE_HASZ(poly->type), precision);
286        size += sizeof("\"coordinates\":[");
287        for (i=0, size=0; i<poly->nrings; i++)
288        {
289                size += pointArray_geojson_size(poly->rings[i], precision);
290                size += sizeof("[]");
291        }
292        size += sizeof(",") * i;
293        size += sizeof("]}");
294
295        return size;
296}
297
298static size_t
299asgeojson_poly_buf(LWPOLY *poly, char *srs, char *output, BOX3D *bbox, int precision)
300{
301        int i;
302        char *ptr=output;
303
304        ptr += sprintf(ptr, "{\"type\":\"Polygon\",");
305        if (srs) ptr += asgeojson_srs_buf(ptr, srs);
306        if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, TYPE_HASZ(poly->type), precision);
307        ptr += sprintf(ptr, "\"coordinates\":[");
308        for (i=0; i<poly->nrings; i++)
309        {
310                if (i) ptr += sprintf(ptr, ",");
311                ptr += sprintf(ptr, "[");
312                ptr += pointArray_to_geojson(poly->rings[i], ptr, precision);
313                ptr += sprintf(ptr, "]");
314        }
315        ptr += sprintf(ptr, "]}");
316
317        return (ptr-output);
318}
319
320static char *
321asgeojson_poly(LWPOLY *poly, char *srs, BOX3D *bbox, int precision)
322{
323        char *output;
324        int size;
325
326        size = asgeojson_poly_size(poly, srs, bbox, precision);
327        output = lwalloc(size);
328        asgeojson_poly_buf(poly, srs, output, bbox, precision);
329
330        return output;
331}
332
333
334
335/**
336 * Multipoint Geometry
337 */
338
339static size_t
340asgeojson_multipoint_size(LWGEOM_INSPECTED *insp, char *srs, BOX3D *bbox, int precision)
341{
342        LWPOINT * point;
343        int size;
344        int i;
345
346        size = sizeof("{'type':'MultiPoint',");
347        if (srs) size += asgeojson_srs_size(srs);
348        if (bbox) size += asgeojson_bbox_size(TYPE_HASZ(insp->type), precision);
349        size += sizeof("'coordinates':[]}");
350
351        for (i=0; i<insp->ngeometries; i++)
352        {
353                point = lwgeom_getpoint_inspected(insp, i);
354                size += pointArray_geojson_size(point->point, precision);
355                lwpoint_release(point);
356        }
357        size += sizeof(",") * i;
358
359        return size;
360}
361
362static size_t
363asgeojson_multipoint_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, BOX3D *bbox, int precision)
364{
365        LWPOINT *point;
366        int i;
367        char *ptr=output;
368
369        ptr += sprintf(ptr, "{\"type\":\"MultiPoint\",");
370        if (srs) ptr += asgeojson_srs_buf(ptr, srs);
371        if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, TYPE_HASZ(insp->type), precision);
372        ptr += sprintf(ptr, "\"coordinates\":[");
373
374        for (i=0; i<insp->ngeometries; i++)
375        {
376                if (i) ptr += sprintf(ptr, ",");
377                point=lwgeom_getpoint_inspected(insp, i);
378                ptr += pointArray_to_geojson(point->point, ptr, precision);
379                lwpoint_release(point);
380        }
381        ptr += sprintf(ptr, "]}");
382
383        return (ptr - output);
384}
385
386static char *
387asgeojson_multipoint(LWGEOM_INSPECTED *insp, char *srs, BOX3D *bbox, int precision)
388{
389        char *output;
390        int size;
391
392        size = asgeojson_multipoint_size(insp, srs, bbox, precision);
393        output = lwalloc(size);
394        asgeojson_multipoint_buf(insp, srs, output, bbox, precision);
395
396        return output;
397}
398
399
400
401/**
402 * Multiline Geometry
403 */
404
405static size_t
406asgeojson_multiline_size(LWGEOM_INSPECTED *insp, char *srs, BOX3D *bbox, int precision)
407{
408        LWLINE * line;
409        int size;
410        int i;
411
412        size = sizeof("{'type':'MultiLineString',");
413        if (srs) size += asgeojson_srs_size(srs);
414        if (bbox) size += asgeojson_bbox_size(TYPE_HASZ(insp->type), precision);
415        size += sizeof("'coordinates':[]}");
416
417        for (i=0 ; i<insp->ngeometries; i++)
418        {
419                line = lwgeom_getline_inspected(insp, i);
420                size += pointArray_geojson_size(line->points, precision);
421                size += sizeof("[]");
422                lwline_release(line);
423        }
424        size += sizeof(",") * i;
425
426        return size;
427}
428
429static size_t
430asgeojson_multiline_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, BOX3D *bbox, int precision)
431{
432        LWLINE *line;
433        int i;
434        char *ptr=output;
435
436        ptr += sprintf(ptr, "{\"type\":\"MultiLineString\",");
437        if (srs) ptr += asgeojson_srs_buf(ptr, srs);
438        if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, TYPE_HASZ(insp->type), precision);
439        ptr += sprintf(ptr, "\"coordinates\":[");
440
441        for (i=0; i<insp->ngeometries; i++)
442        {
443                if (i) ptr += sprintf(ptr, ",");
444                ptr += sprintf(ptr, "[");
445                line = lwgeom_getline_inspected(insp, i);
446                ptr += pointArray_to_geojson(line->points, ptr, precision);
447                ptr += sprintf(ptr, "]");
448
449                lwline_release(line);
450        }
451
452        ptr += sprintf(ptr, "]}");
453
454        return (ptr - output);
455}
456
457static char *
458asgeojson_multiline(LWGEOM_INSPECTED *insp, char *srs, BOX3D *bbox, int precision)
459{
460        char *output;
461        int size;
462
463        size = asgeojson_multiline_size(insp, srs, bbox, precision);
464        output = lwalloc(size);
465        asgeojson_multiline_buf(insp, srs, output, bbox, precision);
466
467        return output;
468}
469
470
471
472/**
473 * MultiPolygon Geometry
474 */
475
476static size_t
477asgeojson_multipolygon_size(LWGEOM_INSPECTED *insp, char *srs, BOX3D *bbox, int precision)
478{
479        LWPOLY *poly;
480        int size;
481        int i, j;
482
483        size = sizeof("{'type':'MultiPolygon',");
484        if (srs) size += asgeojson_srs_size(srs);
485        if (bbox) size += asgeojson_bbox_size(TYPE_HASZ(insp->type), precision);
486        size += sizeof("'coordinates':[]}");
487
488        for (i=0; i < insp->ngeometries; i++)
489        {
490                poly = lwgeom_getpoly_inspected(insp, i);
491                for (j=0 ; j <poly->nrings ; j++)
492                {
493                        size += pointArray_geojson_size(poly->rings[j], precision);
494                        size += sizeof("[]");
495                }
496                lwpoly_release(poly);
497                size += sizeof("[]");
498        }
499        size += sizeof(",") * i;
500        size += sizeof("]}");
501
502        return size;
503}
504
505static size_t
506asgeojson_multipolygon_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, BOX3D *bbox, int precision)
507{
508        LWPOLY *poly;
509        int i, j;
510        char *ptr=output;
511
512        ptr += sprintf(ptr, "{\"type\":\"MultiPolygon\",");
513        if (srs) ptr += asgeojson_srs_buf(ptr, srs);
514        if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, TYPE_HASZ(insp->type), precision);
515        ptr += sprintf(ptr, "\"coordinates\":[");
516        for (i=0; i<insp->ngeometries; i++)
517        {
518                if (i) ptr += sprintf(ptr, ",");
519                ptr += sprintf(ptr, "[");
520                poly = lwgeom_getpoly_inspected(insp, i);
521                for (j=0 ; j < poly->nrings ; j++)
522                {
523                        if (j) ptr += sprintf(ptr, ",");
524                        ptr += sprintf(ptr, "[");
525                        ptr += pointArray_to_geojson(poly->rings[j], ptr, precision);
526                        ptr += sprintf(ptr, "]");
527                }
528                ptr += sprintf(ptr, "]");
529                lwpoly_release(poly);
530        }
531        ptr += sprintf(ptr, "]}");
532
533        return (ptr - output);
534}
535
536static char *
537asgeojson_multipolygon(LWGEOM_INSPECTED *insp, char *srs, BOX3D *bbox, int precision)
538{
539        char *output;
540        int size;
541
542        size = asgeojson_multipolygon_size(insp, srs, bbox, precision);
543        output = lwalloc(size);
544        asgeojson_multipolygon_buf(insp, srs, output, bbox, precision);
545
546        return output;
547}
548
549
550
551/**
552 * Collection Geometry
553 */
554
555static size_t
556asgeojson_collection_size(LWGEOM_INSPECTED *insp, char *srs, BOX3D *bbox, int precision)
557{
558        int i;
559        int size;
560        LWGEOM_INSPECTED *subinsp;
561        uchar *subgeom;
562
563        size = sizeof("{'type':'GeometryCollection',");
564        if (srs) size += asgeojson_srs_size(srs);
565        if (bbox) size += asgeojson_bbox_size(TYPE_HASZ(insp->type), precision);
566        size += sizeof("'geometries':");
567
568        for (i=0; i<insp->ngeometries; i++)
569        {
570                subgeom = lwgeom_getsubgeometry_inspected(insp, i);
571                subinsp = lwgeom_inspect(subgeom);
572                size += asgeojson_inspected_size(subinsp, NULL, precision);
573                lwinspected_release(subinsp);
574        }
575        size += sizeof(",") * i;
576        size += sizeof("]}");
577
578        return size;
579}
580
581static size_t
582asgeojson_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, BOX3D *bbox, int precision)
583{
584        int i;
585        char *ptr=output;
586        LWGEOM_INSPECTED *subinsp;
587        uchar *subgeom;
588
589        ptr += sprintf(ptr, "{\"type\":\"GeometryCollection\",");
590        if (srs) ptr += asgeojson_srs_buf(ptr, srs);
591        if (bbox) ptr += asgeojson_bbox_buf(ptr, bbox, TYPE_HASZ(insp->type), precision);
592        ptr += sprintf(ptr, "\"geometries\":[");
593
594        for (i=0; i<insp->ngeometries; i++)
595        {
596                if (i) ptr += sprintf(ptr, ",");
597                subgeom = lwgeom_getsubgeometry_inspected(insp, i);
598                subinsp = lwgeom_inspect(subgeom);
599                ptr += asgeojson_inspected_buf(subinsp, ptr, NULL, precision);
600                lwinspected_release(subinsp);
601        }
602
603        ptr += sprintf(ptr, "]}");
604
605        return (ptr - output);
606}
607
608static char *
609asgeojson_collection(LWGEOM_INSPECTED *insp, char *srs, BOX3D *bbox, int precision)
610{
611        char *output;
612        int size;
613
614        size = asgeojson_collection_size(insp, srs, bbox, precision);
615        output = lwalloc(size);
616        asgeojson_collection_buf(insp, srs, output, bbox, precision);
617
618        return output;
619}
620
621
622
623static size_t
624asgeojson_inspected_size(LWGEOM_INSPECTED *insp, BOX3D *bbox, int precision)
625{
626        int type = lwgeom_getType(insp->serialized_form[0]);
627        size_t size = 0;
628        LWPOINT *point;
629        LWLINE *line;
630        LWPOLY *poly;
631
632        switch (type)
633        {
634        case POINTTYPE:
635                point=lwgeom_getpoint_inspected(insp, 0);
636                size = asgeojson_point_size(point, NULL, bbox, precision);
637                lwpoint_release(point);
638                break;
639
640        case LINETYPE:
641                line=lwgeom_getline_inspected(insp, 0);
642                size = asgeojson_line_size(line, NULL, bbox, precision);
643                lwline_release(line);
644                break;
645
646        case POLYGONTYPE:
647                poly=lwgeom_getpoly_inspected(insp, 0);
648                size = asgeojson_poly_size(poly, NULL, bbox, precision);
649                lwpoly_release(poly);
650                break;
651
652        case MULTIPOINTTYPE:
653                size = asgeojson_multipoint_size(insp, NULL, bbox, precision);
654                break;
655
656        case MULTILINETYPE:
657                size = asgeojson_multiline_size(insp, NULL, bbox, precision);
658                break;
659
660        case MULTIPOLYGONTYPE:
661                size = asgeojson_multipolygon_size(insp, NULL, bbox, precision);
662                break;
663
664        default:
665                lwerror("GeoJson: geometry not supported.");
666        }
667
668        return size;
669}
670
671
672static size_t
673asgeojson_inspected_buf(LWGEOM_INSPECTED *insp, char *output, BOX3D *bbox, int precision)
674{
675        LWPOINT *point;
676        LWLINE *line;
677        LWPOLY *poly;
678        int type = lwgeom_getType(insp->serialized_form[0]);
679        char *ptr=output;
680
681        switch (type)
682        {
683        case POINTTYPE:
684                point=lwgeom_getpoint_inspected(insp, 0);
685                ptr += asgeojson_point_buf(point, NULL, ptr, bbox, precision);
686                lwpoint_release(point);
687                break;
688
689        case LINETYPE:
690                line=lwgeom_getline_inspected(insp, 0);
691                ptr += asgeojson_line_buf(line, NULL, ptr, bbox, precision);
692                lwline_release(line);
693                break;
694
695        case POLYGONTYPE:
696                poly=lwgeom_getpoly_inspected(insp, 0);
697                ptr += asgeojson_poly_buf(poly, NULL, ptr, bbox, precision);
698                lwpoly_release(poly);
699                break;
700
701        case MULTIPOINTTYPE:
702                ptr += asgeojson_multipoint_buf(insp, NULL, ptr, bbox, precision);
703                break;
704
705        case MULTILINETYPE:
706                ptr += asgeojson_multiline_buf(insp, NULL, ptr, bbox, precision);
707                break;
708
709        case MULTIPOLYGONTYPE:
710                ptr += asgeojson_multipolygon_buf(insp, NULL, ptr, bbox, precision);
711                break;
712
713        default:
714                if (bbox) lwfree(bbox);
715                lwerror("GeoJson: geometry not supported.");
716        }
717
718        return (ptr-output);
719}
720
721
722static size_t
723pointArray_to_geojson(POINTARRAY *pa, char *output, int precision)
724{
725        int i;
726        char *ptr;
727        char x[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
728        char y[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
729        char z[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
730
731        ptr = output;
732
733        if (!TYPE_HASZ(pa->dims))
734        {
735                for (i=0; i<pa->npoints; i++)
736                {
737                        POINT2D pt;
738                        getPoint2d_p(pa, i, &pt);
739
740                        if (fabs(pt.x) < OUT_MAX_DOUBLE)
741                                sprintf(x, "%.*f", precision, pt.x);
742                        else
743                                sprintf(x, "%g", pt.x);
744                        trim_trailing_zeros(x);
745
746                        if (fabs(pt.y) < OUT_MAX_DOUBLE)
747                                sprintf(y, "%.*f", precision, pt.y);
748                        else
749                                sprintf(y, "%g", pt.y);
750                        trim_trailing_zeros(y);
751
752                        if ( i ) ptr += sprintf(ptr, ",");
753                        ptr += sprintf(ptr, "[%s,%s]", x, y);
754                }
755        }
756        else
757        {
758                for (i=0; i<pa->npoints; i++)
759                {
760                        POINT4D pt;
761                        getPoint4d_p(pa, i, &pt);
762
763                        if (fabs(pt.x) < OUT_MAX_DOUBLE)
764                                sprintf(x, "%.*f", precision, pt.x);
765                        else
766                                sprintf(x, "%g", pt.x);
767                        trim_trailing_zeros(x);
768
769                        if (fabs(pt.y) < OUT_MAX_DOUBLE)
770                                sprintf(y, "%.*f", precision, pt.y);
771                        else
772                                sprintf(y, "%g", pt.y);
773                        trim_trailing_zeros(y);
774
775                        if (fabs(pt.z) < OUT_MAX_DOUBLE)
776                                sprintf(z, "%.*f", precision, pt.z);
777                        else
778                                sprintf(z, "%g", pt.z);
779                        trim_trailing_zeros(z);
780
781                        if ( i ) ptr += sprintf(ptr, ",");
782                        ptr += sprintf(ptr, "[%s,%s,%s]", x, y, z);
783                }
784        }
785
786        return (ptr-output);
787}
788
789
790
791/**
792 * Returns maximum size of rendered pointarray in bytes.
793 */
794static size_t
795pointArray_geojson_size(POINTARRAY *pa, int precision)
796{
797        if (TYPE_NDIMS(pa->dims) == 2)
798                return (OUT_MAX_DIGS_DOUBLE + precision + sizeof(","))
799                       * 2 * pa->npoints + sizeof(",[]");
800
801        return (OUT_MAX_DIGS_DOUBLE + precision + sizeof(",,"))
802               * 3 * pa->npoints + sizeof(",[]");
803}
Note: See TracBrowser for help on using the repository browser.