PostGIS  2.1.10dev-r@@SVN_REVISION@@
lwgeom.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * http://postgis.net
5  *
6  * Copyright (C) 2001-2006 Refractions Research Inc.
7  *
8  * This is free software; you can redistribute and/or modify it under
9  * the terms of the GNU General Public Licence. See the COPYING file.
10  *
11  **********************************************************************/
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <stdarg.h>
16 
17 #include "liblwgeom_internal.h"
18 #include "lwgeom_log.h"
19 
20 
22 void
24 {
25  LWCOLLECTION *coll;
26  int i;
27 
28  switch (lwgeom->type)
29  {
30  case POLYGONTYPE:
31  lwpoly_force_clockwise((LWPOLY *)lwgeom);
32  return;
33 
34  case TRIANGLETYPE:
36  return;
37 
38  /* Not handle POLYHEDRALSURFACE and TIN
39  as they are supposed to be well oriented */
40  case MULTIPOLYGONTYPE:
41  case COLLECTIONTYPE:
42  coll = (LWCOLLECTION *)lwgeom;
43  for (i=0; i<coll->ngeoms; i++)
44  lwgeom_force_clockwise(coll->geoms[i]);
45  return;
46  }
47 }
48 
50 void
52 {
53  int i;
54  LWCOLLECTION *col;
55 
56  switch (lwgeom->type)
57  {
58  case LINETYPE:
59  lwline_reverse((LWLINE *)lwgeom);
60  return;
61  case POLYGONTYPE:
62  lwpoly_reverse((LWPOLY *)lwgeom);
63  return;
64  case TRIANGLETYPE:
65  lwtriangle_reverse((LWTRIANGLE *)lwgeom);
66  return;
67  case MULTILINETYPE:
68  case MULTIPOLYGONTYPE:
70  case TINTYPE:
71  case COLLECTIONTYPE:
72  col = (LWCOLLECTION *)lwgeom;
73  for (i=0; i<col->ngeoms; i++)
74  lwgeom_reverse(col->geoms[i]);
75  return;
76  }
77 }
78 
79 LWPOINT *
80 lwgeom_as_lwpoint(const LWGEOM *lwgeom)
81 {
82  if ( lwgeom == NULL ) return NULL;
83  if ( lwgeom->type == POINTTYPE )
84  return (LWPOINT *)lwgeom;
85  else return NULL;
86 }
87 
88 LWLINE *
89 lwgeom_as_lwline(const LWGEOM *lwgeom)
90 {
91  if ( lwgeom == NULL ) return NULL;
92  if ( lwgeom->type == LINETYPE )
93  return (LWLINE *)lwgeom;
94  else return NULL;
95 }
96 
99 {
100  if ( lwgeom == NULL ) return NULL;
101  if ( lwgeom->type == CIRCSTRINGTYPE )
102  return (LWCIRCSTRING *)lwgeom;
103  else return NULL;
104 }
105 
106 LWCOMPOUND *
108 {
109  if ( lwgeom == NULL ) return NULL;
110  if ( lwgeom->type == COMPOUNDTYPE )
111  return (LWCOMPOUND *)lwgeom;
112  else return NULL;
113 }
114 
115 LWCURVEPOLY *
117 {
118  if ( lwgeom == NULL ) return NULL;
119  if ( lwgeom->type == CURVEPOLYTYPE )
120  return (LWCURVEPOLY *)lwgeom;
121  else return NULL;
122 }
123 
124 LWPOLY *
125 lwgeom_as_lwpoly(const LWGEOM *lwgeom)
126 {
127  if ( lwgeom == NULL ) return NULL;
128  if ( lwgeom->type == POLYGONTYPE )
129  return (LWPOLY *)lwgeom;
130  else return NULL;
131 }
132 
133 LWTRIANGLE *
135 {
136  if ( lwgeom == NULL ) return NULL;
137  if ( lwgeom->type == TRIANGLETYPE )
138  return (LWTRIANGLE *)lwgeom;
139  else return NULL;
140 }
141 
142 LWCOLLECTION *
144 {
145  if ( lwgeom == NULL ) return NULL;
146  if ( lwgeom_is_collection(lwgeom) )
147  return (LWCOLLECTION*)lwgeom;
148  else return NULL;
149 }
150 
151 LWMPOINT *
153 {
154  if ( lwgeom == NULL ) return NULL;
155  if ( lwgeom->type == MULTIPOINTTYPE )
156  return (LWMPOINT *)lwgeom;
157  else return NULL;
158 }
159 
160 LWMLINE *
161 lwgeom_as_lwmline(const LWGEOM *lwgeom)
162 {
163  if ( lwgeom == NULL ) return NULL;
164  if ( lwgeom->type == MULTILINETYPE )
165  return (LWMLINE *)lwgeom;
166  else return NULL;
167 }
168 
169 LWMPOLY *
170 lwgeom_as_lwmpoly(const LWGEOM *lwgeom)
171 {
172  if ( lwgeom == NULL ) return NULL;
173  if ( lwgeom->type == MULTIPOLYGONTYPE )
174  return (LWMPOLY *)lwgeom;
175  else return NULL;
176 }
177 
178 LWPSURFACE *
180 {
181  if ( lwgeom->type == POLYHEDRALSURFACETYPE )
182  return (LWPSURFACE *)lwgeom;
183  else return NULL;
184 }
185 
186 LWTIN *
187 lwgeom_as_lwtin(const LWGEOM *lwgeom)
188 {
189  if ( lwgeom->type == TINTYPE )
190  return (LWTIN *)lwgeom;
191  else return NULL;
192 }
193 
195 {
196  return (LWGEOM *)obj;
197 }
198 
200 {
201  return (LWGEOM *)obj;
202 }
203 
205 {
206  if ( obj == NULL ) return NULL;
207  return (LWGEOM *)obj;
208 }
210 {
211  if ( obj == NULL ) return NULL;
212  return (LWGEOM *)obj;
213 }
215 {
216  if ( obj == NULL ) return NULL;
217  return (LWGEOM *)obj;
218 }
220 {
221  if ( obj == NULL ) return NULL;
222  return (LWGEOM *)obj;
223 }
225 {
226  if ( obj == NULL ) return NULL;
227  return (LWGEOM *)obj;
228 }
230 {
231  if ( obj == NULL ) return NULL;
232  return (LWGEOM *)obj;
233 }
235 {
236  if ( obj == NULL ) return NULL;
237  return (LWGEOM *)obj;
238 }
240 {
241  if ( obj == NULL ) return NULL;
242  return (LWGEOM *)obj;
243 }
245 {
246  if ( obj == NULL ) return NULL;
247  return (LWGEOM *)obj;
248 }
250 {
251  if ( obj == NULL ) return NULL;
252  return (LWGEOM *)obj;
253 }
255 {
256  if ( obj == NULL ) return NULL;
257  return (LWGEOM *)obj;
258 }
259 
260 
264 uint8_t MULTITYPE[NUMTYPES] =
265 {
266  0,
267  MULTIPOINTTYPE, /* 1 */
268  MULTILINETYPE, /* 2 */
269  MULTIPOLYGONTYPE, /* 3 */
270  0,0,0,0,
271  MULTICURVETYPE, /* 8 */
272  MULTICURVETYPE, /* 9 */
273  MULTISURFACETYPE, /* 10 */
274  POLYHEDRALSURFACETYPE, /* 11 */
275  0, 0,
276  TINTYPE, /* 14 */
277  0
278 };
279 
283 LWGEOM *
284 lwgeom_as_multi(const LWGEOM *lwgeom)
285 {
286  LWGEOM **ogeoms;
287  LWGEOM *ogeom = NULL;
288  GBOX *box = NULL;
289  int type;
290 
291  type = lwgeom->type;
292 
293  if ( ! MULTITYPE[type] ) return lwgeom_clone(lwgeom);
294 
295  if( lwgeom_is_empty(lwgeom) )
296  {
298  MULTITYPE[type],
299  lwgeom->srid,
300  FLAGS_GET_Z(lwgeom->flags),
301  FLAGS_GET_M(lwgeom->flags)
302  );
303  }
304  else
305  {
306  ogeoms = lwalloc(sizeof(LWGEOM*));
307  ogeoms[0] = lwgeom_clone(lwgeom);
308 
309  /* Sub-geometries are not allowed to have bboxes or SRIDs, move the bbox to the collection */
310  box = ogeoms[0]->bbox;
311  ogeoms[0]->bbox = NULL;
312  ogeoms[0]->srid = SRID_UNKNOWN;
313 
314  ogeom = (LWGEOM *)lwcollection_construct(MULTITYPE[type], lwgeom->srid, box, 1, ogeoms);
315  }
316 
317  return ogeom;
318 }
319 
320 
327 void
329 {
330  if ( ! lwgeom )
331  lwerror("lwgeom_release: someone called on 0x0");
332 
333  LWDEBUGF(3, "releasing type %s", lwtype_name(lwgeom->type));
334 
335  /* Drop bounding box (always a copy) */
336  if ( lwgeom->bbox )
337  {
338  LWDEBUGF(3, "lwgeom_release: releasing bbox. %p", lwgeom->bbox);
339  lwfree(lwgeom->bbox);
340  }
341  lwfree(lwgeom);
342 
343 }
344 
345 
346 /* @brief Clone LWGEOM object. Serialized point lists are not copied.
347  *
348  * @see ptarray_clone
349  */
350 LWGEOM *
351 lwgeom_clone(const LWGEOM *lwgeom)
352 {
353  LWDEBUGF(2, "lwgeom_clone called with %p, %s",
354  lwgeom, lwtype_name(lwgeom->type));
355 
356  switch (lwgeom->type)
357  {
358  case POINTTYPE:
359  return (LWGEOM *)lwpoint_clone((LWPOINT *)lwgeom);
360  case LINETYPE:
361  return (LWGEOM *)lwline_clone((LWLINE *)lwgeom);
362  case CIRCSTRINGTYPE:
363  return (LWGEOM *)lwcircstring_clone((LWCIRCSTRING *)lwgeom);
364  case POLYGONTYPE:
365  return (LWGEOM *)lwpoly_clone((LWPOLY *)lwgeom);
366  case TRIANGLETYPE:
367  return (LWGEOM *)lwtriangle_clone((LWTRIANGLE *)lwgeom);
368  case COMPOUNDTYPE:
369  case CURVEPOLYTYPE:
370  case MULTICURVETYPE:
371  case MULTISURFACETYPE:
372  case MULTIPOINTTYPE:
373  case MULTILINETYPE:
374  case MULTIPOLYGONTYPE:
376  case TINTYPE:
377  case COLLECTIONTYPE:
378  return (LWGEOM *)lwcollection_clone((LWCOLLECTION *)lwgeom);
379  default:
380  lwerror("lwgeom_clone: Unknown geometry type: %s", lwtype_name(lwgeom->type));
381  return NULL;
382  }
383 }
384 
388 LWGEOM *
389 lwgeom_clone_deep(const LWGEOM *lwgeom)
390 {
391  LWDEBUGF(2, "lwgeom_clone called with %p, %s",
392  lwgeom, lwtype_name(lwgeom->type));
393 
394  switch (lwgeom->type)
395  {
396  case POINTTYPE:
397  case LINETYPE:
398  case CIRCSTRINGTYPE:
399  case TRIANGLETYPE:
400  return (LWGEOM *)lwline_clone_deep((LWLINE *)lwgeom);
401  case POLYGONTYPE:
402  return (LWGEOM *)lwpoly_clone_deep((LWPOLY *)lwgeom);
403  case COMPOUNDTYPE:
404  case CURVEPOLYTYPE:
405  case MULTICURVETYPE:
406  case MULTISURFACETYPE:
407  case MULTIPOINTTYPE:
408  case MULTILINETYPE:
409  case MULTIPOLYGONTYPE:
411  case TINTYPE:
412  case COLLECTIONTYPE:
413  return (LWGEOM *)lwcollection_clone_deep((LWCOLLECTION *)lwgeom);
414  default:
415  lwerror("lwgeom_clone_deep: Unknown geometry type: %s", lwtype_name(lwgeom->type));
416  return NULL;
417  }
418 }
419 
420 
424 char*
425 lwgeom_to_ewkt(const LWGEOM *lwgeom)
426 {
427  char* wkt = NULL;
428  size_t wkt_size = 0;
429 
430  wkt = lwgeom_to_wkt(lwgeom, WKT_EXTENDED, 12, &wkt_size);
431 
432  if ( ! wkt )
433  {
434  lwerror("Error writing geom %p to WKT", lwgeom);
435  }
436 
437  return wkt;
438 }
439 
450 char
451 lwgeom_same(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2)
452 {
453  LWDEBUGF(2, "lwgeom_same(%s, %s) called",
454  lwtype_name(lwgeom1->type),
455  lwtype_name(lwgeom2->type));
456 
457  if ( lwgeom1->type != lwgeom2->type )
458  {
459  LWDEBUG(3, " type differ");
460 
461  return LW_FALSE;
462  }
463 
464  if ( FLAGS_GET_ZM(lwgeom1->flags) != FLAGS_GET_ZM(lwgeom2->flags) )
465  {
466  LWDEBUG(3, " ZM flags differ");
467 
468  return LW_FALSE;
469  }
470 
471  /* Check boxes if both already computed */
472  if ( lwgeom1->bbox && lwgeom2->bbox )
473  {
474  /*lwnotice("bbox1:%p, bbox2:%p", lwgeom1->bbox, lwgeom2->bbox);*/
475  if ( ! gbox_same(lwgeom1->bbox, lwgeom2->bbox) )
476  {
477  LWDEBUG(3, " bounding boxes differ");
478 
479  return LW_FALSE;
480  }
481  }
482 
483  /* geoms have same type, invoke type-specific function */
484  switch (lwgeom1->type)
485  {
486  case POINTTYPE:
487  return lwpoint_same((LWPOINT *)lwgeom1,
488  (LWPOINT *)lwgeom2);
489  case LINETYPE:
490  return lwline_same((LWLINE *)lwgeom1,
491  (LWLINE *)lwgeom2);
492  case POLYGONTYPE:
493  return lwpoly_same((LWPOLY *)lwgeom1,
494  (LWPOLY *)lwgeom2);
495  case TRIANGLETYPE:
496  return lwtriangle_same((LWTRIANGLE *)lwgeom1,
497  (LWTRIANGLE *)lwgeom2);
498  case CIRCSTRINGTYPE:
499  return lwcircstring_same((LWCIRCSTRING *)lwgeom1,
500  (LWCIRCSTRING *)lwgeom2);
501  case MULTIPOINTTYPE:
502  case MULTILINETYPE:
503  case MULTIPOLYGONTYPE:
504  case MULTICURVETYPE:
505  case MULTISURFACETYPE:
506  case COMPOUNDTYPE:
507  case CURVEPOLYTYPE:
509  case TINTYPE:
510  case COLLECTIONTYPE:
511  return lwcollection_same((LWCOLLECTION *)lwgeom1,
512  (LWCOLLECTION *)lwgeom2);
513  default:
514  lwerror("lwgeom_same: unsupported geometry type: %s",
515  lwtype_name(lwgeom1->type));
516  return LW_FALSE;
517  }
518 
519 }
520 
521 int
522 lwpoint_inside_circle(const LWPOINT *p, double cx, double cy, double rad)
523 {
524  POINT2D center;
525  POINT2D pt;
526 
527  if ( ! p || ! p->point )
528  return LW_FALSE;
529 
530  getPoint2d_p(p->point, 0, &pt);
531 
532  center.x = cx;
533  center.y = cy;
534 
535  if ( distance2d_pt_pt(&pt, &center) < rad )
536  return LW_TRUE;
537 
538  return LW_FALSE;
539 }
540 
541 void
543 {
544  if ( lwgeom->bbox ) lwfree(lwgeom->bbox);
545  lwgeom->bbox = NULL;
546  FLAGS_SET_BBOX(lwgeom->flags, 0);
547 }
548 
554 void
556 {
557  /* an empty LWGEOM has no bbox */
558  if ( lwgeom_is_empty(lwgeom) ) return;
559 
560  if ( lwgeom->bbox ) return;
561  FLAGS_SET_BBOX(lwgeom->flags, 1);
562  lwgeom->bbox = gbox_new(lwgeom->flags);
563  lwgeom_calculate_gbox(lwgeom, lwgeom->bbox);
564 }
565 
566 void
568 {
569  if ( lwgeom_is_empty(lwgeom) ) return;
570 
571  FLAGS_SET_BBOX(lwgeom->flags, 1);
572 
573  if ( ! ( gbox || lwgeom->bbox ) )
574  {
575  lwgeom->bbox = gbox_new(lwgeom->flags);
576  lwgeom_calculate_gbox(lwgeom, lwgeom->bbox);
577  }
578  else if ( gbox && ! lwgeom->bbox )
579  {
580  lwgeom->bbox = gbox_clone(gbox);
581  }
582 
583  if ( lwgeom_is_collection(lwgeom) )
584  {
585  int i;
586  LWCOLLECTION *lwcol = (LWCOLLECTION*)lwgeom;
587 
588  for ( i = 0; i < lwcol->ngeoms; i++ )
589  {
590  lwgeom_add_bbox_deep(lwcol->geoms[i], lwgeom->bbox);
591  }
592  }
593 }
594 
595 const GBOX *
597 {
598  /* add it if not already there */
599  lwgeom_add_bbox((LWGEOM *)lwg);
600  return lwg->bbox;
601 }
602 
603 
608 int lwgeom_calculate_gbox(const LWGEOM *lwgeom, GBOX *gbox)
609 {
610  gbox->flags = lwgeom->flags;
611  if( FLAGS_GET_GEODETIC(lwgeom->flags) )
612  return lwgeom_calculate_gbox_geodetic(lwgeom, gbox);
613  else
614  return lwgeom_calculate_gbox_cartesian(lwgeom, gbox);
615 }
616 
617 void
619 {
620  lwgeom->srid = SRID_UNKNOWN; /* TODO: To be changed to SRID_UNKNOWN */
621 }
622 
623 LWGEOM *
624 lwgeom_segmentize2d(LWGEOM *lwgeom, double dist)
625 {
626  switch (lwgeom->type)
627  {
628  case LINETYPE:
629  return (LWGEOM *)lwline_segmentize2d((LWLINE *)lwgeom,
630  dist);
631  case POLYGONTYPE:
632  return (LWGEOM *)lwpoly_segmentize2d((LWPOLY *)lwgeom,
633  dist);
634  case MULTILINETYPE:
635  case MULTIPOLYGONTYPE:
636  case COLLECTIONTYPE:
638  (LWCOLLECTION *)lwgeom, dist);
639 
640  default:
641  return lwgeom_clone(lwgeom);
642  }
643 }
644 
645 LWGEOM*
647 {
648  return lwgeom_force_dims(geom, 0, 0);
649 }
650 
651 LWGEOM*
653 {
654  return lwgeom_force_dims(geom, 1, 0);
655 }
656 
657 LWGEOM*
659 {
660  return lwgeom_force_dims(geom, 0, 1);
661 }
662 
663 LWGEOM*
665 {
666  return lwgeom_force_dims(geom, 1, 1);
667 }
668 
669 LWGEOM*
670 lwgeom_force_dims(const LWGEOM *geom, int hasz, int hasm)
671 {
672  switch(geom->type)
673  {
674  case POINTTYPE:
675  return lwpoint_as_lwgeom(lwpoint_force_dims((LWPOINT*)geom, hasz, hasm));
676  case CIRCSTRINGTYPE:
677  case LINETYPE:
678  case TRIANGLETYPE:
679  return lwline_as_lwgeom(lwline_force_dims((LWLINE*)geom, hasz, hasm));
680  case POLYGONTYPE:
681  return lwpoly_as_lwgeom(lwpoly_force_dims((LWPOLY*)geom, hasz, hasm));
682  case COMPOUNDTYPE:
683  case CURVEPOLYTYPE:
684  case MULTICURVETYPE:
685  case MULTISURFACETYPE:
686  case MULTIPOINTTYPE:
687  case MULTILINETYPE:
688  case MULTIPOLYGONTYPE:
690  case TINTYPE:
691  case COLLECTIONTYPE:
692  return lwcollection_as_lwgeom(lwcollection_force_dims((LWCOLLECTION*)geom, hasz, hasm));
693  default:
694  lwerror("lwgeom_force_2d: unsupported geom type: %s", lwtype_name(geom->type));
695  return NULL;
696  }
697 }
698 
699 LWGEOM*
700 lwgeom_force_sfs(LWGEOM *geom, int version)
701 {
702  LWCOLLECTION *col;
703  int i;
704  LWGEOM *g;
705 
706  /* SFS 1.2 version */
707  if (version == 120)
708  {
709  switch(geom->type)
710  {
711  /* SQL/MM types */
712  case CIRCSTRINGTYPE:
713  case COMPOUNDTYPE:
714  case CURVEPOLYTYPE:
715  case MULTICURVETYPE:
716  case MULTISURFACETYPE:
717  return lwgeom_segmentize(geom, 32);
718 
719  case COLLECTIONTYPE:
720  col = (LWCOLLECTION*)geom;
721  for ( i = 0; i < col->ngeoms; i++ )
722  col->geoms[i] = lwgeom_force_sfs((LWGEOM*)col->geoms[i], version);
723 
724  return lwcollection_as_lwgeom((LWCOLLECTION*)geom);
725 
726  default:
727  return (LWGEOM *)geom;
728  }
729  }
730 
731 
732  /* SFS 1.1 version */
733  switch(geom->type)
734  {
735  /* SQL/MM types */
736  case CIRCSTRINGTYPE:
737  case COMPOUNDTYPE:
738  case CURVEPOLYTYPE:
739  case MULTICURVETYPE:
740  case MULTISURFACETYPE:
741  return lwgeom_segmentize(geom, 32);
742 
743  /* SFS 1.2 types */
744  case TRIANGLETYPE:
745  g = lwpoly_as_lwgeom(lwpoly_from_lwlines((LWLINE*)geom, 0, NULL));
746  lwgeom_free(geom);
747  return g;
748 
749  case TINTYPE:
750  col = (LWCOLLECTION*) geom;
751  for ( i = 0; i < col->ngeoms; i++ )
752  {
753  g = lwpoly_as_lwgeom(lwpoly_from_lwlines((LWLINE*)col->geoms[i], 0, NULL));
754  lwgeom_free(col->geoms[i]);
755  col->geoms[i] = g;
756  }
757  col->type = COLLECTIONTYPE;
758  return lwmpoly_as_lwgeom((LWMPOLY*)geom);
759 
761  geom->type = COLLECTIONTYPE;
762  return (LWGEOM *)geom;
763 
764  /* Collection */
765  case COLLECTIONTYPE:
766  col = (LWCOLLECTION*)geom;
767  for ( i = 0; i < col->ngeoms; i++ )
768  col->geoms[i] = lwgeom_force_sfs((LWGEOM*)col->geoms[i], version);
769 
770  return lwcollection_as_lwgeom((LWCOLLECTION*)geom);
771 
772  default:
773  return (LWGEOM *)geom;
774  }
775 }
776 
777 int32_t
779 {
780  if ( ! geom ) return SRID_UNKNOWN;
781  return geom->srid;
782 }
783 
784 uint32_t
786 {
787  if ( ! geom ) return 0;
788  return geom->type;
789 }
790 
791 int
792 lwgeom_has_z(const LWGEOM *geom)
793 {
794  if ( ! geom ) return LW_FALSE;
795  return FLAGS_GET_Z(geom->flags);
796 }
797 
798 int
799 lwgeom_has_m(const LWGEOM *geom)
800 {
801  if ( ! geom ) return LW_FALSE;
802  return FLAGS_GET_M(geom->flags);
803 }
804 
805 int
806 lwgeom_ndims(const LWGEOM *geom)
807 {
808  if ( ! geom ) return 0;
809  return FLAGS_NDIMS(geom->flags);
810 }
811 
812 
813 void
815 {
816  LWPOINT *pt;
817  LWLINE *ln;
818  LWPOLY *ply;
819  LWCOLLECTION *col;
820  int i;
821 
822  FLAGS_SET_GEODETIC(geom->flags, value);
823  if ( geom->bbox )
824  FLAGS_SET_GEODETIC(geom->bbox->flags, value);
825 
826  switch(geom->type)
827  {
828  case POINTTYPE:
829  pt = (LWPOINT*)geom;
830  if ( pt->point )
831  FLAGS_SET_GEODETIC(pt->point->flags, value);
832  break;
833  case LINETYPE:
834  ln = (LWLINE*)geom;
835  if ( ln->points )
836  FLAGS_SET_GEODETIC(ln->points->flags, value);
837  break;
838  case POLYGONTYPE:
839  ply = (LWPOLY*)geom;
840  for ( i = 0; i < ply->nrings; i++ )
841  FLAGS_SET_GEODETIC(ply->rings[i]->flags, value);
842  break;
843  case MULTIPOINTTYPE:
844  case MULTILINETYPE:
845  case MULTIPOLYGONTYPE:
846  case COLLECTIONTYPE:
847  col = (LWCOLLECTION*)geom;
848  for ( i = 0; i < col->ngeoms; i++ )
849  lwgeom_set_geodetic(col->geoms[i], value);
850  break;
851  default:
852  lwerror("lwgeom_set_geodetic: unsupported geom type: %s", lwtype_name(geom->type));
853  return;
854  }
855 }
856 
857 void
859 {
860  int i;
861  switch (lwgeom->type)
862  {
863  LWPOINT *point;
864  LWLINE *line;
865  LWPOLY *poly;
866  LWTRIANGLE *triangle;
867  LWCOLLECTION *coll;
868 
869  case POINTTYPE:
870  point = (LWPOINT *)lwgeom;
872  return;
873  case LINETYPE:
874  line = (LWLINE *)lwgeom;
876  return;
877  case POLYGONTYPE:
878  poly = (LWPOLY *)lwgeom;
879  for (i=0; i<poly->nrings; i++)
880  ptarray_longitude_shift(poly->rings[i]);
881  return;
882  case TRIANGLETYPE:
883  triangle = (LWTRIANGLE *)lwgeom;
884  ptarray_longitude_shift(triangle->points);
885  return;
886  case MULTIPOINTTYPE:
887  case MULTILINETYPE:
888  case MULTIPOLYGONTYPE:
890  case TINTYPE:
891  case COLLECTIONTYPE:
892  coll = (LWCOLLECTION *)lwgeom;
893  for (i=0; i<coll->ngeoms; i++)
894  lwgeom_longitude_shift(coll->geoms[i]);
895  return;
896  default:
897  lwerror("lwgeom_longitude_shift: unsupported geom type: %s",
898  lwtype_name(lwgeom->type));
899  }
900 }
901 
902 int
904 {
905  int type = geom->type;
906 
907  if( lwgeom_is_empty(geom) )
908  return LW_FALSE;
909 
910  /* Test linear types for closure */
911  switch (type)
912  {
913  case LINETYPE:
914  return lwline_is_closed((LWLINE*)geom);
915  case POLYGONTYPE:
916  return lwpoly_is_closed((LWPOLY*)geom);
917  case CIRCSTRINGTYPE:
918  return lwcircstring_is_closed((LWCIRCSTRING*)geom);
919  case COMPOUNDTYPE:
920  return lwcompound_is_closed((LWCOMPOUND*)geom);
921  case TINTYPE:
922  return lwtin_is_closed((LWTIN*)geom);
924  return lwpsurface_is_closed((LWPSURFACE*)geom);
925  }
926 
927  /* Recurse into collections and see if anything is not closed */
928  if ( lwgeom_is_collection(geom) )
929  {
931  int i;
932  int closed;
933  for ( i = 0; i < col->ngeoms; i++ )
934  {
935  closed = lwgeom_is_closed(col->geoms[i]);
936  if ( ! closed )
937  return LW_FALSE;
938  }
939  return LW_TRUE;
940  }
941 
942  /* All non-linear non-collection types we will call closed */
943  return LW_TRUE;
944 }
945 
946 int
948 {
949  if( ! geom ) return LW_FALSE;
950  return lwtype_is_collection(geom->type);
951 }
952 
954 int
955 lwtype_is_collection(uint8_t type)
956 {
957 
958  switch (type)
959  {
960  case MULTIPOINTTYPE:
961  case MULTILINETYPE:
962  case MULTIPOLYGONTYPE:
963  case COLLECTIONTYPE:
964  case CURVEPOLYTYPE:
965  case COMPOUNDTYPE:
966  case MULTICURVETYPE:
967  case MULTISURFACETYPE:
969  case TINTYPE:
970  return LW_TRUE;
971  break;
972 
973  default:
974  return LW_FALSE;
975  }
976 }
977 
981 int
983 {
984  switch (type)
985  {
986  case POINTTYPE:
987  return MULTIPOINTTYPE;
988  case LINETYPE:
989  return MULTILINETYPE;
990  case POLYGONTYPE:
991  return MULTIPOLYGONTYPE;
992  case CIRCSTRINGTYPE:
993  return MULTICURVETYPE;
994  case COMPOUNDTYPE:
995  return MULTICURVETYPE;
996  case CURVEPOLYTYPE:
997  return MULTISURFACETYPE;
998  case TRIANGLETYPE:
999  return TINTYPE;
1000  default:
1001  return COLLECTIONTYPE;
1002  }
1003 }
1004 
1005 
1006 void lwgeom_free(LWGEOM *lwgeom)
1007 {
1008 
1009  /* There's nothing here to free... */
1010  if( ! lwgeom ) return;
1011 
1012  LWDEBUGF(5,"freeing a %s",lwtype_name(lwgeom->type));
1013 
1014  switch (lwgeom->type)
1015  {
1016  case POINTTYPE:
1017  lwpoint_free((LWPOINT *)lwgeom);
1018  break;
1019  case LINETYPE:
1020  lwline_free((LWLINE *)lwgeom);
1021  break;
1022  case POLYGONTYPE:
1023  lwpoly_free((LWPOLY *)lwgeom);
1024  break;
1025  case CIRCSTRINGTYPE:
1026  lwcircstring_free((LWCIRCSTRING *)lwgeom);
1027  break;
1028  case TRIANGLETYPE:
1029  lwtriangle_free((LWTRIANGLE *)lwgeom);
1030  break;
1031  case MULTIPOINTTYPE:
1032  lwmpoint_free((LWMPOINT *)lwgeom);
1033  break;
1034  case MULTILINETYPE:
1035  lwmline_free((LWMLINE *)lwgeom);
1036  break;
1037  case MULTIPOLYGONTYPE:
1038  lwmpoly_free((LWMPOLY *)lwgeom);
1039  break;
1040  case POLYHEDRALSURFACETYPE:
1041  lwpsurface_free((LWPSURFACE *)lwgeom);
1042  break;
1043  case TINTYPE:
1044  lwtin_free((LWTIN *)lwgeom);
1045  break;
1046  case CURVEPOLYTYPE:
1047  case COMPOUNDTYPE:
1048  case MULTICURVETYPE:
1049  case MULTISURFACETYPE:
1050  case COLLECTIONTYPE:
1051  lwcollection_free((LWCOLLECTION *)lwgeom);
1052  break;
1053  default:
1054  lwerror("lwgeom_free called with unknown type (%d) %s", lwgeom->type, lwtype_name(lwgeom->type));
1055  }
1056  return;
1057 }
1058 
1059 int lwgeom_needs_bbox(const LWGEOM *geom)
1060 {
1061  assert(geom);
1062  if ( geom->type == POINTTYPE )
1063  {
1064  return LW_FALSE;
1065  }
1066  return LW_TRUE;
1067 }
1068 
1073 {
1074  int result = 0;
1075 
1076  /* Null? Zero. */
1077  if( ! geom ) return 0;
1078 
1079  LWDEBUGF(4, "lwgeom_count_vertices got type %s",
1080  lwtype_name(geom->type));
1081 
1082  /* Empty? Zero. */
1083  if( lwgeom_is_empty(geom) ) return 0;
1084 
1085  switch (geom->type)
1086  {
1087  case POINTTYPE:
1088  result = 1;
1089  break;
1090  case TRIANGLETYPE:
1091  case CIRCSTRINGTYPE:
1092  case LINETYPE:
1093  result = lwline_count_vertices((LWLINE *)geom);
1094  break;
1095  case POLYGONTYPE:
1096  result = lwpoly_count_vertices((LWPOLY *)geom);
1097  break;
1098  case COMPOUNDTYPE:
1099  case CURVEPOLYTYPE:
1100  case MULTICURVETYPE:
1101  case MULTISURFACETYPE:
1102  case MULTIPOINTTYPE:
1103  case MULTILINETYPE:
1104  case MULTIPOLYGONTYPE:
1105  case POLYHEDRALSURFACETYPE:
1106  case TINTYPE:
1107  case COLLECTIONTYPE:
1108  result = lwcollection_count_vertices((LWCOLLECTION *)geom);
1109  break;
1110  default:
1111  lwerror("lwgeom_count_vertices: unsupported input geometry type: %s",
1112  lwtype_name(geom->type));
1113  break;
1114  }
1115  LWDEBUGF(3, "counted %d vertices", result);
1116  return result;
1117 }
1118 
1124 int lwgeom_dimension(const LWGEOM *geom)
1125 {
1126 
1127  /* Null? Zero. */
1128  if( ! geom ) return -1;
1129 
1130  LWDEBUGF(4, "lwgeom_dimension got type %s",
1131  lwtype_name(geom->type));
1132 
1133  /* Empty? Zero. */
1134  /* if( lwgeom_is_empty(geom) ) return 0; */
1135 
1136  switch (geom->type)
1137  {
1138  case POINTTYPE:
1139  case MULTIPOINTTYPE:
1140  return 0;
1141  case CIRCSTRINGTYPE:
1142  case LINETYPE:
1143  case COMPOUNDTYPE:
1144  case MULTICURVETYPE:
1145  case MULTILINETYPE:
1146  return 1;
1147  case TRIANGLETYPE:
1148  case POLYGONTYPE:
1149  case CURVEPOLYTYPE:
1150  case MULTISURFACETYPE:
1151  case MULTIPOLYGONTYPE:
1152  case TINTYPE:
1153  return 2;
1154  case POLYHEDRALSURFACETYPE:
1155  {
1156  /* A closed polyhedral surface contains a volume. */
1157  int closed = lwpsurface_is_closed((LWPSURFACE*)geom);
1158  return ( closed ? 3 : 2 );
1159  }
1160  case COLLECTIONTYPE:
1161  {
1162  int maxdim = 0, i;
1163  LWCOLLECTION *col = (LWCOLLECTION*)geom;
1164  for( i = 0; i < col->ngeoms; i++ )
1165  {
1166  int dim = lwgeom_dimension(col->geoms[i]);
1167  maxdim = ( dim > maxdim ? dim : maxdim );
1168  }
1169  return maxdim;
1170  }
1171  default:
1172  lwerror("lwgeom_dimension: unsupported input geometry type: %s",
1173  lwtype_name(geom->type));
1174  }
1175  return -1;
1176 }
1177 
1181 int lwgeom_count_rings(const LWGEOM *geom)
1182 {
1183  int result = 0;
1184 
1185  /* Null? Empty? Zero. */
1186  if( ! geom || lwgeom_is_empty(geom) )
1187  return 0;
1188 
1189  switch (geom->type)
1190  {
1191  case POINTTYPE:
1192  case CIRCSTRINGTYPE:
1193  case COMPOUNDTYPE:
1194  case MULTICURVETYPE:
1195  case MULTIPOINTTYPE:
1196  case MULTILINETYPE:
1197  case LINETYPE:
1198  result = 0;
1199  break;
1200  case TRIANGLETYPE:
1201  result = 1;
1202  break;
1203  case POLYGONTYPE:
1204  result = ((LWPOLY *)geom)->nrings;
1205  break;
1206  case CURVEPOLYTYPE:
1207  result = ((LWCURVEPOLY *)geom)->nrings;
1208  break;
1209  case MULTISURFACETYPE:
1210  case MULTIPOLYGONTYPE:
1211  case POLYHEDRALSURFACETYPE:
1212  case TINTYPE:
1213  case COLLECTIONTYPE:
1214  {
1215  LWCOLLECTION *col = (LWCOLLECTION*)geom;
1216  int i = 0;
1217  for( i = 0; i < col->ngeoms; i++ )
1218  result += lwgeom_count_rings(col->geoms[i]);
1219  break;
1220  }
1221  default:
1222  lwerror("lwgeom_count_rings: unsupported input geometry type: %s", lwtype_name(geom->type));
1223  break;
1224  }
1225  LWDEBUGF(3, "counted %d rings", result);
1226  return result;
1227 }
1228 
1229 int lwgeom_is_empty(const LWGEOM *geom)
1230 {
1231  int result = LW_FALSE;
1232  LWDEBUGF(4, "lwgeom_is_empty: got type %s",
1233  lwtype_name(geom->type));
1234 
1235  switch (geom->type)
1236  {
1237  case POINTTYPE:
1238  return lwpoint_is_empty((LWPOINT*)geom);
1239  break;
1240  case LINETYPE:
1241  return lwline_is_empty((LWLINE*)geom);
1242  break;
1243  case CIRCSTRINGTYPE:
1244  return lwcircstring_is_empty((LWCIRCSTRING*)geom);
1245  break;
1246  case POLYGONTYPE:
1247  return lwpoly_is_empty((LWPOLY*)geom);
1248  break;
1249  case TRIANGLETYPE:
1250  return lwtriangle_is_empty((LWTRIANGLE*)geom);
1251  break;
1252  case MULTIPOINTTYPE:
1253  case MULTILINETYPE:
1254  case MULTIPOLYGONTYPE:
1255  case COMPOUNDTYPE:
1256  case CURVEPOLYTYPE:
1257  case MULTICURVETYPE:
1258  case MULTISURFACETYPE:
1259  case POLYHEDRALSURFACETYPE:
1260  case TINTYPE:
1261  case COLLECTIONTYPE:
1262  return lwcollection_is_empty((LWCOLLECTION *)geom);
1263  break;
1264  default:
1265  lwerror("lwgeom_is_empty: unsupported input geometry type: %s",
1266  lwtype_name(geom->type));
1267  break;
1268  }
1269  return result;
1270 }
1271 
1272 int lwgeom_has_srid(const LWGEOM *geom)
1273 {
1274  if ( geom->srid != SRID_UNKNOWN )
1275  return LW_TRUE;
1276 
1277  return LW_FALSE;
1278 }
1279 
1280 
1282 {
1283  int i;
1284  int dimensionality = 0;
1285  for ( i = 0; i < col->ngeoms; i++ )
1286  {
1287  int d = lwgeom_dimensionality(col->geoms[i]);
1288  if ( d > dimensionality )
1289  dimensionality = d;
1290  }
1291  return dimensionality;
1292 }
1293 
1295 {
1296  int dim;
1297 
1298  LWDEBUGF(3, "lwgeom_dimensionality got type %s",
1299  lwtype_name(geom->type));
1300 
1301  switch (geom->type)
1302  {
1303  case POINTTYPE:
1304  case MULTIPOINTTYPE:
1305  return 0;
1306  break;
1307  case LINETYPE:
1308  case CIRCSTRINGTYPE:
1309  case MULTILINETYPE:
1310  case COMPOUNDTYPE:
1311  case MULTICURVETYPE:
1312  return 1;
1313  break;
1314  case POLYGONTYPE:
1315  case TRIANGLETYPE:
1316  case CURVEPOLYTYPE:
1317  case MULTIPOLYGONTYPE:
1318  case MULTISURFACETYPE:
1319  return 2;
1320  break;
1321 
1322  case POLYHEDRALSURFACETYPE:
1323  case TINTYPE:
1324  dim = lwgeom_is_closed(geom)?3:2;
1325  return dim;
1326  break;
1327 
1328  case COLLECTIONTYPE:
1329  return lwcollection_dimensionality((LWCOLLECTION *)geom);
1330  break;
1331  default:
1332  lwerror("lwgeom_dimensionality: unsupported input geometry type: %s",
1333  lwtype_name(geom->type));
1334  break;
1335  }
1336  return 0;
1337 }
1338 
1340 {
1341  LWDEBUGF(4, "lwgeom_remove_repeated_points got type %s",
1342  lwtype_name(in->type));
1343 
1344  if(lwgeom_is_empty(in))
1345  {
1346  return lwgeom_clone_deep(in);
1347  }
1348 
1349  switch (in->type)
1350  {
1351  case MULTIPOINTTYPE:
1353  break;
1354  case LINETYPE:
1356 
1357  case MULTILINETYPE:
1358  case COLLECTIONTYPE:
1359  case MULTIPOLYGONTYPE:
1360  case POLYHEDRALSURFACETYPE:
1362 
1363  case POLYGONTYPE:
1364  return lwpoly_remove_repeated_points((LWPOLY *)in);
1365  break;
1366 
1367  case POINTTYPE:
1368  case TRIANGLETYPE:
1369  case TINTYPE:
1370  /* No point is repeated for a single point, or for Triangle or TIN */
1371  return lwgeom_clone_deep(in);
1372 
1373  case CIRCSTRINGTYPE:
1374  case COMPOUNDTYPE:
1375  case MULTICURVETYPE:
1376  case CURVEPOLYTYPE:
1377  case MULTISURFACETYPE:
1378  /* Dunno how to handle these, will return untouched */
1379  return lwgeom_clone_deep(in);
1380 
1381  default:
1382  lwnotice("lwgeom_remove_repeated_points: unsupported geometry type: %s",
1383  lwtype_name(in->type));
1384  return lwgeom_clone_deep(in);
1385  break;
1386  }
1387  return 0;
1388 }
1389 
1391 {
1392  LWCOLLECTION *col;
1393  LWPOLY *poly;
1394  int i;
1395 
1396  if ( (!in) || lwgeom_is_empty(in) )
1397  return in;
1398 
1399  LWDEBUGF(4, "lwgeom_flip_coordinates, got type: %s",
1400  lwtype_name(in->type));
1401 
1402  switch (in->type)
1403  {
1404  case POINTTYPE:
1406  break;
1407 
1408  case LINETYPE:
1410  break;
1411 
1412  case CIRCSTRINGTYPE:
1414  break;
1415 
1416  case POLYGONTYPE:
1417  poly = (LWPOLY *) in;
1418  for (i=0; i<poly->nrings; i++)
1419  {
1420  ptarray_flip_coordinates(poly->rings[i]);
1421  }
1422  break;
1423 
1424  case TRIANGLETYPE:
1426  break;
1427 
1428  case MULTIPOINTTYPE:
1429  case MULTILINETYPE:
1430  case MULTIPOLYGONTYPE:
1431  case COLLECTIONTYPE:
1432  case COMPOUNDTYPE:
1433  case CURVEPOLYTYPE:
1434  case MULTISURFACETYPE:
1435  case MULTICURVETYPE:
1436  case POLYHEDRALSURFACETYPE:
1437  case TINTYPE:
1438  col = (LWCOLLECTION *) in;
1439  for (i=0; i<col->ngeoms; i++)
1440  {
1441  lwgeom_flip_coordinates(col->geoms[i]);
1442  }
1443  break;
1444 
1445  default:
1446  lwerror("lwgeom_flip_coordinates: unsupported geometry type: %s",
1447  lwtype_name(in->type));
1448  return NULL;
1449  }
1450 
1451  /* only refresh bbox if X or Y changed */
1452  if ( in->bbox ) {
1453  lwgeom_drop_bbox(in);
1454  lwgeom_add_bbox(in);
1455  }
1456  return in;
1457 }
1458 
1459 void lwgeom_set_srid(LWGEOM *geom, int32_t srid)
1460 {
1461  int i;
1462 
1463  LWDEBUGF(4,"entered with srid=%d",srid);
1464 
1465  geom->srid = srid;
1466 
1467  if ( lwgeom_is_collection(geom) )
1468  {
1469  /* All the children are set to the same SRID value */
1470  LWCOLLECTION *col = lwgeom_as_lwcollection(geom);
1471  for ( i = 0; i < col->ngeoms; i++ )
1472  {
1473  lwgeom_set_srid(col->geoms[i], srid);
1474  }
1475  }
1476 }
1477 
1478 LWGEOM* lwgeom_simplify(const LWGEOM *igeom, double dist)
1479 {
1480  switch (igeom->type)
1481  {
1482  case POINTTYPE:
1483  case MULTIPOINTTYPE:
1484  return lwgeom_clone(igeom);
1485  case LINETYPE:
1486  return (LWGEOM*)lwline_simplify((LWLINE*)igeom, dist);
1487  case POLYGONTYPE:
1488  return (LWGEOM*)lwpoly_simplify((LWPOLY*)igeom, dist);
1489  case MULTILINETYPE:
1490  case MULTIPOLYGONTYPE:
1491  case COLLECTIONTYPE:
1492  return (LWGEOM*)lwcollection_simplify((LWCOLLECTION *)igeom, dist);
1493  default:
1494  lwerror("lwgeom_simplify: unsupported geometry type: %s",lwtype_name(igeom->type));
1495  }
1496  return NULL;
1497 }
1498 
1499 double lwgeom_area(const LWGEOM *geom)
1500 {
1501  int type = geom->type;
1502 
1503  if ( type == POLYGONTYPE )
1504  return lwpoly_area((LWPOLY*)geom);
1505  else if ( type == CURVEPOLYTYPE )
1506  return lwcurvepoly_area((LWCURVEPOLY*)geom);
1507  else if (type == TRIANGLETYPE )
1508  return lwtriangle_area((LWTRIANGLE*)geom);
1509  else if ( lwgeom_is_collection(geom) )
1510  {
1511  double area = 0.0;
1512  int i;
1513  LWCOLLECTION *col = (LWCOLLECTION*)geom;
1514  for ( i = 0; i < col->ngeoms; i++ )
1515  area += lwgeom_area(col->geoms[i]);
1516  return area;
1517  }
1518  else
1519  return 0.0;
1520 }
1521 
1522 double lwgeom_perimeter(const LWGEOM *geom)
1523 {
1524  int type = geom->type;
1525  if ( type == POLYGONTYPE )
1526  return lwpoly_perimeter((LWPOLY*)geom);
1527  else if ( type == CURVEPOLYTYPE )
1528  return lwcurvepoly_perimeter((LWCURVEPOLY*)geom);
1529  else if ( type == TRIANGLETYPE )
1530  return lwtriangle_perimeter((LWTRIANGLE*)geom);
1531  else if ( lwgeom_is_collection(geom) )
1532  {
1533  double perimeter = 0.0;
1534  int i;
1535  LWCOLLECTION *col = (LWCOLLECTION*)geom;
1536  for ( i = 0; i < col->ngeoms; i++ )
1537  perimeter += lwgeom_perimeter(col->geoms[i]);
1538  return perimeter;
1539  }
1540  else
1541  return 0.0;
1542 }
1543 
1544 double lwgeom_perimeter_2d(const LWGEOM *geom)
1545 {
1546  int type = geom->type;
1547  if ( type == POLYGONTYPE )
1548  return lwpoly_perimeter_2d((LWPOLY*)geom);
1549  else if ( type == CURVEPOLYTYPE )
1550  return lwcurvepoly_perimeter_2d((LWCURVEPOLY*)geom);
1551  else if ( type == TRIANGLETYPE )
1552  return lwtriangle_perimeter_2d((LWTRIANGLE*)geom);
1553  else if ( lwgeom_is_collection(geom) )
1554  {
1555  double perimeter = 0.0;
1556  int i;
1557  LWCOLLECTION *col = (LWCOLLECTION*)geom;
1558  for ( i = 0; i < col->ngeoms; i++ )
1559  perimeter += lwgeom_perimeter_2d(col->geoms[i]);
1560  return perimeter;
1561  }
1562  else
1563  return 0.0;
1564 }
1565 
1566 double lwgeom_length(const LWGEOM *geom)
1567 {
1568  int type = geom->type;
1569  if ( type == LINETYPE )
1570  return lwline_length((LWLINE*)geom);
1571  else if ( type == CIRCSTRINGTYPE )
1572  return lwcircstring_length((LWCIRCSTRING*)geom);
1573  else if ( type == COMPOUNDTYPE )
1574  return lwcompound_length((LWCOMPOUND*)geom);
1575  else if ( lwgeom_is_collection(geom) )
1576  {
1577  double length = 0.0;
1578  int i;
1579  LWCOLLECTION *col = (LWCOLLECTION*)geom;
1580  for ( i = 0; i < col->ngeoms; i++ )
1581  length += lwgeom_length(col->geoms[i]);
1582  return length;
1583  }
1584  else
1585  return 0.0;
1586 }
1587 
1588 double lwgeom_length_2d(const LWGEOM *geom)
1589 {
1590  int type = geom->type;
1591  if ( type == LINETYPE )
1592  return lwline_length_2d((LWLINE*)geom);
1593  else if ( type == CIRCSTRINGTYPE )
1594  return lwcircstring_length_2d((LWCIRCSTRING*)geom);
1595  else if ( type == COMPOUNDTYPE )
1596  return lwcompound_length_2d((LWCOMPOUND*)geom);
1597  else if ( lwgeom_is_collection(geom) )
1598  {
1599  double length = 0.0;
1600  int i;
1601  LWCOLLECTION *col = (LWCOLLECTION*)geom;
1602  for ( i = 0; i < col->ngeoms; i++ )
1603  length += lwgeom_length_2d(col->geoms[i]);
1604  return length;
1605  }
1606  else
1607  return 0.0;
1608 }
1609 
1610 void
1611 lwgeom_affine(LWGEOM *geom, const AFFINE *affine)
1612 {
1613  int type = geom->type;
1614  int i;
1615 
1616  switch(type)
1617  {
1618  /* Take advantage of fact tht pt/ln/circ/tri have same memory structure */
1619  case POINTTYPE:
1620  case LINETYPE:
1621  case CIRCSTRINGTYPE:
1622  case TRIANGLETYPE:
1623  {
1624  LWLINE *l = (LWLINE*)geom;
1625  ptarray_affine(l->points, affine);
1626  break;
1627  }
1628  case POLYGONTYPE:
1629  {
1630  LWPOLY *p = (LWPOLY*)geom;
1631  for( i = 0; i < p->nrings; i++ )
1632  ptarray_affine(p->rings[i], affine);
1633  break;
1634  }
1635  case CURVEPOLYTYPE:
1636  {
1637  LWCURVEPOLY *c = (LWCURVEPOLY*)geom;
1638  for( i = 0; i < c->nrings; i++ )
1639  lwgeom_affine(c->rings[i], affine);
1640  break;
1641  }
1642  default:
1643  {
1644  if( lwgeom_is_collection(geom) )
1645  {
1646  LWCOLLECTION *c = (LWCOLLECTION*)geom;
1647  for( i = 0; i < c->ngeoms; i++ )
1648  {
1649  lwgeom_affine(c->geoms[i], affine);
1650  }
1651  }
1652  else
1653  {
1654  lwerror("lwgeom_affine: unable to handle type '%s'", lwtype_name(type));
1655  }
1656  }
1657  }
1658 
1659 }
1660 
1661 LWGEOM*
1662 lwgeom_construct_empty(uint8_t type, int srid, char hasz, char hasm)
1663 {
1664  switch(type)
1665  {
1666  case POINTTYPE:
1667  return lwpoint_as_lwgeom(lwpoint_construct_empty(srid, hasz, hasm));
1668  case LINETYPE:
1669  return lwline_as_lwgeom(lwline_construct_empty(srid, hasz, hasm));
1670  case POLYGONTYPE:
1671  return lwpoly_as_lwgeom(lwpoly_construct_empty(srid, hasz, hasm));
1672  case CURVEPOLYTYPE:
1673  return lwcurvepoly_as_lwgeom(lwcurvepoly_construct_empty(srid, hasz, hasm));
1674  case CIRCSTRINGTYPE:
1675  return lwcircstring_as_lwgeom(lwcircstring_construct_empty(srid, hasz, hasm));
1676  case TRIANGLETYPE:
1677  return lwtriangle_as_lwgeom(lwtriangle_construct_empty(srid, hasz, hasm));
1678  case COMPOUNDTYPE:
1679  case MULTIPOINTTYPE:
1680  case MULTILINETYPE:
1681  case MULTIPOLYGONTYPE:
1682  case COLLECTIONTYPE:
1683  return lwcollection_as_lwgeom(lwcollection_construct_empty(type, srid, hasz, hasm));
1684  default:
1685  lwerror("lwgeom_construct_empty: unsupported geometry type: %s",
1686  lwtype_name(type));
1687  return NULL;
1688  }
1689 }
1690 
1691 int
1692 lwgeom_startpoint(const LWGEOM* lwgeom, POINT4D* pt)
1693 {
1694  if ( ! lwgeom )
1695  return LW_FAILURE;
1696 
1697  switch( lwgeom->type )
1698  {
1699  case POINTTYPE:
1700  return ptarray_startpoint(((LWPOINT*)lwgeom)->point, pt);
1701  case TRIANGLETYPE:
1702  case CIRCSTRINGTYPE:
1703  case LINETYPE:
1704  return ptarray_startpoint(((LWLINE*)lwgeom)->points, pt);
1705  case POLYGONTYPE:
1706  return lwpoly_startpoint((LWPOLY*)lwgeom, pt);
1707  case CURVEPOLYTYPE:
1708  case COMPOUNDTYPE:
1709  case MULTIPOINTTYPE:
1710  case MULTILINETYPE:
1711  case MULTIPOLYGONTYPE:
1712  case COLLECTIONTYPE:
1713  return lwcollection_startpoint((LWCOLLECTION*)lwgeom, pt);
1714  default:
1715  lwerror("int: unsupported geometry type: %s",
1716  lwtype_name(lwgeom->type));
1717  return LW_FAILURE;
1718  }
1719 }
1720 
LWMPOINT * lwgeom_as_lwmpoint(const LWGEOM *lwgeom)
Definition: lwgeom.c:152
#define LINETYPE
Definition: liblwgeom.h:61
int lwgeom_calculate_gbox_geodetic(const LWGEOM *geom, GBOX *gbox)
Calculate the geodetic bounding box for an LWGEOM.
Definition: lwgeodetic.c:2612
LWPOINT * lwpoint_force_dims(const LWPOINT *lwpoint, int hasz, int hasm)
Definition: lwpoint.c:238
int lwcollection_count_vertices(LWCOLLECTION *col)
Definition: lwcollection.c:484
static int lwcollection_dimensionality(LWCOLLECTION *col)
Definition: lwgeom.c:1281
int lwgeom_startpoint(const LWGEOM *lwgeom, POINT4D *pt)
Definition: lwgeom.c:1692
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition: lwgeom.c:239
LWPSURFACE * lwgeom_as_lwpsurface(const LWGEOM *lwgeom)
Definition: lwgeom.c:179
GBOX * gbox_new(uint8_t flags)
Create a new gbox with the dimensionality indicated by the flags.
Definition: g_box.c:26
GBOX * bbox
Definition: liblwgeom.h:354
void lwgeom_add_bbox_deep(LWGEOM *lwgeom, GBOX *gbox)
Compute a box for geom and all sub-geometries, if not already computed.
Definition: lwgeom.c:567
LWPOLY * lwpoly_clone_deep(const LWPOLY *lwgeom)
Definition: lwpoly.c:135
LWLINE * lwline_construct_empty(int srid, char hasz, char hasm)
Definition: lwline.c:51
POINTARRAY * points
Definition: liblwgeom.h:389
char lwpoint_same(const LWPOINT *p1, const LWPOINT *p2)
Definition: lwpoint.c:231
double lwcircstring_length(const LWCIRCSTRING *circ)
Definition: lwcircstring.c:270
#define MULTICURVETYPE
Definition: liblwgeom.h:70
void lwgeom_drop_bbox(LWGEOM *lwgeom)
Call this function to drop BBOX and SRID from LWGEOM.
Definition: lwgeom.c:542
GEOGRAPHIC_POINT center
LWCOLLECTION * lwcollection_construct(uint8_t type, int srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:30
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
Definition: lwout_wkt.c:655
LWGEOM * lwgeom_force_3dm(const LWGEOM *geom)
Definition: lwgeom.c:658
void lwgeom_drop_srid(LWGEOM *lwgeom)
Definition: lwgeom.c:618
void lwmline_free(LWMLINE *mline)
Definition: lwmline.c:99
LWLINE * lwline_segmentize2d(LWLINE *line, double dist)
Definition: lwline.c:134
void lwfree(void *mem)
Definition: lwutil.c:190
LWTRIANGLE * lwtriangle_construct_empty(int srid, char hasz, char hasm)
Definition: lwtriangle.c:45
int lwline_count_vertices(LWLINE *line)
Definition: lwline.c:472
int32_t lwgeom_get_srid(const LWGEOM *geom)
Return SRID number.
Definition: lwgeom.c:778
LWGEOM ** rings
Definition: liblwgeom.h:491
LWLINE * lwline_clone(const LWLINE *lwgeom)
Definition: lwline.c:89
int lwtin_is_closed(const LWTIN *tin)
Definition: lwtin.c:80
uint8_t type
Definition: liblwgeom.h:459
double lwgeom_length(const LWGEOM *geom)
Definition: lwgeom.c:1566
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
Definition: lwgeom.c:799
void lwcircstring_free(LWCIRCSTRING *curve)
Definition: lwcircstring.c:85
LWGEOM * lwgeom_remove_repeated_points(LWGEOM *in)
Remove repeated points!
Definition: lwgeom.c:1339
void lwgeom_force_clockwise(LWGEOM *lwgeom)
Force Right-hand-rule on LWGEOM polygons.
Definition: lwgeom.c:23
#define FLAGS_GET_GEODETIC(flags)
Definition: liblwgeom.h:109
#define POLYGONTYPE
Definition: liblwgeom.h:62
Datum area(PG_FUNCTION_ARGS)
void lwtin_free(LWTIN *tin)
Definition: lwtin.c:26
uint8_t flags
Definition: liblwgeom.h:353
#define CURVEPOLYTYPE
Definition: liblwgeom.h:69
void lwpoint_free(LWPOINT *pt)
Definition: lwpoint.c:180
#define COMPOUNDTYPE
Definition: liblwgeom.h:68
#define MULTIPOINTTYPE
Definition: liblwgeom.h:63
LWPOLY * lwgeom_as_lwpoly(const LWGEOM *lwgeom)
Definition: lwgeom.c:125
int lwgeom_ndims(const LWGEOM *geom)
Return the number of dimensions (2, 3, 4) in a geometry.
Definition: lwgeom.c:806
void lwgeom_longitude_shift(LWGEOM *lwgeom)
Definition: lwgeom.c:858
void lwline_free(LWLINE *line)
Definition: lwline.c:63
LWGEOM * lwgeom_segmentize2d(LWGEOM *lwgeom, double dist)
Definition: lwgeom.c:624
int lwgeom_count_rings(const LWGEOM *geom)
Count rings in an LWGEOM.
Definition: lwgeom.c:1181
double lwtriangle_perimeter_2d(const LWTRIANGLE *triangle)
Definition: lwtriangle.c:205
#define FLAGS_GET_ZM(flags)
Definition: liblwgeom.h:119
double lwcircstring_length_2d(const LWCIRCSTRING *circ)
Definition: lwcircstring.c:275
LWTRIANGLE * lwtriangle_clone(const LWTRIANGLE *lwgeom)
Definition: lwtriangle.c:86
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:50
double lwline_length_2d(const LWLINE *line)
Definition: lwline.c:503
#define TRIANGLETYPE
Definition: liblwgeom.h:73
void lwtriangle_reverse(LWTRIANGLE *triangle)
Definition: lwtriangle.c:100
LWGEOM * lwmpoint_as_lwgeom(const LWMPOINT *obj)
Definition: lwgeom.c:214
#define POLYHEDRALSURFACETYPE
Definition: liblwgeom.h:72
int lwgeom_count_vertices(const LWGEOM *geom)
Count points in an LWGEOM.
Definition: lwgeom.c:1072
void lwtriangle_force_clockwise(LWTRIANGLE *triangle)
Definition: lwtriangle.c:93
int lwcompound_is_closed(const LWCOMPOUND *curve)
Definition: lwcompound.c:22
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
Definition: lwgeom.c:254
double distance2d_pt_pt(const POINT2D *p1, const POINT2D *p2)
The old function nessecary for ptarray_segmentize2d in ptarray.c.
Definition: measures.c:2123
#define FLAGS_SET_GEODETIC(flags, value)
Definition: liblwgeom.h:115
LWPOINT * lwpoint_construct_empty(int srid, char hasz, char hasm)
Definition: lwpoint.c:118
void lwpoly_force_clockwise(LWPOLY *poly)
Definition: lwpoly.c:175
LWTRIANGLE * lwgeom_as_lwtriangle(const LWGEOM *lwgeom)
Definition: lwgeom.c:134
double lwtriangle_area(const LWTRIANGLE *triangle)
Find the area of the outer ring.
Definition: lwtriangle.c:173
POINTARRAY * point
Definition: liblwgeom.h:367
char ** result
Definition: liblwgeom.h:218
int32_t srid
Definition: liblwgeom.h:355
int lwgeom_is_closed(const LWGEOM *geom)
Return true or false depending on whether a geometry is a linear feature that closes on itself...
Definition: lwgeom.c:903
LWGEOM * lwpsurface_as_lwgeom(const LWPSURFACE *obj)
Definition: lwgeom.c:199
double lwtriangle_perimeter(const LWTRIANGLE *triangle)
Definition: lwtriangle.c:196
char lwgeom_same(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2)
geom1 same as geom2 iff
Definition: lwgeom.c:451
LWGEOM * lwgeom_segmentize(LWGEOM *geom, uint32_t perQuad)
Definition: lwsegmentize.c:446
#define LW_FAILURE
Definition: liblwgeom.h:54
POINTARRAY * ptarray_flip_coordinates(POINTARRAY *pa)
Reverse X and Y axis on a given POINTARRAY.
Definition: ptarray.c:354
LWGEOM * lwtin_as_lwgeom(const LWTIN *obj)
Definition: lwgeom.c:194
char lwcollection_same(const LWCOLLECTION *p1, const LWCOLLECTION *p2)
check for same geometry composition
Definition: lwcollection.c:238
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:67
double x
Definition: liblwgeom.h:284
LWCOMPOUND * lwgeom_as_lwcompound(const LWGEOM *lwgeom)
Definition: lwgeom.c:107
int lwtriangle_is_empty(const LWTRIANGLE *triangle)
Definition: lwtriangle.c:162
LWCURVEPOLY * lwgeom_as_lwcurvepoly(const LWGEOM *lwgeom)
Definition: lwgeom.c:116
LWGEOM * lwgeom_clone_deep(const LWGEOM *lwgeom)
Deep-clone an LWGEOM object.
Definition: lwgeom.c:389
void lwmpoly_free(LWMPOLY *mpoly)
Definition: lwmpoly.c:40
void lwmpoint_free(LWMPOINT *mpt)
Definition: lwmpoint.c:59
void lwnotice(const char *fmt,...)
Write a notice out to the notice handler.
Definition: lwutil.c:54
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:164
LWGEOM * lwmpoly_as_lwgeom(const LWMPOLY *obj)
Definition: lwgeom.c:204
double lwgeom_area(const LWGEOM *geom)
Definition: lwgeom.c:1499
char lwcircstring_same(const LWCIRCSTRING *p1, const LWCIRCSTRING *p2)
Definition: lwcircstring.c:125
double lwgeom_perimeter(const LWGEOM *geom)
Definition: lwgeom.c:1522
double lwcompound_length_2d(const LWCOMPOUND *comp)
Definition: lwcompound.c:61
int lwcollection_is_empty(const LWCOLLECTION *col)
Definition: lwcollection.c:471
LWCIRCSTRING * lwcircstring_construct_empty(int srid, char hasz, char hasm)
Definition: lwcircstring.c:67
char lwtriangle_same(const LWTRIANGLE *p1, const LWTRIANGLE *p2)
Definition: lwtriangle.c:114
#define LW_FALSE
Definition: liblwgeom.h:52
LWPOLY * lwpoly_force_dims(const LWPOLY *lwpoly, int hasz, int hasm)
Definition: lwpoly.c:303
LWGEOM * lwgeom_force_3dz(const LWGEOM *geom)
Definition: lwgeom.c:652
uint8_t flags
Definition: liblwgeom.h:325
void lwpoly_free(LWPOLY *poly)
Definition: lwpoly.c:79
int lwgeom_has_srid(const LWGEOM *geom)
Return true or false depending on whether a geometry has a valid SRID set.
Definition: lwgeom.c:1272
LWPOINT * lwpoint_clone(const LWPOINT *lwgeom)
Definition: lwpoint.c:206
double lwgeom_perimeter_2d(const LWGEOM *geom)
Definition: lwgeom.c:1544
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:51
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition: lwgeom.c:89
LWGEOM ** geoms
Definition: liblwgeom.h:465
int lwpoly_is_closed(const LWPOLY *poly)
Definition: lwpoly.c:455
double lwcompound_length(const LWCOMPOUND *comp)
Definition: lwcompound.c:56
int lwcircstring_is_closed(const LWCIRCSTRING *curve)
Definition: lwcircstring.c:255
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:154
#define TINTYPE
Definition: liblwgeom.h:74
LWPOLY * lwpoly_simplify(const LWPOLY *ipoly, double dist)
Definition: lwpoly.c:346
LWGEOM * lwline_remove_repeated_points(LWLINE *in)
Definition: lwline.c:423
void lwgeom_affine(LWGEOM *geom, const AFFINE *affine)
Definition: lwgeom.c:1611
LWMLINE * lwgeom_as_lwmline(const LWGEOM *lwgeom)
Definition: lwgeom.c:161
POINTARRAY ** rings
Definition: liblwgeom.h:413
LWCIRCSTRING * lwcircstring_clone(const LWCIRCSTRING *curve)
Definition: lwcircstring.c:112
LWGEOM * lwgeom_as_multi(const LWGEOM *lwgeom)
Create a new LWGEOM of the appropriate MULTI* type.
Definition: lwgeom.c:284
LWGEOM * lwcurvepoly_as_lwgeom(const LWCURVEPOLY *obj)
Definition: lwgeom.c:229
int lwtype_is_collection(uint8_t type)
Return TRUE if the geometry may contain sub-geometries, i.e.
Definition: lwgeom.c:955
LWGEOM * lwgeom_force_4d(const LWGEOM *geom)
Definition: lwgeom.c:664
double lwpoly_area(const LWPOLY *poly)
Find the area of the outer ring - sum (area of inner rings).
Definition: lwpoly.c:390
int lwgeom_dimensionality(LWGEOM *geom)
Return the dimensionality (relating to point/line/poly) of an lwgeom.
Definition: lwgeom.c:1294
int lwpoly_is_empty(const LWPOLY *poly)
Definition: lwpoly.c:327
LWCURVEPOLY * lwcurvepoly_construct_empty(int srid, char hasz, char hasm)
Definition: lwcurvepoly.c:23
uint8_t MULTITYPE[NUMTYPES]
Look-up for the correct MULTI* type promotion for singleton types.
Definition: lwgeom.c:264
double lwcurvepoly_perimeter_2d(const LWCURVEPOLY *poly)
Definition: lwcurvepoly.c:146
LWGEOM * lwgeom_clone(const LWGEOM *lwgeom)
Clone LWGEOM object.
Definition: lwgeom.c:351
LWGEOM * lwcircstring_as_lwgeom(const LWCIRCSTRING *obj)
Definition: lwgeom.c:224
int nrings
Definition: liblwgeom.h:411
#define NUMTYPES
Definition: liblwgeom.h:76
double y
Definition: liblwgeom.h:284
int getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point)
Definition: lwgeom_api.c:434
int lwpsurface_is_closed(const LWPSURFACE *psurface)
Definition: lwpsurface.c:86
#define FLAGS_GET_Z(flags)
Macros for manipulating the 'flags' byte.
Definition: liblwgeom.h:106
int lwcollection_startpoint(const LWCOLLECTION *col, POINT4D *pt)
Definition: lwcollection.c:550
LWCOLLECTION * lwcollection_clone_deep(const LWCOLLECTION *lwgeom)
Deep clone LWCOLLECTION object.
Definition: lwcollection.c:136
LWGEOM * lwgeom_simplify(const LWGEOM *igeom, double dist)
Definition: lwgeom.c:1478
int lwpoly_startpoint(const LWPOLY *lwpoly, POINT4D *pt)
Definition: lwpoly.c:480
double lwpoly_perimeter_2d(const LWPOLY *poly)
Compute the sum of polygon rings length (forcing 2d computation).
Definition: lwpoly.c:441
LWCOLLECTION * lwgeom_as_lwcollection(const LWGEOM *lwgeom)
Definition: lwgeom.c:143
int lwcircstring_is_empty(const LWCIRCSTRING *circ)
Definition: lwcircstring.c:263
uint8_t flags
Definition: liblwgeom.h:247
double lwpoly_perimeter(const LWPOLY *poly)
Compute the sum of polygon rings length.
Definition: lwpoly.c:423
void lwtriangle_free(LWTRIANGLE *triangle)
Definition: lwtriangle.c:56
LWCOLLECTION * lwcollection_segmentize2d(LWCOLLECTION *coll, double dist)
Definition: lwcollection.c:220
void lwpsurface_free(LWPSURFACE *psurf)
Definition: lwpsurface.c:26
LWCIRCSTRING * lwgeom_as_lwcircstring(const LWGEOM *lwgeom)
Definition: lwgeom.c:98
void lwgeom_set_geodetic(LWGEOM *geom, int value)
Set the FLAGS geodetic bit on geometry an all sub-geometries and pointlists.
Definition: lwgeom.c:814
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
Definition: lwgeom.c:219
LWCOLLECTION * lwcollection_force_dims(const LWCOLLECTION *lwcol, int hasz, int hasm)
Definition: lwcollection.c:448
int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members) ...
Definition: lwgeom.c:1229
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:65
double lwgeom_length_2d(const LWGEOM *geom)
Definition: lwgeom.c:1588
LWGEOM * lwgeom_force_dims(const LWGEOM *geom, int hasz, int hasm)
Definition: lwgeom.c:670
void lwpoly_reverse(LWPOLY *poly)
Definition: lwpoly.c:201
int ptarray_startpoint(const POINTARRAY *pa, POINT4D *pt)
Definition: ptarray.c:1740
int lwline_is_empty(const LWLINE *line)
Definition: lwline.c:464
LWGEOM * lwgeom_force_2d(const LWGEOM *geom)
Strip out the Z/M components of an LWGEOM.
Definition: lwgeom.c:646
#define WKT_EXTENDED
Definition: liblwgeom.h:1778
LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
Definition: lwgeom.c:80
LWPOLY * lwpoly_from_lwlines(const LWLINE *shell, uint32_t nholes, const LWLINE **holes)
Definition: lwpoly.c:250
#define FLAGS_SET_BBOX(flags, value)
Definition: liblwgeom.h:114
int lwpoint_inside_circle(const LWPOINT *p, double cx, double cy, double rad)
Definition: lwgeom.c:522
double lwcurvepoly_perimeter(const LWCURVEPOLY *poly)
Definition: lwcurvepoly.c:134
void lwline_reverse(LWLINE *line)
Definition: lwline.c:127
LWLINE * lwline_force_dims(const LWLINE *lwline, int hasz, int hasm)
Definition: lwline.c:445
LWGEOM * lwgeom_force_sfs(LWGEOM *geom, int version)
Definition: lwgeom.c:700
int lwgeom_is_collection(const LWGEOM *geom)
Determine whether a LWGEOM can contain sub-geometries or not.
Definition: lwgeom.c:947
LWLINE * lwline_simplify(const LWLINE *iline, double dist)
Definition: lwline.c:480
void ptarray_longitude_shift(POINTARRAY *pa)
Longitude shift for a pointarray.
Definition: ptarray.c:1378
double lwline_length(const LWLINE *line)
Definition: lwline.c:496
int lwgeom_dimension(const LWGEOM *geom)
For an LWGEOM, returns 0 for points, 1 for lines, 2 for polygons, 3 for volume, and the max dimension...
Definition: lwgeom.c:1124
#define MULTISURFACETYPE
Definition: liblwgeom.h:71
LWGEOM * lwmpoint_remove_repeated_points(LWMPOINT *in)
Definition: lwmpoint.c:79
int lwline_is_closed(const LWLINE *line)
Definition: lwline.c:435
char * lwgeom_to_ewkt(const LWGEOM *lwgeom)
Return an alloced string.
Definition: lwgeom.c:425
LWMPOLY * lwgeom_as_lwmpoly(const LWGEOM *lwgeom)
Definition: lwgeom.c:170
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition: lwgeom.c:792
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:60
int lwpoint_is_empty(const LWPOINT *point)
Definition: lwpoint.c:258
LWPOLY * lwpoly_construct_empty(int srid, char hasz, char hasm)
Definition: lwpoly.c:66
LWGEOM * lwmline_as_lwgeom(const LWMLINE *obj)
Definition: lwgeom.c:209
void lwgeom_add_bbox(LWGEOM *lwgeom)
Ensure there's a box in the LWGEOM.
Definition: lwgeom.c:555
#define FLAGS_GET_M(flags)
Definition: liblwgeom.h:107
int lwgeom_needs_bbox(const LWGEOM *geom)
Check whether or not a lwgeom is big enough to warrant a bounding box.
Definition: lwgeom.c:1059
int lwtype_get_collectiontype(uint8_t type)
Given an lwtype number, what homogeneous collection can hold it?
Definition: lwgeom.c:982
LWGEOM * lwpoly_remove_repeated_points(LWPOLY *in)
Definition: lwpoly.c:284
uint8_t type
Definition: liblwgeom.h:352
LWCOLLECTION * lwcollection_clone(const LWCOLLECTION *lwgeom)
Clone LWCOLLECTION object.
Definition: lwcollection.c:110
void lwcollection_free(LWCOLLECTION *col)
Definition: lwcollection.c:316
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition: lwgeom.c:249
LWGEOM * lwgeom_construct_empty(uint8_t type, int srid, char hasz, char hasm)
Definition: lwgeom.c:1662
int lwgeom_calculate_gbox(const LWGEOM *lwgeom, GBOX *gbox)
Calculate the gbox for this goemetry, a cartesian box or geodetic box, depending on how it is flagged...
Definition: lwgeom.c:608
GBOX * gbox_clone(const GBOX *gbox)
Definition: g_box.c:39
LWTIN * lwgeom_as_lwtin(const LWGEOM *lwgeom)
Definition: lwgeom.c:187
void lwgeom_set_srid(LWGEOM *geom, int32_t srid)
Definition: lwgeom.c:1459
#define CIRCSTRINGTYPE
Definition: liblwgeom.h:67
LWPOLY * lwpoly_segmentize2d(LWPOLY *line, double dist)
Definition: lwpoly.c:210
void * lwalloc(size_t size)
Definition: lwutil.c:175
LWGEOM * lwtriangle_as_lwgeom(const LWTRIANGLE *obj)
Definition: lwgeom.c:244
void lwgeom_free(LWGEOM *lwgeom)
Definition: lwgeom.c:1006
int lwpoly_count_vertices(LWPOLY *poly)
Definition: lwpoly.c:334
uint32_t lwgeom_get_type(const LWGEOM *geom)
Return LWTYPE number.
Definition: lwgeom.c:785
#define MULTILINETYPE
Definition: liblwgeom.h:64
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int srid, char hasz, char hasm)
Definition: lwcollection.c:81
LWPOLY * lwpoly_clone(const LWPOLY *lwgeom)
Definition: lwpoly.c:120
LWLINE * lwline_clone_deep(const LWLINE *lwgeom)
Definition: lwline.c:105
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:55
#define FLAGS_NDIMS(flags)
Definition: liblwgeom.h:118
double lwcurvepoly_area(const LWCURVEPOLY *curvepoly)
This should be rewritten to make use of the curve itself.
Definition: lwcurvepoly.c:120
int gbox_same(const GBOX *g1, const GBOX *g2)
Check if 2 given Gbox are the same.
Definition: g_box.c:139
LWGEOM * lwgeom_flip_coordinates(LWGEOM *in)
Reverse the X and Y coordinate order.
Definition: lwgeom.c:1390
char lwpoly_same(const LWPOLY *p1, const LWPOLY *p2)
Definition: lwpoly.c:229
LWGEOM * lwcompound_as_lwgeom(const LWCOMPOUND *obj)
Definition: lwgeom.c:234
void lwgeom_release(LWGEOM *lwgeom)
Free the containing LWGEOM and the associated BOX.
Definition: lwgeom.c:328
LWCOLLECTION * lwcollection_simplify(const LWCOLLECTION *igeom, double dist)
Definition: lwcollection.c:496
char lwline_same(const LWLINE *p1, const LWLINE *p2)
Definition: lwline.c:142
#define COLLECTIONTYPE
Definition: liblwgeom.h:66
void ptarray_affine(POINTARRAY *pa, const AFFINE *affine)
Affine transform a pointarray.
Definition: ptarray.c:1692
void lwgeom_reverse(LWGEOM *lwgeom)
Reverse vertex order of LWGEOM.
Definition: lwgeom.c:51
POINTARRAY * points
Definition: liblwgeom.h:378
const GBOX * lwgeom_get_bbox(const LWGEOM *lwg)
Get a non-empty geometry bounding box, computing and caching it if not already there.
Definition: lwgeom.c:596
int lwgeom_calculate_gbox_cartesian(const LWGEOM *lwgeom, GBOX *gbox)
Calculate the 2-4D bounding box of a geometry.
Definition: g_box.c:607
LWGEOM * lwcollection_remove_repeated_points(LWCOLLECTION *in)
Definition: lwcollection.c:430