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.
This commit is contained in:
Martin Dobias 2015-09-19 13:14:11 +08:00
parent f0bc2e9b5a
commit c7b394d9b7
6 changed files with 80 additions and 80 deletions

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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<QgsFeatureId, QString> mDxfLayerNames;
};
#endif // QGSDXFPALLABELING_H

View File

@ -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

View File

@ -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,

View File

@ -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<QgsLabelCandidate>* 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 );