[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