[postgis-tickets] r14457 - #2232, avoid accumulated error in SVG rounding
Paul Ramsey
pramsey at cleverelephant.ca
Mon Nov 30 08:31:18 PST 2015
Author: pramsey
Date: 2015-11-30 08:31:18 -0800 (Mon, 30 Nov 2015)
New Revision: 14457
Modified:
trunk/liblwgeom/lwout_svg.c
trunk/regress/tickets.sql
trunk/regress/tickets_expected
Log:
#2232, avoid accumulated error in SVG rounding
Modified: trunk/liblwgeom/lwout_svg.c
===================================================================
--- trunk/liblwgeom/lwout_svg.c 2015-11-30 16:31:08 UTC (rev 14456)
+++ trunk/liblwgeom/lwout_svg.c 2015-11-30 16:31:18 UTC (rev 14457)
@@ -547,54 +547,78 @@
{
int i, end;
char *ptr;
- char x[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
- char y[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
- POINT2D pt, lpt;
+ char sx[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
+ char sy[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
+ const POINT2D *pt;
+ double f = 1.0;
+ double dx, dy, x, y, accum_x, accum_y;
+
ptr = output;
+ if (precision >= 0)
+ {
+ f = pow(10, precision);
+ }
+
if (close_ring) end = pa->npoints;
else end = pa->npoints - 1;
/* Starting point */
- getPoint2d_p(pa, 0, &pt);
+ pt = getPoint2d_cp(pa, 0);
- if (fabs(pt.x) < OUT_MAX_DOUBLE)
- sprintf(x, "%.*f", precision, pt.x);
+ x = round(pt->x*f)/f;
+ y = round(pt->y*f)/f;
+
+ if (fabs(x) < OUT_MAX_DOUBLE)
+ sprintf(sx, "%.*f", precision, x);
else
- sprintf(x, "%g", pt.x);
- trim_trailing_zeros(x);
+ sprintf(sx, "%g", x);
+ trim_trailing_zeros(sx);
- if (fabs(pt.y) < OUT_MAX_DOUBLE)
- sprintf(y, "%.*f", precision, fabs(pt.y) ? pt.y * -1 : pt.y);
+ if (fabs(y) < OUT_MAX_DOUBLE)
+ sprintf(sy, "%.*f", precision, fabs(y) ? y * -1 : y);
else
- sprintf(y, "%g", fabs(pt.y) ? pt.y * -1 : pt.y);
- trim_trailing_zeros(y);
+ sprintf(sy, "%g", fabs(y) ? y * -1 : y);
+ trim_trailing_zeros(sy);
- ptr += sprintf(ptr,"%s %s l", x, y);
+ ptr += sprintf(ptr,"%s %s l", sx, sy);
+
+ /* accum */
+ accum_x = x;
+ accum_y = y;
/* All the following ones */
for (i=1 ; i < end ; i++)
{
- lpt = pt;
+ // lpt = pt;
- getPoint2d_p(pa, i, &pt);
- if (fabs(pt.x -lpt.x) < OUT_MAX_DOUBLE)
- sprintf(x, "%.*f", precision, pt.x -lpt.x);
+ pt = getPoint2d_cp(pa, i);
+
+ x = round(pt->x*f)/f;
+ y = round(pt->y*f)/f;
+ dx = x - accum_x;
+ dy = y - accum_y;
+
+ if (fabs(dx) < OUT_MAX_DOUBLE)
+ sprintf(sx, "%.*f", precision, dx);
else
- sprintf(x, "%g", pt.x -lpt.x);
- trim_trailing_zeros(x);
+ sprintf(sx, "%g", dx);
+ trim_trailing_zeros(sx);
/* SVG Y axis is reversed, an no need to transform 0 into -0 */
- if (fabs(pt.y -lpt.y) < OUT_MAX_DOUBLE)
- sprintf(y, "%.*f", precision,
- fabs(pt.y -lpt.y) ? (pt.y - lpt.y) * -1: (pt.y - lpt.y));
+ if (fabs(dy) < OUT_MAX_DOUBLE)
+ sprintf(sy, "%.*f", precision,
+ fabs(dy) ? dy * -1: dy);
else
- sprintf(y, "%g",
- fabs(pt.y -lpt.y) ? (pt.y - lpt.y) * -1: (pt.y - lpt.y));
- trim_trailing_zeros(y);
+ sprintf(sy, "%g",
+ fabs(dy) ? dy * -1: dy);
+ trim_trailing_zeros(sy);
+
+ accum_x += dx;
+ accum_y += dy;
- ptr += sprintf(ptr," %s %s", x, y);
+ ptr += sprintf(ptr," %s %s", sx, sy);
}
return (ptr-output);
Modified: trunk/regress/tickets.sql
===================================================================
--- trunk/regress/tickets.sql 2015-11-30 16:31:08 UTC (rev 14456)
+++ trunk/regress/tickets.sql 2015-11-30 16:31:18 UTC (rev 14457)
@@ -822,6 +822,8 @@
SELECT '#2145',
round(ST_Length(St_Segmentize(ST_GeographyFromText('LINESTRING(-89.3000030518 28.2000007629,-89.1999969482 89.1999969482,-89.1999969482 89.1999969482)'), 10000))::numeric,0);
+SELECT '#2232', ST_AsSVG('LINESTRING(0 0, 0.4 0, 0.8 0, 1.2 0,1.6 0, 2 0)'::geometry,1,0);
+
-- #2307 --
SELECT '#2307', ST_AsText(ST_SnapToGrid(ST_MakeValid('0106000020E6100000010000000103000000010000000A0000004B7DA956B99844C0DB0790FE8B4D1DC010BA74A9AF9444C049AFFC5B8C4D1DC03FC6CC690D9844C0DD67E5628C4D1DC07117B56B0D9844C0C80ABA67C45E1DC0839166ABAF9444C0387D4568C45E1DC010BA74A9AF9444C049AFFC5B8C4D1DC040C3CD74169444C0362EC0608C4D1DC07C1A3B77169444C0DC3ADB40B2641DC03AAE5F68B99844C0242948DEB1641DC04B7DA956B99844C0DB0790FE8B4D1DC0'::geometry),0.0001));
Modified: trunk/regress/tickets_expected
===================================================================
--- trunk/regress/tickets_expected 2015-11-30 16:31:08 UTC (rev 14456)
+++ trunk/regress/tickets_expected 2015-11-30 16:31:18 UTC (rev 14457)
@@ -244,6 +244,7 @@
#2110.2|t
#2110.3|t
#2145|6792004
+#2232|M 0 0 l 0 0 1 0 0 0 1 0 0 0
#2307|MULTIPOLYGON(((-41.1932 -7.3257,-41.1616 -7.3257,-41.1569 -7.3257,-41.1569 -7.3483,-41.1932 -7.3483,-41.1932 -7.3257),(-41.1616 -7.3257,-41.1879 -7.3257,-41.1879 -7.3425,-41.1616 -7.3425,-41.1616 -7.3257)))
#2409|GeometryCollection[B] with 2 elements
MultiSurface[] with 2 elements
More information about the postgis-tickets
mailing list