Skip to content

Commit 18f0af8

Browse files
mhugentnyalldawson
authored andcommitted
Port dxf export improvements to QGIS 3
1 parent aa47dbe commit 18f0af8

9 files changed

+152
-45
lines changed

python/core/auto_generated/dxf/qgsdxfexport.sip.in

+14-3
Original file line numberDiff line numberDiff line change
@@ -397,10 +397,21 @@ Write mtext (MTEXT)
397397
.. versionadded:: 2.15
398398
%End
399399

400-
static double mapUnitScaleFactor( double scale, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits );
400+
static double mapUnitScaleFactor( double scaleDenominator, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits, double mapUnitsPerPixel = 1.0 );
401401
%Docstring
402-
Calculates a scaling factor to convert from map units to a specified symbol unit.
403-
The ``scale`` parameter indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
402+
Returns scale factor for conversion to map units
403+
@param scaleDenominator the map scale denominator
404+
@param symbolUnits the symbol output units
405+
@param mapUnits the map units
406+
@param mapUnitsPerPixel Map units per pixel*
407+
%End
408+
409+
void clipValueToMapUnitScale( double &value, const QgsMapUnitScale &scale, double pixelToMMFactor ) const;
410+
%Docstring
411+
Clips value to scale minimum/maximum
412+
@param value the value to clip
413+
@param scale the scale dependent minimum/maximum values
414+
@param pixelToMMFactor pixels per mm*
404415
%End
405416

406417
static QString dxfLayerName( const QString &name );

src/core/dxf/qgsdxfexport.cpp

+49-7
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,7 @@ void QgsDxfExport::writeBlocks()
930930
writeGroup( 1, QLatin1String( "" ) );
931931

932932
// maplayer 0 -> block receives layer from INSERT statement
933-
ml->writeDxf( *this, mapUnitScaleFactor( mSymbologyScale, ml->sizeUnit(), mMapUnits ), QStringLiteral( "0" ), ctx );
933+
ml->writeDxf( *this, mapUnitScaleFactor( mSymbologyScale, ml->sizeUnit(), mMapUnits, ctx.renderContext().mapToPixel().mapUnitsPerPixel() ), QStringLiteral( "0" ), ctx );
934934

935935
writeGroup( 0, QStringLiteral( "ENDBLK" ) );
936936
writeHandle();
@@ -966,6 +966,9 @@ void QgsDxfExport::writeEntities()
966966
ctx.setMapToPixel( QgsMapToPixel( 1.0 / mFactor, mExtent.center().x(), mExtent.center().y(), mExtent.width() * mFactor,
967967
mExtent.height() * mFactor, 0 ) );
968968

969+
ctx.expressionContext().appendScope( QgsExpressionContextUtils::projectScope( QgsProject::instance() ) );
970+
ctx.expressionContext().appendScope( QgsExpressionContextUtils::globalScope() );
971+
969972
// label engine
970973
QgsLabelingEngine engine;
971974
engine.setMapSettings( mMapSettings );
@@ -3435,7 +3438,7 @@ void QgsDxfExport::writePoint( const QgsPoint &pt, const QString &layer, const Q
34353438
const QgsMarkerSymbolLayer *msl = dynamic_cast< const QgsMarkerSymbolLayer * >( symbolLayer );
34363439
if ( msl && symbol )
34373440
{
3438-
if ( symbolLayer->writeDxf( *this, mapUnitScaleFactor( mSymbologyScale, msl->sizeUnit(), mMapUnits ), layer, ctx, QPointF( pt.x(), pt.y() ) ) )
3441+
if ( symbolLayer->writeDxf( *this, mapUnitScaleFactor( mSymbologyScale, msl->sizeUnit(), mMapUnits, ctx.renderContext().mapToPixel().mapUnitsPerPixel() ), layer, ctx, QPointF( pt.x(), pt.y() ) ) )
34393442
{
34403443
return;
34413444
}
@@ -3982,14 +3985,53 @@ QgsRenderContext QgsDxfExport::renderContext() const
39823985
return context;
39833986
}
39843987

3985-
double QgsDxfExport::mapUnitScaleFactor( double scale, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits )
3988+
double QgsDxfExport::mapUnitScaleFactor( double scaleDenominator, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits, double mapUnitsPerPixel )
39863989
{
39873990
if ( symbolUnits == QgsUnitTypes::RenderMapUnits )
39883991
{
39893992
return 1.0;
39903993
}
3991-
// MM symbol unit
3992-
return scale * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceMeters, mapUnits ) / 1000.0;
3994+
else if ( symbolUnits == QgsUnitTypes::RenderMillimeters )
3995+
{
3996+
return ( scaleDenominator * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceMeters, mapUnits ) / 1000.0 );
3997+
}
3998+
else if ( symbolUnits == QgsUnitTypes::RenderPixels )
3999+
{
4000+
return mapUnitsPerPixel;
4001+
}
4002+
return 1.0;
4003+
}
4004+
4005+
void QgsDxfExport::clipValueToMapUnitScale( double &value, const QgsMapUnitScale &scale, double pixelToMMFactor ) const
4006+
{
4007+
if ( !scale.minSizeMMEnabled && !scale.maxSizeMMEnabled )
4008+
{
4009+
return;
4010+
}
4011+
4012+
double mapUnitsPerPixel = mMapSettings.mapToPixel().mapUnitsPerPixel();
4013+
4014+
double minSizeMU = -DBL_MAX;
4015+
if ( scale.minSizeMMEnabled )
4016+
{
4017+
minSizeMU = scale.minSizeMM * pixelToMMFactor * mapUnitsPerPixel;
4018+
}
4019+
if ( !qgsDoubleNear( scale.minScale, 0.0 ) )
4020+
{
4021+
minSizeMU = qMax( minSizeMU, value );
4022+
}
4023+
value = qMax( value, minSizeMU );
4024+
4025+
double maxSizeMU = DBL_MAX;
4026+
if ( scale.maxSizeMMEnabled )
4027+
{
4028+
maxSizeMU = scale.maxSizeMM * pixelToMMFactor * mapUnitsPerPixel;
4029+
}
4030+
if ( !qgsDoubleNear( scale.maxScale, 0.0 ) )
4031+
{
4032+
maxSizeMU = qMin( maxSizeMU, value );
4033+
}
4034+
value = qMin( value, maxSizeMU );
39934035
}
39944036

39954037
QList< QPair< QgsSymbolLayer *, QgsSymbol * > > QgsDxfExport::symbolLayers( QgsRenderContext &context )
@@ -4122,7 +4164,7 @@ void QgsDxfExport::writeLinetype( const QString &styleName, const QVector<qreal>
41224164
QVector<qreal>::const_iterator dashIt = pattern.constBegin();
41234165
for ( ; dashIt != pattern.constEnd(); ++dashIt )
41244166
{
4125-
length += ( *dashIt * mapUnitScaleFactor( mSymbologyScale, u, mMapUnits ) );
4167+
length += ( *dashIt * mapUnitScaleFactor( mSymbologyScale, u, mMapUnits, mMapSettings.mapToPixel().mapUnitsPerPixel() ) );
41264168
}
41274169

41284170
writeGroup( 0, QStringLiteral( "LTYPE" ) );
@@ -4143,7 +4185,7 @@ void QgsDxfExport::writeLinetype( const QString &styleName, const QVector<qreal>
41434185
{
41444186
// map units or mm?
41454187
double segmentLength = ( isGap ? -*dashIt : *dashIt );
4146-
segmentLength *= mapUnitScaleFactor( mSymbologyScale, u, mMapUnits );
4188+
segmentLength *= mapUnitScaleFactor( mSymbologyScale, u, mMapUnits, mMapSettings.mapToPixel().mapUnitsPerPixel() );
41474189
writeGroup( 49, segmentLength );
41484190
writeGroup( 74, 0 );
41494191
isGap = !isGap;

src/core/dxf/qgsdxfexport.h

+13-4
Original file line numberDiff line numberDiff line change
@@ -385,10 +385,19 @@ class CORE_EXPORT QgsDxfExport
385385
void writeMText( const QString &layer, const QString &text, const QgsPoint &pt, double width, double angle, const QColor &color );
386386

387387
/**
388-
* Calculates a scaling factor to convert from map units to a specified symbol unit.
389-
* The \a scale parameter indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
390-
*/
391-
static double mapUnitScaleFactor( double scale, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits );
388+
* Returns scale factor for conversion to map units
389+
* @param scaleDenominator the map scale denominator
390+
* @param symbolUnits the symbol output units
391+
* @param mapUnits the map units
392+
* @param mapUnitsPerPixel Map units per pixel*/
393+
static double mapUnitScaleFactor( double scaleDenominator, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits, double mapUnitsPerPixel = 1.0 );
394+
395+
/**
396+
* Clips value to scale minimum/maximum
397+
* @param value the value to clip
398+
* @param scale the scale dependent minimum/maximum values
399+
* @param pixelToMMFactor pixels per mm*/
400+
void clipValueToMapUnitScale( double &value, const QgsMapUnitScale &scale, double pixelToMMFactor ) const;
392401

393402
//! Returns cleaned layer name for use in DXF
394403
static QString dxfLayerName( const QString &name );

src/core/dxf/qgsdxfpaintengine.cpp

+32-4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ QgsDxfPaintEngine::QgsDxfPaintEngine( const QgsDxfPaintDevice *dxfDevice, QgsDxf
2424
: QPaintEngine( QPaintEngine::AllFeatures /*QPaintEngine::PainterPaths | QPaintEngine::PaintOutsidePaintEvent*/ )
2525
, mPaintDevice( dxfDevice )
2626
, mDxf( dxf )
27+
, mOpacity( 1.0 )
2728
{
2829
}
2930

@@ -60,6 +61,11 @@ void QgsDxfPaintEngine::updateState( const QPaintEngineState &state )
6061

6162
if ( state.state() & QPaintEngine::DirtyBrush )
6263
mBrush = state.brush();
64+
65+
if ( state.state() & QPaintEngine::DirtyOpacity )
66+
{
67+
mOpacity = state.opacity();
68+
}
6369
}
6470

6571
void QgsDxfPaintEngine::setRing( QgsPointSequence &polyline, const QPointF *points, int pointCount )
@@ -82,12 +88,12 @@ void QgsDxfPaintEngine::drawPolygon( const QPointF *points, int pointCount, Poly
8288
if ( mode == QPaintEngine::PolylineMode )
8389
{
8490
if ( mPen.style() != Qt::NoPen && mPen.brush().style() != Qt::NoBrush )
85-
mDxf->writePolyline( polygon.at( 0 ), mLayer, QStringLiteral( "CONTINUOUS" ), mPen.color(), currentWidth() );
91+
mDxf->writePolyline( polygon.at( 0 ), mLayer, QStringLiteral( "CONTINUOUS" ), penColor(), currentWidth() );
8692
}
8793
else
8894
{
8995
if ( mBrush.style() != Qt::NoBrush )
90-
mDxf->writePolygon( polygon, mLayer, QStringLiteral( "SOLID" ), mBrush.color() );
96+
mDxf->writePolygon( polygon, mLayer, QStringLiteral( "SOLID" ), brushColor() );
9197
}
9298
}
9399

@@ -118,7 +124,7 @@ void QgsDxfPaintEngine::drawPath( const QPainterPath &path )
118124
endPolygon();
119125

120126
if ( !mPolygon.isEmpty() && mBrush.style() != Qt::NoBrush )
121-
mDxf->writePolygon( mPolygon, mLayer, QStringLiteral( "SOLID" ), mBrush.color() );
127+
mDxf->writePolygon( mPolygon, mLayer, QStringLiteral( "SOLID" ), brushColor() );
122128

123129
mPolygon.clear();
124130
}
@@ -194,7 +200,7 @@ void QgsDxfPaintEngine::drawLines( const QLineF *lines, int lineCount )
194200
{
195201
mDxf->writeLine( toDxfCoordinates( lines[i].p1() ),
196202
toDxfCoordinates( lines[i].p2() ),
197-
mLayer, QStringLiteral( "CONTINUOUS" ), mPen.color(), currentWidth() );
203+
mLayer, QStringLiteral( "CONTINUOUS" ), penColor(), currentWidth() );
198204
}
199205
}
200206

@@ -287,3 +293,25 @@ int QgsDxfPaintEngine::faculty( int n )
287293

288294
return result;
289295
}
296+
297+
QColor QgsDxfPaintEngine::penColor() const
298+
{
299+
if ( qgsDoubleNear( mOpacity, 1.0 ) )
300+
{
301+
return mPen.color();
302+
}
303+
QColor c = mPen.color();
304+
c.setAlphaF( c.alphaF() * mOpacity );
305+
return c;
306+
}
307+
308+
QColor QgsDxfPaintEngine::brushColor() const
309+
{
310+
if ( qgsDoubleNear( mOpacity, 1.0 ) )
311+
{
312+
return mBrush.color();
313+
}
314+
QColor c = mBrush.color();
315+
c.setAlphaF( c.alphaF() * mOpacity );
316+
return c;
317+
}

src/core/dxf/qgsdxfpaintengine.h

+7
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ class CORE_EXPORT QgsDxfPaintEngine: public QPaintEngine
6464
QTransform mTransform;
6565
QPen mPen;
6666
QBrush mBrush;
67+
//! Opacity
68+
double mOpacity;
6769
QString mLayer;
6870
QPointF mShift;
6971
QgsRingSequence mPolygon;
@@ -87,6 +89,11 @@ class CORE_EXPORT QgsDxfPaintEngine: public QPaintEngine
8789
static int lower( int n, int i );
8890
static double power( double a, int b );
8991
static int faculty( int n );
92+
93+
//! Returns current pen color
94+
QColor penColor() const;
95+
//! Returns current brush color
96+
QColor brushColor() const;
9097
};
9198

9299
#endif // QGSDXFPAINTENGINE_H

src/core/symbology/qgsfillsymbollayer.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ double QgsSimpleFillSymbolLayer::dxfWidth( const QgsDxfExport &e, QgsSymbolRende
406406
context.setOriginalValueVariable( mStrokeWidth );
407407
width = mDataDefinedProperties.valueAsDouble( QgsSymbolLayer::PropertyStrokeWidth, context.renderContext().expressionContext(), mStrokeWidth );
408408
}
409-
return width * e.mapUnitScaleFactor( e.symbologyScale(), mStrokeWidthUnit, e.mapUnits() );
409+
return width * e.mapUnitScaleFactor( e.symbologyScale(), mStrokeWidthUnit, e.mapUnits(), context.renderContext().mapToPixel().mapUnitsPerPixel() );
410410
}
411411

412412
QColor QgsSimpleFillSymbolLayer::dxfColor( QgsSymbolRenderContext &context ) const
@@ -1672,7 +1672,7 @@ double QgsImageFillSymbolLayer::dxfWidth( const QgsDxfExport &e, QgsSymbolRender
16721672
context.setOriginalValueVariable( mStrokeWidth );
16731673
width = mDataDefinedProperties.valueAsDouble( QgsSymbolLayer::PropertyWidth, context.renderContext().expressionContext(), mStrokeWidth );
16741674
}
1675-
return width * e.mapUnitScaleFactor( e.symbologyScale(), mStrokeWidthUnit, e.mapUnits() );
1675+
return width * e.mapUnitScaleFactor( e.symbologyScale(), mStrokeWidthUnit, e.mapUnits(), context.renderContext().mapToPixel().mapUnitsPerPixel() );
16761676
}
16771677

16781678
QColor QgsImageFillSymbolLayer::dxfColor( QgsSymbolRenderContext &context ) const

src/core/symbology/qgslinesymbollayer.cpp

+14-5
Original file line numberDiff line numberDiff line change
@@ -594,15 +594,18 @@ Qt::PenStyle QgsSimpleLineSymbolLayer::dxfPenStyle() const
594594
double QgsSimpleLineSymbolLayer::dxfWidth( const QgsDxfExport &e, QgsSymbolRenderContext &context ) const
595595
{
596596
double width = mWidth;
597-
598597
if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyStrokeWidth ) )
599598
{
600599
context.setOriginalValueVariable( mWidth );
601-
width = mDataDefinedProperties.valueAsDouble( QgsSymbolLayer::PropertyStrokeWidth, context.renderContext().expressionContext(), mWidth )
602-
* e.mapUnitScaleFactor( e.symbologyScale(), widthUnit(), e.mapUnits() );
600+
width = mDataDefinedProperties.valueAsDouble( QgsSymbolLayer::PropertyStrokeWidth, context.renderContext().expressionContext(), mWidth );
603601
}
604602

605-
return width * e.mapUnitScaleFactor( e.symbologyScale(), widthUnit(), e.mapUnits() );
603+
width *= e.mapUnitScaleFactor( e.symbologyScale(), widthUnit(), e.mapUnits(), context.renderContext().mapToPixel().mapUnitsPerPixel() );
604+
if ( mWidthUnit == QgsUnitTypes::RenderMapUnits )
605+
{
606+
e.clipValueToMapUnitScale( width, mWidthMapUnitScale, context.renderContext().scaleFactor() );
607+
}
608+
return width;
606609
}
607610

608611
QColor QgsSimpleLineSymbolLayer::dxfColor( QgsSymbolRenderContext &context ) const
@@ -625,7 +628,13 @@ double QgsSimpleLineSymbolLayer::dxfOffset( const QgsDxfExport &e, QgsSymbolRend
625628
context.setOriginalValueVariable( mOffset );
626629
offset = mDataDefinedProperties.valueAsDouble( QgsSymbolLayer::PropertyOffset, context.renderContext().expressionContext(), mOffset );
627630
}
628-
return offset;
631+
632+
offset *= e.mapUnitScaleFactor( e.symbologyScale(), offsetUnit(), e.mapUnits(), context.renderContext().mapToPixel().mapUnitsPerPixel() );
633+
if ( mOffsetUnit == QgsUnitTypes::RenderMapUnits )
634+
{
635+
e.clipValueToMapUnitScale( offset, mOffsetMapUnitScale, context.renderContext().scaleFactor() );
636+
}
637+
return -offset; //direction seems to be inverse to symbology offset
629638
}
630639

631640
/////////

0 commit comments

Comments
 (0)