[postgis-commits] svn - r3637 - in trunk/liblwgeom: . cunit

postgis-commits at postgis.refractions.net postgis-commits at postgis.refractions.net
Tue Feb 3 12:51:04 PST 2009


Author: pramsey
Date: 2009-02-03 12:51:04 -0800 (Tue, 03 Feb 2009)
New Revision: 3637

Modified:
   trunk/liblwgeom/cunit/cu_algorithm.c
   trunk/liblwgeom/lwalgorithm.c
Log:
Fix boundary conditions with from==to hitting first/list vertex.


Modified: trunk/liblwgeom/cunit/cu_algorithm.c
===================================================================
--- trunk/liblwgeom/cunit/cu_algorithm.c	2009-02-03 19:09:48 UTC (rev 3636)
+++ trunk/liblwgeom/cunit/cu_algorithm.c	2009-02-03 20:51:04 UTC (rev 3637)
@@ -100,7 +100,6 @@
 	if ( q2 ) lwfree(q2);
 	if ( l21 ) lwline_free(l21);
 	if ( l22 ) lwline_free(l22);
-	if ( l51 ) lwline_free(l51);
 	return 0;
 }
 
@@ -338,6 +337,8 @@
 	
 void test_lwline_crossing_long_lines(void) 
 {
+    LWLINE *l51;
+    LWLINE *l52;
 	/* 
 	** More complex test, longer lines and multiple crossings 
 	*/
@@ -395,6 +396,8 @@
 	CU_ASSERT( lwline_crossing_direction(l51, l52) == LINE_NO_CROSS );
 	lwline_free(l52);
 
+	lwline_free(l51);
+
 }
 
 void test_lwpoint_set_ordinate(void) 
@@ -464,8 +467,13 @@
 void test_lwline_clip(void)
 {
 	LWCOLLECTION *c;
+	LWLINE *line = NULL;
+    LWLINE *l51 = NULL;
 	char *ewkt;
 	
+	/* Vertical line with vertices at y integers */
+	l51 = (LWLINE*)lwgeom_from_ewkt("LINESTRING(0 0, 0 1, 0 2, 0 3, 0 4)", PARSER_CHECK_NONE);
+	
 	/* Clip in the middle, mid-range. */
 	c = lwline_clip_to_ordinate_range(l51, 1, 1.5, 2.5);
 	ewkt = lwgeom_to_ewkt((LWGEOM*)c, PARSER_CHECK_NONE);
@@ -522,6 +530,48 @@
 	lwfree(ewkt);
 	lwcollection_free(c);
 
+	/* ST_LocateBetweenElevations(ST_GeomFromEWKT('LINESTRING(1 2 3, 4 5 6, 6 6 6, 1 1 1)'), 1, 2)) */
+	line = (LWLINE*)lwgeom_from_ewkt("LINESTRING(1 2 3, 4 5 6, 6 6 6, 1 1 1)", PARSER_CHECK_NONE);
+	c = lwline_clip_to_ordinate_range(line, 2, 1.0, 2.0);
+	ewkt = lwgeom_to_ewkt((LWGEOM*)c, PARSER_CHECK_NONE);
+	//printf("a = %s\n", ewkt);
+	CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((2 2 2,1 1 1))" );
+	lwfree(ewkt);
+	lwcollection_free(c);
+	lwline_free(line);
+
+	/* ST_LocateBetweenElevations('LINESTRING(1 2 3, 4 5 6, 6 6 6, 1 1 1)', 1, 2)) */
+	line = (LWLINE*)lwgeom_from_ewkt("LINESTRING(1 2 3, 4 5 6, 6 6 6, 1 1 1)", PARSER_CHECK_NONE);
+	c = lwline_clip_to_ordinate_range(line, 2, 1.0, 2.0);
+	ewkt = lwgeom_to_ewkt((LWGEOM*)c, PARSER_CHECK_NONE);
+	//printf("a = %s\n", ewkt);
+	CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((2 2 2,1 1 1))" );
+	lwfree(ewkt);
+	lwcollection_free(c);
+	lwline_free(line);
+    
+	/* ST_LocateBetweenElevations('LINESTRING(1 2 3, 4 5 6, 6 6 6, 1 1 1)', 1, 1)) */
+	line = (LWLINE*)lwgeom_from_ewkt("LINESTRING(1 2 3, 4 5 6, 6 6 6, 1 1 1)", PARSER_CHECK_NONE);
+	c = lwline_clip_to_ordinate_range(line, 2, 1.0, 1.0);
+	ewkt = lwgeom_to_ewkt((LWGEOM*)c, PARSER_CHECK_NONE);
+	//printf("b = %s\n", ewkt);
+	CU_ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(1 1 1))" );
+	lwfree(ewkt);
+	lwcollection_free(c);
+	lwline_free(line);
+
+	/* ST_LocateBetweenElevations('LINESTRING(1 1 1, 1 2 2)', 1,1) */
+	line = (LWLINE*)lwgeom_from_ewkt("LINESTRING(1 1 1, 1 2 2)", PARSER_CHECK_NONE);
+	c = lwline_clip_to_ordinate_range(line, 2, 1.0, 1.0);
+	ewkt = lwgeom_to_ewkt((LWGEOM*)c, PARSER_CHECK_NONE);
+	//printf("c = %s\n", ewkt);
+	CU_ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(1 1 1))" );
+	lwfree(ewkt);
+	lwcollection_free(c);
+	lwline_free(line);
+
+    lwline_free(l51);
+
 }
 
 void test_lwmline_clip(void)

Modified: trunk/liblwgeom/lwalgorithm.c
===================================================================
--- trunk/liblwgeom/lwalgorithm.c	2009-02-03 19:09:48 UTC (rev 3636)
+++ trunk/liblwgeom/lwalgorithm.c	2009-02-03 20:51:04 UTC (rev 3637)
@@ -335,6 +335,8 @@
 		lwerror("Cannot extract ordinate %d.", ordinate);
 		return;
 	}
+	
+	LWDEBUGF(4, "    setting ordinate %d to %g", ordinate, value);
 
 	switch ( ordinate )
 	{
@@ -378,11 +380,12 @@
 
 	for ( i = 0; i < ndims; i++ )
 	{
+		double newordinate = 0.0;
 		p1_value = lwpoint_get_ordinate(p1, i);
 		p2_value = lwpoint_get_ordinate(p2, i);
-		lwpoint_set_ordinate(p, i, p1_value + proportion * (p2_value - p1_value));
-
-		LWDEBUGF(3, "   clip ordinate(%d) p1_value(%g) p2_value(%g) proportion(%g)", i, p1_value, p2_value, proportion );
+		newordinate = p1_value + proportion * (p2_value - p1_value);
+		lwpoint_set_ordinate(p, i, newordinate);
+		LWDEBUGF(4, "   clip ordinate(%d) p1_value(%g) p2_value(%g) proportion(%g) newordinate(%g) ", i, p1_value, p2_value, proportion, newordinate );
 	}
 
 	return 1;
@@ -484,7 +487,7 @@
 	char dims = TYPE_NDIMS(line->type);
 	char hassrid = TYPE_HASSRID(line->type);
 
-	LWDEBUGF(5, "hassrid = %d", hassrid);
+	LWDEBUGF(4, "hassrid = %d", hassrid);
 
 	/* Null input, nothing we can do. */
 	if ( ! line )
@@ -501,6 +504,9 @@
 		to = t;
 	}
 
+	LWDEBUGF(4, "from = %g, to = %g, ordinate = %d", from, to, ordinate);
+	LWDEBUGF(4, "%s", lwgeom_to_ewkt((LWGEOM*)line, PARSER_CHECK_NONE));
+
 	/* Asking for an ordinate we don't have. Error. */
 	if ( ordinate >= dims )
 	{
@@ -549,6 +555,7 @@
 
 			if ( ! added_last_point )
 			{
+				LWDEBUG(4,"  new ptarray required");
 				/* We didn't add the previous point, so this is a new segment.
 				*  Make a new point array. */
 				if ( dp ) lwfree(dp);
@@ -600,8 +607,9 @@
 				/* We're out and the last point was on the boundary.
 				*  If the last point was the near boundary, nothing to do.
 				*  If it was the far boundary, we need an interpolated point. */
-				if ( (ordinate_value_q == from && ordinate_value_p > from) ||
-				        (ordinate_value_q == to && ordinate_value_p < to) )
+				if ( from != to && (
+				     (ordinate_value_q == from && ordinate_value_p > from) ||
+				     (ordinate_value_q == to && ordinate_value_p < to) ) )
 				{
 					double interpolation_value;
 					(ordinate_value_p > to) ? (interpolation_value = to) : (interpolation_value = from);
@@ -610,7 +618,7 @@
 					LWDEBUGF(4, " interpolating between (%g, %g) with interpolation point (%g)", ordinate_value_q, ordinate_value_p, interpolation_value);
 				}
 			}
-			else if ( ordinate_value_q < from && ordinate_value_p > to )
+			else if ( i && ordinate_value_q < from && ordinate_value_p > to )
 			{
 				/* We just hopped over the whole range, from bottom to top,
 				*  so we need to add *two* interpolated points! */
@@ -622,7 +630,7 @@
 				rv = lwpoint_interpolate(p, q, r, dims, ordinate, to);
 				setPoint4d(pa_out, 1, r);
 			}
-			else if ( ordinate_value_q > to && ordinate_value_p < from )
+			else if ( i && ordinate_value_q > to && ordinate_value_p < from )
 			{
 				/* We just hopped over the whole range, from top to bottom,
 				*  so we need to add *two* interpolated points! */
@@ -638,6 +646,7 @@
 			if ( dp || pa_out )
 			{
 				LWGEOM *oline;
+				LWDEBUG(4, "saving pointarray to multi-line (1)");
 				if ( dp )
 				{
 					/* Only one point, so we have to make an lwpoint to hold this
@@ -683,8 +692,22 @@
 	if ( dp && dp->pa->npoints > 0 )
 	{
 		LWGEOM *oline;
-		oline = (LWGEOM*)lwline_construct(line->SRID, NULL, dp->pa);
-		oline->type = lwgeom_makeType(hasz, hasm, hassrid, LINETYPE);
+		LWDEBUG(4, "saving pointarray to multi-line (2)");
+		LWDEBUGF(4, "dp->pa->npoints == %d", dp->pa->npoints);
+		LWDEBUGF(4, "lwgeom_out->ngeoms == %d", lwgeom_out->ngeoms);
+		
+		if ( dp->pa->npoints == 1 )
+		{
+			oline = (LWGEOM*)lwpoint_construct(line->SRID, NULL, dp->pa);
+			oline->type = lwgeom_makeType(hasz, hasm, hassrid, POINTTYPE);
+			lwgeom_out->type = lwgeom_makeType(hasz, hasm, hassrid, COLLECTIONTYPE);
+		}
+		else
+		{
+			oline = (LWGEOM*)lwline_construct(line->SRID, NULL, dp->pa);
+			oline->type = lwgeom_makeType(hasz, hasm, hassrid, LINETYPE);
+		}
+		
 		lwgeom_out->ngeoms++;
 		if ( lwgeom_out->geoms ) /* We can't just realloc, since repalloc chokes on a starting null ptr. */
 		{
@@ -697,8 +720,10 @@
 		lwgeom_out->geoms[lwgeom_out->ngeoms - 1] = oline;
 		lwgeom_dropBBOX((LWGEOM*)lwgeom_out);
 		lwgeom_addBBOX((LWGEOM*)lwgeom_out);
-		lwfree(dp);
+		if ( dp ) lwfree(dp);
+		dp = NULL;
 	}
+
 	lwfree(p);
 	lwfree(q);
 	lwfree(r);



More information about the postgis-commits mailing list