//! Simplifies the OGR-geometry (Removing duplicated points) when is applied the specified map2pixel context bool QgsOgrMapToPixelSimplifier::simplifyOgrGeometry( OGRGeometry* geometry, bool isaLinearRing ) { OGRwkbGeometryType wkbGeometryType = wkbFlatten( geometry->getGeometryType() ); // Simplify the geometry rewriting temporally its WKB-stream for saving calloc's. if ( wkbGeometryType == wkbLineString ) { OGRLineString* lineString = ( OGRLineString* )geometry; int numPoints = lineString->getNumPoints(); if (( isaLinearRing && numPoints <= 5 ) || ( !isaLinearRing && numPoints <= 2 ) ) return false; OGREnvelope env; geometry->getEnvelope( &env ); QgsRectangle envelope( env.MinX, env.MinY, env.MaxX, env.MaxY ); // Can replace the geometry by its BBOX ? if (( mSimplifyFlags & QgsMapToPixelSimplifier::SimplifyEnvelope ) && canbeGeneralizedByMapBoundingBox( envelope ) ) { OGRRawPoint* points = NULL; int numPoints = 0; double x1 = envelope.xMinimum(); double y1 = envelope.yMinimum(); double x2 = envelope.xMaximum(); double y2 = envelope.yMaximum(); if ( isaLinearRing ) { numPoints = 5; points = mallocPoints( numPoints ); points[0].x = x1; points[0].y = y1; points[1].x = x2; points[1].y = y1; points[2].x = x2; points[2].y = y2; points[3].x = x1; points[3].y = y2; points[4].x = x1; points[4].y = y1; } else { numPoints = 2; points = mallocPoints( numPoints ); points[0].x = x1; points[0].y = y1; points[1].x = x2; points[1].y = y2; } lineString->setPoints( numPoints, points ); lineString->flattenTo2D(); return true; } else if ( mSimplifyFlags & QgsMapToPixelSimplifier::SimplifyGeometry ) { QGis::GeometryType geometryType = isaLinearRing ? QGis::Polygon : QGis::Line; int numSimplifiedPoints = 0; OGRRawPoint* points = mallocPoints( numPoints ); double* xptr = ( double* )points; double* yptr = xptr + 1; lineString->getPoints( points ); if ( simplifyOgrGeometry( geometryType, envelope, xptr, 16, yptr, 16, numPoints, numSimplifiedPoints ) ) { lineString->setPoints( numSimplifiedPoints, points ); lineString->flattenTo2D(); } return numSimplifiedPoints != numPoints; } } else if ( wkbGeometryType == wkbPolygon ) { OGRPolygon* polygon = ( OGRPolygon* )geometry; bool result = simplifyOgrGeometry( polygon->getExteriorRing(), true ); for ( int i = 0, numInteriorRings = polygon->getNumInteriorRings(); i < numInteriorRings; ++i ) { result |= simplifyOgrGeometry( polygon->getInteriorRing( i ), true ); } if ( result ) polygon->flattenTo2D(); return result; } else if ( wkbGeometryType == wkbMultiLineString || wkbGeometryType == wkbMultiPolygon ) { OGRGeometryCollection* collection = ( OGRGeometryCollection* )geometry; bool result = false; for ( int i = 0, numGeometries = collection->getNumGeometries(); i < numGeometries; ++i ) { result |= simplifyOgrGeometry( collection->getGeometryRef( i ), wkbGeometryType == wkbMultiPolygon ); } if ( result ) collection->flattenTo2D(); return result; } return false; }