25 : mSimplifyFlags( simplifyFlags )
26 , mTolerance( tolerance )
40 float vx =
static_cast< float >( x2 - x1 );
41 float vy =
static_cast< float >( y2 - y1 );
53 Q_ASSERT( skipZM >= 0 );
55 for (
int i = 0; i < numPoints; ++i )
78 Q_ASSERT( skipZM >= 0 );
81 int minimumSize = geometryType ==
QGis::WKBLineString ? 4 + 2 * ( 2 *
sizeof( double ) + skipZM ) : 8 + 5 * ( 2 *
sizeof( double ) + skipZM );
86 if ( sourceWkbPtr.
remaining() <= minimumSize )
111 targetWkbPtr << 2 << x1 << y1 << x2 << y2;
115 targetWkbPtr << 5 << x1 << y1 << x2 << y1 << x2 << y2 << x1 << y2 << x1 << y1;
118 targetWkbSize += targetWkbPtr - savedTargetWkb;
124 bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
130 bool writeHeader,
bool isaLinearRing )
132 bool isGeneralizable =
true;
137 QgsWkbPtr targetPrevWkbPtr( targetWkbPtr );
138 int targetWkbPrevSize = targetWkbSize;
145 if ( isGeneralizable )
150 isGeneralizable =
false;
159 targetWkbSize += targetWkbPtr - targetPrevWkbPtr;
167 QgsWkbPtr savedTargetWkbPtr( targetWkbPtr );
168 double x = 0.0, y = 0.0, lastX = 0, lastY = 0;
173 Q_ASSERT( skipZM >= 0 );
176 sourceWkbPtr >> numPoints;
178 if ( numPoints <= ( isaLinearRing ? 5 : 2 ) )
179 isGeneralizable =
false;
183 int numTargetPoints = 0;
184 targetWkbPtr << numTargetPoints;
187 map2pixelTol *= map2pixelTol;
190 bool hasLongSegments =
false;
197 double x1, y1, x2, y2;
199 checkPtr >> x1 >> y1;
200 checkPtr += skipZM + ( numPoints - 2 ) * ( 2 *
sizeof(
double ) + skipZM );
201 checkPtr >> x2 >> y2;
207 for (
int i = 0; i < numPoints; ++i )
209 sourceWkbPtr >> x >> y;
210 sourceWkbPtr += skipZM;
212 isLongSegment =
false;
217 ( !isaLinearRing && ( i == 1 || i >= numPoints - 2 ) ) )
219 targetWkbPtr << x << y;
224 hasLongSegments |= isLongSegment;
232 targetWkbPtr = savedTargetWkbPtr;
233 targetWkbPtr +=
sizeof( int );
235 if ( numTargetPoints < ( isaLinearRing ? 4 : 2 ) )
238 if ( !hasLongSegments )
243 int targetWkbTempSize = targetWkbSize;
245 sourceWkbPtr = sourcePrevWkbPtr;
246 targetWkbPtr = targetPrevWkbPtr;
247 targetWkbSize = targetWkbPrevSize;
251 targetWkbPtr = tempWkbPtr;
252 targetWkbSize = targetWkbTempSize;
267 targetWkbPtr << x << y;
270 nextPointPtr << x << y;
275 numPtr << numTargetPoints;
276 targetWkbSize += numTargetPoints *
sizeof( double ) * 2;
278 result = numPoints != numTargetPoints;
283 sourceWkbPtr >> numRings;
284 targetWkbPtr << numRings;
287 for (
int i = 0; i < numRings; ++i )
290 sourceWkbPtr >> numPoints_i;
294 sourceWkbPtr -=
sizeof( int );
296 int sourceWkbSize_i =
sizeof( int ) + numPoints_i *
QGis::wkbDimensions( wkbType ) *
sizeof( double );
297 int targetWkbSize_i = 0;
299 result |= simplifyWkbGeometry(
simplifyFlags, wkbType, sourceWkbPtr, targetWkbPtr, targetWkbSize_i, envelope_i, map2pixelTol,
false,
true );
300 sourceWkbPtr += sourceWkbSize_i;
301 targetWkbPtr += targetWkbSize_i;
303 targetWkbSize += targetWkbSize_i;
309 sourceWkbPtr >> numGeoms;
310 targetWkbPtr << numGeoms;
315 for (
int i = 0; i < numGeoms; ++i )
317 int sourceWkbSize_i = 0;
318 int targetWkbSize_i = 0;
326 sourceWkbPtr2 >> numPoints_i;
330 sourceWkbSize_i += 9 + wkbSize_i;
331 sourceWkbPtr2 += wkbSize_i;
336 sourceWkbPtr2 >> numPrings_i;
337 sourceWkbSize_i = 1 + 2 *
sizeof( int );
339 for (
int j = 0; j < numPrings_i; ++j )
342 sourceWkbPtr2 >> numPoints_i;
346 sourceWkbSize_i += 4 + wkbSize_i;
347 sourceWkbPtr2 += wkbSize_i;
350 result |= simplifyWkbGeometry(
simplifyFlags,
QGis::singleType( wkbType ), sourceWkbPtr, targetWkbPtr, targetWkbSize_i, envelope, map2pixelTol,
true,
false );
351 sourceWkbPtr += sourceWkbSize_i;
352 targetWkbPtr += targetWkbSize_i;
354 targetWkbSize += targetWkbSize_i;
367 return envelope.
width() < map2pixelTol && envelope.
height() < map2pixelTol;
375 int wkbSize = geometry->
wkbSize();
376 unsigned char* wkb =
new unsigned char[ wkbSize ];
377 memcpy( wkb, geometry->
asWkb(), wkbSize );
387 int finalWkbSize = 0;
399 unsigned char* targetWkb =
new unsigned char[wkbPtr.remaining()];
400 memcpy( targetWkb, wkbPtr, wkbPtr.remaining() );
401 QgsWkbPtr targetWkbPtr( targetWkb, wkbPtr.remaining() );
405 if ( simplifyWkbGeometry( simplifyFlags, wkbType, wkbPtr, targetWkbPtr, finalWkbSize, envelope, tolerance ) )
407 unsigned char *finalWkb =
new unsigned char[finalWkbSize];
408 memcpy( finalWkb, targetWkb, finalWkbSize );
409 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()
void fromWkb(unsigned char *wkb, int length)
Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length...
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.
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
QgsWKBTypes::Type readHeader() const
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)
static QgsRectangle calculateBoundingBox(QGis::WkbType wkbType, QgsConstWkbPtr wkbPtr, int numPoints)
Returns the BBOX of the specified WKB-point stream.
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.)
int simplifyFlags() const
static WkbType singleType(WkbType type)
Map multi to single type.
double mTolerance
Distance tolerance for the simplification.
int wkbSize() const
Returns the size of the WKB in asWkb().
static bool generalizeWkbGeometryByBoundingBox(QGis::WkbType wkbType, QgsConstWkbPtr sourceWkbPtr, QgsWkbPtr targetWkbPtr, int &targetWkbSize, const QgsRectangle &envelope, bool writeHeader)
Generalize the WKB-geometry using the BBOX of the original geometry.
static Type flatType(Type type)
Returns the flat type for a WKB type.
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.