[postgis-tickets] r16383 - Add support to unstroke GEOMETRYCOLLECTION
Darafei
komzpa at gmail.com
Sat Feb 17 12:46:21 PST 2018
Author: komzpa
Date: 2018-02-17 00:46:20 -0800 (Sat, 17 Feb 2018)
New Revision: 16383
Modified:
trunk/liblwgeom/cunit/cu_lwstroke.c
trunk/liblwgeom/cunit/cu_ptarray.c
trunk/liblwgeom/lwstroke.c
trunk/liblwgeom/ptarray.c
Log:
Add support to unstroke GEOMETRYCOLLECTION
Patch by Raúl Marín Rodríguez
Closes https://github.com/postgis/postgis/pull/209
Modified: trunk/liblwgeom/cunit/cu_lwstroke.c
===================================================================
--- trunk/liblwgeom/cunit/cu_lwstroke.c 2018-02-17 08:42:21 UTC (rev 16382)
+++ trunk/liblwgeom/cunit/cu_lwstroke.c 2018-02-17 08:46:20 UTC (rev 16383)
@@ -294,12 +294,12 @@
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 @@
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 @@
{
CU_pSuite suite = CU_add_suite("lwstroke", NULL, NULL);
PG_ADD_TEST(suite, test_lwcurve_linearize);
+ PG_ADD_TEST(suite, test_unstroke);
}
Modified: trunk/liblwgeom/cunit/cu_ptarray.c
===================================================================
--- trunk/liblwgeom/cunit/cu_ptarray.c 2018-02-17 08:42:21 UTC (rev 16382)
+++ trunk/liblwgeom/cunit/cu_ptarray.c 2018-02-17 08:46:20 UTC (rev 16383)
@@ -340,131 +340,6 @@
}
-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 @@
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);
Modified: trunk/liblwgeom/lwstroke.c
===================================================================
--- trunk/liblwgeom/lwstroke.c 2018-02-17 08:42:21 UTC (rev 16382)
+++ trunk/liblwgeom/lwstroke.c 2018-02-17 08:46:20 UTC (rev 16383)
@@ -43,6 +43,7 @@
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 @@
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 @@
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 @@
{
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 @@
{
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 @@
{
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,12 +1078,40 @@
{
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)
{
LWDEBUG(2, "lwgeom_unstroke called.");
@@ -1097,8 +1126,10 @@
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);
}
}
Modified: trunk/liblwgeom/ptarray.c
===================================================================
--- trunk/liblwgeom/ptarray.c 2018-02-17 08:42:21 UTC (rev 16382)
+++ trunk/liblwgeom/ptarray.c 2018-02-17 08:46:20 UTC (rev 16383)
@@ -653,7 +653,7 @@
{
POINTARRAY *out = lwalloc(sizeof(POINTARRAY));
- LWDEBUG(3, "ptarray_clone_deep called.");
+ LWDEBUG(3, "ptarray_clone called.");
out->flags = in->flags;
out->npoints = in->npoints;
More information about the postgis-tickets
mailing list