@@ -44,7 +44,6 @@ float QgsMapToPixelSimplifier::calculateLengthSquared2D( double x1, double y1, d
44
44
return ( vx * vx ) + ( vy * vy );
45
45
}
46
46
47
-
48
47
// ! Returns whether the points belong to the same grid
49
48
bool QgsMapToPixelSimplifier::equalSnapToGrid ( double x1, double y1, double x2, double y2, double gridOriginX, double gridOriginY, float gridInverseSizeXY )
50
49
{
@@ -79,6 +78,32 @@ inline static QgsRectangle calculateBoundingBox( QGis::WkbType wkbType, QgsConst
79
78
return r;
80
79
}
81
80
81
+ // ////////////////////////////////////////////////////////////////////////////////////////////
82
+ // Helper simplification methods for Visvalingam method
83
+
84
+ // It uses a refactored code of the liblwgeom implementation:
85
+ // https://github.com/postgis/postgis/blob/svn-trunk/liblwgeom/effectivearea.h
86
+ // https://github.com/postgis/postgis/blob/svn-trunk/liblwgeom/effectivearea.c
87
+
88
+ #define LWDEBUG //
89
+ #define LWDEBUGF //
90
+ #define FP_MAX qMax
91
+ #define FLAGS_GET_Z ( flags ) ( ( flags ) & 0x01 )
92
+ #define LW_MSG_MAXLEN 256
93
+ #define lwalloc qgsMalloc
94
+ #define lwfree qgsFree
95
+ #define lwerror qWarning
96
+
97
+ #include " simplify/effectivearea.h"
98
+ #include " simplify/effectivearea.c"
99
+
100
+ double * getPoint_internal ( const POINTARRAY* inpts, int pointIndex )
101
+ {
102
+ return inpts->pointlist + ( pointIndex * inpts->dimension );
103
+ }
104
+
105
+ // ////////////////////////////////////////////////////////////////////////////////////////////
106
+
82
107
// ! Generalize the WKB-geometry using the BBOX of the original geometry
83
108
static bool generalizeWkbGeometryByBoundingBox (
84
109
QGis::WkbType wkbType,
@@ -248,6 +273,40 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
248
273
r.combineExtentWith ( x, y );
249
274
}
250
275
}
276
+ else if ( simplifyAlgorithm == Visvalingam )
277
+ {
278
+ map2pixelTol *= map2pixelTol; // -> Use mappixelTol for 'Area' calculations.
279
+
280
+ POINTARRAY inpts;
281
+ inpts.pointlist = ( double * )( const unsigned char * )sourceWkbPtr;
282
+ inpts.dimension = QGis::wkbDimensions ( wkbType );
283
+ inpts.npoints = numPoints;
284
+ inpts.flags = 0 ;
285
+
286
+ EFFECTIVE_AREAS* ea;
287
+ ea = initiate_effectivearea ( &inpts );
288
+
289
+ int set_area = 0 ;
290
+ ptarray_calc_areas ( ea, isaLinearRing ? 4 : 2 , set_area, map2pixelTol );
291
+
292
+ for ( int i = 0 ; i < numPoints; ++i )
293
+ {
294
+ if ( ea->res_arealist [ i ] > map2pixelTol )
295
+ {
296
+ double * coord = getPoint_internal ( &inpts, i );
297
+ x = coord[ 0 ];
298
+ y = coord[ 1 ];
299
+
300
+ targetWkbPtr << x << y;
301
+ lastX = x;
302
+ lastY = y;
303
+ numTargetPoints++;
304
+ }
305
+ }
306
+ destroy_effectivearea ( ea );
307
+
308
+ sourceWkbPtr += numPoints * ( inpts.dimension * sizeof ( double ) );
309
+ }
251
310
else
252
311
{
253
312
map2pixelTol *= map2pixelTol; // -> Use mappixelTol for 'LengthSquare' calculations.
0 commit comments