PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
lwout_wkt.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 (C) 2009 Paul Ramsey <pramsey@cleverelephant.ca>
22 *
23 **********************************************************************/
24
25
26#include "liblwgeom_internal.h"
27#include "lwgeom_log.h"
28#include "stringbuffer.h"
29
30static void lwgeom_to_wkt_sb(const LWGEOM *geom, stringbuffer_t *sb, int precision, uint8_t variant);
31
32
33/*
34* ISO format uses both Z and M qualifiers.
35* Extended format only uses an M qualifier for 3DM variants, where it is not
36* clear what the third dimension represents.
37* SFSQL format never has more than two dimensions, so no qualifiers.
38*/
39static void dimension_qualifiers_to_wkt_sb(const LWGEOM *geom, stringbuffer_t *sb, uint8_t variant)
40{
41
42 /* Extended WKT: POINTM(0 0 0) */
43#if 0
44 if ( (variant & WKT_EXTENDED) && ! (variant & WKT_IS_CHILD) && FLAGS_GET_M(geom->flags) && (!FLAGS_GET_Z(geom->flags)) )
45#else
46 if ( (variant & WKT_EXTENDED) && FLAGS_GET_M(geom->flags) && (!FLAGS_GET_Z(geom->flags)) )
47#endif
48 {
49 stringbuffer_append(sb, "M"); /* "M" */
50 return;
51 }
52
53 /* ISO WKT: POINT ZM (0 0 0 0) */
54 if ( (variant & WKT_ISO) && (FLAGS_NDIMS(geom->flags) > 2) )
55 {
56 stringbuffer_append(sb, " ");
57 if ( FLAGS_GET_Z(geom->flags) )
58 stringbuffer_append(sb, "Z");
59 if ( FLAGS_GET_M(geom->flags) )
60 stringbuffer_append(sb, "M");
61 stringbuffer_append(sb, " ");
62 }
63}
64
65/*
66* Write an empty token out, padding with a space if
67* necessary.
68*/
70{
71 if ( ! strchr(" ,(", stringbuffer_lastchar(sb)) ) /* "EMPTY" */
72 {
73 stringbuffer_append(sb, " ");
74 }
75 stringbuffer_append(sb, "EMPTY");
76}
77
78/*
79* Point array is a list of coordinates. Depending on output mode,
80* we may suppress some dimensions. ISO and Extended formats include
81* all dimensions. Standard OGC output only includes X/Y coordinates.
82*/
83static void ptarray_to_wkt_sb(const POINTARRAY *ptarray, stringbuffer_t *sb, int precision, uint8_t variant)
84{
85 /* OGC only includes X/Y */
86 uint32_t dimensions = 2;
87 uint32_t i, j;
88 static size_t buffer_size = 128;
89 char coord[buffer_size];
90
91 /* ISO and extended formats include all dimensions */
92 if ( variant & ( WKT_ISO | WKT_EXTENDED ) )
93 dimensions = FLAGS_NDIMS(ptarray->flags);
94
95 /* Opening paren? */
96 if ( ! (variant & WKT_NO_PARENS) )
97 stringbuffer_append(sb, "(");
98
99 /* Digits and commas */
100 for (i = 0; i < ptarray->npoints; i++)
101 {
102 double *dbl_ptr = (double*)getPoint_internal(ptarray, i);
103
104 /* Commas before ever coord but the first */
105 if ( i > 0 )
106 stringbuffer_append(sb, ",");
107
108 for (j = 0; j < dimensions; j++)
109 {
110 /* Spaces before every ordinate but the first */
111 if ( j > 0 )
112 stringbuffer_append(sb, " ");
113 lwprint_double(dbl_ptr[j],
114 precision,
115 coord,
116 buffer_size);
117 stringbuffer_append(sb, coord);
118 }
119 }
120
121 /* Closing paren? */
122 if ( ! (variant & WKT_NO_PARENS) )
123 stringbuffer_append(sb, ")");
124}
125
126/*
127* A four-dimensional point will have different outputs depending on variant.
128* ISO: POINT ZM (0 0 0 0)
129* Extended: POINT(0 0 0 0)
130* OGC: POINT(0 0)
131* A three-dimensional m-point will have different outputs too.
132* ISO: POINT M (0 0 0)
133* Extended: POINTM(0 0 0)
134* OGC: POINT(0 0)
135*/
136static void lwpoint_to_wkt_sb(const LWPOINT *pt, stringbuffer_t *sb, int precision, uint8_t variant)
137{
138 if ( ! (variant & WKT_NO_TYPE) )
139 {
140 stringbuffer_append(sb, "POINT"); /* "POINT" */
142 }
143
144 if ( lwpoint_is_empty(pt) )
145 {
146 empty_to_wkt_sb(sb);
147 return;
148 }
149
151}
152
153/*
154* LINESTRING(0 0 0, 1 1 1)
155*/
156static void lwline_to_wkt_sb(const LWLINE *line, stringbuffer_t *sb, int precision, uint8_t variant)
157{
158 if ( ! (variant & WKT_NO_TYPE) )
159 {
160 stringbuffer_append(sb, "LINESTRING"); /* "LINESTRING" */
162 }
163 if ( lwline_is_empty(line) )
164 {
165 empty_to_wkt_sb(sb);
166 return;
167 }
168
170}
171
172/*
173* POLYGON(0 0 1, 1 0 1, 1 1 1, 0 1 1, 0 0 1)
174*/
175static void lwpoly_to_wkt_sb(const LWPOLY *poly, stringbuffer_t *sb, int precision, uint8_t variant)
176{
177 uint32_t i = 0;
178 if ( ! (variant & WKT_NO_TYPE) )
179 {
180 stringbuffer_append(sb, "POLYGON"); /* "POLYGON" */
182 }
183 if ( lwpoly_is_empty(poly) )
184 {
185 empty_to_wkt_sb(sb);
186 return;
187 }
188
189 stringbuffer_append(sb, "(");
190 for ( i = 0; i < poly->nrings; i++ )
191 {
192 if ( i > 0 )
193 stringbuffer_append(sb, ",");
195 }
196 stringbuffer_append(sb, ")");
197}
198
199/*
200* CIRCULARSTRING
201*/
202static void lwcircstring_to_wkt_sb(const LWCIRCSTRING *circ, stringbuffer_t *sb, int precision, uint8_t variant)
203{
204 if ( ! (variant & WKT_NO_TYPE) )
205 {
206 stringbuffer_append(sb, "CIRCULARSTRING"); /* "CIRCULARSTRING" */
208 }
209 if ( lwcircstring_is_empty(circ) )
210 {
211 empty_to_wkt_sb(sb);
212 return;
213 }
215}
216
217
218/*
219* Multi-points do not wrap their sub-members in parens, unlike other multi-geometries.
220* MULTPOINT(0 0, 1 1) instead of MULTIPOINT((0 0),(1 1))
221*/
222static void lwmpoint_to_wkt_sb(const LWMPOINT *mpoint, stringbuffer_t *sb, int precision, uint8_t variant)
223{
224 uint32_t i = 0;
225 if ( ! (variant & WKT_NO_TYPE) )
226 {
227 stringbuffer_append(sb, "MULTIPOINT"); /* "MULTIPOINT" */
229 }
230 if ( mpoint->ngeoms < 1 )
231 {
232 empty_to_wkt_sb(sb);
233 return;
234 }
235 stringbuffer_append(sb, "(");
236 variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are childre */
237 for ( i = 0; i < mpoint->ngeoms; i++ )
238 {
239 if ( i > 0 )
240 stringbuffer_append(sb, ",");
241 /* We don't want type strings or parens on our subgeoms */
243 }
244 stringbuffer_append(sb, ")");
245}
246
247/*
248* MULTILINESTRING
249*/
250static void lwmline_to_wkt_sb(const LWMLINE *mline, stringbuffer_t *sb, int precision, uint8_t variant)
251{
252 uint32_t i = 0;
253
254 if ( ! (variant & WKT_NO_TYPE) )
255 {
256 stringbuffer_append(sb, "MULTILINESTRING"); /* "MULTILINESTRING" */
258 }
259 if ( mline->ngeoms < 1 )
260 {
261 empty_to_wkt_sb(sb);
262 return;
263 }
264
265 stringbuffer_append(sb, "(");
266 variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are childre */
267 for ( i = 0; i < mline->ngeoms; i++ )
268 {
269 if ( i > 0 )
270 stringbuffer_append(sb, ",");
271 /* We don't want type strings on our subgeoms */
273 }
274 stringbuffer_append(sb, ")");
275}
276
277/*
278* MULTIPOLYGON
279*/
280static void lwmpoly_to_wkt_sb(const LWMPOLY *mpoly, stringbuffer_t *sb, int precision, uint8_t variant)
281{
282 uint32_t i = 0;
283
284 if ( ! (variant & WKT_NO_TYPE) )
285 {
286 stringbuffer_append(sb, "MULTIPOLYGON"); /* "MULTIPOLYGON" */
288 }
289 if ( mpoly->ngeoms < 1 )
290 {
291 empty_to_wkt_sb(sb);
292 return;
293 }
294
295 stringbuffer_append(sb, "(");
296 variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are childre */
297 for ( i = 0; i < mpoly->ngeoms; i++ )
298 {
299 if ( i > 0 )
300 stringbuffer_append(sb, ",");
301 /* We don't want type strings on our subgeoms */
303 }
304 stringbuffer_append(sb, ")");
305}
306
307/*
308* Compound curves provide type information for their curved sub-geometries
309* but not their linestring sub-geometries.
310* COMPOUNDCURVE((0 0, 1 1), CURVESTRING(1 1, 2 2, 3 3))
311*/
312static void lwcompound_to_wkt_sb(const LWCOMPOUND *comp, stringbuffer_t *sb, int precision, uint8_t variant)
313{
314 uint32_t i = 0;
315
316 if ( ! (variant & WKT_NO_TYPE) )
317 {
318 stringbuffer_append(sb, "COMPOUNDCURVE"); /* "COMPOUNDCURVE" */
320 }
321 if ( comp->ngeoms < 1 )
322 {
323 empty_to_wkt_sb(sb);
324 return;
325 }
326
327 stringbuffer_append(sb, "(");
328 variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are childre */
329 for ( i = 0; i < comp->ngeoms; i++ )
330 {
331 int type = comp->geoms[i]->type;
332 if ( i > 0 )
333 stringbuffer_append(sb, ",");
334 /* Linestring subgeoms don't get type identifiers */
335 if ( type == LINETYPE )
336 {
338 }
339 /* But circstring subgeoms *do* get type identifiers */
340 else if ( type == CIRCSTRINGTYPE )
341 {
343 }
344 else
345 {
346 lwerror("lwcompound_to_wkt_sb: Unknown type received %d - %s", type, lwtype_name(type));
347 }
348 }
349 stringbuffer_append(sb, ")");
350}
351
352/*
353* Curve polygons provide type information for their curved rings
354* but not their linestring rings.
355* CURVEPOLYGON((0 0, 1 1, 0 1, 0 0), CURVESTRING(0 0, 1 1, 0 1, 0.5 1, 0 0))
356*/
357static void lwcurvepoly_to_wkt_sb(const LWCURVEPOLY *cpoly, stringbuffer_t *sb, int precision, uint8_t variant)
358{
359 uint32_t i = 0;
360
361 if ( ! (variant & WKT_NO_TYPE) )
362 {
363 stringbuffer_append(sb, "CURVEPOLYGON"); /* "CURVEPOLYGON" */
365 }
366 if ( cpoly->nrings < 1 )
367 {
368 empty_to_wkt_sb(sb);
369 return;
370 }
371 stringbuffer_append(sb, "(");
372 variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are childre */
373 for ( i = 0; i < cpoly->nrings; i++ )
374 {
375 int type = cpoly->rings[i]->type;
376 if ( i > 0 )
377 stringbuffer_append(sb, ",");
378 switch (type)
379 {
380 case LINETYPE:
381 /* Linestring subgeoms don't get type identifiers */
383 break;
384 case CIRCSTRINGTYPE:
385 /* But circstring subgeoms *do* get type identifiers */
387 break;
388 case COMPOUNDTYPE:
389 /* And compoundcurve subgeoms *do* get type identifiers */
391 break;
392 default:
393 lwerror("lwcurvepoly_to_wkt_sb: Unknown type received %d - %s", type, lwtype_name(type));
394 }
395 }
396 stringbuffer_append(sb, ")");
397}
398
399
400/*
401* Multi-curves provide type information for their curved sub-geometries
402* but not their linear sub-geometries.
403* MULTICURVE((0 0, 1 1), CURVESTRING(0 0, 1 1, 2 2))
404*/
405static void lwmcurve_to_wkt_sb(const LWMCURVE *mcurv, stringbuffer_t *sb, int precision, uint8_t variant)
406{
407 uint32_t i = 0;
408
409 if ( ! (variant & WKT_NO_TYPE) )
410 {
411 stringbuffer_append(sb, "MULTICURVE"); /* "MULTICURVE" */
413 }
414 if ( mcurv->ngeoms < 1 )
415 {
416 empty_to_wkt_sb(sb);
417 return;
418 }
419 stringbuffer_append(sb, "(");
420 variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are childre */
421 for ( i = 0; i < mcurv->ngeoms; i++ )
422 {
423 int type = mcurv->geoms[i]->type;
424 if ( i > 0 )
425 stringbuffer_append(sb, ",");
426 switch (type)
427 {
428 case LINETYPE:
429 /* Linestring subgeoms don't get type identifiers */
431 break;
432 case CIRCSTRINGTYPE:
433 /* But circstring subgeoms *do* get type identifiers */
435 break;
436 case COMPOUNDTYPE:
437 /* And compoundcurve subgeoms *do* get type identifiers */
439 break;
440 default:
441 lwerror("lwmcurve_to_wkt_sb: Unknown type received %d - %s", type, lwtype_name(type));
442 }
443 }
444 stringbuffer_append(sb, ")");
445}
446
447
448/*
449* Multi-surfaces provide type information for their curved sub-geometries
450* but not their linear sub-geometries.
451* MULTISURFACE(((0 0, 1 1, 1 0, 0 0)), CURVEPOLYGON(CURVESTRING(0 0, 1 1, 2 2, 0 1, 0 0)))
452*/
453static void lwmsurface_to_wkt_sb(const LWMSURFACE *msurf, stringbuffer_t *sb, int precision, uint8_t variant)
454{
455 uint32_t i = 0;
456
457 if ( ! (variant & WKT_NO_TYPE) )
458 {
459 stringbuffer_append(sb, "MULTISURFACE"); /* "MULTISURFACE" */
461 }
462 if ( msurf->ngeoms < 1 )
463 {
464 empty_to_wkt_sb(sb);
465 return;
466 }
467 stringbuffer_append(sb, "(");
468 variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are childre */
469 for ( i = 0; i < msurf->ngeoms; i++ )
470 {
471 int type = msurf->geoms[i]->type;
472 if ( i > 0 )
473 stringbuffer_append(sb, ",");
474 switch (type)
475 {
476 case POLYGONTYPE:
477 /* Linestring subgeoms don't get type identifiers */
479 break;
480 case CURVEPOLYTYPE:
481 /* But circstring subgeoms *do* get type identifiers */
483 break;
484 default:
485 lwerror("lwmsurface_to_wkt_sb: Unknown type received %d - %s", type, lwtype_name(type));
486 }
487 }
488 stringbuffer_append(sb, ")");
489}
490
491/*
492* Geometry collections provide type information for all their curved sub-geometries
493* but not their linear sub-geometries.
494* GEOMETRYCOLLECTION(POLYGON((0 0, 1 1, 1 0, 0 0)), CURVEPOLYGON(CURVESTRING(0 0, 1 1, 2 2, 0 1, 0 0)))
495*/
496static void lwcollection_to_wkt_sb(const LWCOLLECTION *collection, stringbuffer_t *sb, int precision, uint8_t variant)
497{
498 uint32_t i = 0;
499
500 if ( ! (variant & WKT_NO_TYPE) )
501 {
502 stringbuffer_append(sb, "GEOMETRYCOLLECTION"); /* "GEOMETRYCOLLECTION" */
504 }
505 if ( collection->ngeoms < 1 )
506 {
507 empty_to_wkt_sb(sb);
508 return;
509 }
510 stringbuffer_append(sb, "(");
511 variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are children */
512 for ( i = 0; i < collection->ngeoms; i++ )
513 {
514 if ( i > 0 )
515 stringbuffer_append(sb, ",");
516 lwgeom_to_wkt_sb((LWGEOM*)collection->geoms[i], sb, precision, variant );
517 }
518 stringbuffer_append(sb, ")");
519}
520
521/*
522* TRIANGLE
523*/
524static void lwtriangle_to_wkt_sb(const LWTRIANGLE *tri, stringbuffer_t *sb, int precision, uint8_t variant)
525{
526 if ( ! (variant & WKT_NO_TYPE) )
527 {
528 stringbuffer_append(sb, "TRIANGLE"); /* "TRIANGLE" */
530 }
531 if ( lwtriangle_is_empty(tri) )
532 {
533 empty_to_wkt_sb(sb);
534 return;
535 }
536
537 stringbuffer_append(sb, "("); /* Triangles have extraneous brackets */
539 stringbuffer_append(sb, ")");
540}
541
542/*
543* TIN
544*/
545static void lwtin_to_wkt_sb(const LWTIN *tin, stringbuffer_t *sb, int precision, uint8_t variant)
546{
547 uint32_t i = 0;
548
549 if ( ! (variant & WKT_NO_TYPE) )
550 {
551 stringbuffer_append(sb, "TIN"); /* "TIN" */
553 }
554 if ( tin->ngeoms < 1 )
555 {
556 empty_to_wkt_sb(sb);
557 return;
558 }
559
560 stringbuffer_append(sb, "(");
561 for ( i = 0; i < tin->ngeoms; i++ )
562 {
563 if ( i > 0 )
564 stringbuffer_append(sb, ",");
565 /* We don't want type strings on our subgeoms */
567 }
568 stringbuffer_append(sb, ")");
569}
570
571/*
572* POLYHEDRALSURFACE
573*/
574static void lwpsurface_to_wkt_sb(const LWPSURFACE *psurf, stringbuffer_t *sb, int precision, uint8_t variant)
575{
576 uint32_t i = 0;
577
578 if ( ! (variant & WKT_NO_TYPE) )
579 {
580 stringbuffer_append(sb, "POLYHEDRALSURFACE"); /* "POLYHEDRALSURFACE" */
582 }
583 if ( psurf->ngeoms < 1 )
584 {
585 empty_to_wkt_sb(sb);
586 return;
587 }
588
589 variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are childre */
590
591 stringbuffer_append(sb, "(");
592 for ( i = 0; i < psurf->ngeoms; i++ )
593 {
594 if ( i > 0 )
595 stringbuffer_append(sb, ",");
596 /* We don't want type strings on our subgeoms */
598 }
599 stringbuffer_append(sb, ")");
600}
601
602
603/*
604* Generic GEOMETRY
605*/
606static void lwgeom_to_wkt_sb(const LWGEOM *geom, stringbuffer_t *sb, int precision, uint8_t variant)
607{
608 LWDEBUGF(4, "lwgeom_to_wkt_sb: type %s, hasz %d, hasm %d",
609 lwtype_name(geom->type), (geom->type),
610 FLAGS_GET_Z(geom->flags)?1:0, FLAGS_GET_M(geom->flags)?1:0);
611
612 switch (geom->type)
613 {
614 case POINTTYPE:
616 break;
617 case LINETYPE:
619 break;
620 case POLYGONTYPE:
622 break;
623 case MULTIPOINTTYPE:
625 break;
626 case MULTILINETYPE:
628 break;
629 case MULTIPOLYGONTYPE:
631 break;
632 case COLLECTIONTYPE:
634 break;
635 case CIRCSTRINGTYPE:
637 break;
638 case COMPOUNDTYPE:
640 break;
641 case CURVEPOLYTYPE:
643 break;
644 case MULTICURVETYPE:
646 break;
647 case MULTISURFACETYPE:
649 break;
650 case TRIANGLETYPE:
652 break;
653 case TINTYPE:
655 break;
658 break;
659 default:
660 lwerror("lwgeom_to_wkt_sb: Type %d - %s unsupported.",
661 geom->type, lwtype_name(geom->type));
662 }
663}
664
676char* lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
677{
678 stringbuffer_t *sb;
679 char *str = NULL;
680 if ( geom == NULL )
681 return NULL;
682 sb = stringbuffer_create();
683 /* Extended mode starts with an "SRID=" section for geoms that have one */
684 if ( (variant & WKT_EXTENDED) && lwgeom_has_srid(geom) )
685 {
686 stringbuffer_aprintf(sb, "SRID=%d;", geom->srid);
687 }
689 if ( stringbuffer_getstring(sb) == NULL )
690 {
691 lwerror("Uh oh");
692 return NULL;
693 }
695 if ( size_out )
696 *size_out = stringbuffer_getlength(sb) + 1;
698 return str;
699}
700
static uint8_t variant
Definition cu_in_twkb.c:26
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
#define COLLECTIONTYPE
Definition liblwgeom.h:122
#define COMPOUNDTYPE
Definition liblwgeom.h:124
#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 WKT_EXTENDED
Definition liblwgeom.h:2132
#define MULTIPOINTTYPE
Definition liblwgeom.h:119
int lwgeom_has_srid(const LWGEOM *geom)
Return true or false depending on whether a geometry has a valid SRID set.
Definition lwgeom.c:1387
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition liblwgeom.h:116
#define FLAGS_GET_Z(flags)
Definition liblwgeom.h:179
#define TINTYPE
Definition liblwgeom.h:130
#define MULTIPOLYGONTYPE
Definition liblwgeom.h:121
#define FLAGS_NDIMS(flags)
Definition liblwgeom.h:193
#define POLYGONTYPE
Definition liblwgeom.h:118
#define POLYHEDRALSURFACETYPE
Definition liblwgeom.h:128
#define CIRCSTRINGTYPE
Definition liblwgeom.h:123
#define WKT_ISO
Definition liblwgeom.h:2130
#define FLAGS_GET_M(flags)
Definition liblwgeom.h:180
#define MULTICURVETYPE
Definition liblwgeom.h:126
#define TRIANGLETYPE
Definition liblwgeom.h:129
#define WKT_NO_PARENS
int lwline_is_empty(const LWLINE *line)
#define WKT_IS_CHILD
int lwpoint_is_empty(const LWPOINT *point)
int lwtriangle_is_empty(const LWTRIANGLE *triangle)
int lwpoly_is_empty(const LWPOLY *poly)
#define WKT_NO_TYPE
Well-Known Text (WKT) Output Variant Types.
int lwprint_double(double d, int maxdd, char *buf, size_t bufsize)
Definition lwprint.c:492
int lwcircstring_is_empty(const LWCIRCSTRING *circ)
#define str(s)
#define LWDEBUGF(level, msg,...)
Definition lwgeom_log.h:88
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition lwutil.c:190
static uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)
Definition lwinline.h:67
static void lwcircstring_to_wkt_sb(const LWCIRCSTRING *circ, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:202
static void lwmsurface_to_wkt_sb(const LWMSURFACE *msurf, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:453
static void dimension_qualifiers_to_wkt_sb(const LWGEOM *geom, stringbuffer_t *sb, uint8_t variant)
Definition lwout_wkt.c:39
static void lwtin_to_wkt_sb(const LWTIN *tin, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:545
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
Definition lwout_wkt.c:676
static void empty_to_wkt_sb(stringbuffer_t *sb)
Definition lwout_wkt.c:69
static void lwcollection_to_wkt_sb(const LWCOLLECTION *collection, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:496
static void lwcompound_to_wkt_sb(const LWCOMPOUND *comp, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:312
static void lwmcurve_to_wkt_sb(const LWMCURVE *mcurv, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:405
static void lwline_to_wkt_sb(const LWLINE *line, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:156
static void lwtriangle_to_wkt_sb(const LWTRIANGLE *tri, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:524
static void lwmpoint_to_wkt_sb(const LWMPOINT *mpoint, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:222
static void lwcurvepoly_to_wkt_sb(const LWCURVEPOLY *cpoly, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:357
static void lwpoint_to_wkt_sb(const LWPOINT *pt, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:136
static void lwmline_to_wkt_sb(const LWMLINE *mline, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:250
static void lwmpoly_to_wkt_sb(const LWMPOLY *mpoly, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:280
static void lwpoly_to_wkt_sb(const LWPOLY *poly, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:175
static void ptarray_to_wkt_sb(const POINTARRAY *ptarray, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:83
static void lwgeom_to_wkt_sb(const LWGEOM *geom, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:606
static void lwpsurface_to_wkt_sb(const LWPSURFACE *psurf, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:574
stringbuffer_t * stringbuffer_create(void)
Allocate a new stringbuffer_t.
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.
char stringbuffer_lastchar(stringbuffer_t *s)
Return the last character in the buffer.
const char * stringbuffer_getstring(stringbuffer_t *s)
Returns a reference to the internal string being managed by the stringbuffer.
char * stringbuffer_getstringcopy(stringbuffer_t *s)
Returns a newly allocated string large enough to contain the current state of the string.
int stringbuffer_getlength(stringbuffer_t *s)
Returns the length of the current string, not including the null terminator (same behavior as strlen(...
void stringbuffer_destroy(stringbuffer_t *s)
Free the stringbuffer_t and all memory managed within it.
static void stringbuffer_append(stringbuffer_t *s, const char *a)
Append the specified string to the stringbuffer_t.
POINTARRAY * points
Definition liblwgeom.h:493
uint32_t ngeoms
Definition liblwgeom.h:566
LWGEOM ** geoms
Definition liblwgeom.h:561
uint32_t ngeoms
Definition liblwgeom.h:580
LWGEOM ** geoms
Definition liblwgeom.h:575
LWGEOM ** rings
Definition liblwgeom.h:589
uint32_t nrings
Definition liblwgeom.h:594
uint8_t type
Definition liblwgeom.h:448
int32_t srid
Definition liblwgeom.h:446
lwflags_t flags
Definition liblwgeom.h:447
POINTARRAY * points
Definition liblwgeom.h:469
LWGEOM ** geoms
Definition liblwgeom.h:603
uint32_t ngeoms
Definition liblwgeom.h:608
LWLINE ** geoms
Definition liblwgeom.h:533
uint32_t ngeoms
Definition liblwgeom.h:538
uint32_t ngeoms
Definition liblwgeom.h:524
LWPOINT ** geoms
Definition liblwgeom.h:519
uint32_t ngeoms
Definition liblwgeom.h:552
LWPOLY ** geoms
Definition liblwgeom.h:547
uint32_t ngeoms
Definition liblwgeom.h:622
LWGEOM ** geoms
Definition liblwgeom.h:617
POINTARRAY * point
Definition liblwgeom.h:457
uint8_t type
Definition liblwgeom.h:460
POINTARRAY ** rings
Definition liblwgeom.h:505
uint32_t nrings
Definition liblwgeom.h:510
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
POINTARRAY * points
Definition liblwgeom.h:481
lwflags_t flags
Definition liblwgeom.h:417
uint32_t npoints
Definition liblwgeom.h:413