Skip to content
Permalink
Browse files

#9360R: enable ogr simplification on provider side only cpp

  • Loading branch information
ahuarte47 committed Jan 19, 2014
1 parent a2b8efa commit 6c14b5034bd04881025e3817e125cb20b01e7aa8
@@ -109,31 +109,45 @@ bool QgsOgrFeatureIterator::prepareSimplification( const QgsSimplifyMethod& simp
if ( !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) && simplifyMethod.methodType() != QgsSimplifyMethod::NoSimplification && !simplifyMethod.forceLocalOptimization() )
{
QgsSimplifyMethod::MethodType methodType = simplifyMethod.methodType();
Q_UNUSED( methodType);

#if defined(HAVE_OGR_GEOMETRY_CLASS)
if ( methodType == QgsSimplifyMethod::OptimizeForRendering )
{
int simplifyFlags = QgsMapToPixelSimplifier::SimplifyGeometry | QgsMapToPixelSimplifier::SimplifyEnvelope;
mGeometrySimplifier = new QgsOgrMapToPixelSimplifier( simplifyFlags, simplifyMethod.tolerance() );
return true;
}
#endif
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1900
else if ( methodType == QgsSimplifyMethod::PreserveTopology )
if ( methodType == QgsSimplifyMethod::PreserveTopology )
{
mGeometrySimplifier = new QgsOgrTopologyPreservingSimplifier( simplifyMethod.tolerance() );
return true;
}
#endif
else
{
QgsDebugMsg( QString( "Simplification method type (%1) is not recognised by OgrFeatureIterator class" ).arg( methodType ) );
}

QgsDebugMsg( QString( "Simplification method type (%1) is not recognised by OgrFeatureIterator class" ).arg( methodType ) );
}
return QgsAbstractFeatureIterator::prepareSimplification( simplifyMethod );
}

bool QgsOgrFeatureIterator::providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const
{
return methodType == QgsSimplifyMethod::OptimizeForRendering || methodType == QgsSimplifyMethod::PreserveTopology;
#if defined(HAVE_OGR_GEOMETRY_CLASS)
if ( methodType == QgsSimplifyMethod::OptimizeForRendering )
{
return true;
}
#endif
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1900
if ( methodType == QgsSimplifyMethod::PreserveTopology )
{
return true;
}
#endif

return false;
}

bool QgsOgrFeatureIterator::fetchFeature( QgsFeature& feature )
@@ -18,26 +18,6 @@
#include "qgsogrprovider.h"
#include "qgsapplication.h"

/***************************************************************************/
// Use OgrGeometry class to speed up simplification if possible

#ifdef __cplusplus
#define USE_OGR_GEOMETRY_CLASS
#endif

#ifdef USE_OGR_GEOMETRY_CLASS
#include <ogr_geometry.h>
#else
class OGRRawPoint
{
public:
double x;
double y;
};
#endif

/***************************************************************************/

QgsOgrAbstractGeometrySimplifier::~QgsOgrAbstractGeometrySimplifier()
{
}
@@ -79,6 +59,11 @@ bool QgsOgrTopologyPreservingSimplifier::simplifyGeometry( OGRGeometryH geometry

/***************************************************************************/

#if defined(HAVE_OGR_GEOMETRY_CLASS)

// Use OgrGeometry class to speed up simplification on provider side
#include <ogr_geometry.h>

QgsOgrMapToPixelSimplifier::QgsOgrMapToPixelSimplifier( int simplifyFlags, double map2pixelTol )
: QgsMapToPixelSimplifier( simplifyFlags, map2pixelTol )
, mPointBufferPtr( NULL )
@@ -153,20 +138,21 @@ bool QgsOgrMapToPixelSimplifier::simplifyOgrGeometry( QGis::GeometryType geometr
}

//! Simplifies the OGR-geometry (Removing duplicated points) when is applied the specified map2pixel context
bool QgsOgrMapToPixelSimplifier::simplifyOgrGeometry( OGRGeometryH geometry, bool isaLinearRing )
bool QgsOgrMapToPixelSimplifier::simplifyOgrGeometry( OGRGeometry* geometry, bool isaLinearRing )
{
OGRwkbGeometryType wkbGeometryType = wkbFlatten( OGR_G_GetGeometryType( geometry ) );
OGRwkbGeometryType wkbGeometryType = wkbFlatten( geometry->getGeometryType() );

// Simplify the geometry rewriting temporally its WKB-stream for saving calloc's.
if ( wkbGeometryType == wkbLineString )
{
int numPoints = OGR_G_GetPointCount( geometry );
OGRLineString* lineString = ( OGRLineString* )geometry;

int numPoints = lineString->getNumPoints();
if (( isaLinearRing && numPoints <= 5 ) || ( !isaLinearRing && numPoints <= 4 ) )
return false;

OGREnvelope env;
OGR_G_GetEnvelope( geometry, &env );
lineString->getEnvelope( &env );
QgsRectangle envelope( env.MinX, env.MinY, env.MaxX, env.MaxY );

// Can replace the geometry by its BBOX ?
@@ -196,8 +182,8 @@ bool QgsOgrMapToPixelSimplifier::simplifyOgrGeometry( OGRGeometryH geometry, boo
points[0].x = x1; points[0].y = y1;
points[1].x = x2; points[1].y = y2;
}
setGeometryPoints( geometry, points, numPoints, isaLinearRing );
OGR_G_FlattenTo2D( geometry );
lineString->setPoints( numPoints, points );
lineString->flattenTo2D();

return true;
}
@@ -209,23 +195,24 @@ bool QgsOgrMapToPixelSimplifier::simplifyOgrGeometry( OGRGeometryH geometry, boo
OGRRawPoint* points = mallocPoints( numPoints );
double* xptr = ( double* )points;
double* yptr = xptr + 1;
OGR_G_GetPoints( geometry, xptr, 16, yptr, 16, NULL, 0 );
lineString->getPoints( points );

if ( simplifyOgrGeometry( geometryType, xptr, 16, yptr, 16, numPoints, numSimplifiedPoints ) )
{
setGeometryPoints( geometry, points, numSimplifiedPoints, isaLinearRing );
OGR_G_FlattenTo2D( geometry );
lineString->setPoints( numSimplifiedPoints, points );
lineString->flattenTo2D();
}
return numSimplifiedPoints != numPoints;
}
}
else if ( wkbGeometryType == wkbPolygon )
{
bool result = simplifyOgrGeometry( OGR_G_GetGeometryRef( geometry, 0 ), true );
OGRPolygon* polygon = ( OGRPolygon* )geometry;
bool result = simplifyOgrGeometry( polygon->getExteriorRing(), true );

for ( int i = 1, numInteriorRings = OGR_G_GetGeometryCount( geometry ); i < numInteriorRings; ++i )
for ( int i = 0, numInteriorRings = polygon->getNumInteriorRings(); i < numInteriorRings; ++i )
{
result |= simplifyOgrGeometry( OGR_G_GetGeometryRef( geometry, i ), true );
result |= simplifyOgrGeometry( polygon->getInteriorRing( i ), true );
}

if ( result )
@@ -235,11 +222,12 @@ bool QgsOgrMapToPixelSimplifier::simplifyOgrGeometry( OGRGeometryH geometry, boo
}
else if ( wkbGeometryType == wkbMultiLineString || wkbGeometryType == wkbMultiPolygon )
{
OGRGeometryCollection* collection = ( OGRGeometryCollection* )geometry;
bool result = false;

for ( int i = 0, numGeometries = OGR_G_GetGeometryCount( geometry ); i < numGeometries; ++i )
for ( int i = 0, numGeometries = collection->getNumGeometries(); i < numGeometries; ++i )
{
result |= simplifyOgrGeometry( OGR_G_GetGeometryRef( geometry, i ), wkbGeometryType == wkbMultiPolygon );
result |= simplifyOgrGeometry( collection->getGeometryRef( i ), wkbGeometryType == wkbMultiPolygon );
}

if ( result )
@@ -251,27 +239,6 @@ bool QgsOgrMapToPixelSimplifier::simplifyOgrGeometry( OGRGeometryH geometry, boo
return false;
}

//! Load a point array to the specified LineString geometry
void QgsOgrMapToPixelSimplifier::setGeometryPoints( OGRGeometryH geometry, OGRRawPoint* points, int numPoints, bool isaLinearRing )
{
#ifdef USE_OGR_GEOMETRY_CLASS
OGRLineString* lineString = ( OGRLineString* )geometry;
lineString->setPoints( numPoints, points );
#else
OGRGeometryH g = OGR_G_CreateGeometry( isaLinearRing ? wkbLinearRing : wkbLineString );

for (int i = 0; i < numPoints; i++, points++)
OGR_G_SetPoint( g, i, points->x, points->y, 0);

size_t wkbSize = OGR_G_WkbSize( g );
unsigned char *wkb = new unsigned char[ wkbSize ];
OGR_G_ExportToWkb( g, ( OGRwkbByteOrder ) QgsApplication::endian(), wkb );
OGR_G_ImportFromWkb( geometry, wkb, wkbSize );
delete [] wkb;
OGR_G_DestroyGeometry( g );
#endif
}

//////////////////////////////////////////////////////////////////////////////////////////////

//! Simplifies the specified geometry
@@ -281,8 +248,10 @@ bool QgsOgrMapToPixelSimplifier::simplifyGeometry( OGRGeometryH geometry )

if ( wkbGeometryType == wkbLineString || wkbGeometryType == wkbPolygon )
{
return simplifyOgrGeometry( geometry, wkbGeometryType == wkbPolygon );
return simplifyOgrGeometry( (OGRGeometry*) geometry, wkbGeometryType == wkbPolygon );
}

return false;
}

#endif
@@ -20,7 +20,12 @@
#include "qgsmaptopixelgeometrysimplifier.h"
#include <ogr_api.h>

class OGRRawPoint;
// Enable OGR-simplification on provider side when OGRGeometry class is available
#if defined(__cplusplus)
#define HAVE_OGR_GEOMETRY_CLASS 1
class OGRGeometry;
class OGRRawPoint;
#endif

/**
* Abstract base class for simplify OGR-geometries using a specific algorithm
@@ -52,6 +57,7 @@ class QgsOgrTopologyPreservingSimplifier : public QgsOgrAbstractGeometrySimplifi
};
#endif

#if defined(HAVE_OGR_GEOMETRY_CLASS)
/**
* OGR implementation of GeometrySimplifier using the "MapToPixel" algorithm
*
@@ -73,17 +79,15 @@ class QgsOgrMapToPixelSimplifier : public QgsOgrAbstractGeometrySimplifier, QgsM
//! Simplifies the OGR-geometry (Removing duplicated points) when is applied the specified map2pixel context
bool simplifyOgrGeometry( QGis::GeometryType geometryType, double* xptr, int xStride, double* yptr, int yStride, int pointCount, int& pointSimplifiedCount );
//! Simplifies the OGR-geometry (Removing duplicated points) when is applied the specified map2pixel context
bool simplifyOgrGeometry( OGRGeometryH geometry, bool isaLinearRing );
bool simplifyOgrGeometry( OGRGeometry* geometry, bool isaLinearRing );

//! Returns a point buffer of the specified size
OGRRawPoint* mallocPoints( int numPoints );

//! Load a point array to the specified LineString geometry
static void setGeometryPoints( OGRGeometryH geometry, OGRRawPoint* points, int numPoints, bool isaLinearRing );

public:
//! Simplifies the specified geometry
virtual bool simplifyGeometry( OGRGeometryH geometry );
};
#endif

#endif // QGSOGRGEOMETRYSIMPLIFIER_H
@@ -45,6 +45,7 @@ email : sherman at mrcc.com
#include "qgsgeometry.h"
#include "qgscoordinatereferencesystem.h"
#include "qgsvectorlayerimport.h"
#include "qgsogrgeometrysimplifier.h"

static const QString TEXT_PROVIDER_KEY = "ogr";
static const QString TEXT_PROVIDER_DESCRIPTION =
@@ -1495,7 +1496,12 @@ int QgsOgrProvider::capabilities() const
}

// supports geometry simplification on provider side
ability |= ( QgsVectorDataProvider::SimplifyGeometries | QgsVectorDataProvider::SimplifyGeometriesWithTopologicalValidation );
#if defined(HAVE_OGR_GEOMETRY_CLASS)
ability |= QgsVectorDataProvider::SimplifyGeometries;
#endif
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1900
ability |= QgsVectorDataProvider::SimplifyGeometriesWithTopologicalValidation;
#endif
}

return ability;

0 comments on commit 6c14b50

Please sign in to comment.
You can’t perform that action at this time.