PostGIS  3.1.6dev-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 984 of file mvt.c.

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

References GEOS2LWGEOM(), LWGEOM2GEOS(), lwgeom_force_clockwise(), lwgeom_geos_error(), 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: