PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
lwout_gml.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 2011 Sandro Santilli <strk@kbt.io>
22 * Copyright 2010-2012 Oslandia
23 * Copyright 2001-2003 Refractions Research Inc.
24 *
25 **********************************************************************/
26
27
34#include <string.h>
35#include "liblwgeom_internal.h"
36#include "liblwgeom.h"
37#include "stringbuffer.h"
38
39typedef struct
40{
41 const char *srs;
43 int opts;
45 const char *prefix;
46 const char *id;
48
49
50static void
52{
53 uint32_t i;
54 if ( ! FLAGS_GET_Z(pa->flags) )
55 {
56 for (i=0; i<pa->npoints; i++)
57 {
58 const POINT2D *pt = getPoint2d_cp(pa, i);
59 if (i) stringbuffer_append_char(sb, ' ');
60 stringbuffer_append_double(sb, pt->x, opts->precision);
62 stringbuffer_append_double(sb, pt->y, opts->precision);
63 }
64 }
65 else
66 {
67 for (i=0; i<pa->npoints; i++)
68 {
69 const POINT3D *pt = getPoint3d_cp(pa, i);
70 if (i) stringbuffer_append_char(sb, ' ');
71 stringbuffer_append_double(sb, pt->x, opts->precision);
73 stringbuffer_append_double(sb, pt->y, opts->precision);
75 stringbuffer_append_double(sb, pt->z, opts->precision);
76 }
77 }
78}
79
80
81static void
82asgml2_gbox(stringbuffer_t* sb, const GBOX *bbox, const GML_Options* opts)
83{
84 if (!bbox)
85 {
86 stringbuffer_aprintf(sb, "<%sBox", opts->prefix);
87 if (opts->srs) stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
88 stringbuffer_append(sb, "/>");
89 return;
90 }
91 else
92 {
93 POINT4D pt = { bbox->xmin, bbox->ymin, bbox->zmin, 0.0 };
96 pt.x = bbox->xmax; pt.y = bbox->ymax; pt.z = bbox->zmax;
98
99 if (opts->srs) stringbuffer_aprintf(sb, "<%sBox srsName=\"%s\">", opts->prefix, opts->srs);
100 else stringbuffer_aprintf(sb, "<%sBox>", opts->prefix);
101
102 stringbuffer_aprintf(sb, "<%scoordinates>", opts->prefix);
103 asgml2_ptarray(sb, pa, opts);
104 stringbuffer_aprintf(sb, "</%scoordinates>", opts->prefix);
105 stringbuffer_aprintf(sb, "</%sBox>", opts->prefix);
106
107 ptarray_free(pa);
108 }
109}
110
111static void
113{
114 uint32_t i;
115 if ( ! FLAGS_GET_Z(pa->flags) )
116 {
117 for (i=0; i<pa->npoints; i++)
118 {
119 const POINT2D *pt = getPoint2d_cp(pa, i);
120 if (i) stringbuffer_append_char(sb, ' ');
121 if (IS_DEGREE(opts->opts))
122 {
123 stringbuffer_append_double(sb, pt->y, opts->precision);
125 stringbuffer_append_double(sb, pt->x, opts->precision);
126 }
127 else
128 {
129 stringbuffer_append_double(sb, pt->x, opts->precision);
131 stringbuffer_append_double(sb, pt->y, opts->precision);
132 }
133 }
134 }
135 else
136 {
137 for (i=0; i<pa->npoints; i++)
138 {
139 const POINT3D *pt = getPoint3d_cp(pa, i);
140 if (i) stringbuffer_append_char(sb, ' ');
141 if (IS_DEGREE(opts->opts))
142 {
143 stringbuffer_append_double(sb, pt->y, opts->precision);
145 stringbuffer_append_double(sb, pt->x, opts->precision);
147 stringbuffer_append_double(sb, pt->z, opts->precision);
148 }
149 else
150 {
151 stringbuffer_append_double(sb, pt->x, opts->precision);
153 stringbuffer_append_double(sb, pt->y, opts->precision);
155 stringbuffer_append_double(sb, pt->z, opts->precision);
156 }
157 }
158 }
159}
160
161
162static void
163asgml3_gbox(stringbuffer_t* sb, const GBOX *bbox, const GML_Options* opts)
164{
165 if (!bbox)
166 {
167 stringbuffer_aprintf(sb, "<%sEnvelope", opts->prefix);
168 if (opts->srs) stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
169 stringbuffer_append(sb, "/>");
170 return;
171 }
172 else
173 {
174 int dimension = FLAGS_GET_Z(bbox->flags) ? 3 : 2;
175
177 POINT4D pt = { bbox->xmin, bbox->ymin, bbox->zmin, 0.0 };
179
180 stringbuffer_aprintf(sb, "<%sEnvelope", opts->prefix);
181 if (opts->srs) stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
182 if (IS_DIMS(opts->opts)) stringbuffer_aprintf(sb, " srsDimension=\"%d\"", dimension);
183 stringbuffer_append(sb, ">");
184
185 stringbuffer_aprintf(sb, "<%slowerCorner>", opts->prefix);
186 asgml3_ptarray(sb, pa, opts);
187 stringbuffer_aprintf(sb, "</%slowerCorner>", opts->prefix);
188
189 pt.x = bbox->xmax; pt.y = bbox->ymax; pt.z =bbox->zmax;
192
193 stringbuffer_aprintf(sb, "<%supperCorner>", opts->prefix);
194 asgml3_ptarray(sb, pa, opts);
195 stringbuffer_aprintf(sb, "</%supperCorner>", opts->prefix);
196
197 stringbuffer_aprintf(sb, "</%sEnvelope>", opts->prefix);
198 ptarray_free(pa);
199 }
200}
201
202static void
203asgml2_point(stringbuffer_t* sb, const LWPOINT *point, const GML_Options* opts)
204{
205
206 stringbuffer_aprintf(sb, "<%sPoint", opts->prefix);
207 if (opts->srs) stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
208 if (lwpoint_is_empty(point))
209 {
210 stringbuffer_append(sb, "/>");
211 return;
212 }
213 stringbuffer_append(sb, ">");
214 stringbuffer_aprintf(sb, "<%scoordinates>", opts->prefix);
215 asgml2_ptarray(sb, point->point, opts);
216 stringbuffer_aprintf(sb, "</%scoordinates>", opts->prefix);
217 stringbuffer_aprintf(sb, "</%sPoint>", opts->prefix);
218}
219
220static void
221asgml2_line(stringbuffer_t* sb, const LWLINE *line, const GML_Options* opts)
222{
223 stringbuffer_aprintf(sb, "<%sLineString", opts->prefix);
224 if (opts->srs) stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
225
226 if (lwline_is_empty(line))
227 {
228 stringbuffer_append(sb, "/>");
229 return;
230 }
231 stringbuffer_append(sb, ">");
232
233 stringbuffer_aprintf(sb, "<%scoordinates>", opts->prefix);
234 asgml2_ptarray(sb, line->points, opts);
235 stringbuffer_aprintf(sb, "</%scoordinates>", opts->prefix);
236 stringbuffer_aprintf(sb, "</%sLineString>", opts->prefix);
237}
238
239static void
240asgml2_poly(stringbuffer_t* sb, const LWPOLY *poly, const GML_Options* opts)
241{
242 uint32_t i;
243
244 stringbuffer_aprintf(sb, "<%sPolygon", opts->prefix);
245 if (opts->srs) stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
246 if (lwpoly_is_empty(poly))
247 {
248 stringbuffer_append(sb, "/>");
249 return;
250 }
251 stringbuffer_append(sb, ">");
252 stringbuffer_aprintf(sb, "<%souterBoundaryIs>", opts->prefix);
253 stringbuffer_aprintf(sb, "<%sLinearRing>", opts->prefix);
254 stringbuffer_aprintf(sb, "<%scoordinates>", opts->prefix);
255 asgml2_ptarray(sb, poly->rings[0], opts);
256 stringbuffer_aprintf(sb, "</%scoordinates>", opts->prefix);
257 stringbuffer_aprintf(sb, "</%sLinearRing>", opts->prefix);
258 stringbuffer_aprintf(sb, "</%souterBoundaryIs>", opts->prefix);
259 for (i=1; i<poly->nrings; i++)
260 {
261 stringbuffer_aprintf(sb, "<%sinnerBoundaryIs>", opts->prefix);
262 stringbuffer_aprintf(sb, "<%sLinearRing>", opts->prefix);
263 stringbuffer_aprintf(sb, "<%scoordinates>", opts->prefix);
264 asgml2_ptarray(sb, poly->rings[i], opts);
265 stringbuffer_aprintf(sb, "</%scoordinates>", opts->prefix);
266 stringbuffer_aprintf(sb, "</%sLinearRing>", opts->prefix);
267 stringbuffer_aprintf(sb, "</%sinnerBoundaryIs>", opts->prefix);
268 }
269 stringbuffer_aprintf(sb, "</%sPolygon>", opts->prefix);
270}
271
272static void
274{
275 uint32_t i;
276 const char* gmltype = "";
277 int type = col->type;
278
279 /* Subgeoms don't get an SRS */
280 GML_Options subopts = *opts;
281 subopts.srs = 0;
282
283 if (type == MULTIPOINTTYPE) gmltype = "MultiPoint";
284 else if (type == MULTILINETYPE) gmltype = "MultiLineString";
285 else if (type == MULTIPOLYGONTYPE) gmltype = "MultiPolygon";
286
287 /* Open outmost tag */
288 stringbuffer_aprintf(sb, "<%s%s", opts->prefix, gmltype);
289 if (opts->srs) stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
290
291 if (!col->ngeoms)
292 {
293 stringbuffer_append(sb, "/>");
294 return;
295 }
296 stringbuffer_append(sb, ">");
297
298 for (i=0; i<col->ngeoms; i++)
299 {
300 LWGEOM* subgeom = col->geoms[i];
301 if (subgeom->type == POINTTYPE)
302 {
303 stringbuffer_aprintf(sb, "<%spointMember>", opts->prefix);
304 asgml2_point(sb, (LWPOINT*)subgeom, &subopts);
305 stringbuffer_aprintf(sb, "</%spointMember>", opts->prefix);
306 }
307 else if (subgeom->type == LINETYPE)
308 {
309 stringbuffer_aprintf(sb, "<%slineStringMember>", opts->prefix);
310 asgml2_line(sb, (LWLINE*)subgeom, &subopts);
311 stringbuffer_aprintf(sb, "</%slineStringMember>", opts->prefix);
312 }
313 else if (subgeom->type == POLYGONTYPE)
314 {
315 stringbuffer_aprintf(sb, "<%spolygonMember>", opts->prefix);
316 asgml2_poly(sb, (LWPOLY*)subgeom, &subopts);
317 stringbuffer_aprintf(sb, "</%spolygonMember>", opts->prefix);
318 }
319 }
320
321 /* Close outmost tag */
322 stringbuffer_aprintf(sb, "</%s%s>", opts->prefix, gmltype);
323}
324
325static void
327{
328 uint32_t i;
329 LWGEOM *subgeom;
330
331 /* Subgeoms don't get an SRS */
332 GML_Options subopts = *opts;
333 subopts.srs = 0;
334
335 /* Open outmost tag */
336 stringbuffer_aprintf(sb, "<%sMultiGeometry", opts->prefix);
337 if (opts->srs) stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
338
339 if (!col->ngeoms)
340 {
341 stringbuffer_append(sb, "/>");
342 return;
343 }
344 stringbuffer_append(sb, ">");
345
346 for (i=0; i<col->ngeoms; i++)
347 {
348 subgeom = col->geoms[i];
349 stringbuffer_aprintf(sb, "<%sgeometryMember>", opts->prefix);
350 switch (subgeom->type)
351 {
352 case POINTTYPE:
353 asgml2_point(sb, (LWPOINT*)subgeom, &subopts);
354 break;
355 case LINETYPE:
356 asgml2_line(sb, (LWLINE*)subgeom, &subopts);;
357 break;
358 case POLYGONTYPE:
359 asgml2_poly(sb, (LWPOLY*)subgeom, &subopts);
360 break;
361 case MULTIPOINTTYPE:
362 case MULTILINETYPE:
363 case MULTIPOLYGONTYPE:
364 asgml2_multi(sb, (LWCOLLECTION*)subgeom, &subopts);
365 break;
366 case COLLECTIONTYPE:
367 asgml2_collection(sb, (LWCOLLECTION*)subgeom, &subopts);
368 break;
369 }
370 stringbuffer_aprintf(sb, "</%sgeometryMember>", opts->prefix);
371 }
372 stringbuffer_aprintf(sb, "</%sMultiGeometry>", opts->prefix);
373}
374
375
376
377static void
378asgml3_point(stringbuffer_t* sb, const LWPOINT *point, const GML_Options* opts)
379{
380 int dimension = FLAGS_GET_Z(point->flags) ? 3 : 2;
381
382 stringbuffer_aprintf(sb, "<%sPoint", opts->prefix);
383 if (opts->srs) stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
384 if (opts->id) stringbuffer_aprintf(sb, " %sid=\"%s\"", opts->prefix, opts->id);
385 if (lwpoint_is_empty(point))
386 {
387 stringbuffer_append(sb, "/>");
388 return;
389 }
390
391 stringbuffer_append(sb, ">");
392 if (IS_DIMS(opts->opts))
393 stringbuffer_aprintf(sb, "<%spos srsDimension=\"%d\">", opts->prefix, dimension);
394 else
395 stringbuffer_aprintf(sb, "<%spos>", opts->prefix);
396 asgml3_ptarray(sb, point->point, opts);
397 stringbuffer_aprintf(sb, "</%spos></%sPoint>", opts->prefix, opts->prefix);
398}
399
400static void
401asgml3_line(stringbuffer_t* sb, const LWLINE *line, const GML_Options* opts)
402{
403 int dimension = FLAGS_GET_Z(line->flags) ? 3 : 2;
404 int shortline = (opts->opts & LW_GML_SHORTLINE);
405
406 if (shortline)
407 {
408 stringbuffer_aprintf(sb, "<%sLineString", opts->prefix);
409 }
410 else
411 {
412 stringbuffer_aprintf(sb, "<%sCurve", opts->prefix);
413 }
414
415 if (opts->srs) stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
416 if (opts->id) stringbuffer_aprintf(sb, " %sid=\"%s\"", opts->prefix, opts->id);
417
418 if (lwline_is_empty(line))
419 {
420 stringbuffer_append(sb, "/>");
421 return;
422 }
423 stringbuffer_append(sb, ">");
424
425 if (!shortline)
426 {
427 stringbuffer_aprintf(sb, "<%ssegments>", opts->prefix);
428 stringbuffer_aprintf(sb, "<%sLineStringSegment>", opts->prefix);
429 }
430
431 if (IS_DIMS(opts->opts))
432 {
433 stringbuffer_aprintf(sb, "<%sposList srsDimension=\"%d\">", opts->prefix, dimension);
434 }
435 else
436 {
437 stringbuffer_aprintf(sb, "<%sposList>", opts->prefix);
438 }
439
440 asgml3_ptarray(sb, line->points, opts);
441 stringbuffer_aprintf(sb, "</%sposList>", opts->prefix);
442
443 if (shortline)
444 {
445 stringbuffer_aprintf(sb, "</%sLineString>", opts->prefix);
446 }
447 else
448 {
449 stringbuffer_aprintf(sb, "</%sLineStringSegment>", opts->prefix);
450 stringbuffer_aprintf(sb, "</%ssegments>", opts->prefix);
451 stringbuffer_aprintf(sb, "</%sCurve>", opts->prefix);
452 }
453}
454
455static void
456asgml3_poly(stringbuffer_t* sb, const LWPOLY *poly, const GML_Options* opts)
457{
458 uint32_t i;
459 int dimension = FLAGS_GET_Z(poly->flags) ? 3 : 2;
460
462 opts->is_patch ? "<%sPolygonPatch" : "<%sPolygon",
463 opts->prefix);
464
465 if (opts->srs) stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
466 if (opts->id) stringbuffer_aprintf(sb, " %sid=\"%s\"", opts->prefix, opts->id);
467
468 if (lwpoly_is_empty(poly))
469 {
470 stringbuffer_append(sb, "/>");
471 return;
472 }
473 stringbuffer_append(sb, ">");
474
475 stringbuffer_aprintf(sb, "<%sexterior>", opts->prefix);
476 stringbuffer_aprintf(sb, "<%sLinearRing>", opts->prefix);
477 if (IS_DIMS(opts->opts))
478 stringbuffer_aprintf(sb, "<%sposList srsDimension=\"%d\">", opts->prefix, dimension);
479 else
480 stringbuffer_aprintf(sb, "<%sposList>", opts->prefix);
481
482 asgml3_ptarray(sb, poly->rings[0], opts);
483 stringbuffer_aprintf(sb, "</%sposList>", opts->prefix);
484 stringbuffer_aprintf(sb, "</%sLinearRing>", opts->prefix);
485 stringbuffer_aprintf(sb, "</%sexterior>", opts->prefix);
486 for (i=1; i<poly->nrings; i++)
487 {
488 stringbuffer_aprintf(sb, "<%sinterior>", opts->prefix);
489 stringbuffer_aprintf(sb, "<%sLinearRing>", opts->prefix);
490 if (IS_DIMS(opts->opts))
491 stringbuffer_aprintf(sb, "<%sposList srsDimension=\"%d\">", opts->prefix, dimension);
492 else
493 stringbuffer_aprintf(sb, "<%sposList>", opts->prefix);
494 asgml3_ptarray(sb, poly->rings[i], opts);
495 stringbuffer_aprintf(sb, "</%sposList>", opts->prefix);
496 stringbuffer_aprintf(sb, "</%sLinearRing>", opts->prefix);
497 stringbuffer_aprintf(sb, "</%sinterior>", opts->prefix);
498 }
499
501 opts->is_patch ? "</%sPolygonPatch>" : "</%sPolygon>",
502 opts->prefix);
503}
504
505
506static void
508{
509 int dimension = FLAGS_GET_Z(circ->flags) ? 3 : 2;
510
511 stringbuffer_aprintf(sb, "<%sCurve", opts->prefix);
512 if (opts->srs)
513 {
514 stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
515 }
516 if (opts->id)
517 {
518 stringbuffer_aprintf(sb, " %sid=\"%s\"", opts->prefix, opts->id);
519 }
520 stringbuffer_append(sb, ">");
521 stringbuffer_aprintf(sb, "<%ssegments>", opts->prefix);
522 stringbuffer_aprintf(sb, "<%sArcString>", opts->prefix);
523 stringbuffer_aprintf(sb, "<%sposList", opts->prefix);
524
525 if (IS_DIMS(opts->opts))
526 {
527 stringbuffer_aprintf(sb, " srsDimension=\"%d\"", dimension);
528 }
529 stringbuffer_append(sb, ">");
530
531 asgml3_ptarray(sb, circ->points, opts);
532
533 stringbuffer_aprintf(sb, "</%sposList>", opts->prefix);
534 stringbuffer_aprintf(sb, "</%sArcString>", opts->prefix);
535 stringbuffer_aprintf(sb, "</%ssegments>", opts->prefix);
536 stringbuffer_aprintf(sb, "</%sCurve>", opts->prefix);
537}
538
539static void
541{
542 LWGEOM *subgeom;
543 uint32_t i;
544 int dimension = FLAGS_GET_Z(col->flags) ? 3 : 2;
545
546 stringbuffer_aprintf(sb, "<%sCurve", opts->prefix);
547 if (opts->srs) stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
548 if (opts->id) stringbuffer_aprintf(sb, " %sid=\"%s\"", opts->prefix, opts->id);
549 stringbuffer_append(sb, ">");
550 stringbuffer_aprintf(sb, "<%ssegments>", opts->prefix);
551
552 for (i = 0; i < col->ngeoms; ++i)
553 {
554 subgeom = col->geoms[i];
555
556 if (subgeom->type != LINETYPE && subgeom->type != CIRCSTRINGTYPE)
557 continue;
558
559 if (subgeom->type == LINETYPE)
560 {
561 stringbuffer_aprintf(sb, "<%sLineStringSegment>", opts->prefix);
562 stringbuffer_aprintf(sb, "<%sposList", opts->prefix);
563 if (IS_DIMS(opts->opts))
564 stringbuffer_aprintf(sb, " srsDimension=\"%d\"", dimension);
565
566 stringbuffer_append(sb, ">");
567 asgml3_ptarray(sb, ((LWCIRCSTRING*)subgeom)->points, opts);
568 stringbuffer_aprintf(sb, "</%sposList>", opts->prefix);
569 stringbuffer_aprintf(sb, "</%sLineStringSegment>", opts->prefix);
570 }
571 else if( subgeom->type == CIRCSTRINGTYPE )
572 {
573 stringbuffer_aprintf(sb, "<%sArcString>", opts->prefix);
574 stringbuffer_aprintf(sb, "<%sposList", opts->prefix);
575 if (IS_DIMS(opts->opts))
576 {
577 stringbuffer_aprintf(sb, " srsDimension=\"%d\"", dimension);
578 }
579 stringbuffer_append(sb, ">");
580 asgml3_ptarray(sb, ((LWLINE*)subgeom)->points, opts);
581 stringbuffer_aprintf(sb, "</%sposList>", opts->prefix);
582 stringbuffer_aprintf(sb, "</%sArcString>", opts->prefix);
583 }
584 }
585 stringbuffer_aprintf(sb, "</%ssegments>", opts->prefix);
586 stringbuffer_aprintf(sb, "</%sCurve>", opts->prefix);
587}
588
589static void
591{
592 uint32_t i;
593 LWGEOM* subgeom;
594 int dimension = FLAGS_GET_Z(poly->flags) ? 3 : 2;
595
596 /* Subgeoms don't get an SRS */
597 GML_Options subopts = *opts;
598 subopts.srs = 0;
599
600 stringbuffer_aprintf(sb, "<%sPolygon", opts->prefix);
601 if (opts->srs)
602 {
603 stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
604 }
605 if (opts->id)
606 {
607 stringbuffer_aprintf(sb, " %sid=\"%s\"", opts->prefix, opts->id);
608 }
609 stringbuffer_append(sb, ">");
610
611 for (i = 0; i < poly->nrings; ++i)
612 {
614 i ? "<%sinterior>" : "<%sexterior>",
615 opts->prefix);
616
617 subgeom = poly->rings[i];
618 if (subgeom->type == LINETYPE)
619 {
620 stringbuffer_aprintf(sb, "<%sLinearRing>", opts->prefix);
621 stringbuffer_aprintf(sb, "<%sposList", opts->prefix);
622 if (IS_DIMS(opts->opts))
623 {
624 stringbuffer_aprintf(sb, " srsDimension=\"%d\"", dimension);
625 }
626 stringbuffer_append(sb, ">");
627 asgml3_ptarray(sb, ((LWLINE*)subgeom)->points, opts);
628 stringbuffer_aprintf(sb, "</%sposList>", opts->prefix);
629 stringbuffer_aprintf(sb, "</%sLinearRing>", opts->prefix);
630 }
631 else if (subgeom->type == CIRCSTRINGTYPE)
632 {
633 stringbuffer_aprintf(sb, "<%sRing>", opts->prefix);
634 stringbuffer_aprintf(sb, "<%scurveMember>", opts->prefix);
635 asgml3_circstring(sb, (LWCIRCSTRING*)subgeom, &subopts);
636 stringbuffer_aprintf(sb, "</%scurveMember>", opts->prefix);
637 stringbuffer_aprintf(sb, "</%sRing>", opts->prefix);
638 }
639 else if (subgeom->type == COMPOUNDTYPE)
640 {
641 stringbuffer_aprintf(sb, "<%sRing>", opts->prefix);
642 stringbuffer_aprintf(sb, "<%scurveMember>", opts->prefix);
643 asgml3_compound(sb, (LWCOMPOUND*)subgeom, &subopts);
644 stringbuffer_aprintf(sb, "</%scurveMember>", opts->prefix);
645 stringbuffer_aprintf(sb, "</%sRing>", opts->prefix);
646 }
647
649 i ? "</%sinterior>" : "</%sexterior>",
650 opts->prefix);
651 }
652 stringbuffer_aprintf(sb, "</%sPolygon>", opts->prefix);
653}
654
655static void
656asgml3_triangle(stringbuffer_t* sb, const LWTRIANGLE *triangle, const GML_Options* opts)
657{
658 int dimension = FLAGS_GET_Z(triangle->flags) ? 3 : 2;
659
660 stringbuffer_aprintf(sb, "<%sTriangle", opts->prefix);
661 if (opts->srs) stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
662 if (opts->id) stringbuffer_aprintf(sb, " %sid=\"%s\"", opts->prefix, opts->id);
663 stringbuffer_append(sb, ">");
664
665 stringbuffer_aprintf(sb, "<%sexterior>", opts->prefix);
666 stringbuffer_aprintf(sb, "<%sLinearRing>", opts->prefix);
667 if (IS_DIMS(opts->opts))
668 stringbuffer_aprintf(sb, "<%sposList srsDimension=\"%d\">", opts->prefix, dimension);
669 else
670 stringbuffer_aprintf(sb, "<%sposList>", opts->prefix);
671
672 asgml3_ptarray(sb, triangle->points, opts);
673 stringbuffer_aprintf(sb, "</%sposList>", opts->prefix);
674 stringbuffer_aprintf(sb, "</%sLinearRing>", opts->prefix);
675 stringbuffer_aprintf(sb, "</%sexterior>", opts->prefix);
676
677 stringbuffer_aprintf(sb, "</%sTriangle>", opts->prefix);
678}
679
680
681static void
683{
684 int type = col->type;
685 uint32_t i;
686 LWGEOM *subgeom;
687 /* Subgeoms don't get an SRS */
688 GML_Options subopts = *opts;
689 subopts.srs = 0;
690
691 const char* gmltype = "";
692
693 if (type == MULTIPOINTTYPE) gmltype = "MultiPoint";
694 else if (type == MULTILINETYPE) gmltype = "MultiCurve";
695 else if (type == MULTIPOLYGONTYPE) gmltype = "MultiSurface";
696
697 /* Open outmost tag */
698 stringbuffer_aprintf(sb, "<%s%s", opts->prefix, gmltype);
699 if (opts->srs) stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
700 if (opts->id) stringbuffer_aprintf(sb, " %sid=\"%s\"", opts->prefix, opts->id);
701
702 if (!col->ngeoms)
703 {
704 stringbuffer_append(sb, "/>");
705 return;
706 }
707 stringbuffer_append(sb, ">");
708
709 for (i=0; i<col->ngeoms; i++)
710 {
711 subgeom = col->geoms[i];
712 if (subgeom->type == POINTTYPE)
713 {
714 stringbuffer_aprintf(sb, "<%spointMember>", opts->prefix);
715 asgml3_point(sb, (LWPOINT*)subgeom, &subopts);
716 stringbuffer_aprintf(sb, "</%spointMember>", opts->prefix);
717 }
718 else if (subgeom->type == LINETYPE)
719 {
720 stringbuffer_aprintf(sb, "<%scurveMember>", opts->prefix);
721 asgml3_line(sb, (LWLINE*)subgeom, &subopts);
722 stringbuffer_aprintf(sb, "</%scurveMember>", opts->prefix);
723 }
724 else if (subgeom->type == POLYGONTYPE)
725 {
726 stringbuffer_aprintf(sb, "<%ssurfaceMember>", opts->prefix);
727 asgml3_poly(sb, (LWPOLY*)subgeom, &subopts);
728 stringbuffer_aprintf(sb, "</%ssurfaceMember>", opts->prefix);
729 }
730 }
731
732 /* Close outmost tag */
733 stringbuffer_aprintf(sb, "</%s%s>", opts->prefix, gmltype);
734}
735
736/*
737 * Don't call this with single-geoms inspected!
738 */
739static void
740asgml3_tin(stringbuffer_t* sb, const LWTIN *tin, const GML_Options* opts)
741{
742 uint32_t i;
743
744 /* Subgeoms don't get an SRS */
745 GML_Options subopts = *opts;
746 subopts.srs = 0;
747
748 /* Open outmost tag */
749 stringbuffer_aprintf(sb, "<%sTin", opts->prefix);
750 if (opts->srs)
751 stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
752 if (opts->id)
753 stringbuffer_aprintf(sb, " %sid=\"%s\"", opts->prefix, opts->id);
754 stringbuffer_append(sb, ">");
755
756 stringbuffer_aprintf(sb, "<%strianglePatches>", opts->prefix);
757 for (i=0; i<tin->ngeoms; i++)
758 {
759 asgml3_triangle(sb, tin->geoms[i], &subopts);
760 }
761
762 /* Close outmost tag */
763 stringbuffer_aprintf(sb, "</%strianglePatches>", opts->prefix);
764 stringbuffer_aprintf(sb, "</%sTin>", opts->prefix);
765}
766
767static void
769{
770 uint32_t i;
771
772 /* Subgeoms don't get an SRS */
773 GML_Options subopts = *opts;
774 subopts.srs = 0;
775 subopts.is_patch = 1;
776
777 /* Open outmost tag */
778 stringbuffer_aprintf(sb, "<%sPolyhedralSurface", opts->prefix);
779 if (opts->srs)
780 stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
781 if (opts->id)
782 stringbuffer_aprintf(sb, " %sid=\"%s\"", opts->prefix, opts->id);
783 stringbuffer_append(sb, ">");
784 stringbuffer_aprintf(sb, "<%spolygonPatches>", opts->prefix);
785
786 for (i=0; i<psur->ngeoms; i++)
787 {
788 asgml3_poly(sb, psur->geoms[i], &subopts);
789 }
790
791 /* Close outmost tag */
792 stringbuffer_aprintf(sb, "</%spolygonPatches>", opts->prefix);
793 stringbuffer_aprintf(sb, "</%sPolyhedralSurface>", opts->prefix);
794}
795
796
797static void
799{
800 uint32_t i;
801 LWGEOM *subgeom;
802
803 /* Subgeoms don't get an SRS */
804 GML_Options subopts = *opts;
805 subopts.srs = 0;
806
807 /* Open outmost tag */
808 stringbuffer_aprintf(sb, "<%sMultiGeometry", opts->prefix);
809 if (opts->srs) stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
810 if (opts->id) stringbuffer_aprintf(sb, " %sid=\"%s\"", opts->prefix, opts->id);
811
812 if (!col->ngeoms)
813 {
814 stringbuffer_append(sb, "/>");
815 return;
816 }
817 stringbuffer_append(sb, ">");
818
819 for (i=0; i<col->ngeoms; i++)
820 {
821 subgeom = col->geoms[i];
822 stringbuffer_aprintf(sb, "<%sgeometryMember>", opts->prefix);
823
824 switch (subgeom->type)
825 {
826 case POINTTYPE:
827 asgml3_point(sb, (LWPOINT*)subgeom, &subopts);
828 break;
829 case LINETYPE:
830 asgml3_line(sb, (LWLINE*)subgeom, &subopts);
831 break;
832 case POLYGONTYPE:
833 asgml3_poly(sb, (LWPOLY*)subgeom, &subopts);
834 break;
835 case MULTIPOINTTYPE:
836 case MULTILINETYPE:
837 case MULTIPOLYGONTYPE:
838 asgml3_multi(sb, (LWCOLLECTION*)subgeom, &subopts);
839 break;
840 case COLLECTIONTYPE:
841 asgml3_collection(sb, (LWCOLLECTION*)subgeom, &subopts);
842 break;
843 default:
844 lwerror("asgml3_collection: unknown geometry type");
845 }
846 stringbuffer_aprintf(sb, "</%sgeometryMember>", opts->prefix);
847 }
848
849 /* Close outmost tag */
850 stringbuffer_aprintf(sb, "</%sMultiGeometry>", opts->prefix);
851}
852
853static void
855{
856 LWGEOM* subgeom;
857 uint32_t i;
858
859 stringbuffer_aprintf(sb, "<%sMultiCurve", opts->prefix);
860 if (opts->srs)
861 {
862 stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
863 }
864 if (opts->id)
865 {
866 stringbuffer_aprintf(sb, " %sid=\"%s\"", opts->prefix, opts->id);
867 }
868 stringbuffer_append(sb, ">");
869
870 for (i = 0; i < cur->ngeoms; ++i)
871 {
872 stringbuffer_aprintf(sb, "<%scurveMember>", opts->prefix);
873 subgeom = cur->geoms[i];
874 if (subgeom->type == LINETYPE)
875 {
876 asgml3_line(sb, (LWLINE*)subgeom, opts);
877 }
878 else if (subgeom->type == CIRCSTRINGTYPE)
879 {
880 asgml3_circstring(sb, (LWCIRCSTRING*)subgeom, opts);
881 }
882 else if (subgeom->type == COMPOUNDTYPE)
883 {
884 asgml3_compound(sb, (LWCOMPOUND*)subgeom, opts);
885 }
886 stringbuffer_aprintf(sb, "</%scurveMember>", opts->prefix);
887 }
888 stringbuffer_aprintf(sb, "</%sMultiCurve>", opts->prefix);
889}
890
891
892static void
894{
895 uint32_t i;
896 LWGEOM* subgeom;
897
898 stringbuffer_aprintf(sb, "<%sMultiSurface", opts->prefix);
899 if (opts->srs) stringbuffer_aprintf(sb, " srsName=\"%s\"", opts->srs);
900 if (opts->id) stringbuffer_aprintf(sb, " %sid=\"%s\"", opts->prefix, opts->id);
901
902 stringbuffer_append(sb, ">");
903
904 for (i = 0; i < sur->ngeoms; ++i)
905 {
906 subgeom = sur->geoms[i];
907 if (subgeom->type == POLYGONTYPE)
908 {
909 asgml3_poly(sb, (LWPOLY*)sur->geoms[i], opts);
910 }
911 else if (subgeom->type == CURVEPOLYTYPE)
912 {
913 asgml3_curvepoly(sb, (LWCURVEPOLY*)sur->geoms[i], opts);
914 }
915 }
916 stringbuffer_aprintf(sb, "</%sMultiSurface>", opts->prefix);
917}
918
919extern lwvarlena_t *
920lwgeom_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
921{
923
924 /* Initialize options */
925 GML_Options gmlopts;
926 memset(&gmlopts, 0, sizeof(gmlopts));
927 gmlopts.srs = srs;
928 gmlopts.precision = precision;
929 gmlopts.prefix = prefix;
930
931 /* Return null for empty (#1377) */
932 if (lwgeom_is_empty(geom))
933 return NULL;
934
936
937 switch (geom->type)
938 {
939 case POINTTYPE:
940 asgml2_point(&sb, (LWPOINT*)geom, &gmlopts);
941 break;
942
943 case LINETYPE:
944 asgml2_line(&sb, (LWLINE*)geom, &gmlopts);
945 break;
946
947 case POLYGONTYPE:
948 asgml2_poly(&sb, (LWPOLY*)geom, &gmlopts);
949 break;
950
951 case MULTIPOINTTYPE:
952 case MULTILINETYPE:
953 case MULTIPOLYGONTYPE:
954 asgml2_multi(&sb, (LWCOLLECTION*)geom, &gmlopts);
955 break;
956
957 case COLLECTIONTYPE:
958 asgml2_collection(&sb, (LWCOLLECTION*)geom, &gmlopts);
959 break;
960
961 case TRIANGLETYPE:
963 case TINTYPE:
964 lwerror("Cannot convert %s to GML2. Try ST_AsGML(3, <geometry>) to generate GML3.", lwtype_name(geom->type));
966 return NULL;
967
968 default:
969 lwerror("lwgeom_to_gml2: '%s' geometry type not supported", lwtype_name(geom->type));
971 return NULL;
972 }
973
974 return stringbuffer_getvarlena(&sb);
975}
976
977extern lwvarlena_t *
978lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix, const char *id)
979{
981
982 /* Initialize options */
983 GML_Options gmlopts;
984 memset(&gmlopts, 0, sizeof(gmlopts));
985 gmlopts.srs = srs;
986 gmlopts.precision = precision;
987 gmlopts.opts = opts;
988 gmlopts.prefix = prefix;
989 gmlopts.id = id;
990
991 /* Return null for empty (#1377) */
992 if (lwgeom_is_empty(geom))
993 return NULL;
994
996
997 switch (geom->type)
998 {
999 case POINTTYPE:
1000 asgml3_point(&sb, (LWPOINT*)geom, &gmlopts);
1001 break;
1002
1003 case LINETYPE:
1004 asgml3_line(&sb, (LWLINE*)geom, &gmlopts);
1005 break;
1006
1007 case CIRCSTRINGTYPE:
1008 asgml3_circstring(&sb, (LWCIRCSTRING*)geom, &gmlopts );
1009 break;
1010
1011 case POLYGONTYPE:
1012 asgml3_poly(&sb, (LWPOLY*)geom, &gmlopts);
1013 break;
1014
1015 case CURVEPOLYTYPE:
1016 asgml3_curvepoly(&sb, (LWCURVEPOLY*)geom, &gmlopts);
1017 break;
1018
1019 case TRIANGLETYPE:
1020 asgml3_triangle(&sb, (LWTRIANGLE*)geom, &gmlopts);
1021 break;
1022
1023 case MULTIPOINTTYPE:
1024 case MULTILINETYPE:
1025 case MULTIPOLYGONTYPE:
1026 asgml3_multi(&sb, (LWCOLLECTION*)geom, &gmlopts);
1027 break;
1028
1030 asgml3_psurface(&sb, (LWPSURFACE*)geom, &gmlopts);
1031 break;
1032
1033 case TINTYPE:
1034 asgml3_tin(&sb, (LWTIN*)geom, &gmlopts);
1035 break;
1036
1037 case COLLECTIONTYPE:
1038 asgml3_collection(&sb, (LWCOLLECTION*)geom, &gmlopts);
1039 break;
1040
1041 case COMPOUNDTYPE:
1042 asgml3_compound(&sb, (LWCOMPOUND*)geom, &gmlopts );
1043 break;
1044
1045 case MULTICURVETYPE:
1046 asgml3_multicurve(&sb, (LWMCURVE*)geom, &gmlopts );
1047 break;
1048
1049 case MULTISURFACETYPE:
1050 asgml3_multisurface(&sb, (LWMSURFACE*)geom, &gmlopts );
1051 break;
1052
1053 default:
1054 lwerror("lwgeom_to_gml3: '%s' geometry type not supported", lwtype_name(geom->type));
1056 return NULL;
1057 }
1058
1059 return stringbuffer_getvarlena(&sb);
1060}
1061
1062extern lwvarlena_t *
1063lwgeom_extent_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
1064{
1065 const GBOX* bbox = lwgeom_get_bbox(geom);
1066 stringbuffer_t sb;
1067
1068 /* Initialize options */
1069 GML_Options gmlopts;
1070 memset(&gmlopts, 0, sizeof(gmlopts));
1071 gmlopts.srs = srs;
1072 gmlopts.precision = precision;
1073 gmlopts.prefix = prefix;
1074
1076 asgml2_gbox(&sb, bbox, &gmlopts);
1077 return stringbuffer_getvarlena(&sb);
1078}
1079
1080extern lwvarlena_t *
1081lwgeom_extent_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix)
1082{
1083 const GBOX* bbox = lwgeom_get_bbox(geom);
1084 stringbuffer_t sb;
1085
1086 /* Initialize options */
1087 GML_Options gmlopts;
1088 memset(&gmlopts, 0, sizeof(gmlopts));
1089 gmlopts.srs = srs;
1090 gmlopts.precision = precision;
1091 gmlopts.opts = opts;
1092 gmlopts.prefix = prefix;
1093
1095 asgml3_gbox(&sb, bbox, &gmlopts);
1096 return stringbuffer_getvarlena(&sb);
1097}
static uint8_t precision
Definition cu_in_twkb.c:25
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition lwutil.c:216
int ptarray_remove_point(POINTARRAY *pa, uint32_t where)
Remove a point from an existing POINTARRAY.
Definition ptarray.c:259
#define COLLECTIONTYPE
Definition liblwgeom.h:108
#define COMPOUNDTYPE
Definition liblwgeom.h:110
#define IS_DIMS(x)
Definition liblwgeom.h:1721
#define CURVEPOLYTYPE
Definition liblwgeom.h:111
#define MULTILINETYPE
Definition liblwgeom.h:106
#define MULTISURFACETYPE
Definition liblwgeom.h:113
#define LINETYPE
Definition liblwgeom.h:103
#define LW_GML_SHORTLINE
For GML3, use <LineString> rather than <Curve> for lines.
Definition liblwgeom.h:1716
#define MULTIPOINTTYPE
Definition liblwgeom.h:105
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition ptarray.c:59
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition liblwgeom.h:102
#define FLAGS_GET_Z(flags)
Definition liblwgeom.h:165
#define TINTYPE
Definition liblwgeom.h:116
#define MULTIPOLYGONTYPE
Definition liblwgeom.h:107
#define POLYGONTYPE
Definition liblwgeom.h:104
#define POLYHEDRALSURFACETYPE
Definition liblwgeom.h:114
#define CIRCSTRINGTYPE
Definition liblwgeom.h:109
void ptarray_free(POINTARRAY *pa)
Definition ptarray.c:327
#define IS_DEGREE(x)
Definition liblwgeom.h:1722
int ptarray_append_point(POINTARRAY *pa, const POINT4D *pt, int allow_duplicates)
Append a point to the end of an existing POINTARRAY If allow_duplicate is LW_FALSE,...
Definition ptarray.c:147
#define MULTICURVETYPE
Definition liblwgeom.h:112
#define TRIANGLETYPE
Definition liblwgeom.h:115
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:93
const GBOX * lwgeom_get_bbox(const LWGEOM *lwgeom)
Get a non-empty geometry bounding box, computing and caching it if not already there.
Definition lwgeom.c:771
This library is the generic geometry handling section of PostGIS.
int lwline_is_empty(const LWLINE *line)
int lwpoint_is_empty(const LWPOINT *point)
int lwpoly_is_empty(const LWPOLY *poly)
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
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:109
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
Definition lwinline.h:199
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:97
static void asgml3_compound(stringbuffer_t *sb, const LWCOMPOUND *col, const GML_Options *opts)
Definition lwout_gml.c:540
lwvarlena_t * lwgeom_extent_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix)
Definition lwout_gml.c:1081
static void asgml3_curvepoly(stringbuffer_t *sb, const LWCURVEPOLY *poly, const GML_Options *opts)
Definition lwout_gml.c:590
static void asgml2_ptarray(stringbuffer_t *sb, const POINTARRAY *pa, const GML_Options *opts)
Definition lwout_gml.c:51
static void asgml3_multi(stringbuffer_t *sb, const LWCOLLECTION *col, const GML_Options *opts)
Definition lwout_gml.c:682
static void asgml3_gbox(stringbuffer_t *sb, const GBOX *bbox, const GML_Options *opts)
Definition lwout_gml.c:163
static void asgml2_point(stringbuffer_t *sb, const LWPOINT *point, const GML_Options *opts)
Definition lwout_gml.c:203
static void asgml2_poly(stringbuffer_t *sb, const LWPOLY *poly, const GML_Options *opts)
Definition lwout_gml.c:240
static void asgml2_gbox(stringbuffer_t *sb, const GBOX *bbox, const GML_Options *opts)
Definition lwout_gml.c:82
static void asgml3_poly(stringbuffer_t *sb, const LWPOLY *poly, const GML_Options *opts)
Definition lwout_gml.c:456
static void asgml3_collection(stringbuffer_t *sb, const LWCOLLECTION *col, const GML_Options *opts)
Definition lwout_gml.c:798
static void asgml3_circstring(stringbuffer_t *sb, const LWCIRCSTRING *circ, const GML_Options *opts)
Definition lwout_gml.c:507
static void asgml2_collection(stringbuffer_t *sb, const LWCOLLECTION *col, const GML_Options *opts)
Definition lwout_gml.c:326
static void asgml3_multisurface(stringbuffer_t *sb, const LWMSURFACE *sur, const GML_Options *opts)
Definition lwout_gml.c:893
lwvarlena_t * lwgeom_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
Definition lwout_gml.c:920
static void asgml3_psurface(stringbuffer_t *sb, const LWPSURFACE *psur, const GML_Options *opts)
Definition lwout_gml.c:768
static void asgml3_multicurve(stringbuffer_t *sb, const LWMCURVE *cur, const GML_Options *opts)
Definition lwout_gml.c:854
static void asgml3_triangle(stringbuffer_t *sb, const LWTRIANGLE *triangle, const GML_Options *opts)
Definition lwout_gml.c:656
static void asgml2_line(stringbuffer_t *sb, const LWLINE *line, const GML_Options *opts)
Definition lwout_gml.c:221
static void asgml3_line(stringbuffer_t *sb, const LWLINE *line, const GML_Options *opts)
Definition lwout_gml.c:401
static void asgml3_ptarray(stringbuffer_t *sb, const POINTARRAY *pa, const GML_Options *opts)
Definition lwout_gml.c:112
lwvarlena_t * lwgeom_extent_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
Definition lwout_gml.c:1063
lwvarlena_t * lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:978
static void asgml3_point(stringbuffer_t *sb, const LWPOINT *point, const GML_Options *opts)
Definition lwout_gml.c:378
static void asgml2_multi(stringbuffer_t *sb, const LWCOLLECTION *col, const GML_Options *opts)
Definition lwout_gml.c:273
static void asgml3_tin(stringbuffer_t *sb, const LWTIN *tin, const GML_Options *opts)
Definition lwout_gml.c:740
lwvarlena_t * stringbuffer_getvarlena(stringbuffer_t *s)
void stringbuffer_release(stringbuffer_t *s)
int stringbuffer_aprintf(stringbuffer_t *s, const char *fmt,...)
Appends a formatted string to the current string buffer, using the format and argument list provided.
void stringbuffer_init_varlena(stringbuffer_t *s)
static void stringbuffer_append_double(stringbuffer_t *s, double d, int precision)
static void stringbuffer_append(stringbuffer_t *s, const char *a)
Append the specified string to the stringbuffer_t.
static void stringbuffer_append_char(stringbuffer_t *s, char c)
double ymax
Definition liblwgeom.h:357
double zmax
Definition liblwgeom.h:359
double xmax
Definition liblwgeom.h:355
double zmin
Definition liblwgeom.h:358
double ymin
Definition liblwgeom.h:356
double xmin
Definition liblwgeom.h:354
lwflags_t flags
Definition liblwgeom.h:353
const char * srs
Definition lwout_gml.c:41
int precision
Definition lwout_gml.c:42
const char * prefix
Definition lwout_gml.c:45
const char * id
Definition lwout_gml.c:46
lwflags_t flags
Definition liblwgeom.h:509
POINTARRAY * points
Definition liblwgeom.h:507
uint32_t ngeoms
Definition liblwgeom.h:580
uint8_t type
Definition liblwgeom.h:578
LWGEOM ** geoms
Definition liblwgeom.h:575
lwflags_t flags
Definition liblwgeom.h:591
uint32_t ngeoms
Definition liblwgeom.h:594
LWGEOM ** geoms
Definition liblwgeom.h:589
LWGEOM ** rings
Definition liblwgeom.h:603
lwflags_t flags
Definition liblwgeom.h:605
uint32_t nrings
Definition liblwgeom.h:608
uint8_t type
Definition liblwgeom.h:462
lwflags_t flags
Definition liblwgeom.h:485
POINTARRAY * points
Definition liblwgeom.h:483
uint32_t ngeoms
Definition liblwgeom.h:636
LWGEOM ** geoms
Definition liblwgeom.h:631
POINTARRAY * point
Definition liblwgeom.h:471
uint8_t type
Definition liblwgeom.h:474
lwflags_t flags
Definition liblwgeom.h:473
POINTARRAY ** rings
Definition liblwgeom.h:519
uint32_t nrings
Definition liblwgeom.h:524
lwflags_t flags
Definition liblwgeom.h:521
LWPOLY ** geoms
Definition liblwgeom.h:645
uint32_t ngeoms
Definition liblwgeom.h:650
uint32_t ngeoms
Definition liblwgeom.h:664
LWTRIANGLE ** geoms
Definition liblwgeom.h:659
lwflags_t flags
Definition liblwgeom.h:497
POINTARRAY * points
Definition liblwgeom.h:495
double y
Definition liblwgeom.h:390
double x
Definition liblwgeom.h:390
double z
Definition liblwgeom.h:402
double x
Definition liblwgeom.h:402
double y
Definition liblwgeom.h:402
double x
Definition liblwgeom.h:414
double z
Definition liblwgeom.h:414
double y
Definition liblwgeom.h:414
lwflags_t flags
Definition liblwgeom.h:431
uint32_t npoints
Definition liblwgeom.h:427