PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ LWGEOM_GEOS_makeValid()

static GEOSGeometry * LWGEOM_GEOS_makeValid ( const GEOSGeometry *  gin)
static

Definition at line 844 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(), LWGEOM_GEOS_makeValidMultiLine(), and lwgeom_make_valid().

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