PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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: