Commit f58c2049 authored by Darafei Praliaskouski's avatar Darafei Praliaskouski

Add support to unstroke GEOMETRYCOLLECTION

Patch by Raúl Marín Rodríguez

Closes https://github.com/postgis/postgis/pull/209



git-svn-id: http://svn.osgeo.org/postgis/trunk@16383 b70326c6-7e19-0410-871a-916f4a2858ee
parent bdf46a39
Pipeline #17659401 failed with stage
in 58 seconds
......@@ -294,12 +294,12 @@ static void test_lwcurve_linearize(void)
in = lwgeom_from_text("CIRCULARSTRING(71.96 -65.64,22.2 -18.52,20 50)");
out = lwcurve_linearize(in, M_PI/4.0,
LW_LINEARIZE_TOLERANCE_TYPE_MAX_ANGLE,
LW_LINEARIZE_FLAG_SYMMETRIC);
LW_LINEARIZE_TOLERANCE_TYPE_MAX_ANGLE,
LW_LINEARIZE_FLAG_SYMMETRIC);
lwgeom_reverse_in_place(in);
out2 = lwcurve_linearize(in, M_PI/4.0,
LW_LINEARIZE_TOLERANCE_TYPE_MAX_ANGLE,
LW_LINEARIZE_FLAG_SYMMETRIC);
LW_LINEARIZE_TOLERANCE_TYPE_MAX_ANGLE,
LW_LINEARIZE_FLAG_SYMMETRIC);
lwgeom_reverse_in_place(out2);
if ( ! lwgeom_same(out, out2) )
{
......@@ -317,6 +317,153 @@ static void test_lwcurve_linearize(void)
lwgeom_free(in);
}
static void test_unstroke()
{
LWGEOM *in, *out;
char *str;
/* It would be nice if this example returned two arcs (it's the intersection of two circles)
but it looks like the intersection itself is too sloppy in generating the derived point
to accurately reconstruct the circles.
in = lwgeom_from_text("POLYGON((0.5 0,0.471177920604846 -0.292635483024192,0.38581929876693 -0.574025148547634,0.247204418453818 -0.833355349529403,0.0606601717798223 -1.06066017177982,-5.44089437167602e-17 -1.11044268820754,-0.0606601717798188 -1.06066017177982,-0.247204418453816 -0.833355349529406,-0.385819298766929 -0.574025148547639,-0.471177920604845 -0.292635483024197,-0.5 -4.84663372329776e-15,-0.471177920604847 0.292635483024187,-0.385819298766932 0.57402514854763,-0.247204418453821 0.833355349529398,-0.0606601717798256 1.06066017177982,3.45538806345173e-16 1.11044268820754,0.0606601717798183 1.06066017177982,0.247204418453816 0.833355349529407,0.385819298766929 0.574025148547638,0.471177920604845 0.292635483024196,0.5 0))");
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
printf("%s\n", str);
ASSERT_STRING_EQUAL(str, "CIRCULARSTRING(-1 0,0 1,0 -1)");
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
*/
in = lwgeom_from_text("CIRCULARSTRING(-1 0,0 1,0 -1)");
out = lwgeom_stroke(in,8);
lwgeom_free(in);
in = out;
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
// printf("%s\n", str);
ASSERT_STRING_EQUAL(str, "CIRCULARSTRING(-1 0,0.70710678 0.70710678,0 -1)");
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
in = lwgeom_from_text("COMPOUNDCURVE(CIRCULARSTRING(-1 0,0 1,0 -1),(0 -1,-1 -1))");
out = lwgeom_stroke(in,8);
lwgeom_free(in);
in = out;
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
// printf("%s\n", str);
ASSERT_STRING_EQUAL(str, "COMPOUNDCURVE(CIRCULARSTRING(-1 0,0.70710678 0.70710678,0 -1),(0 -1,-1 -1))");
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
in = lwgeom_from_text("COMPOUNDCURVE((-3 -3,-1 0),CIRCULARSTRING(-1 0,0 1,0 -1),(0 -1,0 -1.5,0 -2),CIRCULARSTRING(0 -2,-1 -3,1 -3),(1 -3,5 5))");
out = lwgeom_stroke(in,8);
lwgeom_free(in);
in = out;
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
// printf("%s\n", str);
ASSERT_STRING_EQUAL(
str,
"COMPOUNDCURVE((-3 -3,-1 0),CIRCULARSTRING(-1 0,0.70710678 "
"0.70710678,0 -1),(0 -1,0 -1.5,0 -2),CIRCULARSTRING(0 "
"-2,-0.70710678 -3.70710678,1 -3),(1 -3,5 5))");
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
in = lwgeom_from_text("COMPOUNDCURVE(CIRCULARSTRING(-1 0,0 1,0 -1),CIRCULARSTRING(0 -1,-1 -2,1 -2))");
out = lwgeom_stroke(in,8);
lwgeom_free(in);
in = out;
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
// printf("%s\n", str);
ASSERT_STRING_EQUAL(
str,
"COMPOUNDCURVE(CIRCULARSTRING(-1 0,0.70710678 0.70710678,0 "
"-1),CIRCULARSTRING(0 -1,-0.70710678 -2.70710678,1 -2))");
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
in = lwgeom_from_text("COMPOUNDCURVE((0 0, 1 1), CIRCULARSTRING(1 1, 2 2, 3 1), (3 1, 4 4))");
out = lwgeom_stroke(in,8);
lwgeom_free(in);
in = out;
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
ASSERT_STRING_EQUAL(str, "COMPOUNDCURVE((0 0,1 1),CIRCULARSTRING(1 1,2 2,3 1),(3 1,4 4))");
lwgeom_free(in);
lwgeom_free(out);
// printf("%s\n", str);
lwfree(str);
// See http://trac.osgeo.org/postgis/ticket/2425
// and http://trac.osgeo.org/postgis/ticket/2420
in = lwgeom_from_text("LINESTRING(0 0,10 0,10 10,0 10,0 0)");
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,10 0,10 10,0 10,0 0)");
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
in = lwgeom_from_text("LINESTRING(10 10,0 10,0 0,10 0)");
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
ASSERT_STRING_EQUAL(str, "LINESTRING(10 10,0 10,0 0,10 0)");
// printf("%s\n", str);
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
in = lwgeom_from_text("LINESTRING(0 0,10 0,10 10,0 10)");
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,10 0,10 10,0 10)");
// printf("%s\n", str);
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
// See http://trac.osgeo.org/postgis/ticket/2412
in = lwgeom_from_text("LINESTRING(0 0, 1 1)");
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
// printf("%s\n", str);
ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,1 1)");
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
in = lwgeom_from_text("GEOMETRYCOLLECTION(LINESTRING(10 10,10 11),LINESTRING(10 11,11 11),LINESTRING(11 11,10 10))");
out = lwgeom_stroke(in,8);
lwgeom_free(in);
in = out;
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
ASSERT_STRING_EQUAL(str, "GEOMETRYCOLLECTION(LINESTRING(10 10,10 11),LINESTRING(10 11,11 11),LINESTRING(11 11,10 10))");
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
in = lwgeom_from_text("GEOMETRYCOLLECTION(LINESTRING(4 4,4 8),CIRCULARSTRING(4 8,6 10,8 8),LINESTRING(8 8,8 4))");
out = lwgeom_stroke(in,8);
lwgeom_free(in);
in = out;
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
// printf("%s\n", str);
ASSERT_STRING_EQUAL(str, "GEOMETRYCOLLECTION(LINESTRING(4 4,4 8),CIRCULARSTRING(4 8,6 10,8 8),LINESTRING(8 8,8 4))");
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
}
/*
** Used by the test harness to register the tests in this file.
*/
......@@ -325,4 +472,5 @@ void lwstroke_suite_setup(void)
{
CU_pSuite suite = CU_add_suite("lwstroke", NULL, NULL);
PG_ADD_TEST(suite, test_lwcurve_linearize);
PG_ADD_TEST(suite, test_unstroke);
}
......@@ -340,131 +340,6 @@ static void test_ptarray_signed_area()
}
static void test_ptarray_unstroke()
{
LWGEOM *in, *out;
char *str;
/* It would be nice if this example returned two arcs (it's the intersection of two circles)
but it looks like the intersection itself is too sloppy in generating the derived point
to accurately reconstruct the circles.
in = lwgeom_from_text("POLYGON((0.5 0,0.471177920604846 -0.292635483024192,0.38581929876693 -0.574025148547634,0.247204418453818 -0.833355349529403,0.0606601717798223 -1.06066017177982,-5.44089437167602e-17 -1.11044268820754,-0.0606601717798188 -1.06066017177982,-0.247204418453816 -0.833355349529406,-0.385819298766929 -0.574025148547639,-0.471177920604845 -0.292635483024197,-0.5 -4.84663372329776e-15,-0.471177920604847 0.292635483024187,-0.385819298766932 0.57402514854763,-0.247204418453821 0.833355349529398,-0.0606601717798256 1.06066017177982,3.45538806345173e-16 1.11044268820754,0.0606601717798183 1.06066017177982,0.247204418453816 0.833355349529407,0.385819298766929 0.574025148547638,0.471177920604845 0.292635483024196,0.5 0))");
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
printf("%s\n", str);
ASSERT_STRING_EQUAL(str, "CIRCULARSTRING(-1 0,0 1,0 -1)");
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
*/
in = lwgeom_from_text("CIRCULARSTRING(-1 0,0 1,0 -1)");
out = lwgeom_stroke(in,8);
lwgeom_free(in);
in = out;
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
// printf("%s\n", str);
ASSERT_STRING_EQUAL(str, "CIRCULARSTRING(-1 0,0.70710678 0.70710678,0 -1)");
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
in = lwgeom_from_text("COMPOUNDCURVE(CIRCULARSTRING(-1 0,0 1,0 -1),(0 -1,-1 -1))");
out = lwgeom_stroke(in,8);
lwgeom_free(in);
in = out;
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
// printf("%s\n", str);
ASSERT_STRING_EQUAL(str, "COMPOUNDCURVE(CIRCULARSTRING(-1 0,0.70710678 0.70710678,0 -1),(0 -1,-1 -1))");
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
in = lwgeom_from_text("COMPOUNDCURVE((-3 -3,-1 0),CIRCULARSTRING(-1 0,0 1,0 -1),(0 -1,0 -1.5,0 -2),CIRCULARSTRING(0 -2,-1 -3,1 -3),(1 -3,5 5))");
out = lwgeom_stroke(in,8);
lwgeom_free(in);
in = out;
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
// printf("%s\n", str);
ASSERT_STRING_EQUAL(
str,
"COMPOUNDCURVE((-3 -3,-1 0),CIRCULARSTRING(-1 0,0.70710678 "
"0.70710678,0 -1),(0 -1,0 -1.5,0 -2),CIRCULARSTRING(0 "
"-2,-0.70710678 -3.70710678,1 -3),(1 -3,5 5))");
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
in = lwgeom_from_text("COMPOUNDCURVE(CIRCULARSTRING(-1 0,0 1,0 -1),CIRCULARSTRING(0 -1,-1 -2,1 -2))");
out = lwgeom_stroke(in,8);
lwgeom_free(in);
in = out;
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
// printf("%s\n", str);
ASSERT_STRING_EQUAL(
str,
"COMPOUNDCURVE(CIRCULARSTRING(-1 0,0.70710678 0.70710678,0 "
"-1),CIRCULARSTRING(0 -1,-0.70710678 -2.70710678,1 -2))");
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
in = lwgeom_from_text("COMPOUNDCURVE((0 0, 1 1), CIRCULARSTRING(1 1, 2 2, 3 1), (3 1, 4 4))");
out = lwgeom_stroke(in,8);
lwgeom_free(in);
in = out;
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
ASSERT_STRING_EQUAL(str, "COMPOUNDCURVE((0 0,1 1),CIRCULARSTRING(1 1,2 2,3 1),(3 1,4 4))");
lwgeom_free(in);
lwgeom_free(out);
// printf("%s\n", str);
lwfree(str);
// See http://trac.osgeo.org/postgis/ticket/2425
// and http://trac.osgeo.org/postgis/ticket/2420
in = lwgeom_from_text("LINESTRING(0 0,10 0,10 10,0 10,0 0)");
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,10 0,10 10,0 10,0 0)");
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
in = lwgeom_from_text("LINESTRING(10 10,0 10,0 0,10 0)");
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
ASSERT_STRING_EQUAL(str, "LINESTRING(10 10,0 10,0 0,10 0)");
// printf("%s\n", str);
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
in = lwgeom_from_text("LINESTRING(0 0,10 0,10 10,0 10)");
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,10 0,10 10,0 10)");
// printf("%s\n", str);
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
// See http://trac.osgeo.org/postgis/ticket/2412
in = lwgeom_from_text("LINESTRING(0 0, 1 1)");
out = lwgeom_unstroke(in);
str = lwgeom_to_wkt(out, WKT_ISO, 8, NULL);
// printf("%s\n", str);
ASSERT_STRING_EQUAL(str, "LINESTRING(0 0,1 1)");
lwgeom_free(in);
lwgeom_free(out);
lwfree(str);
}
static void test_ptarray_contains_point()
{
/* int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt, int *winding_number) */
......@@ -754,7 +629,6 @@ void ptarray_suite_setup(void)
PG_ADD_TEST(suite, test_ptarray_locate_point);
PG_ADD_TEST(suite, test_ptarray_isccw);
PG_ADD_TEST(suite, test_ptarray_signed_area);
PG_ADD_TEST(suite, test_ptarray_unstroke);
PG_ADD_TEST(suite, test_ptarray_insert_point);
PG_ADD_TEST(suite, test_ptarray_contains_point);
PG_ADD_TEST(suite, test_ptarrayarc_contains_point);
......
......@@ -43,6 +43,7 @@ LWGEOM* lwline_unstroke(const LWLINE *line);
LWGEOM* lwpolygon_unstroke(const LWPOLY *poly);
LWGEOM* lwmline_unstroke(const LWMLINE *mline);
LWGEOM* lwmpolygon_unstroke(const LWMPOLY *mpoly);
LWGEOM* lwcollection_unstroke(const LWCOLLECTION *c);
LWGEOM* lwgeom_unstroke(const LWGEOM *geom);
......@@ -669,7 +670,7 @@ lwcollection_linearize(const LWCOLLECTION *collection, double tol,
geoms[i] = (LWGEOM *)lwcollection_linearize((LWCOLLECTION *)tmp, tol, type, flags);
break;
default:
geoms[i] = lwgeom_clone(tmp);
geoms[i] = lwgeom_clone_deep(tmp);
break;
}
}
......@@ -704,7 +705,7 @@ lwcurve_linearize(const LWGEOM *geom, double tol,
ogeom = (LWGEOM *)lwcollection_linearize((LWCOLLECTION *)geom, tol, type, flags);
break;
default:
ogeom = lwgeom_clone(geom);
ogeom = lwgeom_clone_deep(geom);
}
return ogeom;
}
......@@ -993,7 +994,7 @@ lwline_unstroke(const LWLINE *line)
{
LWDEBUG(2, "lwline_unstroke called.");
if ( line->points->npoints < 4 ) return lwline_as_lwgeom(lwline_clone(line));
if ( line->points->npoints < 4 ) return lwline_as_lwgeom(lwline_clone_deep(line));
else return pta_unstroke(line->points, line->srid);
}
......@@ -1020,7 +1021,7 @@ lwpolygon_unstroke(const LWPOLY *poly)
{
lwfree(geoms[i]); /* TODO: should this be lwgeom_free instead ? */
}
return lwgeom_clone((LWGEOM *)poly);
return lwgeom_clone_deep((LWGEOM *)poly);
}
return (LWGEOM *)lwcollection_construct(CURVEPOLYTYPE, poly->srid, NULL, poly->nrings, geoms);
......@@ -1049,7 +1050,7 @@ lwmline_unstroke(const LWMLINE *mline)
{
lwfree(geoms[i]); /* TODO: should this be lwgeom_free instead ? */
}
return lwgeom_clone((LWGEOM *)mline);
return lwgeom_clone_deep((LWGEOM *)mline);
}
return (LWGEOM *)lwcollection_construct(MULTICURVETYPE, mline->srid, NULL, mline->ngeoms, geoms);
}
......@@ -1077,11 +1078,39 @@ lwmpolygon_unstroke(const LWMPOLY *mpoly)
{
lwfree(geoms[i]); /* TODO: should this be lwgeom_free instead ? */
}
return lwgeom_clone((LWGEOM *)mpoly);
return lwgeom_clone_deep((LWGEOM *)mpoly);
}
return (LWGEOM *)lwcollection_construct(MULTISURFACETYPE, mpoly->srid, NULL, mpoly->ngeoms, geoms);
}
LWGEOM *
lwcollection_unstroke(const LWCOLLECTION *c)
{
LWCOLLECTION *ret = lwalloc(sizeof(LWCOLLECTION));
memcpy(ret, c, sizeof(LWCOLLECTION));
if (c->ngeoms > 0)
{
uint32_t i;
ret->geoms = lwalloc(sizeof(LWGEOM *)*c->ngeoms);
for (i=0; i < c->ngeoms; i++)
{
ret->geoms[i] = lwgeom_unstroke(c->geoms[i]);
}
if (c->bbox)
{
ret->bbox = gbox_copy(c->bbox);
}
}
else
{
ret->bbox = NULL;
ret->geoms = NULL;
}
return (LWGEOM *)ret;
}
LWGEOM *
lwgeom_unstroke(const LWGEOM *geom)
{
......@@ -1097,8 +1126,10 @@ lwgeom_unstroke(const LWGEOM *geom)
return lwmline_unstroke((LWMLINE *)geom);
case MULTIPOLYGONTYPE:
return lwmpolygon_unstroke((LWMPOLY *)geom);
case COLLECTIONTYPE:
return lwcollection_unstroke((LWCOLLECTION *)geom);
default:
return lwgeom_clone(geom);
return lwgeom_clone_deep(geom);
}
}
......@@ -653,7 +653,7 @@ ptarray_clone(const POINTARRAY *in)
{
POINTARRAY *out = lwalloc(sizeof(POINTARRAY));
LWDEBUG(3, "ptarray_clone_deep called.");
LWDEBUG(3, "ptarray_clone called.");
out->flags = in->flags;
out->npoints = in->npoints;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment