PostGIS  2.4.9dev-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 
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  lwerror("%s [%d] found duplicate geometry in collection %p == %p", __FILE__, __LINE__, col->geoms[i], geom);
223  LWDEBUGF(4, "Found duplicate geometry in collection %p == %p", col->geoms[i], geom);
224  return col;
225  }
226  }
227  }
228 #endif
229 
230  col->geoms[col->ngeoms] = (LWGEOM*)geom;
231  col->ngeoms++;
232  return col;
233 }
234 
235 
236 LWCOLLECTION *
238 {
239  uint32_t i;
240  LWGEOM **newgeoms;
241 
242  if ( ! col->ngeoms ) return lwcollection_clone(col);
243 
244  newgeoms = lwalloc(sizeof(LWGEOM *)*col->ngeoms);
245  for (i=0; i<col->ngeoms; i++)
246  {
247  newgeoms[i] = lwgeom_segmentize2d(col->geoms[i], dist);
248  if ( ! newgeoms[i] ) {
249  while (i--) lwgeom_free(newgeoms[i]);
250  lwfree(newgeoms);
251  return NULL;
252  }
253  }
254 
255  return lwcollection_construct(col->type, col->srid, NULL, col->ngeoms, newgeoms);
256 }
257 
261 char
263 {
264  uint32_t i;
265 
266  LWDEBUG(2, "lwcollection_same called");
267 
268  if ( c1->type != c2->type ) return LW_FALSE;
269  if ( c1->ngeoms != c2->ngeoms ) return LW_FALSE;
270 
271  for ( i = 0; i < c1->ngeoms; i++ )
272  {
273  if ( ! lwgeom_same(c1->geoms[i], c2->geoms[i]) )
274  return LW_FALSE;
275  }
276 
277  /* Former method allowed out-of-order equality between collections
278 
279  hit = lwalloc(sizeof(uint32_t)*c1->ngeoms);
280  memset(hit, 0, sizeof(uint32_t)*c1->ngeoms);
281 
282  for (i=0; i<c1->ngeoms; i++)
283  {
284  char found=0;
285  for (j=0; j<c2->ngeoms; j++)
286  {
287  if ( hit[j] ) continue;
288  if ( lwgeom_same(c1->geoms[i], c2->geoms[j]) )
289  {
290  hit[j] = 1;
291  found=1;
292  break;
293  }
294  }
295  if ( ! found ) return LW_FALSE;
296  }
297  */
298 
299  return LW_TRUE;
300 }
301 
303 {
304  int i;
305  int ngeoms = 0;
306 
307  if ( ! col )
308  {
309  lwerror("Null input geometry.");
310  return 0;
311  }
312 
313  for ( i = 0; i < col->ngeoms; i++ )
314  {
315  if ( col->geoms[i])
316  {
317  switch (col->geoms[i]->type)
318  {
319  case POINTTYPE:
320  case LINETYPE:
321  case CIRCSTRINGTYPE:
322  case POLYGONTYPE:
323  ngeoms += 1;
324  break;
325  case MULTIPOINTTYPE:
326  case MULTILINETYPE:
327  case MULTICURVETYPE:
328  case MULTIPOLYGONTYPE:
329  ngeoms += col->ngeoms;
330  break;
331  case COLLECTIONTYPE:
332  ngeoms += lwcollection_ngeoms((LWCOLLECTION*)col->geoms[i]);
333  break;
334  }
335  }
336  }
337  return ngeoms;
338 }
339 
341 {
342  int i;
343  if ( ! col ) return;
344 
345  if ( col->bbox )
346  {
347  lwfree(col->bbox);
348  }
349  for ( i = 0; i < col->ngeoms; i++ )
350  {
351  LWDEBUGF(4,"freeing geom[%d]", i);
352  if ( col->geoms && col->geoms[i] )
353  lwgeom_free(col->geoms[i]);
354  }
355  if ( col->geoms )
356  {
357  lwfree(col->geoms);
358  }
359  lwfree(col);
360 }
361 
362 
370 {
371  int i = 0;
372  LWGEOM **geomlist;
373  LWCOLLECTION *outcol;
374  int geomlistsize = 16;
375  int geomlistlen = 0;
376  uint8_t outtype;
377 
378  if ( ! col ) return NULL;
379 
380  switch (type)
381  {
382  case POINTTYPE:
383  outtype = MULTIPOINTTYPE;
384  break;
385  case LINETYPE:
386  outtype = MULTILINETYPE;
387  break;
388  case POLYGONTYPE:
389  outtype = MULTIPOLYGONTYPE;
390  break;
391  default:
392  lwerror("Only POLYGON, LINESTRING and POINT are supported by lwcollection_extract. %s requested.", lwtype_name(type));
393  return NULL;
394  }
395 
396  geomlist = lwalloc(sizeof(LWGEOM*) * geomlistsize);
397 
398  /* Process each sub-geometry */
399  for ( i = 0; i < col->ngeoms; i++ )
400  {
401  int subtype = col->geoms[i]->type;
402  /* Don't bother adding empty sub-geometries */
403  if ( lwgeom_is_empty(col->geoms[i]) )
404  {
405  continue;
406  }
407  /* Copy our sub-types into the output list */
408  if ( subtype == type )
409  {
410  /* We've over-run our buffer, double the memory segment */
411  if ( geomlistlen == geomlistsize )
412  {
413  geomlistsize *= 2;
414  geomlist = lwrealloc(geomlist, sizeof(LWGEOM*) * geomlistsize);
415  }
416  geomlist[geomlistlen] = lwgeom_clone(col->geoms[i]);
417  geomlistlen++;
418  }
419  /* Recurse into sub-collections */
420  if ( lwtype_is_collection( subtype ) )
421  {
422  int j = 0;
423  LWCOLLECTION *tmpcol = lwcollection_extract((LWCOLLECTION*)col->geoms[i], type);
424  for ( j = 0; j < tmpcol->ngeoms; j++ )
425  {
426  /* We've over-run our buffer, double the memory segment */
427  if ( geomlistlen == geomlistsize )
428  {
429  geomlistsize *= 2;
430  geomlist = lwrealloc(geomlist, sizeof(LWGEOM*) * geomlistsize);
431  }
432  geomlist[geomlistlen] = tmpcol->geoms[j];
433  geomlistlen++;
434  }
435  if (tmpcol->geoms)
436  lwfree(tmpcol->geoms);
437  if (tmpcol->bbox)
438  lwfree(tmpcol->bbox);
439  lwfree(tmpcol);
440  }
441  }
442 
443  if ( geomlistlen > 0 )
444  {
445  GBOX gbox;
446  outcol = lwcollection_construct(outtype, col->srid, NULL, geomlistlen, geomlist);
447  lwgeom_calculate_gbox((LWGEOM *) outcol, &gbox);
448  outcol->bbox = gbox_copy(&gbox);
449  }
450  else
451  {
452  lwfree(geomlist);
453  outcol = lwcollection_construct_empty(outtype, col->srid, FLAGS_GET_Z(col->flags), FLAGS_GET_M(col->flags));
454  }
455 
456  return outcol;
457 }
458 
459 LWGEOM*
460 lwcollection_remove_repeated_points(const LWCOLLECTION *coll, double tolerance)
461 {
462  uint32_t i;
463  LWGEOM **newgeoms;
464 
465  newgeoms = lwalloc(sizeof(LWGEOM *)*coll->ngeoms);
466  for (i=0; i<coll->ngeoms; i++)
467  {
468  newgeoms[i] = lwgeom_remove_repeated_points(coll->geoms[i], tolerance);
469  }
470 
471  return (LWGEOM*)lwcollection_construct(coll->type,
472  coll->srid, coll->bbox ? gbox_copy(coll->bbox) : NULL,
473  coll->ngeoms, newgeoms);
474 }
475 
476 
478 lwcollection_force_dims(const LWCOLLECTION *col, int hasz, int hasm)
479 {
480  LWCOLLECTION *colout;
481 
482  /* Return 2D empty */
483  if( lwcollection_is_empty(col) )
484  {
485  colout = lwcollection_construct_empty(col->type, col->srid, hasz, hasm);
486  }
487  else
488  {
489  int i;
490  LWGEOM **geoms = NULL;
491  geoms = lwalloc(sizeof(LWGEOM*) * col->ngeoms);
492  for( i = 0; i < col->ngeoms; i++ )
493  {
494  geoms[i] = lwgeom_force_dims(col->geoms[i], hasz, hasm);
495  }
496  colout = lwcollection_construct(col->type, col->srid, NULL, col->ngeoms, geoms);
497  }
498  return colout;
499 }
500 
502 {
503  int i;
504  if ( (col->ngeoms == 0) || (!col->geoms) )
505  return LW_TRUE;
506  for( i = 0; i < col->ngeoms; i++ )
507  {
508  if ( ! lwgeom_is_empty(col->geoms[i]) ) return LW_FALSE;
509  }
510  return LW_TRUE;
511 }
512 
513 
515 {
516  int i = 0;
517  int v = 0; /* vertices */
518  assert(col);
519  for ( i = 0; i < col->ngeoms; i++ )
520  {
521  v += lwgeom_count_vertices(col->geoms[i]);
522  }
523  return v;
524 }
525 
526 LWCOLLECTION* lwcollection_simplify(const LWCOLLECTION *igeom, double dist, int preserve_collapsed)
527 {
528  int i;
529  LWCOLLECTION *out = lwcollection_construct_empty(igeom->type, igeom->srid, FLAGS_GET_Z(igeom->flags), FLAGS_GET_M(igeom->flags));
530 
531  if( lwcollection_is_empty(igeom) )
532  return out; /* should we return NULL instead ? */
533 
534  for( i = 0; i < igeom->ngeoms; i++ )
535  {
536  LWGEOM *ngeom = lwgeom_simplify(igeom->geoms[i], dist, preserve_collapsed);
537  if ( ngeom ) out = lwcollection_add_lwgeom(out, ngeom);
538  }
539 
540  return out;
541 }
542 
543 int lwcollection_allows_subtype(int collectiontype, int subtype)
544 {
545  if ( collectiontype == COLLECTIONTYPE )
546  return LW_TRUE;
547  if ( collectiontype == MULTIPOINTTYPE &&
548  subtype == POINTTYPE )
549  return LW_TRUE;
550  if ( collectiontype == MULTILINETYPE &&
551  subtype == LINETYPE )
552  return LW_TRUE;
553  if ( collectiontype == MULTIPOLYGONTYPE &&
554  subtype == POLYGONTYPE )
555  return LW_TRUE;
556  if ( collectiontype == COMPOUNDTYPE &&
557  (subtype == LINETYPE || subtype == CIRCSTRINGTYPE) )
558  return LW_TRUE;
559  if ( collectiontype == CURVEPOLYTYPE &&
560  (subtype == CIRCSTRINGTYPE || subtype == LINETYPE || subtype == COMPOUNDTYPE) )
561  return LW_TRUE;
562  if ( collectiontype == MULTICURVETYPE &&
563  (subtype == CIRCSTRINGTYPE || subtype == LINETYPE || subtype == COMPOUNDTYPE) )
564  return LW_TRUE;
565  if ( collectiontype == MULTISURFACETYPE &&
566  (subtype == POLYGONTYPE || subtype == CURVEPOLYTYPE) )
567  return LW_TRUE;
568  if ( collectiontype == POLYHEDRALSURFACETYPE &&
569  subtype == POLYGONTYPE )
570  return LW_TRUE;
571  if ( collectiontype == TINTYPE &&
572  subtype == TRIANGLETYPE )
573  return LW_TRUE;
574 
575  /* Must be a bad combination! */
576  return LW_FALSE;
577 }
578 
579 int
581 {
582  if ( col->ngeoms < 1 )
583  return LW_FAILURE;
584 
585  return lwgeom_startpoint(col->geoms[0], pt);
586 }
587 
588 
590 {
591  uint32_t i;
592  LWCOLLECTION *newcoll;
593 
594  newcoll = lwcollection_construct_empty(coll->type, coll->srid, lwgeom_has_z((LWGEOM*)coll), lwgeom_has_m((LWGEOM*)coll));
595 
596  for (i=0; i<coll->ngeoms; i++)
597  {
598  LWGEOM *g = lwgeom_grid(coll->geoms[i], grid);
599  if ( g )
600  lwcollection_add_lwgeom(newcoll, g);
601  }
602 
603  return newcoll;
604 }
#define LINETYPE
Definition: liblwgeom.h:86
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:398
#define MULTICURVETYPE
Definition: liblwgeom.h:95
LWGEOM * lwgeom_grid(const LWGEOM *lwgeom, const gridspec *grid)
Definition: lwgeom.c:1912
int lwcollection_count_vertices(LWCOLLECTION *col)
Definition: lwcollection.c:514
void lwfree(void *mem)
Definition: lwutil.c:244
uint8_t type
Definition: liblwgeom.h:503
int lwgeom_startpoint(const LWGEOM *lwgeom, POINT4D *pt)
Definition: lwgeom.c:1881
#define POLYGONTYPE
Definition: liblwgeom.h:87
LWCOLLECTION * lwcollection_clone(const LWCOLLECTION *g)
Clone LWCOLLECTION object.
Definition: lwcollection.c:123
#define CURVEPOLYTYPE
Definition: liblwgeom.h:94
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1099
#define COMPOUNDTYPE
Definition: liblwgeom.h:93
#define MULTIPOINTTYPE
Definition: liblwgeom.h:88
GBOX * bbox
Definition: liblwgeom.h:505
#define FLAGS_GET_ZM(flags)
Definition: liblwgeom.h:153
void lwcollection_free(LWCOLLECTION *col)
Definition: lwcollection.c:340
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:83
#define TRIANGLETYPE
Definition: liblwgeom.h:98
#define POLYHEDRALSURFACETYPE
Definition: liblwgeom.h:97
LWCOLLECTION * lwcollection_segmentize2d(LWCOLLECTION *col, double dist)
Definition: lwcollection.c:237
LWGEOM * lwgeom_clone_deep(const LWGEOM *lwgeom)
Deep clone an LWGEOM, everything is copied.
Definition: lwgeom.c:482
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition: lwgeom.c:885
LWCOLLECTION * lwcollection_grid(const LWCOLLECTION *coll, const gridspec *grid)
Definition: lwcollection.c:589
int lwcollection_is_empty(const LWCOLLECTION *col)
Definition: lwcollection.c:501
#define LW_FAILURE
Definition: liblwgeom.h:79
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int srid, char hasz, char hasm)
Definition: lwcollection.c:94
unsigned int uint32_t
Definition: uthash.h:78
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:701
uint8_t flags
Definition: liblwgeom.h:504
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:218
#define LW_FALSE
Definition: liblwgeom.h:77
LWCOLLECTION * lwcollection_extract(LWCOLLECTION *col, int type)
Takes a potentially heterogeneous collection and returns a homogeneous collection consisting only of ...
Definition: lwcollection.c:369
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:302
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:76
LWGEOM ** geoms
Definition: liblwgeom.h:509
LWGEOM * lwgeom_simplify(const LWGEOM *igeom, double dist, int preserve_collapsed)
Definition: lwgeom.c:1602
#define TINTYPE
Definition: liblwgeom.h:99
int lwtype_is_collection(uint8_t type)
Determine whether a type number is a collection or not.
Definition: lwgeom.c:1048
char lwcollection_same(const LWCOLLECTION *c1, const LWCOLLECTION *c2)
check for same geometry composition
Definition: lwcollection.c:262
int lwcollection_allows_subtype(int collectiontype, int subtype)
Check if subtype is allowed in collectiontype.
Definition: lwcollection.c:543
int32_t srid
Definition: liblwgeom.h:506
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:140
LWGEOM * lwgeom_force_dims(const LWGEOM *lwgeom, int hasz, int hasm)
Definition: lwgeom.c:763
LWGEOM * lwgeom_clone(const LWGEOM *lwgeom)
Clone LWGEOM object.
Definition: lwgeom.c:444
char lwgeom_same(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2)
geom1 same as geom2 iff
Definition: lwgeom.c:544
uint8_t gflags(int hasz, int hasm, int geodetic)
Construct a new flags char.
Definition: g_util.c:145
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:90
#define FLAGS_SET_BBOX(flags, value)
Definition: liblwgeom.h:148
LWCOLLECTION * lwcollection_force_dims(const LWCOLLECTION *col, int hasz, int hasm)
Definition: lwcollection.c:478
int lwcollection_startpoint(const LWCOLLECTION *col, POINT4D *pt)
Definition: lwcollection.c:580
LWGEOM * lwcollection_remove_repeated_points(const LWCOLLECTION *coll, double tolerance)
Definition: lwcollection.c:460
#define MULTISURFACETYPE
Definition: liblwgeom.h:96
LWGEOM * lwcollection_getsubgeom(LWCOLLECTION *col, int gnum)
Definition: lwcollection.c:113
void * lwrealloc(void *mem, size_t size)
Definition: lwutil.c:237
LWGEOM * lwgeom_segmentize2d(LWGEOM *line, double dist)
Definition: lwgeom.c:717
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:85
#define FLAGS_GET_M(flags)
Definition: liblwgeom.h:141
void lwgeom_release(LWGEOM *lwgeom)
Free the containing LWGEOM and the associated BOX.
Definition: lwgeom.c:421
uint8_t type
Definition: liblwgeom.h:396
type
Definition: ovdump.py:41
LWGEOM * lwgeom_remove_repeated_points(const LWGEOM *in, double tolerance)
Remove repeated points!
Definition: lwgeom.c:1456
#define CIRCSTRINGTYPE
Definition: liblwgeom.h:92
void * lwalloc(size_t size)
Definition: lwutil.c:229
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:1346
int lwgeom_count_vertices(const LWGEOM *geom)
Count the total number of vertices in any LWGEOM.
Definition: lwgeom.c:1189
#define MULTILINETYPE
Definition: liblwgeom.h:89
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
unsigned char uint8_t
Definition: uthash.h:79
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
Definition: lwgeom.c:892
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
LWCOLLECTION * lwcollection_simplify(const LWCOLLECTION *igeom, double dist, int preserve_collapsed)
Definition: lwcollection.c:526
#define COLLECTIONTYPE
Definition: liblwgeom.h:91
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
Definition: lwgeom.c:268
Snap to grid.