Skip to content

Commit

Permalink
Merge pull request #6810 from mhugent/dxf_fixes_2_18
Browse files Browse the repository at this point in the history
Dxf fixes for 2 18
  • Loading branch information
mhugent committed Apr 20, 2018
2 parents 9bf55aa + 543f501 commit c577b65
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 44 deletions.
12 changes: 11 additions & 1 deletion python/core/dxf/qgsdxfexport.sip
Expand Up @@ -375,7 +375,17 @@ class QgsDxfExport
//! @note added in 2.15
void writeMText( const QString &layer, const QString &text, const QgsPointV2 &pt, double width, double angle, const QColor& color );

static double mapUnitScaleFactor( double scaleDenominator, QgsSymbolV2::OutputUnit symbolUnits, QGis::UnitType 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, QgsSymbolV2::OutputUnit symbolUnits, QGis::UnitType 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;

//! Return cleaned layer name for use in DXF
static QString dxfLayerName( const QString &name );
Expand Down
124 changes: 115 additions & 9 deletions src/core/dxf/qgsdxfexport.cpp
Expand Up @@ -28,6 +28,7 @@

#include "qgsdxfexport.h"
#include "qgsdxfpallabeling.h"
#include "qgsgeometrygeneratorsymbollayerv2.h"
#include "qgsvectordataprovider.h"
#include "qgspoint.h"
#include "qgsrendererv2.h"
Expand Down Expand Up @@ -932,7 +933,7 @@ void QgsDxfExport::writeBlocks()
writeGroup( 1, "" );

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

writeGroup( 0, "ENDBLK" );
writeHandle();
Expand Down Expand Up @@ -967,6 +968,9 @@ void QgsDxfExport::writeEntities()
ctx.setScaleFactor( 96.0 / 25.4 );
ctx.setMapToPixel( QgsMapToPixel( 1.0 / mFactor, mExtent.center().x(), mExtent.center().y(), mExtent.width() * mFactor, mExtent.height() * mFactor, 0 ) );

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

// label engine
QgsLabelingEngineV2 engine;
engine.readSettingsFromProject();
Expand Down Expand Up @@ -1082,7 +1086,22 @@ void QgsDxfExport::writeEntities()
int nSymbolLayers = ( *symbolIt )->symbolLayerCount();
for ( int i = 0; i < nSymbolLayers; ++i )
{
addFeature( sctx, ct, lName, ( *symbolIt )->symbolLayer( i ), *symbolIt );
QgsSymbolLayerV2* sl = ( *symbolIt )->symbolLayer( i );
if ( !sl )
{
continue;
}

bool isGeometryGenerator = ( sl->layerType() == "GeometryGenerator" );

if ( isGeometryGenerator )
{
addGeometryGeneratorSymbolLayer( sctx, ct, lName, sl, true );
}
else
{
addFeature( sctx, ct, lName, sl, *symbolIt );
}
}
}
}
Expand All @@ -1094,7 +1113,15 @@ void QgsDxfExport::writeEntities()
{
continue;
}
addFeature( sctx, ct, lName, s->symbolLayer( 0 ), s );

if ( s->symbolLayer( 0 )->layerType() == "GeometryGenerator" )
{
addGeometryGeneratorSymbolLayer( sctx, ct, lName, s->symbolLayer( 0 ), false );
}
else
{
addFeature( sctx, ct, lName, s->symbolLayer( 0 ), s );
}
}

if ( lp )
Expand Down Expand Up @@ -3424,7 +3451,7 @@ void QgsDxfExport::writePoint( const QgsPointV2 &pt, const QString& layer, const
const QgsMarkerSymbolLayerV2* msl = dynamic_cast< const QgsMarkerSymbolLayerV2* >( symbolLayer );
if ( msl && symbol )
{
if ( symbolLayer->writeDxf( *this, mapUnitScaleFactor( mSymbologyScaleDenominator, msl->sizeUnit(), mMapUnits ), layer, ctx, QPointF( pt.x(), pt.y() ) ) )
if ( symbolLayer->writeDxf( *this, mapUnitScaleFactor( mSymbologyScaleDenominator, msl->sizeUnit(), mMapUnits, ctx.renderContext().mapToPixel().mapUnitsPerPixel() ), layer, ctx, QPointF( pt.x(), pt.y() ) ) )
{
return;
}
Expand Down Expand Up @@ -3956,6 +3983,46 @@ void QgsDxfExport::addFeature( QgsSymbolV2RenderContext& ctx, const QgsCoordinat
}
}

void QgsDxfExport::addGeometryGeneratorSymbolLayer( QgsSymbolV2RenderContext &ctx, const QgsCoordinateTransform *ct, const QString &layer, QgsSymbolLayerV2 *symbolLayer, bool allSymbolLayers )
{
QgsGeometryGeneratorSymbolLayerV2* gg = dynamic_cast<QgsGeometryGeneratorSymbolLayerV2*>( symbolLayer );
if ( !gg )
{
return;
}

const QgsFeature* fet = ctx.feature();
if ( !fet )
{
return;
}

QgsFeature f = *fet;

QgsExpressionContext& expressionContext = ctx.renderContext().expressionContext();
QgsExpression geomExpr( gg->geometryExpression() );
geomExpr.prepare( &expressionContext );
QgsGeometry geom = geomExpr.evaluate( &expressionContext ).value<QgsGeometry>();
f.setGeometry( geom );

QgsSymbolV2* symbol = gg->subSymbol();
if ( symbol && symbol->symbolLayerCount() > 0 )
{
QgsExpressionContextScope* symbolExpressionContextScope = symbol->symbolRenderContext()->expressionContextScope();
symbolExpressionContextScope->setFeature( f );

ctx.setFeature( &f );

int nSymbolLayers = allSymbolLayers ? symbol->symbolLayerCount() : 1;
for ( int i = 0; i < nSymbolLayers; ++i )
{
addFeature( ctx, ct, layer, symbol->symbolLayer( i ), symbol );
}

ctx.setFeature( fet );
}
}

QColor QgsDxfExport::colorFromSymbolLayer( const QgsSymbolLayerV2* symbolLayer, QgsSymbolV2RenderContext &ctx )
{
if ( !symbolLayer )
Expand Down Expand Up @@ -4036,14 +4103,53 @@ QgsRenderContext QgsDxfExport::renderContext() const
return context;
}

double QgsDxfExport::mapUnitScaleFactor( double scaleDenominator, QgsSymbolV2::OutputUnit symbolUnits, QGis::UnitType mapUnits )
double QgsDxfExport::mapUnitScaleFactor( double scaleDenominator, QgsSymbolV2::OutputUnit symbolUnits, QGis::UnitType mapUnits, double mapUnitsPerPixel )
{
if ( symbolUnits == QgsSymbolV2::MapUnit )
{
return 1.0;
}
// MM symbol unit
return scaleDenominator * QgsUnitTypes::fromUnitToUnitFactor( QGis::Meters, mapUnits ) / 1000.0;
else if ( symbolUnits == QgsSymbolV2::MM )
{
return ( scaleDenominator * QgsUnitTypes::fromUnitToUnitFactor( QGis::Meters, mapUnits ) / 1000.0 );
}
else if ( symbolUnits == QgsSymbolV2::Pixel )
{
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< QgsSymbolLayerV2*, QgsSymbolV2* > > QgsDxfExport::symbolLayers( QgsRenderContext &context )
Expand Down Expand Up @@ -4174,7 +4280,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( mSymbologyScaleDenominator, u, mMapUnits ) );
length += ( *dashIt * mapUnitScaleFactor( mSymbologyScaleDenominator, u, mMapUnits, mMapSettings.mapToPixel().mapUnitsPerPixel() ) );
}

writeGroup( 0, "LTYPE" );
Expand All @@ -4195,7 +4301,7 @@ void QgsDxfExport::writeLinetype( const QString& styleName, const QVector<qreal>
{
// map units or mm?
double segmentLength = ( isGap ? -*dashIt : *dashIt );
segmentLength *= mapUnitScaleFactor( mSymbologyScaleDenominator, u, mMapUnits );
segmentLength *= mapUnitScaleFactor( mSymbologyScaleDenominator, u, mMapUnits, mMapSettings.mapToPixel().mapUnitsPerPixel() );
writeGroup( 49, segmentLength );
writeGroup( 74, 0 );
isGap = !isGap;
Expand Down
19 changes: 18 additions & 1 deletion src/core/dxf/qgsdxfexport.h
Expand Up @@ -402,7 +402,17 @@ class CORE_EXPORT QgsDxfExport
//! @note added in 2.15
void writeMText( const QString &layer, const QString &text, const QgsPointV2 &pt, double width, double angle, const QColor& color );

static double mapUnitScaleFactor( double scaleDenominator, QgsSymbolV2::OutputUnit symbolUnits, QGis::UnitType 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, QgsSymbolV2::OutputUnit symbolUnits, QGis::UnitType 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;

//! Return cleaned layer name for use in DXF
static QString dxfLayerName( const QString &name );
Expand Down Expand Up @@ -467,6 +477,13 @@ class CORE_EXPORT QgsDxfExport
void writeLinetype( const QString &styleName, const QVector<qreal> &pattern, QgsSymbolV2::OutputUnit u );

void addFeature( QgsSymbolV2RenderContext &ctx, const QgsCoordinateTransform *ct, const QString &layer, const QgsSymbolLayerV2 *symbolLayer, const QgsSymbolV2 *symbol );
/** Writes geometry generator symbol layer
@param ctx the symbol render context
@param ct the coordinate transform
@param layer the layer name
@param symbolLayer the symbollayer to write to the dxf file
@param allSymbolLayers if true, all symbol layers of the subsymbol are writeen. If false, only the first one is written*/
void addGeometryGeneratorSymbolLayer( QgsSymbolV2RenderContext &ctx, const QgsCoordinateTransform *ct, const QString &layer, QgsSymbolLayerV2 *symbolLayer, bool allSymbolLayers );

//returns dxf palette index from symbol layer color
static QColor colorFromSymbolLayer( const QgsSymbolLayerV2 *symbolLayer, QgsSymbolV2RenderContext &ctx );
Expand Down
36 changes: 32 additions & 4 deletions src/core/dxf/qgsdxfpaintengine.cpp
Expand Up @@ -24,6 +24,7 @@ QgsDxfPaintEngine::QgsDxfPaintEngine( const QgsDxfPaintDevice* dxfDevice, QgsDxf
: QPaintEngine( QPaintEngine::AllFeatures /*QPaintEngine::PainterPaths | QPaintEngine::PaintOutsidePaintEvent*/ )
, mPaintDevice( dxfDevice )
, mDxf( dxf )
, mOpacity( 1.0 )
{
}

Expand Down Expand Up @@ -64,6 +65,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( QgsPointSequenceV2 &polyline, const QPointF *points, int pointCount )
Expand All @@ -86,12 +92,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, "CONTINUOUS", mPen.color(), currentWidth() );
mDxf->writePolyline( polygon.at( 0 ), mLayer, "CONTINUOUS", penColor(), currentWidth() );
}
else
{
if ( mBrush.style() != Qt::NoBrush )
mDxf->writePolygon( polygon, mLayer, "SOLID", mBrush.color() );
mDxf->writePolygon( polygon, mLayer, "SOLID", brushColor() );
}
}

Expand Down Expand Up @@ -122,7 +128,7 @@ void QgsDxfPaintEngine::drawPath( const QPainterPath& path )
endPolygon();

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

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

Expand Down Expand Up @@ -291,3 +297,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;
}
7 changes: 7 additions & 0 deletions src/core/dxf/qgsdxfpaintengine.h
Expand Up @@ -61,6 +61,8 @@ class CORE_EXPORT QgsDxfPaintEngine: public QPaintEngine
QTransform mTransform;
QPen mPen;
QBrush mBrush;
/** Opacity*/
double mOpacity;
QString mLayer;
QPointF mShift;
QgsRingSequenceV2 mPolygon;
Expand All @@ -84,6 +86,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
4 changes: 2 additions & 2 deletions src/core/symbology-ng/qgsfillsymbollayerv2.cpp
Expand Up @@ -416,7 +416,7 @@ double QgsSimpleFillSymbolLayerV2::dxfWidth( const QgsDxfExport& e, QgsSymbolV2R
context.setOriginalValueVariable( mBorderWidth );
width = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_WIDTH_BORDER, context, mBorderWidth ).toDouble();
}
return width * e.mapUnitScaleFactor( e.symbologyScaleDenominator(), mBorderWidthUnit, e.mapUnits() );
return width * e.mapUnitScaleFactor( e.symbologyScaleDenominator(), mBorderWidthUnit, e.mapUnits(), context.renderContext().mapToPixel().mapUnitsPerPixel() );
}

QColor QgsSimpleFillSymbolLayerV2::dxfColor( QgsSymbolV2RenderContext &context ) const
Expand Down Expand Up @@ -1702,7 +1702,7 @@ double QgsImageFillSymbolLayer::dxfWidth( const QgsDxfExport& e, QgsSymbolV2Rend
context.setOriginalValueVariable( mOutlineWidth );
width = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_WIDTH, context, mOutlineWidth ).toDouble();
}
return width * e.mapUnitScaleFactor( e.symbologyScaleDenominator(), mOutlineWidthUnit, e.mapUnits() );
return width * e.mapUnitScaleFactor( e.symbologyScaleDenominator(), mOutlineWidthUnit, e.mapUnits(), context.renderContext().mapToPixel().mapUnitsPerPixel() );
}

QColor QgsImageFillSymbolLayer::dxfColor( QgsSymbolV2RenderContext &context ) const
Expand Down

0 comments on commit c577b65

Please sign in to comment.