mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
dxf export: support rule based labeling (fixes #13757)
This commit is contained in:
parent
b7a4e20627
commit
f19a35c34e
@ -35,7 +35,7 @@ class QgsLabelingEngineInterface
|
||||
|
||||
//! called when we're going to start with rendering
|
||||
//! @deprecated since 2.4 - use override with QgsMapSettings
|
||||
virtual void init( QgsMapRenderer* mp ) = 0 /Deprecated/;
|
||||
virtual void init( QgsMapRenderer *mp ) = 0 /Deprecated/;
|
||||
//! called when we're going to start with rendering
|
||||
virtual void init( const QgsMapSettings& mapSettings ) = 0;
|
||||
//! called to find out whether the layer is used for labeling
|
||||
@ -48,17 +48,17 @@ class QgsLabelingEngineInterface
|
||||
virtual int prepareLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx ) = 0;
|
||||
//! returns PAL layer settings for a registered layer
|
||||
//! @deprecated since 2.12 - if direct access to QgsPalLayerSettings is necessary, use QgsPalLayerSettings::fromLayer()
|
||||
virtual QgsPalLayerSettings& layer( const QString& layerName ) = 0 /Deprecated/;
|
||||
virtual QgsPalLayerSettings &layer( const QString &layerName ) = 0 /Deprecated/;
|
||||
//! adds a diagram layer to the labeling engine
|
||||
//! @note added in QGIS 2.12
|
||||
virtual int prepareDiagramLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx );
|
||||
virtual int prepareDiagramLayer( QgsVectorLayer *layer, QStringList &attrNames, QgsRenderContext &ctx );
|
||||
//! adds a diagram layer to the labeling engine
|
||||
//! @deprecated since 2.12 - use prepareDiagramLayer()
|
||||
virtual int addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLayerSettings* s ) /Deprecated/;
|
||||
virtual int addDiagramLayer( QgsVectorLayer *layer, const QgsDiagramLayerSettings *s ) /Deprecated/;
|
||||
//! called for every feature
|
||||
virtual void registerFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context, const QString& dxfLayer = QString::null ) = 0;
|
||||
virtual void registerFeature( const QString &layerID, QgsFeature &feat, QgsRenderContext &context ) = 0;
|
||||
//! called for every diagram feature
|
||||
virtual void registerDiagramFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context );
|
||||
virtual void registerDiagramFeature( const QString &layerID, QgsFeature &feat, QgsRenderContext &context );
|
||||
//! called when the map is drawn and labels should be placed
|
||||
virtual void drawLabeling( QgsRenderContext& context ) = 0;
|
||||
//! called when we're done with rendering
|
||||
@ -268,7 +268,7 @@ class QgsMapRenderer : QObject
|
||||
//! Accessor for render context
|
||||
QgsRenderContext* rendererContext();
|
||||
|
||||
//! Labeling engine (NULL if there's no custom engine)
|
||||
//! Labeling engine (nullptr if there's no custom engine)
|
||||
QgsLabelingEngineInterface* labelingEngine();
|
||||
|
||||
//! Set labeling engine. Previous engine (if any) is deleted.
|
||||
|
@ -551,7 +551,6 @@ class QgsPalLayerSettings
|
||||
* @param f feature to label
|
||||
* @param context render context. The QgsExpressionContext contained within the render context
|
||||
* must have already had the feature and fields sets prior to calling this method.
|
||||
* @param dxfLayer dxfLayer name
|
||||
* @param labelFeature if using QgsLabelingEngineV2, this will receive the label feature. Not available
|
||||
* in Python bindings.
|
||||
* @param obstacleGeometry optional obstacle geometry, if a different geometry to the feature's geometry
|
||||
@ -560,7 +559,7 @@ class QgsPalLayerSettings
|
||||
* the feature's original geometry will be used as an obstacle for labels. Not available
|
||||
* in Python bindings.
|
||||
*/
|
||||
void registerFeature( QgsFeature& f, QgsRenderContext& context, const QString& dxfLayer );
|
||||
void registerFeature( QgsFeature& f, QgsRenderContext& context );
|
||||
|
||||
void readFromLayer( QgsVectorLayer* layer );
|
||||
void writeToLayer( QgsVectorLayer* layer );
|
||||
@ -867,9 +866,8 @@ class QgsPalLabeling : QgsLabelingEngineInterface
|
||||
* @param feat feature to label
|
||||
* @param context render context. The QgsExpressionContext contained within the render context
|
||||
* must have already had the feature and fields sets prior to calling this method.
|
||||
* @param dxfLayer dxfLayer name
|
||||
*/
|
||||
virtual void registerFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context, const QString& dxfLayer = QString::null );
|
||||
virtual void registerFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context );
|
||||
|
||||
virtual void registerDiagramFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context );
|
||||
//! called when the map is drawn and labels should be placed
|
||||
|
@ -37,6 +37,11 @@
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsmaplayerregistry.h"
|
||||
#include "qgsunittypes.h"
|
||||
#include "qgstextlabelfeature.h"
|
||||
|
||||
#include "pal/feature.h"
|
||||
#include "pal/pointset.h"
|
||||
#include "pal/labelposition.h"
|
||||
|
||||
#include <QIODevice>
|
||||
|
||||
@ -942,12 +947,32 @@ void QgsDxfExport::writeEntities()
|
||||
attributes << layerAttr;
|
||||
}
|
||||
|
||||
QgsDxfLabelProvider* lp = new QgsDxfLabelProvider( vl, this );
|
||||
engine.addProvider( lp );
|
||||
if ( !lp->prepare( ctx, attributes ) )
|
||||
const QgsAbstractVectorLayerLabeling *labeling = vl->labeling();
|
||||
QgsDxfLabelProvider *lp = nullptr;
|
||||
QgsDxfRuleBasedLabelProvider *rblp = nullptr;
|
||||
if ( dynamic_cast<const QgsRuleBasedLabeling*>( labeling ) )
|
||||
{
|
||||
engine.removeProvider( lp );
|
||||
lp = nullptr;
|
||||
const QgsRuleBasedLabeling *rbl = dynamic_cast<const QgsRuleBasedLabeling*>( labeling );
|
||||
rblp = new QgsDxfRuleBasedLabelProvider( *rbl, vl, this );
|
||||
rblp->reinit( vl );
|
||||
engine.addProvider( rblp );
|
||||
|
||||
if ( !rblp->prepare( ctx, attributes ) )
|
||||
{
|
||||
engine.removeProvider( rblp );
|
||||
rblp = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lp = new QgsDxfLabelProvider( vl, this, nullptr );
|
||||
engine.addProvider( lp );
|
||||
|
||||
if ( !lp->prepare( ctx, attributes ) )
|
||||
{
|
||||
engine.removeProvider( lp );
|
||||
lp = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if ( mSymbologyExport == QgsDxfExport::SymbolLayerSymbology &&
|
||||
@ -1012,6 +1037,10 @@ void QgsDxfExport::writeEntities()
|
||||
{
|
||||
lp->registerDxfFeature( fet, ctx, lName );
|
||||
}
|
||||
else if ( rblp )
|
||||
{
|
||||
rblp->registerDxfFeature( fet, ctx, lName );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4169,3 +4198,112 @@ QString QgsDxfExport::layerName( QgsVectorLayer *vl ) const
|
||||
Q_ASSERT( vl );
|
||||
return mLayerTitleAsName && !vl->title().isEmpty() ? vl->title() : vl->name();
|
||||
}
|
||||
|
||||
void QgsDxfExport::drawLabel( QString layerId, QgsRenderContext& context, pal::LabelPosition* label, const QgsPalLayerSettings &settings )
|
||||
{
|
||||
Q_UNUSED( context );
|
||||
QgsTextLabelFeature* lf = dynamic_cast<QgsTextLabelFeature*>( label->getFeaturePart()->feature() );
|
||||
if ( !lf )
|
||||
return;
|
||||
|
||||
//label text
|
||||
QString txt = lf->text( label->getPartId() );
|
||||
|
||||
//angle
|
||||
double angle = label->getAlpha() * 180 / M_PI;
|
||||
|
||||
QgsFeatureId fid = label->getFeaturePart()->featureId();
|
||||
QString dxfLayer = mDxfLayerNames[layerId][fid];
|
||||
|
||||
//debug: show label rectangle
|
||||
#if 0
|
||||
QgsPolyline line;
|
||||
for ( int i = 0; i < 4; ++i )
|
||||
{
|
||||
line.append( QgsPoint( label->getX( i ), label->getY( i ) ) );
|
||||
}
|
||||
writePolyline( line, dxfLayer, "CONTINUOUS", 1, 0.01, true );
|
||||
#endif
|
||||
|
||||
QString wrapchr = settings.wrapChar.isEmpty() ? "\n" : settings.wrapChar;
|
||||
|
||||
//add the direction symbol if needed
|
||||
if ( !txt.isEmpty() && settings.placement == QgsPalLayerSettings::Line && settings.addDirectionSymbol )
|
||||
{
|
||||
bool prependSymb = false;
|
||||
QString symb = settings.rightDirectionSymbol;
|
||||
|
||||
if ( label->getReversed() )
|
||||
{
|
||||
prependSymb = true;
|
||||
symb = settings.leftDirectionSymbol;
|
||||
}
|
||||
|
||||
if ( settings.reverseDirectionSymbol )
|
||||
{
|
||||
if ( symb == settings.rightDirectionSymbol )
|
||||
{
|
||||
prependSymb = true;
|
||||
symb = settings.leftDirectionSymbol;
|
||||
}
|
||||
else
|
||||
{
|
||||
prependSymb = false;
|
||||
symb = settings.rightDirectionSymbol;
|
||||
}
|
||||
}
|
||||
|
||||
if ( settings.placeDirectionSymbol == QgsPalLayerSettings::SymbolAbove )
|
||||
{
|
||||
prependSymb = true;
|
||||
symb = symb + wrapchr;
|
||||
}
|
||||
else if ( settings.placeDirectionSymbol == QgsPalLayerSettings::SymbolBelow )
|
||||
{
|
||||
prependSymb = false;
|
||||
symb = wrapchr + symb;
|
||||
}
|
||||
|
||||
if ( prependSymb )
|
||||
{
|
||||
txt.prepend( symb );
|
||||
}
|
||||
else
|
||||
{
|
||||
txt.append( symb );
|
||||
}
|
||||
}
|
||||
|
||||
txt = txt.replace( wrapchr, "\\P" );
|
||||
|
||||
if ( settings.textFont.underline() )
|
||||
{
|
||||
txt.prepend( "\\L" ).append( "\\l" );
|
||||
}
|
||||
|
||||
if ( settings.textFont.overline() )
|
||||
{
|
||||
txt.prepend( "\\O" ).append( "\\o" );
|
||||
}
|
||||
|
||||
if ( settings.textFont.strikeOut() )
|
||||
{
|
||||
txt.prepend( "\\K" ).append( "\\k" );
|
||||
}
|
||||
|
||||
txt.prepend( QString( "\\f%1|i%2|b%3;\\H%4;\\W0.75;" )
|
||||
.arg( settings.textFont.family() )
|
||||
.arg( settings.textFont.italic() ? 1 : 0 )
|
||||
.arg( settings.textFont.bold() ? 1 : 0 )
|
||||
.arg( label->getHeight() / ( 1 + txt.count( "\\P" ) ) * 0.75 ) );
|
||||
|
||||
writeMText( dxfLayer, txt, QgsPoint( label->getX(), label->getY() ), label->getWidth() * 1.1, angle, settings.textColor );
|
||||
}
|
||||
|
||||
void QgsDxfExport::registerDxfLayer( QString layerId, QgsFeatureId fid, QString layerName )
|
||||
{
|
||||
if ( !mDxfLayerNames.contains( layerId ) )
|
||||
mDxfLayerNames[ layerId ] = QMap<QgsFeatureId, QString>();
|
||||
|
||||
mDxfLayerNames[layerId][fid] = layerName;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgssymbolv2.h"
|
||||
|
||||
#include <QColor>
|
||||
#include <QList>
|
||||
#include <QTextStream>
|
||||
@ -28,6 +29,12 @@ class QgsMapLayer;
|
||||
class QgsPoint;
|
||||
class QgsSymbolLayerV2;
|
||||
class QIODevice;
|
||||
class QgsPalLayerSettings;
|
||||
|
||||
namespace pal
|
||||
{
|
||||
class LabelPosition;
|
||||
};
|
||||
|
||||
class CORE_EXPORT QgsDxfExport
|
||||
{
|
||||
@ -283,6 +290,9 @@ class CORE_EXPORT QgsDxfExport
|
||||
//! return list of available DXF encodings
|
||||
static QStringList encodings();
|
||||
|
||||
void drawLabel( QString layerId, QgsRenderContext& context, pal::LabelPosition* label, const QgsPalLayerSettings &settings );
|
||||
void registerDxfLayer( QString layerId, QgsFeatureId fid, QString layer );
|
||||
|
||||
private:
|
||||
QList< QPair<QgsVectorLayer*, int> > mLayers;
|
||||
|
||||
@ -350,6 +360,9 @@ class CORE_EXPORT QgsDxfExport
|
||||
|
||||
QHash<QString, int> mBlockHandles;
|
||||
QString mBlockHandle;
|
||||
|
||||
//! DXF layer name for each label feature
|
||||
QMap< QString, QMap<QgsFeatureId, QString> > mDxfLayerNames;
|
||||
};
|
||||
|
||||
#endif // QGSDXFEXPORT_H
|
||||
|
@ -17,131 +17,57 @@
|
||||
|
||||
#include "qgsdxfpallabeling.h"
|
||||
#include "qgsdxfexport.h"
|
||||
#include "qgstextlabelfeature.h"
|
||||
#include "qgspallabeling.h"
|
||||
#include "qgsmapsettings.h"
|
||||
|
||||
#include "pal/feature.h"
|
||||
#include "pal/pointset.h"
|
||||
#include "pal/labelposition.h"
|
||||
#include "qgslogger.h"
|
||||
|
||||
|
||||
QgsDxfLabelProvider::QgsDxfLabelProvider( QgsVectorLayer* layer , QgsDxfExport* dxf )
|
||||
: QgsVectorLayerLabelProvider( layer, false )
|
||||
QgsDxfLabelProvider::QgsDxfLabelProvider( QgsVectorLayer* layer, QgsDxfExport* dxf, const QgsPalLayerSettings *settings )
|
||||
: QgsVectorLayerLabelProvider( layer, false, settings )
|
||||
, mDxfExport( dxf )
|
||||
{
|
||||
}
|
||||
|
||||
void QgsDxfLabelProvider::drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const
|
||||
{
|
||||
Q_UNUSED( context );
|
||||
|
||||
//debug: print label infos
|
||||
if ( mDxfExport )
|
||||
{
|
||||
QgsTextLabelFeature* lf = dynamic_cast<QgsTextLabelFeature*>( label->getFeaturePart()->feature() );
|
||||
if ( !lf )
|
||||
return;
|
||||
|
||||
const QgsPalLayerSettings& tmpLyr = mSettings;
|
||||
|
||||
//label text
|
||||
QString txt = lf->text( label->getPartId() );
|
||||
|
||||
//angle
|
||||
double angle = label->getAlpha() * 180 / M_PI;
|
||||
|
||||
QgsFeatureId fid = label->getFeaturePart()->featureId();
|
||||
QString dxfLayer = mDxfLayerNames[fid];
|
||||
|
||||
//debug: show label rectangle
|
||||
#if 0
|
||||
QgsPolyline line;
|
||||
for ( int i = 0; i < 4; ++i )
|
||||
{
|
||||
line.append( QgsPoint( label->getX( i ), label->getY( i ) ) );
|
||||
}
|
||||
mDxfExport->writePolyline( line, dxfLayer, "CONTINUOUS", 1, 0.01, true );
|
||||
#endif
|
||||
|
||||
QString wrapchr = tmpLyr.wrapChar.isEmpty() ? "\n" : tmpLyr.wrapChar;
|
||||
|
||||
//add the direction symbol if needed
|
||||
if ( !txt.isEmpty() && tmpLyr.placement == QgsPalLayerSettings::Line && tmpLyr.addDirectionSymbol )
|
||||
{
|
||||
bool prependSymb = false;
|
||||
QString symb = tmpLyr.rightDirectionSymbol;
|
||||
|
||||
if ( label->getReversed() )
|
||||
{
|
||||
prependSymb = true;
|
||||
symb = tmpLyr.leftDirectionSymbol;
|
||||
}
|
||||
|
||||
if ( tmpLyr.reverseDirectionSymbol )
|
||||
{
|
||||
if ( symb == tmpLyr.rightDirectionSymbol )
|
||||
{
|
||||
prependSymb = true;
|
||||
symb = tmpLyr.leftDirectionSymbol;
|
||||
}
|
||||
else
|
||||
{
|
||||
prependSymb = false;
|
||||
symb = tmpLyr.rightDirectionSymbol;
|
||||
}
|
||||
}
|
||||
|
||||
if ( tmpLyr.placeDirectionSymbol == QgsPalLayerSettings::SymbolAbove )
|
||||
{
|
||||
prependSymb = true;
|
||||
symb = symb + wrapchr;
|
||||
}
|
||||
else if ( tmpLyr.placeDirectionSymbol == QgsPalLayerSettings::SymbolBelow )
|
||||
{
|
||||
prependSymb = false;
|
||||
symb = wrapchr + symb;
|
||||
}
|
||||
|
||||
if ( prependSymb )
|
||||
{
|
||||
txt.prepend( symb );
|
||||
}
|
||||
else
|
||||
{
|
||||
txt.append( symb );
|
||||
}
|
||||
}
|
||||
|
||||
txt = txt.replace( wrapchr, "\\P" );
|
||||
|
||||
if ( tmpLyr.textFont.underline() )
|
||||
{
|
||||
txt.prepend( "\\L" ).append( "\\l" );
|
||||
}
|
||||
|
||||
if ( tmpLyr.textFont.overline() )
|
||||
{
|
||||
txt.prepend( "\\O" ).append( "\\o" );
|
||||
}
|
||||
|
||||
if ( tmpLyr.textFont.strikeOut() )
|
||||
{
|
||||
txt.prepend( "\\K" ).append( "\\k" );
|
||||
}
|
||||
|
||||
txt.prepend( QString( "\\f%1|i%2|b%3;\\H%4;\\W0.75;" )
|
||||
.arg( tmpLyr.textFont.family() )
|
||||
.arg( tmpLyr.textFont.italic() ? 1 : 0 )
|
||||
.arg( tmpLyr.textFont.bold() ? 1 : 0 )
|
||||
.arg( label->getHeight() / ( 1 + txt.count( "\\P" ) ) * 0.75 ) );
|
||||
|
||||
mDxfExport->writeMText( dxfLayer, txt, QgsPoint( label->getX(), label->getY() ), label->getWidth() * 1.1, angle, tmpLyr.textColor );
|
||||
}
|
||||
Q_ASSERT( mDxfExport );
|
||||
mDxfExport->drawLabel( layerId(), context, label, mSettings );
|
||||
}
|
||||
|
||||
void QgsDxfLabelProvider::registerDxfFeature( QgsFeature& feature, QgsRenderContext& context, const QString& dxfLayerName )
|
||||
{
|
||||
registerFeature( feature, context );
|
||||
mDxfLayerNames[feature.id()] = dxfLayerName;
|
||||
mDxfExport->registerDxfLayer( layerId(), feature.id(), dxfLayerName );
|
||||
}
|
||||
|
||||
QgsDxfRuleBasedLabelProvider::QgsDxfRuleBasedLabelProvider( const QgsRuleBasedLabeling &rules, QgsVectorLayer* layer, QgsDxfExport* dxf )
|
||||
: QgsRuleBasedLabelProvider( rules, layer, false )
|
||||
, mDxfExport( dxf )
|
||||
{
|
||||
}
|
||||
|
||||
void QgsDxfRuleBasedLabelProvider::reinit( QgsVectorLayer* layer )
|
||||
{
|
||||
QgsDebugMsg( "Entering." );
|
||||
mRules.rootRule()->createSubProviders( layer, mSubProviders, this );
|
||||
}
|
||||
|
||||
QgsVectorLayerLabelProvider *QgsDxfRuleBasedLabelProvider::createProvider( QgsVectorLayer *layer, bool withFeatureLoop, const QgsPalLayerSettings *settings )
|
||||
{
|
||||
QgsDebugMsg( "Entering." );
|
||||
Q_UNUSED( withFeatureLoop );
|
||||
return new QgsDxfLabelProvider( layer, mDxfExport, settings );
|
||||
}
|
||||
|
||||
void QgsDxfRuleBasedLabelProvider::drawLabel( QgsRenderContext &context, pal::LabelPosition *label ) const
|
||||
{
|
||||
QgsDebugMsg( "Entering." );
|
||||
Q_ASSERT( mDxfExport );
|
||||
mDxfExport->drawLabel( layerId(), context, label, mSettings );
|
||||
}
|
||||
|
||||
void QgsDxfRuleBasedLabelProvider::registerDxfFeature( QgsFeature &feature, QgsRenderContext &context, const QString &dxfLayerName )
|
||||
{
|
||||
registerFeature( feature, context );
|
||||
mDxfExport->registerDxfLayer( layerId(), feature.id(), dxfLayerName );
|
||||
}
|
||||
|
@ -21,8 +21,11 @@
|
||||
#include "qgsmaprenderer.h"
|
||||
#include "qgsrendercontext.h"
|
||||
#include "qgsvectorlayerlabelprovider.h"
|
||||
#include "qgsrulebasedlabeling.h"
|
||||
|
||||
class QgsDxfExport;
|
||||
class QgsPalLayerSettings;
|
||||
class QgsRuleBasedLabeling;
|
||||
|
||||
|
||||
/** Implements a derived label provider internally used for DXF export
|
||||
@ -34,10 +37,10 @@ class QgsDxfLabelProvider : public QgsVectorLayerLabelProvider
|
||||
{
|
||||
public:
|
||||
//! construct the provider
|
||||
explicit QgsDxfLabelProvider( QgsVectorLayer* layer, QgsDxfExport* dxf );
|
||||
explicit QgsDxfLabelProvider( QgsVectorLayer* layer, QgsDxfExport* dxf, const QgsPalLayerSettings *settings );
|
||||
|
||||
//! re-implementation that writes to DXF file instead of drawing with QPainter
|
||||
virtual void drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const override;
|
||||
void drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const override;
|
||||
|
||||
//! registration method that keeps track of DXF layer names of individual features
|
||||
void registerDxfFeature( QgsFeature& feature, QgsRenderContext &context, const QString& dxfLayerName );
|
||||
@ -45,8 +48,29 @@ class QgsDxfLabelProvider : public QgsVectorLayerLabelProvider
|
||||
protected:
|
||||
//! pointer to parent DXF export where this instance is used
|
||||
QgsDxfExport* mDxfExport;
|
||||
//! DXF layer name for each label feature
|
||||
QMap<QgsFeatureId, QString> mDxfLayerNames;
|
||||
};
|
||||
|
||||
class QgsDxfRuleBasedLabelProvider : public QgsRuleBasedLabelProvider
|
||||
{
|
||||
public:
|
||||
//! construct the provider
|
||||
explicit QgsDxfRuleBasedLabelProvider( const QgsRuleBasedLabeling &rules, QgsVectorLayer* layer, QgsDxfExport* dxf );
|
||||
|
||||
void reinit( QgsVectorLayer* layer );
|
||||
|
||||
//! re-implementation that writes to DXF file instead of drawing with QPainter
|
||||
void drawLabel( QgsRenderContext &context, pal::LabelPosition *label ) const override;
|
||||
|
||||
//! registration method that keeps track of DXF layer names of individual features
|
||||
void registerDxfFeature( QgsFeature& feature, QgsRenderContext &context, const QString& dxfLayerName );
|
||||
|
||||
virtual QgsVectorLayerLabelProvider *createProvider( QgsVectorLayer *layer, bool withFeatureLoop, const QgsPalLayerSettings *settings ) override;
|
||||
|
||||
protected:
|
||||
//! pointer to parent DXF export where this instance is used
|
||||
QgsDxfExport* mDxfExport;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // QGSDXFPALLABELING_H
|
||||
|
@ -13,7 +13,6 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
#include "qgslabelfeature.h"
|
||||
|
||||
#include "feature.h"
|
||||
|
||||
|
||||
|
@ -46,9 +46,10 @@ class QgsDiagramLayerSettings;
|
||||
class CORE_EXPORT QgsLabelPosition
|
||||
{
|
||||
public:
|
||||
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 ):
|
||||
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 ) {}
|
||||
QgsLabelPosition(): featureId( -1 ), rotation( 0 ), labelRect( QgsRectangle() ), width( 0 ), height( 0 ), layerID( "" ), labelText( "" ), labelFont( QFont() ), upsideDown( false ), isDiagram( false ), isPinned( false ) {}
|
||||
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 )
|
||||
: 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 ) {}
|
||||
QgsLabelPosition()
|
||||
: featureId( -1 ), rotation( 0 ), labelRect( QgsRectangle() ), width( 0 ), height( 0 ), layerID( "" ), labelText( "" ), labelFont( QFont() ), upsideDown( false ), isDiagram( false ), isPinned( false ) {}
|
||||
int featureId;
|
||||
double rotation;
|
||||
QVector< QgsPoint > cornerPoints;
|
||||
@ -72,7 +73,7 @@ class CORE_EXPORT QgsLabelingEngineInterface
|
||||
|
||||
//! called when we're going to start with rendering
|
||||
//! @deprecated since 2.4 - use override with QgsMapSettings
|
||||
Q_DECL_DEPRECATED virtual void init( QgsMapRenderer* mp ) = 0;
|
||||
Q_DECL_DEPRECATED virtual void init( QgsMapRenderer *mp ) = 0;
|
||||
//! called when we're going to start with rendering
|
||||
virtual void init( const QgsMapSettings& mapSettings ) = 0;
|
||||
//! called to find out whether the layer is used for labeling
|
||||
@ -85,19 +86,19 @@ class CORE_EXPORT QgsLabelingEngineInterface
|
||||
virtual int prepareLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx ) = 0;
|
||||
//! returns PAL layer settings for a registered layer
|
||||
//! @deprecated since 2.12 - if direct access to QgsPalLayerSettings is necessary, use QgsPalLayerSettings::fromLayer()
|
||||
Q_DECL_DEPRECATED virtual QgsPalLayerSettings& layer( const QString& layerName ) = 0;
|
||||
Q_DECL_DEPRECATED virtual QgsPalLayerSettings &layer( const QString &layerName ) = 0;
|
||||
//! adds a diagram layer to the labeling engine
|
||||
//! @note added in QGIS 2.12
|
||||
virtual int prepareDiagramLayer( QgsVectorLayer* layer, QStringList& attrNames, QgsRenderContext& ctx )
|
||||
virtual int prepareDiagramLayer( QgsVectorLayer *layer, QStringList &attrNames, QgsRenderContext &ctx )
|
||||
{ Q_UNUSED( layer ); Q_UNUSED( attrNames ); Q_UNUSED( ctx ); return 0; }
|
||||
//! adds a diagram layer to the labeling engine
|
||||
//! @deprecated since 2.12 - use prepareDiagramLayer()
|
||||
Q_DECL_DEPRECATED virtual int addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLayerSettings* s )
|
||||
Q_DECL_DEPRECATED virtual int addDiagramLayer( QgsVectorLayer *layer, const QgsDiagramLayerSettings *s )
|
||||
{ Q_UNUSED( layer ); Q_UNUSED( s ); return 0; }
|
||||
//! called for every feature
|
||||
virtual void registerFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context, const QString& dxfLayer = QString::null ) = 0;
|
||||
virtual void registerFeature( const QString &layerID, QgsFeature &feat, QgsRenderContext &context ) = 0;
|
||||
//! called for every diagram feature
|
||||
virtual void registerDiagramFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context )
|
||||
virtual void registerDiagramFeature( const QString &layerID, QgsFeature &feat, QgsRenderContext &context )
|
||||
{ Q_UNUSED( layerID ); Q_UNUSED( feat ); Q_UNUSED( context ); }
|
||||
//! called when the map is drawn and labels should be placed
|
||||
virtual void drawLabeling( QgsRenderContext& context ) = 0;
|
||||
|
@ -1939,13 +1939,11 @@ void QgsPalLayerSettings::calculateLabelSize( const QFontMetricsF* fm, QString t
|
||||
#endif
|
||||
}
|
||||
|
||||
void QgsPalLayerSettings::registerFeature( QgsFeature& f, QgsRenderContext &context, const QString& dxfLayer, QgsLabelFeature** labelFeature , QgsGeometry* obstacleGeometry )
|
||||
void QgsPalLayerSettings::registerFeature( QgsFeature& f, QgsRenderContext &context, QgsLabelFeature** labelFeature , QgsGeometry* obstacleGeometry )
|
||||
{
|
||||
// either used in QgsPalLabeling (palLayer is set) or in QgsLabelingEngineV2 (labelFeature is set)
|
||||
Q_ASSERT( labelFeature );
|
||||
|
||||
Q_UNUSED( dxfLayer ); // now handled in QgsDxfLabelProvider
|
||||
|
||||
QVariant exprVal; // value() is repeatedly nulled on data defined evaluation and replaced when successful
|
||||
mCurFeat = &f;
|
||||
|
||||
@ -1960,7 +1958,7 @@ void QgsPalLayerSettings::registerFeature( QgsFeature& f, QgsRenderContext &cont
|
||||
{
|
||||
if ( isObstacle )
|
||||
{
|
||||
registerObstacleFeature( f, context, QString(), labelFeature, obstacleGeometry );
|
||||
registerObstacleFeature( f, context, labelFeature, obstacleGeometry );
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -2812,10 +2810,8 @@ void QgsPalLayerSettings::registerFeature( QgsFeature& f, QgsRenderContext &cont
|
||||
lf->setDataDefinedValues( dataDefinedValues );
|
||||
}
|
||||
|
||||
void QgsPalLayerSettings::registerObstacleFeature( QgsFeature& f, QgsRenderContext &context, const QString& dxfLayer, QgsLabelFeature** obstacleFeature, QgsGeometry* obstacleGeometry )
|
||||
void QgsPalLayerSettings::registerObstacleFeature( QgsFeature& f, QgsRenderContext &context, QgsLabelFeature** obstacleFeature, QgsGeometry* obstacleGeometry )
|
||||
{
|
||||
Q_UNUSED( dxfLayer ); // now handled in QgsDxfLabelProvider
|
||||
|
||||
mCurFeat = &f;
|
||||
|
||||
const QgsGeometry* geom = nullptr;
|
||||
@ -3809,9 +3805,8 @@ int QgsPalLabeling::addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLaye
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QgsPalLabeling::registerFeature( const QString& layerID, QgsFeature& f, QgsRenderContext &context, const QString& dxfLayer )
|
||||
void QgsPalLabeling::registerFeature( const QString& layerID, QgsFeature& f, QgsRenderContext &context )
|
||||
{
|
||||
Q_UNUSED( dxfLayer ); // now handled by QgsDxfLabelProvider
|
||||
if ( QgsVectorLayerLabelProvider* provider = mLabelProviders.value( layerID, nullptr ) )
|
||||
provider->registerFeature( f, context );
|
||||
}
|
||||
|
@ -533,7 +533,6 @@ class CORE_EXPORT QgsPalLayerSettings
|
||||
* @param f feature to label
|
||||
* @param context render context. The QgsExpressionContext contained within the render context
|
||||
* must have already had the feature and fields sets prior to calling this method.
|
||||
* @param dxfLayer dxfLayer name
|
||||
* @param labelFeature if using QgsLabelingEngineV2, this will receive the label feature. Not available
|
||||
* in Python bindings.
|
||||
* @param obstacleGeometry optional obstacle geometry, if a different geometry to the feature's geometry
|
||||
@ -542,7 +541,7 @@ class CORE_EXPORT QgsPalLayerSettings
|
||||
* the feature's original geometry will be used as an obstacle for labels. Not available
|
||||
* in Python bindings.
|
||||
*/
|
||||
void registerFeature( QgsFeature& f, QgsRenderContext& context, const QString& dxfLayer, QgsLabelFeature** labelFeature = nullptr, QgsGeometry* obstacleGeometry = nullptr );
|
||||
void registerFeature( QgsFeature& f, QgsRenderContext& context, QgsLabelFeature** labelFeature = nullptr, QgsGeometry* obstacleGeometry = nullptr );
|
||||
|
||||
void readFromLayer( QgsVectorLayer* layer );
|
||||
void writeToLayer( QgsVectorLayer* layer );
|
||||
@ -712,7 +711,7 @@ class CORE_EXPORT QgsPalLayerSettings
|
||||
|
||||
/** Registers a feature as an obstacle only (no label rendered)
|
||||
*/
|
||||
void registerObstacleFeature( QgsFeature &f, QgsRenderContext &context, const QString& dxfLayer, QgsLabelFeature** obstacleFeature, QgsGeometry* obstacleGeometry = nullptr );
|
||||
void registerObstacleFeature( QgsFeature &f, QgsRenderContext &context, QgsLabelFeature** obstacleFeature, QgsGeometry* obstacleGeometry = nullptr );
|
||||
|
||||
QMap<DataDefinedProperties, QVariant> dataDefinedValues;
|
||||
QgsExpression* expression;
|
||||
@ -949,9 +948,8 @@ class CORE_EXPORT QgsPalLabeling : public QgsLabelingEngineInterface
|
||||
* @param feat feature to label
|
||||
* @param context render context. The QgsExpressionContext contained within the render context
|
||||
* must have already had the feature and fields sets prior to calling this method.
|
||||
* @param dxfLayer dxfLayer name
|
||||
*/
|
||||
virtual void registerFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context, const QString& dxfLayer = QString::null ) override;
|
||||
virtual void registerFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context ) override;
|
||||
|
||||
virtual void registerDiagramFeature( const QString& layerID, QgsFeature& feat, QgsRenderContext& context ) override;
|
||||
//! called when the map is drawn and labels should be placed
|
||||
|
@ -15,12 +15,11 @@
|
||||
#include "qgsrulebasedlabeling.h"
|
||||
|
||||
|
||||
|
||||
QgsRuleBasedLabelProvider::QgsRuleBasedLabelProvider( const QgsRuleBasedLabeling& rules, QgsVectorLayer* layer, bool withFeatureLoop )
|
||||
: QgsVectorLayerLabelProvider( layer, withFeatureLoop )
|
||||
, mRules( rules )
|
||||
{
|
||||
mRules.rootRule()->createSubProviders( layer, mSubProviders );
|
||||
mRules.rootRule()->createSubProviders( layer, mSubProviders, this );
|
||||
}
|
||||
|
||||
QgsRuleBasedLabelProvider::~QgsRuleBasedLabelProvider()
|
||||
@ -28,6 +27,10 @@ QgsRuleBasedLabelProvider::~QgsRuleBasedLabelProvider()
|
||||
// sub-providers owned by labeling engine
|
||||
}
|
||||
|
||||
QgsVectorLayerLabelProvider *QgsRuleBasedLabelProvider::createProvider( QgsVectorLayer *layer, bool withFeatureLoop, const QgsPalLayerSettings *settings )
|
||||
{
|
||||
return new QgsVectorLayerLabelProvider( layer, withFeatureLoop, settings );
|
||||
}
|
||||
|
||||
bool QgsRuleBasedLabelProvider::prepare( const QgsRenderContext& context, QStringList& attributeNames )
|
||||
{
|
||||
@ -213,19 +216,20 @@ QDomElement QgsRuleBasedLabeling::Rule::save( QDomDocument& doc ) const
|
||||
return ruleElem;
|
||||
}
|
||||
|
||||
void QgsRuleBasedLabeling::Rule::createSubProviders( QgsVectorLayer* layer, QgsRuleBasedLabeling::RuleToProviderMap& subProviders )
|
||||
void QgsRuleBasedLabeling::Rule::createSubProviders( QgsVectorLayer* layer, QgsRuleBasedLabeling::RuleToProviderMap& subProviders, QgsRuleBasedLabelProvider *provider )
|
||||
{
|
||||
if ( mSettings )
|
||||
{
|
||||
// add provider!
|
||||
QgsVectorLayerLabelProvider* p = new QgsVectorLayerLabelProvider( layer, false, mSettings );
|
||||
QgsVectorLayerLabelProvider *p = provider->createProvider( layer, false, mSettings );
|
||||
delete subProviders.value( this, nullptr );
|
||||
subProviders[this] = p;
|
||||
}
|
||||
|
||||
// call recursively
|
||||
Q_FOREACH ( Rule* rule, mChildren )
|
||||
{
|
||||
rule->createSubProviders( layer, subProviders );
|
||||
rule->createSubProviders( layer, subProviders, provider );
|
||||
}
|
||||
}
|
||||
|
||||
@ -262,6 +266,8 @@ QgsRuleBasedLabeling::Rule::RegisterResult QgsRuleBasedLabeling::Rule::registerF
|
||||
|
||||
bool registered = false;
|
||||
|
||||
Q_ASSERT( !mSettings == subProviders.contains( this ) );
|
||||
|
||||
// do we have active subprovider for the rule?
|
||||
if ( subProviders.contains( this ) && mIsActive )
|
||||
{
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <QMap>
|
||||
|
||||
#include "qgsvectorlayerlabeling.h"
|
||||
#include "qgsvectorlayerlabelprovider.h"
|
||||
|
||||
class QDomDocument;
|
||||
class QDomElement;
|
||||
@ -28,6 +29,7 @@ class QgsFeature;
|
||||
class QgsPalLayerSettings;
|
||||
class QgsRenderContext;
|
||||
class QgsGeometry;
|
||||
class QgsRuleBasedLabelProvider;
|
||||
|
||||
/**
|
||||
* @class QgsRuleBasedLabeling
|
||||
@ -42,7 +44,6 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
|
||||
typedef QList<Rule*> RuleList;
|
||||
typedef QMap<Rule*, QgsVectorLayerLabelProvider*> RuleToProviderMap;
|
||||
|
||||
|
||||
/**
|
||||
* @class QgsRuleBasedLabeling::Rule
|
||||
* @note not available in Python bindings
|
||||
@ -214,7 +215,7 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
|
||||
// evaluation
|
||||
|
||||
//! add providers
|
||||
void createSubProviders( QgsVectorLayer* layer, RuleToProviderMap& subProviders );
|
||||
void createSubProviders( QgsVectorLayer* layer, RuleToProviderMap& subProviders, QgsRuleBasedLabelProvider *provider );
|
||||
|
||||
//! call prepare() on sub-providers and populate attributeNames
|
||||
void prepare( const QgsRenderContext& context, QStringList& attributeNames, RuleToProviderMap& subProviders );
|
||||
@ -285,15 +286,13 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
|
||||
|
||||
virtual QString type() const override;
|
||||
virtual QDomElement save( QDomDocument& doc ) const override;
|
||||
virtual QgsVectorLayerLabelProvider* provider( QgsVectorLayer* layer ) const override;
|
||||
virtual QgsVectorLayerLabelProvider *provider( QgsVectorLayer* layer ) const override;
|
||||
|
||||
protected:
|
||||
Rule* mRootRule;
|
||||
};
|
||||
|
||||
|
||||
#include "qgsvectorlayerlabelprovider.h"
|
||||
|
||||
/**
|
||||
* @class QgsRuleBasedLabelProvider
|
||||
* @note not available in Python bindings
|
||||
@ -312,6 +311,7 @@ class CORE_EXPORT QgsRuleBasedLabelProvider : public QgsVectorLayerLabelProvider
|
||||
virtual void registerFeature( QgsFeature& feature, QgsRenderContext& context, QgsGeometry* obstacleGeometry = nullptr ) override;
|
||||
|
||||
// new methods
|
||||
virtual QgsVectorLayerLabelProvider *createProvider( QgsVectorLayer *layer, bool withFeatureLoop, const QgsPalLayerSettings *settings );
|
||||
|
||||
virtual QList<QgsAbstractLabelProvider*> subProviders() override;
|
||||
|
||||
|
@ -316,7 +316,7 @@ QList<QgsLabelFeature*> QgsVectorLayerLabelProvider::labelFeatures( QgsRenderCon
|
||||
void QgsVectorLayerLabelProvider::registerFeature( QgsFeature& feature, QgsRenderContext& context, QgsGeometry* obstacleGeometry )
|
||||
{
|
||||
QgsLabelFeature* label = nullptr;
|
||||
mSettings.registerFeature( feature, context, QString(), &label, obstacleGeometry );
|
||||
mSettings.registerFeature( feature, context, &label, obstacleGeometry );
|
||||
if ( label )
|
||||
mLabels << label;
|
||||
}
|
||||
|
@ -116,5 +116,4 @@ class CORE_EXPORT QgsVectorLayerLabelProvider : public QgsAbstractLabelProvider
|
||||
QList<QgsLabelFeature*> mLabels;
|
||||
};
|
||||
|
||||
|
||||
#endif // QGSVECTORLAYERLABELPROVIDER_H
|
||||
|
@ -259,7 +259,7 @@ void TestQgsLabelingEngineV2::testRuleBased()
|
||||
|
||||
delete rl2;
|
||||
|
||||
/*
|
||||
#if 0
|
||||
QPainter p( &img );
|
||||
QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings );
|
||||
context.setPainter( &p );
|
||||
@ -267,7 +267,8 @@ void TestQgsLabelingEngineV2::testRuleBased()
|
||||
QgsLabelingEngineV2 engine;
|
||||
engine.setMapSettings( mapSettings );
|
||||
engine.addProvider( new QgsRuleBasedLabelProvider( , vl ) );
|
||||
engine.run( context );*/
|
||||
engine.run( context );
|
||||
#endif
|
||||
}
|
||||
|
||||
void TestQgsLabelingEngineV2::zOrder()
|
||||
|
Loading…
x
Reference in New Issue
Block a user