dxf export: consider layer styles (fixes #15946)

This commit is contained in:
Juergen E. Fischer 2017-02-12 20:20:12 +01:00
parent bb2a6c8033
commit 92091c536b
6 changed files with 108 additions and 48 deletions

View File

@ -31,6 +31,12 @@ class QgsDxfExport
QgsDxfExport(); QgsDxfExport();
~QgsDxfExport(); ~QgsDxfExport();
/**
* Set map settings and assign layer name attributes
* @param settings map settings to apply
*/
void setMapSettings( const QgsMapSettings &settings );
/** /**
* Add layers to export * Add layers to export
* @param layers list of layers and corresponding attribute indexes that determine the layer name (-1 for original layer name or title) * @param layers list of layers and corresponding attribute indexes that determine the layer name (-1 for original layer name or title)

View File

@ -5212,6 +5212,10 @@ void QgisApp::dxfExport()
if ( d.exec() == QDialog::Accepted ) if ( d.exec() == QDialog::Accepted )
{ {
QgsDxfExport dxfExport; QgsDxfExport dxfExport;
QgsMapSettings settings( mapCanvas()->mapSettings() );
settings.setLayerStyleOverrides( QgsProject::instance()->mapThemeCollection()->mapThemeStyleOverrides( d.mapTheme() ) );
dxfExport.setMapSettings( settings );
dxfExport.addLayers( d.layers() ); dxfExport.addLayers( d.layers() );
dxfExport.setSymbologyScaleDenominator( d.symbologyScale() ); dxfExport.setSymbologyScaleDenominator( d.symbologyScale() );
dxfExport.setSymbologyExport( d.symbologyMode() ); dxfExport.setSymbologyExport( d.symbologyMode() );

View File

@ -638,3 +638,8 @@ QgsCoordinateReferenceSystem QgsDxfExportDialog::crs() const
{ {
return mCRS; return mCRS;
} }
QString QgsDxfExportDialog::mapTheme() const
{
return mVisibilityPresets->currentText();
}

View File

@ -87,6 +87,7 @@ class QgsDxfExportDialog : public QDialog, private Ui::QgsDxfExportDialogBase
QString saveFile() const; QString saveFile() const;
bool exportMapExtent() const; bool exportMapExtent() const;
bool layerTitleAsName() const; bool layerTitleAsName() const;
QString mapTheme() const;
QString encoding() const; QString encoding() const;
QgsCoordinateReferenceSystem crs() const; QgsCoordinateReferenceSystem crs() const;

View File

@ -41,6 +41,7 @@
#include "qgstextlabelfeature.h" #include "qgstextlabelfeature.h"
#include "qgscrscache.h" #include "qgscrscache.h"
#include "qgslogger.h" #include "qgslogger.h"
#include "qgsmaplayerstylemanager.h"
#include "qgswkbtypes.h" #include "qgswkbtypes.h"
#include "qgspointv2.h" #include "qgspointv2.h"
@ -384,7 +385,8 @@ QgsDxfExport::QgsDxfExport( const QgsDxfExport& dxfExport )
QgsDxfExport &QgsDxfExport::operator=( const QgsDxfExport & dxfExport ) QgsDxfExport &QgsDxfExport::operator=( const QgsDxfExport & dxfExport )
{ {
mLayers = dxfExport.mLayers; mMapSettings = dxfExport.mMapSettings;
mLayerNameAttribute = dxfExport.mLayerNameAttribute;
mSymbologyScaleDenominator = dxfExport.mSymbologyScaleDenominator; mSymbologyScaleDenominator = dxfExport.mSymbologyScaleDenominator;
mSymbologyExport = dxfExport.mSymbologyExport; mSymbologyExport = dxfExport.mSymbologyExport;
mMapUnits = dxfExport.mMapUnits; mMapUnits = dxfExport.mMapUnits;
@ -397,9 +399,26 @@ QgsDxfExport& QgsDxfExport::operator=( const QgsDxfExport & dxfExport )
return *this; return *this;
} }
void QgsDxfExport::setMapSettings( const QgsMapSettings &settings )
{
mMapSettings = settings;
}
void QgsDxfExport::addLayers( const QList< QPair< QgsVectorLayer *, int > > &layers ) void QgsDxfExport::addLayers( const QList< QPair< QgsVectorLayer *, int > > &layers )
{ {
mLayers = layers; QList<QgsMapLayer*> layerList;
mLayerNameAttribute.clear();
QList< QPair< QgsVectorLayer*, int > >::const_iterator layerIt = layers.constBegin();
for ( ; layerIt != layers.constEnd(); ++layerIt )
{
layerList << layerIt->first;
if ( layerIt->second >= 0 )
mLayerNameAttribute.insert( layerIt->first->id(), layerIt->second );
}
mMapSettings.setLayers( layerList );
} }
void QgsDxfExport::writeGroup( int code, int i ) void QgsDxfExport::writeGroup( int code, int i )
@ -497,13 +516,14 @@ int QgsDxfExport::writeToFile( QIODevice* d, const QString& encoding )
if ( mExtent.isEmpty() ) if ( mExtent.isEmpty() )
{ {
QList< QPair<QgsVectorLayer*, int> >::const_iterator layerIt = mLayers.constBegin(); Q_FOREACH ( QgsMapLayer *ml, mMapSettings.layers() )
for ( ; layerIt != mLayers.constEnd(); ++layerIt )
{ {
if ( layerIt->first ) QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( ml );
{ if ( !vl )
QgsRectangle layerExtent = layerIt->first->extent(); continue;
layerExtent = mMapSettings.layerToMapCoordinates( layerIt->first, layerExtent );
QgsRectangle layerExtent = vl->extent();
layerExtent = mMapSettings.layerToMapCoordinates( vl, layerExtent );
if ( mExtent.isEmpty() ) if ( mExtent.isEmpty() )
{ {
@ -515,7 +535,6 @@ int QgsDxfExport::writeToFile( QIODevice* d, const QString& encoding )
} }
} }
} }
}
mMapSettings.setMapUnits( mMapUnits ); mMapSettings.setMapUnits( mMapUnits );
mMapSettings.setExtent( mExtent ); mMapSettings.setExtent( mExtent );
@ -747,30 +766,31 @@ void QgsDxfExport::writeTables()
writeGroup( 70, 0 ); writeGroup( 70, 0 );
writeGroup( 0, QStringLiteral( "ENDTAB" ) ); writeGroup( 0, QStringLiteral( "ENDTAB" ) );
QList< QPair<QgsVectorLayer*, int> >::const_iterator layerIt = mLayers.constBegin();
QSet<QString> layerNames; QSet<QString> layerNames;
for ( ; layerIt != mLayers.constEnd(); ++layerIt ) Q_FOREACH ( QgsMapLayer *ml, mMapSettings.layers() )
{ {
if ( !layerIsScaleBasedVisible( layerIt->first ) ) if ( !layerIsScaleBasedVisible( ml ) )
continue; continue;
if ( layerIt->first ) QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( ml );
if ( !vl )
continue;
int attrIdx = mLayerNameAttribute.value( vl->id(), -1 );
if ( attrIdx < 0 )
{ {
if ( layerIt->second < 0 ) layerNames << dxfLayerName( layerName( vl ) );
{
layerNames << dxfLayerName( layerName( layerIt->first ) );
} }
else else
{ {
QList<QVariant> values; QList<QVariant> values;
layerIt->first->uniqueValues( layerIt->second, values ); vl->uniqueValues( attrIdx, values );
Q_FOREACH ( const QVariant& v, values ) Q_FOREACH ( const QVariant& v, values )
{ {
layerNames << dxfLayerName( v.toString() ); layerNames << dxfLayerName( v.toString() );
} }
} }
} }
}
// Layers // Layers
// TODO: iterate features of all layer to produce a data-defined layer list // TODO: iterate features of all layer to produce a data-defined layer list
@ -946,27 +966,40 @@ void QgsDxfExport::writeEntities()
engine.setMapSettings( mMapSettings ); engine.setMapSettings( mMapSettings );
// iterate through the maplayers // iterate through the maplayers
QList< QPair< QgsVectorLayer*, int > >::const_iterator layerIt = mLayers.constBegin(); Q_FOREACH ( QgsMapLayer *ml, mMapSettings.layers() )
for ( ; layerIt != mLayers.constEnd(); ++layerIt )
{ {
QgsVectorLayer* vl = layerIt->first; QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
if ( !vl || !layerIsScaleBasedVisible( vl ) ) if ( !vl || !layerIsScaleBasedVisible( vl ) )
{ {
continue; continue;
} }
bool hasStyleOverride = mMapSettings.layerStyleOverrides().contains( vl->id() );
if ( hasStyleOverride )
{
QgsDebugMsg( QString( "%1: apply override style" ).arg( vl->id() ) );
vl->styleManager()->setOverrideStyle( mMapSettings.layerStyleOverrides().value( vl->id() ) );
}
else
{
QgsDebugMsg( QString( "%1: not override style" ).arg( vl->id() ) );
}
QgsSymbolRenderContext sctx( ctx, QgsUnitTypes::RenderMillimeters, 1.0, false, 0, nullptr ); QgsSymbolRenderContext sctx( ctx, QgsUnitTypes::RenderMillimeters, 1.0, false, 0, nullptr );
QgsFeatureRenderer* renderer = vl->renderer(); QgsFeatureRenderer* renderer = vl->renderer();
if ( !renderer ) if ( !renderer )
{ {
if ( hasStyleOverride )
vl->styleManager()->restoreOverrideStyle();
continue; continue;
} }
renderer->startRender( ctx, vl->fields() ); renderer->startRender( ctx, vl->fields() );
QSet<QString> attributes = renderer->usedAttributes( ctx ); QSet<QString> attributes = renderer->usedAttributes( ctx );
if ( vl->fields().exists( layerIt->second ) ) int attrIdx = mLayerNameAttribute.value( vl->id(), 1 );
if ( vl->fields().exists( attrIdx ) )
{ {
QString layerAttr = vl->fields().at( layerIt->second ).name(); QString layerAttr = vl->fields().at( attrIdx ).name();
attributes << layerAttr; attributes << layerAttr;
} }
@ -1003,6 +1036,10 @@ void QgsDxfExport::writeEntities()
{ {
writeEntitiesSymbolLevels( vl ); writeEntitiesSymbolLevels( vl );
renderer->stopRender( ctx ); renderer->stopRender( ctx );
if ( hasStyleOverride )
vl->styleManager()->restoreOverrideStyle();
continue; continue;
} }
@ -1017,7 +1054,7 @@ void QgsDxfExport::writeEntities()
while ( featureIt.nextFeature( fet ) ) while ( featureIt.nextFeature( fet ) )
{ {
ctx.expressionContext().setFeature( fet ); ctx.expressionContext().setFeature( fet );
QString lName( dxfLayerName( layerIt->second == -1 ? layerName( vl ) : fet.attribute( layerIt->second ).toString() ) ); QString lName( dxfLayerName( attrIdx < 0 ? layerName( vl ) : fet.attribute( attrIdx ).toString() ) );
sctx.setFeature( &fet ); sctx.setFeature( &fet );
if ( mSymbologyExport == NoSymbology ) if ( mSymbologyExport == NoSymbology )
@ -1067,6 +1104,9 @@ void QgsDxfExport::writeEntities()
} }
renderer->stopRender( ctx ); renderer->stopRender( ctx );
if ( hasStyleOverride )
vl->styleManager()->restoreOverrideStyle();
} }
engine.run( ctx ); engine.run( ctx );
@ -3936,11 +3976,9 @@ QList< QPair< QgsSymbolLayer*, QgsSymbol* > > QgsDxfExport::symbolLayers( QgsRen
{ {
QList< QPair< QgsSymbolLayer*, QgsSymbol* > > symbolLayers; QList< QPair< QgsSymbolLayer*, QgsSymbol* > > symbolLayers;
QList< QPair< QgsVectorLayer*, int> >::const_iterator lIt = mLayers.constBegin(); Q_FOREACH ( QgsMapLayer *ml, mMapSettings.layers() )
for ( ; lIt != mLayers.constEnd(); ++lIt )
{ {
// cast to vector layer QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
QgsVectorLayer* vl = lIt->first;
if ( !vl ) if ( !vl )
{ {
continue; continue;
@ -4192,12 +4230,13 @@ bool QgsDxfExport::layerIsScaleBasedVisible( const QgsMapLayer* layer ) const
QString QgsDxfExport::layerName( const QString &id, const QgsFeature &f ) const QString QgsDxfExport::layerName( const QString &id, const QgsFeature &f ) const
{ {
QList< QPair<QgsVectorLayer*, int> >::const_iterator layerIt = mLayers.constBegin(); Q_FOREACH ( QgsMapLayer *ml, mMapSettings.layers() )
for ( ; layerIt != mLayers.constEnd(); ++layerIt )
{ {
if ( layerIt->first && layerIt->first->id() == id ) QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( ml );
if ( vl && vl->id() == id )
{ {
return dxfLayerName( layerIt->second < 0 ? layerName( layerIt->first ) : f.attribute( layerIt->second ).toString() ); int attrIdx = mLayerNameAttribute.value( vl->id(), -1 );
return dxfLayerName( attrIdx < 0 ? layerName( vl ) : f.attribute( attrIdx ).toString() );
} }
} }

View File

@ -55,6 +55,12 @@ class CORE_EXPORT QgsDxfExport
QgsDxfExport( const QgsDxfExport &dxfExport ); QgsDxfExport( const QgsDxfExport &dxfExport );
QgsDxfExport &operator=( const QgsDxfExport &dxfExport ); QgsDxfExport &operator=( const QgsDxfExport &dxfExport );
/**
* Set map settings and assign layer name attributes
* @param settings map settings to apply
*/
void setMapSettings( const QgsMapSettings &settings );
/** /**
* Add layers to export * Add layers to export
* @param layers list of layers and corresponding attribute indexes that determine the layer name (-1 for original layer name or title) * @param layers list of layers and corresponding attribute indexes that determine the layer name (-1 for original layer name or title)
@ -328,8 +334,6 @@ class CORE_EXPORT QgsDxfExport
void registerDxfLayer( const QString &layerId, QgsFeatureId fid, const QString &layer ); void registerDxfLayer( const QString &layerId, QgsFeatureId fid, const QString &layer );
private: private:
QList< QPair<QgsVectorLayer*, int> > mLayers;
//! Extent for export, only intersecting features are exported. If the extent is an empty rectangle, all features are exported //! Extent for export, only intersecting features are exported. If the extent is an empty rectangle, all features are exported
QgsRectangle mExtent; QgsRectangle mExtent;
//! Scale for symbology export (used if symbols units are mm) //! Scale for symbology export (used if symbols units are mm)
@ -396,6 +400,7 @@ class CORE_EXPORT QgsDxfExport
QMap< QString, QMap<QgsFeatureId, QString> > mDxfLayerNames; QMap< QString, QMap<QgsFeatureId, QString> > mDxfLayerNames;
QgsCoordinateReferenceSystem mCrs; QgsCoordinateReferenceSystem mCrs;
QgsMapSettings mMapSettings; QgsMapSettings mMapSettings;
QHash<QString, int> mLayerNameAttribute;
double mFactor; double mFactor;
}; };