Skip to content
Permalink
Browse files

Port dxf export improvements to QGIS 3

  • Loading branch information
mhugent authored and nyalldawson committed Jun 5, 2018
1 parent aa47dbe commit 18f0af8c23dcbc7d0d6082ced369f41e7f7a1661
@@ -397,10 +397,21 @@ Write mtext (MTEXT)
.. versionadded:: 2.15
%End

static double mapUnitScaleFactor( double scale, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits );
static double mapUnitScaleFactor( double scaleDenominator, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits, double mapUnitsPerPixel = 1.0 );
%Docstring
Calculates a scaling factor to convert from map units to a specified symbol unit.
The ``scale`` parameter indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
Returns scale factor for conversion to map units
@param scaleDenominator the map scale denominator
@param symbolUnits the symbol output units
@param mapUnits the map units
@param mapUnitsPerPixel Map units per pixel*
%End

void clipValueToMapUnitScale( double &value, const QgsMapUnitScale &scale, double pixelToMMFactor ) const;
%Docstring
Clips value to scale minimum/maximum
@param value the value to clip
@param scale the scale dependent minimum/maximum values
@param pixelToMMFactor pixels per mm*
%End

static QString dxfLayerName( const QString &name );
@@ -930,7 +930,7 @@ void QgsDxfExport::writeBlocks()
writeGroup( 1, QLatin1String( "" ) );

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

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

ctx.expressionContext().appendScope( QgsExpressionContextUtils::projectScope( QgsProject::instance() ) );
ctx.expressionContext().appendScope( QgsExpressionContextUtils::globalScope() );

// label engine
QgsLabelingEngine engine;
engine.setMapSettings( mMapSettings );
@@ -3435,7 +3438,7 @@ void QgsDxfExport::writePoint( const QgsPoint &pt, const QString &layer, const Q
const QgsMarkerSymbolLayer *msl = dynamic_cast< const QgsMarkerSymbolLayer * >( symbolLayer );
if ( msl && symbol )
{
if ( symbolLayer->writeDxf( *this, mapUnitScaleFactor( mSymbologyScale, msl->sizeUnit(), mMapUnits ), layer, ctx, QPointF( pt.x(), pt.y() ) ) )
if ( symbolLayer->writeDxf( *this, mapUnitScaleFactor( mSymbologyScale, msl->sizeUnit(), mMapUnits, ctx.renderContext().mapToPixel().mapUnitsPerPixel() ), layer, ctx, QPointF( pt.x(), pt.y() ) ) )
{
return;
}
@@ -3982,14 +3985,53 @@ QgsRenderContext QgsDxfExport::renderContext() const
return context;
}

double QgsDxfExport::mapUnitScaleFactor( double scale, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits )
double QgsDxfExport::mapUnitScaleFactor( double scaleDenominator, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits, double mapUnitsPerPixel )
{
if ( symbolUnits == QgsUnitTypes::RenderMapUnits )
{
return 1.0;
}
// MM symbol unit
return scale * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceMeters, mapUnits ) / 1000.0;
else if ( symbolUnits == QgsUnitTypes::RenderMillimeters )
{
return ( scaleDenominator * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceMeters, mapUnits ) / 1000.0 );
}
else if ( symbolUnits == QgsUnitTypes::RenderPixels )
{
return mapUnitsPerPixel;
}
return 1.0;
}

void QgsDxfExport::clipValueToMapUnitScale( double &value, const QgsMapUnitScale &scale, double pixelToMMFactor ) const
{
if ( !scale.minSizeMMEnabled && !scale.maxSizeMMEnabled )
{
return;
}

double mapUnitsPerPixel = mMapSettings.mapToPixel().mapUnitsPerPixel();

double minSizeMU = -DBL_MAX;
if ( scale.minSizeMMEnabled )
{
minSizeMU = scale.minSizeMM * pixelToMMFactor * mapUnitsPerPixel;
}
if ( !qgsDoubleNear( scale.minScale, 0.0 ) )
{
minSizeMU = qMax( minSizeMU, value );
}
value = qMax( value, minSizeMU );

double maxSizeMU = DBL_MAX;
if ( scale.maxSizeMMEnabled )
{
maxSizeMU = scale.maxSizeMM * pixelToMMFactor * mapUnitsPerPixel;
}
if ( !qgsDoubleNear( scale.maxScale, 0.0 ) )
{
maxSizeMU = qMin( maxSizeMU, value );
}
value = qMin( value, maxSizeMU );
}

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

writeGroup( 0, QStringLiteral( "LTYPE" ) );
@@ -4143,7 +4185,7 @@ void QgsDxfExport::writeLinetype( const QString &styleName, const QVector<qreal>
{
// map units or mm?
double segmentLength = ( isGap ? -*dashIt : *dashIt );
segmentLength *= mapUnitScaleFactor( mSymbologyScale, u, mMapUnits );
segmentLength *= mapUnitScaleFactor( mSymbologyScale, u, mMapUnits, mMapSettings.mapToPixel().mapUnitsPerPixel() );
writeGroup( 49, segmentLength );
writeGroup( 74, 0 );
isGap = !isGap;
@@ -385,10 +385,19 @@ class CORE_EXPORT QgsDxfExport
void writeMText( const QString &layer, const QString &text, const QgsPoint &pt, double width, double angle, const QColor &color );

/**
* Calculates a scaling factor to convert from map units to a specified symbol unit.
* The \a scale parameter indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
*/
static double mapUnitScaleFactor( double scale, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits );
* Returns scale factor for conversion to map units
* @param scaleDenominator the map scale denominator
* @param symbolUnits the symbol output units
* @param mapUnits the map units
* @param mapUnitsPerPixel Map units per pixel*/
static double mapUnitScaleFactor( double scaleDenominator, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits, double mapUnitsPerPixel = 1.0 );

/**
* Clips value to scale minimum/maximum
* @param value the value to clip
* @param scale the scale dependent minimum/maximum values
* @param pixelToMMFactor pixels per mm*/
void clipValueToMapUnitScale( double &value, const QgsMapUnitScale &scale, double pixelToMMFactor ) const;

//! Returns cleaned layer name for use in DXF
static QString dxfLayerName( const QString &name );
@@ -24,6 +24,7 @@ QgsDxfPaintEngine::QgsDxfPaintEngine( const QgsDxfPaintDevice *dxfDevice, QgsDxf
: QPaintEngine( QPaintEngine::AllFeatures /*QPaintEngine::PainterPaths | QPaintEngine::PaintOutsidePaintEvent*/ )
, mPaintDevice( dxfDevice )
, mDxf( dxf )
, mOpacity( 1.0 )
{
}

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

if ( state.state() & QPaintEngine::DirtyBrush )
mBrush = state.brush();

if ( state.state() & QPaintEngine::DirtyOpacity )
{
mOpacity = state.opacity();
}
}

void QgsDxfPaintEngine::setRing( QgsPointSequence &polyline, const QPointF *points, int pointCount )
@@ -82,12 +88,12 @@ void QgsDxfPaintEngine::drawPolygon( const QPointF *points, int pointCount, Poly
if ( mode == QPaintEngine::PolylineMode )
{
if ( mPen.style() != Qt::NoPen && mPen.brush().style() != Qt::NoBrush )
mDxf->writePolyline( polygon.at( 0 ), mLayer, QStringLiteral( "CONTINUOUS" ), mPen.color(), currentWidth() );
mDxf->writePolyline( polygon.at( 0 ), mLayer, QStringLiteral( "CONTINUOUS" ), penColor(), currentWidth() );
}
else
{
if ( mBrush.style() != Qt::NoBrush )
mDxf->writePolygon( polygon, mLayer, QStringLiteral( "SOLID" ), mBrush.color() );
mDxf->writePolygon( polygon, mLayer, QStringLiteral( "SOLID" ), brushColor() );
}
}

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

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

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

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

return result;
}

QColor QgsDxfPaintEngine::penColor() const
{
if ( qgsDoubleNear( mOpacity, 1.0 ) )
{
return mPen.color();
}
QColor c = mPen.color();
c.setAlphaF( c.alphaF() * mOpacity );
return c;
}

QColor QgsDxfPaintEngine::brushColor() const
{
if ( qgsDoubleNear( mOpacity, 1.0 ) )
{
return mBrush.color();
}
QColor c = mBrush.color();
c.setAlphaF( c.alphaF() * mOpacity );
return c;
}
@@ -64,6 +64,8 @@ class CORE_EXPORT QgsDxfPaintEngine: public QPaintEngine
QTransform mTransform;
QPen mPen;
QBrush mBrush;
//! Opacity
double mOpacity;
QString mLayer;
QPointF mShift;
QgsRingSequence mPolygon;
@@ -87,6 +89,11 @@ class CORE_EXPORT QgsDxfPaintEngine: public QPaintEngine
static int lower( int n, int i );
static double power( double a, int b );
static int faculty( int n );

//! Returns current pen color
QColor penColor() const;
//! Returns current brush color
QColor brushColor() const;
};

#endif // QGSDXFPAINTENGINE_H
@@ -406,7 +406,7 @@ double QgsSimpleFillSymbolLayer::dxfWidth( const QgsDxfExport &e, QgsSymbolRende
context.setOriginalValueVariable( mStrokeWidth );
width = mDataDefinedProperties.valueAsDouble( QgsSymbolLayer::PropertyStrokeWidth, context.renderContext().expressionContext(), mStrokeWidth );
}
return width * e.mapUnitScaleFactor( e.symbologyScale(), mStrokeWidthUnit, e.mapUnits() );
return width * e.mapUnitScaleFactor( e.symbologyScale(), mStrokeWidthUnit, e.mapUnits(), context.renderContext().mapToPixel().mapUnitsPerPixel() );
}

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

QColor QgsImageFillSymbolLayer::dxfColor( QgsSymbolRenderContext &context ) const
@@ -594,15 +594,18 @@ Qt::PenStyle QgsSimpleLineSymbolLayer::dxfPenStyle() const
double QgsSimpleLineSymbolLayer::dxfWidth( const QgsDxfExport &e, QgsSymbolRenderContext &context ) const
{
double width = mWidth;

if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyStrokeWidth ) )
{
context.setOriginalValueVariable( mWidth );
width = mDataDefinedProperties.valueAsDouble( QgsSymbolLayer::PropertyStrokeWidth, context.renderContext().expressionContext(), mWidth )
* e.mapUnitScaleFactor( e.symbologyScale(), widthUnit(), e.mapUnits() );
width = mDataDefinedProperties.valueAsDouble( QgsSymbolLayer::PropertyStrokeWidth, context.renderContext().expressionContext(), mWidth );
}

return width * e.mapUnitScaleFactor( e.symbologyScale(), widthUnit(), e.mapUnits() );
width *= e.mapUnitScaleFactor( e.symbologyScale(), widthUnit(), e.mapUnits(), context.renderContext().mapToPixel().mapUnitsPerPixel() );
if ( mWidthUnit == QgsUnitTypes::RenderMapUnits )
{
e.clipValueToMapUnitScale( width, mWidthMapUnitScale, context.renderContext().scaleFactor() );
}
return width;
}

QColor QgsSimpleLineSymbolLayer::dxfColor( QgsSymbolRenderContext &context ) const
@@ -625,7 +628,13 @@ double QgsSimpleLineSymbolLayer::dxfOffset( const QgsDxfExport &e, QgsSymbolRend
context.setOriginalValueVariable( mOffset );
offset = mDataDefinedProperties.valueAsDouble( QgsSymbolLayer::PropertyOffset, context.renderContext().expressionContext(), mOffset );
}
return offset;

offset *= e.mapUnitScaleFactor( e.symbologyScale(), offsetUnit(), e.mapUnits(), context.renderContext().mapToPixel().mapUnitsPerPixel() );
if ( mOffsetUnit == QgsUnitTypes::RenderMapUnits )
{
e.clipValueToMapUnitScale( offset, mOffsetMapUnitScale, context.renderContext().scaleFactor() );
}
return -offset; //direction seems to be inverse to symbology offset
}

/////////

0 comments on commit 18f0af8

Please sign in to comment.
You can’t perform that action at this time.