2 changes: 0 additions & 2 deletions src/core/qgsvectorlayerlabelprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@ class CORE_EXPORT QgsVectorLayerLabelProvider : public QgsAbstractLabelProvider
protected:
//! Layer's labeling configuration
QgsPalLayerSettings mSettings;
//! Layer's ID
QString mLayerId;
//! Geometry type of layer
QGis::GeometryType mLayerGeometryType;

Expand Down
320 changes: 179 additions & 141 deletions src/ui/qgsdiagrampropertiesbase.ui

Large diffs are not rendered by default.

598 changes: 512 additions & 86 deletions src/ui/qgslabelingguibase.ui

Large diffs are not rendered by default.

116 changes: 116 additions & 0 deletions tests/src/core/testqgslabelingenginev2.cpp
Original file line number Diff line number Diff line change
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.