PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ LWGEOM_GEOS_makeValidMultiLine()

static GEOSGeometry* LWGEOM_GEOS_makeValidMultiLine ( const GEOSGeometry *  gin)
static

Definition at line 678 of file liblwgeom/lwgeom_geos_clean.c.

References lwalloc(), lwerror(), lwfree(), LWGEOM_GEOS_makeValid(), LWGEOM_GEOS_makeValidLine(), and lwrealloc().

Referenced by LWGEOM_GEOS_makeValid().

679 {
680  GEOSGeometry** lines;
681  GEOSGeometry** points;
682  GEOSGeometry* mline_out=0;
683  GEOSGeometry* mpoint_out=0;
684  GEOSGeometry* gout=0;
685  uint32_t nlines=0, nlines_alloc;
686  uint32_t npoints=0;
687  uint32_t ngeoms=0, nsubgeoms;
688  uint32_t i, j;
689 
690  ngeoms = GEOSGetNumGeometries(gin);
691 
692  nlines_alloc = ngeoms;
693  lines = lwalloc(sizeof(GEOSGeometry*)*nlines_alloc);
694  points = lwalloc(sizeof(GEOSGeometry*)*ngeoms);
695 
696  for (i=0; i<ngeoms; ++i)
697  {
698  const GEOSGeometry* g = GEOSGetGeometryN(gin, i);
699  GEOSGeometry* vg;
701  /* Drop any invalid or empty geometry */
702  if (!vg)
703  continue;
704  if (GEOSisEmpty(vg))
705  {
706  GEOSGeom_destroy(vg);
707  continue;
708  }
709  if ( GEOSGeomTypeId(vg) == GEOS_POINT )
710  {
711  points[npoints++] = vg;
712  }
713  else if ( GEOSGeomTypeId(vg) == GEOS_LINESTRING )
714  {
715  lines[nlines++] = vg;
716  }
717  else if ( GEOSGeomTypeId(vg) == GEOS_MULTILINESTRING )
718  {
719  nsubgeoms=GEOSGetNumGeometries(vg);
720  nlines_alloc += nsubgeoms;
721  lines = lwrealloc(lines, sizeof(GEOSGeometry*)*nlines_alloc);
722  for (j=0; j<nsubgeoms; ++j)
723  {
724  const GEOSGeometry* gc = GEOSGetGeometryN(vg, j);
725  /* NOTE: ownership of the cloned geoms will be
726  * taken by final collection */
727  lines[nlines++] = GEOSGeom_clone(gc);
728  }
729  }
730  else
731  {
732  /* NOTE: return from GEOSGeomType will leak
733  * but we really don't expect this to happen */
734  lwerror("unexpected geom type returned "
735  "by LWGEOM_GEOS_makeValid: %s",
736  GEOSGeomType(vg));
737  }
738  }
739 
740  if ( npoints )
741  {
742  if ( npoints > 1 )
743  {
744  mpoint_out = GEOSGeom_createCollection(GEOS_MULTIPOINT,
745  points, npoints);
746  }
747  else
748  {
749  mpoint_out = points[0];
750  }
751  }
752 
753  if ( nlines )
754  {
755  if ( nlines > 1 )
756  {
757  mline_out = GEOSGeom_createCollection(
758  GEOS_MULTILINESTRING, lines, nlines);
759  }
760  else
761  {
762  mline_out = lines[0];
763  }
764  }
765 
766  lwfree(lines);
767 
768  if ( mline_out && mpoint_out )
769  {
770  points[0] = mline_out;
771  points[1] = mpoint_out;
772  gout = GEOSGeom_createCollection(GEOS_GEOMETRYCOLLECTION,
773  points, 2);
774  }
775  else if ( mline_out )
776  {
777  gout = mline_out;
778  }
779  else if ( mpoint_out )
780  {
781  gout = mpoint_out;
782  }
783 
784  lwfree(points);
785 
786  return gout;
787 }
void lwfree(void *mem)
Definition: lwutil.c:244
unsigned int uint32_t
Definition: uthash.h:78
static GEOSGeometry * LWGEOM_GEOS_makeValidLine(const GEOSGeometry *gin)
void * lwrealloc(void *mem, size_t size)
Definition: lwutil.c:237
void * lwalloc(size_t size)
Definition: lwutil.c:229
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
Here is the call graph for this function:
Here is the caller graph for this function: