From c7b394d9b748fa2bcc7d6aa624a9c6b558b9533a Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Sat, 19 Sep 2015 13:14:11 +0800 Subject: [PATCH] Port DXF labeling to new labeling engine This code has been funded by Tuscany Region (Italy) - SITA (CIG: 63526840AE) and commissioned to Gis3W s.a.s. --- src/core/dxf/qgsdxfexport.cpp | 45 +++++++++++++++++++--- src/core/dxf/qgsdxfpallabeling.cpp | 61 +++++++++--------------------- src/core/dxf/qgsdxfpallabeling.h | 31 ++++++++------- src/core/qgspalgeometry.h | 5 --- src/core/qgspallabeling.cpp | 14 +++---- src/core/qgspallabeling.h | 4 -- 6 files changed, 80 insertions(+), 80 deletions(-) diff --git a/src/core/dxf/qgsdxfexport.cpp b/src/core/dxf/qgsdxfexport.cpp index b4b2238ac79..e6d41330fab 100644 --- a/src/core/dxf/qgsdxfexport.cpp +++ b/src/core/dxf/qgsdxfexport.cpp @@ -876,6 +876,7 @@ void QgsDxfExport::writeBlocks() endSection(); } + void QgsDxfExport::writeEntities() { startSection(); @@ -883,9 +884,34 @@ void QgsDxfExport::writeEntities() mBlockHandle = QString( "%1" ).arg( mBlockHandles[ "*Model_Space" ], 0, 16 ); + QgsRectangle bbox = mExtent.isEmpty() ? dxfExtent() : mExtent; + + QgsMapSettings mapSettings; + mapSettings.setMapUnits( mMapUnits ); + mapSettings.setExtent( bbox ); + + int dpi = 96; + double factor = 1000 * dpi / mSymbologyScaleDenominator / 25.4 * QGis::fromUnitToUnitFactor( mMapUnits, QGis::Meters ); + mapSettings.setOutputSize( QSize( bbox.width() * factor, bbox.height() * factor ) ); + mapSettings.setOutputDpi( dpi ); + mapSettings.setCrsTransformEnabled( false ); + + QImage image( 10, 10, QImage::Format_ARGB32_Premultiplied ); + image.setDotsPerMeterX( 96 / 25.4 * 1000 ); + image.setDotsPerMeterY( 96 / 25.4 * 1000 ); + QPainter painter( &image ); + QgsRenderContext ctx; + ctx.setPainter( &painter ); + ctx.setRendererScale( mSymbologyScaleDenominator ); + ctx.setExtent( bbox ); + ctx.setScaleFactor( 96.0 / 25.4 ); + Q_NOWARN_DEPRECATED_PUSH + ctx.setMapToPixel( QgsMapToPixel( 1.0 / factor, bbox.xMinimum(), bbox.yMinimum(), bbox.height() * factor ) ); + Q_NOWARN_DEPRECATED_POP + // label engine - QgsDxfPalLabeling labelEngine( this, mExtent.isEmpty() ? dxfExtent() : mExtent, mSymbologyScaleDenominator, mMapUnits ); - QgsRenderContext& ctx = labelEngine.renderContext(); + QgsLabelingEngineV2 engine; + engine.setMapSettings( mapSettings ); // iterate through the maplayers QList< QPair< QgsVectorLayer*, int > >::iterator layerIt = mLayers.begin(); @@ -913,7 +939,13 @@ void QgsDxfExport::writeEntities() attributes << layerAttr; } - bool labelLayer = labelEngine.prepareLayer( vl, attributes, ctx ) != 0; + QgsDxfLabelProvider* lp = new QgsDxfLabelProvider( vl, this ); + engine.addProvider( lp ); + if ( !lp->prepare( ctx, attributes ) ) + { + engine.removeProvider( lp ); + lp = 0; + } if ( mSymbologyExport == QgsDxfExport::SymbolLayerSymbology && ( renderer->capabilities() & QgsFeatureRendererV2::SymbolLevels ) && @@ -973,9 +1005,9 @@ void QgsDxfExport::writeEntities() addFeature( sctx, layerName, s->symbolLayer( 0 ), s ); } - if ( labelLayer ) + if ( lp ) { - labelEngine.registerFeature( vl->id(), fet, ctx, layerName ); + lp->registerDxfFeature( fet, ctx, layerName ); } } } @@ -983,7 +1015,8 @@ void QgsDxfExport::writeEntities() renderer->stopRender( ctx ); } - labelEngine.drawLabeling( ctx ); + engine.run( ctx ); + endSection(); } diff --git a/src/core/dxf/qgsdxfpallabeling.cpp b/src/core/dxf/qgsdxfpallabeling.cpp index 39931809e04..4c7ee708c10 100644 --- a/src/core/dxf/qgsdxfpallabeling.cpp +++ b/src/core/dxf/qgsdxfpallabeling.cpp @@ -18,60 +18,22 @@ #include "qgsdxfpallabeling.h" #include "qgsdxfexport.h" #include "qgspalgeometry.h" +#include "qgspallabeling.h" #include "qgsmapsettings.h" #include "pal/pointset.h" #include "pal/labelposition.h" -using namespace pal; -QgsDxfPalLabeling::QgsDxfPalLabeling( QgsDxfExport* dxf, const QgsRectangle& bbox, double scale, QGis::UnitType mapUnits ) - : QgsPalLabeling() +QgsDxfLabelProvider::QgsDxfLabelProvider( QgsVectorLayer* layer , QgsDxfExport* dxf ) + : QgsVectorLayerLabelProvider( layer, false ) , mDxfExport( dxf ) - , mImage( 0 ) - , mPainter( 0 ) { - mSettings = new QgsMapSettings; - mSettings->setMapUnits( mapUnits ); - mSettings->setExtent( bbox ); - - int dpi = 96; - double factor = 1000 * dpi / scale / 25.4 * QGis::fromUnitToUnitFactor( mapUnits, QGis::Meters ); - mSettings->setOutputSize( QSize( bbox.width() * factor, bbox.height() * factor ) ); - mSettings->setOutputDpi( dpi ); - mSettings->setCrsTransformEnabled( false ); - init( *mSettings ); - - mImage = new QImage( 10, 10, QImage::Format_ARGB32_Premultiplied ); - mImage->setDotsPerMeterX( 96 / 25.4 * 1000 ); - mImage->setDotsPerMeterY( 96 / 25.4 * 1000 ); - mPainter = new QPainter( mImage ); - mRenderContext.setPainter( mPainter ); - mRenderContext.setRendererScale( scale ); - mRenderContext.setExtent( bbox ); - mRenderContext.setScaleFactor( 96.0 / 25.4 ); - Q_NOWARN_DEPRECATED_PUSH - mRenderContext.setMapToPixel( QgsMapToPixel( 1.0 / factor, bbox.xMinimum(), bbox.yMinimum(), bbox.height() * factor ) ); - Q_NOWARN_DEPRECATED_POP } -QgsDxfPalLabeling::~QgsDxfPalLabeling() -{ - delete mPainter; - delete mImage; - delete mSettings; -} - -void QgsDxfPalLabeling::drawLabel( pal::LabelPosition* label, QgsRenderContext& context, QgsPalLayerSettings& tmpLyr, DrawLabelType drawType, double dpiRatio ) +void QgsDxfLabelProvider::drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const { Q_UNUSED( context ); - Q_UNUSED( drawType ); - Q_UNUSED( dpiRatio ); - - if ( drawType == QgsPalLabeling::LabelBuffer ) - { - return; - } //debug: print label infos if ( mDxfExport ) @@ -80,12 +42,17 @@ void QgsDxfPalLabeling::drawLabel( pal::LabelPosition* label, QgsRenderContext& if ( !g ) return; + const QgsPalLayerSettings& tmpLyr = mSettings; + //label text QString txt = g->text( label->getPartId() ); //angle double angle = label->getAlpha() * 180 / M_PI; + QgsFeatureId fid = STRING_TO_FID( label->getFeaturePart()->getUID() ); + QString dxfLayer = mDxfLayerNames[fid]; + //debug: show label rectangle #if 0 QgsPolyline line; @@ -93,7 +60,7 @@ void QgsDxfPalLabeling::drawLabel( pal::LabelPosition* label, QgsRenderContext& { line.append( QgsPoint( label->getX( i ), label->getY( i ) ) ); } - mDxfExport->writePolyline( line, g->dxfLayer(), "CONTINUOUS", 1, 0.01, true ); + mDxfExport->writePolyline( line, dxfLayer, "CONTINUOUS", 1, 0.01, true ); #endif QString wrapchr = tmpLyr.wrapChar.isEmpty() ? "\n" : tmpLyr.wrapChar; @@ -168,6 +135,12 @@ void QgsDxfPalLabeling::drawLabel( pal::LabelPosition* label, QgsRenderContext& .arg( tmpLyr.textFont.bold() ? 1 : 0 ) .arg( label->getHeight() / ( 1 + txt.count( "\\P" ) ) * 0.75 ) ); - mDxfExport->writeMText( g->dxfLayer(), txt, QgsPoint( label->getX(), label->getY() ), label->getWidth() * 1.1, angle, tmpLyr.textColor ); + mDxfExport->writeMText( dxfLayer, txt, QgsPoint( label->getX(), label->getY() ), label->getWidth() * 1.1, angle, tmpLyr.textColor ); } } + +void QgsDxfLabelProvider::registerDxfFeature( QgsFeature& feature, const QgsRenderContext& context, const QString& dxfLayerName ) +{ + registerFeature( feature, context ); + mDxfLayerNames[feature.id()] = dxfLayerName; +} diff --git a/src/core/dxf/qgsdxfpallabeling.h b/src/core/dxf/qgsdxfpallabeling.h index 09aa707f232..71a76ca7771 100644 --- a/src/core/dxf/qgsdxfpallabeling.h +++ b/src/core/dxf/qgsdxfpallabeling.h @@ -18,29 +18,34 @@ #ifndef QGSDXFPALLABELING_H #define QGSDXFPALLABELING_H -#include "qgspallabeling.h" #include "qgsmaprenderer.h" #include "qgsrendercontext.h" +#include "qgsvectorlayerlabelprovider.h" class QgsDxfExport; -class CORE_EXPORT QgsDxfPalLabeling : public QgsPalLabeling + +/** Implements a derived label provider internally used for DXF export + * + * Internal class, not in public API. Added in QGIS 2.12 + */ +class QgsDxfLabelProvider : public QgsVectorLayerLabelProvider { public: - QgsDxfPalLabeling( QgsDxfExport* dxf, const QgsRectangle& bbox, double scale, QGis::UnitType mapUnits ); - ~QgsDxfPalLabeling(); + //! construct the provider + explicit QgsDxfLabelProvider( QgsVectorLayer* layer, QgsDxfExport* dxf ); - QgsRenderContext& renderContext() { return mRenderContext; } - void drawLabel( pal::LabelPosition* label, QgsRenderContext& context, QgsPalLayerSettings& tmpLyr, DrawLabelType drawType, double dpiRatio = 1.0 ) override; + //! re-implementation that writes to DXF file instead of drawing with QPainter + virtual void drawLabel( QgsRenderContext& context, pal::LabelPosition* label ) const override; - private: + //! registration method that keeps track of DXF layer names of individual features + void registerDxfFeature( QgsFeature& feature, const QgsRenderContext& context, const QString& dxfLayerName ); + + protected: + //! pointer to parent DXF export where this instance is used QgsDxfExport* mDxfExport; - QgsRenderContext mRenderContext; - - //only used for render context - QImage* mImage; - QPainter* mPainter; - QgsMapSettings* mSettings; + //! DXF layer name for each label feature + QMap mDxfLayerNames; }; #endif // QGSDXFPALLABELING_H diff --git a/src/core/qgspalgeometry.h b/src/core/qgspalgeometry.h index d93272d2e57..5cf8e0bc222 100644 --- a/src/core/qgspalgeometry.h +++ b/src/core/qgspalgeometry.h @@ -153,9 +153,6 @@ class QgsPalGeometry : public PalGeometry feature.setValid( true ); } - void setDxfLayer( QString dxfLayer ) { mDxfLayer = dxfLayer; } - QString dxfLayer() const { return mDxfLayer; } - protected: GEOSGeometry* mG; QString mText; @@ -175,8 +172,6 @@ class QgsPalGeometry : public PalGeometry /** Stores attribute values for diagram rendering*/ QgsAttributes mDiagramAttributes; - - QString mDxfLayer; }; #endif //QGSPALGEOMETRY_H diff --git a/src/core/qgspallabeling.cpp b/src/core/qgspallabeling.cpp index ba4329740d7..217d4fa4130 100644 --- a/src/core/qgspallabeling.cpp +++ b/src/core/qgspallabeling.cpp @@ -1471,11 +1471,13 @@ void QgsPalLayerSettings::registerFeature( QgsFeature& f, const QgsRenderContext // either used in QgsPalLabeling (palLayer is set) or in QgsLabelingEngineV2 (labelFeature is set) Q_ASSERT( labelFeature ); + Q_UNUSED( dxfLayer ); // now handled in QgsDxfLabelProvider + if ( !drawLabels ) { if ( obstacle ) { - registerObstacleFeature( f, context, dxfLayer, labelFeature ); + registerObstacleFeature( f, context, QString(), labelFeature ); } return; } @@ -2140,8 +2142,6 @@ void QgsPalLayerSettings::registerFeature( QgsFeature& f, const QgsRenderContext labelFont.wordSpacing(), placement == QgsPalLayerSettings::Curved ); - lbl->setDxfLayer( dxfLayer ); - // record the created geometry - it will be deleted at the end. geometries.append( lbl ); @@ -2296,6 +2296,8 @@ void QgsPalLayerSettings::registerFeature( QgsFeature& f, const QgsRenderContext void QgsPalLayerSettings::registerObstacleFeature( QgsFeature& f, const QgsRenderContext& context, QString dxfLayer , QgsLabelFeature** obstacleFeature ) { + Q_UNUSED( dxfLayer ); // now handled in QgsDxfLabelProvider + mCurFeat = &f; const QgsGeometry* geom = f.constGeometry(); @@ -2327,8 +2329,6 @@ void QgsPalLayerSettings::registerObstacleFeature( QgsFeature& f, const QgsRende QgsPalGeometry* lbl = new QgsPalGeometry( f.id(), QString(), geos_geom_clone ); - lbl->setDxfLayer( dxfLayer ); - // record the created geometry - it will be deleted at the end. geometries.append( lbl ); @@ -3278,6 +3278,7 @@ int QgsPalLabeling::addDiagramLayer( QgsVectorLayer* layer, const QgsDiagramLaye void QgsPalLabeling::registerFeature( const QString& layerID, QgsFeature& f, const QgsRenderContext& context, QString dxfLayer ) { + Q_UNUSED( dxfLayer ); // now handled by QgsDxfLabelProvider if ( QgsVectorLayerLabelProvider* provider = mLabelProviders.value( layerID, 0 ) ) provider->registerFeature( f, context ); } @@ -3967,9 +3968,6 @@ void QgsPalLabeling::drawLabelCandidateRect( pal::LabelPosition* lp, QPainter* p drawLabelCandidateRect( lp->getNextPart(), painter, xform, candidates ); } -void QgsPalLabeling::drawLabel( pal::LabelPosition* label, QgsRenderContext& context, QgsPalLayerSettings& tmpLyr, DrawLabelType drawType, double dpiRatio ) -{ -} void QgsPalLabeling::drawLabelBuffer( QgsRenderContext& context, const QgsLabelComponent& component, diff --git a/src/core/qgspallabeling.h b/src/core/qgspallabeling.h index 8821f62c957..5580f068da2 100644 --- a/src/core/qgspallabeling.h +++ b/src/core/qgspallabeling.h @@ -886,10 +886,6 @@ class CORE_EXPORT QgsPalLabeling : public QgsLabelingEngineInterface //! @note not available in python bindings static void drawLabelCandidateRect( pal::LabelPosition* lp, QPainter* painter, const QgsMapToPixel* xform, QList* candidates = 0 ); - //!drawLabel - //! @note not available in python bindings - virtual void drawLabel( pal::LabelPosition* label, QgsRenderContext& context, QgsPalLayerSettings& tmpLyr, DrawLabelType drawType, double dpiRatio = 1.0 ); - static void drawLabelBuffer( QgsRenderContext& context, const QgsLabelComponent &component, const QgsPalLayerSettings& tmpLyr );