PostGIS  2.3.8dev-r@@SVN_REVISION@@
lwcollection.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) 2001-2006 Refractions Research Inc.
22  *
23  **********************************************************************/
24 
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include "liblwgeom_internal.h"
30 #include "lwgeom_log.h"
31 
32 
33 #define CHECK_LWGEOM_ZM 1
34 
35 void
37 {
39 }
40 
41 
43 lwcollection_construct(uint8_t type, int srid, GBOX *bbox,
44  uint32_t ngeoms, LWGEOM **geoms)
45 {
46  LWCOLLECTION *ret;
47  int hasz, hasm;
48 #ifdef CHECK_LWGEOM_ZM
49  char zm;
50  uint32_t i;
51 #endif
52 
53  LWDEBUGF(2, "lwcollection_construct called with %d, %d, %p, %d, %p.", type, srid, bbox, ngeoms, geoms);
54 
55  if( ! lwtype_is_collection(type) )
56  lwerror("Non-collection type specified in collection constructor!");
57 
58  hasz = 0;
59  hasm = 0;
60  if ( ngeoms > 0 )
61  {
62  hasz = FLAGS_GET_Z(geoms[0]->flags);
63  hasm = FLAGS_GET_M(geoms[0]->flags);
64 #ifdef CHECK_LWGEOM_ZM
65  zm = FLAGS_GET_ZM(geoms[0]->flags);
66 
67  LWDEBUGF(3, "lwcollection_construct type[0]=%d", geoms[0]->type);
68 
69  for (i=1; i<ngeoms; i++)
70  {
71  LWDEBUGF(3, "lwcollection_construct type=[%d]=%d", i, geoms[i]->type);
72 
73  if ( zm != FLAGS_GET_ZM(geoms[i]->flags) )
74  lwerror("lwcollection_construct: mixed dimension geometries: %d/%d", zm, FLAGS_GET_ZM(geoms[i]->flags));
75  }
76 #endif
77  }
78 
79 
80  ret = lwalloc(sizeof(LWCOLLECTION));
81  ret->type = type;
82  ret->flags = gflags(hasz,hasm,0);
83  FLAGS_SET_BBOX(ret->flags, bbox?1:0);
84  ret->srid = srid;
85  ret->ngeoms = ngeoms;
86  ret->maxgeoms = ngeoms;
87  ret->geoms = geoms;
88  ret->bbox = bbox;
89 
90  return ret;
91 }
92 
94 lwcollection_construct_empty(uint8_t type, int srid, char hasz, char hasm)
95 {
96  LWCOLLECTION *ret;
97  if( ! lwtype_is_collection(type) )
98  lwerror("Non-collection type specified in collection constructor!");
99 
100  ret = lwalloc(sizeof(LWCOLLECTION));
101  ret->type = type;
102  ret->flags = gflags(hasz,hasm,0);
103  ret->srid = srid;
104  ret->ngeoms = 0;
105  ret->maxgeoms = 1; /* Allocate room for sub-members, just in case. */
106  ret->geoms = lwalloc(ret->maxgeoms * sizeof(LWGEOM*));
107  ret->bbox = NULL;
108 
109  return ret;
110 }
111 
112 LWGEOM *
114 {
115  return (LWGEOM *)col->geoms[gnum];
116 }
117 
122 LWCOLLECTION *
124 {
125  uint32_t i;
126  LWCOLLECTION *ret = lwalloc(sizeof(LWCOLLECTION));
127  memcpy(ret, g, sizeof(LWCOLLECTION));
128  if ( g->ngeoms > 0 )
129  {
130  ret->geoms = lwalloc(sizeof(LWGEOM *)*g->ngeoms);
131  for (i=0; i<g->ngeoms; i++)
132  {
133  ret->geoms[i] = lwgeom_clone(g->geoms[i]);
134  }
135  if ( g->bbox ) ret->bbox = gbox_copy(g->bbox);
136  }
137  else
138  {
139  ret->bbox = NULL; /* empty collection */
140  ret->geoms = NULL;
141  }
142  return ret;
143 }
144 
148 LWCOLLECTION *
150 {
151  uint32_t i;
152  LWCOLLECTION *ret = lwalloc(sizeof(LWCOLLECTION));
153  memcpy(ret, g, sizeof(LWCOLLECTION));
154  if ( g->ngeoms > 0 )
155  {
156  ret->geoms = lwalloc(sizeof(LWGEOM *)*g->ngeoms);
157  for (i=0; i<g->ngeoms; i++)
158  {
159  ret->geoms[i] = lwgeom_clone_deep(g->geoms[i]);
160  }
161  if ( g->bbox ) ret->bbox = gbox_copy(g->bbox);
162  }
163  else
164  {
165  ret->bbox = NULL; /* empty collection */
166  ret->geoms = NULL;
167  }
168  return ret;
169 }
170 
174 void lwcollection_reserve(LWCOLLECTION *col, int ngeoms)
175 {
176  if ( ngeoms <= col->maxgeoms ) return;
177 
178  /* Allocate more space if we need it */
179  do { col->maxgeoms *= 2; } while ( col->maxgeoms < ngeoms );
180  col->geoms = lwrealloc(col->geoms, sizeof(LWGEOM*) * col->maxgeoms);
181 }
182 
188 {
189  if ( col == NULL || geom == NULL ) return NULL;
190 
191  if ( col->geoms == NULL && (col->ngeoms || col->maxgeoms) ) {
192  lwerror("Collection is in inconsistent state. Null memory but non-zero collection counts.");
193  return NULL;
194  }
195 
196  /* Check type compatibility */
197  if ( ! lwcollection_allows_subtype(col->type, geom->type) ) {
198  lwerror("%s cannot contain %s element", lwtype_name(col->type), lwtype_name(geom->type));
199  return NULL;
200  }
201 
202  /* In case this is a truly empty, make some initial space */
203  if ( col->geoms == NULL )
204  {
205  col->maxgeoms = 2;
206  col->ngeoms = 0;
207  col->geoms = lwalloc(col->maxgeoms * sizeof(LWGEOM*));
208  }
209 
210  /* Allocate more space if we need it */
211  lwcollection_reserve(col, col->ngeoms + 1);
212 
213 #if PARANOIA_LEVEL > 1
214  /* See http://trac.osgeo.org/postgis/ticket/2933 */
215  /* Make sure we don't already have a reference to this geom */
216  {
217  int i = 0;
218  for ( i = 0; i < col->ngeoms; i++ )
219  {
220  if ( col->geoms[i] == geom )
221  {
222  LWDEBUGF(4, "Found duplicate geometry in collection %p == %p", col->geoms[i], geom);
223  return col;
224  }
225  }
226  }
227 #endif
228 
229  col->geoms[col->ngeoms] = (LWGEOM*)geom;
230  col->ngeoms++;
231  return col;
232 }
233 
234 
235 LWCOLLECTION *
237 {
238  uint32_t i;
239  LWGEOM **newgeoms;
240 
241  if ( ! col->ngeoms ) return lwcollection_clone(col);
242 
243  newgeoms = lwalloc(sizeof(LWGEOM *)*col->ngeoms);
244  for (i=0; i<col->ngeoms; i++)
245  {
246  newgeoms[i] = lwgeom_segmentize2d(col->geoms[i], dist);
247  if ( ! newgeoms[i] ) {
248  while (i--) lwgeom_free(newgeoms[i]);
249  lwfree(newgeoms);
250  return NULL;
251  }
252  }
253 
254  return lwcollection_construct(col->type, col->srid, NULL, col->ngeoms, newgeoms);
255 }
256 
260 char
262 {
263  uint32_t i;
264 
265  LWDEBUG(2, "lwcollection_same called");
266 
267  if ( c1->type != c2->type ) return LW_FALSE;
268  if ( c1->ngeoms != c2->ngeoms ) return LW_FALSE;
269 
270  for ( i = 0; i < c1->ngeoms; i++ )
271  {
272  if ( ! lwgeom_same(c1->geoms[i], c2->geoms[i]) )
273  return LW_FALSE;
274  }
275 
276  /* Former method allowed out-of-order equality between collections
277 
278  hit = lwalloc(sizeof(uint32_t)*c1->ngeoms);
279  memset(hit, 0, sizeof(uint32_t)*c1->ngeoms);
280 
281  for (i=0; i<c1->ngeoms; i++)
282  {
283  char found=0;
284  for (j=0; j<c2->ngeoms; j++)
285  {
286  if ( hit[j] ) continue;
287  if ( lwgeom_same(c1->geoms[i], c2->geoms[j]) )
288  {
289  hit[j] = 1;
290  found=1;
291  break;
292  }
293  }
294  if ( ! found ) return LW_FALSE;
295  }
296  */
297 
298  return LW_TRUE;
299 }
300 
302 {
303  int i;
304  int ngeoms = 0;
305 
306  if ( ! col )
307  {
308  lwerror("Null input geometry.");
309  return 0;
310  }
311 
312  for ( i = 0; i < col->ngeoms; i++ )
313  {
314  if ( col->geoms[i])
315  {
316  switch (col->geoms[i]->type)
317  {
318  case POINTTYPE:
319  case LINETYPE:
320  case CIRCSTRINGTYPE:
321  case POLYGONTYPE:
322  ngeoms += 1;
323  break;
324  case MULTIPOINTTYPE:
325  case MULTILINETYPE:
326  case MULTICURVETYPE:
327  case MULTIPOLYGONTYPE:
328  ngeoms += col->ngeoms;
329  break;
330  case COLLECTIONTYPE:
331  ngeoms += lwcollection_ngeoms((LWCOLLECTION*)col->geoms[i]);
332  break;
333  }
334  }
335  }
336  return ngeoms;
337 }
338 
340 {
341  int i;
342  if ( ! col ) return;
343 
344  if ( col->bbox )
345  {
346  lwfree(col->bbox);
347  }
348  for ( i = 0; i < col->ngeoms; i++ )
349  {
350  LWDEBUGF(4,"freeing geom[%d]", i);
351  if ( col->geoms && col->geoms[i] )
352  lwgeom_free(col->geoms[i]);
353  }
354  if ( col->geoms )
355  {
356  lwfree(col->geoms);
357  }
358  lwfree(col);
359 }
360 
361 
367 {
368  int i = 0;
369  LWGEOM **geomlist;
370  LWCOLLECTION *outcol;
371  int geomlistsize = 16;
372  int geomlistlen = 0;
373  uint8_t outtype;
374 
375  if ( ! col ) return NULL;
376 
377  switch (type)
378  {
379  case POINTTYPE:
380  outtype = MULTIPOINTTYPE;
381  break;
382  case LINETYPE:
383  outtype = MULTILINETYPE;
384  break;
385  case POLYGONTYPE:
386  outtype = MULTIPOLYGONTYPE;
387  break;
388  default:
389  lwerror("Only POLYGON, LINESTRING and POINT are supported by lwcollection_extract. %s requested.", lwtype_name(type));
390  return NULL;
391  }
392 
393  geomlist = lwalloc(sizeof(LWGEOM*) * geomlistsize);
394 
395  /* Process each sub-geometry */
396  for ( i = 0; i < col->ngeoms; i++ )
397  {
398  int subtype = col->geoms[i]->type;
399  /* Don't bother adding empty sub-geometries */
400  if ( lwgeom_is_empty(col->geoms[i]) )
401  {
402  continue;
403  }
404  /* Copy our sub-types into the output list */
405  if ( subtype == type )
406  {
407  /* We've over-run our buffer, double the memory segment */
408  if ( geomlistlen == geomlistsize )
409  {
410  geomlistsize *= 2;
411  geomlist = lwrealloc(geomlist, sizeof(LWGEOM*) * geomlistsize);
412  }
413  geomlist[geomlistlen] = lwgeom_clone(col->geoms[i]);
414  geomlistlen++;
415  }
416  /* Recurse into sub-collections */
417  if ( lwtype_is_collection( subtype ) )
418  {
419  int j = 0;
420  LWCOLLECTION *tmpcol = lwcollection_extract((LWCOLLECTION*)col->geoms[i], type);
421  for ( j = 0; j < tmpcol->ngeoms; j++ )
422  {
423  /* We've over-run our buffer, double the memory segment */
424  if ( geomlistlen == geomlistsize )
425  {
426  geomlistsize *= 2;
427  geomlist = lwrealloc(geomlist, sizeof(LWGEOM*) * geomlistsize);
428  }
429  geomlist[geomlistlen] = tmpcol->geoms[j];
430  geomlistlen++;
431  }
432  lwfree(tmpcol);
433  }
434  }
435 
436  if ( geomlistlen > 0 )
437  {
438  GBOX gbox;
439  outcol = lwcollection_construct(outtype, col->srid, NULL, geomlistlen, geomlist);
440  lwgeom_calculate_gbox((LWGEOM *) outcol, &gbox);
441  outcol->bbox = gbox_copy(&gbox);
442  }
443  else
444  {
445  lwfree(geomlist);
446  outcol = lwcollection_construct_empty(outtype, col->srid, FLAGS_GET_Z(col->flags), FLAGS_GET_M(col->flags));
447  }
448 
449  return outcol;
450 }
451 
452 LWGEOM*
453 lwcollection_remove_repeated_points(const LWCOLLECTION *coll, double tolerance)
454 {
455  uint32_t i;
456  LWGEOM **newgeoms;
457 
458  newgeoms = lwalloc(sizeof(LWGEOM *)*coll->ngeoms);
459  for (i=0; i<coll->ngeoms; i++)
460  {
461  newgeoms[i] = lwgeom_remove_repeated_points(coll->geoms[i], tolerance);
462  }
463 
464  return (LWGEOM*)lwcollection_construct(coll->type,
465  coll->srid, coll->bbox ? gbox_copy(coll->bbox) : NULL,
466  coll->ngeoms, newgeoms);
467 }
468 
469 
471 lwcollection_force_dims(const LWCOLLECTION *col, int hasz, int hasm)
472 {
473  LWCOLLECTION *colout;
474 
475  /* Return 2D empty */
476  if( lwcollection_is_empty(col) )
477  {
478  colout = lwcollection_construct_empty(col->type, col->srid, hasz, hasm);
479  }
480  else
481  {
482  int i;
483  LWGEOM **geoms = NULL;
484  geoms = lwalloc(sizeof(LWGEOM*) * col->ngeoms);
485  for( i = 0; i < col->ngeoms; i++ )
486  {
487  geoms[i] = lwgeom_force_dims(col->geoms[i], hasz, hasm);
488  }
489  colout = lwcollection_construct(col->type, col->srid, NULL, col->ngeoms, geoms);
490  }
491  return colout;
492 }
493 
495 {
496  int i;
497  if ( (col->ngeoms == 0) || (!col->geoms) )
498  return LW_TRUE;
499  for( i = 0; i < col->ngeoms; i++ )
500  {
501  if ( ! lwgeom_is_empty(col->geoms[i]) ) return LW_FALSE;
502  }
503  return LW_TRUE;
504 }
505 
506 
508 {
509  int i = 0;
510  int v = 0; /* vertices */
511  assert(col);
512  for ( i = 0; i < col->ngeoms; i++ )
513  {
514  v += lwgeom_count_vertices(col->geoms[i]);
515  }
516  return v;
517 }
518 
519 LWCOLLECTION* lwcollection_simplify(const LWCOLLECTION *igeom, double dist, int preserve_collapsed)
520 {
521  int i;
522  LWCOLLECTION *out = lwcollection_construct_empty(igeom->type, igeom->srid, FLAGS_GET_Z(igeom->flags), FLAGS_GET_M(igeom->flags));
523 
524  if( lwcollection_is_empty(igeom) )
525  return out; /* should we return NULL instead ? */
526 
527  for( i = 0; i < igeom->ngeoms; i++ )
528  {
529  LWGEOM *ngeom = lwgeom_simplify(igeom->geoms[i], dist, preserve_collapsed);
530  if ( ngeom ) out = lwcollection_add_lwgeom(out, ngeom);
531  }
532 
533  return out;
534 }
535 
536 int lwcollection_allows_subtype(int collectiontype, int subtype)
537 {
538  if ( collectiontype == COLLECTIONTYPE )
539  return LW_TRUE;
540  if ( collectiontype == MULTIPOINTTYPE &&
541  subtype == POINTTYPE )
542  return LW_TRUE;
543  if ( collectiontype == MULTILINETYPE &&
544  subtype == LINETYPE )
545  return LW_TRUE;
546  if ( collectiontype == MULTIPOLYGONTYPE &&
547  subtype == POLYGONTYPE )
548  return LW_TRUE;
549  if ( collectiontype == COMPOUNDTYPE &&
550  (subtype == LINETYPE || subtype == CIRCSTRINGTYPE) )
551  return LW_TRUE;
552  if ( collectiontype == CURVEPOLYTYPE &&
553  (subtype == CIRCSTRINGTYPE || subtype == LINETYPE || subtype == COMPOUNDTYPE) )
554  return LW_TRUE;
555  if ( collectiontype == MULTICURVETYPE &&
556  (subtype == CIRCSTRINGTYPE || subtype == LINETYPE || subtype == COMPOUNDTYPE) )
557  return LW_TRUE;
558  if ( collectiontype == MULTISURFACETYPE &&
559  (subtype == POLYGONTYPE || subtype == CURVEPOLYTYPE) )
560  return LW_TRUE;
561  if ( collectiontype == POLYHEDRALSURFACETYPE &&
562  subtype == POLYGONTYPE )
563  return LW_TRUE;
564  if ( collectiontype == TINTYPE &&
565  subtype == TRIANGLETYPE )
566  return LW_TRUE;
567 
568  /* Must be a bad combination! */
569  return LW_FALSE;
570 }
571 
572 int
574 {
575  if ( col->ngeoms < 1 )
576  return LW_FAILURE;
577 
578  return lwgeom_startpoint(col->geoms[0], pt);
579 }
580 
581 
583 {
584  uint32_t i;
585  LWCOLLECTION *newcoll;
586 
587  newcoll = lwcollection_construct_empty(coll->type, coll->srid, lwgeom_has_z((LWGEOM*)coll), lwgeom_has_m((LWGEOM*)coll));
588 
589  for (i=0; i<coll->ngeoms; i++)
590  {
591  LWGEOM *g = lwgeom_grid(coll->geoms[i], grid);
592  if ( g )
593  lwcollection_add_lwgeom(newcoll, g);
594  }
595 
596  return newcoll;
597 }
#define LINETYPE
Definition: liblwgeom.h:85
GBOX * gbox_copy(const GBOX *box)
Return a copy of the GBOX, based on dimensionality of flags.
Definition: g_box.c:438
void lwcollection_release(LWCOLLECTION *lwcollection)
Definition: lwcollection.c:36
void lwcollection_reserve(LWCOLLECTION *col, int ngeoms)
Ensure the collection can hold up at least ngeoms.
Definition: lwcollection.c:174
GBOX * bbox
Definition: liblwgeom.h:397
#define MULTICURVETYPE
Definition: liblwgeom.h:94
LWGEOM * lwgeom_grid(const LWGEOM *lwgeom, const gridspec *grid)
Definition: lwgeom.c:1881
int lwcollection_count_vertices(LWCOLLECTION *col)
Definition: lwcollection.c:507
void lwfree(void *mem)
Definition: lwutil.c:242
uint8_t type
Definition: liblwgeom.h:502
int lwgeom_startpoint(const LWGEOM *lwgeom, POINT4D *pt)
Definition: lwgeom.c:1850
#define POLYGONTYPE
Definition: liblwgeom.h:86
LWCOLLECTION * lwcollection_clone(const LWCOLLECTION *g)
Clone LWCOLLECTION object.
Definition: lwcollection.c:123
#define CURVEPOLYTYPE
Definition: liblwgeom.h:93
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1063
#define COMPOUNDTYPE
Definition: liblwgeom.h:92
#define MULTIPOINTTYPE
Definition: liblwgeom.h:87
GBOX * bbox
Definition: liblwgeom.h:504
#define FLAGS_GET_ZM(flags)
Definition: liblwgeom.h:152
void lwcollection_free(LWCOLLECTION *col)
Definition: lwcollection.c:339
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:83
#define TRIANGLETYPE
Definition: liblwgeom.h:97
#define POLYHEDRALSURFACETYPE
Definition: liblwgeom.h:96
LWCOLLECTION * lwcollection_segmentize2d(LWCOLLECTION *col, double dist)
Definition: lwcollection.c:236
LWGEOM * lwgeom_clone_deep(const LWGEOM *lwgeom)
Deep clone an LWGEOM, everything is copied.
Definition: lwgeom.c:446
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition: lwgeom.c:849
LWCOLLECTION * lwcollection_grid(const LWCOLLECTION *coll, const gridspec *grid)
Definition: lwcollection.c:582
int lwcollection_is_empty(const LWCOLLECTION *col)
Definition: lwcollection.c:494
#define LW_FAILURE
Definition: liblwgeom.h:78
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int srid, char hasz, char hasm)
Definition: lwcollection.c:94
int lwgeom_calculate_gbox(const LWGEOM *lwgeom, GBOX *gbox)
Calculate bounding box of a geometry, automatically taking into account whether it is cartesian or ge...
Definition: lwgeom.c:665
uint8_t flags
Definition: liblwgeom.h:503
LWCOLLECTION * lwcollection_construct(uint8_t type, int srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:43
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:216
#define LW_FALSE
Definition: liblwgeom.h:76
LWCOLLECTION * lwcollection_extract(LWCOLLECTION *col, int type)
Takes a potentially heterogeneous collection and returns a homogeneous collection consisting only of ...
Definition: lwcollection.c:366
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
Definition: lwcollection.c:187
int lwcollection_ngeoms(const LWCOLLECTION *col)
Definition: lwcollection.c:301
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:75
LWGEOM ** geoms
Definition: liblwgeom.h:508
LWGEOM * lwgeom_simplify(const LWGEOM *igeom, double dist, int preserve_collapsed)
Definition: lwgeom.c:1571
#define TINTYPE
Definition: liblwgeom.h:98
int lwtype_is_collection(uint8_t type)
Determine whether a type number is a collection or not.
Definition: lwgeom.c:1012
char lwcollection_same(const LWCOLLECTION *c1, const LWCOLLECTION *c2)
check for same geometry composition
Definition: lwcollection.c:261
int lwcollection_allows_subtype(int collectiontype, int subtype)
Check if subtype is allowed in collectiontype.
Definition: lwcollection.c:536
int32_t srid
Definition: liblwgeom.h:505
LWCOLLECTION * lwcollection_clone_deep(const LWCOLLECTION *g)
Deep clone LWCOLLECTION object.
Definition: lwcollection.c:149
#define FLAGS_GET_Z(flags)
Macros for manipulating the &#39;flags&#39; byte.
Definition: liblwgeom.h:139
LWGEOM * lwgeom_force_dims(const LWGEOM *lwgeom, int hasz, int hasm)
Definition: lwgeom.c:727
LWGEOM * lwgeom_clone(const LWGEOM *lwgeom)
Clone LWGEOM object.
Definition: lwgeom.c:408
char lwgeom_same(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2)
geom1 same as geom2 iff
Definition: lwgeom.c:508
uint8_t gflags(int hasz, int hasm, int geodetic)
Construct a new flags char.
Definition: g_util.c:145
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:89
#define FLAGS_SET_BBOX(flags, value)
Definition: liblwgeom.h:147
LWCOLLECTION * lwcollection_force_dims(const LWCOLLECTION *col, int hasz, int hasm)
Definition: lwcollection.c:471
int lwcollection_startpoint(const LWCOLLECTION *col, POINT4D *pt)
Definition: lwcollection.c:573
LWGEOM * lwcollection_remove_repeated_points(const LWCOLLECTION *coll, double tolerance)
Definition: lwcollection.c:453
#define MULTISURFACETYPE
Definition: liblwgeom.h:95
LWGEOM * lwcollection_getsubgeom(LWCOLLECTION *col, int gnum)
Definition: lwcollection.c:113
void * lwrealloc(void *mem, size_t size)
Definition: lwutil.c:235
LWGEOM * lwgeom_segmentize2d(LWGEOM *line, double dist)
Definition: lwgeom.c:681
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:84
#define FLAGS_GET_M(flags)
Definition: liblwgeom.h:140
void lwgeom_release(LWGEOM *lwgeom)
Free the containing LWGEOM and the associated BOX.
Definition: lwgeom.c:385
uint8_t type
Definition: liblwgeom.h:395
type
Definition: ovdump.py:41
LWGEOM * lwgeom_remove_repeated_points(const LWGEOM *in, double tolerance)
Remove repeated points!
Definition: lwgeom.c:1420
#define CIRCSTRINGTYPE
Definition: liblwgeom.h:91
void * lwalloc(size_t size)
Definition: lwutil.c:227
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:1310
int lwgeom_count_vertices(const LWGEOM *geom)
Count the total number of vertices in any LWGEOM.
Definition: lwgeom.c:1153
#define MULTILINETYPE
Definition: liblwgeom.h:88
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
Definition: lwgeom.c:856
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:102
LWCOLLECTION * lwcollection_simplify(const LWCOLLECTION *igeom, double dist, int preserve_collapsed)
Definition: lwcollection.c:519
#define COLLECTIONTYPE
Definition: liblwgeom.h:90
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
Definition: lwgeom.c:232
Snap to grid.