PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
lwin_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) 2010 Paul Ramsey <pramsey@cleverelephant.ca>
22 *
23 **********************************************************************/
24
25
26#include <stdlib.h>
27#include <ctype.h> /* for isspace */
28
29#include "lwin_wkt.h"
30#include "lwin_wkt_parse.h"
31#include "lwgeom_log.h"
32
33
34/*
35* Error messages for failures in the parser.
36*/
37const char *parser_error_messages[] =
38{
39 "",
40 "geometry requires more points",
41 "geometry must have an odd number of points",
42 "geometry contains non-closed rings",
43 "can not mix dimensionality in a geometry",
44 "parse error - invalid geometry",
45 "invalid WKB type",
46 "incontinuous compound curve",
47 "triangle must have exactly 4 points",
48 "geometry has too many points",
49 "parse error - invalid geometry"
50};
51
52#define SET_PARSER_ERROR(errno) { \
53 global_parser_result.message = parser_error_messages[(errno)]; \
54 global_parser_result.errcode = (errno); \
55 global_parser_result.errlocation = wkt_yylloc.last_column; \
56 }
57
62{
63 char *c = str;
64 long i = 0;
65 int32_t srid;
66
67 if( ! str ) return SRID_UNKNOWN;
68 c += 5; /* Advance past "SRID=" */
69 i = strtol(c, NULL, 10);
70 srid = clamp_srid((int32_t)i);
71 /* TODO: warn on explicit UNKNOWN srid ? */
72 return srid;
73}
74
75static lwflags_t wkt_dimensionality(char *dimensionality)
76{
77 size_t i = 0;
78 lwflags_t flags = 0;
79
80 if( ! dimensionality )
81 return flags;
82
83 /* If there's an explicit dimensionality, we use that */
84 for( i = 0; i < strlen(dimensionality); i++ )
85 {
86 if( (dimensionality[i] == 'Z') || (dimensionality[i] == 'z') )
87 FLAGS_SET_Z(flags,1);
88 else if( (dimensionality[i] == 'M') || (dimensionality[i] == 'm') )
89 FLAGS_SET_M(flags,1);
90 /* only a space is accepted in between */
91 else if( ! isspace(dimensionality[i]) ) break;
92 }
93 return flags;
94}
95
96
101static int wkt_parser_set_dims(LWGEOM *geom, lwflags_t flags)
102{
103 int hasz = FLAGS_GET_Z(flags);
104 int hasm = FLAGS_GET_M(flags);
105 uint32_t i = 0;
106
107 /* Error on junk */
108 if( ! geom )
109 return LW_FAILURE;
110
111 FLAGS_SET_Z(geom->flags, hasz);
112 FLAGS_SET_M(geom->flags, hasm);
113
114 switch( geom->type )
115 {
116 case POINTTYPE:
117 {
118 LWPOINT *pt = (LWPOINT*)geom;
119 if ( pt->point )
120 {
121 FLAGS_SET_Z(pt->point->flags, hasz);
122 FLAGS_SET_M(pt->point->flags, hasm);
123 }
124 break;
125 }
126 case TRIANGLETYPE:
127 case CIRCSTRINGTYPE:
128 case LINETYPE:
129 {
130 LWLINE *ln = (LWLINE*)geom;
131 if ( ln->points )
132 {
133 FLAGS_SET_Z(ln->points->flags, hasz);
134 FLAGS_SET_M(ln->points->flags, hasm);
135 }
136 break;
137 }
138 case POLYGONTYPE:
139 {
140 LWPOLY *poly = (LWPOLY*)geom;
141 for ( i = 0; i < poly->nrings; i++ )
142 {
143 if( poly->rings[i] )
144 {
145 FLAGS_SET_Z(poly->rings[i]->flags, hasz);
146 FLAGS_SET_M(poly->rings[i]->flags, hasm);
147 }
148 }
149 break;
150 }
151 case CURVEPOLYTYPE:
152 {
153 LWCURVEPOLY *poly = (LWCURVEPOLY*)geom;
154 for ( i = 0; i < poly->nrings; i++ )
155 wkt_parser_set_dims(poly->rings[i], flags);
156 break;
157 }
158 default:
159 {
160 if ( lwtype_is_collection(geom->type) )
161 {
162 LWCOLLECTION *col = (LWCOLLECTION*)geom;
163 for ( i = 0; i < col->ngeoms; i++ )
164 wkt_parser_set_dims(col->geoms[i], flags);
165 return LW_SUCCESS;
166 }
167 else
168 {
169 LWDEBUGF(2,"Unknown geometry type: %d", geom->type);
170 return LW_FAILURE;
171 }
172 }
173 }
174
175 return LW_SUCCESS;
176}
177
184{
185 int hasz = FLAGS_GET_Z(flags);
186 int hasm = FLAGS_GET_M(flags);
187 int ndims = 2 + hasz + hasm;
188
189 /* No dimensionality or array means we go with what we have */
190 if( ! (flags && pa) )
191 return LW_TRUE;
192
193 LWDEBUGF(5,"dimensionality ndims == %d", ndims);
194 LWDEBUGF(5,"FLAGS_NDIMS(pa->flags) == %d", FLAGS_NDIMS(pa->flags));
195
196 /*
197 * ndims > 2 implies that the flags have something useful to add,
198 * that there is a 'Z' or an 'M' or both.
199 */
200 if( ndims > 2 )
201 {
202 /* Mismatch implies a problem */
203 if ( FLAGS_NDIMS(pa->flags) != ndims )
204 return LW_FALSE;
205 /* Match means use the explicit dimensionality */
206 else
207 {
208 FLAGS_SET_Z(pa->flags, hasz);
209 FLAGS_SET_M(pa->flags, hasm);
210 }
211 }
212
213 return LW_TRUE;
214}
215
216
217
221POINT wkt_parser_coord_2(double c1, double c2)
222{
223 POINT p;
224 p.flags = 0;
225 p.x = c1;
226 p.y = c2;
227 p.z = p.m = 0.0;
228 FLAGS_SET_Z(p.flags, 0);
229 FLAGS_SET_M(p.flags, 0);
230 return p;
231}
232
237POINT wkt_parser_coord_3(double c1, double c2, double c3)
238{
239 POINT p;
240 p.flags = 0;
241 p.x = c1;
242 p.y = c2;
243 p.z = c3;
244 p.m = 0;
245 FLAGS_SET_Z(p.flags, 1);
246 FLAGS_SET_M(p.flags, 0);
247 return p;
248}
249
252POINT wkt_parser_coord_4(double c1, double c2, double c3, double c4)
253{
254 POINT p;
255 p.flags = 0;
256 p.x = c1;
257 p.y = c2;
258 p.z = c3;
259 p.m = c4;
260 FLAGS_SET_Z(p.flags, 1);
261 FLAGS_SET_M(p.flags, 1);
262 return p;
263}
264
266{
267 POINT4D pt;
268 LWDEBUG(4,"entered");
269
270 /* Error on trouble */
271 if( ! pa )
272 {
274 return NULL;
275 }
276
277 /* Check that the coordinate has the same dimensionality as the array */
278 if( FLAGS_NDIMS(p.flags) != FLAGS_NDIMS(pa->flags) )
279 {
280 ptarray_free(pa);
282 return NULL;
283 }
284
285 /* While parsing the point arrays, XYM and XMZ points are both treated as XYZ */
286 pt.x = p.x;
287 pt.y = p.y;
288 if( FLAGS_GET_Z(pa->flags) )
289 pt.z = p.z;
290 if( FLAGS_GET_M(pa->flags) )
291 pt.m = p.m;
292 /* If the destination is XYM, we'll write the third coordinate to m */
293 if( FLAGS_GET_M(pa->flags) && ! FLAGS_GET_Z(pa->flags) )
294 pt.m = p.z;
295
296 ptarray_append_point(pa, &pt, LW_TRUE); /* Allow duplicate points in array */
297 return pa;
298}
299
304{
305 int ndims = FLAGS_NDIMS(p.flags);
306 POINTARRAY *pa = ptarray_construct_empty((ndims>2), (ndims>3), 4);
307 LWDEBUG(4,"entered");
308 if ( ! pa )
309 {
311 return NULL;
312 }
313 return wkt_parser_ptarray_add_coord(pa, p);
314}
315
320LWGEOM* wkt_parser_point_new(POINTARRAY *pa, char *dimensionality)
321{
322 lwflags_t flags = wkt_dimensionality(dimensionality);
323 LWDEBUG(4,"entered");
324
325 /* No pointarray means it is empty */
326 if( ! pa )
328
329 /* If the number of dimensions is not consistent, we have a problem. */
330 if( wkt_pointarray_dimensionality(pa, flags) == LW_FALSE )
331 {
332 ptarray_free(pa);
334 return NULL;
335 }
336
337 /* Only one point allowed in our point array! */
338 if( pa->npoints != 1 )
339 {
340 ptarray_free(pa);
342 return NULL;
343 }
344
346}
347
348
354LWGEOM* wkt_parser_linestring_new(POINTARRAY *pa, char *dimensionality)
355{
356 lwflags_t flags = wkt_dimensionality(dimensionality);
357 LWDEBUG(4,"entered");
358
359 /* No pointarray means it is empty */
360 if( ! pa )
362
363 /* If the number of dimensions is not consistent, we have a problem. */
364 if( wkt_pointarray_dimensionality(pa, flags) == LW_FALSE )
365 {
366 ptarray_free(pa);
368 return NULL;
369 }
370
371 /* Apply check for not enough points, if requested. */
373 {
374 ptarray_free(pa);
376 return NULL;
377 }
378
380}
381
389{
390 lwflags_t flags = wkt_dimensionality(dimensionality);
391 LWDEBUG(4,"entered");
392
393 /* No pointarray means it is empty */
394 if( ! pa )
396
397 /* If the number of dimensions is not consistent, we have a problem. */
398 if( wkt_pointarray_dimensionality(pa, flags) == LW_FALSE )
399 {
400 ptarray_free(pa);
402 return NULL;
403 }
404
405 /* Apply check for not enough points, if requested. */
407 {
408 ptarray_free(pa);
410 return NULL;
411 }
412
413 /* Apply check for odd number of points, if requested. */
415 {
416 ptarray_free(pa);
418 return NULL;
419 }
420
422}
423
424LWGEOM* wkt_parser_triangle_new(POINTARRAY *pa, char *dimensionality)
425{
426 lwflags_t flags = wkt_dimensionality(dimensionality);
427 LWDEBUG(4,"entered");
428
429 /* No pointarray means it is empty */
430 if( ! pa )
432
433 /* If the number of dimensions is not consistent, we have a problem. */
434 if( wkt_pointarray_dimensionality(pa, flags) == LW_FALSE )
435 {
436 ptarray_free(pa);
438 return NULL;
439 }
440
441 /* Triangles need four points. */
442 if( (pa->npoints != 4) )
443 {
444 ptarray_free(pa);
446 return NULL;
447 }
448
449 /* Triangles need closure. */
450 if( ! ptarray_is_closed_z(pa) )
451 {
452 ptarray_free(pa);
454 return NULL;
455 }
456
458}
459
461{
462 LWPOLY *poly = NULL;
463 LWDEBUG(4,"entered");
464
465 /* No pointarray is a problem */
466 if( ! pa )
467 {
469 return NULL;
470 }
471
473
474 /* Error out if we can't build this polygon. */
475 if( ! poly )
476 {
478 return NULL;
479 }
480
482 return lwpoly_as_lwgeom(poly);
483}
484
486{
487 LWDEBUG(4,"entered");
488
489 /* Bad inputs are a problem */
490 if( ! (pa && poly) )
491 {
493 return NULL;
494 }
495
496 /* Rings must agree on dimensionality */
497 if( FLAGS_NDIMS(poly->flags) != FLAGS_NDIMS(pa->flags) )
498 {
499 ptarray_free(pa);
500 lwgeom_free(poly);
502 return NULL;
503 }
504
505 /* Apply check for minimum number of points, if requested. */
507 {
508 ptarray_free(pa);
509 lwgeom_free(poly);
511 return NULL;
512 }
513
514 /* Apply check for not closed rings, if requested. */
516 ! (dimcheck == 'Z' ? ptarray_is_closed_z(pa) : ptarray_is_closed_2d(pa)) )
517 {
518 ptarray_free(pa);
519 lwgeom_free(poly);
521 return NULL;
522 }
523
524 /* If something goes wrong adding a ring, error out. */
525 if ( LW_FAILURE == lwpoly_add_ring(lwgeom_as_lwpoly(poly), pa) )
526 {
527 ptarray_free(pa);
528 lwgeom_free(poly);
530 return NULL;
531 }
532 return poly;
533}
534
535LWGEOM* wkt_parser_polygon_finalize(LWGEOM *poly, char *dimensionality)
536{
537 lwflags_t flags = wkt_dimensionality(dimensionality);
538 int flagdims = FLAGS_NDIMS(flags);
539 LWDEBUG(4,"entered");
540
541 /* Null input implies empty return */
542 if( ! poly )
544
545 /* If the number of dimensions are not consistent, we have a problem. */
546 if( flagdims > 2 )
547 {
548 if ( flagdims != FLAGS_NDIMS(poly->flags) )
549 {
550 lwgeom_free(poly);
552 return NULL;
553 }
554
555 /* Harmonize the flags in the sub-components with the wkt flags */
556 if( LW_FAILURE == wkt_parser_set_dims(poly, flags) )
557 {
558 lwgeom_free(poly);
560 return NULL;
561 }
562 }
563
564 return poly;
565}
566
568{
569 LWGEOM *poly;
570 LWDEBUG(4,"entered");
571
572 /* Toss error on null geometry input */
573 if( ! ring )
574 {
576 return NULL;
577 }
578
579 /* Construct poly and add the ring. */
581 /* Return the result. */
582 return wkt_parser_curvepolygon_add_ring(poly,ring);
583}
584
586{
587 LWDEBUG(4,"entered");
588
589 /* Toss error on null input */
590 if( ! (ring && poly) )
591 {
593 LWDEBUG(4,"inputs are null");
594 return NULL;
595 }
596
597 /* All the elements must agree on dimensionality */
598 if( FLAGS_NDIMS(poly->flags) != FLAGS_NDIMS(ring->flags) )
599 {
600 LWDEBUG(4,"dimensionality does not match");
601 lwgeom_free(ring);
602 lwgeom_free(poly);
604 return NULL;
605 }
606
607 /* Apply check for minimum number of points, if requested. */
609 {
610 uint32_t vertices_needed = 3;
611
612 if ( ring->type == LINETYPE )
613 vertices_needed = 4;
614
615 if (lwgeom_count_vertices(ring) < vertices_needed)
616 {
617 LWDEBUG(4,"number of points is incorrect");
618 lwgeom_free(ring);
619 lwgeom_free(poly);
621 return NULL;
622 }
623 }
624
625 /* Apply check for not closed rings, if requested. */
627 {
628 int is_closed = 1;
629 LWDEBUG(4,"checking ring closure");
630 switch ( ring->type )
631 {
632 case LINETYPE:
633 is_closed = lwline_is_closed(lwgeom_as_lwline(ring));
634 break;
635
636 case CIRCSTRINGTYPE:
638 break;
639
640 case COMPOUNDTYPE:
642 break;
643 }
644 if ( ! is_closed )
645 {
646 LWDEBUG(4,"ring is not closed");
647 lwgeom_free(ring);
648 lwgeom_free(poly);
650 return NULL;
651 }
652 }
653
655 {
656 LWDEBUG(4,"failed to add ring");
657 lwgeom_free(ring);
658 lwgeom_free(poly);
660 return NULL;
661 }
662
663 return poly;
664}
665
666LWGEOM* wkt_parser_curvepolygon_finalize(LWGEOM *poly, char *dimensionality)
667{
668 lwflags_t flags = wkt_dimensionality(dimensionality);
669 int flagdims = FLAGS_NDIMS(flags);
670 LWDEBUG(4,"entered");
671
672 /* Null input implies empty return */
673 if( ! poly )
675
676 if ( flagdims > 2 )
677 {
678 /* If the number of dimensions are not consistent, we have a problem. */
679 if( flagdims != FLAGS_NDIMS(poly->flags) )
680 {
681 lwgeom_free(poly);
683 return NULL;
684 }
685
686 /* Harmonize the flags in the sub-components with the wkt flags */
687 if( LW_FAILURE == wkt_parser_set_dims(poly, flags) )
688 {
689 lwgeom_free(poly);
691 return NULL;
692 }
693 }
694
695 return poly;
696}
697
699{
700 LWCOLLECTION *col;
701 LWGEOM **geoms;
702 static int ngeoms = 1;
703 LWDEBUG(4,"entered");
704
705 /* Toss error on null geometry input */
706 if( ! geom )
707 {
709 return NULL;
710 }
711
712 /* Create our geometry array */
713 geoms = lwalloc(sizeof(LWGEOM*) * ngeoms);
714 geoms[0] = geom;
715
716 /* Make a new collection */
717 col = lwcollection_construct(COLLECTIONTYPE, SRID_UNKNOWN, NULL, ngeoms, geoms);
718
719 /* Return the result. */
720 return lwcollection_as_lwgeom(col);
721}
722
723
725{
726 LWCOLLECTION *col;
727 LWGEOM **geoms;
728 static int ngeoms = 1;
729 LWDEBUG(4,"entered");
730
731 /* Toss error on null geometry input */
732 if( ! geom )
733 {
735 return NULL;
736 }
737
738 /* Elements of a compoundcurve cannot be empty, because */
739 /* empty things can't join up and form a ring */
740 if ( lwgeom_is_empty(geom) )
741 {
742 lwgeom_free(geom);
744 return NULL;
745 }
746
747 /* Create our geometry array */
748 geoms = lwalloc(sizeof(LWGEOM*) * ngeoms);
749 geoms[0] = geom;
750
751 /* Make a new collection */
752 col = lwcollection_construct(COLLECTIONTYPE, SRID_UNKNOWN, NULL, ngeoms, geoms);
753
754 /* Return the result. */
755 return lwcollection_as_lwgeom(col);
756}
757
758
760{
761 LWDEBUG(4,"entered");
762
763 /* Toss error on null geometry input */
764 if( ! (geom && col) )
765 {
767 return NULL;
768 }
769
770 /* All the elements must agree on dimensionality */
771 if( FLAGS_NDIMS(col->flags) != FLAGS_NDIMS(geom->flags) )
772 {
773 lwgeom_free(col);
774 lwgeom_free(geom);
776 return NULL;
777 }
778
779 if( LW_FAILURE == lwcompound_add_lwgeom((LWCOMPOUND*)col, geom) )
780 {
781 lwgeom_free(col);
782 lwgeom_free(geom);
784 return NULL;
785 }
786
787 return col;
788}
789
790
791LWGEOM* wkt_parser_compound_finalize(LWGEOM *compound, char *dimensionality)
792{
793 lwflags_t flags = wkt_dimensionality(dimensionality);
794 int flagdims = FLAGS_NDIMS(flags);
795
796 /* No geometry means it is empty */
797 if ( ! compound )
798 {
800 }
801
802 if ( flagdims > 2 )
803 {
804 /* If the number of dimensions are not consistent, we have a problem. */
805 if( flagdims != FLAGS_NDIMS(compound->flags) )
806 {
807 lwgeom_free(compound);
809 return NULL;
810 }
811
812 /* Harmonize the flags in the sub-components with the wkt flags */
813 if( LW_FAILURE == wkt_parser_set_dims(compound, flags) )
814 {
815 lwgeom_free(compound);
817 return NULL;
818 }
819 }
820 compound->type = COMPOUNDTYPE;
821 return compound;
822}
823
824
825
827{
828 LWDEBUG(4,"entered");
829
830 /* Toss error on null geometry input */
831 if( ! (geom && col) )
832 {
834 return NULL;
835 }
836
838}
839
840LWGEOM* wkt_parser_collection_finalize(int lwtype, LWGEOM *geom, char *dimensionality)
841{
842 lwflags_t flags = wkt_dimensionality(dimensionality);
843 int flagdims = FLAGS_NDIMS(flags);
844
845 /* No geometry means it is empty */
846 if( ! geom )
847 {
849 }
850
851 /* There are 'Z' or 'M' tokens in the signature */
852 if ( flagdims > 2 )
853 {
855 uint32_t i;
856
857 for ( i = 0 ; i < col->ngeoms; i++ )
858 {
859 LWGEOM *subgeom = col->geoms[i];
860 if ( FLAGS_NDIMS(flags) != FLAGS_NDIMS(subgeom->flags) &&
861 ! lwgeom_is_empty(subgeom) )
862 {
863 lwgeom_free(geom);
865 return NULL;
866 }
867
868 if ( lwtype == COLLECTIONTYPE &&
869 ( (FLAGS_GET_Z(flags) != FLAGS_GET_Z(subgeom->flags)) ||
870 (FLAGS_GET_M(flags) != FLAGS_GET_M(subgeom->flags)) ) &&
871 ! lwgeom_is_empty(subgeom) )
872 {
873 lwgeom_free(geom);
875 return NULL;
876 }
877 }
878
879 /* Harmonize the collection dimensionality */
880 if( LW_FAILURE == wkt_parser_set_dims(geom, flags) )
881 {
882 lwgeom_free(geom);
884 return NULL;
885 }
886 }
887
888 /* Set the collection type */
889 geom->type = lwtype;
890
891 return geom;
892}
893
894void
895wkt_parser_geometry_new(LWGEOM *geom, int32_t srid)
896{
897 LWDEBUG(4,"entered");
898 LWDEBUGF(4,"geom %p",geom);
899 LWDEBUGF(4,"srid %d",srid);
900
901 if ( geom == NULL )
902 {
903 lwerror("Parsed geometry is null!");
904 return;
905 }
906
907 if ( srid != SRID_UNKNOWN && srid <= SRID_MAXIMUM )
908 lwgeom_set_srid(geom, srid);
909 else
911
913}
914
916{
917 memset(parser_result, 0, sizeof(LWGEOM_PARSER_RESULT));
918}
919
920
922{
923 if ( parser_result->geom )
924 {
925 lwgeom_free(parser_result->geom);
926 parser_result->geom = 0;
927 }
928 if ( parser_result->serialized_lwgeom )
929 {
930 lwfree(parser_result->serialized_lwgeom );
931 parser_result->serialized_lwgeom = 0;
932 }
933 /* We don't free parser_result->message because
934 it is a const *char */
935}
936
937/*
938* Public function used for easy access to the parser.
939*/
940LWGEOM *lwgeom_from_wkt(const char *wkt, const char check)
941{
943
944 if( LW_FAILURE == lwgeom_parse_wkt(&r, (char*)wkt, check) )
945 {
946 lwerror("%s", r.message);
947 return NULL;
948 }
949
950 return r.geom;
951}
952
953
char * r
Definition cu_in_wkt.c:24
#define LW_PARSER_CHECK_ODD
Definition liblwgeom.h:2145
#define PARSER_ERROR_MIXDIMS
Definition liblwgeom.h:2175
LWCOLLECTION * lwcollection_construct(uint8_t type, int32_t srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
Definition lwgeom.c:372
#define LW_FALSE
Definition liblwgeom.h:94
#define COLLECTIONTYPE
Definition liblwgeom.h:108
#define COMPOUNDTYPE
Definition liblwgeom.h:110
void lwgeom_set_srid(LWGEOM *geom, int32_t srid)
Set the SRID on an LWGEOM For collections, only the parent gets an SRID, all the children get SRID_UN...
Definition lwgeom.c:1638
#define LW_PARSER_CHECK_CLOSURE
Definition liblwgeom.h:2146
#define LW_FAILURE
Definition liblwgeom.h:96
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1246
#define CURVEPOLYTYPE
Definition liblwgeom.h:111
LWCURVEPOLY * lwcurvepoly_construct_empty(int32_t srid, char hasz, char hasm)
Definition lwcurvepoly.c:35
#define LINETYPE
Definition liblwgeom.h:103
LWCOLLECTION * lwgeom_as_lwcollection(const LWGEOM *lwgeom)
Definition lwgeom.c:261
#define PARSER_ERROR_MOREPOINTS
Definition liblwgeom.h:2172
#define PARSER_ERROR_INCONTINUOUS
Definition liblwgeom.h:2178
LWGEOM * lwcompound_as_lwgeom(const LWCOMPOUND *obj)
Definition lwgeom.c:352
#define LW_SUCCESS
Definition liblwgeom.h:97
LWPOINT * lwpoint_construct(int32_t srid, GBOX *bbox, POINTARRAY *point)
Definition lwpoint.c:129
uint16_t lwflags_t
Definition liblwgeom.h:299
int lwgeom_parse_wkt(LWGEOM_PARSER_RESULT *parser_result, char *wktstr, int parse_flags)
Parse a WKT geometry string into an LWGEOM structure.
int lwpoly_add_ring(LWPOLY *poly, POINTARRAY *pa)
Add a ring, allocating extra space if necessary.
Definition lwpoly.c:247
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition ptarray.c:59
#define PARSER_ERROR_OTHER
Definition liblwgeom.h:2181
LWCURVEPOLY * lwgeom_as_lwcurvepoly(const LWGEOM *lwgeom)
Definition lwgeom.c:234
LWTRIANGLE * lwtriangle_construct_empty(int32_t srid, char hasz, char hasm)
Definition lwtriangle.c:58
int lwtype_is_collection(uint8_t type)
Determine whether a type number is a collection or not.
Definition lwgeom.c:1196
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition liblwgeom.h:102
#define FLAGS_GET_Z(flags)
Definition liblwgeom.h:165
#define SRID_MAXIMUM
Maximum allowed SRID value in serialized geometry.
Definition liblwgeom.h:206
void * lwalloc(size_t size)
Definition lwutil.c:227
LWPOLY * lwgeom_as_lwpoly(const LWGEOM *lwgeom)
Definition lwgeom.c:243
LWLINE * lwline_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
Definition lwline.c:42
uint32_t lwgeom_count_vertices(const LWGEOM *geom)
Count the total number of vertices in any LWGEOM.
Definition lwgeom.c:1337
LWGEOM * lwcurvepoly_as_lwgeom(const LWCURVEPOLY *obj)
Definition lwgeom.c:347
void lwfree(void *mem)
Definition lwutil.c:248
#define FLAGS_NDIMS(flags)
Definition liblwgeom.h:179
#define PARSER_ERROR_ODDPOINTS
Definition liblwgeom.h:2173
LWCOMPOUND * lwgeom_as_lwcompound(const LWGEOM *lwgeom)
Definition lwgeom.c:225
LWGEOM * lwtriangle_as_lwgeom(const LWTRIANGLE *obj)
Definition lwgeom.c:362
#define POLYGONTYPE
Definition liblwgeom.h:104
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition lwgeom.c:367
LWCIRCSTRING * lwgeom_as_lwcircstring(const LWGEOM *lwgeom)
Definition lwgeom.c:216
int lwcurvepoly_add_ring(LWCURVEPOLY *poly, LWGEOM *ring)
Add a ring, allocating extra space if necessary.
Definition lwcurvepoly.c:71
#define CIRCSTRINGTYPE
Definition liblwgeom.h:109
int ptarray_is_closed_z(const POINTARRAY *pa)
Definition ptarray.c:736
LWPOINT * lwpoint_construct_empty(int32_t srid, char hasz, char hasm)
Definition lwpoint.c:151
LWCOMPOUND * lwcompound_construct_empty(int32_t srid, char hasz, char hasm)
Definition lwcompound.c:166
#define FLAGS_GET_M(flags)
Definition liblwgeom.h:166
#define PARSER_ERROR_LESSPOINTS
Definition liblwgeom.h:2180
#define LW_PARSER_CHECK_MINPOINTS
Parser check flags.
Definition liblwgeom.h:2144
void ptarray_free(POINTARRAY *pa)
Definition ptarray.c:327
LWGEOM * lwcircstring_as_lwgeom(const LWCIRCSTRING *obj)
Definition lwgeom.c:342
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition lwgeom.c:207
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
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 TRIANGLETYPE
Definition liblwgeom.h:115
LWCIRCSTRING * lwcircstring_construct_empty(int32_t srid, char hasz, char hasm)
int lwcompound_add_lwgeom(LWCOMPOUND *comp, LWGEOM *geom)
Add a component, allocating extra space if necessary.
Definition lwcompound.c:131
int ptarray_is_closed_2d(const POINTARRAY *pa)
Definition ptarray.c:710
#define PARSER_ERROR_TRIANGLEPOINTS
Definition liblwgeom.h:2179
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:93
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
#define FLAGS_SET_M(flags, value)
Definition liblwgeom.h:173
LWPOLY * lwpoly_construct_empty(int32_t srid, char hasz, char hasm)
Definition lwpoly.c:161
#define SRID_UNKNOWN
Unknown SRID value.
Definition liblwgeom.h:215
LWLINE * lwline_construct_empty(int32_t srid, char hasz, char hasm)
Definition lwline.c:55
#define FLAGS_SET_Z(flags, value)
Definition liblwgeom.h:172
#define PARSER_ERROR_UNCLOSED
Definition liblwgeom.h:2174
LWCIRCSTRING * lwcircstring_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition lwgeom.c:357
LWTRIANGLE * lwtriangle_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
Definition lwtriangle.c:40
int32_t clamp_srid(int32_t srid)
Return a valid SRID from an arbitrary integer Raises a notice if what comes out is different from wha...
Definition lwutil.c:339
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
Definition lwgeom.c:337
int lwcircstring_is_closed(const LWCIRCSTRING *curve)
int lwline_is_closed(const LWLINE *line)
Definition lwline.c:455
int lwcompound_is_closed(const LWCOMPOUND *curve)
Definition lwcompound.c:48
#define str(s)
#define LWDEBUG(level, msg)
Definition lwgeom_log.h:101
#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.
LWGEOM * wkt_parser_compound_finalize(LWGEOM *compound, char *dimensionality)
Definition lwin_wkt.c:791
static int wkt_pointarray_dimensionality(POINTARRAY *pa, lwflags_t flags)
Read the dimensionality from a flag, if provided.
Definition lwin_wkt.c:183
POINTARRAY * wkt_parser_ptarray_add_coord(POINTARRAY *pa, POINT p)
Definition lwin_wkt.c:265
#define SET_PARSER_ERROR(errno)
Definition lwin_wkt.c:52
LWGEOM * wkt_parser_polygon_add_ring(LWGEOM *poly, POINTARRAY *pa, char dimcheck)
Definition lwin_wkt.c:485
LWGEOM * wkt_parser_curvepolygon_finalize(LWGEOM *poly, char *dimensionality)
Definition lwin_wkt.c:666
LWGEOM * wkt_parser_collection_finalize(int lwtype, LWGEOM *geom, char *dimensionality)
Definition lwin_wkt.c:840
LWGEOM * wkt_parser_collection_add_geom(LWGEOM *col, LWGEOM *geom)
Definition lwin_wkt.c:826
void lwgeom_parser_result_init(LWGEOM_PARSER_RESULT *parser_result)
Definition lwin_wkt.c:915
LWGEOM * wkt_parser_triangle_new(POINTARRAY *pa, char *dimensionality)
Definition lwin_wkt.c:424
POINTARRAY * wkt_parser_ptarray_new(POINT p)
Start a point array from the first coordinate.
Definition lwin_wkt.c:303
POINT wkt_parser_coord_2(double c1, double c2)
Build a 2d coordinate.
Definition lwin_wkt.c:221
POINT wkt_parser_coord_4(double c1, double c2, double c3, double c4)
Definition lwin_wkt.c:252
const char * parser_error_messages[]
Definition lwin_wkt.c:37
static int wkt_parser_set_dims(LWGEOM *geom, lwflags_t flags)
Force the dimensionality of a geometry to match the dimensionality of a set of flags (usually derived...
Definition lwin_wkt.c:101
LWGEOM * wkt_parser_compound_new(LWGEOM *geom)
Definition lwin_wkt.c:724
LWGEOM * wkt_parser_polygon_finalize(LWGEOM *poly, char *dimensionality)
Definition lwin_wkt.c:535
LWGEOM * wkt_parser_compound_add_geom(LWGEOM *col, LWGEOM *geom)
Definition lwin_wkt.c:759
LWGEOM * wkt_parser_circularstring_new(POINTARRAY *pa, char *dimensionality)
Create a new circularstring.
Definition lwin_wkt.c:388
int wkt_lexer_read_srid(char *str)
Read the SRID number from an SRID=<> string.
Definition lwin_wkt.c:61
POINT wkt_parser_coord_3(double c1, double c2, double c3)
Note, if this is an XYM coordinate we'll have to fix it later when we build the object itself and hav...
Definition lwin_wkt.c:237
LWGEOM * wkt_parser_curvepolygon_add_ring(LWGEOM *poly, LWGEOM *ring)
Definition lwin_wkt.c:585
LWGEOM * wkt_parser_collection_new(LWGEOM *geom)
Definition lwin_wkt.c:698
static lwflags_t wkt_dimensionality(char *dimensionality)
Definition lwin_wkt.c:75
LWGEOM * wkt_parser_curvepolygon_new(LWGEOM *ring)
Definition lwin_wkt.c:567
LWGEOM * wkt_parser_linestring_new(POINTARRAY *pa, char *dimensionality)
Create a new linestring.
Definition lwin_wkt.c:354
LWGEOM * wkt_parser_point_new(POINTARRAY *pa, char *dimensionality)
Create a new point.
Definition lwin_wkt.c:320
LWGEOM * lwgeom_from_wkt(const char *wkt, const char check)
Definition lwin_wkt.c:940
LWGEOM * wkt_parser_polygon_new(POINTARRAY *pa, char dimcheck)
Definition lwin_wkt.c:460
void lwgeom_parser_result_free(LWGEOM_PARSER_RESULT *parser_result)
Definition lwin_wkt.c:921
void wkt_parser_geometry_new(LWGEOM *geom, int32_t srid)
Definition lwin_wkt.c:895
LWGEOM_PARSER_RESULT global_parser_result
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
Definition lwinline.h:199
uint32_t ngeoms
Definition liblwgeom.h:580
LWGEOM ** geoms
Definition liblwgeom.h:575
LWGEOM ** rings
Definition liblwgeom.h:603
uint32_t nrings
Definition liblwgeom.h:608
uint8_t type
Definition liblwgeom.h:462
lwflags_t flags
Definition liblwgeom.h:461
POINTARRAY * points
Definition liblwgeom.h:483
POINTARRAY * point
Definition liblwgeom.h:471
POINTARRAY ** rings
Definition liblwgeom.h:519
uint32_t nrings
Definition liblwgeom.h:524
double m
Definition liblwgeom.h:414
double x
Definition liblwgeom.h:414
double z
Definition liblwgeom.h:414
double y
Definition liblwgeom.h:414
lwflags_t flags
Definition liblwgeom.h:431
uint32_t npoints
Definition liblwgeom.h:427
double y
Definition lwin_wkt.h:36
double m
Definition lwin_wkt.h:38
lwflags_t flags
Definition lwin_wkt.h:34
double z
Definition lwin_wkt.h:37
double x
Definition lwin_wkt.h:35
Parser result structure: returns the result of attempting to convert (E)WKT/(E)WKB to LWGEOM.
Definition liblwgeom.h:2157