mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
Merge branch 'master' of github.com:qgis/Quantum-GIS
This commit is contained in:
commit
fd7e03d7b3
@ -77,6 +77,17 @@ public:
|
||||
|
||||
virtual QString dump();
|
||||
|
||||
enum Capabilities
|
||||
{
|
||||
SymbolLevels = 1, // rendering with symbol levels (i.e. implements symbols(), symbolForFeature())
|
||||
RotationField = 2, // rotate symbols by attribute value
|
||||
MoreSymbolsPerFeature = 4 // may use more than one symbol to render a feature: symbolsForFeature() will return them
|
||||
};
|
||||
|
||||
//! returns bitwise OR-ed capabilities of the renderer
|
||||
//! \note added in 2.0
|
||||
virtual int capabilities();
|
||||
|
||||
virtual QgsFeatureRendererV2* clone()=0 /Factory/;
|
||||
|
||||
virtual QgsSymbolV2List symbols()=0;
|
||||
@ -105,6 +116,18 @@ public:
|
||||
//! @note added in 1.9
|
||||
virtual void setRotationField( QString fieldName );
|
||||
|
||||
//! return whether the renderer will render a feature or not.
|
||||
//! Must be called between startRender() and stopRender() calls.
|
||||
//! Default implementation uses symbolForFeature().
|
||||
//! @note added in 1.9
|
||||
virtual bool willRenderFeature( QgsFeature& feat );
|
||||
|
||||
//! return list of symbols used for rendering the feature.
|
||||
//! For renderers that do not support MoreSymbolsPerFeature it is more efficient
|
||||
//! to use symbolForFeature()
|
||||
//! @note added in 1.9
|
||||
virtual QgsSymbolV2List symbolsForFeature( QgsFeature& feat );
|
||||
|
||||
protected:
|
||||
QgsFeatureRendererV2(QString type);
|
||||
|
||||
@ -154,6 +177,10 @@ public:
|
||||
|
||||
virtual QString dump();
|
||||
|
||||
//! returns bitwise OR-ed capabilities of the renderer
|
||||
//! \note added in 2.0
|
||||
virtual int capabilities();
|
||||
|
||||
virtual QgsFeatureRendererV2* clone() /Factory/;
|
||||
|
||||
virtual QgsSymbolV2List symbols();
|
||||
@ -221,6 +248,10 @@ public:
|
||||
|
||||
virtual QString dump();
|
||||
|
||||
//! returns bitwise OR-ed capabilities of the renderer
|
||||
//! \note added in 2.0
|
||||
virtual int capabilities();
|
||||
|
||||
virtual QgsFeatureRendererV2* clone() /Factory/;
|
||||
|
||||
virtual QgsSymbolV2List symbols();
|
||||
@ -320,6 +351,10 @@ public:
|
||||
|
||||
virtual QString dump();
|
||||
|
||||
//! returns bitwise OR-ed capabilities of the renderer
|
||||
//! \note added in 2.0
|
||||
virtual int capabilities();
|
||||
|
||||
virtual QgsFeatureRendererV2* clone() /Factory/;
|
||||
|
||||
virtual QgsSymbolV2List symbols();
|
||||
@ -410,27 +445,76 @@ class QgsRuleBasedRendererV2 : QgsFeatureRendererV2
|
||||
class Rule
|
||||
{
|
||||
public:
|
||||
//! Constructor takes ownership of the symbol
|
||||
Rule( QgsSymbolV2* symbol /Transfer/, int scaleMinDenom = 0, int scaleMaxDenom = 0, QString filterExp = QString() );
|
||||
//Rule( const QgsRuleBasedRendererV2::Rule& other );
|
||||
|
||||
Rule( QgsSymbolV2* symbol /Transfer/, int scaleMinDenom = 0, int scaleMaxDenom = 0, QString filterExp = QString(),
|
||||
QString label = QString(), QString description = QString() );
|
||||
~Rule();
|
||||
QString dump() const;
|
||||
//QStringList needsFields() const;
|
||||
QString dump( int offset = 0 ) const;
|
||||
QSet<QString> usedAttributes();
|
||||
QgsSymbolV2List symbols();
|
||||
// TODO QgsLegendSymbolList legendSymbolItems();
|
||||
bool isFilterOK( QgsFeature& f ) const;
|
||||
bool isScaleOK( double scale ) const;
|
||||
|
||||
QgsSymbolV2* symbol();
|
||||
QString label() const;
|
||||
bool dependsOnScale() const;
|
||||
int scaleMinDenom() const;
|
||||
int scaleMaxDenom() const;
|
||||
QString filterExpression() const;
|
||||
QgsExpression* filter() const;
|
||||
QString filterExpression() const;
|
||||
QString description() const;
|
||||
|
||||
//! set a new symbol (or NULL). Deletes old symbol.
|
||||
void setSymbol( QgsSymbolV2* sym /Transfer/ );
|
||||
void setLabel( QString label );
|
||||
void setScaleMinDenom( int scaleMinDenom );
|
||||
void setScaleMaxDenom( int scaleMaxDenom );
|
||||
void setFilterExpression( QString filterExp );
|
||||
void setDescription( QString description );
|
||||
|
||||
//! clone this rule, return new instance
|
||||
QgsRuleBasedRendererV2::Rule* clone() const /Factory/;
|
||||
|
||||
QDomElement save( QDomDocument& doc, QgsSymbolV2Map& symbolMap );
|
||||
|
||||
//! prepare the rule for rendering and its children (build active children array)
|
||||
bool startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer );
|
||||
//! get all used z-levels from this rule and children
|
||||
QSet<int> collectZLevels();
|
||||
//! assign normalized z-levels [0..N-1] for this rule's symbol for quick access during rendering
|
||||
// TODO void setNormZLevels( const QMap<int, int>& zLevelsToNormLevels );
|
||||
|
||||
// TODO bool renderFeature( FeatureToRender& featToRender, QgsRenderContext& context, RenderQueue& renderQueue );
|
||||
|
||||
//! only tell whether a feature will be rendered without actually rendering it
|
||||
//! @note added in 1.9
|
||||
bool willRenderFeature( QgsFeature& feat );
|
||||
|
||||
//! tell which symbols will be used to render the feature
|
||||
//! @note added in 1.9
|
||||
QgsSymbolV2List symbolsForFeature( QgsFeature& feat );
|
||||
|
||||
void stopRender( QgsRenderContext& context );
|
||||
|
||||
static QgsRuleBasedRendererV2::Rule* create( QDomElement& ruleElem, QgsSymbolV2Map& symbolMap ) /Factory/;
|
||||
|
||||
QList<QgsRuleBasedRendererV2::Rule*>& children();
|
||||
QgsRuleBasedRendererV2::Rule* parent();
|
||||
|
||||
//! add child rule, take ownership, sets this as parent
|
||||
void appendChild( QgsRuleBasedRendererV2::Rule* rule /Transfer/ );
|
||||
//! add child rule, take ownership, sets this as parent
|
||||
void insertChild( int i, QgsRuleBasedRendererV2::Rule* rule /Transfer/ );
|
||||
//! delete child rule
|
||||
void removeChild( QgsRuleBasedRendererV2::Rule* rule );
|
||||
//! delete child rule
|
||||
void removeChildAt( int i );
|
||||
//! take child rule out, set parent as null
|
||||
void takeChild( QgsRuleBasedRendererV2::Rule* rule );
|
||||
//! take child rule out, set parent as null
|
||||
QgsRuleBasedRendererV2::Rule* takeChildAt( int i );
|
||||
|
||||
//Rule& operator=( const Rule& other );
|
||||
};
|
||||
|
||||
/////
|
||||
@ -453,6 +537,12 @@ class QgsRuleBasedRendererV2 : QgsFeatureRendererV2
|
||||
|
||||
virtual QList<QString> usedAttributes();
|
||||
|
||||
virtual QString dump();
|
||||
|
||||
//! returns bitwise OR-ed capabilities of the renderer
|
||||
//! \note added in 2.0
|
||||
virtual int capabilities();
|
||||
|
||||
virtual QgsFeatureRendererV2* clone() /Factory/;
|
||||
|
||||
virtual QgsSymbolV2List symbols();
|
||||
@ -463,6 +553,17 @@ class QgsRuleBasedRendererV2 : QgsFeatureRendererV2
|
||||
//! return a list of symbology items for the legend
|
||||
virtual QgsLegendSymbologyList legendSymbologyItems( QSize iconSize );
|
||||
|
||||
//! return whether the renderer will render a feature or not.
|
||||
//! Must be called between startRender() and stopRender() calls.
|
||||
//! @note added in 1.9
|
||||
virtual bool willRenderFeature( QgsFeature& feat );
|
||||
|
||||
//! return list of symbols used for rendering the feature.
|
||||
//! For renderers that do not support MoreSymbolsPerFeature it is more efficient
|
||||
//! to use symbolForFeature()
|
||||
//! @note added in 1.9
|
||||
virtual QgsSymbolV2List symbolsForFeature( QgsFeature& feat );
|
||||
|
||||
/////
|
||||
|
||||
|
||||
|
@ -508,37 +508,40 @@ class geometryThread( QThread ):
|
||||
return True
|
||||
|
||||
def export_geometry_info( self ):
|
||||
ellips = None
|
||||
crs = None
|
||||
coordTransform = None
|
||||
|
||||
# calculate with:
|
||||
# 0 - layer CRS
|
||||
# 1 - project CRS
|
||||
# 2 - ellipsoidal
|
||||
if self.myCalcType == 2:
|
||||
settings = QSettings()
|
||||
ellips = settings.value( "/qgis/measure/ellipsoid", "WGS84" ).toString()
|
||||
crs = self.vlayer.crs().srsid()
|
||||
elif self.myCalcType == 1:
|
||||
mapCRS = self.parent.iface.mapCanvas().mapRenderer().destinationCrs()
|
||||
layCRS = self.vlayer.crs()
|
||||
coordTransform = QgsCoordinateTransform( layCRS, mapCRS )
|
||||
|
||||
inFeat = QgsFeature()
|
||||
outFeat = QgsFeature()
|
||||
inGeom = QgsGeometry()
|
||||
nElement = 0
|
||||
|
||||
vprovider = self.vlayer.dataProvider()
|
||||
|
||||
self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0)
|
||||
self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, vprovider.featureCount() ) )
|
||||
|
||||
if self.writeShape:
|
||||
vprovider = self.vlayer.dataProvider()
|
||||
allAttrs = vprovider.attributeIndexes()
|
||||
vprovider.select( allAttrs )
|
||||
( fields, index1, index2 ) = self.checkGeometryFields( self.vlayer )
|
||||
writer = QgsVectorFileWriter( self.myName, self.myEncoding, fields,
|
||||
vprovider.geometryType(), vprovider.crs() )
|
||||
inFeat = QgsFeature()
|
||||
outFeat = QgsFeature()
|
||||
inGeom = QgsGeometry()
|
||||
nFeat = vprovider.featureCount()
|
||||
nElement = 0
|
||||
|
||||
# calculate with:
|
||||
# 0 - layer CRS
|
||||
# 1 - project CRS
|
||||
# 2 - ellipsoidal
|
||||
ellips = None
|
||||
crs = None
|
||||
coordTransform = None
|
||||
if self.myCalcType == 2:
|
||||
settings = QSettings()
|
||||
ellips = settings.value( "/qgis/measure/ellipsoid", "WGS84" ).toString()
|
||||
crs = self.parent.iface.mapCanvas().mapRenderer().destinationCrs().srsid()
|
||||
elif self.myCalcType == 1:
|
||||
mapCRS = self.parent.iface.mapCanvas().mapRenderer().destinationCrs()
|
||||
layCRS = self.vlayer.crs()
|
||||
coordTransform = QgsCoordinateTransform( layCRS, mapCRS )
|
||||
|
||||
self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0)
|
||||
self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, nFeat ) )
|
||||
while vprovider.nextFeature(inFeat):
|
||||
self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), nElement )
|
||||
nElement += 1
|
||||
@ -546,6 +549,7 @@ class geometryThread( QThread ):
|
||||
|
||||
if self.myCalcType == 1:
|
||||
inGeom.transform( coordTransform )
|
||||
|
||||
( attr1, attr2 ) = self.simpleMeasure( inGeom, self.myCalcType, ellips, crs )
|
||||
|
||||
outFeat.setGeometry( inGeom )
|
||||
@ -558,34 +562,9 @@ class geometryThread( QThread ):
|
||||
return True
|
||||
else: # update existing file
|
||||
newFields = []
|
||||
vprovider = self.vlayer.dataProvider()
|
||||
geomType = self.vlayer.geometryType()
|
||||
( index1, index2 ) = self.findOrCreateFields()
|
||||
|
||||
inFeat = QgsFeature()
|
||||
inGeom = QgsGeometry()
|
||||
nFeat = vprovider.featureCount()
|
||||
nElement = 0
|
||||
|
||||
# calculate with:
|
||||
# 0 - layer CRS
|
||||
# 1 - project CRS
|
||||
# 2 - ellipsoidal
|
||||
ellips = None
|
||||
crs = None
|
||||
coordTransform = None
|
||||
if self.myCalcType == 2:
|
||||
settings = QSettings()
|
||||
ellips = settings.value( "/qgis/measure/ellipsoid", "WGS84" ).toString()
|
||||
crs = self.parent.iface.mapCanvas().mapRenderer().destinationCrs().srsid()
|
||||
elif self.myCalcType == 1:
|
||||
mapCRS = self.parent.iface.mapCanvas().mapRenderer().destinationCrs()
|
||||
layCRS = self.vlayer.crs()
|
||||
coordTransform = QgsCoordinateTransform( layCRS, mapCRS )
|
||||
|
||||
self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0)
|
||||
self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, nFeat ) )
|
||||
|
||||
while vprovider.nextFeature(inFeat):
|
||||
self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), nElement )
|
||||
nElement += 1
|
||||
|
@ -1018,7 +1018,10 @@ void QgisApp::createActionGroups()
|
||||
mMapToolGroup->addAction( mActionMeasureAngle );
|
||||
mMapToolGroup->addAction( mActionAddFeature );
|
||||
mMapToolGroup->addAction( mActionMoveFeature );
|
||||
#if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
|
||||
((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3)))
|
||||
mMapToolGroup->addAction( mActionOffsetCurve );
|
||||
#endif
|
||||
mMapToolGroup->addAction( mActionReshapeFeatures );
|
||||
mMapToolGroup->addAction( mActionSplitFeatures );
|
||||
mMapToolGroup->addAction( mActionDeleteSelected );
|
||||
@ -1667,8 +1670,15 @@ void QgisApp::createCanvasTools()
|
||||
mMapTools.mAddFeature->setAction( mActionAddFeature );
|
||||
mMapTools.mMoveFeature = new QgsMapToolMoveFeature( mMapCanvas );
|
||||
mMapTools.mMoveFeature->setAction( mActionMoveFeature );
|
||||
//need at least geos 3.3 for OffsetCurve tool
|
||||
#if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
|
||||
((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3)))
|
||||
mMapTools.mOffsetCurve = new QgsMapToolOffsetCurve( mMapCanvas );
|
||||
mMapTools.mOffsetCurve->setAction( mActionOffsetCurve );
|
||||
#else
|
||||
mAdvancedDigitizeToolBar->removeAction( mActionOffsetCurve );
|
||||
mEditMenu->removeAction( mActionOffsetCurve );
|
||||
#endif //GEOS_VERSION
|
||||
mMapTools.mReshapeFeatures = new QgsMapToolReshape( mMapCanvas );
|
||||
mMapTools.mReshapeFeatures->setAction( mActionReshapeFeatures );
|
||||
mMapTools.mSplitFeatures = new QgsMapToolSplitFeatures( mMapCanvas );
|
||||
|
@ -352,7 +352,16 @@ void QgsMapToolOffsetCurve::setOffsetForRubberBand( double offset, bool leftSide
|
||||
int joinStyle = s.value( "/qgis/digitizing/offset_join_style", 0 ).toInt();
|
||||
int quadSegments = s.value( "/qgis/digitizing/offset_quad_seg", 8 ).toInt();
|
||||
double mitreLimit = s.value( "/qgis/digitizine/offset_miter_limit", 5.0 ).toDouble();
|
||||
GEOSGeometry* offsetGeom = GEOSSingleSidedBuffer( geosGeom, offset, quadSegments, joinStyle, mitreLimit, leftSide ? 1 : 0 );
|
||||
|
||||
GEOSGeometry* offsetGeom = 0;
|
||||
//need at least geos 3.3 for OffsetCurve tool
|
||||
#if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
|
||||
((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3)))
|
||||
GEOSGeometry* offsetGeom = GEOSOffsetCurve( geosGeom, ( leftSide > 0 ) ? offset : -offset, quadSegments, joinStyle, mitreLimit );
|
||||
#else
|
||||
return;
|
||||
#endif //GEOS_VERSION
|
||||
|
||||
if ( !offsetGeom )
|
||||
{
|
||||
deleteRubberBandAndGeometry();
|
||||
@ -365,9 +374,6 @@ void QgsMapToolOffsetCurve::setOffsetForRubberBand( double offset, bool leftSide
|
||||
return;
|
||||
}
|
||||
|
||||
//GEOS >= 3.3
|
||||
//GEOSGeometry* offsetGeom = GEOSOffsetCurve( geosGeom, (leftSide > 0) ? offset : -offset, quadSegments, joinStyle, mitreLimit );
|
||||
|
||||
if ( offsetGeom )
|
||||
{
|
||||
mModifiedGeometry.fromGeos( offsetGeom );
|
||||
|
@ -417,3 +417,11 @@ void QgsFeatureRendererV2::renderVertexMarkerPolygon( QPolygonF& pts, QList<QPol
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QgsSymbolV2List QgsFeatureRendererV2::symbolsForFeature( QgsFeature& feat )
|
||||
{
|
||||
QgsSymbolV2List lst;
|
||||
QgsSymbolV2* s = symbolForFeature( feat );
|
||||
if ( s ) lst.append( s );
|
||||
return lst;
|
||||
}
|
||||
|
@ -81,7 +81,8 @@ class CORE_EXPORT QgsFeatureRendererV2
|
||||
enum Capabilities
|
||||
{
|
||||
SymbolLevels = 1, // rendering with symbol levels (i.e. implements symbols(), symbolForFeature())
|
||||
RotationField = 1 << 1 // rotate symbols by attribute value
|
||||
RotationField = 1 << 1, // rotate symbols by attribute value
|
||||
MoreSymbolsPerFeature = 1 << 2 // may use more than one symbol to render a feature: symbolsForFeature() will return them
|
||||
};
|
||||
|
||||
//! returns bitwise OR-ed capabilities of the renderer
|
||||
@ -117,7 +118,17 @@ class CORE_EXPORT QgsFeatureRendererV2
|
||||
//! @note added in 1.9
|
||||
virtual void setRotationField( QString fieldName ) { Q_UNUSED( fieldName ); }
|
||||
|
||||
//! return whether the renderer will render a feature or not.
|
||||
//! Must be called between startRender() and stopRender() calls.
|
||||
//! Default implementation uses symbolForFeature().
|
||||
//! @note added in 1.9
|
||||
virtual bool willRenderFeature( QgsFeature& feat ) { return symbolForFeature( feat ) != NULL; }
|
||||
|
||||
//! return list of symbols used for rendering the feature.
|
||||
//! For renderers that do not support MoreSymbolsPerFeature it is more efficient
|
||||
//! to use symbolForFeature()
|
||||
//! @note added in 1.9
|
||||
virtual QgsSymbolV2List symbolsForFeature( QgsFeature& feat );
|
||||
|
||||
protected:
|
||||
QgsFeatureRendererV2( QString type );
|
||||
|
@ -288,6 +288,38 @@ bool QgsRuleBasedRendererV2::Rule::renderFeature( QgsRuleBasedRendererV2::Featur
|
||||
return rendered;
|
||||
}
|
||||
|
||||
bool QgsRuleBasedRendererV2::Rule::willRenderFeature( QgsFeature& feat )
|
||||
{
|
||||
if ( !isFilterOK( feat ) )
|
||||
return false;
|
||||
if ( mSymbol )
|
||||
return true;
|
||||
|
||||
for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
|
||||
{
|
||||
Rule* rule = *it;
|
||||
if ( rule->willRenderFeature( feat ) )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QgsSymbolV2List QgsRuleBasedRendererV2::Rule::symbolsForFeature( QgsFeature& feat )
|
||||
{
|
||||
QgsSymbolV2List lst;
|
||||
if ( !isFilterOK( feat ) )
|
||||
return lst;
|
||||
if ( mSymbol )
|
||||
lst.append( mSymbol );
|
||||
|
||||
for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
|
||||
{
|
||||
Rule* rule = *it;
|
||||
lst += rule->symbolsForFeature( feat );
|
||||
}
|
||||
return lst;
|
||||
}
|
||||
|
||||
|
||||
void QgsRuleBasedRendererV2::Rule::stopRender( QgsRenderContext& context )
|
||||
{
|
||||
@ -581,3 +613,13 @@ QString QgsRuleBasedRendererV2::dump()
|
||||
msg += mRootRule->dump();
|
||||
return msg;
|
||||
}
|
||||
|
||||
bool QgsRuleBasedRendererV2::willRenderFeature( QgsFeature& feat )
|
||||
{
|
||||
return mRootRule->willRenderFeature( feat );
|
||||
}
|
||||
|
||||
QgsSymbolV2List QgsRuleBasedRendererV2::symbolsForFeature( QgsFeature& feat )
|
||||
{
|
||||
return mRootRule->symbolsForFeature( feat );
|
||||
}
|
||||
|
@ -127,6 +127,14 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2
|
||||
|
||||
bool renderFeature( FeatureToRender& featToRender, QgsRenderContext& context, RenderQueue& renderQueue );
|
||||
|
||||
//! only tell whether a feature will be rendered without actually rendering it
|
||||
//! @note added in 1.9
|
||||
bool willRenderFeature( QgsFeature& feat );
|
||||
|
||||
//! tell which symbols will be used to render the feature
|
||||
//! @note added in 1.9
|
||||
QgsSymbolV2List symbolsForFeature( QgsFeature& feat );
|
||||
|
||||
void stopRender( QgsRenderContext& context );
|
||||
|
||||
static Rule* create( QDomElement& ruleElem, QgsSymbolV2Map& symbolMap );
|
||||
@ -204,6 +212,21 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2
|
||||
//! for debugging
|
||||
virtual QString dump();
|
||||
|
||||
//! return whether the renderer will render a feature or not.
|
||||
//! Must be called between startRender() and stopRender() calls.
|
||||
//! @note added in 1.9
|
||||
virtual bool willRenderFeature( QgsFeature& feat );
|
||||
|
||||
//! return list of symbols used for rendering the feature.
|
||||
//! For renderers that do not support MoreSymbolsPerFeature it is more efficient
|
||||
//! to use symbolForFeature()
|
||||
//! @note added in 1.9
|
||||
virtual QgsSymbolV2List symbolsForFeature( QgsFeature& feat );
|
||||
|
||||
//! returns bitwise OR-ed capabilities of the renderer
|
||||
//! \note added in 2.0
|
||||
virtual int capabilities() { return MoreSymbolsPerFeature; }
|
||||
|
||||
/////
|
||||
|
||||
Rule* rootRule() { return mRootRule; }
|
||||
|
@ -4,4 +4,5 @@
|
||||
<qgisgrassmodule label="Create a MASK for limiting raster operation" module="r.mask">
|
||||
<option key="input" />
|
||||
<option key="maskcats" />
|
||||
<flag key="r" />
|
||||
</qgisgrassmodule>
|
||||
|
@ -18,75 +18,128 @@
|
||||
//header for class being tested
|
||||
#include <qgsrulebasedrendererv2.h>
|
||||
|
||||
#include <qgsapplication.h>
|
||||
#include <qgssymbolv2.h>
|
||||
#include <qgsvectorlayer.h>
|
||||
|
||||
#if QT_VERSION < 0x40701
|
||||
// See http://hub.qgis.org/issues/4284
|
||||
Q_DECLARE_METATYPE( QVariant )
|
||||
#endif
|
||||
|
||||
typedef QgsRuleBasedRendererV2::Rule RRule;
|
||||
|
||||
class TestQgsRuleBasedRenderer: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
|
||||
void test_load_xml()
|
||||
{
|
||||
QDomDocument doc;
|
||||
xml2domElement( "rulebasedrenderer_simple.xml", doc );
|
||||
QDomElement elem = doc.documentElement();
|
||||
void initTestCase()
|
||||
{
|
||||
// we need memory provider, so make sure to load providers
|
||||
QgsApplication::init();
|
||||
QgsApplication::initQgis();
|
||||
}
|
||||
|
||||
QgsRuleBasedRendererV2* r = static_cast<QgsRuleBasedRendererV2*>( QgsRuleBasedRendererV2::create( elem ) );
|
||||
QVERIFY( r );
|
||||
check_tree_valid( r->rootRule() );
|
||||
delete r;
|
||||
}
|
||||
void test_load_xml()
|
||||
{
|
||||
QDomDocument doc;
|
||||
xml2domElement( "rulebasedrenderer_simple.xml", doc );
|
||||
QDomElement elem = doc.documentElement();
|
||||
|
||||
void test_load_invalid_xml()
|
||||
{
|
||||
QDomDocument doc;
|
||||
xml2domElement( "rulebasedrenderer_invalid.xml", doc );
|
||||
QDomElement elem = doc.documentElement();
|
||||
QgsRuleBasedRendererV2* r = static_cast<QgsRuleBasedRendererV2*>( QgsRuleBasedRendererV2::create( elem ) );
|
||||
QVERIFY( r );
|
||||
check_tree_valid( r->rootRule() );
|
||||
delete r;
|
||||
}
|
||||
|
||||
QgsRuleBasedRendererV2* r = static_cast<QgsRuleBasedRendererV2*>( QgsRuleBasedRendererV2::create( elem ) );
|
||||
QVERIFY( r == NULL );
|
||||
}
|
||||
void test_load_invalid_xml()
|
||||
{
|
||||
QDomDocument doc;
|
||||
xml2domElement( "rulebasedrenderer_invalid.xml", doc );
|
||||
QDomElement elem = doc.documentElement();
|
||||
|
||||
private:
|
||||
void xml2domElement( QString testFile, QDomDocument& doc )
|
||||
{
|
||||
QString fileName = QString( TEST_DATA_DIR ) + QDir::separator() + testFile;
|
||||
QFile f(fileName);
|
||||
bool fileOpen = f.open(QIODevice::ReadOnly);
|
||||
QVERIFY( fileOpen );
|
||||
QgsRuleBasedRendererV2* r = static_cast<QgsRuleBasedRendererV2*>( QgsRuleBasedRendererV2::create( elem ) );
|
||||
QVERIFY( r == NULL );
|
||||
}
|
||||
|
||||
QString msg;
|
||||
int line, col;
|
||||
bool parse = doc.setContent( &f, &msg, &line, &col );
|
||||
QVERIFY( parse );
|
||||
}
|
||||
void test_willRenderFeature_symbolsForFeature()
|
||||
{
|
||||
// prepare features
|
||||
QgsVectorLayer* layer = new QgsVectorLayer( "point?field=fld:int", "x", "memory" );
|
||||
int idx = layer->fieldNameIndex( "fld" );
|
||||
QVERIFY( idx != -1 );
|
||||
QgsFeature f1; f1.addAttribute( idx, QVariant( 2 ) );
|
||||
QgsFeature f2; f2.addAttribute( idx, QVariant( 8 ) );
|
||||
QgsFeature f3; f3.addAttribute( idx, QVariant( 100 ) );
|
||||
|
||||
void check_tree_valid( QgsRuleBasedRendererV2::Rule* root )
|
||||
{
|
||||
// root must always exist (although it does not have children)
|
||||
QVERIFY( root );
|
||||
// and does not have a parent
|
||||
QVERIFY( root->parent() == NULL );
|
||||
// prepare renderer
|
||||
QgsSymbolV2* s1 = QgsSymbolV2::defaultSymbol( QGis::Point );
|
||||
QgsSymbolV2* s2 = QgsSymbolV2::defaultSymbol( QGis::Point );
|
||||
RRule* rootRule = new RRule( NULL );
|
||||
rootRule->appendChild( new RRule( s1, 0, 0, "fld >= 5 and fld <= 20" ) );
|
||||
rootRule->appendChild( new RRule( s2, 0, 0, "fld <= 10" ) );
|
||||
QgsRuleBasedRendererV2 r( rootRule );
|
||||
|
||||
foreach ( QgsRuleBasedRendererV2::Rule* node, root->children() )
|
||||
QVERIFY( r.capabilities() & QgsFeatureRendererV2::MoreSymbolsPerFeature );
|
||||
|
||||
QgsRenderContext ctx; // dummy render context
|
||||
r.startRender( ctx, layer );
|
||||
|
||||
// test willRenderFeature
|
||||
QVERIFY( r.willRenderFeature( f1 ) == true );
|
||||
QVERIFY( r.willRenderFeature( f2 ) == true );
|
||||
QVERIFY( r.willRenderFeature( f3 ) == false );
|
||||
|
||||
// test symbolsForFeature
|
||||
QgsSymbolV2List lst1 = r.symbolsForFeature( f1 );
|
||||
QVERIFY( lst1.count() == 1 );
|
||||
QgsSymbolV2List lst2 = r.symbolsForFeature( f2 );
|
||||
QVERIFY( lst2.count() == 2 );
|
||||
QgsSymbolV2List lst3 = r.symbolsForFeature( f3 );
|
||||
QVERIFY( lst3.count() == 0 );
|
||||
|
||||
r.stopRender( ctx );
|
||||
|
||||
delete layer;
|
||||
}
|
||||
|
||||
private:
|
||||
void xml2domElement( QString testFile, QDomDocument& doc )
|
||||
{
|
||||
QString fileName = QString( TEST_DATA_DIR ) + QDir::separator() + testFile;
|
||||
QFile f( fileName );
|
||||
bool fileOpen = f.open( QIODevice::ReadOnly );
|
||||
QVERIFY( fileOpen );
|
||||
|
||||
QString msg;
|
||||
int line, col;
|
||||
bool parse = doc.setContent( &f, &msg, &line, &col );
|
||||
QVERIFY( parse );
|
||||
}
|
||||
|
||||
void check_tree_valid( QgsRuleBasedRendererV2::Rule* root )
|
||||
{
|
||||
// root must always exist (although it does not have children)
|
||||
QVERIFY( root );
|
||||
// and does not have a parent
|
||||
QVERIFY( root->parent() == NULL );
|
||||
|
||||
foreach( QgsRuleBasedRendererV2::Rule* node, root->children() )
|
||||
check_non_root_rule( node );
|
||||
}
|
||||
}
|
||||
|
||||
void check_non_root_rule( QgsRuleBasedRendererV2::Rule* node )
|
||||
{
|
||||
qDebug() << node->dump();
|
||||
// children must not be NULL
|
||||
QVERIFY( node );
|
||||
// and must have a parent
|
||||
QVERIFY( node->parent() );
|
||||
// check that all children are okay
|
||||
foreach ( QgsRuleBasedRendererV2::Rule* child, node->children() )
|
||||
void check_non_root_rule( QgsRuleBasedRendererV2::Rule* node )
|
||||
{
|
||||
qDebug() << node->dump();
|
||||
// children must not be NULL
|
||||
QVERIFY( node );
|
||||
// and must have a parent
|
||||
QVERIFY( node->parent() );
|
||||
// check that all children are okay
|
||||
foreach( QgsRuleBasedRendererV2::Rule* child, node->children() )
|
||||
check_non_root_rule( child );
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user