Skip to content

Commit f19a35c

Browse files
committedApr 13, 2016
dxf export: support rule based labeling (fixes #13757)
1 parent b7a4e20 commit f19a35c

15 files changed

+264
-166
lines changed
 

‎python/core/qgsmaprenderer.sip

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class QgsLabelingEngineInterface
3535

3636
//! called when we're going to start with rendering
3737
//! @deprecated since 2.4 - use override with QgsMapSettings
38-
virtual void init( QgsMapRenderer* mp ) = 0 /Deprecated/;
38+
virtual void init( QgsMapRenderer *mp ) = 0 /Deprecated/;
3939
//! called when we're going to start with rendering
4040
virtual void init( const QgsMapSettings& mapSettings ) = 0;
4141
//! called to find out whether the layer is used for labeling
@@ -48,17 +48,17 @@ class QgsLabelingEngineInterface
4848
virtual int prepareLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx ) = 0;
4949
//! returns PAL layer settings for a registered layer
5050
//! @deprecated since 2.12 - if direct access to QgsPalLayerSettings is necessary, use QgsPalLayerSettings::fromLayer()
51-
virtual QgsPalLayerSettings& layer( const QString& layerName ) = 0 /Deprecated/;
51+
virtual QgsPalLayerSettings &layer( const QString &layerName ) = 0 /Deprecated/;
5252
//! adds a diagram layer to the labeling engine
5353
//! @note added in QGIS 2.12
54-
virtual int prepareDiagramLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx );
54+
virtual int prepareDiagramLayer( QgsVectorLayer *layer, QStringList &attrNames, QgsRenderContext &ctx );
5555
//! adds a diagram layer to the labeling engine
5656
//! @deprecated since 2.12 - use prepareDiagramLayer()
57-
virtual int addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLayerSettings* s ) /Deprecated/;
57+
virtual int addDiagramLayer( QgsVectorLayer *layer, const QgsDiagramLayerSettings *s ) /Deprecated/;
5858
//! called for every feature
59-
virtual void registerFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context, const QString& dxfLayer = QString::null ) = 0;
59+
virtual void registerFeature( const QString &layerID, QgsFeature &feat, QgsRenderContext &context ) = 0;
6060
//! called for every diagram feature
61-
virtual void registerDiagramFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context );
61+
virtual void registerDiagramFeature( const QString &layerID, QgsFeature &feat, QgsRenderContext &context );
6262
//! called when the map is drawn and labels should be placed
6363
virtual void drawLabeling( QgsRenderContext& context ) = 0;
6464
//! called when we're done with rendering
@@ -268,7 +268,7 @@ class QgsMapRenderer : QObject
268268
//! Accessor for render context
269269
QgsRenderContext* rendererContext();
270270

271-
//! Labeling engine (NULL if there's no custom engine)
271+
//! Labeling engine (nullptr if there's no custom engine)
272272
QgsLabelingEngineInterface* labelingEngine();
273273

274274
//! Set labeling engine. Previous engine (if any) is deleted.

‎python/core/qgspallabeling.sip

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,6 @@ class QgsPalLayerSettings
551551
* @param f feature to label
552552
* @param context render context. The QgsExpressionContext contained within the render context
553553
* must have already had the feature and fields sets prior to calling this method.
554-
* @param dxfLayer dxfLayer name
555554
* @param labelFeature if using QgsLabelingEngineV2, this will receive the label feature. Not available
556555
* in Python bindings.
557556
* @param obstacleGeometry optional obstacle geometry, if a different geometry to the feature's geometry
@@ -560,7 +559,7 @@ class QgsPalLayerSettings
560559
* the feature's original geometry will be used as an obstacle for labels. Not available
561560
* in Python bindings.
562561
*/
563-
void registerFeature( QgsFeature& f, QgsRenderContext& context, const QString& dxfLayer );
562+
void registerFeature( QgsFeature& f, QgsRenderContext& context );
564563

565564
void readFromLayer( QgsVectorLayer* layer );
566565
void writeToLayer( QgsVectorLayer* layer );
@@ -867,9 +866,8 @@ class QgsPalLabeling : QgsLabelingEngineInterface
867866
* @param feat feature to label
868867
* @param context render context. The QgsExpressionContext contained within the render context
869868
* must have already had the feature and fields sets prior to calling this method.
870-
* @param dxfLayer dxfLayer name
871869
*/
872-
virtual void registerFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context, const QString& dxfLayer = QString::null );
870+
virtual void registerFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context );
873871

874872
virtual void registerDiagramFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context );
875873
//! called when the map is drawn and labels should be placed

‎src/core/dxf/qgsdxfexport.cpp

Lines changed: 143 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@
3737
#include "qgsvectorlayer.h"
3838
#include "qgsmaplayerregistry.h"
3939
#include "qgsunittypes.h"
40+
#include "qgstextlabelfeature.h"
41+
42+
#include "pal/feature.h"
43+
#include "pal/pointset.h"
44+
#include "pal/labelposition.h"
4045

4146
#include <QIODevice>
4247

@@ -942,12 +947,32 @@ void QgsDxfExport::writeEntities()
942947
attributes << layerAttr;
943948
}
944949

945-
QgsDxfLabelProvider* lp = new QgsDxfLabelProvider( vl, this );
946-
engine.addProvider( lp );
947-
if ( !lp->prepare( ctx, attributes ) )
950+
const QgsAbstractVectorLayerLabeling *labeling = vl->labeling();
951+
QgsDxfLabelProvider *lp = nullptr;
952+
QgsDxfRuleBasedLabelProvider *rblp = nullptr;
953+
if ( dynamic_cast<const QgsRuleBasedLabeling*>( labeling ) )
954+
{
955+
const QgsRuleBasedLabeling *rbl = dynamic_cast<const QgsRuleBasedLabeling*>( labeling );
956+
rblp = new QgsDxfRuleBasedLabelProvider( *rbl, vl, this );
957+
rblp->reinit( vl );
958+
engine.addProvider( rblp );
959+
960+
if ( !rblp->prepare( ctx, attributes ) )
961+
{
962+
engine.removeProvider( rblp );
963+
rblp = nullptr;
964+
}
965+
}
966+
else
948967
{
949-
engine.removeProvider( lp );
950-
lp = nullptr;
968+
lp = new QgsDxfLabelProvider( vl, this, nullptr );
969+
engine.addProvider( lp );
970+
971+
if ( !lp->prepare( ctx, attributes ) )
972+
{
973+
engine.removeProvider( lp );
974+
lp = nullptr;
975+
}
951976
}
952977

953978
if ( mSymbologyExport == QgsDxfExport::SymbolLayerSymbology &&
@@ -1012,6 +1037,10 @@ void QgsDxfExport::writeEntities()
10121037
{
10131038
lp->registerDxfFeature( fet, ctx, lName );
10141039
}
1040+
else if ( rblp )
1041+
{
1042+
rblp->registerDxfFeature( fet, ctx, lName );
1043+
}
10151044
}
10161045
}
10171046

@@ -4169,3 +4198,112 @@ QString QgsDxfExport::layerName( QgsVectorLayer *vl ) const
41694198
Q_ASSERT( vl );
41704199
return mLayerTitleAsName && !vl->title().isEmpty() ? vl->title() : vl->name();
41714200
}
4201+
4202+
void QgsDxfExport::drawLabel( QString layerId, QgsRenderContext& context, pal::LabelPosition* label, const QgsPalLayerSettings &settings )
4203+
{
4204+
Q_UNUSED( context );
4205+
QgsTextLabelFeature* lf = dynamic_cast<QgsTextLabelFeature*>( label->getFeaturePart()->feature() );
4206+
if ( !lf )
4207+
return;
4208+
4209+
//label text
4210+
QString txt = lf->text( label->getPartId() );
4211+
4212+
//angle
4213+
double angle = label->getAlpha() * 180 / M_PI;
4214+
4215+
QgsFeatureId fid = label->getFeaturePart()->featureId();
4216+
QString dxfLayer = mDxfLayerNames[layerId][fid];
4217+
4218+
//debug: show label rectangle
4219+
#if 0
4220+
QgsPolyline line;
4221+
for ( int i = 0; i < 4; ++i )
4222+
{
4223+
line.append( QgsPoint( label->getX( i ), label->getY( i ) ) );
4224+
}
4225+
writePolyline( line, dxfLayer, "CONTINUOUS", 1, 0.01, true );
4226+
#endif
4227+
4228+
QString wrapchr = settings.wrapChar.isEmpty() ? "\n" : settings.wrapChar;
4229+
4230+
//add the direction symbol if needed
4231+
if ( !txt.isEmpty() && settings.placement == QgsPalLayerSettings::Line && settings.addDirectionSymbol )
4232+
{
4233+
bool prependSymb = false;
4234+
QString symb = settings.rightDirectionSymbol;
4235+
4236+
if ( label->getReversed() )
4237+
{
4238+
prependSymb = true;
4239+
symb = settings.leftDirectionSymbol;
4240+
}
4241+
4242+
if ( settings.reverseDirectionSymbol )
4243+
{
4244+
if ( symb == settings.rightDirectionSymbol )
4245+
{
4246+
prependSymb = true;
4247+
symb = settings.leftDirectionSymbol;
4248+
}
4249+
else
4250+
{
4251+
prependSymb = false;
4252+
symb = settings.rightDirectionSymbol;
4253+
}
4254+
}
4255+
4256+
if ( settings.placeDirectionSymbol == QgsPalLayerSettings::SymbolAbove )
4257+
{
4258+
prependSymb = true;
4259+
symb = symb + wrapchr;
4260+
}
4261+
else if ( settings.placeDirectionSymbol == QgsPalLayerSettings::SymbolBelow )
4262+
{
4263+
prependSymb = false;
4264+
symb = wrapchr + symb;
4265+
}
4266+
4267+
if ( prependSymb )
4268+
{
4269+
txt.prepend( symb );
4270+
}
4271+
else
4272+
{
4273+
txt.append( symb );
4274+
}
4275+
}
4276+
4277+
txt = txt.replace( wrapchr, "\\P" );
4278+
4279+
if ( settings.textFont.underline() )
4280+
{
4281+
txt.prepend( "\\L" ).append( "\\l" );
4282+
}
4283+
4284+
if ( settings.textFont.overline() )
4285+
{
4286+
txt.prepend( "\\O" ).append( "\\o" );
4287+
}
4288+
4289+
if ( settings.textFont.strikeOut() )
4290+
{
4291+
txt.prepend( "\\K" ).append( "\\k" );
4292+
}
4293+
4294+
txt.prepend( QString( "\\f%1|i%2|b%3;\\H%4;\\W0.75;" )
4295+
.arg( settings.textFont.family() )
4296+
.arg( settings.textFont.italic() ? 1 : 0 )
4297+
.arg( settings.textFont.bold() ? 1 : 0 )
4298+
.arg( label->getHeight() / ( 1 + txt.count( "\\P" ) ) * 0.75 ) );
4299+
4300+
writeMText( dxfLayer, txt, QgsPoint( label->getX(), label->getY() ), label->getWidth() * 1.1, angle, settings.textColor );
4301+
}
4302+
4303+
void QgsDxfExport::registerDxfLayer( QString layerId, QgsFeatureId fid, QString layerName )
4304+
{
4305+
if ( !mDxfLayerNames.contains( layerId ) )
4306+
mDxfLayerNames[ layerId ] = QMap<QgsFeatureId, QString>();
4307+
4308+
mDxfLayerNames[layerId][fid] = layerName;
4309+
}

‎src/core/dxf/qgsdxfexport.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "qgsgeometry.h"
2222
#include "qgssymbolv2.h"
23+
2324
#include <QColor>
2425
#include <QList>
2526
#include <QTextStream>
@@ -28,6 +29,12 @@ class QgsMapLayer;
2829
class QgsPoint;
2930
class QgsSymbolLayerV2;
3031
class QIODevice;
32+
class QgsPalLayerSettings;
33+
34+
namespace pal
35+
{
36+
class LabelPosition;
37+
};
3138

3239
class CORE_EXPORT QgsDxfExport
3340
{
@@ -283,6 +290,9 @@ class CORE_EXPORT QgsDxfExport
283290
//! return list of available DXF encodings
284291
static QStringList encodings();
285292

293+
void drawLabel( QString layerId, QgsRenderContext& context, pal::LabelPosition* label, const QgsPalLayerSettings &settings );
294+
void registerDxfLayer( QString layerId, QgsFeatureId fid, QString layer );
295+
286296
private:
287297
QList< QPair<QgsVectorLayer*, int> > mLayers;
288298

@@ -350,6 +360,9 @@ class CORE_EXPORT QgsDxfExport
350360

351361
QHash<QString, int> mBlockHandles;
352362
QString mBlockHandle;
363+
364+
//! DXF layer name for each label feature
365+
QMap< QString, QMap<QgsFeatureId, QString> > mDxfLayerNames;
353366
};
354367

355368
#endif // QGSDXFEXPORT_H

‎src/core/dxf/qgsdxfpallabeling.cpp

Lines changed: 34 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -17,131 +17,57 @@
1717

1818
#include "qgsdxfpallabeling.h"
1919
#include "qgsdxfexport.h"
20-
#include "qgstextlabelfeature.h"
2120
#include "qgspallabeling.h"
2221
#include "qgsmapsettings.h"
22+
#include "qgslogger.h"
2323

24-
#include "pal/feature.h"
25-
#include "pal/pointset.h"
26-
#include "pal/labelposition.h"
2724

28-
29-
QgsDxfLabelProvider::QgsDxfLabelProvider( QgsVectorLayer* layer , QgsDxfExport* dxf )
30-
: QgsVectorLayerLabelProvider( layer, false )
25+
QgsDxfLabelProvider::QgsDxfLabelProvider( QgsVectorLayer* layer, QgsDxfExport* dxf, const QgsPalLayerSettings *settings )
26+
: QgsVectorLayerLabelProvider( layer, false, settings )
3127
, mDxfExport( dxf )
3228
{
3329
}
3430

3531
void QgsDxfLabelProvider::drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const
3632
{
37-
Q_UNUSED( context );
38-
39-
//debug: print label infos
40-
if ( mDxfExport )
41-
{
42-
QgsTextLabelFeature* lf = dynamic_cast<QgsTextLabelFeature*>( label->getFeaturePart()->feature() );
43-
if ( !lf )
44-
return;
45-
46-
const QgsPalLayerSettings& tmpLyr = mSettings;
47-
48-
//label text
49-
QString txt = lf->text( label->getPartId() );
50-
51-
//angle
52-
double angle = label->getAlpha() * 180 / M_PI;
53-
54-
QgsFeatureId fid = label->getFeaturePart()->featureId();
55-
QString dxfLayer = mDxfLayerNames[fid];
56-
57-
//debug: show label rectangle
58-
#if 0
59-
QgsPolyline line;
60-
for ( int i = 0; i < 4; ++i )
61-
{
62-
line.append( QgsPoint( label->getX( i ), label->getY( i ) ) );
63-
}
64-
mDxfExport->writePolyline( line, dxfLayer, "CONTINUOUS", 1, 0.01, true );
65-
#endif
66-
67-
QString wrapchr = tmpLyr.wrapChar.isEmpty() ? "\n" : tmpLyr.wrapChar;
68-
69-
//add the direction symbol if needed
70-
if ( !txt.isEmpty() && tmpLyr.placement == QgsPalLayerSettings::Line && tmpLyr.addDirectionSymbol )
71-
{
72-
bool prependSymb = false;
73-
QString symb = tmpLyr.rightDirectionSymbol;
74-
75-
if ( label->getReversed() )
76-
{
77-
prependSymb = true;
78-
symb = tmpLyr.leftDirectionSymbol;
79-
}
80-
81-
if ( tmpLyr.reverseDirectionSymbol )
82-
{
83-
if ( symb == tmpLyr.rightDirectionSymbol )
84-
{
85-
prependSymb = true;
86-
symb = tmpLyr.leftDirectionSymbol;
87-
}
88-
else
89-
{
90-
prependSymb = false;
91-
symb = tmpLyr.rightDirectionSymbol;
92-
}
93-
}
94-
95-
if ( tmpLyr.placeDirectionSymbol == QgsPalLayerSettings::SymbolAbove )
96-
{
97-
prependSymb = true;
98-
symb = symb + wrapchr;
99-
}
100-
else if ( tmpLyr.placeDirectionSymbol == QgsPalLayerSettings::SymbolBelow )
101-
{
102-
prependSymb = false;
103-
symb = wrapchr + symb;
104-
}
105-
106-
if ( prependSymb )
107-
{
108-
txt.prepend( symb );
109-
}
110-
else
111-
{
112-
txt.append( symb );
113-
}
114-
}
115-
116-
txt = txt.replace( wrapchr, "\\P" );
33+
Q_ASSERT( mDxfExport );
34+
mDxfExport->drawLabel( layerId(), context, label, mSettings );
35+
}
11736

118-
if ( tmpLyr.textFont.underline() )
119-
{
120-
txt.prepend( "\\L" ).append( "\\l" );
121-
}
37+
void QgsDxfLabelProvider::registerDxfFeature( QgsFeature& feature, QgsRenderContext& context, const QString& dxfLayerName )
38+
{
39+
registerFeature( feature, context );
40+
mDxfExport->registerDxfLayer( layerId(), feature.id(), dxfLayerName );
41+
}
12242

123-
if ( tmpLyr.textFont.overline() )
124-
{
125-
txt.prepend( "\\O" ).append( "\\o" );
126-
}
43+
QgsDxfRuleBasedLabelProvider::QgsDxfRuleBasedLabelProvider( const QgsRuleBasedLabeling &rules, QgsVectorLayer* layer, QgsDxfExport* dxf )
44+
: QgsRuleBasedLabelProvider( rules, layer, false )
45+
, mDxfExport( dxf )
46+
{
47+
}
12748

128-
if ( tmpLyr.textFont.strikeOut() )
129-
{
130-
txt.prepend( "\\K" ).append( "\\k" );
131-
}
49+
void QgsDxfRuleBasedLabelProvider::reinit( QgsVectorLayer* layer )
50+
{
51+
QgsDebugMsg( "Entering." );
52+
mRules.rootRule()->createSubProviders( layer, mSubProviders, this );
53+
}
13254

133-
txt.prepend( QString( "\\f%1|i%2|b%3;\\H%4;\\W0.75;" )
134-
.arg( tmpLyr.textFont.family() )
135-
.arg( tmpLyr.textFont.italic() ? 1 : 0 )
136-
.arg( tmpLyr.textFont.bold() ? 1 : 0 )
137-
.arg( label->getHeight() / ( 1 + txt.count( "\\P" ) ) * 0.75 ) );
55+
QgsVectorLayerLabelProvider *QgsDxfRuleBasedLabelProvider::createProvider( QgsVectorLayer *layer, bool withFeatureLoop, const QgsPalLayerSettings *settings )
56+
{
57+
QgsDebugMsg( "Entering." );
58+
Q_UNUSED( withFeatureLoop );
59+
return new QgsDxfLabelProvider( layer, mDxfExport, settings );
60+
}
13861

139-
mDxfExport->writeMText( dxfLayer, txt, QgsPoint( label->getX(), label->getY() ), label->getWidth() * 1.1, angle, tmpLyr.textColor );
140-
}
62+
void QgsDxfRuleBasedLabelProvider::drawLabel( QgsRenderContext &context, pal::LabelPosition *label ) const
63+
{
64+
QgsDebugMsg( "Entering." );
65+
Q_ASSERT( mDxfExport );
66+
mDxfExport->drawLabel( layerId(), context, label, mSettings );
14167
}
14268

143-
void QgsDxfLabelProvider::registerDxfFeature( QgsFeature& feature, QgsRenderContext& context, const QString& dxfLayerName )
69+
void QgsDxfRuleBasedLabelProvider::registerDxfFeature( QgsFeature &feature, QgsRenderContext &context, const QString &dxfLayerName )
14470
{
14571
registerFeature( feature, context );
146-
mDxfLayerNames[feature.id()] = dxfLayerName;
72+
mDxfExport->registerDxfLayer( layerId(), feature.id(), dxfLayerName );
14773
}

‎src/core/dxf/qgsdxfpallabeling.h

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@
2121
#include "qgsmaprenderer.h"
2222
#include "qgsrendercontext.h"
2323
#include "qgsvectorlayerlabelprovider.h"
24+
#include "qgsrulebasedlabeling.h"
2425

2526
class QgsDxfExport;
27+
class QgsPalLayerSettings;
28+
class QgsRuleBasedLabeling;
2629

2730

2831
/** Implements a derived label provider internally used for DXF export
@@ -34,19 +37,40 @@ class QgsDxfLabelProvider : public QgsVectorLayerLabelProvider
3437
{
3538
public:
3639
//! construct the provider
37-
explicit QgsDxfLabelProvider( QgsVectorLayer* layer, QgsDxfExport* dxf );
40+
explicit QgsDxfLabelProvider( QgsVectorLayer* layer, QgsDxfExport* dxf, const QgsPalLayerSettings *settings );
3841

3942
//! re-implementation that writes to DXF file instead of drawing with QPainter
40-
virtual void drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const override;
43+
void drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const override;
4144

4245
//! registration method that keeps track of DXF layer names of individual features
4346
void registerDxfFeature( QgsFeature& feature, QgsRenderContext &context, const QString& dxfLayerName );
4447

4548
protected:
4649
//! pointer to parent DXF export where this instance is used
4750
QgsDxfExport* mDxfExport;
48-
//! DXF layer name for each label feature
49-
QMap<QgsFeatureId, QString> mDxfLayerNames;
5051
};
5152

53+
class QgsDxfRuleBasedLabelProvider : public QgsRuleBasedLabelProvider
54+
{
55+
public:
56+
//! construct the provider
57+
explicit QgsDxfRuleBasedLabelProvider( const QgsRuleBasedLabeling &rules, QgsVectorLayer* layer, QgsDxfExport* dxf );
58+
59+
void reinit( QgsVectorLayer* layer );
60+
61+
//! re-implementation that writes to DXF file instead of drawing with QPainter
62+
void drawLabel( QgsRenderContext &context, pal::LabelPosition *label ) const override;
63+
64+
//! registration method that keeps track of DXF layer names of individual features
65+
void registerDxfFeature( QgsFeature& feature, QgsRenderContext &context, const QString& dxfLayerName );
66+
67+
virtual QgsVectorLayerLabelProvider *createProvider( QgsVectorLayer *layer, bool withFeatureLoop, const QgsPalLayerSettings *settings ) override;
68+
69+
protected:
70+
//! pointer to parent DXF export where this instance is used
71+
QgsDxfExport* mDxfExport;
72+
};
73+
74+
75+
5276
#endif // QGSDXFPALLABELING_H

‎src/core/qgslabelfeature.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
* *
1414
***************************************************************************/
1515
#include "qgslabelfeature.h"
16-
1716
#include "feature.h"
1817

1918

‎src/core/qgsmaprenderer.h

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,10 @@ class QgsDiagramLayerSettings;
4646
class CORE_EXPORT QgsLabelPosition
4747
{
4848
public:
49-
QgsLabelPosition( int id, double r, const QVector< QgsPoint >& corners, const QgsRectangle& rect, double w, double h, const QString& layer, const QString& labeltext, const QFont& labelfont, bool upside_down, bool diagram = false, bool pinned = false ):
50-
featureId( id ), rotation( r ), cornerPoints( corners ), labelRect( rect ), width( w ), height( h ), layerID( layer ), labelText( labeltext ), labelFont( labelfont ), upsideDown( upside_down ), isDiagram( diagram ), isPinned( pinned ) {}
51-
QgsLabelPosition(): featureId( -1 ), rotation( 0 ), labelRect( QgsRectangle() ), width( 0 ), height( 0 ), layerID( "" ), labelText( "" ), labelFont( QFont() ), upsideDown( false ), isDiagram( false ), isPinned( false ) {}
49+
QgsLabelPosition( int id, double r, const QVector< QgsPoint >& corners, const QgsRectangle& rect, double w, double h, const QString& layer, const QString& labeltext, const QFont& labelfont, bool upside_down, bool diagram = false, bool pinned = false )
50+
: featureId( id ), rotation( r ), cornerPoints( corners ), labelRect( rect ), width( w ), height( h ), layerID( layer ), labelText( labeltext ), labelFont( labelfont ), upsideDown( upside_down ), isDiagram( diagram ), isPinned( pinned ) {}
51+
QgsLabelPosition()
52+
: featureId( -1 ), rotation( 0 ), labelRect( QgsRectangle() ), width( 0 ), height( 0 ), layerID( "" ), labelText( "" ), labelFont( QFont() ), upsideDown( false ), isDiagram( false ), isPinned( false ) {}
5253
int featureId;
5354
double rotation;
5455
QVector< QgsPoint > cornerPoints;
@@ -72,7 +73,7 @@ class CORE_EXPORT QgsLabelingEngineInterface
7273

7374
//! called when we're going to start with rendering
7475
//! @deprecated since 2.4 - use override with QgsMapSettings
75-
Q_DECL_DEPRECATED virtual void init( QgsMapRenderer* mp ) = 0;
76+
Q_DECL_DEPRECATED virtual void init( QgsMapRenderer *mp ) = 0;
7677
//! called when we're going to start with rendering
7778
virtual void init( const QgsMapSettings& mapSettings ) = 0;
7879
//! called to find out whether the layer is used for labeling
@@ -85,19 +86,19 @@ class CORE_EXPORT QgsLabelingEngineInterface
8586
virtual int prepareLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx ) = 0;
8687
//! returns PAL layer settings for a registered layer
8788
//! @deprecated since 2.12 - if direct access to QgsPalLayerSettings is necessary, use QgsPalLayerSettings::fromLayer()
88-
Q_DECL_DEPRECATED virtual QgsPalLayerSettings& layer( const QString& layerName ) = 0;
89+
Q_DECL_DEPRECATED virtual QgsPalLayerSettings &layer( const QString &layerName ) = 0;
8990
//! adds a diagram layer to the labeling engine
9091
//! @note added in QGIS 2.12
91-
virtual int prepareDiagramLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx )
92+
virtual int prepareDiagramLayer( QgsVectorLayer *layer, QStringList &attrNames, QgsRenderContext &ctx )
9293
{ Q_UNUSED( layer ); Q_UNUSED( attrNames ); Q_UNUSED( ctx ); return 0; }
9394
//! adds a diagram layer to the labeling engine
9495
//! @deprecated since 2.12 - use prepareDiagramLayer()
95-
Q_DECL_DEPRECATED virtual int addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLayerSettings* s )
96+
Q_DECL_DEPRECATED virtual int addDiagramLayer( QgsVectorLayer *layer, const QgsDiagramLayerSettings *s )
9697
{ Q_UNUSED( layer ); Q_UNUSED( s ); return 0; }
9798
//! called for every feature
98-
virtual void registerFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context, const QString& dxfLayer = QString::null ) = 0;
99+
virtual void registerFeature( const QString &layerID, QgsFeature &feat, QgsRenderContext &context ) = 0;
99100
//! called for every diagram feature
100-
virtual void registerDiagramFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context )
101+
virtual void registerDiagramFeature( const QString &layerID, QgsFeature &feat, QgsRenderContext &context )
101102
{ Q_UNUSED( layerID ); Q_UNUSED( feat ); Q_UNUSED( context ); }
102103
//! called when the map is drawn and labels should be placed
103104
virtual void drawLabeling( QgsRenderContext& context ) = 0;

‎src/core/qgspallabeling.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1939,13 +1939,11 @@ void QgsPalLayerSettings::calculateLabelSize( const QFontMetricsF* fm, QString t
19391939
#endif
19401940
}
19411941

1942-
void QgsPalLayerSettings::registerFeature( QgsFeature& f, QgsRenderContext &context, const QString& dxfLayer, QgsLabelFeature** labelFeature , QgsGeometry* obstacleGeometry )
1942+
void QgsPalLayerSettings::registerFeature( QgsFeature& f, QgsRenderContext &context, QgsLabelFeature** labelFeature , QgsGeometry* obstacleGeometry )
19431943
{
19441944
// either used in QgsPalLabeling (palLayer is set) or in QgsLabelingEngineV2 (labelFeature is set)
19451945
Q_ASSERT( labelFeature );
19461946

1947-
Q_UNUSED( dxfLayer ); // now handled in QgsDxfLabelProvider
1948-
19491947
QVariant exprVal; // value() is repeatedly nulled on data defined evaluation and replaced when successful
19501948
mCurFeat = &f;
19511949

@@ -1960,7 +1958,7 @@ void QgsPalLayerSettings::registerFeature( QgsFeature& f, QgsRenderContext &cont
19601958
{
19611959
if ( isObstacle )
19621960
{
1963-
registerObstacleFeature( f, context, QString(), labelFeature, obstacleGeometry );
1961+
registerObstacleFeature( f, context, labelFeature, obstacleGeometry );
19641962
}
19651963
return;
19661964
}
@@ -2812,10 +2810,8 @@ void QgsPalLayerSettings::registerFeature( QgsFeature& f, QgsRenderContext &cont
28122810
lf->setDataDefinedValues( dataDefinedValues );
28132811
}
28142812

2815-
void QgsPalLayerSettings::registerObstacleFeature( QgsFeature& f, QgsRenderContext &context, const QString& dxfLayer, QgsLabelFeature** obstacleFeature, QgsGeometry* obstacleGeometry )
2813+
void QgsPalLayerSettings::registerObstacleFeature( QgsFeature& f, QgsRenderContext &context, QgsLabelFeature** obstacleFeature, QgsGeometry* obstacleGeometry )
28162814
{
2817-
Q_UNUSED( dxfLayer ); // now handled in QgsDxfLabelProvider
2818-
28192815
mCurFeat = &f;
28202816

28212817
const QgsGeometry* geom = nullptr;
@@ -3809,9 +3805,8 @@ int QgsPalLabeling::addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLaye
38093805
return 0;
38103806
}
38113807

3812-
void QgsPalLabeling::registerFeature( const QString& layerID, QgsFeature& f, QgsRenderContext &context, const QString& dxfLayer )
3808+
void QgsPalLabeling::registerFeature( const QString& layerID, QgsFeature& f, QgsRenderContext &context )
38133809
{
3814-
Q_UNUSED( dxfLayer ); // now handled by QgsDxfLabelProvider
38153810
if ( QgsVectorLayerLabelProvider* provider = mLabelProviders.value( layerID, nullptr ) )
38163811
provider->registerFeature( f, context );
38173812
}

‎src/core/qgspallabeling.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,6 @@ class CORE_EXPORT QgsPalLayerSettings
533533
* @param f feature to label
534534
* @param context render context. The QgsExpressionContext contained within the render context
535535
* must have already had the feature and fields sets prior to calling this method.
536-
* @param dxfLayer dxfLayer name
537536
* @param labelFeature if using QgsLabelingEngineV2, this will receive the label feature. Not available
538537
* in Python bindings.
539538
* @param obstacleGeometry optional obstacle geometry, if a different geometry to the feature's geometry
@@ -542,7 +541,7 @@ class CORE_EXPORT QgsPalLayerSettings
542541
* the feature's original geometry will be used as an obstacle for labels. Not available
543542
* in Python bindings.
544543
*/
545-
void registerFeature( QgsFeature& f, QgsRenderContext& context, const QString& dxfLayer, QgsLabelFeature** labelFeature = nullptr, QgsGeometry* obstacleGeometry = nullptr );
544+
void registerFeature( QgsFeature& f, QgsRenderContext& context, QgsLabelFeature** labelFeature = nullptr, QgsGeometry* obstacleGeometry = nullptr );
546545

547546
void readFromLayer( QgsVectorLayer* layer );
548547
void writeToLayer( QgsVectorLayer* layer );
@@ -712,7 +711,7 @@ class CORE_EXPORT QgsPalLayerSettings
712711

713712
/** Registers a feature as an obstacle only (no label rendered)
714713
*/
715-
void registerObstacleFeature( QgsFeature &f, QgsRenderContext &context, const QString& dxfLayer, QgsLabelFeature** obstacleFeature, QgsGeometry* obstacleGeometry = nullptr );
714+
void registerObstacleFeature( QgsFeature &f, QgsRenderContext &context, QgsLabelFeature** obstacleFeature, QgsGeometry* obstacleGeometry = nullptr );
716715

717716
QMap<DataDefinedProperties, QVariant> dataDefinedValues;
718717
QgsExpression* expression;
@@ -949,9 +948,8 @@ class CORE_EXPORT QgsPalLabeling : public QgsLabelingEngineInterface
949948
* @param feat feature to label
950949
* @param context render context. The QgsExpressionContext contained within the render context
951950
* must have already had the feature and fields sets prior to calling this method.
952-
* @param dxfLayer dxfLayer name
953951
*/
954-
virtual void registerFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context, const QString& dxfLayer = QString::null ) override;
952+
virtual void registerFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context ) override;
955953

956954
virtual void registerDiagramFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context ) override;
957955
//! called when the map is drawn and labels should be placed

‎src/core/qgsrulebasedlabeling.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,22 @@
1515
#include "qgsrulebasedlabeling.h"
1616

1717

18-
1918
QgsRuleBasedLabelProvider::QgsRuleBasedLabelProvider( const QgsRuleBasedLabeling& rules, QgsVectorLayer* layer, bool withFeatureLoop )
2019
: QgsVectorLayerLabelProvider( layer, withFeatureLoop )
2120
, mRules( rules )
2221
{
23-
mRules.rootRule()->createSubProviders( layer, mSubProviders );
22+
mRules.rootRule()->createSubProviders( layer, mSubProviders, this );
2423
}
2524

2625
QgsRuleBasedLabelProvider::~QgsRuleBasedLabelProvider()
2726
{
2827
// sub-providers owned by labeling engine
2928
}
3029

30+
QgsVectorLayerLabelProvider *QgsRuleBasedLabelProvider::createProvider( QgsVectorLayer *layer, bool withFeatureLoop, const QgsPalLayerSettings *settings )
31+
{
32+
return new QgsVectorLayerLabelProvider( layer, withFeatureLoop, settings );
33+
}
3134

3235
bool QgsRuleBasedLabelProvider::prepare( const QgsRenderContext& context, QStringList& attributeNames )
3336
{
@@ -213,19 +216,20 @@ QDomElement QgsRuleBasedLabeling::Rule::save( QDomDocument& doc ) const
213216
return ruleElem;
214217
}
215218

216-
void QgsRuleBasedLabeling::Rule::createSubProviders( QgsVectorLayer* layer, QgsRuleBasedLabeling::RuleToProviderMap& subProviders )
219+
void QgsRuleBasedLabeling::Rule::createSubProviders( QgsVectorLayer* layer, QgsRuleBasedLabeling::RuleToProviderMap& subProviders, QgsRuleBasedLabelProvider *provider )
217220
{
218221
if ( mSettings )
219222
{
220223
// add provider!
221-
QgsVectorLayerLabelProvider* p = new QgsVectorLayerLabelProvider( layer, false, mSettings );
224+
QgsVectorLayerLabelProvider *p = provider->createProvider( layer, false, mSettings );
225+
delete subProviders.value( this, nullptr );
222226
subProviders[this] = p;
223227
}
224228

225229
// call recursively
226230
Q_FOREACH ( Rule* rule, mChildren )
227231
{
228-
rule->createSubProviders( layer, subProviders );
232+
rule->createSubProviders( layer, subProviders, provider );
229233
}
230234
}
231235

@@ -262,6 +266,8 @@ QgsRuleBasedLabeling::Rule::RegisterResult QgsRuleBasedLabeling::Rule::registerF
262266

263267
bool registered = false;
264268

269+
Q_ASSERT( !mSettings == subProviders.contains( this ) );
270+
265271
// do we have active subprovider for the rule?
266272
if ( subProviders.contains( this ) && mIsActive )
267273
{

‎src/core/qgsrulebasedlabeling.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <QMap>
2020

2121
#include "qgsvectorlayerlabeling.h"
22+
#include "qgsvectorlayerlabelprovider.h"
2223

2324
class QDomDocument;
2425
class QDomElement;
@@ -28,6 +29,7 @@ class QgsFeature;
2829
class QgsPalLayerSettings;
2930
class QgsRenderContext;
3031
class QgsGeometry;
32+
class QgsRuleBasedLabelProvider;
3133

3234
/**
3335
* @class QgsRuleBasedLabeling
@@ -42,7 +44,6 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
4244
typedef QList<Rule*> RuleList;
4345
typedef QMap<Rule*, QgsVectorLayerLabelProvider*> RuleToProviderMap;
4446

45-
4647
/**
4748
* @class QgsRuleBasedLabeling::Rule
4849
* @note not available in Python bindings
@@ -214,7 +215,7 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
214215
// evaluation
215216

216217
//! add providers
217-
void createSubProviders( QgsVectorLayer* layer, RuleToProviderMap& subProviders );
218+
void createSubProviders( QgsVectorLayer* layer, RuleToProviderMap& subProviders, QgsRuleBasedLabelProvider *provider );
218219

219220
//! call prepare() on sub-providers and populate attributeNames
220221
void prepare( const QgsRenderContext& context, QStringList& attributeNames, RuleToProviderMap& subProviders );
@@ -285,15 +286,13 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
285286

286287
virtual QString type() const override;
287288
virtual QDomElement save( QDomDocument& doc ) const override;
288-
virtual QgsVectorLayerLabelProvider* provider( QgsVectorLayer* layer ) const override;
289+
virtual QgsVectorLayerLabelProvider *provider( QgsVectorLayer* layer ) const override;
289290

290291
protected:
291292
Rule* mRootRule;
292293
};
293294

294295

295-
#include "qgsvectorlayerlabelprovider.h"
296-
297296
/**
298297
* @class QgsRuleBasedLabelProvider
299298
* @note not available in Python bindings
@@ -312,6 +311,7 @@ class CORE_EXPORT QgsRuleBasedLabelProvider : public QgsVectorLayerLabelProvider
312311
virtual void registerFeature( QgsFeature& feature, QgsRenderContext& context, QgsGeometry* obstacleGeometry = nullptr ) override;
313312

314313
// new methods
314+
virtual QgsVectorLayerLabelProvider *createProvider( QgsVectorLayer *layer, bool withFeatureLoop, const QgsPalLayerSettings *settings );
315315

316316
virtual QList<QgsAbstractLabelProvider*> subProviders() override;
317317

‎src/core/qgsvectorlayerlabelprovider.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( QgsRenderCon
316316
void QgsVectorLayerLabelProvider::registerFeature( QgsFeature& feature, QgsRenderContext& context, QgsGeometry* obstacleGeometry )
317317
{
318318
QgsLabelFeature* label = nullptr;
319-
mSettings.registerFeature( feature, context, QString(), &label, obstacleGeometry );
319+
mSettings.registerFeature( feature, context, &label, obstacleGeometry );
320320
if ( label )
321321
mLabels << label;
322322
}

‎src/core/qgsvectorlayerlabelprovider.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,5 +116,4 @@ class CORE_EXPORT QgsVectorLayerLabelProvider : public QgsAbstractLabelProvider
116116
QList<QgsLabelFeature*> mLabels;
117117
};
118118

119-
120119
#endif // QGSVECTORLAYERLABELPROVIDER_H

‎tests/src/core/testqgslabelingenginev2.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,15 +259,16 @@ void TestQgsLabelingEngineV2::testRuleBased()
259259

260260
delete rl2;
261261

262-
/*
262+
#if 0
263263
QPainter p( &img );
264264
QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings );
265265
context.setPainter( &p );
266266

267267
QgsLabelingEngineV2 engine;
268268
engine.setMapSettings( mapSettings );
269269
engine.addProvider( new QgsRuleBasedLabelProvider( , vl ) );
270-
engine.run( context );*/
270+
engine.run( context );
271+
#endif
271272
}
272273

273274
void TestQgsLabelingEngineV2::zOrder()

0 commit comments

Comments
 (0)
Please sign in to comment.