PostGIS  2.5.0dev-r@@SVN_REVISION@@
static GEOSGeometry * LWGEOM_GEOS_makeValid ( const GEOSGeometry *  gin)
static

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

References GEOS2LWGEOM(), LWDEBUGF, lwerror(), lwgeom_geos_errmsg, LWGEOM_GEOS_makeValidCollection(), LWGEOM_GEOS_makeValidLine(), LWGEOM_GEOS_makeValidMultiLine(), LWGEOM_GEOS_makeValidPolygon(), lwgeom_to_ewkt(), and lwnotice().

Referenced by LWGEOM_GEOS_makeValidCollection(), and lwgeom_make_valid().

844 {
845  GEOSGeometry* gout;
846  char ret_char;
847 
848  /*
849  * Step 2: return what we got so far if already valid
850  */
851 
852  ret_char = GEOSisValid(gin);
853  if ( ret_char == 2 )
854  {
855  /* I don't think should ever happen */
856  lwerror("GEOSisValid(): %s", lwgeom_geos_errmsg);
857  return NULL;
858  }
859  else if ( ret_char )
860  {
861  LWDEBUGF(3,
862  "Geometry [%s] is valid. ",
863  lwgeom_to_ewkt(GEOS2LWGEOM(gin, 0)));
864 
865  /* It's valid at this step, return what we have */
866  return GEOSGeom_clone(gin);
867  }
868 
869  LWDEBUGF(3,
870  "Geometry [%s] is still not valid: %s. "
871  "Will try to clean up further.",
873 
874 
875 
876  /*
877  * Step 3 : make what we got valid
878  */
879 
880  switch (GEOSGeomTypeId(gin))
881  {
882  case GEOS_MULTIPOINT:
883  case GEOS_POINT:
884  /* points are always valid, but we might have invalid ordinate values */
885  lwnotice("PUNTUAL geometry resulted invalid to GEOS -- dunno how to clean that up");
886  return NULL;
887  break;
888 
889  case GEOS_LINESTRING:
890  gout = LWGEOM_GEOS_makeValidLine(gin);
891  if ( ! gout ) /* an exception or something */
892  {
893  /* cleanup and throw */
895  return NULL;
896  }
897  break; /* we've done */
898 
899  case GEOS_MULTILINESTRING:
900  gout = LWGEOM_GEOS_makeValidMultiLine(gin);
901  if ( ! gout ) /* an exception or something */
902  {
903  /* cleanup and throw */
905  return NULL;
906  }
907  break; /* we've done */
908 
909  case GEOS_POLYGON:
910  case GEOS_MULTIPOLYGON:
911  {
912  gout = LWGEOM_GEOS_makeValidPolygon(gin);
913  if ( ! gout ) /* an exception or something */
914  {
915  /* cleanup and throw */
917  return NULL;
918  }
919  break; /* we've done */
920  }
921 
922  case GEOS_GEOMETRYCOLLECTION:
923  {
925  if ( ! gout ) /* an exception or something */
926  {
927  /* cleanup and throw */
929  return NULL;
930  }
931  break; /* we've done */
932  }
933 
934  default:
935  {
936  char* typname = GEOSGeomType(gin);
937  lwnotice("ST_MakeValid: doesn't support geometry type: %s",
938  typname);
939  GEOSFree(typname);
940  return NULL;
941  break;
942  }
943  }
944 
945 #if PARANOIA_LEVEL > 1
946  /*
947  * Now check if every point of input is also found
948  * in output, or abort by returning NULL
949  *
950  * Input geometry was lwgeom_in
951  */
952  {
953  int loss;
954  GEOSGeometry *pi, *po, *pd;
955 
956  /* TODO: handle some errors here...
957  * Lack of exceptions is annoying indeed,
958  * I'm getting old --strk;
959  */
960  pi = GEOSGeom_extractUniquePoints(gin);
961  po = GEOSGeom_extractUniquePoints(gout);
962  pd = GEOSDifference(pi, po); /* input points - output points */
963  GEOSGeom_destroy(pi);
964  GEOSGeom_destroy(po);
965  loss = !GEOSisEmpty(pd);
966  GEOSGeom_destroy(pd);
967  if ( loss )
968  {
969  lwnotice("%s [%d] Vertices lost in LWGEOM_GEOS_makeValid", __FILE__, __LINE__);
970  /* return NULL */
971  }
972  }
973 #endif /* PARANOIA_LEVEL > 1 */
974 
975 
976  return gout;
977 }
static GEOSGeometry * LWGEOM_GEOS_makeValidPolygon(const GEOSGeometry *gin)
void lwnotice(const char *fmt,...)
Write a notice out to the notice handler.
Definition: lwutil.c:177
char * lwgeom_to_ewkt(const LWGEOM *lwgeom)
Return an alloced string.
Definition: lwgeom.c:549
char lwgeom_geos_errmsg[LWGEOM_GEOS_ERRMSG_MAXSIZE]
static GEOSGeometry * LWGEOM_GEOS_makeValidLine(const GEOSGeometry *gin)
LWGEOM * GEOS2LWGEOM(const GEOSGeometry *geom, char want3d)
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
static GEOSGeometry * LWGEOM_GEOS_makeValidMultiLine(const GEOSGeometry *gin)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
static GEOSGeometry * LWGEOM_GEOS_makeValidCollection(const GEOSGeometry *gin)

Here is the call graph for this function:

Here is the caller graph for this function: