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

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

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

Here is the call graph for this function:

Here is the caller graph for this function: