25 : mSimplifyFlags( simplifyFlags )
26 , mSimplifyAlgorithm( simplifyAlgorithm )
27 , mTolerance( tolerance )
41 float vx =
static_cast< float >( x2 - x1 );
42 float vy =
static_cast< float >( y2 - y1 );
44 return ( vx * vx ) + ( vy * vy );
50 int grid_x1 = qRound(( x1 - gridOriginX ) * gridInverseSizeXY );
51 int grid_x2 = qRound(( x2 - gridOriginX ) * gridInverseSizeXY );
52 if ( grid_x1 != grid_x2 )
return false;
54 int grid_y1 = qRound(( y1 - gridOriginY ) * gridInverseSizeXY );
55 int grid_y2 = qRound(( y2 - gridOriginY ) * gridInverseSizeXY );
56 if ( grid_y1 != grid_y2 )
return false;
68 Q_ASSERT( skipZM >= 0 );
70 for (
int i = 0; i < numPoints; ++i )
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 97 #include "simplify/effectivearea.h" 98 #include "simplify/effectivearea.c" 102 return inpts->pointlist + ( pointIndex * inpts->dimension );
115 QgsWkbPtr savedTargetWkb( targetWkbPtr );
119 Q_ASSERT( skipZM >= 0 );
122 int minimumSize = geometryType ==
QGis::WKBLineString ? 4 + 2 * ( 2 *
sizeof( double ) + skipZM ) : 8 + 5 * ( 2 *
sizeof( double ) + skipZM );
127 if ( sourceWkbPtr.
remaining() <= minimumSize )
152 targetWkbPtr << 2 << x1 << y1 << x2 << y2;
156 targetWkbPtr << 5 << x1 << y1 << x2 << y1 << x2 << y2 << x1 << y2 << x1 << y1;
159 targetWkbSize += targetWkbPtr - savedTargetWkb;
165 bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
173 bool writeHeader,
bool isaLinearRing )
175 bool isGeneralizable =
true;
180 QgsWkbPtr targetPrevWkbPtr( targetWkbPtr );
181 int targetWkbPrevSize = targetWkbSize;
188 if ( isGeneralizable )
193 isGeneralizable =
false;
202 targetWkbSize += targetWkbPtr - targetPrevWkbPtr;
210 QgsWkbPtr savedTargetWkbPtr( targetWkbPtr );
211 double x = 0.0, y = 0.0, lastX = 0, lastY = 0;
216 Q_ASSERT( skipZM >= 0 );
219 sourceWkbPtr >> numPoints;
221 if ( numPoints <= ( isaLinearRing ? 5 : 2 ) )
222 isGeneralizable =
false;
226 int numTargetPoints = 0;
227 targetWkbPtr << numTargetPoints;
231 bool hasLongSegments =
false;
232 bool badLuck =
false;
239 double x1, y1, x2, y2;
241 checkPtr >> x1 >> y1;
242 checkPtr += skipZM + ( numPoints - 2 ) * ( 2 *
sizeof(
double ) + skipZM );
243 checkPtr >> x2 >> y2;
251 double gridOriginX = envelope.
xMinimum();
252 double gridOriginY = envelope.
yMinimum();
255 float gridInverseSizeXY = map2pixelTol != 0 ? ( float )( 1.0f / ( 0.8 * map2pixelTol ) ) : 0.0f;
257 for (
int i = 0; i < numPoints; ++i )
259 sourceWkbPtr >> x >> y;
260 sourceWkbPtr += skipZM;
264 !
equalSnapToGrid( x, y, lastX, lastY, gridOriginX, gridOriginY, gridInverseSizeXY ) ||
265 ( !isaLinearRing && ( i == 1 || i >= numPoints - 2 ) ) )
267 targetWkbPtr << x << y;
278 map2pixelTol *= map2pixelTol;
281 inpts.pointlist = (
double* )(
const unsigned char* )sourceWkbPtr;
283 inpts.npoints = numPoints;
287 ea = initiate_effectivearea( &inpts );
290 ptarray_calc_areas( ea, isaLinearRing ? 4 : 2, set_area, map2pixelTol );
292 for (
int i = 0; i < numPoints; ++i )
294 if ( ea->res_arealist[ i ] > map2pixelTol )
300 targetWkbPtr << x << y;
306 destroy_effectivearea( ea );
308 sourceWkbPtr += numPoints * ( inpts.dimension *
sizeof( double ) );
312 map2pixelTol *= map2pixelTol;
314 for (
int i = 0; i < numPoints; ++i )
316 sourceWkbPtr >> x >> y;
317 sourceWkbPtr += skipZM;
319 isLongSegment =
false;
324 ( !isaLinearRing && ( i == 1 || i >= numPoints - 2 ) ) )
326 targetWkbPtr << x << y;
331 hasLongSegments |= isLongSegment;
340 targetWkbPtr = savedTargetWkbPtr;
341 targetWkbPtr +=
sizeof( int );
343 if ( numTargetPoints < ( isaLinearRing ? 4 : 2 ) )
346 if ( !hasLongSegments )
351 int targetWkbTempSize = targetWkbSize;
353 sourceWkbPtr = sourcePrevWkbPtr;
354 targetWkbPtr = targetPrevWkbPtr;
355 targetWkbSize = targetWkbPrevSize;
359 targetWkbPtr = tempWkbPtr;
360 targetWkbSize = targetWkbTempSize;
374 targetWkbPtr << x << y;
377 nextPointPtr << x << y;
382 numPtr << numTargetPoints;
383 targetWkbSize += numTargetPoints *
sizeof( double ) * 2;
385 result = !badLuck && numTargetPoints > 0;
390 sourceWkbPtr >> numRings;
391 targetWkbPtr << numRings;
394 for (
int i = 0; i < numRings; ++i )
397 sourceWkbPtr >> numPoints_i;
401 sourceWkbPtr -=
sizeof( int );
403 int sourceWkbSize_i =
sizeof( int ) + numPoints_i *
QGis::wkbDimensions( wkbType ) *
sizeof( double );
404 int targetWkbSize_i = 0;
406 result |= simplifyWkbGeometry(
simplifyFlags,
simplifyAlgorithm, wkbType, sourceWkbPtr, targetWkbPtr, targetWkbSize_i, envelope_i, map2pixelTol,
false,
true );
407 sourceWkbPtr += sourceWkbSize_i;
408 targetWkbPtr += targetWkbSize_i;
410 targetWkbSize += targetWkbSize_i;
416 sourceWkbPtr >> numGeoms;
417 targetWkbPtr << numGeoms;
422 for (
int i = 0; i < numGeoms; ++i )
424 int sourceWkbSize_i = 0;
425 int targetWkbSize_i = 0;
433 sourceWkbPtr2 >> numPoints_i;
437 sourceWkbSize_i += 9 + wkbSize_i;
438 sourceWkbPtr2 += wkbSize_i;
443 sourceWkbPtr2 >> numPrings_i;
444 sourceWkbSize_i = 1 + 2 *
sizeof( int );
446 for (
int j = 0; j < numPrings_i; ++j )
449 sourceWkbPtr2 >> numPoints_i;
453 sourceWkbSize_i += 4 + wkbSize_i;
454 sourceWkbPtr2 += wkbSize_i;
458 sourceWkbPtr += sourceWkbSize_i;
459 targetWkbPtr += targetWkbSize_i;
461 targetWkbSize += targetWkbSize_i;
474 return envelope.
width() < map2pixelTol && envelope.
height() < map2pixelTol;
482 int wkbSize = geometry->
wkbSize();
483 unsigned char* wkb =
new unsigned char[ wkbSize ];
484 memcpy( wkb, geometry->
asWkb(), wkbSize );
494 int finalWkbSize = 0;
506 unsigned char* targetWkb =
new unsigned char[wkbPtr.remaining()];
507 memcpy( targetWkb, wkbPtr, wkbPtr.remaining() );
508 QgsWkbPtr targetWkbPtr( targetWkb, wkbPtr.remaining() );
512 if ( simplifyWkbGeometry( simplifyFlags, simplifyAlgorithm, wkbType, wkbPtr, targetWkbPtr, finalWkbSize, envelope, tolerance ) )
514 unsigned char *finalWkb =
new unsigned char[finalWkbSize];
515 memcpy( finalWkb, targetWkb, finalWkbSize );
516 geometry->
fromWkb( finalWkb, finalWkbSize );
548 sourceWkbPtr >> numPoints;
551 if ( numPoints <= ( isaLinearRing ? 6 : 3 ) )
555 sourceWkbPtr -=
sizeof( int );
557 int targetWkbSize = 5 +
sizeof( int ) + numPoints * ( 2 *
sizeof(
double ) );
558 unsigned char* targetWkb =
new unsigned char[ targetWkbSize ];
563 QgsWkbPtr targetWkbPtr( targetWkb, targetWkbSize );
567 if ( simplifyWkbGeometry( simplifyFlags, simplifyAlgorithm,
QGis::fromNewWkbType( singleType ), sourceWkbPtr, targetWkbPtr, targetWkbSize, envelope, tolerance,
false, isaLinearRing ) )
571 finalWkbPtr >> targetPoints;
574 sourceWkbPtr +=
sizeof( int ) + numPoints * ( 2 *
sizeof(
double ) + skipZM );
static WkbType flatType(WkbType type)
Map 2d+ to 2d type.
A rectangle specified with double values.
QGis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
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...
static QGis::WkbType fromNewWkbType(QgsWKBTypes::Type type)
Converts from new (post 2.10) WKB type (OGC) to old WKB type.
virtual bool simplifyGeometry(QgsGeometry *geometry) const override
Simplifies the specified geometry.
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.
The simplification uses a grid (similar to ST_SnapToGrid) to remove duplicate points.
SimplifyAlgorithm
Types of simplification algorithms that can be used.
static endian_t endian()
Returns whether this machine uses big or little endian.
int wkbSize() const
Returns the size of the WKB in asWkb().
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
double * getPoint_internal(const POINTARRAY *inpts, int pointIndex)
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...
static bool equalSnapToGrid(double x1, double y1, double x2, double y2, double gridOriginX, double gridOriginY, float gridInverseSizeXY)
Returns whether the points belong to the same grid.
SimplifyAlgorithm simplifyAlgorithm() const
Gets the local simplification algorithm of the vector layer managed.
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.
double width() const
Width of the rectangle.
int simplifyFlags() const
Gets the simplification hints of the vector layer managed.
The simplification gives each point in a line an importance weighting, so that least important points...
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.
const unsigned char * asWkb() const
Returns the buffer containing this geometry in WKB format.
QGis::GeometryType type() const
Returns type of the geometry as a QGis::GeometryType.
static WkbType singleType(WkbType type)
Map multi to single type.
double mTolerance
Distance tolerance for the simplification.
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
virtual bool simplifyPoints(QgsWKBTypes::Type wkbType, QgsConstWkbPtr &sourceWkbPtr, QPolygonF &targetPoints) const
Simplifies the specified WKB-point array.
double xMaximum() const
Get the x maximum value (right side of rectangle)
void combineExtentWith(const QgsRectangle &rect)
expand the rectangle so that covers both the original rectangle and the given rectangle ...
QgsMapToPixelSimplifier(int simplifyFlags, double tolerance, SimplifyAlgorithm simplifyAlgorithm=Distance)
Constructor.
QgsRectangle boundingBox() const
Returns the bounding box of this feature.
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.
double xMinimum() const
Get the x minimum value (left side of rectangle)
static Type flatType(Type type)
Returns the flat type for a WKB type.
double yMaximum() const
Get the y maximum value (top side of rectangle)
int mSimplifyFlags
Current simplification flags.
SimplifyAlgorithm mSimplifyAlgorithm
Current algorithm.
QgsWKBTypes::Type readHeader() const
The geometries can be simplified using the current map2pixel context state.
double height() const
Height of the rectangle.
static Type singleType(Type type)
Returns the single type for a WKB type.