[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