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 const 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 );
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 const unsigned char* sourceWkb,
size_t sourceWkbSize,
155 unsigned char* targetWkb,
size_t& targetWkbSize,
157 bool writeHeader,
bool isaLinearRing )
159 bool isGeneralizable =
true;
164 const 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 const 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 const unsigned char* startWkbX = sourceWkb;
234 const unsigned char* startWkbY = startWkbX + sizeOfDoubleX;
235 const unsigned char* finalWkbX = sourceWkb + ( numPoints - 1 ) * ( sizeOfDoubleX + sizeOfDoubleY );
236 const 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 finalWkbSize = 0;
431 const unsigned char* wkb = geometry->
asWkb();
432 size_t wkbSize = geometry->
wkbSize();
434 unsigned char* targetWkb =
new unsigned char[wkbSize];
435 memcpy( targetWkb, wkb, wkbSize );
437 if ( simplifyWkbGeometry( simplifyFlags, wkbType, wkb, wkbSize, targetWkb, finalWkbSize, envelope, tolerance ) )
439 unsigned char* finalWkb =
new unsigned char[finalWkbSize];
440 memcpy( finalWkb, targetWkb, finalWkbSize );
441 geometry->
fromWkb( finalWkb, finalWkbSize );
static WkbType flatType(WkbType type)
Map 2d+ to 2d type.
A rectangle specified with double values.
void setMinimal()
Set a rectangle so that min corner is at max and max corner is at min.
static int wkbDimensions(WkbType type)
virtual ~QgsMapToPixelSimplifier()
static QgsRectangle calculateBoundingBox(QGis::WkbType wkbType, const unsigned char *wkb, size_t numPoints)
Returns the BBOX of the specified WKB-point stream.
size_t wkbSize() const
Returns the size of the WKB in asWkb().
double yMaximum() const
Get the y maximum value (top side of rectangle)
virtual bool simplifyGeometry(QgsGeometry *geometry) const override
Simplifies the specified geometry.
QgsRectangle boundingBox() const
Returns the bounding box of this feature.
QGis::GeometryType type() const
Returns type of the geometry as a QGis::GeometryType.
A geometry is the spatial representation of a feature.
virtual QgsGeometry * simplify(QgsGeometry *geometry) const override
Returns a simplified version the specified geometry.
WkbType
Used for symbology operations.
static endian_t endian()
Returns whether this machine uses big or little endian.
static bool isGeneralizableByMapBoundingBox(const QgsRectangle &envelope, double map2pixelTol)
Returns whether the envelope can be replaced by its BBOX when is applied the specified map2pixel cont...
void combineExtentWith(QgsRectangle *rect)
expand the rectangle so that covers both the original rectangle and the given rectangle ...
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
double xMaximum() const
Get the x maximum value (right side of rectangle)
The geometries can be fully simplified by its BoundingBox.
QgsMapToPixelSimplifier(int simplifyFlags, double tolerance)
static float calculateLengthSquared2D(double x1, double y1, double x2, double y2)
Returns the squared 2D-distance of the vector defined by the two points specified.
QGis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
static bool generalizeWkbGeometryByBoundingBox(QGis::WkbType wkbType, const unsigned char *sourceWkb, size_t sourceWkbSize, unsigned char *targetWkb, size_t &targetWkbSize, const QgsRectangle &envelope, bool writeHeader)
Generalize the WKB-geometry using the BBOX of the original geometry.
static WkbType singleType(WkbType type)
Map multi to single type.
double mTolerance
Distance tolerance for the simplification.
void fromWkb(unsigned char *wkb, size_t length)
Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length...
int mSimplifyFlags
Current simplification flags.
The geometries can be simplified using the current map2pixel context state.
double width() const
Width of the rectangle.
const unsigned char * asWkb() const
Returns the buffer containing this geometry in WKB format.
double xMinimum() const
Get the x minimum value (left side of rectangle)
double height() const
Height of the rectangle.