Expand Up
@@ -41,6 +41,7 @@ class TestQgsLabelingEngineV2 : public QObject
void testBasic ();
void testDiagrams ();
void testRuleBased ();
void zOrder (); // test that labels are stacked correctly
private:
QgsVectorLayer* vl;
Expand Down
Expand Up
@@ -266,9 +267,124 @@ void TestQgsLabelingEngineV2::testRuleBased()
engine.setMapSettings( mapSettings );
engine.addProvider( new QgsRuleBasedLabelProvider( , vl ) );
engine.run( context );*/
}
void TestQgsLabelingEngineV2::zOrder ()
{
QSize size ( 640 , 480 );
QgsMapSettings mapSettings;
mapSettings.setOutputSize ( size );
mapSettings.setExtent ( vl->extent () );
mapSettings.setLayers ( QStringList () << vl->id () );
mapSettings.setOutputDpi ( 96 );
QgsMapRendererSequentialJob job ( mapSettings );
job.start ();
job.waitForFinished ();
QImage img = job.renderedImage ();
QPainter p ( &img );
QgsRenderContext context = QgsRenderContext::fromMapSettings ( mapSettings );
context.setPainter ( &p );
QgsPalLayerSettings pls1;
pls1.enabled = true ;
pls1.fieldName = " Class" ;
pls1.placement = QgsPalLayerSettings::OverPoint;
pls1.quadOffset = QgsPalLayerSettings::QuadrantAboveRight;
pls1.displayAll = true ;
pls1.textFont = QgsFontUtils::getStandardTestFont ( " Bold" );
pls1.textFont .setPointSizeF ( 70 );
// use data defined coloring and font size so that stacking order of labels can be determined
pls1.setDataDefinedProperty ( QgsPalLayerSettings::Color, true , true , " case when \" Class\" ='Jet' then '#ff5500' when \" Class\" ='B52' then '#00ffff' else '#ff00ff' end" , QString () );
pls1.setDataDefinedProperty ( QgsPalLayerSettings::Size , true , true , " case when \" Class\" ='Jet' then 100 when \" Class\" ='B52' then 30 else 50 end" , QString () );
QgsVectorLayerLabelProvider* provider1 = new QgsVectorLayerLabelProvider ( vl, true , &pls1 );
QgsLabelingEngineV2 engine;
engine.setMapSettings ( mapSettings );
engine.addProvider ( provider1 );
// engine.setFlags( QgsLabelingEngineV2::RenderOutlineLabels | QgsLabelingEngineV2::DrawLabelRectOnly );
engine.run ( context );
p.end ();
engine.removeProvider ( provider1 );
// since labels are all from same layer and have same z-index then smaller labels should be stacked on top of larger
// labels. Eg: B52 > Biplane > Jet
QVERIFY ( imageCheck ( " label_order_size" , img, 0 ) );
img = job.renderedImage ();
// test data defined z-index
pls1.setDataDefinedProperty ( QgsPalLayerSettings::ZIndex, true , true , " case when \" Class\" ='Jet' then 3 when \" Class\" ='B52' then 1 else 2 end" , QString () );
provider1 = new QgsVectorLayerLabelProvider ( vl, true , &pls1 );
engine.addProvider ( provider1 );
p.begin ( &img );
engine.run ( context );
p.end ();
engine.removeProvider ( provider1 );
// z-index will take preference over label size, so labels should be stacked Jet > Biplane > B52
QVERIFY ( imageCheck ( " label_order_zindex" , img, 0 ) );
img = job.renderedImage ();
pls1.removeAllDataDefinedProperties ();
pls1.textColor = QColor ( 255 , 50 , 100 );
pls1.textFont .setPointSizeF ( 30 );
provider1 = new QgsVectorLayerLabelProvider ( vl, true , &pls1 );
engine.addProvider ( provider1 );
// add a second layer
QString filename = QString ( TEST_DATA_DIR ) + " /points.shp" ;
QgsVectorLayer* vl2 = new QgsVectorLayer ( filename, " points" , " ogr" );
Q_ASSERT ( vl2->isValid () );
QgsMapLayerRegistry::instance ()->addMapLayer ( vl2 );
QgsPalLayerSettings pls2 ( pls1 );
pls2.textColor = QColor ( 0 , 0 , 0 );
QgsVectorLayerLabelProvider* provider2 = new QgsVectorLayerLabelProvider ( vl2, true , &pls2 );
engine.addProvider ( provider2 );
mapSettings.setLayers ( QStringList () << vl->id () << vl2->id () );
engine.setMapSettings ( mapSettings );
p.begin ( &img );
engine.run ( context );
p.end ();
// labels have same z-index, so layer order will be used
QVERIFY ( imageCheck ( " label_order_layer1" , img, 0 ) );
img = job.renderedImage ();
// flip layer order and re-test
mapSettings.setLayers ( QStringList () << vl2->id () << vl->id () );
engine.setMapSettings ( mapSettings );
p.begin ( &img );
engine.run ( context );
p.end ();
// label order should be reversed
QVERIFY ( imageCheck ( " label_order_layer2" , img, 0 ) );
img = job.renderedImage ();
// try mixing layer order and z-index
engine.removeProvider ( provider1 );
pls1.setDataDefinedProperty ( QgsPalLayerSettings::ZIndex, true , true , " if(\" Class\" ='Jet',3,0)" , QString () );
provider1 = new QgsVectorLayerLabelProvider ( vl, true , &pls1 );
engine.addProvider ( provider1 );
p.begin ( &img );
engine.run ( context );
p.end ();
// label order should be most labels from layer 1, then labels from layer 2, then "Jet"s from layer 1
QVERIFY ( imageCheck ( " label_order_mixed" , img, 0 ) );
img = job.renderedImage ();
// cleanup
QgsMapLayerRegistry::instance ()->removeMapLayer ( vl2 );
}
bool TestQgsLabelingEngineV2::imageCheck ( const QString& testName, QImage &image, int mismatchCount )
{
// draw background
Expand Down