[FEATURE] Add option to symbology to prevent clipping of features

This option (located under the symbol advanced menu) disables the
automatic clipping of lines/polygons to the canvas extent. In
some cases this clipping results in unfavourable symbology (eg
centroid fills where the centroid must always be the actual
feature's centroid). (fix #9757)
This commit is contained in:
Nyall Dawson 2015-03-24 23:01:25 +11:00
parent 742f3233ee
commit 8b37ea2b05
18 changed files with 230 additions and 19 deletions

View File

@ -229,8 +229,8 @@ class QgsFeatureRendererV2
void renderVertexMarkerPolygon( QPolygonF& pts, QList<QPolygonF>* rings, QgsRenderContext& context ); void renderVertexMarkerPolygon( QPolygonF& pts, QList<QPolygonF>* rings, QgsRenderContext& context );
static const unsigned char* _getPoint( QPointF& pt, QgsRenderContext& context, const unsigned char* wkb ); static const unsigned char* _getPoint( QPointF& pt, QgsRenderContext& context, const unsigned char* wkb );
static const unsigned char* _getLineString( QPolygonF& pts, QgsRenderContext& context, const unsigned char* wkb ); static const unsigned char* _getLineString( QPolygonF& pts, QgsRenderContext& context, const unsigned char* wkb, bool clipToExtent = true );
static const unsigned char* _getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, const unsigned char* wkb ); static const unsigned char* _getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, const unsigned char* wkb, bool clipToExtent = true );
void setScaleMethodToSymbol( QgsSymbolV2* symbol, int scaleMethod ); void setScaleMethodToSymbol( QgsSymbolV2* symbol, int scaleMethod );

View File

@ -130,6 +130,26 @@ class QgsSymbolV2
void setRenderHints( int hints ); void setRenderHints( int hints );
int renderHints() const; int renderHints() const;
/**Sets whether features drawn by the symbol should be clipped to the render context's
* extent. If this option is enabled then features which are partially outside the extent
* will be clipped. This speeds up rendering of the feature, but may have undesirable
* side effects for certain symbol types.
* @param clipFeaturesToExtent set to true to enable clipping (defaults to true)
* @note added in QGIS 2.9
* @see clipFeaturesToExtent
*/
void setClipFeaturesToExtent( bool clipFeaturesToExtent );
/**Returns whether features drawn by the symbol will be clipped to the render context's
* extent. If this option is enabled then features which are partially outside the extent
* will be clipped. This speeds up rendering of the feature, but may have undesirable
* side effects for certain symbol types.
* @returns true if features will be clipped
* @note added in QGIS 2.9
* @see setClipFeaturesToExtent
*/
double clipFeaturesToExtent() const;
QSet<QString> usedAttributes() const; QSet<QString> usedAttributes() const;
void setLayer( const QgsVectorLayer* layer ); void setLayer( const QgsVectorLayer* layer );

View File

@ -58,20 +58,21 @@ const unsigned char* QgsFeatureRendererV2::_getPoint( QPointF& pt, QgsRenderCont
return wkbPtr; return wkbPtr;
} }
const unsigned char* QgsFeatureRendererV2::_getLineString( QPolygonF& pts, QgsRenderContext& context, const unsigned char* wkb ) const unsigned char* QgsFeatureRendererV2::_getLineString( QPolygonF& pts, QgsRenderContext& context, const unsigned char* wkb, bool clipToExtent )
{ {
QgsConstWkbPtr wkbPtr( wkb ); QgsConstWkbPtr wkbPtr( wkb + 1 );
unsigned int wkbType, nPoints; unsigned int wkbType, nPoints;
wkbPtr >> wkbType >> nPoints; wkbPtr >> wkbType >> nPoints;
bool hasZValue = wkbType == QGis::WKBLineString25D; bool hasZValue = wkbType == QGis::WKBLineString25D;
double x, y; double x = 0.0;
double y = 0.0;
const QgsCoordinateTransform* ct = context.coordinateTransform(); const QgsCoordinateTransform* ct = context.coordinateTransform();
const QgsMapToPixel& mtp = context.mapToPixel(); const QgsMapToPixel& mtp = context.mapToPixel();
//apply clipping for large lines to achieve a better rendering performance //apply clipping for large lines to achieve a better rendering performance
if ( nPoints > 1 ) if ( clipToExtent && nPoints > 1 )
{ {
const QgsRectangle& e = context.extent(); const QgsRectangle& e = context.extent();
double cw = e.width() / 10; double ch = e.height() / 10; double cw = e.width() / 10; double ch = e.height() / 10;
@ -108,7 +109,7 @@ const unsigned char* QgsFeatureRendererV2::_getLineString( QPolygonF& pts, QgsRe
return wkbPtr; return wkbPtr;
} }
const unsigned char* QgsFeatureRendererV2::_getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, const unsigned char* wkb ) const unsigned char* QgsFeatureRendererV2::_getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, const unsigned char* wkb, bool clipToExtent )
{ {
QgsConstWkbPtr wkbPtr( wkb + 1 ); QgsConstWkbPtr wkbPtr( wkb + 1 );
@ -152,7 +153,7 @@ const unsigned char* QgsFeatureRendererV2::_getPolygon( QPolygonF& pts, QList<QP
//clip close to view extent, if needed //clip close to view extent, if needed
QRectF ptsRect = poly.boundingRect(); QRectF ptsRect = poly.boundingRect();
if ( !context.extent().contains( ptsRect ) ) QgsClipper::trimPolygon( poly, clipRect ); if ( clipToExtent && !context.extent().contains( ptsRect ) ) QgsClipper::trimPolygon( poly, clipRect );
//transform the QPolygonF to screen coordinates //transform the QPolygonF to screen coordinates
if ( ct ) if ( ct )
@ -271,7 +272,7 @@ void QgsFeatureRendererV2::renderFeatureWithSymbol( QgsFeature& feature, QgsSymb
break; break;
} }
QPolygonF pts; QPolygonF pts;
_getLineString( pts, context, geom->asWkb() ); _getLineString( pts, context, geom->asWkb(), symbol->clipFeaturesToExtent() );
(( QgsLineSymbolV2* )symbol )->renderPolyline( pts, &feature, context, layer, selected ); (( QgsLineSymbolV2* )symbol )->renderPolyline( pts, &feature, context, layer, selected );
if ( drawVertexMarker ) if ( drawVertexMarker )
@ -289,7 +290,7 @@ void QgsFeatureRendererV2::renderFeatureWithSymbol( QgsFeature& feature, QgsSymb
} }
QPolygonF pts; QPolygonF pts;
QList<QPolygonF> holes; QList<QPolygonF> holes;
_getPolygon( pts, holes, context, geom->asWkb() ); _getPolygon( pts, holes, context, geom->asWkb(), symbol->clipFeaturesToExtent() );
(( QgsFillSymbolV2* )symbol )->renderPolygon( pts, ( holes.count() ? &holes : NULL ), &feature, context, layer, selected ); (( QgsFillSymbolV2* )symbol )->renderPolygon( pts, ( holes.count() ? &holes : NULL ), &feature, context, layer, selected );
if ( drawVertexMarker ) if ( drawVertexMarker )
@ -306,7 +307,7 @@ void QgsFeatureRendererV2::renderFeatureWithSymbol( QgsFeature& feature, QgsSymb
break; break;
} }
QgsConstWkbPtr wkbPtr( geom->asWkb() + 5 ); QgsConstWkbPtr wkbPtr( geom->asWkb() + 1 + sizeof( int ) );
unsigned int num; unsigned int num;
wkbPtr >> num; wkbPtr >> num;
const unsigned char* ptr = wkbPtr; const unsigned char* ptr = wkbPtr;
@ -332,7 +333,7 @@ void QgsFeatureRendererV2::renderFeatureWithSymbol( QgsFeature& feature, QgsSymb
break; break;
} }
QgsConstWkbPtr wkbPtr( geom->asWkb() + 5 ); QgsConstWkbPtr wkbPtr( geom->asWkb() + 1 + sizeof( int ) );
unsigned int num; unsigned int num;
wkbPtr >> num; wkbPtr >> num;
const unsigned char* ptr = wkbPtr; const unsigned char* ptr = wkbPtr;
@ -340,7 +341,7 @@ void QgsFeatureRendererV2::renderFeatureWithSymbol( QgsFeature& feature, QgsSymb
for ( unsigned int i = 0; i < num; ++i ) for ( unsigned int i = 0; i < num; ++i )
{ {
ptr = QgsConstWkbPtr( _getLineString( pts, context, ptr ) ); ptr = QgsConstWkbPtr( _getLineString( pts, context, ptr, symbol->clipFeaturesToExtent() ) );
(( QgsLineSymbolV2* )symbol )->renderPolyline( pts, &feature, context, layer, selected ); (( QgsLineSymbolV2* )symbol )->renderPolyline( pts, &feature, context, layer, selected );
if ( drawVertexMarker ) if ( drawVertexMarker )
@ -358,7 +359,7 @@ void QgsFeatureRendererV2::renderFeatureWithSymbol( QgsFeature& feature, QgsSymb
break; break;
} }
QgsConstWkbPtr wkbPtr( geom->asWkb() + 5 ); QgsConstWkbPtr wkbPtr( geom->asWkb() + 1 + sizeof( int ) );
unsigned int num; unsigned int num;
wkbPtr >> num; wkbPtr >> num;
const unsigned char* ptr = wkbPtr; const unsigned char* ptr = wkbPtr;
@ -367,7 +368,7 @@ void QgsFeatureRendererV2::renderFeatureWithSymbol( QgsFeature& feature, QgsSymb
for ( unsigned int i = 0; i < num; ++i ) for ( unsigned int i = 0; i < num; ++i )
{ {
ptr = _getPolygon( pts, holes, context, ptr ); ptr = _getPolygon( pts, holes, context, ptr, symbol->clipFeaturesToExtent() );
(( QgsFillSymbolV2* )symbol )->renderPolygon( pts, ( holes.count() ? &holes : NULL ), &feature, context, layer, selected ); (( QgsFillSymbolV2* )symbol )->renderPolygon( pts, ( holes.count() ? &holes : NULL ), &feature, context, layer, selected );
if ( drawVertexMarker ) if ( drawVertexMarker )

View File

@ -251,8 +251,8 @@ class CORE_EXPORT QgsFeatureRendererV2
void renderVertexMarkerPolygon( QPolygonF& pts, QList<QPolygonF>* rings, QgsRenderContext& context ); void renderVertexMarkerPolygon( QPolygonF& pts, QList<QPolygonF>* rings, QgsRenderContext& context );
static const unsigned char* _getPoint( QPointF& pt, QgsRenderContext& context, const unsigned char* wkb ); static const unsigned char* _getPoint( QPointF& pt, QgsRenderContext& context, const unsigned char* wkb );
static const unsigned char* _getLineString( QPolygonF& pts, QgsRenderContext& context, const unsigned char* wkb ); static const unsigned char* _getLineString( QPolygonF& pts, QgsRenderContext& context, const unsigned char* wkb, bool clipToExtent = true );
static const unsigned char* _getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, const unsigned char* wkb ); static const unsigned char* _getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, const unsigned char* wkb, bool clipToExtent = true );
void setScaleMethodToSymbol( QgsSymbolV2* symbol, int scaleMethod ); void setScaleMethodToSymbol( QgsSymbolV2* symbol, int scaleMethod );

View File

@ -940,6 +940,7 @@ QgsSymbolV2* QgsSymbolLayerV2Utils::loadSymbol( const QDomElement &element )
symbol->setMapUnitScale( mapUnitScale ); symbol->setMapUnitScale( mapUnitScale );
} }
symbol->setAlpha( element.attribute( "alpha", "1.0" ).toDouble() ); symbol->setAlpha( element.attribute( "alpha", "1.0" ).toDouble() );
symbol->setClipFeaturesToExtent( element.attribute( "clip_to_extent", "1" ).toInt() );
return symbol; return symbol;
} }
@ -993,6 +994,7 @@ QDomElement QgsSymbolLayerV2Utils::saveSymbol( QString name, QgsSymbolV2* symbol
symEl.setAttribute( "type", _nameForSymbolType( symbol->type() ) ); symEl.setAttribute( "type", _nameForSymbolType( symbol->type() ) );
symEl.setAttribute( "name", name ); symEl.setAttribute( "name", name );
symEl.setAttribute( "alpha", QString::number( symbol->alpha() ) ); symEl.setAttribute( "alpha", QString::number( symbol->alpha() ) );
symEl.setAttribute( "clip_to_extent", symbol->clipFeaturesToExtent() ? "1" : "0" );
QgsDebugMsg( "num layers " + QString::number( symbol->symbolLayerCount() ) ); QgsDebugMsg( "num layers " + QString::number( symbol->symbolLayerCount() ) );
for ( int i = 0; i < symbol->symbolLayerCount(); i++ ) for ( int i = 0; i < symbol->symbolLayerCount(); i++ )

View File

@ -40,6 +40,7 @@ QgsSymbolV2::QgsSymbolV2( SymbolType type, QgsSymbolLayerV2List layers )
, mLayers( layers ) , mLayers( layers )
, mAlpha( 1.0 ) , mAlpha( 1.0 )
, mRenderHints( 0 ) , mRenderHints( 0 )
, mClipFeaturesToExtent( true )
, mLayer( 0 ) , mLayer( 0 )
{ {
@ -631,6 +632,7 @@ QgsSymbolV2* QgsMarkerSymbolV2::clone() const
QgsSymbolV2* cloneSymbol = new QgsMarkerSymbolV2( cloneLayers() ); QgsSymbolV2* cloneSymbol = new QgsMarkerSymbolV2( cloneLayers() );
cloneSymbol->setAlpha( mAlpha ); cloneSymbol->setAlpha( mAlpha );
cloneSymbol->setLayer( mLayer ); cloneSymbol->setLayer( mLayer );
cloneSymbol->setClipFeaturesToExtent( mClipFeaturesToExtent );
return cloneSymbol; return cloneSymbol;
} }
@ -728,6 +730,7 @@ QgsSymbolV2* QgsLineSymbolV2::clone() const
QgsSymbolV2* cloneSymbol = new QgsLineSymbolV2( cloneLayers() ); QgsSymbolV2* cloneSymbol = new QgsLineSymbolV2( cloneLayers() );
cloneSymbol->setAlpha( mAlpha ); cloneSymbol->setAlpha( mAlpha );
cloneSymbol->setLayer( mLayer ); cloneSymbol->setLayer( mLayer );
cloneSymbol->setClipFeaturesToExtent( mClipFeaturesToExtent );
return cloneSymbol; return cloneSymbol;
} }
@ -834,6 +837,7 @@ QgsSymbolV2* QgsFillSymbolV2::clone() const
QgsSymbolV2* cloneSymbol = new QgsFillSymbolV2( cloneLayers() ); QgsSymbolV2* cloneSymbol = new QgsFillSymbolV2( cloneLayers() );
cloneSymbol->setAlpha( mAlpha ); cloneSymbol->setAlpha( mAlpha );
cloneSymbol->setLayer( mLayer ); cloneSymbol->setLayer( mLayer );
cloneSymbol->setClipFeaturesToExtent( mClipFeaturesToExtent );
return cloneSymbol; return cloneSymbol;
} }

View File

@ -161,6 +161,26 @@ class CORE_EXPORT QgsSymbolV2
void setRenderHints( int hints ) { mRenderHints = hints; } void setRenderHints( int hints ) { mRenderHints = hints; }
int renderHints() const { return mRenderHints; } int renderHints() const { return mRenderHints; }
/**Sets whether features drawn by the symbol should be clipped to the render context's
* extent. If this option is enabled then features which are partially outside the extent
* will be clipped. This speeds up rendering of the feature, but may have undesirable
* side effects for certain symbol types.
* @param clipFeaturesToExtent set to true to enable clipping (defaults to true)
* @note added in QGIS 2.9
* @see clipFeaturesToExtent
*/
void setClipFeaturesToExtent( bool clipFeaturesToExtent ) { mClipFeaturesToExtent = clipFeaturesToExtent; }
/**Returns whether features drawn by the symbol will be clipped to the render context's
* extent. If this option is enabled then features which are partially outside the extent
* will be clipped. This speeds up rendering of the feature, but may have undesirable
* side effects for certain symbol types.
* @returns true if features will be clipped
* @note added in QGIS 2.9
* @see setClipFeaturesToExtent
*/
double clipFeaturesToExtent() const { return mClipFeaturesToExtent; }
QSet<QString> usedAttributes() const; QSet<QString> usedAttributes() const;
void setLayer( const QgsVectorLayer* layer ) { mLayer = layer; } void setLayer( const QgsVectorLayer* layer ) { mLayer = layer; }
@ -182,6 +202,7 @@ class CORE_EXPORT QgsSymbolV2
qreal mAlpha; qreal mAlpha;
int mRenderHints; int mRenderHints;
bool mClipFeaturesToExtent;
const QgsVectorLayer* mLayer; //current vectorlayer const QgsVectorLayer* mLayer; //current vectorlayer

View File

@ -35,7 +35,10 @@
#include <QMenu> #include <QMenu>
QgsSymbolsListWidget::QgsSymbolsListWidget( QgsSymbolV2* symbol, QgsStyleV2* style, QMenu* menu, QWidget* parent ) : QWidget( parent ) QgsSymbolsListWidget::QgsSymbolsListWidget( QgsSymbolV2* symbol, QgsStyleV2* style, QMenu* menu, QWidget* parent )
: QWidget( parent )
, mAdvancedMenu( 0 )
, mClipFeaturesAction( 0 )
{ {
mSymbol = symbol; mSymbol = symbol;
mStyle = style; mStyle = style;
@ -47,9 +50,17 @@ QgsSymbolsListWidget::QgsSymbolsListWidget( QgsSymbolV2* symbol, QgsStyleV2* sty
btnAdvanced->hide(); // advanced button is hidden by default btnAdvanced->hide(); // advanced button is hidden by default
if ( menu ) // show it if there is a menu pointer if ( menu ) // show it if there is a menu pointer
{ {
btnAdvanced->setMenu( menu ); mAdvancedMenu = menu;
btnAdvanced->show(); btnAdvanced->show();
btnAdvanced->setMenu( mAdvancedMenu );
} }
else
{
btnAdvanced->setMenu( new QMenu( this ) );
}
mClipFeaturesAction = new QAction( tr( "Clip features to canvas extent" ), this );
mClipFeaturesAction->setCheckable( true );
connect( mClipFeaturesAction, SIGNAL( toggled( bool ) ), this, SLOT( clipFeaturesToggled( bool ) ) );
// populate the groups // populate the groups
groupsCombo->addItem( "" ); groupsCombo->addItem( "" );
@ -163,6 +174,15 @@ void QgsSymbolsListWidget::openStyleManager()
populateSymbolView(); populateSymbolView();
} }
void QgsSymbolsListWidget::clipFeaturesToggled( bool checked )
{
if ( !mSymbol )
return;
mSymbol->setClipFeaturesToExtent( checked );
emit changed();
}
void QgsSymbolsListWidget::setSymbolColor( const QColor& color ) void QgsSymbolsListWidget::setSymbolColor( const QColor& color )
{ {
mSymbol->setColor( color ); mSymbol->setColor( color );
@ -294,6 +314,21 @@ void QgsSymbolsListWidget::updateSymbolInfo()
mTransparencySlider->setValue( transparency * 255 ); mTransparencySlider->setValue( transparency * 255 );
displayTransparency( mSymbol->alpha() ); displayTransparency( mSymbol->alpha() );
mTransparencySlider->blockSignals( false ); mTransparencySlider->blockSignals( false );
if ( mSymbol->type() == QgsSymbolV2::Line || mSymbol->type() == QgsSymbolV2::Fill )
{
//add clip features option for line or fill symbols
btnAdvanced->menu()->addAction( mClipFeaturesAction );
}
else
{
btnAdvanced->menu()->removeAction( mClipFeaturesAction );
}
btnAdvanced->setVisible( mAdvancedMenu || !btnAdvanced->menu()->isEmpty() );
mClipFeaturesAction->blockSignals( true );
mClipFeaturesAction->setChecked( mSymbol->clipFeaturesToExtent() );
mClipFeaturesAction->blockSignals( false );
} }
void QgsSymbolsListWidget::setSymbolFromStyle( const QModelIndex & index ) void QgsSymbolsListWidget::setSymbolFromStyle( const QModelIndex & index )

View File

@ -47,6 +47,7 @@ class GUI_EXPORT QgsSymbolsListWidget : public QWidget, private Ui::SymbolsListW
void on_groupsCombo_editTextChanged( const QString &text ); void on_groupsCombo_editTextChanged( const QString &text );
void openStyleManager(); void openStyleManager();
void clipFeaturesToggled( bool checked );
signals: signals:
void changed(); void changed();
@ -54,6 +55,8 @@ class GUI_EXPORT QgsSymbolsListWidget : public QWidget, private Ui::SymbolsListW
protected: protected:
QgsSymbolV2* mSymbol; QgsSymbolV2* mSymbol;
QgsStyleV2* mStyle; QgsStyleV2* mStyle;
QMenu* mAdvancedMenu;
QAction* mClipFeaturesAction;
void populateSymbolView(); void populateSymbolView();
void populateSymbols( QStringList symbols ); void populateSymbols( QStringList symbols );

View File

@ -20,11 +20,17 @@
#include <QFileInfo> #include <QFileInfo>
//qgis includes... //qgis includes...
#include "qgsmultirenderchecker.h"
#include <qgsapplication.h> #include <qgsapplication.h>
#include "qgsconfig.h" #include "qgsconfig.h"
#include "qgslogger.h" #include "qgslogger.h"
#include "qgsvectorcolorrampv2.h" #include "qgsvectorcolorrampv2.h"
#include "qgscptcityarchive.h" #include "qgscptcityarchive.h"
#include "qgsvectorlayer.h"
#include "qgsmaplayerregistry.h"
#include "qgslinesymbollayerv2.h"
#include "qgsfillsymbollayerv2.h"
#include "qgssinglesymbolrendererv2.h"
#include "qgsstylev2.h" #include "qgsstylev2.h"
@ -40,10 +46,18 @@ class TestStyleV2 : public QObject
private: private:
QString mReport;
QgsStyleV2 *mStyle; QgsStyleV2 *mStyle;
QString mTestDataDir; QString mTestDataDir;
QgsMapSettings mMapSettings;
QgsVectorLayer * mpPointsLayer;
QgsVectorLayer * mpLinesLayer;
QgsVectorLayer * mpPolysLayer;
bool testValidColor( QgsVectorColorRampV2 *ramp, double value, QColor expected ); bool testValidColor( QgsVectorColorRampV2 *ramp, double value, QColor expected );
bool imageCheck( QgsMapSettings &ms, const QString &testName );
private slots: private slots:
@ -54,11 +68,14 @@ class TestStyleV2 : public QObject
void cleanup() {}// will be called after every testfunction. void cleanup() {}// will be called after every testfunction.
// void initStyles(); // void initStyles();
void testCanvasClip();
void testCreateColorRamps(); void testCreateColorRamps();
void testLoadColorRamps(); void testLoadColorRamps();
void testSaveLoad(); void testSaveLoad();
void testParseColor(); void testParseColor();
void testParseColorList(); void testParseColorList();
}; };
TestStyleV2::TestStyleV2() TestStyleV2::TestStyleV2()
@ -96,6 +113,44 @@ void TestStyleV2::initTestCase()
// cpt-city ramp, small selection available in <testdir>/cpt-city // cpt-city ramp, small selection available in <testdir>/cpt-city
QgsCptCityArchive::initArchives(); QgsCptCityArchive::initArchives();
//
//create a point layer that will be used in all tests...
//
QString myDataDir( TEST_DATA_DIR ); //defined in CmakeLists.txt
mTestDataDir = myDataDir + QDir::separator();
QString myPointsFileName = mTestDataDir + "points.shp";
QFileInfo myPointFileInfo( myPointsFileName );
mpPointsLayer = new QgsVectorLayer( myPointFileInfo.filePath(),
myPointFileInfo.completeBaseName(), "ogr" );
// Register the layer with the registry
QgsMapLayerRegistry::instance()->addMapLayers(
QList<QgsMapLayer *>() << mpPointsLayer );
//
//create a poly layer that will be used in all tests...
//
QString myPolysFileName = mTestDataDir + "polys.shp";
QFileInfo myPolyFileInfo( myPolysFileName );
mpPolysLayer = new QgsVectorLayer( myPolyFileInfo.filePath(),
myPolyFileInfo.completeBaseName(), "ogr" );
// Register the layer with the registry
QgsMapLayerRegistry::instance()->addMapLayers(
QList<QgsMapLayer *>() << mpPolysLayer );
//
// Create a line layer that will be used in all tests...
//
QString myLinesFileName = mTestDataDir + "lines.shp";
QFileInfo myLineFileInfo( myLinesFileName );
mpLinesLayer = new QgsVectorLayer( myLineFileInfo.filePath(),
myLineFileInfo.completeBaseName(), "ogr" );
// Register the layer with the registry
QgsMapLayerRegistry::instance()->addMapLayers(
QList<QgsMapLayer *>() << mpLinesLayer );
mReport += "<h1>StyleV2 Tests</h1>\n";
} }
void TestStyleV2::cleanupTestCase() void TestStyleV2::cleanupTestCase()
@ -104,6 +159,76 @@ void TestStyleV2::cleanupTestCase()
// mStyle->save(); // mStyle->save();
delete mStyle; delete mStyle;
QgsApplication::exitQgis(); QgsApplication::exitQgis();
QString myReportFile = QDir::tempPath() + QDir::separator() + "qgistest.html";
QFile myFile( myReportFile );
if ( myFile.open( QIODevice::WriteOnly | QIODevice::Append ) )
{
QTextStream myQTextStream( &myFile );
myQTextStream << mReport;
myFile.close();
//QDesktopServices::openUrl( "file:///" + myReportFile );
}
}
bool TestStyleV2::imageCheck( QgsMapSettings& ms, const QString& testName )
{
QgsMultiRenderChecker checker;
checker.setControlName( "expected_" + testName );
checker.setMapSettings( ms );
bool result = checker.runTest( testName, 0 );
mReport += checker.report();
return result;
}
void TestStyleV2::testCanvasClip()
{
//test rendering with and without clip to canvas enabled
QgsMapSettings ms;
QgsRectangle extent( -110.0, 25.0, -90, 40.0 );
ms.setExtent( extent );
ms.setFlag( QgsMapSettings::ForceVectorOutput );
//line
mReport += "<h2>Line canvas clip</h2>\n";
ms.setLayers( QStringList() << mpLinesLayer->id() );
QgsMarkerLineSymbolLayerV2* markerLine = new QgsMarkerLineSymbolLayerV2();
markerLine->setPlacement( QgsMarkerLineSymbolLayerV2:: CentralPoint );
QgsLineSymbolV2* lineSymbol = new QgsLineSymbolV2();
lineSymbol->changeSymbolLayer( 0, markerLine );
QgsSingleSymbolRendererV2* renderer = new QgsSingleSymbolRendererV2( lineSymbol );
mpLinesLayer->setRendererV2( renderer );
bool result;
lineSymbol->setClipFeaturesToExtent( true );
result = imageCheck( ms, "stylev2_linecanvasclip" );
QVERIFY( result );
lineSymbol->setClipFeaturesToExtent( false );
result = imageCheck( ms, "stylev2_linecanvasclip_off" );
QVERIFY( result );
//poly
mReport += "<h2>Polygon canvas clip</h2>\n";
ms.setLayers( QStringList() << mpPolysLayer->id() );
QgsCentroidFillSymbolLayerV2* centroidFill = new QgsCentroidFillSymbolLayerV2();
QgsFillSymbolV2* fillSymbol = new QgsFillSymbolV2();
fillSymbol->changeSymbolLayer( 0, centroidFill );
renderer = new QgsSingleSymbolRendererV2( fillSymbol );
mpPolysLayer->setRendererV2( renderer );
extent = QgsRectangle( -106.0, 29.0, -94, 36.0 );
ms.setExtent( extent );
fillSymbol->setClipFeaturesToExtent( true );
result = imageCheck( ms, "stylev2_polycanvasclip" );
QVERIFY( result );
fillSymbol->setClipFeaturesToExtent( false );
result = imageCheck( ms, "stylev2_polycanvasclip_off" );
QVERIFY( result );
} }
bool TestStyleV2::testValidColor( QgsVectorColorRampV2 *ramp, double value, QColor expected ) bool TestStyleV2::testValidColor( QgsVectorColorRampV2 *ramp, double value, QColor expected )

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB