22 : mSimplifyFlags( simplifyFlags )
23 , mTolerance( tolerance )
36 float vx = ( float )( x2 - x1 );
37 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;
58 if ( xmin > x ) xmin = x;
59 if ( ymin > y ) ymin = y;
60 if ( xmax < x ) xmax = x;
61 if ( ymax < y ) ymax = y;
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 ) );
79 if ( writeHeader ) minimumSize += 5;
80 if ( sourceWkbSize <= minimumSize )
95 memcpy( targetWkb, &byteOrder, 1 );
98 memcpy( targetWkb, &geometryType, 4 );
104 memcpy( targetWkb, &numRings, 4 );
113 memcpy( targetWkb, &numPoints, 4 );
116 memcpy( targetWkb, &x1,
sizeof(
double ) ); targetWkb +=
sizeof( double );
117 memcpy( targetWkb, &y1,
sizeof(
double ) ); targetWkb +=
sizeof( double );
118 memcpy( targetWkb, &x2,
sizeof(
double ) ); targetWkb +=
sizeof( double );
119 memcpy( targetWkb, &y2,
sizeof(
double ) ); targetWkb +=
sizeof( double );
124 memcpy( targetWkb, &numPoints, 4 );
127 memcpy( targetWkb, &x1,
sizeof(
double ) ); targetWkb +=
sizeof( double );
128 memcpy( targetWkb, &y1,
sizeof(
double ) ); targetWkb +=
sizeof( double );
129 memcpy( targetWkb, &x2,
sizeof(
double ) ); targetWkb +=
sizeof( double );
130 memcpy( targetWkb, &y1,
sizeof(
double ) ); targetWkb +=
sizeof( double );
131 memcpy( targetWkb, &x2,
sizeof(
double ) ); targetWkb +=
sizeof( double );
132 memcpy( targetWkb, &y2,
sizeof(
double ) ); targetWkb +=
sizeof( double );
133 memcpy( targetWkb, &x1,
sizeof(
double ) ); targetWkb +=
sizeof( double );
134 memcpy( targetWkb, &y2,
sizeof(
double ) ); targetWkb +=
sizeof( double );
135 memcpy( targetWkb, &x1,
sizeof(
double ) ); targetWkb +=
sizeof( double );
136 memcpy( targetWkb, &y1,
sizeof(
double ) ); targetWkb +=
sizeof( double );
138 targetWkbSize += targetWkb - wkb2;
146 bool canbeGeneralizable =
true;
151 unsigned char* sourcePrevWkb = sourceWkb;
152 unsigned char* targetPrevWkb = targetWkb;
153 size_t targetWkbPrevSize = targetWkbSize;
158 canbeGeneralizable =
generalizeWkbGeometry( wkbType, sourceWkb, sourceWkbSize, targetWkb, targetWkbSize, envelope, writeHeader );
159 if ( canbeGeneralizable )
return true;
166 targetWkb[0] = sourceWkb[0];
171 memcpy( &geometryType, sourceWkb, 4 );
173 memcpy( targetWkb, &flatType, 4 );
180 unsigned char* wkb1 = sourceWkb;
181 unsigned char* wkb2 = targetWkb;
187 double x, y, lastX = 0, lastY = 0;
194 int sizeOfDoubleX =
sizeof( double );
195 int sizeOfDoubleY =
QGis::wkbDimensions( wkbType ) == 3 ? 2 *
sizeof( double ) :
sizeof(
double );
198 memcpy( &numPoints, sourceWkb, 4 );
200 if ( numPoints <= ( isaLinearRing ? 5 : 2 ) ) canbeGeneralizable =
false;
202 int numTargetPoints = 0;
203 memcpy( targetWkb, &numTargetPoints, 4 );
207 double* ptr = (
double* )targetWkb;
208 map2pixelTol *= map2pixelTol;
213 double x1, y1, x2, y2;
215 unsigned char* startWkbX = sourceWkb;
216 unsigned char* startWkbY = startWkbX + sizeOfDoubleX;
217 unsigned char* finalWkbX = sourceWkb + ( numPoints - 1 ) * ( sizeOfDoubleX + sizeOfDoubleY );
218 unsigned char* finalWkbY = finalWkbX + sizeOfDoubleX;
220 memcpy( &x1, startWkbX,
sizeof(
double ) );
221 memcpy( &y1, startWkbY,
sizeof(
double ) );
222 memcpy( &x2, finalWkbX,
sizeof(
double ) );
223 memcpy( &y2, finalWkbY,
sizeof(
double ) );
225 isaLinearRing = ( x1 == x2 ) && ( y1 == y2 );
229 for (
int i = 0, numPoints_i = ( isaLinearRing ? numPoints - 1 : numPoints ); i < numPoints_i; ++i )
231 memcpy( &x, sourceWkb,
sizeof(
double ) ); sourceWkb += sizeOfDoubleX;
232 memcpy( &y, sourceWkb,
sizeof(
double ) ); sourceWkb += sizeOfDoubleY;
236 memcpy( ptr, &x,
sizeof(
double ) ); lastX = x; ptr++;
237 memcpy( ptr, &y,
sizeof(
double ) ); lastY = y; ptr++;
240 if ( xmin > x ) xmin = x;
241 if ( ymin > y ) ymin = y;
242 if ( xmax < x ) xmax = x;
243 if ( ymax < y ) ymax = y;
245 targetWkb = wkb2 + 4;
248 if ( numTargetPoints <= ( isaLinearRing ? 2 : 1 ) )
250 unsigned char* targetTempWkb = targetWkb;
251 int targetWkbTempSize = targetWkbSize;
253 sourceWkb = sourcePrevWkb;
254 targetWkb = targetPrevWkb;
255 targetWkbSize = targetWkbPrevSize;
257 if ( isok )
return true;
259 targetWkb = targetTempWkb;
260 targetWkbSize = targetWkbTempSize;
264 memcpy( &x, targetWkb + 0,
sizeof(
double ) );
265 memcpy( &y, targetWkb + 8,
sizeof(
double ) );
266 memcpy( ptr, &x,
sizeof(
double ) ); ptr++;
267 memcpy( ptr, &y,
sizeof(
double ) ); ptr++;
270 targetWkbSize += numTargetPoints * 16;
273 memcpy( targetWkb, &numTargetPoints, 4 );
274 result = numPoints != numTargetPoints;
280 memcpy( &numRings, sourceWkb, 4 );
283 memcpy( targetWkb, &numRings, 4 );
287 for (
int i = 0; i < numRings; ++i )
290 memcpy( &numPoints_i, sourceWkb, 4 );
293 size_t sourceWkbSize_i = 4 + numPoints_i * ( hasZValue ? 3 : 2 ) *
sizeof(
double );
294 size_t targetWkbSize_i = 0;
296 result |=
simplifyWkbGeometry( simplifyFlags, wkbType, sourceWkb, sourceWkbSize_i, targetWkb, targetWkbSize_i, envelope_i, map2pixelTol,
false,
true );
297 sourceWkb += sourceWkbSize_i;
298 targetWkb += targetWkbSize_i;
300 targetWkbSize += targetWkbSize_i;
307 memcpy( &numGeoms, sourceWkb, 4 );
311 memcpy( targetWkb, &numGeoms, 4 );
315 for (
int i = 0; i < numGeoms; ++i )
317 size_t sourceWkbSize_i = 0;
318 size_t targetWkbSize_i = 0;
324 memcpy( &numPoints_i, wkb1 + 5, 4 );
325 int wkbSize_i = 4 + numPoints_i * ( hasZValue ? 3 : 2 ) *
sizeof(
double );
327 sourceWkbSize_i += 5 + wkbSize_i;
328 wkb1 += 5 + wkbSize_i;
333 memcpy( &numPrings_i, wkb1 + 5, 4 );
337 for (
int j = 0; j < numPrings_i; ++j )
340 memcpy( &numPoints_i, wkb1, 4 );
341 int wkbSize_i = 4 + numPoints_i * ( hasZValue ? 3 : 2 ) *
sizeof(
double );
343 sourceWkbSize_i += wkbSize_i;
348 sourceWkb += sourceWkbSize_i;
349 targetWkb += targetWkbSize_i;
351 targetWkbSize += targetWkbSize_i;
375 size_t wkbSize = geometry->
wkbSize();
376 unsigned char* wkb = (
unsigned char* )malloc( wkbSize );
377 memcpy( wkb, geometry->
asWkb(), wkbSize );
387 size_t targetWkbSize = 0;
396 unsigned char* wkb = (
unsigned char* )geometry->
asWkb( );
397 size_t wkbSize = geometry->
wkbSize( );
400 if (
simplifyWkbGeometry( simplifyFlags, wkbType, wkb, wkbSize, wkb, targetWkbSize, envelope, tolerance ) )
402 unsigned char* targetWkb =
new unsigned char[targetWkbSize];
403 memcpy( targetWkb, wkb, targetWkbSize );
404 geometry->
fromWkb( targetWkb, targetWkbSize );
static WkbType singleType(WkbType type)
A rectangle specified with double values.
virtual ~QgsMapToPixelSimplifier()
size_t wkbSize() const
Returns the size of the WKB in asWkb().
double yMaximum() const
Get the y maximum value (top side of rectangle)
static bool generalizeWkbGeometry(QGis::WkbType wkbType, 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.
QGis::GeometryType type()
Returns type of the vector.
static QgsRectangle calculateBoundingBox(QGis::WkbType wkbType, unsigned char *wkb, size_t numPoints)
Returns the BBOX of the specified WKB-point stream.
WkbType
Used for symbology operations.
static endian_t endian()
Returns whether this machine uses big or little endian.
double ANALYSIS_EXPORT max(double x, double y)
returns the maximum of two doubles or the first argument if both are equal
static WkbType flatType(WkbType type)
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.
static bool canbeGeneralizedByMapBoundingBox(const QgsRectangle &envelope, double map2pixelTol)
Returns whether the envelope can be replaced by its BBOX when is applied the specified map2pixel cont...
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 wkb (point / linestring / polygon etc.)
double mTolerance
Distance tolerance for the simplification.
virtual QgsGeometry * simplify(QgsGeometry *geometry) const
Returns a simplified version the specified geometry.
QgsRectangle boundingBox()
Returns the bounding box of this feature.
static int wkbDimensions(WkbType type)
virtual bool simplifyGeometry(QgsGeometry *geometry) const
Simplifies the specified geometry.
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...
static bool simplifyWkbGeometry(int simplifyFlags, QGis::WkbType wkbType, unsigned char *sourceWkb, size_t sourceWkbSize, unsigned char *targetWkb, size_t &targetWkbSize, const QgsRectangle &envelope, double map2pixelTol, bool writeHeader=true, bool isaLinearRing=false)
Simplify the WKB-geometry using the specified tolerance.
int mSimplifyFlags
Current simplification flags.
The geometries can be simplified using the current map2pixel context state.
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)