mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-03 00:05:24 -04:00
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:
parent
f0bc2e9b5a
commit
c7b394d9b7
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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 );
|
||||
|
Loading…
x
Reference in New Issue
Block a user