Skip to content
Permalink
Browse files

#8725-R: simplifier execute in rendering loop

  • Loading branch information
ahuarte47 authored and m-kuhn committed Jan 15, 2014
1 parent 319acc2 commit 08b5e3058a1d413c844004b8291ad4eb9767e767
@@ -23,9 +23,6 @@ QgsFeatureRequest::QgsFeatureRequest()
: mFilter( FilterNone )
, mFilterExpression( 0 )
, mFlags( 0 )
, mMapCoordTransform( NULL )
, mMapToPixel( NULL )
, mMapToPixelTol( QGis::DEFAULT_MAPTOPIXEL_THRESHOLD )
{
}

@@ -34,9 +31,6 @@ QgsFeatureRequest::QgsFeatureRequest( QgsFeatureId fid )
, mFilterFid( fid )
, mFilterExpression( 0 )
, mFlags( 0 )
, mMapCoordTransform( NULL )
, mMapToPixel( NULL )
, mMapToPixelTol( QGis::DEFAULT_MAPTOPIXEL_THRESHOLD )
{
}

@@ -45,19 +39,13 @@ QgsFeatureRequest::QgsFeatureRequest( const QgsRectangle& rect )
, mFilterRect( rect )
, mFilterExpression( 0 )
, mFlags( 0 )
, mMapCoordTransform( NULL )
, mMapToPixel( NULL )
, mMapToPixelTol( QGis::DEFAULT_MAPTOPIXEL_THRESHOLD )
{
}

QgsFeatureRequest::QgsFeatureRequest( const QgsExpression& expr )
: mFilter( FilterExpression )
, mFilterExpression( new QgsExpression( expr.expression() ) )
, mFlags( 0 )
, mMapCoordTransform( NULL )
, mMapToPixel( NULL )
, mMapToPixelTol( QGis::DEFAULT_MAPTOPIXEL_THRESHOLD )
{
}

@@ -82,9 +70,6 @@ QgsFeatureRequest& QgsFeatureRequest::operator=( const QgsFeatureRequest & rh )
mFilterExpression = 0;
}
mAttrs = rh.mAttrs;
mMapCoordTransform = rh.mMapCoordTransform;
mMapToPixel = rh.mMapToPixel;
mMapToPixelTol = rh.mMapToPixelTol;
return *this;
}

@@ -189,21 +174,3 @@ bool QgsFeatureRequest::acceptFeature( const QgsFeature& feature )

return true;
}

QgsFeatureRequest& QgsFeatureRequest::setCoordinateTransform( const QgsCoordinateTransform* ct )
{
mMapCoordTransform = ct;
return *this;
}

QgsFeatureRequest& QgsFeatureRequest::setMapToPixel( const QgsMapToPixel* mtp )
{
mMapToPixel = mtp;
return *this;
}

QgsFeatureRequest& QgsFeatureRequest::setMapToPixelTol( float map2pixelTol )
{
mMapToPixelTol = map2pixelTol;
return *this;
}
@@ -21,9 +21,6 @@
#include "qgsrectangle.h"
#include "qgsexpression.h"

#include "qgscoordinatetransform.h"
#include "qgsmaptopixel.h"

#include <QList>
typedef QList<int> QgsAttributeList;

@@ -64,9 +61,7 @@ class CORE_EXPORT QgsFeatureRequest
NoFlags = 0,
NoGeometry = 1, //!< Geometry is not required. It may still be returned if e.g. required for a filter condition.
SubsetOfAttributes = 2, //!< Fetch only a subset of attributes (setSubsetOfAttributes sets this flag)
ExactIntersect = 4, //!< Use exact geometry intersection (slower) instead of bounding boxes
SimplifyGeometry = 8, //!< The geometries can be simplified using the current map2pixel context state (e.g. for fast rendering...)
SimplifyEnvelope = 16 //!< The geometries can be fully simplified by its BoundingBox (e.g. for fast rendering...)
ExactIntersect = 4 //!< Use exact geometry intersection (slower) instead of bounding boxes
};
Q_DECLARE_FLAGS( Flags, Flag )

@@ -140,15 +135,6 @@ class CORE_EXPORT QgsFeatureRequest
// void setFilterNativeExpression(con QString& expr); // using provider's SQL (if supported)
// void setLimit(int limit);

const QgsCoordinateTransform* coordinateTransform() const { return mMapCoordTransform; }
QgsFeatureRequest& setCoordinateTransform( const QgsCoordinateTransform* ct );

const QgsMapToPixel* mapToPixel() const { return mMapToPixel; }
QgsFeatureRequest& setMapToPixel( const QgsMapToPixel* mtp );

float mapToPixelTol() const { return mMapToPixelTol; }
QgsFeatureRequest& setMapToPixelTol( float map2pixelTol );

protected:
FilterType mFilter;
QgsRectangle mFilterRect;
@@ -157,13 +143,6 @@ class CORE_EXPORT QgsFeatureRequest
QgsExpression* mFilterExpression;
Flags mFlags;
QgsAttributeList mAttrs;

//! For transformation between coordinate systems from current layer to map target. Can be 0 if on-the-fly reprojection is not used
const QgsCoordinateTransform* mMapCoordTransform;
//! For transformation between map coordinates and device coordinates
const QgsMapToPixel* mMapToPixel;
//! Factor tolterance to apply in transformation between map coordinates and device coordinates
float mMapToPixelTol;
};

Q_DECLARE_OPERATORS_FOR_FLAGS( QgsFeatureRequest::Flags )
@@ -60,13 +60,13 @@ QgsTopologyPreservingSimplifier::~QgsTopologyPreservingSimplifier()
}

//! Returns a simplified version the specified geometry
QgsGeometry* QgsTopologyPreservingSimplifier::simplify( QgsGeometry* geometry )
QgsGeometry* QgsTopologyPreservingSimplifier::simplify( QgsGeometry* geometry ) const
{
return geometry->simplify( mTolerance );
}

//! Simplifies the specified geometry
bool QgsTopologyPreservingSimplifier::simplifyGeometry( QgsGeometry* geometry )
bool QgsTopologyPreservingSimplifier::simplifyGeometry( QgsGeometry* geometry ) const
{
QgsGeometry* g = geometry->simplify( mTolerance );

@@ -28,9 +28,9 @@ class CORE_EXPORT QgsAbstractGeometrySimplifier
virtual ~QgsAbstractGeometrySimplifier();

//! Returns a simplified version the specified geometry
virtual QgsGeometry* simplify( QgsGeometry* geometry ) = 0;
virtual QgsGeometry* simplify( QgsGeometry* geometry ) const = 0;
//! Simplifies the specified geometry
virtual bool simplifyGeometry( QgsGeometry* geometry ) = 0;
virtual bool simplifyGeometry( QgsGeometry* geometry ) const = 0;

// MapToPixel simplification helper methods
public:
@@ -59,9 +59,9 @@ class CORE_EXPORT QgsTopologyPreservingSimplifier : public QgsAbstractGeometrySi

public:
//! Returns a simplified version the specified geometry
virtual QgsGeometry* simplify( QgsGeometry* geometry );
virtual QgsGeometry* simplify( QgsGeometry* geometry ) const;
//! Simplifies the specified geometry
virtual bool simplifyGeometry( QgsGeometry* geometry );
virtual bool simplifyGeometry( QgsGeometry* geometry ) const;
};

#endif // QGSGEOMETRYSIMPLIFIER_H
@@ -352,7 +352,7 @@ bool QgsMapToPixelSimplifier::canbeGeneralizedByMapBoundingBox( const QgsRectang
}

//! Returns a simplified version the specified geometry (Removing duplicated points) when is applied the specified map2pixel context
QgsGeometry* QgsMapToPixelSimplifier::simplify( QgsGeometry* geometry )
QgsGeometry* QgsMapToPixelSimplifier::simplify( QgsGeometry* geometry ) const
{
QgsGeometry* g = new QgsGeometry();

@@ -393,7 +393,7 @@ bool QgsMapToPixelSimplifier::simplifyGeometry( QgsGeometry* geometry, int simpl
}

//! Simplifies the geometry (Removing duplicated points) when is applied the specified map2pixel context
bool QgsMapToPixelSimplifier::simplifyGeometry( QgsGeometry* geometry )
bool QgsMapToPixelSimplifier::simplifyGeometry( QgsGeometry* geometry ) const
{
return simplifyGeometry( geometry, mSimplifyFlags, mMapCoordTransform, mMapToPixel, mMapToPixelTol );
}
@@ -77,9 +77,9 @@ class CORE_EXPORT QgsMapToPixelSimplifier : public QgsAbstractGeometrySimplifier
void setMapToPixelTol( float map2pixelTol ) { mMapToPixelTol = map2pixelTol; }

//! Returns a simplified version the specified geometry
virtual QgsGeometry* simplify( QgsGeometry* geometry );
virtual QgsGeometry* simplify( QgsGeometry* geometry ) const;
//! Simplifies the specified geometry
virtual bool simplifyGeometry( QgsGeometry* geometry );
virtual bool simplifyGeometry( QgsGeometry* geometry ) const;

// MapToPixel simplification helper methods
public:
@@ -194,12 +194,6 @@ QString QgsVectorDataProvider::capabilitiesString() const
QgsDebugMsg( "Capability: Change Geometries" );
}

if ( abilities & QgsVectorDataProvider::SimplifyGeometries )
{
abilitiesList += tr( "Simplify Geometries" );
QgsDebugMsg( "Capability: Simplify Geometries before fetch the feature" );
}

return abilitiesList.join( ", " );

}
@@ -86,8 +86,6 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
CreateAttributeIndex = 1 << 12,
/** allows user to select encoding */
SelectEncoding = 1 << 13,
/** supports simplification of geometries before fetch the feature */
SimplifyGeometries = 1 << 14,
};

/** bitmask of all provider's editing capabilities */
@@ -400,7 +400,7 @@ void QgsVectorLayer::drawLabels( QgsRenderContext& rendererContext )



void QgsVectorLayer::drawRendererV2( QgsFeatureIterator &fit, QgsRenderContext& rendererContext, bool labeling )
void QgsVectorLayer::drawRendererV2( QgsFeatureIterator &fit, QgsRenderContext& rendererContext, bool labeling, const QgsAbstractGeometrySimplifier* geometrySimplifier )
{
if ( !hasGeometryType() )
return;
@@ -451,6 +451,13 @@ void QgsVectorLayer::drawRendererV2( QgsFeatureIterator &fit, QgsRenderContext&
bool sel = mSelectedFeatureIds.contains( fet.id() );
bool drawMarker = ( mEditBuffer && ( !vertexMarkerOnlyForSelection || sel ) );

// simplify the geometry using the current map2pixel context
if ( geometrySimplifier )
{
fet = QgsFeature( fet );
geometrySimplifier->simplifyGeometry( fet.geometry() );
}

// render feature
bool rendered = mRendererV2->renderFeature( fet, rendererContext, -1, sel, drawMarker );

@@ -493,7 +500,7 @@ void QgsVectorLayer::drawRendererV2( QgsFeatureIterator &fit, QgsRenderContext&
#endif
}

void QgsVectorLayer::drawRendererV2Levels( QgsFeatureIterator &fit, QgsRenderContext& rendererContext, bool labeling )
void QgsVectorLayer::drawRendererV2Levels( QgsFeatureIterator &fit, QgsRenderContext& rendererContext, bool labeling, const QgsAbstractGeometrySimplifier* geometrySimplifier )
{
if ( !hasGeometryType() )
return;
@@ -539,6 +546,13 @@ void QgsVectorLayer::drawRendererV2Levels( QgsFeatureIterator &fit, QgsRenderCon
continue;
}

// simplify the geometry using the current map2pixel context
if ( geometrySimplifier )
{
fet = QgsFeature( fet );
geometrySimplifier->simplifyGeometry( fet.geometry() );
}

if ( !features.contains( sym ) )
{
features.insert( sym, QList<QgsFeature>() );
@@ -698,14 +712,14 @@ bool QgsVectorLayer::draw( QgsRenderContext& rendererContext )
//do startRender before getFeatures to give renderers the possibility of querying features in the startRender method
mRendererV2->startRender( rendererContext, this );

QgsFeatureRequest& featureRequest = QgsFeatureRequest()
.setFilterRect( rendererContext.extent() )
.setSubsetOfAttributes( attributes );
QgsFeatureIterator fit = getFeatures( QgsFeatureRequest()
.setFilterRect( rendererContext.extent() )
.setSubsetOfAttributes( attributes ) );

QgsFeatureIterator fit = QgsFeatureIterator();
QgsAbstractGeometrySimplifier* geometrySimplifier = NULL;

// Enable the simplification of the geometries (Using the current map2pixel context) before fetch the features.
if ( simplifyDrawingCanbeApplied( QgsVectorLayer::GeometrySimplification | QgsVectorLayer::EnvelopeSimplification ) && !( featureRequest.flags() & QgsFeatureRequest::NoGeometry ) )
// enable the simplification of the geometries (Using the current map2pixel context) before send it to renderer engine.
if ( simplifyDrawingCanbeApplied( QgsVectorLayer::GeometrySimplification | QgsVectorLayer::EnvelopeSimplification ) )
{
QPainter* p = rendererContext.painter();
float dpi = ( p->device()->logicalDpiX() + p->device()->logicalDpiY() ) / 2;
@@ -715,29 +729,21 @@ bool QgsVectorLayer::draw( QgsRenderContext& rendererContext )
if ( mSimplifyDrawingHints & QgsVectorLayer::GeometrySimplification ) simplifyFlags |= QgsMapToPixelSimplifier::SimplifyGeometry;
if ( mSimplifyDrawingHints & QgsVectorLayer::EnvelopeSimplification ) simplifyFlags |= QgsMapToPixelSimplifier::SimplifyEnvelope;

QgsFeatureRequest::Flags requestFlags = QgsFeatureRequest::NoFlags;
if ( mSimplifyDrawingHints & QgsVectorLayer::GeometrySimplification ) requestFlags |= QgsFeatureRequest::SimplifyGeometry;
if ( mSimplifyDrawingHints & QgsVectorLayer::EnvelopeSimplification ) requestFlags |= QgsFeatureRequest::SimplifyEnvelope;

featureRequest.setFlags( featureRequest.flags() | requestFlags );
featureRequest.setCoordinateTransform( rendererContext.coordinateTransform() );
featureRequest.setMapToPixel( &rendererContext.mapToPixel() );
featureRequest.setMapToPixelTol( map2pixelTol );

QgsMapToPixelSimplifier* simplifier =
geometrySimplifier =
new QgsMapToPixelSimplifier( simplifyFlags, rendererContext.coordinateTransform(), &rendererContext.mapToPixel(), map2pixelTol );

fit = QgsFeatureIterator( new QgsSimplifiedVectorLayerFeatureIterator( this, featureRequest, simplifier ) );
}
else
{
fit = getFeatures( featureRequest );
}

if (( mRendererV2->capabilities() & QgsFeatureRendererV2::SymbolLevels ) && mRendererV2->usingSymbolLevels() )
drawRendererV2Levels( fit, rendererContext, labeling );
drawRendererV2Levels( fit, rendererContext, labeling, geometrySimplifier );
else
drawRendererV2( fit, rendererContext, labeling );
drawRendererV2( fit, rendererContext, labeling, geometrySimplifier );

// release the optional geometry simplifier
if ( geometrySimplifier )
{
delete geometrySimplifier;
geometrySimplifier = NULL;
}

return true;
}
@@ -57,6 +57,7 @@ class QgsDiagramLayerSettings;
class QgsGeometryCache;
class QgsVectorLayerEditBuffer;
class QgsSymbolV2;
class QgsAbstractGeometrySimplifier;

typedef QList<int> QgsAttributeList;
typedef QSet<int> QgsAttributeIds;
@@ -729,12 +730,12 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
/** Draw layer with renderer V2. QgsFeatureRenderer::startRender() needs to be called before using this method
* @note added in 1.4
*/
void drawRendererV2( QgsFeatureIterator &fit, QgsRenderContext& rendererContext, bool labeling );
void drawRendererV2( QgsFeatureIterator &fit, QgsRenderContext& rendererContext, bool labeling, const QgsAbstractGeometrySimplifier* geometrySimplifier = NULL );

/** Draw layer with renderer V2 using symbol levels. QgsFeatureRenderer::startRender() needs to be called before using this method
* @note added in 1.4
*/
void drawRendererV2Levels( QgsFeatureIterator &fit, QgsRenderContext& rendererContext, bool labeling );
void drawRendererV2Levels( QgsFeatureIterator &fit, QgsRenderContext& rendererContext, bool labeling, const QgsAbstractGeometrySimplifier* geometrySimplifier = NULL );

/** Returns point, line or polygon */
QGis::GeometryType geometryType() const;
@@ -589,47 +589,3 @@ void QgsVectorLayerFeatureIterator::updateFeatureGeometry( QgsFeature &f )
if ( mChangedGeometries.contains( f.id() ) )
f.setGeometry( mChangedGeometries[f.id()] );
}

/***************************************************************************
QgsSimplifiedVectorLayerFeatureIterator class
----------------------
begin : December 2013
copyright : (C) 2013 by Alvaro Huarte
email : http://wiki.osgeo.org/wiki/Alvaro_Huarte
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

QgsSimplifiedVectorLayerFeatureIterator::QgsSimplifiedVectorLayerFeatureIterator( QgsVectorLayer* layer, const QgsFeatureRequest& request, QgsAbstractGeometrySimplifier* simplifier )
: QgsVectorLayerFeatureIterator( layer, request )
, mSimplifier( simplifier )
{
mSupportsPresimplify = layer->dataProvider()->capabilities() & QgsVectorDataProvider::SimplifyGeometries;
}

QgsSimplifiedVectorLayerFeatureIterator::~QgsSimplifiedVectorLayerFeatureIterator()
{
if ( mSimplifier )
{
delete mSimplifier;
mSimplifier = NULL;
}
}

//! fetch next feature, return true on success
bool QgsSimplifiedVectorLayerFeatureIterator::fetchFeature( QgsFeature& feature )
{
if ( QgsVectorLayerFeatureIterator::fetchFeature( feature ) )
{
const QgsMapToPixel* mtp = mRequest.mapToPixel();
if ( mtp && !mSupportsPresimplify && mSimplifier ) mSimplifier->simplifyGeometry( feature.geometry() );
return true;
}
return false;
}

0 comments on commit 08b5e30

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