[postgis-tickets] r16221 - Fix ST_RemoveRepeatedPoints dropping one extra point in certain ptarrays

Darafei komzpa at gmail.com
Fri Jan 5 05:16:13 PST 2018


Author: komzpa
Date: 2018-01-05 05:16:12 -0800 (Fri, 05 Jan 2018)
New Revision: 16221

Modified:
   trunk/liblwgeom/cunit/cu_algorithm.c
   trunk/liblwgeom/ptarray.c
   trunk/regress/remove_repeated_points.sql
   trunk/regress/remove_repeated_points_expected
Log:
Fix ST_RemoveRepeatedPoints dropping one extra point in certain ptarrays

Patch by Raúl Marín Rodríguez.

Closes #3969
Closes https://github.com/postgis/postgis/pull/182



Modified: trunk/liblwgeom/cunit/cu_algorithm.c
===================================================================
--- trunk/liblwgeom/cunit/cu_algorithm.c	2018-01-04 21:47:10 UTC (rev 16220)
+++ trunk/liblwgeom/cunit/cu_algorithm.c	2018-01-05 13:16:12 UTC (rev 16221)
@@ -1012,7 +1012,6 @@
 	lwgeom_remove_repeated_points_in_place(g, 1);
 	ewkt = lwgeom_to_ewkt(g);
 	CU_ASSERT_STRING_EQUAL(ewkt, "MULTIPOINT(0 0,10 0,10 10,0 10,5 5)");
-	// printf("%s\n", ewkt);
 	lwgeom_free(g);
 	lwfree(ewkt);
 
@@ -1020,20 +1019,22 @@
 	lwgeom_remove_repeated_points_in_place(g, 0.01);
 	ewkt = lwgeom_to_ewkt(g);
 	CU_ASSERT_STRING_EQUAL(ewkt, "LINESTRING(1612830.15445 4841287.12672,1612829.98813 4841274.56198)");
-	// printf("%s\n", ewkt);
 	lwgeom_free(g);
 	lwfree(ewkt);
 
-
 	g = lwgeom_from_wkt("MULTIPOINT(0 0,10 0,10 10,10 10,0 10,0 10,0 10,0 0,0 0,0 0,5 5,5 5,5 8,8 8,8 8,8 8,8 5,8 5,5 5,5 5,5 5,5 5,5 5,50 50,50 50,50 50,50 60,50 60,50 60,60 60,60 50,60 50,50 50,55 55,55 58,58 58,58 55,58 55,55 55)", LW_PARSER_CHECK_NONE);
 	lwgeom_remove_repeated_points_in_place(g, 1);
 	ewkt = lwgeom_to_ewkt(g);
 	CU_ASSERT_STRING_EQUAL(ewkt, "MULTIPOINT(0 0,10 0,10 10,0 10,5 5,5 8,8 8,8 5,50 50,50 60,60 60,60 50,55 55,55 58,58 58,58 55)");
-	// printf("%s\n", ewkt);
 	lwgeom_free(g);
 	lwfree(ewkt);
 
-
+	g = lwgeom_from_wkt("POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))", LW_PARSER_CHECK_NONE);
+	lwgeom_remove_repeated_points_in_place(g, 10000);
+	ewkt = lwgeom_to_ewkt(g);
+	CU_ASSERT_STRING_EQUAL(ewkt, "POLYGON((0 0,1 1,1 0,0 0))");
+	lwgeom_free(g);
+	lwfree(ewkt);
 }
 
 static void test_lwgeom_simplify(void)

Modified: trunk/liblwgeom/ptarray.c
===================================================================
--- trunk/liblwgeom/ptarray.c	2018-01-04 21:47:10 UTC (rev 16220)
+++ trunk/liblwgeom/ptarray.c	2018-01-05 13:16:12 UTC (rev 16221)
@@ -1452,52 +1452,48 @@
 	const POINT2D *last = NULL;
 	const POINT2D *pt;
 	int n_points = pa->npoints;
-	int n_points_out = 0;
-	int pt_size = ptarray_point_size(pa);
+	int n_points_out = 1;
 	double dsq = FLT_MAX;
 
 	/* No-op on short inputs */
-	if ( n_points <= 2 ) return;
+	if ( n_points <= min_points ) return;
 
-	for (i = 0; i < n_points; i++)
+	last = getPoint2d_cp(pa, 0);
+	for (i = 1; i < n_points; i++)
 	{
 		int last_point = (i == n_points-1);
 
 		/* Look straight into the abyss */
 		pt = getPoint2d_cp(pa, i);
 
-		/* Preserve first point always */
-		if (last)
+		/* Don't drop points if we are running short of points */
+		if (n_points - i > min_points - n_points_out)
 		{
-			/* Don't drop points if we are running short of points */
-		        if (n_points - i > min_points - n_points_out)
+			if (tolerance > 0.0)
 			{
-				if (tolerance > 0.0)
+				/* Only drop points that are within our tolerance */
+				dsq = distance2d_sqr_pt_pt(last, pt);
+				/* Allow any point but the last one to be dropped */
+				if (!last_point && dsq <= tolsq)
 				{
-					/* Only drop points that are within our tolerance */
-					dsq = distance2d_sqr_pt_pt(last, pt);
-					/* Allow any point but the last one to be dropped */
-					if (!last_point && dsq <= tolsq)
-					{
-						continue;
-					}
+					continue;
 				}
-				else
-				{
-					/* At tolerance zero, only skip exact dupes */
-					if (memcmp((char*)pt, (char*)last, pt_size) == 0)
-						continue;
-				}
 			}
-		}
+			else
+			{
+				/* At tolerance zero, only skip exact dupes */
+				if (memcmp((char*)pt, (char*)last, ptarray_point_size(pa)) == 0)
+					continue;
+			}
 
-		/* Got to last point, and it's not very different from */
-		/* the point that preceded it. We want to keep the last */
-		/* point, not the second-to-last one, so we pull our write */
-		/* index back one value */
-		if (last_point && n_points_out > 1 && tolerance > 0.0 && dsq <= tolsq)
-		{
-			n_points_out--;
+			/* Got to last point, and it's not very different from */
+			/* the point that preceded it. We want to keep the last */
+			/* point, not the second-to-last one, so we pull our write */
+			/* index back one value */
+			if (last_point && n_points_out > 1 && tolerance > 0.0 && dsq <= tolsq)
+			{
+				n_points_out--;
+			}
 		}
 
 		/* Compact all remaining values to front of array */

Modified: trunk/regress/remove_repeated_points.sql
===================================================================
--- trunk/regress/remove_repeated_points.sql	2018-01-04 21:47:10 UTC (rev 16220)
+++ trunk/regress/remove_repeated_points.sql	2018-01-05 13:16:12 UTC (rev 16221)
@@ -27,5 +27,6 @@
 SELECT 15, ST_AsText(ST_RemoveRepeatedPoints('MULTIPOINT(0 0, 0 0, 1 1, 2 2)'::geometry));
 SELECT 16, ST_AsText(ST_RemoveRepeatedPoints('MULTIPOINT(0 0, 0 0, 1 1, 2 2)'::geometry,0.1));
 SELECT 17, ST_AsText(ST_RemoveRepeatedPoints('MULTIPOINT(0 0, 0 0, 1 1, 4 4)'::geometry,2));
+SELECT 18, ST_AsText(ST_RemoveRepeatedPoints('POLYGON((-215922 5325694,-218080 5321866,-218693 5322119,-216112 5325812,-215922 5325694))'::geometry, 10000));
 
 

Modified: trunk/regress/remove_repeated_points_expected
===================================================================
--- trunk/regress/remove_repeated_points_expected	2018-01-04 21:47:10 UTC (rev 16220)
+++ trunk/regress/remove_repeated_points_expected	2018-01-05 13:16:12 UTC (rev 16221)
@@ -16,3 +16,4 @@
 15|MULTIPOINT(0 0,1 1,2 2)
 16|MULTIPOINT(0 0,1 1,2 2)
 17|MULTIPOINT(0 0,4 4)
+18|POLYGON((-215922 5325694,-218693 5322119,-216112 5325812,-215922 5325694))



More information about the postgis-tickets mailing list