mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
591 lines
22 KiB
C++
591 lines
22 KiB
C++
/***************************************************************************
|
|
testqgslabelingengine.cpp
|
|
--------------------------------------
|
|
Date : September 2015
|
|
Copyright : (C) 2015 by Martin Dobias
|
|
Email : wonder dot sk at gmail dot com
|
|
***************************************************************************
|
|
* *
|
|
* 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. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "qgstest.h"
|
|
|
|
#include <qgsapplication.h>
|
|
#include <qgslabelingengine.h>
|
|
#include <qgsproject.h>
|
|
#include <qgsmaprenderersequentialjob.h>
|
|
#include <qgsreadwritecontext.h>
|
|
#include <qgsrulebasedlabeling.h>
|
|
#include <qgsvectorlayer.h>
|
|
#include <qgsvectorlayerdiagramprovider.h>
|
|
#include <qgsvectorlayerlabeling.h>
|
|
#include <qgsvectorlayerlabelprovider.h>
|
|
#include "qgsrenderchecker.h"
|
|
#include "qgsfontutils.h"
|
|
|
|
class TestQgsLabelingEngine : public QObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
TestQgsLabelingEngine() : vl( 0 ) {}
|
|
|
|
private slots:
|
|
void initTestCase();
|
|
void cleanupTestCase();
|
|
void init();// will be called before each testfunction is executed.
|
|
void cleanup();// will be called after every testfunction.
|
|
void testBasic();
|
|
void testDiagrams();
|
|
void testRuleBased();
|
|
void zOrder(); //test that labels are stacked correctly
|
|
void testEncodeDecodePositionOrder();
|
|
void testSubstitutions();
|
|
void testCapitalization();
|
|
void testParticipatingLayers();
|
|
|
|
private:
|
|
QgsVectorLayer *vl = nullptr;
|
|
|
|
QString mReport;
|
|
|
|
void setDefaultLabelParams( QgsPalLayerSettings &settings );
|
|
bool imageCheck( const QString &testName, QImage &image, int mismatchCount );
|
|
|
|
};
|
|
|
|
void TestQgsLabelingEngine::initTestCase()
|
|
{
|
|
mReport += QLatin1String( "<h1>Labeling Engine Tests</h1>\n" );
|
|
|
|
QgsApplication::init();
|
|
QgsApplication::initQgis();
|
|
QgsApplication::showSettings();
|
|
QgsFontUtils::loadStandardTestFonts( QStringList() << QStringLiteral( "Bold" ) );
|
|
}
|
|
|
|
void TestQgsLabelingEngine::cleanupTestCase()
|
|
{
|
|
QgsApplication::exitQgis();
|
|
QString myReportFile = QDir::tempPath() + "/qgistest.html";
|
|
QFile myFile( myReportFile );
|
|
if ( myFile.open( QIODevice::WriteOnly | QIODevice::Append ) )
|
|
{
|
|
QTextStream myQTextStream( &myFile );
|
|
myQTextStream << mReport;
|
|
myFile.close();
|
|
}
|
|
}
|
|
|
|
void TestQgsLabelingEngine::init()
|
|
{
|
|
QString filename = QStringLiteral( TEST_DATA_DIR ) + "/points.shp";
|
|
vl = new QgsVectorLayer( filename, QStringLiteral( "points" ), QStringLiteral( "ogr" ) );
|
|
Q_ASSERT( vl->isValid() );
|
|
QgsProject::instance()->addMapLayer( vl );
|
|
}
|
|
|
|
void TestQgsLabelingEngine::cleanup()
|
|
{
|
|
QgsProject::instance()->removeMapLayer( vl->id() );
|
|
vl = 0;
|
|
}
|
|
|
|
void TestQgsLabelingEngine::setDefaultLabelParams( QgsPalLayerSettings &settings )
|
|
{
|
|
QgsTextFormat format;
|
|
format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ).family() );
|
|
format.setSize( 12 );
|
|
format.setNamedStyle( "Bold" );
|
|
format.setColor( QColor( 200, 0, 200 ) );
|
|
settings.setFormat( format );
|
|
}
|
|
|
|
void TestQgsLabelingEngine::testBasic()
|
|
{
|
|
QSize size( 640, 480 );
|
|
QgsMapSettings mapSettings;
|
|
mapSettings.setOutputSize( size );
|
|
mapSettings.setExtent( vl->extent() );
|
|
mapSettings.setLayers( QList<QgsMapLayer *>() << vl );
|
|
mapSettings.setOutputDpi( 96 );
|
|
|
|
// first render the map and labeling separately
|
|
|
|
QgsMapRendererSequentialJob job( mapSettings );
|
|
job.start();
|
|
job.waitForFinished();
|
|
|
|
QImage img = job.renderedImage();
|
|
|
|
QPainter p( &img );
|
|
QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings );
|
|
context.setPainter( &p );
|
|
|
|
QgsPalLayerSettings settings;
|
|
settings.fieldName = "Class";
|
|
setDefaultLabelParams( settings );
|
|
|
|
vl->setLabeling( new QgsVectorLayerSimpleLabeling( settings ) ); // TODO: this should not be necessary!
|
|
|
|
QgsLabelingEngine engine;
|
|
engine.setMapSettings( mapSettings );
|
|
engine.addProvider( new QgsVectorLayerLabelProvider( vl, QString(), true, &settings ) );
|
|
//engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::DrawLabelRectOnly );
|
|
engine.run( context );
|
|
|
|
p.end();
|
|
|
|
QVERIFY( imageCheck( "labeling_basic", img, 20 ) );
|
|
|
|
// now let's test the variant when integrated into rendering loop
|
|
//note the reference images are slightly different due to use of renderer for this test
|
|
|
|
job.start();
|
|
job.waitForFinished();
|
|
QImage img2 = job.renderedImage();
|
|
|
|
vl->setLabeling( nullptr );
|
|
|
|
QVERIFY( imageCheck( "labeling_basic", img2, 20 ) );
|
|
}
|
|
|
|
|
|
void TestQgsLabelingEngine::testDiagrams()
|
|
{
|
|
QSize size( 640, 480 );
|
|
QgsMapSettings mapSettings;
|
|
mapSettings.setOutputSize( size );
|
|
mapSettings.setExtent( vl->extent() );
|
|
mapSettings.setLayers( QList<QgsMapLayer *>() << vl );
|
|
mapSettings.setOutputDpi( 96 );
|
|
|
|
// first render the map and diagrams separately
|
|
|
|
QgsMapRendererSequentialJob job( mapSettings );
|
|
job.start();
|
|
job.waitForFinished();
|
|
|
|
QImage img = job.renderedImage();
|
|
|
|
QPainter p( &img );
|
|
QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings );
|
|
context.setPainter( &p );
|
|
|
|
bool res;
|
|
vl->loadNamedStyle( QStringLiteral( TEST_DATA_DIR ) + "/points_diagrams.qml", res );
|
|
Q_ASSERT( res );
|
|
|
|
QgsLabelingEngine engine;
|
|
engine.setMapSettings( mapSettings );
|
|
engine.addProvider( new QgsVectorLayerDiagramProvider( vl ) );
|
|
engine.run( context );
|
|
|
|
p.end();
|
|
|
|
QVERIFY( imageCheck( "labeling_point_diagrams", img, 20 ) );
|
|
|
|
// now let's test the variant when integrated into rendering loop
|
|
job.start();
|
|
job.waitForFinished();
|
|
QImage img2 = job.renderedImage();
|
|
|
|
vl->loadDefaultStyle( res );
|
|
QVERIFY( imageCheck( "labeling_point_diagrams", img2, 20 ) );
|
|
}
|
|
|
|
|
|
void TestQgsLabelingEngine::testRuleBased()
|
|
{
|
|
QSize size( 640, 480 );
|
|
QgsMapSettings mapSettings;
|
|
mapSettings.setOutputSize( size );
|
|
mapSettings.setExtent( vl->extent() );
|
|
mapSettings.setLayers( QList<QgsMapLayer *>() << vl );
|
|
mapSettings.setOutputDpi( 96 );
|
|
|
|
// set up most basic rule-based labeling for layer
|
|
QgsRuleBasedLabeling::Rule *root = new QgsRuleBasedLabeling::Rule( 0 );
|
|
|
|
QgsPalLayerSettings s1;
|
|
s1.fieldName = QStringLiteral( "Class" );
|
|
s1.obstacle = false;
|
|
s1.dist = 2;
|
|
s1.distInMapUnits = false;
|
|
QgsTextFormat format = s1.format();
|
|
format.setColor( QColor( 200, 0, 200 ) );
|
|
format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ) );
|
|
format.setSize( 12 );
|
|
s1.setFormat( format );
|
|
s1.placement = QgsPalLayerSettings::OverPoint;
|
|
s1.quadOffset = QgsPalLayerSettings::QuadrantAboveLeft;
|
|
s1.displayAll = true;
|
|
|
|
root->appendChild( new QgsRuleBasedLabeling::Rule( new QgsPalLayerSettings( s1 ) ) );
|
|
|
|
QgsPalLayerSettings s2;
|
|
s2.fieldName = QStringLiteral( "Class" );
|
|
s2.obstacle = false;
|
|
s2.dist = 2;
|
|
format = s2.format();
|
|
format.setColor( Qt::red );
|
|
format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ) );
|
|
s2.setFormat( format );
|
|
s2.placement = QgsPalLayerSettings::OverPoint;
|
|
s2.quadOffset = QgsPalLayerSettings::QuadrantBelowRight;
|
|
s2.displayAll = true;
|
|
|
|
s2.dataDefinedProperties().setProperty( QgsPalLayerSettings::Size, QgsProperty::fromValue( QStringLiteral( "18" ) ) );
|
|
|
|
root->appendChild( new QgsRuleBasedLabeling::Rule( new QgsPalLayerSettings( s2 ), 0, 0, QStringLiteral( "Class = 'Jet'" ) ) );
|
|
|
|
vl->setLabeling( new QgsRuleBasedLabeling( root ) );
|
|
//setDefaultLabelParams( vl );
|
|
|
|
QgsMapRendererSequentialJob job( mapSettings );
|
|
job.start();
|
|
job.waitForFinished();
|
|
QImage img = job.renderedImage();
|
|
QVERIFY( imageCheck( "labeling_rulebased", img, 20 ) );
|
|
|
|
// test read/write rules
|
|
QDomDocument doc, doc2, doc3;
|
|
QDomElement e = vl->labeling()->save( doc, QgsReadWriteContext() );
|
|
doc.appendChild( e );
|
|
// read saved rules
|
|
doc2.setContent( doc.toString() );
|
|
QDomElement e2 = doc2.documentElement();
|
|
QgsRuleBasedLabeling *rl2 = QgsRuleBasedLabeling::create( e2, QgsReadWriteContext() );
|
|
QVERIFY( rl2 );
|
|
// check that another save will keep the data the same
|
|
QDomElement e3 = rl2->save( doc3, QgsReadWriteContext() );
|
|
doc3.appendChild( e3 );
|
|
QCOMPARE( doc.toString(), doc3.toString() );
|
|
|
|
vl->setLabeling( nullptr );
|
|
|
|
delete rl2;
|
|
|
|
#if 0
|
|
QPainter p( &img );
|
|
QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings );
|
|
context.setPainter( &p );
|
|
|
|
QgsLabelingEngine engine;
|
|
engine.setMapSettings( mapSettings );
|
|
engine.addProvider( new QgsRuleBasedLabelProvider(, vl ) );
|
|
engine.run( context );
|
|
#endif
|
|
}
|
|
|
|
void TestQgsLabelingEngine::zOrder()
|
|
{
|
|
QSize size( 640, 480 );
|
|
QgsMapSettings mapSettings;
|
|
mapSettings.setOutputSize( size );
|
|
mapSettings.setExtent( vl->extent() );
|
|
mapSettings.setLayers( QList<QgsMapLayer *>() << vl );
|
|
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.fieldName = QStringLiteral( "Class" );
|
|
pls1.placement = QgsPalLayerSettings::OverPoint;
|
|
pls1.quadOffset = QgsPalLayerSettings::QuadrantAboveRight;
|
|
pls1.displayAll = true;
|
|
QgsTextFormat format = pls1.format();
|
|
format.setFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ) );
|
|
format.setSize( 70 );
|
|
pls1.setFormat( format );
|
|
|
|
//use data defined coloring and font size so that stacking order of labels can be determined
|
|
pls1.dataDefinedProperties().setProperty( QgsPalLayerSettings::Color, QgsProperty::fromExpression( QStringLiteral( "case when \"Class\"='Jet' then '#ff5500' when \"Class\"='B52' then '#00ffff' else '#ff00ff' end" ) ) );
|
|
pls1.dataDefinedProperties().setProperty( QgsPalLayerSettings::Size, QgsProperty::fromExpression( QStringLiteral( "case when \"Class\"='Jet' then 100 when \"Class\"='B52' then 30 else 50 end" ) ) );
|
|
|
|
QgsVectorLayerLabelProvider *provider1 = new QgsVectorLayerLabelProvider( vl, QString(), true, &pls1 );
|
|
QgsLabelingEngine engine;
|
|
engine.setMapSettings( mapSettings );
|
|
engine.addProvider( provider1 );
|
|
//engine.setFlags( QgsLabelingEngine::RenderOutlineLabels | QgsLabelingEngine::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. For example: B52 > Biplane > Jet
|
|
QVERIFY( imageCheck( "label_order_size", img, 20 ) );
|
|
img = job.renderedImage();
|
|
|
|
//test data defined z-index
|
|
pls1.dataDefinedProperties().setProperty( QgsPalLayerSettings::ZIndex, QgsProperty::fromExpression( QStringLiteral( "case when \"Class\"='Jet' then 3 when \"Class\"='B52' then 1 else 2 end" ) ) );
|
|
provider1 = new QgsVectorLayerLabelProvider( vl, QString(), 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, 20 ) );
|
|
img = job.renderedImage();
|
|
|
|
pls1.dataDefinedProperties().clear();
|
|
format = pls1.format();
|
|
format.setColor( QColor( 255, 50, 100 ) );
|
|
format.setSize( 30 );
|
|
pls1.setFormat( format );
|
|
provider1 = new QgsVectorLayerLabelProvider( vl, QString(), true, &pls1 );
|
|
engine.addProvider( provider1 );
|
|
|
|
//add a second layer
|
|
QString filename = QStringLiteral( TEST_DATA_DIR ) + "/points.shp";
|
|
QgsVectorLayer *vl2 = new QgsVectorLayer( filename, QStringLiteral( "points" ), QStringLiteral( "ogr" ) );
|
|
Q_ASSERT( vl2->isValid() );
|
|
QgsProject::instance()->addMapLayer( vl2 );
|
|
|
|
QgsPalLayerSettings pls2( pls1 );
|
|
format = pls2.format();
|
|
format.setColor( QColor( 0, 0, 0 ) );
|
|
pls2.setFormat( format );
|
|
QgsVectorLayerLabelProvider *provider2 = new QgsVectorLayerLabelProvider( vl2, QString(), true, &pls2 );
|
|
engine.addProvider( provider2 );
|
|
|
|
mapSettings.setLayers( QList<QgsMapLayer *>() << vl << vl2 );
|
|
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, 20 ) );
|
|
img = job.renderedImage();
|
|
|
|
//flip layer order and re-test
|
|
mapSettings.setLayers( QList<QgsMapLayer *>() << vl2 << vl );
|
|
engine.setMapSettings( mapSettings );
|
|
p.begin( &img );
|
|
engine.run( context );
|
|
p.end();
|
|
|
|
// label order should be reversed
|
|
QVERIFY( imageCheck( "label_order_layer2", img, 20 ) );
|
|
img = job.renderedImage();
|
|
|
|
//try mixing layer order and z-index
|
|
engine.removeProvider( provider1 );
|
|
pls1.dataDefinedProperties().setProperty( QgsPalLayerSettings::ZIndex, QgsProperty::fromExpression( QStringLiteral( "if(\"Class\"='Jet',3,0)" ) ) );
|
|
provider1 = new QgsVectorLayerLabelProvider( vl, QString(), 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, 20 ) );
|
|
img = job.renderedImage();
|
|
|
|
//cleanup
|
|
QgsProject::instance()->removeMapLayer( vl2 );
|
|
}
|
|
|
|
void TestQgsLabelingEngine::testEncodeDecodePositionOrder()
|
|
{
|
|
//create an ordered position list
|
|
QVector< QgsPalLayerSettings::PredefinedPointPosition > original;
|
|
//make sure all placements are added here
|
|
original << QgsPalLayerSettings::BottomLeft << QgsPalLayerSettings::BottomSlightlyLeft
|
|
<< QgsPalLayerSettings::BottomMiddle << QgsPalLayerSettings::BottomSlightlyRight
|
|
<< QgsPalLayerSettings::BottomRight << QgsPalLayerSettings::MiddleRight
|
|
<< QgsPalLayerSettings::MiddleLeft << QgsPalLayerSettings::TopLeft
|
|
<< QgsPalLayerSettings::TopSlightlyLeft << QgsPalLayerSettings::TopMiddle
|
|
<< QgsPalLayerSettings::TopSlightlyRight << QgsPalLayerSettings::TopRight;
|
|
//encode list
|
|
QString encoded = QgsLabelingUtils::encodePredefinedPositionOrder( original );
|
|
QVERIFY( !encoded.isEmpty() );
|
|
|
|
//decode
|
|
QVector< QgsPalLayerSettings::PredefinedPointPosition > decoded = QgsLabelingUtils::decodePredefinedPositionOrder( encoded );
|
|
QCOMPARE( decoded, original );
|
|
|
|
//test decoding with a messy string
|
|
decoded = QgsLabelingUtils::decodePredefinedPositionOrder( QStringLiteral( ",tr,x,BSR, L, t,," ) );
|
|
QVector< QgsPalLayerSettings::PredefinedPointPosition > expected;
|
|
expected << QgsPalLayerSettings::TopRight << QgsPalLayerSettings::BottomSlightlyRight
|
|
<< QgsPalLayerSettings::MiddleLeft << QgsPalLayerSettings::TopMiddle;
|
|
QCOMPARE( decoded, expected );
|
|
}
|
|
|
|
void TestQgsLabelingEngine::testSubstitutions()
|
|
{
|
|
QgsPalLayerSettings settings;
|
|
settings.useSubstitutions = false;
|
|
QgsStringReplacementCollection collection( QList< QgsStringReplacement >() << QgsStringReplacement( QStringLiteral( "aa" ), QStringLiteral( "bb" ) ) );
|
|
settings.substitutions = collection;
|
|
settings.fieldName = QStringLiteral( "'aa label'" );
|
|
settings.isExpression = true;
|
|
|
|
QgsVectorLayerLabelProvider *provider = new QgsVectorLayerLabelProvider( vl, QStringLiteral( "test" ), true, &settings );
|
|
QgsFeature f( vl->fields(), 1 );
|
|
f.setGeometry( QgsGeometry::fromPoint( QgsPoint( 1, 2 ) ) );
|
|
|
|
// make a fake render context
|
|
QSize size( 640, 480 );
|
|
QgsMapSettings mapSettings;
|
|
mapSettings.setOutputSize( size );
|
|
mapSettings.setExtent( vl->extent() );
|
|
mapSettings.setLayers( QList<QgsMapLayer *>() << vl );
|
|
mapSettings.setOutputDpi( 96 );
|
|
QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings );
|
|
QSet<QString> attributes;
|
|
QgsLabelingEngine engine;
|
|
engine.setMapSettings( mapSettings );
|
|
engine.addProvider( provider );
|
|
provider->prepare( context, attributes );
|
|
|
|
provider->registerFeature( f, context );
|
|
QCOMPARE( provider->mLabels.at( 0 )->labelText(), QString( "aa label" ) );
|
|
|
|
//with substitution
|
|
settings.useSubstitutions = true;
|
|
QgsVectorLayerLabelProvider *provider2 = new QgsVectorLayerLabelProvider( vl, QStringLiteral( "test2" ), true, &settings );
|
|
engine.addProvider( provider2 );
|
|
provider2->prepare( context, attributes );
|
|
|
|
provider2->registerFeature( f, context );
|
|
QCOMPARE( provider2->mLabels.at( 0 )->labelText(), QString( "bb label" ) );
|
|
}
|
|
|
|
void TestQgsLabelingEngine::testCapitalization()
|
|
{
|
|
QgsFeature f( vl->fields(), 1 );
|
|
f.setGeometry( QgsGeometry::fromPoint( QgsPoint( 1, 2 ) ) );
|
|
|
|
// make a fake render context
|
|
QSize size( 640, 480 );
|
|
QgsMapSettings mapSettings;
|
|
mapSettings.setOutputSize( size );
|
|
mapSettings.setExtent( vl->extent() );
|
|
mapSettings.setLayers( QList<QgsMapLayer *>() << vl );
|
|
mapSettings.setOutputDpi( 96 );
|
|
QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings );
|
|
QSet<QString> attributes;
|
|
QgsLabelingEngine engine;
|
|
engine.setMapSettings( mapSettings );
|
|
|
|
// no change
|
|
QgsPalLayerSettings settings;
|
|
QgsTextFormat format = settings.format();
|
|
QFont font = format.font();
|
|
font.setCapitalization( QFont::MixedCase );
|
|
format.setFont( font );
|
|
settings.setFormat( format );
|
|
settings.fieldName = QStringLiteral( "'a teSt LABEL'" );
|
|
settings.isExpression = true;
|
|
|
|
QgsVectorLayerLabelProvider *provider = new QgsVectorLayerLabelProvider( vl, QStringLiteral( "test" ), true, &settings );
|
|
engine.addProvider( provider );
|
|
provider->prepare( context, attributes );
|
|
provider->registerFeature( f, context );
|
|
QCOMPARE( provider->mLabels.at( 0 )->labelText(), QString( "a teSt LABEL" ) );
|
|
|
|
//uppercase
|
|
font.setCapitalization( QFont::AllUppercase );
|
|
format.setFont( font );
|
|
settings.setFormat( format );
|
|
QgsVectorLayerLabelProvider *provider2 = new QgsVectorLayerLabelProvider( vl, QStringLiteral( "test2" ), true, &settings );
|
|
engine.addProvider( provider2 );
|
|
provider2->prepare( context, attributes );
|
|
provider2->registerFeature( f, context );
|
|
QCOMPARE( provider2->mLabels.at( 0 )->labelText(), QString( "A TEST LABEL" ) );
|
|
|
|
//lowercase
|
|
font.setCapitalization( QFont::AllLowercase );
|
|
format.setFont( font );
|
|
settings.setFormat( format );
|
|
QgsVectorLayerLabelProvider *provider3 = new QgsVectorLayerLabelProvider( vl, QStringLiteral( "test3" ), true, &settings );
|
|
engine.addProvider( provider3 );
|
|
provider3->prepare( context, attributes );
|
|
provider3->registerFeature( f, context );
|
|
QCOMPARE( provider3->mLabels.at( 0 )->labelText(), QString( "a test label" ) );
|
|
|
|
//first letter uppercase
|
|
font.setCapitalization( QFont::Capitalize );
|
|
format.setFont( font );
|
|
settings.setFormat( format );
|
|
QgsVectorLayerLabelProvider *provider4 = new QgsVectorLayerLabelProvider( vl, QStringLiteral( "test4" ), true, &settings );
|
|
engine.addProvider( provider4 );
|
|
provider4->prepare( context, attributes );
|
|
provider4->registerFeature( f, context );
|
|
QCOMPARE( provider4->mLabels.at( 0 )->labelText(), QString( "A TeSt LABEL" ) );
|
|
}
|
|
|
|
void TestQgsLabelingEngine::testParticipatingLayers()
|
|
{
|
|
QgsLabelingEngine engine;
|
|
QVERIFY( engine.participatingLayers().isEmpty() );
|
|
|
|
QgsPalLayerSettings settings1;
|
|
QgsVectorLayerLabelProvider *provider = new QgsVectorLayerLabelProvider( vl, QStringLiteral( "test" ), true, &settings1 );
|
|
engine.addProvider( provider );
|
|
QCOMPARE( engine.participatingLayers(), QList<QgsMapLayer *>() << vl );
|
|
|
|
QgsVectorLayer *layer2 = new QgsVectorLayer( QStringLiteral( "Point?field=col1:integer" ), QStringLiteral( "layer2" ), QStringLiteral( "memory" ) );
|
|
QgsPalLayerSettings settings2;
|
|
QgsVectorLayerLabelProvider *provider2 = new QgsVectorLayerLabelProvider( layer2, QStringLiteral( "test2" ), true, &settings2 );
|
|
engine.addProvider( provider2 );
|
|
QCOMPARE( engine.participatingLayers().toSet(), QSet< QgsMapLayer * >() << vl << layer2 );
|
|
|
|
// add a rule-based labeling node
|
|
QgsRuleBasedLabeling::Rule *root = new QgsRuleBasedLabeling::Rule( 0 );
|
|
QgsPalLayerSettings s1;
|
|
root->appendChild( new QgsRuleBasedLabeling::Rule( new QgsPalLayerSettings( s1 ) ) );
|
|
QgsPalLayerSettings s2;
|
|
root->appendChild( new QgsRuleBasedLabeling::Rule( new QgsPalLayerSettings( s2 ) ) );
|
|
|
|
QgsVectorLayer *layer3 = new QgsVectorLayer( QStringLiteral( "Point?field=col1:integer" ), QStringLiteral( "layer3" ), QStringLiteral( "memory" ) );
|
|
QgsRuleBasedLabelProvider *ruleProvider = new QgsRuleBasedLabelProvider( QgsRuleBasedLabeling( root ), layer3 );
|
|
engine.addProvider( ruleProvider );
|
|
QCOMPARE( engine.participatingLayers().toSet(), QSet< QgsMapLayer * >() << vl << layer2 << layer3 );
|
|
}
|
|
|
|
bool TestQgsLabelingEngine::imageCheck( const QString &testName, QImage &image, int mismatchCount )
|
|
{
|
|
//draw background
|
|
QImage imageWithBackground( image.width(), image.height(), QImage::Format_RGB32 );
|
|
QgsRenderChecker::drawBackground( &imageWithBackground );
|
|
QPainter painter( &imageWithBackground );
|
|
painter.drawImage( 0, 0, image );
|
|
painter.end();
|
|
|
|
mReport += "<h2>" + testName + "</h2>\n";
|
|
QString tempDir = QDir::tempPath() + '/';
|
|
QString fileName = tempDir + testName + ".png";
|
|
imageWithBackground.save( fileName, "PNG" );
|
|
QgsRenderChecker checker;
|
|
checker.setControlPathPrefix( QStringLiteral( "labelingengine" ) );
|
|
checker.setControlName( "expected_" + testName );
|
|
checker.setRenderedImage( fileName );
|
|
checker.setColorTolerance( 2 );
|
|
bool resultFlag = checker.compareImages( testName, mismatchCount );
|
|
mReport += checker.report();
|
|
return resultFlag;
|
|
}
|
|
|
|
QGSTEST_MAIN( TestQgsLabelingEngine )
|
|
#include "testqgslabelingengine.moc"
|