PostGIS 3.0.6dev-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
37
38static size_t asgml2_point_size(const LWPOINT *point, const char *srs, int precision, const char *prefix);
39static char *asgml2_point(const LWPOINT *point, const char *srs, int precision, const char *prefix);
40static size_t asgml2_line_size(const LWLINE *line, const char *srs, int precision, const char *prefix);
41static char *asgml2_line(const LWLINE *line, const char *srs, int precision, const char *prefix);
42static size_t asgml2_poly_size(const LWPOLY *poly, const char *srs, int precision, const char *prefix);
43static char *asgml2_poly(const LWPOLY *poly, const char *srs, int precision, const char *prefix);
44static size_t asgml2_multi_size(const LWCOLLECTION *col, const char *srs, int precision, const char *prefix);
45static char *asgml2_multi(const LWCOLLECTION *col, const char *srs, int precision, const char *prefix);
46static size_t asgml2_collection_size(const LWCOLLECTION *col, const char *srs, int precision, const char *prefix);
47static char *asgml2_collection(const LWCOLLECTION *col, const char *srs, int precision, const char *prefix);
48static size_t pointArray_toGML2(POINTARRAY *pa, char *buf, int precision);
49
50static size_t asgml3_point_size(const LWPOINT *point, const char *srs, int precision, int opts, const char *prefix, const char *id);
51static char *asgml3_point(const LWPOINT *point, const char *srs, int precision, int opts, const char *prefix, const char *id);
52static size_t asgml3_line_size(const LWLINE *line, const char *srs, int precision, int opts, const char *prefix, const char *id);
53static char *asgml3_line(const LWLINE *line, const char *srs, int precision, int opts, const char *prefix, const char *id);
54static char *asgml3_circstring( const LWCIRCSTRING *circ, const char *srs, int precision, int opts, const char *prefix, const char *id );
55static size_t asgml3_poly_size(const LWPOLY *poly, const char *srs, int precision, int opts, const char *prefix, const char *id);
56static char *asgml3_poly(const LWPOLY *poly, const char *srs, int precision, int opts, int is_patch, const char *prefix, const char *id);
57static char * asgml3_curvepoly(const LWCURVEPOLY* poly, const char *srs, int precision, int opts, const char *prefix, const char *id);
58static size_t asgml3_triangle_size(const LWTRIANGLE *triangle, const char *srs, int precision, int opts, const char *prefix, const char *id);
59static char *asgml3_triangle(const LWTRIANGLE *triangle, const char *srs, int precision, int opts, const char *prefix, const char *id);
60static size_t asgml3_multi_size(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id);
61static char *asgml3_multi(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id);
62static char *asgml3_psurface(const LWPSURFACE *psur, const char *srs, int precision, int opts, const char *prefix, const char *id);
63static char *asgml3_tin(const LWTIN *tin, const char *srs, int precision, int opts, const char *prefix, const char *id);
64static size_t asgml3_collection_size(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id);
65static char *asgml3_collection(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id);
66static char *asgml3_compound(const LWCOMPOUND *col, const char *srs, int precision, int opts, const char *prefix, const char *id );
67static char *asgml3_multicurve( const LWMCURVE* cur, const char *srs, int precision, int opts, const char *prefix, const char *id );
68static char *asgml3_multisurface(const LWMSURFACE *sur, const char *srs, int precision, int opts, const char *prefix, const char *id);
69static size_t pointArray_toGML3(POINTARRAY *pa, char *buf, int precision, int opts);
70
71
72static size_t pointArray_GMLsize(POINTARRAY *pa, int precision);
73
74static char *
75gbox_to_gml2(const GBOX *bbox, const char *srs, int precision, const char *prefix)
76{
77 int size;
78 POINT4D pt;
79 POINTARRAY *pa;
80 char *ptr, *output;
81 size_t prefixlen = strlen(prefix);
82
83 if ( ! bbox )
84 {
85 size = ( sizeof("<Box>/") + (prefixlen*2) ) * 2;
86 if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
87
88 ptr = output = lwalloc(size);
89
90 ptr += sprintf(ptr, "<%sBox", prefix);
91
92 if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
93
94 ptr += sprintf(ptr, "/>");
95
96 return output;
97 }
98
99 pa = ptarray_construct_empty(FLAGS_GET_Z(bbox->flags), 0, 2);
100
101 pt.x = bbox->xmin;
102 pt.y = bbox->ymin;
103 if (FLAGS_GET_Z(bbox->flags)) pt.z = bbox->zmin;
105
106 pt.x = bbox->xmax;
107 pt.y = bbox->ymax;
108 if (FLAGS_GET_Z(bbox->flags)) pt.z = bbox->zmax;
110
111 size = pointArray_GMLsize(pa, precision);
112 size += ( sizeof("<Box><coordinates>/") + (prefixlen*2) ) * 2;
113 if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
114
115 ptr = output = lwalloc(size);
116
117 if ( srs ) ptr += sprintf(ptr, "<%sBox srsName=\"%s\">", prefix, srs);
118 else ptr += sprintf(ptr, "<%sBox>", prefix);
119
120 ptr += sprintf(ptr, "<%scoordinates>", prefix);
121 ptr += pointArray_toGML2(pa, ptr, precision);
122 ptr += sprintf(ptr, "</%scoordinates></%sBox>", prefix, prefix);
123
124 ptarray_free(pa);
125
126 return output;
127}
128
129static char *
130gbox_to_gml3(const GBOX *bbox, const char *srs, int precision, int opts, const char *prefix)
131{
132 int size;
133 POINT4D pt;
134 POINTARRAY *pa;
135 char *ptr, *output;
136 size_t prefixlen = strlen(prefix);
137 int dimension = 2;
138
139 if ( ! bbox )
140 {
141 size = ( sizeof("<Envelope>/") + (prefixlen*2) ) * 2;
142 if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
143
144 ptr = output = lwalloc(size);
145
146 ptr += sprintf(ptr, "<%sEnvelope", prefix);
147 if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
148
149 ptr += sprintf(ptr, "/>");
150
151 return output;
152 }
153
154 if (FLAGS_GET_Z(bbox->flags)) dimension = 3;
155
156 pa = ptarray_construct_empty(FLAGS_GET_Z(bbox->flags), 0, 1);
157
158 pt.x = bbox->xmin;
159 pt.y = bbox->ymin;
160 if (FLAGS_GET_Z(bbox->flags)) pt.z = bbox->zmin;
162
163 size = pointArray_GMLsize(pa, precision) * 2;
164 size += ( sizeof("<Envelope><lowerCorner><upperCorner>//") + (prefixlen*3) ) * 2;
165 if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
166 if ( IS_DIMS(opts) ) size += sizeof(" srsDimension=. .");
167
168 ptr = output = lwalloc(size);
169
170 ptr += sprintf(ptr, "<%sEnvelope", prefix);
171 if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
172 if ( IS_DIMS(opts) ) ptr += sprintf(ptr, " srsDimension=\"%d\"", dimension);
173 ptr += sprintf(ptr, ">");
174
175 ptr += sprintf(ptr, "<%slowerCorner>", prefix);
176 ptr += pointArray_toGML3(pa, ptr, precision, opts);
177 ptr += sprintf(ptr, "</%slowerCorner>", prefix);
178
180 pt.x = bbox->xmax;
181 pt.y = bbox->ymax;
182 if (FLAGS_GET_Z(bbox->flags)) pt.z = bbox->zmax;
184
185 ptr += sprintf(ptr, "<%supperCorner>", prefix);
186 ptr += pointArray_toGML3(pa, ptr, precision, opts);
187 ptr += sprintf(ptr, "</%supperCorner>", prefix);
188
189 ptr += sprintf(ptr, "</%sEnvelope>", prefix);
190
191 ptarray_free(pa);
192
193 return output;
194}
195
196
197extern char *
198lwgeom_extent_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
199{
200 const GBOX* bbox = lwgeom_get_bbox(geom);
201 /*
202 if ( ! bbox ) {
203 lwerror("lwgeom_extent_to_gml2: empty geometry doesn't have a bounding box");
204 return NULL;
205 }
206 */
207 char *ret = gbox_to_gml2(bbox, srs, precision, prefix);
208 return ret;
209}
210
211
212extern char *
213lwgeom_extent_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix)
214{
215 const GBOX* bbox = lwgeom_get_bbox(geom);
216 /*
217 if ( ! bbox ) {
218 lwerror("lwgeom_extent_to_gml3: empty geometry doesn't have a bounding box");
219 return NULL;
220 }
221 */
222 return gbox_to_gml3(bbox, srs, precision, opts, prefix);
223}
224
225
230extern char *
231lwgeom_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char* prefix)
232{
233 int type = geom->type;
234
235 /* Return null for empty (#1377) */
236 if ( lwgeom_is_empty(geom) )
237 return NULL;
238
239 switch (type)
240 {
241 case POINTTYPE:
242 return asgml2_point((LWPOINT*)geom, srs, precision, prefix);
243
244 case LINETYPE:
245 return asgml2_line((LWLINE*)geom, srs, precision, prefix);
246
247 case POLYGONTYPE:
248 return asgml2_poly((LWPOLY*)geom, srs, precision, prefix);
249
250 case MULTIPOINTTYPE:
251 case MULTILINETYPE:
252 case MULTIPOLYGONTYPE:
253 return asgml2_multi((LWCOLLECTION*)geom, srs, precision, prefix);
254
255 case COLLECTIONTYPE:
256 return asgml2_collection((LWCOLLECTION*)geom, srs, precision, prefix);
257
258 case TRIANGLETYPE:
260 case TINTYPE:
261 lwerror("Cannot convert %s to GML2. Try ST_AsGML(3, <geometry>) to generate GML3.", lwtype_name(type));
262 return NULL;
263
264 default:
265 lwerror("lwgeom_to_gml2: '%s' geometry type not supported", lwtype_name(type));
266 return NULL;
267 }
268}
269
270static size_t
271asgml2_point_size(const LWPOINT *point, const char *srs, int precision, const char* prefix)
272{
273 int size;
274 size_t prefixlen = strlen(prefix);
275
276 size = pointArray_GMLsize(point->point, precision);
277 size += ( sizeof("<point><coordinates>/") + (prefixlen*2) ) * 2;
278 if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
279 return size;
280}
281
282static size_t
283asgml2_point_buf(const LWPOINT *point, const char *srs, char *output, int precision, const char* prefix)
284{
285 char *ptr = output;
286
287 ptr += sprintf(ptr, "<%sPoint", prefix);
288 if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
289 if ( lwpoint_is_empty(point) )
290 {
291 ptr += sprintf(ptr, "/>");
292 return (ptr-output);
293 }
294 ptr += sprintf(ptr, ">");
295 ptr += sprintf(ptr, "<%scoordinates>", prefix);
296 ptr += pointArray_toGML2(point->point, ptr, precision);
297 ptr += sprintf(ptr, "</%scoordinates></%sPoint>", prefix, prefix);
298
299 return (ptr-output);
300}
301
302static char *
303asgml2_point(const LWPOINT *point, const char *srs, int precision, const char *prefix)
304{
305 char *output;
306 int size;
307
308 size = asgml2_point_size(point, srs, precision, prefix);
309 output = lwalloc(size);
310 asgml2_point_buf(point, srs, output, precision, prefix);
311 return output;
312}
313
314static size_t
315asgml2_line_size(const LWLINE *line, const char *srs, int precision, const char *prefix)
316{
317 int size;
318 size_t prefixlen = strlen(prefix);
319
320 size = pointArray_GMLsize(line->points, precision);
321 size += ( sizeof("<linestring><coordinates>/") + (prefixlen*2) ) * 2;
322 if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
323 return size;
324}
325
326static size_t
327asgml2_line_buf(const LWLINE *line, const char *srs, char *output, int precision,
328 const char *prefix)
329{
330 char *ptr=output;
331
332 ptr += sprintf(ptr, "<%sLineString", prefix);
333 if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
334
335 if ( lwline_is_empty(line) )
336 {
337 ptr += sprintf(ptr, "/>");
338 return (ptr-output);
339 }
340 ptr += sprintf(ptr, ">");
341
342 ptr += sprintf(ptr, "<%scoordinates>", prefix);
343 ptr += pointArray_toGML2(line->points, ptr, precision);
344 ptr += sprintf(ptr, "</%scoordinates></%sLineString>", prefix, prefix);
345
346 return (ptr-output);
347}
348
349static char *
350asgml2_line(const LWLINE *line, const char *srs, int precision, const char *prefix)
351{
352 char *output;
353 int size;
354
355 size = asgml2_line_size(line, srs, precision, prefix);
356 output = lwalloc(size);
357 asgml2_line_buf(line, srs, output, precision, prefix);
358 return output;
359}
360
361static size_t
362asgml2_poly_size(const LWPOLY *poly, const char *srs, int precision, const char *prefix)
363{
364 size_t size;
365 uint32_t i;
366 size_t prefixlen = strlen(prefix);
367
368 size = sizeof("<polygon></polygon>") + prefixlen*2;
369 if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
370 if ( lwpoly_is_empty(poly) )
371 return size;
372 size += ( sizeof("<outerboundaryis><linearring><coordinates>/") + ( prefixlen*3) ) * 2;
373 size += ( sizeof("<innerboundaryis><linearring><coordinates>/") + ( prefixlen*2) ) * 2 * poly->nrings;
374
375 for (i=0; i<poly->nrings; i++)
376 size += pointArray_GMLsize(poly->rings[i], precision);
377
378 return size;
379}
380
381static size_t
382asgml2_poly_buf(const LWPOLY *poly, const char *srs, char *output, int precision,
383 const char *prefix)
384{
385 uint32_t i;
386 char *ptr=output;
387
388 ptr += sprintf(ptr, "<%sPolygon", prefix);
389 if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
390 if ( lwpoly_is_empty(poly) )
391 {
392 ptr += sprintf(ptr, "/>");
393 return (ptr-output);
394 }
395 ptr += sprintf(ptr, ">");
396 ptr += sprintf(ptr, "<%souterBoundaryIs><%sLinearRing><%scoordinates>",
397 prefix, prefix, prefix);
398 ptr += pointArray_toGML2(poly->rings[0], ptr, precision);
399 ptr += sprintf(ptr, "</%scoordinates></%sLinearRing></%souterBoundaryIs>", prefix, prefix, prefix);
400 for (i=1; i<poly->nrings; i++)
401 {
402 ptr += sprintf(ptr, "<%sinnerBoundaryIs><%sLinearRing><%scoordinates>", prefix, prefix, prefix);
403 ptr += pointArray_toGML2(poly->rings[i], ptr, precision);
404 ptr += sprintf(ptr, "</%scoordinates></%sLinearRing></%sinnerBoundaryIs>", prefix, prefix, prefix);
405 }
406 ptr += sprintf(ptr, "</%sPolygon>", prefix);
407
408 return (ptr-output);
409}
410
411static char *
412asgml2_poly(const LWPOLY *poly, const char *srs, int precision, const char *prefix)
413{
414 char *output;
415 int size;
416
417 size = asgml2_poly_size(poly, srs, precision, prefix);
418 output = lwalloc(size);
419 asgml2_poly_buf(poly, srs, output, precision, prefix);
420 return output;
421}
422
423/*
424 * Compute max size required for GML version of this
425 * inspected geometry. Will recurse when needed.
426 * Don't call this with single-geoms inspected.
427 */
428static size_t
429asgml2_multi_size(const LWCOLLECTION *col, const char *srs, int precision,
430 const char *prefix)
431{
432 uint32_t i;
433 size_t size;
434 size_t prefixlen = strlen(prefix);
435 LWGEOM *subgeom;
436
437 /* the longest possible multi version */
438 size = sizeof("<MultiLineString></MultiLineString>");
439 size += 2*prefixlen;
440
441 if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
442
443 for (i=0; i<col->ngeoms; i++)
444 {
445 subgeom = col->geoms[i];
446 if (subgeom->type == POINTTYPE)
447 {
448 size += ( sizeof("<pointMember>/") + prefixlen ) * 2;
449 size += asgml2_point_size((LWPOINT*)subgeom, 0, precision, prefix);
450 }
451 else if (subgeom->type == LINETYPE)
452 {
453 size += ( sizeof("<lineStringMember>/") + prefixlen ) * 2;
454 size += asgml2_line_size((LWLINE*)subgeom, 0, precision, prefix);
455 }
456 else if (subgeom->type == POLYGONTYPE)
457 {
458 size += ( sizeof("<polygonMember>/") + prefixlen ) * 2;
459 size += asgml2_poly_size((LWPOLY*)subgeom, 0, precision, prefix);
460 }
461 }
462
463 return size;
464}
465
466/*
467 * Don't call this with single-geoms inspected!
468 */
469static size_t
470asgml2_multi_buf(const LWCOLLECTION *col, const char *srs, char *output,
471 int precision, const char *prefix)
472{
473 int type = col->type;
474 char *ptr, *gmltype;
475 uint32_t i;
476 LWGEOM *subgeom;
477
478 ptr = output;
479 gmltype="";
480
481 if (type == MULTIPOINTTYPE) gmltype = "MultiPoint";
482 else if (type == MULTILINETYPE) gmltype = "MultiLineString";
483 else if (type == MULTIPOLYGONTYPE) gmltype = "MultiPolygon";
484
485 /* Open outmost tag */
486 ptr += sprintf(ptr, "<%s%s", prefix, gmltype);
487 if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
488
489 if (!col->ngeoms)
490 {
491 ptr += sprintf(ptr, "/>");
492 return (ptr-output);
493 }
494 ptr += sprintf(ptr, ">");
495
496 for (i=0; i<col->ngeoms; i++)
497 {
498 subgeom = col->geoms[i];
499 if (subgeom->type == POINTTYPE)
500 {
501 ptr += sprintf(ptr, "<%spointMember>", prefix);
502 ptr += asgml2_point_buf((LWPOINT*)subgeom, 0, ptr, precision, prefix);
503 ptr += sprintf(ptr, "</%spointMember>", prefix);
504 }
505 else if (subgeom->type == LINETYPE)
506 {
507 ptr += sprintf(ptr, "<%slineStringMember>", prefix);
508 ptr += asgml2_line_buf((LWLINE*)subgeom, 0, ptr, precision, prefix);
509 ptr += sprintf(ptr, "</%slineStringMember>", prefix);
510 }
511 else if (subgeom->type == POLYGONTYPE)
512 {
513 ptr += sprintf(ptr, "<%spolygonMember>", prefix);
514 ptr += asgml2_poly_buf((LWPOLY*)subgeom, 0, ptr, precision, prefix);
515 ptr += sprintf(ptr, "</%spolygonMember>", prefix);
516 }
517 }
518
519 /* Close outmost tag */
520 ptr += sprintf(ptr, "</%s%s>", prefix, gmltype);
521
522 return (ptr-output);
523}
524
525/*
526 * Don't call this with single-geoms inspected!
527 */
528static char *
529asgml2_multi(const LWCOLLECTION *col, const char *srs, int precision,
530 const char *prefix)
531{
532 char *gml;
533 size_t size;
534
535 size = asgml2_multi_size(col, srs, precision, prefix);
536 gml = lwalloc(size);
537 asgml2_multi_buf(col, srs, gml, precision, prefix);
538 return gml;
539}
540
541
542/*
543 * Don't call this with single-geoms!
544 */
545static size_t
546asgml2_collection_size(const LWCOLLECTION *col, const char *srs, int precision,
547 const char *prefix)
548{
549 uint32_t i;
550 size_t size;
551 size_t prefixlen = strlen(prefix);
552 LWGEOM *subgeom;
553
554 size = sizeof("<MultiGeometry></MultiGeometry>");
555 size += (prefixlen * 2);
556
557 if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
558
559 for (i=0; i<col->ngeoms; i++)
560 {
561 subgeom = col->geoms[i];
562
563 size += ( sizeof("<geometryMember>/") + prefixlen ) * 2;
564 if ( subgeom->type == POINTTYPE)
565 {
566 size += asgml2_point_size((LWPOINT*)subgeom, 0, precision, prefix);
567 }
568 else if ( subgeom->type == LINETYPE)
569 {
570 size += asgml2_line_size((LWLINE*)subgeom, 0, precision, prefix);
571 }
572 else if ( subgeom->type == POLYGONTYPE)
573 {
574 size += asgml2_poly_size((LWPOLY*)subgeom, 0, precision, prefix);
575 }
576 else if ( lwgeom_is_collection(subgeom) )
577 {
578 size += asgml2_collection_size((LWCOLLECTION*)subgeom, 0, precision, prefix);
579 }
580 else
581 lwerror("asgml2_collection_size: Unable to process geometry type!");
582 }
583
584
585 return size;
586}
587
588/*
589 * Don't call this with single-geoms inspected!
590 */
591static size_t
592asgml2_collection_buf(const LWCOLLECTION *col, const char *srs, char *output, int precision, const char *prefix)
593{
594 char *ptr;
595 uint32_t i;
596 LWGEOM *subgeom;
597
598 ptr = output;
599
600 /* Open outmost tag */
601 ptr += sprintf(ptr, "<%sMultiGeometry", prefix);
602 if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
603
604 if (!col->ngeoms)
605 {
606 ptr += sprintf(ptr, "/>");
607 return (ptr-output);
608 }
609 ptr += sprintf(ptr, ">");
610
611 for (i=0; i<col->ngeoms; i++)
612 {
613 subgeom = col->geoms[i];
614
615 ptr += sprintf(ptr, "<%sgeometryMember>", prefix);
616 if (subgeom->type == POINTTYPE)
617 {
618 ptr += asgml2_point_buf((LWPOINT*)subgeom, 0, ptr, precision, prefix);
619 }
620 else if (subgeom->type == LINETYPE)
621 {
622 ptr += asgml2_line_buf((LWLINE*)subgeom, 0, ptr, precision, prefix);
623 }
624 else if (subgeom->type == POLYGONTYPE)
625 {
626 ptr += asgml2_poly_buf((LWPOLY*)subgeom, 0, ptr, precision, prefix);
627 }
628 else if (lwgeom_is_collection(subgeom))
629 {
630 if (subgeom->type == COLLECTIONTYPE)
631 ptr += asgml2_collection_buf((LWCOLLECTION*)subgeom, 0, ptr, precision, prefix);
632 else
633 ptr += asgml2_multi_buf((LWCOLLECTION*)subgeom, 0, ptr, precision, prefix);
634 }
635 ptr += sprintf(ptr, "</%sgeometryMember>", prefix);
636 }
637
638 /* Close outmost tag */
639 ptr += sprintf(ptr, "</%sMultiGeometry>", prefix);
640
641 return (ptr-output);
642}
643
644/*
645 * Don't call this with single-geoms inspected!
646 */
647static char *
648asgml2_collection(const LWCOLLECTION *col, const char *srs, int precision,
649 const char *prefix)
650{
651 char *gml;
652 size_t size;
653
654 size = asgml2_collection_size(col, srs, precision, prefix);
655 gml = lwalloc(size);
656 asgml2_collection_buf(col, srs, gml, precision, prefix);
657 return gml;
658}
659
660
661static size_t
663{
664 uint32_t i;
665 char *ptr;
669
670 ptr = output;
671
672 if ( ! FLAGS_GET_Z(pa->flags) )
673 {
674 for (i=0; i<pa->npoints; i++)
675 {
676 const POINT2D *pt;
677 pt = getPoint2d_cp(pa, i);
678
683
684 if ( i ) ptr += sprintf(ptr, " ");
685 ptr += sprintf(ptr, "%s,%s", x, y);
686 }
687 }
688 else
689 {
690 for (i=0; i<pa->npoints; i++)
691 {
692 const POINT3D *pt = getPoint3d_cp(pa, i);
699
700 if ( i ) ptr += sprintf(ptr, " ");
701 ptr += sprintf(ptr, "%s,%s,%s", x, y, z);
702 }
703 }
704
705 return ptr-output;
706}
707
708
709/*
710 * VERSION GML 3.1.1
711 */
712
713
714/* takes a GEOMETRY and returns a GML representation */
715extern char *
716lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix, const char *id)
717{
718 int type = geom->type;
719
720 /* Return null for empty (#1377) */
721 if ( lwgeom_is_empty(geom) )
722 return NULL;
723
724 switch (type)
725 {
726 case POINTTYPE:
727 return asgml3_point((LWPOINT*)geom, srs, precision, opts, prefix, id);
728
729 case LINETYPE:
730 return asgml3_line((LWLINE*)geom, srs, precision, opts, prefix, id);
731
732 case CIRCSTRINGTYPE:
733 return asgml3_circstring((LWCIRCSTRING*)geom, srs, precision, opts, prefix, id );
734
735 case POLYGONTYPE:
736 return asgml3_poly((LWPOLY*)geom, srs, precision, opts, 0, prefix, id);
737
738 case CURVEPOLYTYPE:
739 return asgml3_curvepoly((LWCURVEPOLY*)geom, srs, precision, opts, prefix, id);
740
741 case TRIANGLETYPE:
742 return asgml3_triangle((LWTRIANGLE*)geom, srs, precision, opts, prefix, id);
743
744 case MULTIPOINTTYPE:
745 case MULTILINETYPE:
746 case MULTIPOLYGONTYPE:
747 return asgml3_multi((LWCOLLECTION*)geom, srs, precision, opts, prefix, id);
748
750 return asgml3_psurface((LWPSURFACE*)geom, srs, precision, opts, prefix, id);
751
752 case TINTYPE:
753 return asgml3_tin((LWTIN*)geom, srs, precision, opts, prefix, id);
754
755 case COLLECTIONTYPE:
756 return asgml3_collection((LWCOLLECTION*)geom, srs, precision, opts, prefix, id);
757
758 case COMPOUNDTYPE:
759 return asgml3_compound( (LWCOMPOUND*)geom, srs, precision, opts, prefix, id );
760
761 case MULTICURVETYPE:
762 return asgml3_multicurve( (LWMCURVE*)geom, srs, precision, opts, prefix, id );
763
764 case MULTISURFACETYPE:
765 return asgml3_multisurface( (LWMSURFACE*)geom, srs, precision, opts, prefix, id );
766
767 default:
768 lwerror("lwgeom_to_gml3: '%s' geometry type not supported", lwtype_name(type));
769 return NULL;
770 }
771}
772
773static size_t
774asgml3_point_size(const LWPOINT *point, const char *srs, int precision, int opts, const char *prefix, const char *id)
775{
776 int size;
777 size_t prefixlen = strlen(prefix);
778
779 size = pointArray_GMLsize(point->point, precision);
780 size += ( sizeof("<point><pos>/") + (prefixlen*2) ) * 2;
781 if (srs) size += strlen(srs) + sizeof(" srsName=..");
782 if (id) size += strlen(id) + strlen(prefix) + sizeof(" id=..");
783 if (IS_DIMS(opts)) size += sizeof(" srsDimension='x'");
784 return size;
785}
786
787static size_t
788asgml3_point_buf(const LWPOINT *point, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
789{
790 char *ptr = output;
791 int dimension=2;
792
793 if (FLAGS_GET_Z(point->flags)) dimension = 3;
794
795 ptr += sprintf(ptr, "<%sPoint", prefix);
796 if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
797 if ( id ) ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id);
798 if ( lwpoint_is_empty(point) )
799 {
800 ptr += sprintf(ptr, "/>");
801 return (ptr-output);
802 }
803
804 ptr += sprintf(ptr, ">");
805 if (IS_DIMS(opts)) ptr += sprintf(ptr, "<%spos srsDimension=\"%d\">", prefix, dimension);
806 else ptr += sprintf(ptr, "<%spos>", prefix);
807 ptr += pointArray_toGML3(point->point, ptr, precision, opts);
808 ptr += sprintf(ptr, "</%spos></%sPoint>", prefix, prefix);
809
810 return (ptr-output);
811}
812
813static char *
814asgml3_point(const LWPOINT *point, const char *srs, int precision, int opts, const char *prefix, const char *id)
815{
816 char *output;
817 int size;
818
819 size = asgml3_point_size(point, srs, precision, opts, prefix, id);
820 output = lwalloc(size);
821 asgml3_point_buf(point, srs, output, precision, opts, prefix, id);
822 return output;
823}
824
825
826static size_t
827asgml3_line_size(const LWLINE *line, const char *srs, int precision, int opts, const char *prefix, const char *id)
828{
829 int size;
830 size_t prefixlen = strlen(prefix);
831
832 size = pointArray_GMLsize(line->points, precision);
833 if ( opts & LW_GML_SHORTLINE )
834 {
835 size += (
836 sizeof("<LineString><posList>/") +
837 ( prefixlen * 2 )
838 ) * 2;
839 }
840 else
841 {
842 size += (
843 sizeof("<Curve><segments><LineStringSegment><posList>/") +
844 ( prefixlen * 4 )
845 ) * 2;
846 }
847 if (srs) size += strlen(srs) + sizeof(" srsName=..");
848 if (id) size += strlen(id) + strlen(prefix) + sizeof(" id=..");
849 if (IS_DIMS(opts)) size += sizeof(" srsDimension='x'");
850 return size;
851}
852
853static size_t
854asgml3_line_buf(const LWLINE *line, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
855{
856 char *ptr=output;
857 int dimension=2;
858 int shortline = ( opts & LW_GML_SHORTLINE );
859
860 if (FLAGS_GET_Z(line->flags)) dimension = 3;
861
862 if ( shortline )
863 {
864 ptr += sprintf(ptr, "<%sLineString", prefix);
865 }
866 else
867 {
868 ptr += sprintf(ptr, "<%sCurve", prefix);
869 }
870
871 if (srs) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
872 if (id) ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id);
873
874 if ( lwline_is_empty(line) )
875 {
876 ptr += sprintf(ptr, "/>");
877 return (ptr-output);
878 }
879 ptr += sprintf(ptr, ">");
880
881 if ( ! shortline )
882 {
883 ptr += sprintf(ptr, "<%ssegments>", prefix);
884 ptr += sprintf(ptr, "<%sLineStringSegment>", prefix);
885 }
886
887 if (IS_DIMS(opts))
888 {
889 ptr += sprintf(ptr, "<%sposList srsDimension=\"%d\">",
890 prefix, dimension);
891 }
892 else
893 {
894 ptr += sprintf(ptr, "<%sposList>", prefix);
895 }
896
897 ptr += pointArray_toGML3(line->points, ptr, precision, opts);
898
899 ptr += sprintf(ptr, "</%sposList>", prefix);
900
901 if ( shortline )
902 {
903 ptr += sprintf(ptr, "</%sLineString>", prefix);
904 }
905 else
906 {
907 ptr += sprintf(ptr, "</%sLineStringSegment>", prefix);
908 ptr += sprintf(ptr, "</%ssegments>", prefix);
909 ptr += sprintf(ptr, "</%sCurve>", prefix);
910 }
911
912 return (ptr-output);
913}
914
915static char *
916asgml3_line(const LWLINE *line, const char *srs, int precision, int opts, const char *prefix, const char *id)
917{
918 char *output;
919 int size;
920
921 size = asgml3_line_size(line, srs, precision, opts, prefix, id);
922 output = lwalloc(size);
923 asgml3_line_buf(line, srs, output, precision, opts, prefix, id);
924 return output;
925}
926
927
928static size_t
929asgml3_circstring_size(const LWCIRCSTRING *circ, const char *srs, int precision, int opts, const char *prefix, const char *id)
930{
931 int size = pointArray_GMLsize( circ->points, precision );
932 size_t prefixlen = strlen(prefix);
933 size += 2 * ( sizeof( "<Curve><segments>/" ) + 2 * prefixlen );
934 size += 2 * ( sizeof( "<ArcString><posList>/" ) + 2 * prefixlen );
935 if (srs) size += strlen(srs) + sizeof(" srsName=..");
936 if (id) size += strlen(id) + strlen(prefix) + sizeof(" id=..");
937 if (IS_DIMS(opts)) size += sizeof(" srsDimension='x'");
938 return size;
939}
940
941static size_t
942asgml3_circstring_buf(const LWCIRCSTRING *circ, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
943{
944 char* ptr = output;
945 int dimension=2;
946
947 if (FLAGS_GET_Z(circ->flags))
948 {
949 dimension = 3;
950 }
951
952 ptr += sprintf(ptr, "<%sCurve", prefix);
953 if (srs)
954 {
955 ptr += sprintf(ptr, " srsName=\"%s\"", srs);
956 }
957 if (id)
958 {
959 ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id);
960 }
961 ptr += sprintf(ptr, ">");
962 ptr += sprintf(ptr, "<%ssegments>", prefix);
963 ptr += sprintf(ptr, "<%sArcString>", prefix);
964 ptr += sprintf(ptr, "<%sposList", prefix);
965
966 if (IS_DIMS(opts))
967 {
968 ptr += sprintf(ptr, " srsDimension=\"%d\"", dimension);
969 }
970 ptr += sprintf(ptr, ">");
971
972 ptr += pointArray_toGML3(circ->points, ptr, precision, opts);
973 ptr += sprintf(ptr, "</%sposList>", prefix);
974 ptr += sprintf(ptr, "</%sArcString>", prefix);
975 ptr += sprintf(ptr, "</%ssegments>", prefix);
976 ptr += sprintf(ptr, "</%sCurve>", prefix);
977 return (ptr-output);
978}
979
980static char *
981asgml3_circstring( const LWCIRCSTRING *circ, const char *srs, int precision, int opts, const char *prefix, const char *id )
982{
983 char *output;
984 int size;
985
986 size = asgml3_circstring_size(circ, srs, precision, opts, prefix, id);
987 output = lwalloc( size );
988 asgml3_circstring_buf(circ, srs, output, precision, opts, prefix, id);
989 return output;
990}
991
992
993static size_t
994asgml3_poly_size(const LWPOLY *poly, const char *srs, int precision, int opts, const char *prefix, const char *id)
995{
996 size_t size;
997 size_t prefixlen = strlen(prefix);
998 uint32_t i;
999
1000 size = ( sizeof("<PolygonPatch><exterior><LinearRing>///") + (prefixlen*3) ) * 2;
1001 size += ( sizeof("<interior><LinearRing>//") + (prefixlen*2) ) * 2 * (poly->nrings - 1);
1002 size += ( sizeof("<posList></posList>") + (prefixlen*2) ) * poly->nrings;
1003 if (srs) size += strlen(srs) + sizeof(" srsName=..");
1004 if (id) size += strlen(id) + strlen(prefix) + sizeof(" id=..");
1005 if (IS_DIMS(opts)) size += sizeof(" srsDimension='x'") * poly->nrings;
1006
1007 for (i=0; i<poly->nrings; i++)
1008 size += pointArray_GMLsize(poly->rings[i], precision);
1009
1010 return size;
1011}
1012
1013static size_t
1014asgml3_poly_buf(const LWPOLY *poly, const char *srs, char *output, int precision, int opts, int is_patch, const char *prefix, const char *id)
1015{
1016 uint32_t i;
1017 char *ptr=output;
1018 int dimension=2;
1019
1020 if (FLAGS_GET_Z(poly->flags)) dimension = 3;
1021 if (is_patch)
1022 {
1023 ptr += sprintf(ptr, "<%sPolygonPatch", prefix);
1024
1025 }
1026 else
1027 {
1028 ptr += sprintf(ptr, "<%sPolygon", prefix);
1029 }
1030
1031 if (srs) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
1032 if (id) ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id);
1033
1034 if ( lwpoly_is_empty(poly) )
1035 {
1036 ptr += sprintf(ptr, "/>");
1037 return (ptr-output);
1038 }
1039 ptr += sprintf(ptr, ">");
1040
1041 ptr += sprintf(ptr, "<%sexterior><%sLinearRing>", prefix, prefix);
1042 if (IS_DIMS(opts)) ptr += sprintf(ptr, "<%sposList srsDimension=\"%d\">", prefix, dimension);
1043 else ptr += sprintf(ptr, "<%sposList>", prefix);
1044
1045 ptr += pointArray_toGML3(poly->rings[0], ptr, precision, opts);
1046 ptr += sprintf(ptr, "</%sposList></%sLinearRing></%sexterior>",
1047 prefix, prefix, prefix);
1048 for (i=1; i<poly->nrings; i++)
1049 {
1050 ptr += sprintf(ptr, "<%sinterior><%sLinearRing>", prefix, prefix);
1051 if (IS_DIMS(opts)) ptr += sprintf(ptr, "<%sposList srsDimension=\"%d\">", prefix, dimension);
1052 else ptr += sprintf(ptr, "<%sposList>", prefix);
1053 ptr += pointArray_toGML3(poly->rings[i], ptr, precision, opts);
1054 ptr += sprintf(ptr, "</%sposList></%sLinearRing></%sinterior>",
1055 prefix, prefix, prefix);
1056 }
1057 if (is_patch) ptr += sprintf(ptr, "</%sPolygonPatch>", prefix);
1058 else ptr += sprintf(ptr, "</%sPolygon>", prefix);
1059
1060 return (ptr-output);
1061}
1062
1063static char *
1064asgml3_poly(const LWPOLY *poly, const char *srs, int precision, int opts, int is_patch, const char *prefix, const char *id)
1065{
1066 char *output;
1067 int size;
1068
1069 size = asgml3_poly_size(poly, srs, precision, opts, prefix, id);
1070 output = lwalloc(size);
1071 asgml3_poly_buf(poly, srs, output, precision, opts, is_patch, prefix, id);
1072 return output;
1073}
1074
1075static size_t
1076asgml3_compound_size(const LWCOMPOUND *col, const char *srs, int precision, int opts, const char *prefix, const char *id )
1077{
1078 uint32_t i;
1079 size_t size;
1080 LWGEOM *subgeom;
1081 size_t prefixlen = strlen(prefix);
1082
1083 size = ( sizeof( "<Curve></Curve>" ) + 2 * prefixlen );
1084
1085 if (srs) size += strlen(srs) + sizeof(" srsName=..");
1086 if (id) size += strlen(id) + strlen(prefix) + sizeof(" id=..");
1087
1088 size += ( sizeof("<segments></segments>") + 2 * prefixlen );
1089
1090 for(i= 0; i < col->ngeoms; ++i )
1091 {
1092 subgeom = col->geoms[i];
1093 if ( subgeom->type == LINETYPE )
1094 {
1095
1096 size += sizeof( "<LineStringSegment></LineStringSegment" ) + 2 * prefixlen;
1097 size += sizeof( "<posList></posList" ) + 2 * prefixlen;
1098 size += pointArray_GMLsize( ((LWLINE*)subgeom)->points, precision );
1099 }
1100 else if( subgeom->type == CIRCSTRINGTYPE )
1101 {
1102 size += sizeof( "<ArcString><posList></ArcString></posList>") + 4 * prefixlen;
1103 size += pointArray_GMLsize( ((LWCIRCSTRING*)subgeom)->points, precision );
1104 }
1105 else
1106 {
1107 continue;
1108 }
1109 if (IS_DIMS(opts))
1110 {
1111 size += sizeof(" srsDimension='x'");
1112 }
1113 }
1114 return size;
1115}
1116
1117static size_t
1118asgml3_compound_buf(const LWCOMPOUND *col, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
1119{
1120 LWGEOM *subgeom;
1121 uint32_t i;
1122 char* ptr = output;
1123 int dimension=2;
1124
1125 if (FLAGS_GET_Z(col->flags))
1126 {
1127 dimension = 3;
1128 }
1129
1130 ptr += sprintf( ptr, "<%sCurve", prefix );
1131 if (srs)
1132 {
1133 ptr += sprintf(ptr, " srsName=\"%s\"", srs);
1134 }
1135 if (id)
1136 {
1137 ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id );
1138 }
1139 ptr += sprintf( ptr, ">" );
1140 ptr += sprintf( ptr, "<%ssegments>", prefix );
1141
1142 for( i = 0; i < col->ngeoms; ++i )
1143 {
1144 subgeom = col->geoms[i];
1145 if( subgeom->type != LINETYPE && subgeom->type != CIRCSTRINGTYPE )
1146 {
1147 continue;
1148 }
1149
1150 if ( subgeom->type == LINETYPE )
1151 {
1152 ptr += sprintf( ptr, "<%sLineStringSegment><%sposList", prefix, prefix );
1153 if (IS_DIMS(opts))
1154 {
1155 ptr += sprintf(ptr, " srsDimension=\"%d\"", dimension);
1156 }
1157 ptr += sprintf(ptr, ">");
1158 ptr += pointArray_toGML3(((LWCIRCSTRING*)subgeom)->points, ptr, precision, opts);
1159 ptr += sprintf( ptr, "</%sposList></%sLineStringSegment>", prefix, prefix );
1160 }
1161 else if( subgeom->type == CIRCSTRINGTYPE )
1162 {
1163 ptr += sprintf( ptr, "<%sArcString><%sposList" , prefix, prefix );
1164 if (IS_DIMS(opts))
1165 {
1166 ptr += sprintf(ptr, " srsDimension=\"%d\"", dimension);
1167 }
1168 ptr += sprintf(ptr, ">");
1169 ptr += pointArray_toGML3(((LWLINE*)subgeom)->points, ptr, precision, opts);
1170 ptr += sprintf( ptr, "</%sposList></%sArcString>", prefix, prefix );
1171 }
1172 }
1173
1174 ptr += sprintf( ptr, "</%ssegments>", prefix );
1175 ptr += sprintf( ptr, "</%sCurve>", prefix );
1176 return ( ptr - output );
1177}
1178
1179static char *
1180asgml3_compound(const LWCOMPOUND *col, const char *srs, int precision, int opts, const char *prefix, const char *id )
1181{
1182 char* gml;
1183 size_t size;
1184
1185 size = asgml3_compound_size( col, srs, precision, opts, prefix, id );
1186 gml = lwalloc( size );
1187 asgml3_compound_buf( col, srs, gml, precision, opts, prefix, id );
1188 return gml;
1189}
1190
1191static size_t asgml3_curvepoly_size(const LWCURVEPOLY* poly, const char *srs, int precision, int opts, const char *prefix, const char *id)
1192{
1193 size_t prefixlen = strlen(prefix);
1194 LWGEOM* subgeom;
1195 size_t size = sizeof( "<Polygon></Polygon" ) + 2 * prefixlen;
1196 if (srs) size += strlen(srs) + sizeof(" srsName=..");
1197 if (id) size += strlen(id) + strlen(prefix) + sizeof(" id=..");
1198 uint32_t i;
1199
1200 for( i = 0; i < poly->nrings; ++i )
1201 {
1202 if( i == 0 )
1203 {
1204 size += sizeof( "<exterior></exterior>" ) + 2 * prefixlen;
1205 }
1206 else
1207 {
1208 size += sizeof( "<interior></interior>" ) + 2 * prefixlen;
1209 }
1210 subgeom = poly->rings[i];
1211
1212 if ( subgeom->type == LINETYPE )
1213 {
1214 size += sizeof("<LinearRing></LinearRing>") + 2 * prefixlen;
1215 size += sizeof("<posList></posList") + 2 * prefixlen;
1216 if (IS_DIMS(opts))
1217 {
1218 size += sizeof(" srsDimension='x'");
1219 }
1220 size += pointArray_GMLsize( ((LWLINE*)subgeom)->points, precision );
1221 }
1222 else if( subgeom->type == CIRCSTRINGTYPE )
1223 {
1224 size += sizeof("<Ring></Ring>") + 2 * prefixlen;
1225 size += sizeof("<CurveMember></CurveMember>") + 2 * prefixlen;
1226 size += asgml3_circstring_size((LWCIRCSTRING*)subgeom, srs, precision, opts, prefix, id);
1227 }
1228 else if( subgeom->type == COMPOUNDTYPE )
1229 {
1230 size += sizeof("<Ring></Ring>") + 2 * prefixlen;
1231 size += sizeof("<curveMember></curveMember>") + 2 * prefixlen;
1232 size += asgml3_compound_size( (LWCOMPOUND*)subgeom, srs, precision, opts, prefix, id );
1233 }
1234 }
1235 return size;
1236}
1237
1238static size_t asgml3_curvepoly_buf(const LWCURVEPOLY* poly, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
1239{
1240 uint32_t i;
1241 LWGEOM* subgeom;
1242 char *ptr=output;
1243 int dimension=2;
1244
1245 if (FLAGS_GET_Z(poly->flags))
1246 {
1247 dimension = 3;
1248 }
1249
1250 ptr += sprintf( ptr, "<%sPolygon", prefix );
1251 if (srs)
1252 {
1253 ptr += sprintf(ptr, " srsName=\"%s\"", srs);
1254 }
1255 if (id)
1256 {
1257 ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id );
1258 }
1259 ptr += sprintf(ptr, ">");
1260
1261 for( i = 0; i < poly->nrings; ++i )
1262 {
1263 if( i == 0 )
1264 {
1265 ptr += sprintf( ptr, "<%sexterior>", prefix);
1266 }
1267 else
1268 {
1269 ptr += sprintf( ptr, "<%sinterior>", prefix);
1270 }
1271
1272 subgeom = poly->rings[i];
1273 if ( subgeom->type == LINETYPE )
1274 {
1275 ptr += sprintf( ptr, "<%sLinearRing>", prefix );
1276 ptr += sprintf( ptr, "<%sposList", prefix );
1277 if (IS_DIMS(opts))
1278 {
1279 ptr += sprintf(ptr, " srsDimension=\"%d\"", dimension);
1280 }
1281 ptr += sprintf( ptr, ">" );
1282 ptr += pointArray_toGML3(((LWLINE*)subgeom)->points, ptr, precision, opts);
1283 ptr += sprintf( ptr, "</%sposList>", prefix );
1284 ptr += sprintf( ptr, "</%sLinearRing>", prefix );
1285 }
1286 else if( subgeom->type == CIRCSTRINGTYPE )
1287 {
1288 ptr += sprintf( ptr, "<%sRing>", prefix );
1289 ptr += sprintf( ptr, "<%scurveMember>", prefix );
1290 ptr += asgml3_circstring_buf( (LWCIRCSTRING*)subgeom, srs, ptr, precision, opts, prefix, id );
1291 ptr += sprintf( ptr, "</%scurveMember>", prefix );
1292 ptr += sprintf( ptr, "</%sRing>", prefix );
1293 }
1294 else if( subgeom->type == COMPOUNDTYPE )
1295 {
1296 ptr += sprintf( ptr, "<%sRing>", prefix );
1297 ptr += sprintf( ptr, "<%scurveMember>", prefix );
1298 ptr += asgml3_compound_buf( (LWCOMPOUND*)subgeom, srs, ptr, precision, opts, prefix, id );
1299 ptr += sprintf( ptr, "</%scurveMember>", prefix );
1300 ptr += sprintf( ptr, "</%sRing>", prefix );
1301 }
1302
1303 if( i == 0 )
1304 {
1305 ptr += sprintf( ptr, "</%sexterior>", prefix);
1306 }
1307 else
1308 {
1309 ptr += sprintf( ptr, "</%sinterior>", prefix);
1310 }
1311 }
1312
1313 ptr += sprintf( ptr, "</%sPolygon>", prefix );
1314 return (ptr - output);
1315}
1316
1317static char* asgml3_curvepoly(const LWCURVEPOLY* poly, const char *srs, int precision, int opts, const char *prefix, const char *id)
1318{
1319 char* gml;
1320 size_t size;
1321
1322 size = asgml3_curvepoly_size( poly, srs, precision, opts, prefix, id );
1323 gml = lwalloc( size );
1324 asgml3_curvepoly_buf( poly, srs, gml, precision, opts, prefix, id );
1325 return gml;
1326}
1327
1328
1329static size_t
1330asgml3_triangle_size(const LWTRIANGLE *triangle, const char *srs, int precision, int opts, const char *prefix, const char *id)
1331{
1332 size_t size;
1333 size_t prefixlen = strlen(prefix);
1334
1335 size = ( sizeof("<Triangle><exterior><LinearRing>///") + (prefixlen*3) ) * 2;
1336 size += sizeof("<posList></posList>") + (prefixlen*2);
1337 if (srs) size += strlen(srs) + sizeof(" srsName=..");
1338 if (id) size += strlen(prefix) + strlen(id) + sizeof(" id=..");
1339 if (IS_DIMS(opts)) size += sizeof(" srsDimension='x'");
1340
1341 size += pointArray_GMLsize(triangle->points, precision);
1342
1343 return size;
1344}
1345
1346static size_t
1347asgml3_triangle_buf(const LWTRIANGLE *triangle, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
1348{
1349 char *ptr=output;
1350 int dimension=2;
1351
1352 if (FLAGS_GET_Z(triangle->flags)) dimension = 3;
1353 ptr += sprintf(ptr, "<%sTriangle", prefix);
1354 if (srs) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
1355 if (id) ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id);
1356 ptr += sprintf(ptr, ">");
1357
1358 ptr += sprintf(ptr, "<%sexterior><%sLinearRing>", prefix, prefix);
1359 if (IS_DIMS(opts)) ptr += sprintf(ptr, "<%sposList srsDimension=\"%d\">", prefix, dimension);
1360 else ptr += sprintf(ptr, "<%sposList>", prefix);
1361
1362 ptr += pointArray_toGML3(triangle->points, ptr, precision, opts);
1363 ptr += sprintf(ptr, "</%sposList></%sLinearRing></%sexterior>",
1364 prefix, prefix, prefix);
1365
1366 ptr += sprintf(ptr, "</%sTriangle>", prefix);
1367
1368 return (ptr-output);
1369}
1370
1371static char *
1372asgml3_triangle(const LWTRIANGLE *triangle, const char *srs, int precision, int opts, const char *prefix, const char *id)
1373{
1374 char *output;
1375 int size;
1376
1377 size = asgml3_triangle_size(triangle, srs, precision, opts, prefix, id);
1378 output = lwalloc(size);
1379 asgml3_triangle_buf(triangle, srs, output, precision, opts, prefix, id);
1380 return output;
1381}
1382
1383
1384/*
1385 * Compute max size required for GML version of this
1386 * inspected geometry. Will recurse when needed.
1387 * Don't call this with single-geoms inspected.
1388 */
1389static size_t
1390asgml3_multi_size(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id)
1391{
1392 uint32_t i;
1393 size_t size;
1394 size_t prefixlen = strlen(prefix);
1395 LWGEOM *subgeom;
1396
1397 /* the longest possible multi version */
1398 size = sizeof("<MultiLineString></MultiLineString>") + prefixlen*2;
1399
1400 if (srs) size += strlen(srs) + sizeof(" srsName=..");
1401 if (id) size += strlen(id) + strlen(prefix) + sizeof(" id=..");
1402
1403 for (i=0; i<col->ngeoms; i++)
1404 {
1405 subgeom = col->geoms[i];
1406 if (subgeom->type == POINTTYPE)
1407 {
1408 size += ( sizeof("<pointMember>/") + prefixlen ) * 2;
1409 size += asgml3_point_size((LWPOINT*)subgeom, 0, precision, opts, prefix, id);
1410 }
1411 else if (subgeom->type == LINETYPE)
1412 {
1413 size += ( sizeof("<curveMember>/") + prefixlen ) * 2;
1414 size += asgml3_line_size((LWLINE*)subgeom, 0, precision, opts, prefix, id);
1415 }
1416 else if (subgeom->type == POLYGONTYPE)
1417 {
1418 size += ( sizeof("<surfaceMember>/") + prefixlen ) * 2;
1419 size += asgml3_poly_size((LWPOLY*)subgeom, 0, precision, opts, prefix, id);
1420 }
1421 }
1422
1423 return size;
1424}
1425
1426/*
1427 * Don't call this with single-geoms inspected!
1428 */
1429static size_t
1430asgml3_multi_buf(const LWCOLLECTION *col, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
1431{
1432 int type = col->type;
1433 char *ptr, *gmltype;
1434 uint32_t i;
1435 LWGEOM *subgeom;
1436
1437 ptr = output;
1438 gmltype="";
1439
1440 if (type == MULTIPOINTTYPE) gmltype = "MultiPoint";
1441 else if (type == MULTILINETYPE) gmltype = "MultiCurve";
1442 else if (type == MULTIPOLYGONTYPE) gmltype = "MultiSurface";
1443
1444 /* Open outmost tag */
1445 ptr += sprintf(ptr, "<%s%s", prefix, gmltype);
1446 if (srs) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
1447 if (id) ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id);
1448
1449 if (!col->ngeoms)
1450 {
1451 ptr += sprintf(ptr, "/>");
1452 return (ptr-output);
1453 }
1454 ptr += sprintf(ptr, ">");
1455
1456 for (i=0; i<col->ngeoms; i++)
1457 {
1458 subgeom = col->geoms[i];
1459 if (subgeom->type == POINTTYPE)
1460 {
1461 ptr += sprintf(ptr, "<%spointMember>", prefix);
1462 ptr += asgml3_point_buf((LWPOINT*)subgeom, 0, ptr, precision, opts, prefix, id);
1463 ptr += sprintf(ptr, "</%spointMember>", prefix);
1464 }
1465 else if (subgeom->type == LINETYPE)
1466 {
1467 ptr += sprintf(ptr, "<%scurveMember>", prefix);
1468 ptr += asgml3_line_buf((LWLINE*)subgeom, 0, ptr, precision, opts, prefix, id);
1469 ptr += sprintf(ptr, "</%scurveMember>", prefix);
1470 }
1471 else if (subgeom->type == POLYGONTYPE)
1472 {
1473 ptr += sprintf(ptr, "<%ssurfaceMember>", prefix);
1474 ptr += asgml3_poly_buf((LWPOLY*)subgeom, 0, ptr, precision, opts, 0, prefix, id);
1475 ptr += sprintf(ptr, "</%ssurfaceMember>", prefix);
1476 }
1477 }
1478
1479 /* Close outmost tag */
1480 ptr += sprintf(ptr, "</%s%s>", prefix, gmltype);
1481
1482 return (ptr-output);
1483}
1484
1485/*
1486 * Don't call this with single-geoms inspected!
1487 */
1488static char *
1489asgml3_multi(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id)
1490{
1491 char *gml;
1492 size_t size;
1493
1494 size = asgml3_multi_size(col, srs, precision, opts, prefix, id);
1495 gml = lwalloc(size);
1496 asgml3_multi_buf(col, srs, gml, precision, opts, prefix, id);
1497 return gml;
1498}
1499
1500
1501static size_t
1502asgml3_psurface_size(const LWPSURFACE *psur, const char *srs, int precision, int opts, const char *prefix, const char *id)
1503{
1504 uint32_t i;
1505 size_t size;
1506 size_t prefixlen = strlen(prefix);
1507
1508 size = (sizeof("<PolyhedralSurface><polygonPatches>/") + prefixlen*2) * 2;
1509 if (srs) size += strlen(srs) + sizeof(" srsName=..");
1510 if (id) size += strlen(id) + strlen(prefix) + sizeof(" id=..");
1511
1512 for (i=0; i<psur->ngeoms; i++)
1513 {
1514 size += asgml3_poly_size(psur->geoms[i], 0, precision, opts, prefix, id);
1515 }
1516
1517 return size;
1518}
1519
1520
1521/*
1522 * Don't call this with single-geoms inspected!
1523 */
1524static size_t
1525asgml3_psurface_buf(const LWPSURFACE *psur, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
1526{
1527 char *ptr;
1528 uint32_t i;
1529
1530 ptr = output;
1531
1532 /* Open outmost tag */
1533 ptr += sprintf(ptr, "<%sPolyhedralSurface", prefix);
1534 if (srs) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
1535 if (id) ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id);
1536 ptr += sprintf(ptr, "><%spolygonPatches>", prefix);
1537
1538 for (i=0; i<psur->ngeoms; i++)
1539 {
1540 ptr += asgml3_poly_buf(psur->geoms[i], 0, ptr, precision, opts, 1, prefix, id);
1541 }
1542
1543 /* Close outmost tag */
1544 ptr += sprintf(ptr, "</%spolygonPatches></%sPolyhedralSurface>",
1545 prefix, prefix);
1546
1547 return (ptr-output);
1548}
1549
1550/*
1551 * Don't call this with single-geoms inspected!
1552 */
1553static char *
1554asgml3_psurface(const LWPSURFACE *psur, const char *srs, int precision, int opts, const char *prefix, const char *id)
1555{
1556 char *gml;
1557 size_t size;
1558
1559 size = asgml3_psurface_size(psur, srs, precision, opts, prefix, id);
1560 gml = lwalloc(size);
1561 asgml3_psurface_buf(psur, srs, gml, precision, opts, prefix, id);
1562 return gml;
1563}
1564
1565
1566static size_t
1567asgml3_tin_size(const LWTIN *tin, const char *srs, int precision, int opts, const char *prefix, const char *id)
1568{
1569 uint32_t i;
1570 size_t size;
1571 size_t prefixlen = strlen(prefix);
1572
1573 size = (sizeof("<Tin><trianglePatches>/") + prefixlen*2) * 2;
1574 if (srs) size += strlen(srs) + sizeof(" srsName=..");
1575 if (id) size += strlen(id) + strlen(prefix) + sizeof(" id=..");
1576
1577 for (i=0; i<tin->ngeoms; i++)
1578 {
1579 size += asgml3_triangle_size(tin->geoms[i], 0, precision, opts, prefix, id);
1580 }
1581
1582 return size;
1583}
1584
1585
1586/*
1587 * Don't call this with single-geoms inspected!
1588 */
1589static size_t
1590asgml3_tin_buf(const LWTIN *tin, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
1591{
1592 char *ptr;
1593 uint32_t i;
1594
1595 ptr = output;
1596
1597 /* Open outmost tag */
1598 ptr += sprintf(ptr, "<%sTin", prefix);
1599 if (srs) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
1600 if (id) ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id);
1601 else ptr += sprintf(ptr, "><%strianglePatches>", prefix);
1602
1603 for (i=0; i<tin->ngeoms; i++)
1604 {
1605 ptr += asgml3_triangle_buf(tin->geoms[i], 0, ptr, precision,
1606 opts, prefix, id);
1607 }
1608
1609 /* Close outmost tag */
1610 ptr += sprintf(ptr, "</%strianglePatches></%sTin>", prefix, prefix);
1611
1612 return (ptr-output);
1613}
1614
1615/*
1616 * Don't call this with single-geoms inspected!
1617 */
1618static char *
1619asgml3_tin(const LWTIN *tin, const char *srs, int precision, int opts, const char *prefix, const char *id)
1620{
1621 char *gml;
1622 size_t size;
1623
1624 size = asgml3_tin_size(tin, srs, precision, opts, prefix, id);
1625 gml = lwalloc(size);
1626 asgml3_tin_buf(tin, srs, gml, precision, opts, prefix, id);
1627 return gml;
1628}
1629
1630static size_t
1631asgml3_collection_size(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id)
1632{
1633 uint32_t i;
1634 size_t size;
1635 size_t prefixlen = strlen(prefix);
1636 LWGEOM *subgeom;
1637
1638 size = sizeof("<MultiGeometry></MultiGeometry>") + prefixlen*2;
1639
1640 if (srs) size += strlen(srs) + sizeof(" srsName=..");
1641 if (id) size += strlen(id) + strlen(prefix) + sizeof(" id=..");
1642
1643 for (i=0; i<col->ngeoms; i++)
1644 {
1645 subgeom = col->geoms[i];
1646 size += ( sizeof("<geometryMember>/") + prefixlen ) * 2;
1647 if ( subgeom->type == POINTTYPE )
1648 {
1649 size += asgml3_point_size((LWPOINT*)subgeom, 0, precision, opts, prefix, id);
1650 }
1651 else if ( subgeom->type == LINETYPE )
1652 {
1653 size += asgml3_line_size((LWLINE*)subgeom, 0, precision, opts, prefix, id);
1654 }
1655 else if ( subgeom->type == POLYGONTYPE )
1656 {
1657 size += asgml3_poly_size((LWPOLY*)subgeom, 0, precision, opts, prefix, id);
1658 }
1659 else if ( lwgeom_is_collection(subgeom) )
1660 {
1661 size += asgml3_multi_size((LWCOLLECTION*)subgeom, 0, precision, opts, prefix, id);
1662 }
1663 else
1664 lwerror("asgml3_collection_size: unknown geometry type");
1665 }
1666
1667 return size;
1668}
1669
1670static size_t
1671asgml3_collection_buf(const LWCOLLECTION *col, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
1672{
1673 char *ptr;
1674 uint32_t i;
1675 LWGEOM *subgeom;
1676
1677 ptr = output;
1678
1679 /* Open outmost tag */
1680 ptr += sprintf(ptr, "<%sMultiGeometry", prefix);
1681 if (srs) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
1682 if (id) ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id);
1683
1684 if (!col->ngeoms)
1685 {
1686 ptr += sprintf(ptr, "/>");
1687 return (ptr-output);
1688 }
1689 ptr += sprintf(ptr, ">");
1690
1691 for (i=0; i<col->ngeoms; i++)
1692 {
1693 subgeom = col->geoms[i];
1694 ptr += sprintf(ptr, "<%sgeometryMember>", prefix);
1695 if ( subgeom->type == POINTTYPE )
1696 {
1697 ptr += asgml3_point_buf((LWPOINT*)subgeom, 0, ptr, precision, opts, prefix, id);
1698 }
1699 else if ( subgeom->type == LINETYPE )
1700 {
1701 ptr += asgml3_line_buf((LWLINE*)subgeom, 0, ptr, precision, opts, prefix, id);
1702 }
1703 else if ( subgeom->type == POLYGONTYPE )
1704 {
1705 ptr += asgml3_poly_buf((LWPOLY*)subgeom, 0, ptr, precision, opts, 0, prefix, id);
1706 }
1707 else if ( lwgeom_is_collection(subgeom) )
1708 {
1709 if ( subgeom->type == COLLECTIONTYPE )
1710 ptr += asgml3_collection_buf((LWCOLLECTION*)subgeom, 0, ptr, precision, opts, prefix, id);
1711 else
1712 ptr += asgml3_multi_buf((LWCOLLECTION*)subgeom, 0, ptr, precision, opts, prefix, id);
1713 }
1714 else
1715 lwerror("asgml3_collection_buf: unknown geometry type");
1716
1717 ptr += sprintf(ptr, "</%sgeometryMember>", prefix);
1718 }
1719
1720 /* Close outmost tag */
1721 ptr += sprintf(ptr, "</%sMultiGeometry>", prefix);
1722
1723 return (ptr-output);
1724}
1725
1726/*
1727 * Don't call this with single-geoms inspected!
1728 */
1729static char *
1730asgml3_collection(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id)
1731{
1732 char *gml;
1733 size_t size;
1734
1735 size = asgml3_collection_size(col, srs, precision, opts, prefix, id);
1736 gml = lwalloc(size);
1737 asgml3_collection_buf(col, srs, gml, precision, opts, prefix, id);
1738 return gml;
1739}
1740
1741static size_t asgml3_multicurve_size( const LWMCURVE* cur, const char *srs, int precision, int opts, const char *prefix, const char *id )
1742{
1743 size_t prefixlen = strlen(prefix);
1744 size_t size = sizeof( "<MultiCurve></MultiCurve>" ) + 2 * prefixlen;
1745 if (srs) size += strlen(srs) + sizeof(" srsName=..");
1746 if (id) size += strlen(id) + strlen(prefix) + sizeof(" id=..");
1747 LWGEOM* subgeom;
1748 uint32_t i;
1749
1750 for( i = 0; i < cur->ngeoms; ++i )
1751 {
1752 size += sizeof( "<curveMember></curveMember>" ) + 2 * prefixlen;
1753 subgeom = cur->geoms[i];
1754 if ( subgeom->type == LINETYPE )
1755 {
1756 size += asgml3_line_size( (LWLINE*)subgeom, srs, precision, opts, prefix, id );
1757 }
1758 else if( subgeom->type == CIRCSTRINGTYPE )
1759 {
1760 size += asgml3_circstring_size( (LWCIRCSTRING*)subgeom, srs, precision, opts, prefix, id );
1761 }
1762 else if( subgeom->type == COMPOUNDTYPE )
1763 {
1764 size += asgml3_compound_size( (LWCOMPOUND*)subgeom, srs, precision, opts, prefix, id );
1765 }
1766 }
1767 return size;
1768}
1769
1770static size_t asgml3_multicurve_buf( const LWMCURVE* cur, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id )
1771{
1772 char* ptr = output;
1773 LWGEOM* subgeom;
1774 uint32_t i;
1775
1776 ptr += sprintf(ptr, "<%sMultiCurve", prefix );
1777 if (srs)
1778 {
1779 ptr += sprintf(ptr, " srsName=\"%s\"", srs);
1780 }
1781 if (id)
1782 {
1783 ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id );
1784 }
1785 ptr += sprintf( ptr, ">");
1786
1787 for( i = 0; i < cur->ngeoms; ++i )
1788 {
1789 ptr += sprintf(ptr, "<%scurveMember>", prefix );
1790 subgeom = cur->geoms[i];
1791 if ( subgeom->type == LINETYPE )
1792 {
1793 ptr += asgml3_line_buf( (LWLINE*)subgeom, srs, ptr, precision, opts, prefix, id );
1794 }
1795 else if( subgeom->type == CIRCSTRINGTYPE )
1796 {
1797 ptr += asgml3_circstring_buf( (LWCIRCSTRING*)subgeom, srs, ptr, precision, opts, prefix, id );
1798 }
1799 else if( subgeom->type == COMPOUNDTYPE )
1800 {
1801 ptr += asgml3_compound_buf( (LWCOMPOUND*)subgeom, srs, ptr, precision, opts, prefix, id );
1802 }
1803 ptr += sprintf(ptr, "</%scurveMember>", prefix );
1804 }
1805 ptr += sprintf(ptr, "</%sMultiCurve>", prefix );
1806 return (ptr - output);
1807}
1808
1809static char *asgml3_multicurve( const LWMCURVE* cur, const char *srs, int precision, int opts, const char *prefix, const char *id )
1810{
1811 char* gml;
1812 size_t size =asgml3_multicurve_size( cur, srs, precision, opts, prefix, id );
1813 gml = lwalloc( size );
1814 asgml3_multicurve_buf( cur, srs, gml, precision, opts, prefix, id );
1815 return gml;
1816}
1817
1818static size_t asgml3_multisurface_size(const LWMSURFACE *sur, const char *srs, int precision, int opts, const char *prefix, const char *id)
1819{
1820 size_t prefixlen = strlen(prefix);
1821 size_t size = sizeof( "<MultiSurface></MultiSurface>" ) + 2 * prefixlen;
1822 if (srs) size += strlen(srs) + sizeof(" srsName=..");
1823 if (id) size += strlen(id) + strlen(prefix) + sizeof(" id=..");
1824 LWGEOM* subgeom;
1825 uint32_t i;
1826
1827 for( i = 0; i < sur->ngeoms; ++i )
1828 {
1829 subgeom = sur->geoms[i];
1830 if( subgeom->type == POLYGONTYPE )
1831 {
1832 size += asgml3_poly_size( (LWPOLY*)sur->geoms[i], srs, precision, opts, prefix, id );
1833 }
1834 else if( subgeom->type == CURVEPOLYTYPE )
1835 {
1836 size += asgml3_curvepoly_size( (LWCURVEPOLY*)sur->geoms[i], srs, precision, opts, prefix, id );
1837 }
1838 }
1839 return size;
1840}
1841
1842static size_t asgml3_multisurface_buf(const LWMSURFACE *sur, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
1843{
1844 char* ptr = output;
1845 uint32_t i;
1846 LWGEOM* subgeom;
1847
1848 ptr += sprintf( ptr, "<%sMultiSurface", prefix );
1849 if (srs)
1850 {
1851 ptr += sprintf(ptr, " srsName=\"%s\"", srs);
1852 }
1853 if (id)
1854 {
1855 ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id );
1856 }
1857 ptr += sprintf( ptr, ">" );
1858
1859 for( i = 0; i < sur->ngeoms; ++i )
1860 {
1861 subgeom = sur->geoms[i];
1862 if( subgeom->type == POLYGONTYPE )
1863 {
1864 ptr += asgml3_poly_buf( (LWPOLY*)sur->geoms[i], srs, ptr, precision, opts, 0, prefix, id );
1865 }
1866 else if( subgeom->type == CURVEPOLYTYPE )
1867 {
1868 ptr += asgml3_curvepoly_buf( (LWCURVEPOLY*)sur->geoms[i], srs, ptr, precision, opts, prefix, id );
1869 }
1870 }
1871 ptr += sprintf( ptr, "</%sMultiSurface>", prefix );
1872 return ptr - output;
1873}
1874
1875static char *asgml3_multisurface(const LWMSURFACE *sur, const char *srs, int precision, int opts, const char *prefix, const char *id)
1876{
1877 char* gml;
1878 size_t size = asgml3_multisurface_size( sur, srs, precision, opts, prefix, id );
1879 gml = lwalloc( size );
1880 asgml3_multisurface_buf( sur, srs, gml, precision, opts, prefix, id );
1881 return gml;
1882}
1883
1884
1885/* In GML3, inside <posList> or <pos>, coordinates are separated by a space separator
1886 * In GML3 also, lat/lon are reversed for geocentric data
1887 */
1888static size_t
1889pointArray_toGML3(POINTARRAY *pa, char *output, int precision, int opts)
1890{
1891 uint32_t i;
1892 char *ptr;
1893 char x[OUT_DOUBLE_BUFFER_SIZE];
1894 char y[OUT_DOUBLE_BUFFER_SIZE];
1895 char z[OUT_DOUBLE_BUFFER_SIZE];
1896
1897 ptr = output;
1898
1899 if ( ! FLAGS_GET_Z(pa->flags) )
1900 {
1901 for (i=0; i<pa->npoints; i++)
1902 {
1903 const POINT2D *pt;
1904 pt = getPoint2d_cp(pa, i);
1909
1910 if ( i ) ptr += sprintf(ptr, " ");
1911 if (IS_DEGREE(opts))
1912 ptr += sprintf(ptr, "%s %s", y, x);
1913 else
1914 ptr += sprintf(ptr, "%s %s", x, y);
1915 }
1916 }
1917 else
1918 {
1919 for (i=0; i<pa->npoints; i++)
1920 {
1921 const POINT3D *pt = getPoint3d_cp(pa, i);
1922
1929
1930 if ( i ) ptr += sprintf(ptr, " ");
1931 if (IS_DEGREE(opts))
1932 ptr += sprintf(ptr, "%s %s %s", y, x, z);
1933 else
1934 ptr += sprintf(ptr, "%s %s %s", x, y, z);
1935 }
1936 }
1937
1938 return ptr-output;
1939}
1940
1941
1942
1943/*
1944 * Returns maximum size of rendered pointarray in bytes.
1945 */
1946static size_t
1948{
1949 if (FLAGS_NDIMS(pa->flags) == 2)
1950 return (OUT_MAX_DIGS_DOUBLE + precision + sizeof(", ")) * 2 * pa->npoints;
1951
1952 return (OUT_MAX_DIGS_DOUBLE + precision + sizeof(", ")) * 3 * pa->npoints;
1953}
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:122
#define COMPOUNDTYPE
Definition liblwgeom.h:124
#define IS_DIMS(x)
Definition liblwgeom.h:1657
#define CURVEPOLYTYPE
Definition liblwgeom.h:125
#define MULTILINETYPE
Definition liblwgeom.h:120
#define MULTISURFACETYPE
Definition liblwgeom.h:127
#define LINETYPE
Definition liblwgeom.h:117
#define LW_GML_SHORTLINE
For GML3, use <LineString> rather than <Curve> for lines.
Definition liblwgeom.h:1652
#define MULTIPOINTTYPE
Definition liblwgeom.h:119
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:116
#define FLAGS_GET_Z(flags)
Definition liblwgeom.h:179
void * lwalloc(size_t size)
Definition lwutil.c:227
#define TINTYPE
Definition liblwgeom.h:130
#define MULTIPOLYGONTYPE
Definition liblwgeom.h:121
#define FLAGS_NDIMS(flags)
Definition liblwgeom.h:193
int lwgeom_is_collection(const LWGEOM *lwgeom)
Determine whether a LWGEOM can contain sub-geometries or not.
Definition lwgeom.c:1079
#define POLYGONTYPE
Definition liblwgeom.h:118
#define POLYHEDRALSURFACETYPE
Definition liblwgeom.h:128
#define CIRCSTRINGTYPE
Definition liblwgeom.h:123
void ptarray_free(POINTARRAY *pa)
Definition ptarray.c:327
#define IS_DEGREE(x)
Definition liblwgeom.h:1658
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:126
#define TRIANGLETYPE
Definition liblwgeom.h:129
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:107
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:725
int lwline_is_empty(const LWLINE *line)
#define OUT_MAX_DIGS_DOUBLE
#define OUT_DOUBLE_BUFFER_SIZE
int lwpoint_is_empty(const LWPOINT *point)
int lwpoly_is_empty(const LWPOLY *poly)
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 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 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:193
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 char * asgml2_collection(const LWCOLLECTION *col, const char *srs, int precision, const char *prefix)
Definition lwout_gml.c:648
static size_t asgml3_multisurface_size(const LWMSURFACE *sur, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1818
static size_t asgml2_multi_size(const LWCOLLECTION *col, const char *srs, int precision, const char *prefix)
Definition lwout_gml.c:429
static size_t asgml2_point_size(const LWPOINT *point, const char *srs, int precision, const char *prefix)
Definition lwout_gml.c:271
static char * asgml3_line(const LWLINE *line, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:916
static size_t pointArray_toGML3(POINTARRAY *pa, char *buf, int precision, int opts)
Definition lwout_gml.c:1889
static char * asgml2_line(const LWLINE *line, const char *srs, int precision, const char *prefix)
Definition lwout_gml.c:350
char * lwgeom_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
VERSION GML 2 takes a GEOMETRY and returns a GML2 representation.
Definition lwout_gml.c:231
static char * asgml3_collection(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1730
static char * asgml3_tin(const LWTIN *tin, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1619
static char * asgml3_multisurface(const LWMSURFACE *sur, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1875
static size_t asgml3_curvepoly_buf(const LWCURVEPOLY *poly, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1238
static size_t asgml3_poly_size(const LWPOLY *poly, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:994
static char * asgml3_multicurve(const LWMCURVE *cur, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1809
static char * asgml3_curvepoly(const LWCURVEPOLY *poly, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1317
static size_t asgml3_psurface_buf(const LWPSURFACE *psur, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1525
static char * asgml3_circstring(const LWCIRCSTRING *circ, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:981
static char * asgml2_point(const LWPOINT *point, const char *srs, int precision, const char *prefix)
Definition lwout_gml.c:303
static char * asgml3_triangle(const LWTRIANGLE *triangle, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1372
static size_t asgml3_point_size(const LWPOINT *point, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:774
static char * asgml3_compound(const LWCOMPOUND *col, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1180
static size_t asgml3_line_size(const LWLINE *line, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:827
static size_t asgml2_collection_size(const LWCOLLECTION *col, const char *srs, int precision, const char *prefix)
Definition lwout_gml.c:546
static size_t asgml3_circstring_size(const LWCIRCSTRING *circ, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:929
static size_t asgml3_collection_size(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1631
static size_t asgml3_multi_buf(const LWCOLLECTION *col, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1430
char * lwgeom_extent_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix)
Definition lwout_gml.c:198
static size_t asgml3_circstring_buf(const LWCIRCSTRING *circ, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:942
static size_t pointArray_GMLsize(POINTARRAY *pa, int precision)
Definition lwout_gml.c:1947
static size_t asgml3_multicurve_buf(const LWMCURVE *cur, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1770
static char * gbox_to_gml2(const GBOX *bbox, const char *srs, int precision, const char *prefix)
Definition lwout_gml.c:75
static char * asgml3_multi(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1489
static size_t asgml2_poly_buf(const LWPOLY *poly, const char *srs, char *output, int precision, const char *prefix)
Definition lwout_gml.c:382
static size_t asgml3_multisurface_buf(const LWMSURFACE *sur, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1842
static size_t asgml3_compound_buf(const LWCOMPOUND *col, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1118
static char * gbox_to_gml3(const GBOX *bbox, const char *srs, int precision, int opts, const char *prefix)
Definition lwout_gml.c:130
static char * asgml3_psurface(const LWPSURFACE *psur, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1554
static size_t asgml3_triangle_size(const LWTRIANGLE *triangle, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1330
static size_t asgml3_multicurve_size(const LWMCURVE *cur, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1741
static char * asgml3_point(const LWPOINT *point, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:814
static size_t asgml3_compound_size(const LWCOMPOUND *col, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1076
static size_t asgml3_psurface_size(const LWPSURFACE *psur, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1502
static size_t asgml2_multi_buf(const LWCOLLECTION *col, const char *srs, char *output, int precision, const char *prefix)
Definition lwout_gml.c:470
static size_t asgml2_line_size(const LWLINE *line, const char *srs, int precision, const char *prefix)
Definition lwout_gml.c:315
static size_t asgml3_collection_buf(const LWCOLLECTION *col, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1671
static size_t asgml3_tin_buf(const LWTIN *tin, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1590
static size_t asgml2_point_buf(const LWPOINT *point, const char *srs, char *output, int precision, const char *prefix)
Definition lwout_gml.c:283
static size_t asgml3_line_buf(const LWLINE *line, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:854
static char * asgml2_multi(const LWCOLLECTION *col, const char *srs, int precision, const char *prefix)
Definition lwout_gml.c:529
static size_t asgml3_point_buf(const LWPOINT *point, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:788
static size_t asgml3_poly_buf(const LWPOLY *poly, const char *srs, char *output, int precision, int opts, int is_patch, const char *prefix, const char *id)
Definition lwout_gml.c:1014
static size_t asgml3_triangle_buf(const LWTRIANGLE *triangle, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1347
static char * asgml2_poly(const LWPOLY *poly, const char *srs, int precision, const char *prefix)
Definition lwout_gml.c:412
static char * asgml3_poly(const LWPOLY *poly, const char *srs, int precision, int opts, int is_patch, const char *prefix, const char *id)
Definition lwout_gml.c:1064
static size_t asgml3_multi_size(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1390
char * lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:716
static size_t asgml2_line_buf(const LWLINE *line, const char *srs, char *output, int precision, const char *prefix)
Definition lwout_gml.c:327
static size_t asgml2_poly_size(const LWPOLY *poly, const char *srs, int precision, const char *prefix)
Definition lwout_gml.c:362
static size_t asgml3_curvepoly_size(const LWCURVEPOLY *poly, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1191
char * lwgeom_extent_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix)
Definition lwout_gml.c:213
static size_t asgml2_collection_buf(const LWCOLLECTION *col, const char *srs, char *output, int precision, const char *prefix)
Definition lwout_gml.c:592
static size_t asgml3_tin_size(const LWTIN *tin, const char *srs, int precision, int opts, const char *prefix, const char *id)
Definition lwout_gml.c:1567
static size_t pointArray_toGML2(POINTARRAY *pa, char *buf, int precision)
Definition lwout_gml.c:662
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:339
lwflags_t flags
Definition liblwgeom.h:495
POINTARRAY * points
Definition liblwgeom.h:493
uint32_t ngeoms
Definition liblwgeom.h:566
uint8_t type
Definition liblwgeom.h:564
LWGEOM ** geoms
Definition liblwgeom.h:561
lwflags_t flags
Definition liblwgeom.h:577
uint32_t ngeoms
Definition liblwgeom.h:580
LWGEOM ** geoms
Definition liblwgeom.h:575
LWGEOM ** rings
Definition liblwgeom.h:589
lwflags_t flags
Definition liblwgeom.h:591
uint32_t nrings
Definition liblwgeom.h:594
uint8_t type
Definition liblwgeom.h:448
lwflags_t flags
Definition liblwgeom.h:471
POINTARRAY * points
Definition liblwgeom.h:469
uint32_t ngeoms
Definition liblwgeom.h:622
LWGEOM ** geoms
Definition liblwgeom.h:617
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
LWPOLY ** geoms
Definition liblwgeom.h:631
uint32_t ngeoms
Definition liblwgeom.h:636
uint32_t ngeoms
Definition liblwgeom.h:650
LWTRIANGLE ** geoms
Definition liblwgeom.h:645
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
double x
Definition liblwgeom.h:400
double z
Definition liblwgeom.h:400
double y
Definition liblwgeom.h:400
lwflags_t flags
Definition liblwgeom.h:417
uint32_t npoints
Definition liblwgeom.h:413