Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
wonder-sk committed Sep 21, 2015
1 parent f0bc2e9 commit c7b394d
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 80 deletions.
45 changes: 39 additions & 6 deletions src/core/dxf/qgsdxfexport.cpp
Expand Up @@ -876,16 +876,42 @@ void QgsDxfExport::writeBlocks()
endSection();
}


void QgsDxfExport::writeEntities()
{
startSection();
writeGroup( 2, "ENTITIES" );

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();
Expand Down Expand Up @@ -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 ) &&
Expand Down Expand Up @@ -973,17 +1005,18 @@ 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 );
}
}
}

renderer->stopRender( ctx );
}

labelEngine.drawLabeling( ctx );
engine.run( ctx );

endSection();
}

Expand Down
61 changes: 17 additions & 44 deletions src/core/dxf/qgsdxfpallabeling.cpp
Expand Up @@ -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 )
Expand All @@ -80,20 +42,25 @@ 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;
for ( int i = 0; i < 4; ++i )
{
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;
Expand Down Expand Up @@ -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;
}
31 changes: 18 additions & 13 deletions src/core/dxf/qgsdxfpallabeling.h
Expand Up @@ -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:
QgsDxfExport* mDxfExport;
QgsRenderContext mRenderContext;
//! registration method that keeps track of DXF layer names of individual features
void registerDxfFeature( QgsFeature& feature, const QgsRenderContext& context, const QString& dxfLayerName );

//only used for render context
QImage* mImage;
QPainter* mPainter;
QgsMapSettings* mSettings;
protected:
//! pointer to parent DXF export where this instance is used
QgsDxfExport* mDxfExport;
//! DXF layer name for each label feature
QMap<QgsFeatureId, QString> mDxfLayerNames;
};

#endif // QGSDXFPALLABELING_H
5 changes: 0 additions & 5 deletions src/core/qgspalgeometry.h
Expand Up @@ -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;
Expand All @@ -175,8 +172,6 @@ class QgsPalGeometry : public PalGeometry

/** Stores attribute values for diagram rendering*/
QgsAttributes mDiagramAttributes;

QString mDxfLayer;
};

#endif //QGSPALGEOMETRY_H
14 changes: 6 additions & 8 deletions src/core/qgspallabeling.cpp
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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 );

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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 );

Expand Down Expand Up @@ -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 );
}
Expand Down Expand Up @@ -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,
Expand Down
4 changes: 0 additions & 4 deletions src/core/qgspallabeling.h
Expand Up @@ -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 );
Expand Down

0 comments on commit c7b394d

Please sign in to comment.