PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ mvt_grid_and_validate_geos()

static LWGEOM* mvt_grid_and_validate_geos ( LWGEOM ng,
uint8_t  basic_type 
)
static

Given a geometry, it uses GEOS operations to make sure that it's valid according to the MVT spec and that all points are snapped into int coordinates It iterates several times if needed, if it fails, returns NULL.

Definition at line 968 of file mvt.c.

969 {
970  gridspec grid = {0, 0, 0, 0, 1, 1, 0, 0};
971  ng = lwgeom_to_basic_type(ng, basic_type);
972 
973  if (basic_type != POLYGONTYPE)
974  {
975  /* Make sure there is no pending float values (clipping can do that) */
976  lwgeom_grid_in_place(ng, &grid);
977  }
978  else
979  {
980  /* For polygons we have to both snap to the integer grid and force validation.
981  * The problem with this procedure is that snapping to the grid can create
982  * an invalid geometry and making it valid can create float values; so
983  * we iterate several times (up to 3) to generate a valid geom with int coordinates
984  */
985  GEOSGeometry *geo;
986  uint32_t iterations = 0;
987  static const uint32_t max_iterations = 3;
988  bool valid = false;
989 
990  /* Grid to int */
991  lwgeom_grid_in_place(ng, &grid);
992 
994  geo = LWGEOM2GEOS(ng, 0);
995  if (!geo)
996  return NULL;
997  valid = GEOSisValid(geo) == 1;
998 
999  while (!valid && iterations < max_iterations)
1000  {
1001 #if POSTGIS_GEOS_VERSION < 38
1002  GEOSGeometry *geo_valid = LWGEOM_GEOS_makeValid(geo);
1003 #else
1004  GEOSGeometry *geo_valid = GEOSMakeValid(geo);
1005 #endif
1006  GEOSGeom_destroy(geo);
1007  if (!geo_valid)
1008  return NULL;
1009 
1010  ng = GEOS2LWGEOM(geo_valid, 0);
1011  GEOSGeom_destroy(geo_valid);
1012  if (!ng)
1013  return NULL;
1014 
1015  lwgeom_grid_in_place(ng, &grid);
1016  ng = lwgeom_to_basic_type(ng, basic_type);
1017  geo = LWGEOM2GEOS(ng, 0);
1018  valid = GEOSisValid(geo) == 1;
1019  iterations++;
1020  }
1021  GEOSGeom_destroy(geo);
1022 
1023  if (!valid)
1024  {
1025  POSTGIS_DEBUG(1, "mvt_geom: Could not transform into a valid MVT geometry");
1026  return NULL;
1027  }
1028 
1029  /* In image coordinates CW actually comes out a CCW, so we reverse */
1032  }
1033  return ng;
1034 }
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom, uint8_t autofix)
LWGEOM * GEOS2LWGEOM(const GEOSGeometry *geom, uint8_t want3d)
void lwgeom_geos_error(const char *fmt,...)
GEOSGeometry * LWGEOM_GEOS_makeValid(const GEOSGeometry *)
#define POLYGONTYPE
Definition: liblwgeom.h:87
void lwgeom_force_clockwise(LWGEOM *lwgeom)
Force Right-hand-rule on LWGEOM polygons.
Definition: lwgeom.c:37
void lwgeom_reverse_in_place(LWGEOM *lwgeom)
Reverse vertex order of LWGEOM.
Definition: lwgeom.c:102
void lwgeom_grid_in_place(LWGEOM *lwgeom, const gridspec *grid)
Definition: lwgeom.c:2152
static LWGEOM * lwgeom_to_basic_type(LWGEOM *geom, uint8 original_type)
In place process a collection to find a concrete geometry object and expose that as the actual object...
Definition: mvt.c:771
Snap to grid.
unsigned int uint32_t
Definition: uthash.h:78

References GEOS2LWGEOM(), LWGEOM2GEOS(), lwgeom_force_clockwise(), lwgeom_geos_error(), LWGEOM_GEOS_makeValid(), lwgeom_grid_in_place(), lwgeom_reverse_in_place(), lwgeom_to_basic_type(), and POLYGONTYPE.

Referenced by mvt_clip_and_validate_geos().

Here is the call graph for this function:
Here is the caller graph for this function: