22 : mSimplifyFlags( simplifyFlags )
23 , mTolerance( tolerance )
37 float vx = ( float )( x2 - x1 );
38 float vy = ( float )( y2 - y1 );
50 int sizeOfDoubleX =
sizeof( double );
51 int sizeOfDoubleY =
QGis::wkbDimensions( wkbType ) == 3 ? 2 *
sizeof( double ) :
sizeof(
double );
53 for (
size_t i = 0; i < numPoints; ++i )
55 memcpy( &x, wkb,
sizeof(
double ) ); wkb += sizeOfDoubleX;
56 memcpy( &y, wkb,
sizeof(
double ) ); wkb += sizeOfDoubleY;
66 unsigned char* sourceWkb,
size_t sourceWkbSize,
67 unsigned char* targetWkb,
size_t& targetWkbSize,
70 Q_UNUSED( sourceWkb );
71 unsigned char* wkb2 = targetWkb;
74 int sizeOfDoubleX =
sizeof( double );
75 int sizeOfDoubleY =
QGis::wkbDimensions( wkbType ) == 3 ? 2 *
sizeof( double ) :
sizeof(
double );
78 size_t minimumSize = geometryType ==
QGis::WKBLineString ? 4 + 2 * ( sizeOfDoubleX + sizeOfDoubleY ) : 8 + 5 * ( sizeOfDoubleX + sizeOfDoubleY );
83 if ( sourceWkbSize <= minimumSize )
98 memcpy( targetWkb, &byteOrder, 1 );
101 memcpy( targetWkb, &geometryType, 4 );
107 memcpy( targetWkb, &numRings, 4 );
116 memcpy( targetWkb, &numPoints, 4 );
119 memcpy( targetWkb, &x1,
sizeof(
double ) ); targetWkb +=
sizeof( double );
120 memcpy( targetWkb, &y1,
sizeof(
double ) ); targetWkb +=
sizeof( double );
122 memcpy( targetWkb, &x2,
sizeof(
double ) ); targetWkb +=
sizeof( double );
123 memcpy( targetWkb, &y2,
sizeof(
double ) ); targetWkb +=
sizeof( double );
128 memcpy( targetWkb, &numPoints, 4 );
131 memcpy( targetWkb, &x1,
sizeof(
double ) ); targetWkb +=
sizeof( double );
132 memcpy( targetWkb, &y1,
sizeof(
double ) ); targetWkb +=
sizeof( double );
134 memcpy( targetWkb, &x2,
sizeof(
double ) ); targetWkb +=
sizeof( double );
135 memcpy( targetWkb, &y1,
sizeof(
double ) ); targetWkb +=
sizeof( double );
137 memcpy( targetWkb, &x2,
sizeof(
double ) ); targetWkb +=
sizeof( double );
138 memcpy( targetWkb, &y2,
sizeof(
double ) ); targetWkb +=
sizeof( double );
140 memcpy( targetWkb, &x1,
sizeof(
double ) ); targetWkb +=
sizeof( double );
141 memcpy( targetWkb, &y2,
sizeof(
double ) ); targetWkb +=
sizeof( double );
143 memcpy( targetWkb, &x1,
sizeof(
double ) ); targetWkb +=
sizeof( double );
144 memcpy( targetWkb, &y1,
sizeof(
double ) ); targetWkb +=
sizeof( double );
146 targetWkbSize += targetWkb - wkb2;
152 bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
154 unsigned char* sourceWkb,
size_t sourceWkbSize,
155 unsigned char* targetWkb,
size_t& targetWkbSize,
157 bool writeHeader,
bool isaLinearRing )
159 bool isGeneralizable =
true;
164 unsigned char* sourcePrevWkb = sourceWkb;
165 unsigned char* targetPrevWkb = targetWkb;
166 size_t targetWkbPrevSize = targetWkbSize;
173 if ( isGeneralizable )
178 isGeneralizable =
false;
183 targetWkb[0] = sourceWkb[0];
188 memcpy( &geometryType, sourceWkb, 4 );
190 memcpy( targetWkb, &flatType, 4 );
197 unsigned char* wkb1 = sourceWkb;
198 unsigned char* wkb2 = targetWkb;
204 double x, y, lastX = 0, lastY = 0;
208 int sizeOfDoubleX =
sizeof( double );
209 int sizeOfDoubleY =
QGis::wkbDimensions( wkbType ) == 3 ? 2 *
sizeof( double ) :
sizeof(
double );
212 memcpy( &numPoints, sourceWkb, 4 );
214 if ( numPoints <= ( isaLinearRing ? 5 : 2 ) )
215 isGeneralizable =
false;
217 int numTargetPoints = 0;
218 memcpy( targetWkb, &numTargetPoints, 4 );
222 double* ptr = (
double* )targetWkb;
223 map2pixelTol *= map2pixelTol;
226 bool hasLongSegments =
false;
231 double x1, y1, x2, y2;
233 unsigned char* startWkbX = sourceWkb;
234 unsigned char* startWkbY = startWkbX + sizeOfDoubleX;
235 unsigned char* finalWkbX = sourceWkb + ( numPoints - 1 ) * ( sizeOfDoubleX + sizeOfDoubleY );
236 unsigned char* finalWkbY = finalWkbX + sizeOfDoubleX;
238 memcpy( &x1, startWkbX,
sizeof(
double ) );
239 memcpy( &y1, startWkbY,
sizeof(
double ) );
240 memcpy( &x2, finalWkbX,
sizeof(
double ) );
241 memcpy( &y2, finalWkbY,
sizeof(
double ) );
243 isaLinearRing = ( x1 == x2 ) && ( y1 == y2 );
247 for (
int i = 0; i < numPoints; ++i )
249 memcpy( &x, sourceWkb,
sizeof(
double ) ); sourceWkb += sizeOfDoubleX;
250 memcpy( &y, sourceWkb,
sizeof(
double ) ); sourceWkb += sizeOfDoubleY;
252 isLongSegment =
false;
257 ( !isaLinearRing && ( i == 1 || i >= numPoints - 2 ) ) )
259 memcpy( ptr, &x,
sizeof(
double ) ); lastX = x; ptr++;
260 memcpy( ptr, &y,
sizeof(
double ) ); lastY = y; ptr++;
263 hasLongSegments |= isLongSegment;
268 targetWkb = wkb2 + 4;
270 if ( numTargetPoints < ( isaLinearRing ? 4 : 2 ) )
273 if ( !hasLongSegments )
277 unsigned char* targetTempWkb = targetWkb;
278 size_t targetWkbTempSize = targetWkbSize;
280 sourceWkb = sourcePrevWkb;
281 targetWkb = targetPrevWkb;
282 targetWkbSize = targetWkbPrevSize;
286 targetWkb = targetTempWkb;
287 targetWkbSize = targetWkbTempSize;
301 memcpy( &x, targetWkb + 0,
sizeof(
double ) );
302 memcpy( &y, targetWkb +
sizeof(
double ),
sizeof(
double ) );
303 if ( lastX != x || lastY != y )
305 memcpy( ptr, &x,
sizeof(
double ) ); ptr++;
306 memcpy( ptr, &y,
sizeof(
double ) ); ptr++;
310 targetWkbSize += numTargetPoints *
sizeof( double ) * 2;
313 memcpy( targetWkb, &numTargetPoints, 4 );
314 result = numPoints != numTargetPoints;
319 memcpy( &numRings, sourceWkb, 4 );
322 memcpy( targetWkb, &numRings, 4 );
326 for (
int i = 0; i < numRings; ++i )
329 memcpy( &numPoints_i, sourceWkb, 4 );
332 size_t sourceWkbSize_i = 4 + numPoints_i * ( hasZValue ? 3 : 2 ) *
sizeof(
double );
333 size_t targetWkbSize_i = 0;
335 result |= simplifyWkbGeometry( simplifyFlags, wkbType, sourceWkb, sourceWkbSize_i, targetWkb, targetWkbSize_i, envelope_i, map2pixelTol,
false,
true );
336 sourceWkb += sourceWkbSize_i;
337 targetWkb += targetWkbSize_i;
339 targetWkbSize += targetWkbSize_i;
345 memcpy( &numGeoms, sourceWkb, 4 );
349 memcpy( targetWkb, &numGeoms, 4 );
353 for (
int i = 0; i < numGeoms; ++i )
355 size_t sourceWkbSize_i = 0;
356 size_t targetWkbSize_i = 0;
362 memcpy( &numPoints_i, wkb1 + 5, 4 );
363 int wkbSize_i = 4 + numPoints_i * ( hasZValue ? 3 : 2 ) *
sizeof(
double );
365 sourceWkbSize_i += 5 + wkbSize_i;
366 wkb1 += 5 + wkbSize_i;
371 memcpy( &numPrings_i, wkb1 + 5, 4 );
375 for (
int j = 0; j < numPrings_i; ++j )
378 memcpy( &numPoints_i, wkb1, 4 );
379 int wkbSize_i = 4 + numPoints_i * ( hasZValue ? 3 : 2 ) *
sizeof(
double );
381 sourceWkbSize_i += wkbSize_i;
385 result |= simplifyWkbGeometry( simplifyFlags,
QGis::singleType( wkbType ), sourceWkb, sourceWkbSize_i, targetWkb, targetWkbSize_i, envelope, map2pixelTol,
true,
false );
386 sourceWkb += sourceWkbSize_i;
387 targetWkb += targetWkbSize_i;
389 targetWkbSize += targetWkbSize_i;
401 return envelope.
width() < map2pixelTol && envelope.
height() < map2pixelTol;
409 size_t wkbSize = geometry->
wkbSize();
410 unsigned char* wkb = (
unsigned char* )malloc( wkbSize );
411 memcpy( wkb, geometry->
asWkb(), wkbSize );
421 size_t targetWkbSize = 0;
431 unsigned char* wkb = (
unsigned char* )geometry->
asWkb();
432 size_t wkbSize = geometry->
wkbSize();
435 if ( simplifyWkbGeometry( simplifyFlags, wkbType, wkb, wkbSize, wkb, targetWkbSize, envelope, tolerance ) )
437 unsigned char* targetWkb =
new unsigned char[targetWkbSize];
438 memcpy( targetWkb, wkb, targetWkbSize );
439 geometry->
fromWkb( targetWkb, targetWkbSize );