[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