[postgis-tickets] r15835 - Triangles un-closed in M should be WKT parseable (Closes #3818)
Paul Ramsey
pramsey at cleverelephant.ca
Tue Sep 26 10:04:17 PDT 2017
Author: pramsey
Date: 2017-09-26 10:04:17 -0700 (Tue, 26 Sep 2017)
New Revision: 15835
Modified:
branches/2.3/NEWS
branches/2.3/liblwgeom/lwin_wkb.c
branches/2.3/liblwgeom/lwin_wkt.c
Log:
Triangles un-closed in M should be WKT parseable (Closes #3818)
Modified: branches/2.3/NEWS
===================================================================
--- branches/2.3/NEWS 2017-09-26 16:59:15 UTC (rev 15834)
+++ branches/2.3/NEWS 2017-09-26 17:04:17 UTC (rev 15835)
@@ -21,6 +21,7 @@
- #2836, Receiving ERROR: ExteriorRing: geom is
not a polygon with ST_ConcaveHull
- #3781, Not-quite curved CurvePolygon rejected by ST_Contains
+ - #3818, Triangles unclosed in M should be parseable
PostGIS 2.3.3
Modified: branches/2.3/liblwgeom/lwin_wkb.c
===================================================================
--- branches/2.3/liblwgeom/lwin_wkb.c 2017-09-26 16:59:15 UTC (rev 15834)
+++ branches/2.3/liblwgeom/lwin_wkb.c 2017-09-26 17:04:17 UTC (rev 15835)
@@ -576,12 +576,6 @@
return NULL;
}
- if( s->check & LW_PARSER_CHECK_CLOSURE && ! ptarray_is_closed(pa) )
- {
- lwerror("%s must have closed rings", lwtype_name(s->lwtype));
- return NULL;
- }
-
if( s->check & LW_PARSER_CHECK_ZCLOSURE && ! ptarray_is_closed_z(pa) )
{
lwerror("%s must have closed rings", lwtype_name(s->lwtype));
Modified: branches/2.3/liblwgeom/lwin_wkt.c
===================================================================
--- branches/2.3/liblwgeom/lwin_wkt.c 2017-09-26 16:59:15 UTC (rev 15834)
+++ branches/2.3/liblwgeom/lwin_wkt.c 2017-09-26 17:04:17 UTC (rev 15835)
@@ -54,7 +54,7 @@
global_parser_result.errcode = (errno); \
global_parser_result.errlocation = wkt_yylloc.last_column; \
}
-
+
/**
* Read the SRID number from an SRID=<> string
*/
@@ -76,10 +76,10 @@
{
int i = 0;
uint8_t flags = 0;
-
+
if( ! dimensionality )
return flags;
-
+
/* If there's an explicit dimensionality, we use that */
for( i = 0; i < strlen(dimensionality); i++ )
{
@@ -103,14 +103,14 @@
int hasz = FLAGS_GET_Z(flags);
int hasm = FLAGS_GET_M(flags);
int i = 0;
-
+
/* Error on junk */
if( ! geom )
return LW_FAILURE;
FLAGS_SET_Z(geom->flags, hasz);
FLAGS_SET_M(geom->flags, hasm);
-
+
switch( geom->type )
{
case POINTTYPE:
@@ -161,7 +161,7 @@
{
LWCOLLECTION *col = (LWCOLLECTION*)geom;
for ( i = 0; i < col->ngeoms; i++ )
- wkt_parser_set_dims(col->geoms[i], flags);
+ wkt_parser_set_dims(col->geoms[i], flags);
return LW_SUCCESS;
}
else
@@ -172,7 +172,7 @@
}
}
- return LW_SUCCESS;
+ return LW_SUCCESS;
}
/**
@@ -181,7 +181,7 @@
* match, ensure the pointarray is using the right "Z" or "M".
*/
static int wkt_pointarray_dimensionality(POINTARRAY *pa, uint8_t flags)
-{
+{
int hasz = FLAGS_GET_Z(flags);
int hasm = FLAGS_GET_M(flags);
int ndims = 2 + hasz + hasm;
@@ -189,10 +189,10 @@
/* No dimensionality or array means we go with what we have */
if( ! (flags && pa) )
return LW_TRUE;
-
+
LWDEBUGF(5,"dimensionality ndims == %d", ndims);
LWDEBUGF(5,"FLAGS_NDIMS(pa->flags) == %d", FLAGS_NDIMS(pa->flags));
-
+
/*
* ndims > 2 implies that the flags have something useful to add,
* that there is a 'Z' or an 'M' or both.
@@ -266,14 +266,14 @@
{
POINT4D pt;
LWDEBUG(4,"entered");
-
+
/* Error on trouble */
if( ! pa )
{
SET_PARSER_ERROR(PARSER_ERROR_OTHER);
- return NULL;
+ return NULL;
}
-
+
/* Check that the coordinate has the same dimesionality as the array */
if( FLAGS_NDIMS(p.flags) != FLAGS_NDIMS(pa->flags) )
{
@@ -281,7 +281,7 @@
SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
return NULL;
}
-
+
/* While parsing the point arrays, XYM and XMZ points are both treated as XYZ */
pt.x = p.x;
pt.y = p.y;
@@ -292,7 +292,7 @@
/* If the destination is XYM, we'll write the third coordinate to m */
if( FLAGS_GET_M(pa->flags) && ! FLAGS_GET_Z(pa->flags) )
pt.m = p.z;
-
+
ptarray_append_point(pa, &pt, LW_TRUE); /* Allow duplicate points in array */
return pa;
}
@@ -321,7 +321,7 @@
{
uint8_t flags = wkt_dimensionality(dimensionality);
LWDEBUG(4,"entered");
-
+
/* No pointarray means it is empty */
if( ! pa )
return lwpoint_as_lwgeom(lwpoint_construct_empty(SRID_UNKNOWN, FLAGS_GET_Z(flags), FLAGS_GET_M(flags)));
@@ -334,13 +334,13 @@
return NULL;
}
- /* Only one point allowed in our point array! */
+ /* Only one point allowed in our point array! */
if( pa->npoints != 1 )
{
ptarray_free(pa);
SET_PARSER_ERROR(PARSER_ERROR_LESSPOINTS);
return NULL;
- }
+ }
return lwpoint_as_lwgeom(lwpoint_construct(SRID_UNKNOWN, NULL, pa));
}
@@ -367,8 +367,8 @@
SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
return NULL;
}
-
- /* Apply check for not enough points, if requested. */
+
+ /* Apply check for not enough points, if requested. */
if( (global_parser_result.parser_check_flags & LW_PARSER_CHECK_MINPOINTS) && (pa->npoints < 2) )
{
ptarray_free(pa);
@@ -401,24 +401,24 @@
SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
return NULL;
}
-
- /* Apply check for not enough points, if requested. */
+
+ /* Apply check for not enough points, if requested. */
if( (global_parser_result.parser_check_flags & LW_PARSER_CHECK_MINPOINTS) && (pa->npoints < 3) )
{
ptarray_free(pa);
SET_PARSER_ERROR(PARSER_ERROR_MOREPOINTS);
return NULL;
- }
+ }
- /* Apply check for odd number of points, if requested. */
+ /* Apply check for odd number of points, if requested. */
if( (global_parser_result.parser_check_flags & LW_PARSER_CHECK_ODD) && ((pa->npoints % 2) == 0) )
{
ptarray_free(pa);
SET_PARSER_ERROR(PARSER_ERROR_ODDPOINTS);
return NULL;
}
-
- return lwcircstring_as_lwgeom(lwcircstring_construct(SRID_UNKNOWN, NULL, pa));
+
+ return lwcircstring_as_lwgeom(lwcircstring_construct(SRID_UNKNOWN, NULL, pa));
}
LWGEOM* wkt_parser_triangle_new(POINTARRAY *pa, char *dimensionality)
@@ -438,21 +438,21 @@
return NULL;
}
- /* Triangles need four points. */
+ /* Triangles need four points. */
if( (pa->npoints != 4) )
{
ptarray_free(pa);
SET_PARSER_ERROR(PARSER_ERROR_TRIANGLEPOINTS);
return NULL;
- }
-
- /* Triangles need closure. */
- if( ! ptarray_is_closed(pa) )
+ }
+
+ /* Triangles need closure. */
+ if( ! ptarray_is_closed_z(pa) )
{
ptarray_free(pa);
SET_PARSER_ERROR(PARSER_ERROR_UNCLOSED);
return NULL;
- }
+ }
return lwtriangle_as_lwgeom(lwtriangle_construct(SRID_UNKNOWN, NULL, pa));
}
@@ -461,24 +461,24 @@
{
LWPOLY *poly = NULL;
LWDEBUG(4,"entered");
-
+
/* No pointarray is a problem */
if( ! pa )
{
SET_PARSER_ERROR(PARSER_ERROR_OTHER);
- return NULL;
+ return NULL;
}
poly = lwpoly_construct_empty(SRID_UNKNOWN, FLAGS_GET_Z(pa->flags), FLAGS_GET_M(pa->flags));
-
+
/* Error out if we can't build this polygon. */
if( ! poly )
{
SET_PARSER_ERROR(PARSER_ERROR_OTHER);
return NULL;
}
-
- wkt_parser_polygon_add_ring(lwpoly_as_lwgeom(poly), pa, dimcheck);
+
+ wkt_parser_polygon_add_ring(lwpoly_as_lwgeom(poly), pa, dimcheck);
return lwpoly_as_lwgeom(poly);
}
@@ -490,7 +490,7 @@
if( ! (pa && poly) )
{
SET_PARSER_ERROR(PARSER_ERROR_OTHER);
- return NULL;
+ return NULL;
}
/* Rings must agree on dimensionality */
@@ -502,7 +502,7 @@
return NULL;
}
- /* Apply check for minimum number of points, if requested. */
+ /* Apply check for minimum number of points, if requested. */
if( (global_parser_result.parser_check_flags & LW_PARSER_CHECK_MINPOINTS) && (pa->npoints < 4) )
{
ptarray_free(pa);
@@ -510,8 +510,8 @@
SET_PARSER_ERROR(PARSER_ERROR_MOREPOINTS);
return NULL;
}
-
- /* Apply check for not closed rings, if requested. */
+
+ /* Apply check for not closed rings, if requested. */
if( (global_parser_result.parser_check_flags & LW_PARSER_CHECK_CLOSURE) &&
! (dimcheck == 'Z' ? ptarray_is_closed_z(pa) : ptarray_is_closed_2d(pa)) )
{
@@ -527,7 +527,7 @@
ptarray_free(pa);
lwgeom_free(poly);
SET_PARSER_ERROR(PARSER_ERROR_OTHER);
- return NULL;
+ return NULL;
}
return poly;
}
@@ -537,7 +537,7 @@
uint8_t flags = wkt_dimensionality(dimensionality);
int flagdims = FLAGS_NDIMS(flags);
LWDEBUG(4,"entered");
-
+
/* Null input implies empty return */
if( ! poly )
return lwpoly_as_lwgeom(lwpoly_construct_empty(SRID_UNKNOWN, FLAGS_GET_Z(flags), FLAGS_GET_M(flags)));
@@ -551,7 +551,7 @@
SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
return NULL;
}
-
+
/* Harmonize the flags in the sub-components with the wkt flags */
if( LW_FAILURE == wkt_parser_set_dims(poly, flags) )
{
@@ -560,13 +560,13 @@
return NULL;
}
}
-
+
return poly;
}
LWGEOM* wkt_parser_curvepolygon_new(LWGEOM *ring)
{
- LWGEOM *poly;
+ LWGEOM *poly;
LWDEBUG(4,"entered");
/* Toss error on null geometry input */
@@ -575,7 +575,7 @@
SET_PARSER_ERROR(PARSER_ERROR_OTHER);
return NULL;
}
-
+
/* Construct poly and add the ring. */
poly = lwcurvepoly_as_lwgeom(lwcurvepoly_construct_empty(SRID_UNKNOWN, FLAGS_GET_Z(ring->flags), FLAGS_GET_M(ring->flags)));
/* Return the result. */
@@ -593,7 +593,7 @@
LWDEBUG(4,"inputs are null");
return NULL;
}
-
+
/* All the elements must agree on dimensionality */
if( FLAGS_NDIMS(poly->flags) != FLAGS_NDIMS(ring->flags) )
{
@@ -603,15 +603,15 @@
SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
return NULL;
}
-
- /* Apply check for minimum number of points, if requested. */
+
+ /* Apply check for minimum number of points, if requested. */
if( (global_parser_result.parser_check_flags & LW_PARSER_CHECK_MINPOINTS) )
{
int vertices_needed = 3;
if ( ring->type == LINETYPE )
vertices_needed = 4;
-
+
if (lwgeom_count_vertices(ring) < vertices_needed)
{
LWDEBUG(4,"number of points is incorrect");
@@ -619,10 +619,10 @@
lwgeom_free(poly);
SET_PARSER_ERROR(PARSER_ERROR_MOREPOINTS);
return NULL;
- }
+ }
}
-
- /* Apply check for not closed rings, if requested. */
+
+ /* Apply check for not closed rings, if requested. */
if( (global_parser_result.parser_check_flags & LW_PARSER_CHECK_CLOSURE) )
{
int is_closed = 1;
@@ -632,11 +632,11 @@
case LINETYPE:
is_closed = lwline_is_closed(lwgeom_as_lwline(ring));
break;
-
+
case CIRCSTRINGTYPE:
is_closed = lwcircstring_is_closed(lwgeom_as_lwcircstring(ring));
break;
-
+
case COMPOUNDTYPE:
is_closed = lwcompound_is_closed(lwgeom_as_lwcompound(ring));
break;
@@ -650,7 +650,7 @@
return NULL;
}
}
-
+
if( LW_FAILURE == lwcurvepoly_add_ring(lwgeom_as_lwcurvepoly(poly), ring) )
{
LWDEBUG(4,"failed to add ring");
@@ -659,7 +659,7 @@
SET_PARSER_ERROR(PARSER_ERROR_OTHER);
return NULL;
}
-
+
return poly;
}
@@ -668,7 +668,7 @@
uint8_t flags = wkt_dimensionality(dimensionality);
int flagdims = FLAGS_NDIMS(flags);
LWDEBUG(4,"entered");
-
+
/* Null input implies empty return */
if( ! poly )
return lwcurvepoly_as_lwgeom(lwcurvepoly_construct_empty(SRID_UNKNOWN, FLAGS_GET_Z(flags), FLAGS_GET_M(flags)));
@@ -691,7 +691,7 @@
return NULL;
}
}
-
+
return poly;
}
@@ -701,18 +701,18 @@
LWGEOM **geoms;
static int ngeoms = 1;
LWDEBUG(4,"entered");
-
+
/* Toss error on null geometry input */
if( ! geom )
{
SET_PARSER_ERROR(PARSER_ERROR_OTHER);
return NULL;
}
-
+
/* Create our geometry array */
geoms = lwalloc(sizeof(LWGEOM*) * ngeoms);
geoms[0] = geom;
-
+
/* Make a new collection */
col = lwcollection_construct(COLLECTIONTYPE, SRID_UNKNOWN, NULL, ngeoms, geoms);
@@ -727,27 +727,27 @@
LWGEOM **geoms;
static int ngeoms = 1;
LWDEBUG(4,"entered");
-
+
/* Toss error on null geometry input */
if( ! geom )
{
SET_PARSER_ERROR(PARSER_ERROR_OTHER);
return NULL;
}
-
+
/* Elements of a compoundcurve cannot be empty, because */
/* empty things can't join up and form a ring */
if ( lwgeom_is_empty(geom) )
{
lwgeom_free(geom);
SET_PARSER_ERROR(PARSER_ERROR_INCONTINUOUS);
- return NULL;
+ return NULL;
}
-
+
/* Create our geometry array */
geoms = lwalloc(sizeof(LWGEOM*) * ngeoms);
geoms[0] = geom;
-
+
/* Make a new collection */
col = lwcollection_construct(COLLECTIONTYPE, SRID_UNKNOWN, NULL, ngeoms, geoms);
@@ -775,7 +775,7 @@
SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
return NULL;
}
-
+
if( LW_FAILURE == lwcompound_add_lwgeom((LWCOMPOUND*)col, geom) )
{
lwgeom_free(col);
@@ -783,7 +783,7 @@
SET_PARSER_ERROR(PARSER_ERROR_INCONTINUOUS);
return NULL;
}
-
+
return col;
}
@@ -798,7 +798,7 @@
SET_PARSER_ERROR(PARSER_ERROR_OTHER);
return NULL;
}
-
+
return lwcollection_as_lwgeom(lwcollection_add_lwgeom(lwgeom_as_lwcollection(col), geom));
}
@@ -806,7 +806,7 @@
{
uint8_t flags = wkt_dimensionality(dimensionality);
int flagdims = FLAGS_NDIMS(flags);
-
+
/* No geometry means it is empty */
if( ! geom )
{
@@ -818,7 +818,7 @@
{
LWCOLLECTION *col = lwgeom_as_lwcollection(geom);
int i;
-
+
for ( i = 0 ; i < col->ngeoms; i++ )
{
LWGEOM *subgeom = col->geoms[i];
@@ -829,7 +829,7 @@
SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
return NULL;
}
-
+
if ( lwtype == COLLECTIONTYPE &&
( (FLAGS_GET_Z(flags) != FLAGS_GET_Z(subgeom->flags)) ||
(FLAGS_GET_M(flags) != FLAGS_GET_M(subgeom->flags)) ) &&
@@ -840,7 +840,7 @@
return NULL;
}
}
-
+
/* Harmonize the collection dimensionality */
if( LW_FAILURE == wkt_parser_set_dims(geom, flags) )
{
@@ -849,10 +849,10 @@
return NULL;
}
}
-
+
/* Set the collection type */
geom->type = lwtype;
-
+
return geom;
}
@@ -867,12 +867,12 @@
lwerror("Parsed geometry is null!");
return;
}
-
+
if ( srid != SRID_UNKNOWN && srid < SRID_MAXIMUM )
lwgeom_set_srid(geom, srid);
else
lwgeom_set_srid(geom, SRID_UNKNOWN);
-
+
global_parser_result.geom = geom;
}
@@ -910,8 +910,8 @@
lwerror(r.message);
return NULL;
}
-
- return r.geom;
+
+ return r.geom;
}
More information about the postgis-tickets
mailing list