PostGIS 3.7.0dev-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#define buffer_size 128
33
34/*
35* ISO format uses both Z and M qualifiers.
36* Extended format only uses an M qualifier for 3DM variants, where it is not
37* clear what the third dimension represents.
38* SFSQL format never has more than two dimensions, so no qualifiers.
39*/
40static void dimension_qualifiers_to_wkt_sb(const LWGEOM *geom, stringbuffer_t *sb, uint8_t variant)
41{
42
43 /* Extended WKT: POINTM(0 0 0) */
44#if 0
45 if ( (variant & WKT_EXTENDED) && ! (variant & WKT_IS_CHILD) && FLAGS_GET_M(geom->flags) && (!FLAGS_GET_Z(geom->flags)) )
46#else
47 if ( (variant & WKT_EXTENDED) && FLAGS_GET_M(geom->flags) && (!FLAGS_GET_Z(geom->flags)) )
48#endif
49 {
50 stringbuffer_append_len(sb, "M", 1); /* "M" */
51 return;
52 }
53
54 /* ISO WKT: POINT ZM (0 0 0 0) */
55 if ( (variant & WKT_ISO) && (FLAGS_NDIMS(geom->flags) > 2) )
56 {
57 stringbuffer_append_len(sb, " ", 1);
58 if ( FLAGS_GET_Z(geom->flags) )
59 stringbuffer_append_len(sb, "Z", 1);
60 if ( FLAGS_GET_M(geom->flags) )
61 stringbuffer_append_len(sb, "M", 1);
62 stringbuffer_append_len(sb, " ", 1);
63 }
64}
65
66/*
67* Write an empty token out, padding with a space if
68* necessary.
69*/
71{
72 if ( ! strchr(" ,(", stringbuffer_lastchar(sb)) ) /* "EMPTY" */
73 {
74 stringbuffer_append_len(sb, " ", 1);
75 }
76 stringbuffer_append_len(sb, "EMPTY", 5);
77}
78
79inline static void
80coordinate_to_wkt_sb(double *coords, stringbuffer_t *sb, uint32_t dimensions, int precision)
81{
82 uint32_t d = 0;
84
85 for (d = 1; d < dimensions; d++)
86 {
87 stringbuffer_append_len(sb, " ", 1);
89 }
90}
91
92/*
93* Point array is a list of coordinates. Depending on output mode,
94* we may suppress some dimensions. ISO and Extended formats include
95* all dimensions. Standard OGC output only includes X/Y coordinates.
96*/
97static void ptarray_to_wkt_sb(const POINTARRAY *ptarray, stringbuffer_t *sb, int precision, uint8_t variant)
98{
99 /* OGC only includes X/Y */
100 uint32_t dimensions = 2;
101
102 /* ISO and extended formats include all dimensions */
103 if ( variant & ( WKT_ISO | WKT_EXTENDED ) )
104 dimensions = FLAGS_NDIMS(ptarray->flags);
105
106 stringbuffer_makeroom(sb, 2 + ((OUT_MAX_BYTES_DOUBLE + 1) * dimensions * ptarray->npoints));
107 /* Opening paren? */
108 if ( ! (variant & WKT_NO_PARENS) )
109 stringbuffer_append_len(sb, "(", 1);
110
111 /* Digits and commas */
112 if (ptarray->npoints)
113 {
114 uint32_t i = 0;
115
116 double *dbl_ptr = (double *)getPoint_internal(ptarray, i);
117 coordinate_to_wkt_sb(dbl_ptr, sb, dimensions, precision);
118
119 for (i = 1; i < ptarray->npoints; i++)
120 {
121 stringbuffer_append_len(sb, ",", 1);
122 dbl_ptr = (double *)getPoint_internal(ptarray, i);
123 coordinate_to_wkt_sb(dbl_ptr, sb, dimensions, precision);
124 }
125 }
126
127 /* Closing paren? */
128 if ( ! (variant & WKT_NO_PARENS) )
129 stringbuffer_append_len(sb, ")", 1);
130}
131
132/*
133* A four-dimensional point will have different outputs depending on variant.
134* ISO: POINT ZM (0 0 0 0)
135* Extended: POINT(0 0 0 0)
136* OGC: POINT(0 0)
137* A three-dimensional m-point will have different outputs too.
138* ISO: POINT M (0 0 0)
139* Extended: POINTM(0 0 0)
140* OGC: POINT(0 0)
141*/
142static void lwpoint_to_wkt_sb(const LWPOINT *pt, stringbuffer_t *sb, int precision, uint8_t variant)
143{
144 if ( ! (variant & WKT_NO_TYPE) )
145 {
146 stringbuffer_append_len(sb, "POINT", 5); /* "POINT" */
148 }
149
150 if ( lwpoint_is_empty(pt) )
151 {
152 empty_to_wkt_sb(sb);
153 return;
154 }
155
157}
158
159/*
160* LINESTRING(0 0 0, 1 1 1)
161*/
162static void lwline_to_wkt_sb(const LWLINE *line, stringbuffer_t *sb, int precision, uint8_t variant)
163{
164 if ( ! (variant & WKT_NO_TYPE) )
165 {
166 stringbuffer_append_len(sb, "LINESTRING", 10); /* "LINESTRING" */
168 }
169 if ( lwline_is_empty(line) )
170 {
171 empty_to_wkt_sb(sb);
172 return;
173 }
174
176}
177
178/*
179* POLYGON(0 0 1, 1 0 1, 1 1 1, 0 1 1, 0 0 1)
180*/
181static void lwpoly_to_wkt_sb(const LWPOLY *poly, stringbuffer_t *sb, int precision, uint8_t variant)
182{
183 uint32_t i = 0;
184 if ( ! (variant & WKT_NO_TYPE) )
185 {
186 stringbuffer_append_len(sb, "POLYGON", 7); /* "POLYGON" */
188 }
189 if ( lwpoly_is_empty(poly) )
190 {
191 empty_to_wkt_sb(sb);
192 return;
193 }
194
195 stringbuffer_append_len(sb, "(", 1);
196 for ( i = 0; i < poly->nrings; i++ )
197 {
198 if ( i > 0 )
199 stringbuffer_append_len(sb, ",", 1);
201 }
202 stringbuffer_append_len(sb, ")", 1);
203}
204
205/*
206* CIRCULARSTRING
207*/
208static void lwcircstring_to_wkt_sb(const LWCIRCSTRING *circ, stringbuffer_t *sb, int precision, uint8_t variant)
209{
210 if ( ! (variant & WKT_NO_TYPE) )
211 {
212 stringbuffer_append_len(sb, "CIRCULARSTRING", 14); /* "CIRCULARSTRING" */
214 }
215 if ( lwcircstring_is_empty(circ) )
216 {
217 empty_to_wkt_sb(sb);
218 return;
219 }
221}
222
223
224/*
225* Multi-points, in non-ISO format, do not wrap their sub-members in parens, unlike other multi-geometries.
226* MULTPOINT(0 0, 1 1) instead of MULTIPOINT((0 0),(1 1))
227* Strictly speaking, the SFA spec also mandates use of parens in sub-members, but
228* use the old non-parens interpretation for WKT_SFSQL
229*/
230static void lwmpoint_to_wkt_sb(const LWMPOINT *mpoint, stringbuffer_t *sb, int precision, uint8_t variant)
231{
232 uint32_t i = 0;
233 if ( ! (variant & WKT_NO_TYPE) )
234 {
235 stringbuffer_append_len(sb, "MULTIPOINT", 10); /* "MULTIPOINT" */
237 }
238 if ( mpoint->ngeoms < 1 )
239 {
240 empty_to_wkt_sb(sb);
241 return;
242 }
243 stringbuffer_append_len(sb, "(", 1);
244 variant = variant | WKT_IS_CHILD | WKT_NO_TYPE; /* Inform the sub-geometries they are children */
245 if ( !(variant & WKT_ISO) )
247 for ( i = 0; i < mpoint->ngeoms; i++ )
248 {
249 if ( i > 0 )
250 stringbuffer_append_len(sb, ",", 1);
251 /* We don't want type strings or parens on our subgeoms */
252 lwpoint_to_wkt_sb(mpoint->geoms[i], sb, precision, variant);
253 }
254 stringbuffer_append_len(sb, ")", 1);
255}
256
257/*
258* MULTILINESTRING
259*/
260static void lwmline_to_wkt_sb(const LWMLINE *mline, stringbuffer_t *sb, int precision, uint8_t variant)
261{
262 uint32_t i = 0;
263
264 if ( ! (variant & WKT_NO_TYPE) )
265 {
266 stringbuffer_append_len(sb, "MULTILINESTRING", 15); /* "MULTILINESTRING" */
268 }
269 if ( mline->ngeoms < 1 )
270 {
271 empty_to_wkt_sb(sb);
272 return;
273 }
274
275 stringbuffer_append_len(sb, "(", 1);
276 variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are childre */
277 for ( i = 0; i < mline->ngeoms; i++ )
278 {
279 if ( i > 0 )
280 stringbuffer_append_len(sb, ",", 1);
281 /* We don't want type strings on our subgeoms */
283 }
284 stringbuffer_append_len(sb, ")", 1);
285}
286
287/*
288* MULTIPOLYGON
289*/
290static void lwmpoly_to_wkt_sb(const LWMPOLY *mpoly, stringbuffer_t *sb, int precision, uint8_t variant)
291{
292 uint32_t i = 0;
293
294 if ( ! (variant & WKT_NO_TYPE) )
295 {
296 stringbuffer_append_len(sb, "MULTIPOLYGON", 12); /* "MULTIPOLYGON" */
298 }
299 if ( mpoly->ngeoms < 1 )
300 {
301 empty_to_wkt_sb(sb);
302 return;
303 }
304
305 stringbuffer_append_len(sb, "(", 1);
306 variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are childre */
307 for ( i = 0; i < mpoly->ngeoms; i++ )
308 {
309 if ( i > 0 )
310 stringbuffer_append_len(sb, ",", 1);
311 /* We don't want type strings on our subgeoms */
313 }
314 stringbuffer_append_len(sb, ")", 1);
315}
316
317/*
318* Compound curves provide type information for their curved sub-geometries
319* but not their linestring sub-geometries.
320* COMPOUNDCURVE((0 0, 1 1), CURVESTRING(1 1, 2 2, 3 3))
321*/
322static void lwcompound_to_wkt_sb(const LWCOMPOUND *comp, stringbuffer_t *sb, int precision, uint8_t variant)
323{
324 uint32_t i = 0;
325
326 if ( ! (variant & WKT_NO_TYPE) )
327 {
328 stringbuffer_append_len(sb, "COMPOUNDCURVE", 13); /* "COMPOUNDCURVE" */
330 }
331 if ( comp->ngeoms < 1 )
332 {
333 empty_to_wkt_sb(sb);
334 return;
335 }
336
337 stringbuffer_append_len(sb, "(", 1);
338 variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are childre */
339 for ( i = 0; i < comp->ngeoms; i++ )
340 {
341 int type = comp->geoms[i]->type;
342 if ( i > 0 )
343 stringbuffer_append_len(sb, ",", 1);
344 /* Linestring subgeoms don't get type identifiers */
345 if ( type == LINETYPE )
346 {
348 }
349 /* But circstring subgeoms *do* get type identifiers */
350 else if ( type == CIRCSTRINGTYPE )
351 {
353 }
354 else
355 {
356 lwerror("lwcompound_to_wkt_sb: Unknown type received %d - %s", type, lwtype_name(type));
357 }
358 }
359 stringbuffer_append_len(sb, ")", 1);
360}
361
362/*
363* Curve polygons provide type information for their curved rings
364* but not their linestring rings.
365* CURVEPOLYGON((0 0, 1 1, 0 1, 0 0), CURVESTRING(0 0, 1 1, 0 1, 0.5 1, 0 0))
366*/
367static void lwcurvepoly_to_wkt_sb(const LWCURVEPOLY *cpoly, stringbuffer_t *sb, int precision, uint8_t variant)
368{
369 uint32_t i = 0;
370
371 if ( ! (variant & WKT_NO_TYPE) )
372 {
373 stringbuffer_append_len(sb, "CURVEPOLYGON", 12); /* "CURVEPOLYGON" */
375 }
376 if ( cpoly->nrings < 1 )
377 {
378 empty_to_wkt_sb(sb);
379 return;
380 }
381 stringbuffer_append_len(sb, "(", 1);
382 variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are childre */
383 for ( i = 0; i < cpoly->nrings; i++ )
384 {
385 int type = cpoly->rings[i]->type;
386 if ( i > 0 )
387 stringbuffer_append_len(sb, ",", 1);
388 switch (type)
389 {
390 case LINETYPE:
391 /* Linestring subgeoms don't get type identifiers */
393 break;
394 case CIRCSTRINGTYPE:
395 /* But circstring subgeoms *do* get type identifiers */
397 break;
398 case COMPOUNDTYPE:
399 /* And compoundcurve subgeoms *do* get type identifiers */
401 break;
402 default:
403 lwerror("lwcurvepoly_to_wkt_sb: Unknown type received %d - %s", type, lwtype_name(type));
404 }
405 }
406 stringbuffer_append_len(sb, ")", 1);
407}
408
409
410/*
411* Multi-curves provide type information for their curved sub-geometries
412* but not their linear sub-geometries.
413* MULTICURVE((0 0, 1 1), CURVESTRING(0 0, 1 1, 2 2))
414*/
415static void lwmcurve_to_wkt_sb(const LWMCURVE *mcurv, stringbuffer_t *sb, int precision, uint8_t variant)
416{
417 uint32_t i = 0;
418
419 if ( ! (variant & WKT_NO_TYPE) )
420 {
421 stringbuffer_append_len(sb, "MULTICURVE", 10); /* "MULTICURVE" */
423 }
424 if ( mcurv->ngeoms < 1 )
425 {
426 empty_to_wkt_sb(sb);
427 return;
428 }
429 stringbuffer_append_len(sb, "(", 1);
430 variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are childre */
431 for ( i = 0; i < mcurv->ngeoms; i++ )
432 {
433 int type = mcurv->geoms[i]->type;
434 if ( i > 0 )
435 stringbuffer_append_len(sb, ",", 1);
436 switch (type)
437 {
438 case LINETYPE:
439 /* Linestring subgeoms don't get type identifiers */
441 break;
442 case CIRCSTRINGTYPE:
443 /* But circstring subgeoms *do* get type identifiers */
445 break;
446 case COMPOUNDTYPE:
447 /* And compoundcurve subgeoms *do* get type identifiers */
449 break;
450 default:
451 lwerror("lwmcurve_to_wkt_sb: Unknown type received %d - %s", type, lwtype_name(type));
452 }
453 }
454 stringbuffer_append_len(sb, ")", 1);
455}
456
457
458/*
459* Multi-surfaces provide type information for their curved sub-geometries
460* but not their linear sub-geometries.
461* MULTISURFACE(((0 0, 1 1, 1 0, 0 0)), CURVEPOLYGON(CURVESTRING(0 0, 1 1, 2 2, 0 1, 0 0)))
462*/
463static void lwmsurface_to_wkt_sb(const LWMSURFACE *msurf, stringbuffer_t *sb, int precision, uint8_t variant)
464{
465 uint32_t i = 0;
466
467 if ( ! (variant & WKT_NO_TYPE) )
468 {
469 stringbuffer_append_len(sb, "MULTISURFACE", 12); /* "MULTISURFACE" */
471 }
472 if ( msurf->ngeoms < 1 )
473 {
474 empty_to_wkt_sb(sb);
475 return;
476 }
477 stringbuffer_append_len(sb, "(", 1);
478 variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are childre */
479 for ( i = 0; i < msurf->ngeoms; i++ )
480 {
481 int type = msurf->geoms[i]->type;
482 if ( i > 0 )
483 stringbuffer_append_len(sb, ",", 1);
484 switch (type)
485 {
486 case POLYGONTYPE:
487 /* Linestring subgeoms don't get type identifiers */
489 break;
490 case CURVEPOLYTYPE:
491 /* But circstring subgeoms *do* get type identifiers */
493 break;
494 default:
495 lwerror("lwmsurface_to_wkt_sb: Unknown type received %d - %s", type, lwtype_name(type));
496 }
497 }
498 stringbuffer_append_len(sb, ")", 1);
499}
500
501/*
502* Geometry collections provide type information for all their curved sub-geometries
503* but not their linear sub-geometries.
504* GEOMETRYCOLLECTION(POLYGON((0 0, 1 1, 1 0, 0 0)), CURVEPOLYGON(CURVESTRING(0 0, 1 1, 2 2, 0 1, 0 0)))
505*/
506static void lwcollection_to_wkt_sb(const LWCOLLECTION *collection, stringbuffer_t *sb, int precision, uint8_t variant)
507{
508 uint32_t i = 0;
509
510 if ( ! (variant & WKT_NO_TYPE) )
511 {
512 stringbuffer_append_len(sb, "GEOMETRYCOLLECTION", 18); /* "GEOMETRYCOLLECTION" */
514 }
515 if ( collection->ngeoms < 1 )
516 {
517 empty_to_wkt_sb(sb);
518 return;
519 }
520 stringbuffer_append_len(sb, "(", 1);
521 variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are children */
522 for ( i = 0; i < collection->ngeoms; i++ )
523 {
524 if ( i > 0 )
525 stringbuffer_append_len(sb, ",", 1);
526 lwgeom_to_wkt_sb((LWGEOM*)collection->geoms[i], sb, precision, variant );
527 }
528 stringbuffer_append_len(sb, ")", 1);
529}
530
531/*
532* TRIANGLE
533*/
534static void lwtriangle_to_wkt_sb(const LWTRIANGLE *tri, stringbuffer_t *sb, int precision, uint8_t variant)
535{
536 if ( ! (variant & WKT_NO_TYPE) )
537 {
538 stringbuffer_append_len(sb, "TRIANGLE", 8); /* "TRIANGLE" */
540 }
541 if ( lwtriangle_is_empty(tri) )
542 {
543 empty_to_wkt_sb(sb);
544 return;
545 }
546
547 stringbuffer_append_len(sb, "(", 1); /* Triangles have extraneous brackets */
549 stringbuffer_append_len(sb, ")", 1);
550}
551
552/*
553* TIN
554*/
555static void lwtin_to_wkt_sb(const LWTIN *tin, stringbuffer_t *sb, int precision, uint8_t variant)
556{
557 uint32_t i = 0;
558
559 if ( ! (variant & WKT_NO_TYPE) )
560 {
561 stringbuffer_append_len(sb, "TIN", 3); /* "TIN" */
563 }
564 if ( tin->ngeoms < 1 )
565 {
566 empty_to_wkt_sb(sb);
567 return;
568 }
569
570 stringbuffer_append_len(sb, "(", 1);
571 for ( i = 0; i < tin->ngeoms; i++ )
572 {
573 if ( i > 0 )
574 stringbuffer_append_len(sb, ",", 1);
575 /* We don't want type strings on our subgeoms */
577 }
578 stringbuffer_append_len(sb, ")", 1);
579}
580
581/*
582* POLYHEDRALSURFACE
583*/
584static void lwpsurface_to_wkt_sb(const LWPSURFACE *psurf, stringbuffer_t *sb, int precision, uint8_t variant)
585{
586 uint32_t i = 0;
587
588 if ( ! (variant & WKT_NO_TYPE) )
589 {
590 stringbuffer_append_len(sb, "POLYHEDRALSURFACE", 17); /* "POLYHEDRALSURFACE" */
592 }
593 if ( psurf->ngeoms < 1 )
594 {
595 empty_to_wkt_sb(sb);
596 return;
597 }
598
599 variant = variant | WKT_IS_CHILD; /* Inform the sub-geometries they are childre */
600
601 stringbuffer_append_len(sb, "(", 1);
602 for ( i = 0; i < psurf->ngeoms; i++ )
603 {
604 if ( i > 0 )
605 stringbuffer_append_len(sb, ",", 1);
606 /* We don't want type strings on our subgeoms */
608 }
609 stringbuffer_append_len(sb, ")", 1);
610}
611
612
613/*
614* Generic GEOMETRY
615*/
616static void lwgeom_to_wkt_sb(const LWGEOM *geom, stringbuffer_t *sb, int precision, uint8_t variant)
617{
618 LWDEBUGF(4, "lwgeom_to_wkt_sb: type %s, hasz %d, hasm %d",
619 lwtype_name(geom->type),
620 FLAGS_GET_Z(geom->flags)?1:0, FLAGS_GET_M(geom->flags)?1:0);
621
622 switch (geom->type)
623 {
624 case POINTTYPE:
626 break;
627 case LINETYPE:
629 break;
630 case POLYGONTYPE:
632 break;
633 case MULTIPOINTTYPE:
635 break;
636 case MULTILINETYPE:
638 break;
639 case MULTIPOLYGONTYPE:
641 break;
642 case COLLECTIONTYPE:
644 break;
645 case CIRCSTRINGTYPE:
647 break;
648 case COMPOUNDTYPE:
650 break;
651 case CURVEPOLYTYPE:
653 break;
654 case MULTICURVETYPE:
656 break;
657 case MULTISURFACETYPE:
659 break;
660 case TRIANGLETYPE:
662 break;
663 case TINTYPE:
665 break;
668 break;
669 default:
670 lwerror("lwgeom_to_wkt_sb: Type %d - %s unsupported.",
671 geom->type, lwtype_name(geom->type));
672 }
673}
674
675static stringbuffer_t *
677{
678 stringbuffer_t *sb;
679 if ( geom == NULL )
680 return NULL;
681 sb = stringbuffer_create();
682 /* Extended mode starts with an "SRID=" section for geoms that have one */
683 if ( (variant & WKT_EXTENDED) && lwgeom_has_srid(geom) )
684 {
685 stringbuffer_aprintf(sb, "SRID=%d;", geom->srid);
686 }
688 if ( stringbuffer_getstring(sb) == NULL )
689 {
690 lwerror("Uh oh");
691 return NULL;
692 }
693 return sb;
694}
695
707char *
708lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
709{
711 if (!sb)
712 return NULL;
714 if ( size_out )
715 *size_out = stringbuffer_getlength(sb) + 1;
717 return str;
718}
719
722{
724 if (!sb)
725 return NULL;
728 return output;
729}
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:108
#define COMPOUNDTYPE
Definition liblwgeom.h:110
#define CURVEPOLYTYPE
Definition liblwgeom.h:111
#define MULTILINETYPE
Definition liblwgeom.h:106
#define MULTISURFACETYPE
Definition liblwgeom.h:113
#define LINETYPE
Definition liblwgeom.h:103
#define WKT_EXTENDED
Definition liblwgeom.h:2221
#define MULTIPOINTTYPE
Definition liblwgeom.h:105
int lwgeom_has_srid(const LWGEOM *geom)
Return true or false depending on whether a geometry has a valid SRID set.
Definition lwgeom.c:1495
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition liblwgeom.h:102
#define FLAGS_GET_Z(flags)
Definition liblwgeom.h:165
#define TINTYPE
Definition liblwgeom.h:116
#define MULTIPOLYGONTYPE
Definition liblwgeom.h:107
#define FLAGS_NDIMS(flags)
Definition liblwgeom.h:179
#define POLYGONTYPE
Definition liblwgeom.h:104
#define POLYHEDRALSURFACETYPE
Definition liblwgeom.h:114
#define CIRCSTRINGTYPE
Definition liblwgeom.h:109
#define WKT_ISO
Definition liblwgeom.h:2219
#define FLAGS_GET_M(flags)
Definition liblwgeom.h:166
#define MULTICURVETYPE
Definition liblwgeom.h:112
#define TRIANGLETYPE
Definition liblwgeom.h:115
#define WKT_NO_PARENS
int lwline_is_empty(const LWLINE *line)
#define OUT_MAX_BYTES_DOUBLE
#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 lwcircstring_is_empty(const LWCIRCSTRING *circ)
#define str(s)
#define LWDEBUGF(level, msg,...)
Definition lwgeom_log.h:106
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
static uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)
Definition lwinline.h:75
static void lwcircstring_to_wkt_sb(const LWCIRCSTRING *circ, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:208
static void lwmsurface_to_wkt_sb(const LWMSURFACE *msurf, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:463
static void dimension_qualifiers_to_wkt_sb(const LWGEOM *geom, stringbuffer_t *sb, uint8_t variant)
Definition lwout_wkt.c:40
static void lwtin_to_wkt_sb(const LWTIN *tin, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:555
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
Definition lwout_wkt.c:708
static void empty_to_wkt_sb(stringbuffer_t *sb)
Definition lwout_wkt.c:70
static stringbuffer_t * lwgeom_to_wkt_internal(const LWGEOM *geom, uint8_t variant, int precision)
Definition lwout_wkt.c:676
static void lwcollection_to_wkt_sb(const LWCOLLECTION *collection, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:506
static void lwcompound_to_wkt_sb(const LWCOMPOUND *comp, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:322
static void lwmcurve_to_wkt_sb(const LWMCURVE *mcurv, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:415
static void lwline_to_wkt_sb(const LWLINE *line, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:162
static void lwtriangle_to_wkt_sb(const LWTRIANGLE *tri, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:534
static void lwmpoint_to_wkt_sb(const LWMPOINT *mpoint, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:230
lwvarlena_t * lwgeom_to_wkt_varlena(const LWGEOM *geom, uint8_t variant, int precision)
Definition lwout_wkt.c:721
static void lwcurvepoly_to_wkt_sb(const LWCURVEPOLY *cpoly, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:367
static void lwpoint_to_wkt_sb(const LWPOINT *pt, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:142
static void lwmline_to_wkt_sb(const LWMLINE *mline, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:260
static void lwmpoly_to_wkt_sb(const LWMPOLY *mpoly, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:290
static void coordinate_to_wkt_sb(double *coords, stringbuffer_t *sb, uint32_t dimensions, int precision)
Definition lwout_wkt.c:80
static void lwpoly_to_wkt_sb(const LWPOLY *poly, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:181
static void ptarray_to_wkt_sb(const POINTARRAY *ptarray, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:97
static void lwgeom_to_wkt_sb(const LWGEOM *geom, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:616
static void lwpsurface_to_wkt_sb(const LWPSURFACE *psurf, stringbuffer_t *sb, int precision, uint8_t variant)
Definition lwout_wkt.c:584
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.
lwvarlena_t * stringbuffer_getvarlenacopy(stringbuffer_t *s)
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_double(stringbuffer_t *s, double d, int precision)
static void stringbuffer_append_len(stringbuffer_t *s, const char *a, size_t alen)
Append the specified string to the stringbuffer_t using known length.
static void stringbuffer_makeroom(stringbuffer_t *s, size_t size_to_add)
If necessary, expand the stringbuffer_t internal buffer to accommodate the specified additional size.
POINTARRAY * points
Definition liblwgeom.h:507
uint32_t ngeoms
Definition liblwgeom.h:580
LWGEOM ** geoms
Definition liblwgeom.h:575
uint32_t ngeoms
Definition liblwgeom.h:594
LWGEOM ** geoms
Definition liblwgeom.h:589
LWGEOM ** rings
Definition liblwgeom.h:603
uint32_t nrings
Definition liblwgeom.h:608
uint8_t type
Definition liblwgeom.h:462
int32_t srid
Definition liblwgeom.h:460
lwflags_t flags
Definition liblwgeom.h:461
POINTARRAY * points
Definition liblwgeom.h:483
LWGEOM ** geoms
Definition liblwgeom.h:617
uint32_t ngeoms
Definition liblwgeom.h:622
LWLINE ** geoms
Definition liblwgeom.h:547
uint32_t ngeoms
Definition liblwgeom.h:552
uint32_t ngeoms
Definition liblwgeom.h:538
LWPOINT ** geoms
Definition liblwgeom.h:533
uint32_t ngeoms
Definition liblwgeom.h:566
LWPOLY ** geoms
Definition liblwgeom.h:561
uint32_t ngeoms
Definition liblwgeom.h:636
LWGEOM ** geoms
Definition liblwgeom.h:631
POINTARRAY * point
Definition liblwgeom.h:471
uint8_t type
Definition liblwgeom.h:474
POINTARRAY ** rings
Definition liblwgeom.h:519
uint32_t nrings
Definition liblwgeom.h:524
LWPOLY ** geoms
Definition liblwgeom.h:645
uint32_t ngeoms
Definition liblwgeom.h:650
uint32_t ngeoms
Definition liblwgeom.h:664
LWTRIANGLE ** geoms
Definition liblwgeom.h:659
POINTARRAY * points
Definition liblwgeom.h:495
lwflags_t flags
Definition liblwgeom.h:431
uint32_t npoints
Definition liblwgeom.h:427