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

Definition at line 841 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().

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

Here is the call graph for this function:

Here is the caller graph for this function: