From aa47dbef103e748fb98e9a21a7ee814ddb4e92cd Mon Sep 17 00:00:00 2001 From: Marco Hugentobler Date: Mon, 4 Jun 2018 16:13:25 +0200 Subject: [PATCH] Support geometry generator in dxf output --- src/core/dxf/qgsdxfexport.cpp | 67 +++++++++++++++++++++++++++++++++-- src/core/dxf/qgsdxfexport.h | 9 +++++ 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/src/core/dxf/qgsdxfexport.cpp b/src/core/dxf/qgsdxfexport.cpp index 174ce5441488..a1422f923016 100644 --- a/src/core/dxf/qgsdxfexport.cpp +++ b/src/core/dxf/qgsdxfexport.cpp @@ -28,6 +28,7 @@ #include "qgsdxfexport.h" #include "qgsdxfpallabeling.h" +#include "qgsgeometrygeneratorsymbollayer.h" #include "qgsvectordataprovider.h" #include "qgspointxy.h" #include "qgsproject.h" @@ -1076,7 +1077,21 @@ void QgsDxfExport::writeEntities() int nSymbolLayers = ( *symbolIt )->symbolLayerCount(); for ( int i = 0; i < nSymbolLayers; ++i ) { - addFeature( sctx, ct, lName, ( *symbolIt )->symbolLayer( i ), *symbolIt ); + QgsSymbolLayer *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 ); + } } } } @@ -1088,7 +1103,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 ) @@ -4127,6 +4150,46 @@ void QgsDxfExport::writeLinetype( const QString &styleName, const QVector } } +void QgsDxfExport::addGeometryGeneratorSymbolLayer( QgsSymbolRenderContext &ctx, const QgsCoordinateTransform &ct, const QString &layer, QgsSymbolLayer *symbolLayer, bool allSymbolLayers ) +{ + QgsGeometryGeneratorSymbolLayer *gg = dynamic_cast( 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(); + f.setGeometry( geom ); + + QgsSymbol *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 ); + } +} + bool QgsDxfExport::hasDataDefinedProperties( const QgsSymbolLayer *sl, const QgsSymbol *symbol ) { if ( !sl || !symbol ) diff --git a/src/core/dxf/qgsdxfexport.h b/src/core/dxf/qgsdxfexport.h index ce6f76e2168f..4d3d2c86194e 100644 --- a/src/core/dxf/qgsdxfexport.h +++ b/src/core/dxf/qgsdxfexport.h @@ -454,6 +454,15 @@ class CORE_EXPORT QgsDxfExport void writeSymbolLayerLinetype( const QgsSymbolLayer *symbolLayer ); void writeLinetype( const QString &styleName, const QVector &pattern, QgsUnitTypes::RenderUnit u ); + /** + * 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( QgsSymbolRenderContext &ctx, const QgsCoordinateTransform &ct, const QString &layer, QgsSymbolLayer *symbolLayer, bool allSymbolLayers ); + void addFeature( QgsSymbolRenderContext &ctx, const QgsCoordinateTransform &ct, const QString &layer, const QgsSymbolLayer *symbolLayer, const QgsSymbol *symbol ); //returns dxf palette index from symbol layer color