PostGIS  3.0.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 1020 of file mvt.c.

1021 {
1022  gridspec grid = {0, 0, 0, 0, 1, 1, 0, 0};
1023  ng = lwgeom_to_basic_type(ng, basic_type);
1024 
1025  if (basic_type != POLYGONTYPE)
1026  {
1027  /* Make sure there is no pending float values (clipping can do that) */
1028  lwgeom_grid_in_place(ng, &grid);
1029  }
1030  else
1031  {
1032  /* For polygons we have to both snap to the integer grid and force validation.
1033  * The problem with this procedure is that snapping to the grid can create
1034  * an invalid geometry and making it valid can create float values; so
1035  * we iterate several times (up to 3) to generate a valid geom with int coordinates
1036  */
1037  GEOSGeometry *geo;
1038  uint32_t iterations = 0;
1039  static const uint32_t max_iterations = 3;
1040  bool valid = false;
1041 
1042  /* Grid to int */
1043  lwgeom_grid_in_place(ng, &grid);
1044 
1046  geo = LWGEOM2GEOS(ng, 0);
1047  if (!geo)
1048  return NULL;
1049  valid = GEOSisValid(geo) == 1;
1050 
1051  while (!valid && iterations < max_iterations)
1052  {
1053 #if POSTGIS_GEOS_VERSION < 38
1054  GEOSGeometry *geo_valid = LWGEOM_GEOS_makeValid(geo);
1055 #else
1056  GEOSGeometry *geo_valid = GEOSMakeValid(geo);
1057 #endif
1058 
1059  GEOSGeom_destroy(geo);
1060  if (!geo_valid)
1061  return NULL;
1062 
1063  ng = GEOS2LWGEOM(geo_valid, 0);
1064  GEOSGeom_destroy(geo_valid);
1065  if (!ng)
1066  return NULL;
1067 
1068  lwgeom_grid_in_place(ng, &grid);
1069  ng = lwgeom_to_basic_type(ng, basic_type);
1070  geo = LWGEOM2GEOS(ng, 0);
1071  valid = GEOSisValid(geo) == 1;
1072  iterations++;
1073  }
1074  GEOSGeom_destroy(geo);
1075 
1076  if (!valid)
1077  {
1078  POSTGIS_DEBUG(1, "mvt_geom: Could not transform into a valid MVT geometry");
1079  return NULL;
1080  }
1081 
1082  /* In image coordinates CW actually comes out a CCW, so we reverse */
1085  }
1086  return ng;
1087 }
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:37
void lwgeom_grid_in_place(LWGEOM *lwgeom, const gridspec *grid)
Definition: lwgeom.c:2144
void lwgeom_reverse_in_place(LWGEOM *lwgeom)
Reverse vertex order of LWGEOM.
Definition: lwgeom.c:102
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:823
Snap-to-grid.
Definition: liblwgeom.h:1341

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: