2020#include " qgspoint.h"
2121#include " qgsrendererv2.h"
2222#include " qgssymbollayerv2.h"
23+ #include " qgslinesymbollayerv2.h"
2324#include " qgsvectorlayer.h"
2425#include < QIODevice>
2526#include < QTextStream>
@@ -285,7 +286,7 @@ double QgsDxfExport::mDxfColors[][3] =
285286 {1 , 1 , 1 } // 255
286287};
287288
288- QgsDxfExport::QgsDxfExport (): mSymbologyScaleDenominator( 1.0 ), mSymbologyExport( NoSymbology ), mMapUnits( QGis::Meters )
289+ QgsDxfExport::QgsDxfExport (): mSymbologyScaleDenominator( 1.0 ), mSymbologyExport( NoSymbology ), mMapUnits( QGis::Meters ), mSymbolLayerCounter( 0 )
289290{
290291}
291292
@@ -378,14 +379,24 @@ void QgsDxfExport::writeTables( QTextStream& stream )
378379 stream << " 2\n " ;
379380 stream << " TABLES\n " ;
380381
382+ // iterate through all layers and get symbol layer pointers
383+ QList<QgsSymbolLayerV2*> slList;
384+ if ( mSymbologyExport != NoSymbology )
385+ {
386+ slList = symbolLayers ();
387+ }
388+
381389 // LTYPE
390+ mLineStyles .clear ();
382391 stream << " 0\n " ;
383392 stream << " TABLE\n " ;
384393 stream << " 2\n " ;
385394 stream << " LTYPE\n " ;
386395 stream << " 70\n " ;
387- stream << " 1\n " ; // number of linetypes
396+ stream << QString ( " % 1\n " ). arg ( nLineTypes ( slList ) ) ; // number of linetypes
388397 stream << " 0\n " ;
398+
399+ // add continuous style as default
389400 stream << " LTYPE\n " ;
390401 stream << " 2\n " ;
391402 stream << " CONTINUOUS\n " ;
@@ -399,6 +410,14 @@ void QgsDxfExport::writeTables( QTextStream& stream )
399410 stream << " 0\n " ;
400411 stream << " 40\n " ; // todo: add segments in group 49
401412 stream << " 0\n " ;
413+
414+ // add symbol layer linestyles
415+ QList<QgsSymbolLayerV2*>::const_iterator slIt = slList.constBegin ();
416+ for ( ; slIt != slList.constEnd (); ++slIt )
417+ {
418+ writeSymbolLayerLinestyle ( stream, *slIt );
419+ }
420+
402421 stream << " 0\n " ;
403422 stream << " ENDTAB\n " ;
404423
@@ -598,15 +617,15 @@ void QgsDxfExport::endSection( QTextStream& stream )
598617 stream << " ENDSEC\n " ;
599618}
600619
601- void QgsDxfExport::writePolyline ( QTextStream& stream, const QgsPolyline& line, const QString& layer, int color,
620+ void QgsDxfExport::writePolyline ( QTextStream& stream, const QgsPolyline& line, const QString& layer, const QString& lineStyleName, int color,
602621 double width, bool polygon )
603622{
604623 stream << " 0\n " ;
605624 stream << " POLYLINE\n " ;
606625 stream << " 8\n " ;
607626 stream << layer << " \n " ;
608627 stream << " 6\n " ;
609- stream << " CONTINUOUS \n " ; // todo: reference to linetype here
628+ stream << QString ( " %1 \n " ). arg ( lineStyleName );
610629 stream << " 62\n " ;
611630 stream << color << " \n " ;
612631 stream << " 66\n " ;
@@ -671,14 +690,20 @@ void QgsDxfExport::addFeature( const QgsFeature& fet, QTextStream& stream, const
671690 {
672691 int c = colorFromSymbolLayer ( symbolLayer );
673692 double width = widthFromSymbolLayer ( symbolLayer );
693+ QString lineStyleName = " CONTINUOUS" ;
694+ QHash< const QgsSymbolLayerV2*, QString >::const_iterator lineTypeIt = mLineStyles .find ( symbolLayer );
695+ if ( lineTypeIt != mLineStyles .constEnd () )
696+ {
697+ lineStyleName = lineTypeIt.value ();
698+ }
674699
675700 // todo: write point symbols as blocks
676701
677702 QGis::WkbType geometryType = geom->wkbType ();
678703 // single line
679704 if ( geometryType == QGis::WKBLineString || geometryType == QGis::WKBLineString25D )
680705 {
681- writePolyline ( stream, geom->asPolyline (), layer, c, width, false );
706+ writePolyline ( stream, geom->asPolyline (), layer, lineStyleName, c, width, false );
682707 }
683708
684709 // multiline
@@ -688,7 +713,7 @@ void QgsDxfExport::addFeature( const QgsFeature& fet, QTextStream& stream, const
688713 QgsMultiPolyline::const_iterator lIt = multiLine.constBegin ();
689714 for ( ; lIt != multiLine.constEnd (); ++lIt )
690715 {
691- writePolyline ( stream, *lIt, layer, c, width, false );
716+ writePolyline ( stream, *lIt, layer, lineStyleName, c, width, false );
692717 }
693718 }
694719
@@ -699,7 +724,7 @@ void QgsDxfExport::addFeature( const QgsFeature& fet, QTextStream& stream, const
699724 QgsPolygon::const_iterator polyIt = polygon.constBegin ();
700725 for ( ; polyIt != polygon.constEnd (); ++polyIt ) // iterate over rings
701726 {
702- writePolyline ( stream, *polyIt, layer, c, width, true );
727+ writePolyline ( stream, *polyIt, layer, lineStyleName, c, width, true );
703728 }
704729 }
705730
@@ -713,7 +738,7 @@ void QgsDxfExport::addFeature( const QgsFeature& fet, QTextStream& stream, const
713738 QgsPolygon::const_iterator polyIt = mpIt->constBegin ();
714739 for ( ; polyIt != mpIt->constEnd (); ++polyIt )
715740 {
716- writePolyline ( stream, *polyIt, layer, c, width, true );
741+ writePolyline ( stream, *polyIt, layer, lineStyleName, c, width, true );
717742 }
718743 }
719744 }
@@ -857,3 +882,118 @@ double QgsDxfExport::mapUnitScaleFactor( double scaleDenominator, QgsSymbolV2::O
857882 }
858883 return 1.0 ;
859884}
885+
886+ QList<QgsSymbolLayerV2*> QgsDxfExport::symbolLayers ()
887+ {
888+ QList<QgsSymbolLayerV2*> symbolLayers;
889+
890+ QList< QgsMapLayer* >::iterator lIt = mLayers .begin ();
891+ for ( ; lIt != mLayers .end (); ++lIt )
892+ {
893+ // cast to vector layer
894+ QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( *lIt );
895+ if ( !vl )
896+ {
897+ continue ;
898+ }
899+
900+ // get rendererv2
901+ QgsFeatureRendererV2* r = vl->rendererV2 ();
902+ if ( !r )
903+ {
904+ continue ;
905+ }
906+
907+ // get all symbols
908+ QgsSymbolV2List symbols = r->symbols ();
909+ QgsSymbolV2List::iterator symbolIt = symbols.begin ();
910+ for ( ; symbolIt != symbols.end (); ++symbolIt )
911+ {
912+ int maxSymbolLayers = ( *symbolIt )->symbolLayerCount ();
913+ if ( mSymbologyExport != SymbolLayerSymbology )
914+ {
915+ maxSymbolLayers = 1 ;
916+ }
917+ for ( int i = 0 ; i < maxSymbolLayers; ++i )
918+ {
919+ symbolLayers.append (( *symbolIt )->symbolLayer ( i ) );
920+ }
921+ }
922+ }
923+
924+ return symbolLayers;
925+ }
926+
927+ void QgsDxfExport::writeSymbolLayerLinestyle ( QTextStream& stream, const QgsSymbolLayerV2* symbolLayer )
928+ {
929+ if ( !symbolLayer )
930+ {
931+ return ;
932+ }
933+
934+ // QgsSimpleLineSymbolLayer can have customDashVector() / customDashPatternUnit()
935+ const QgsSimpleLineSymbolLayerV2* simpleLine = dynamic_cast < const QgsSimpleLineSymbolLayerV2* >( symbolLayer );
936+ if ( simpleLine )
937+ {
938+ if ( simpleLine->useCustomDashPattern () )
939+ {
940+ ++mSymbolLayerCounter ;
941+ QString name = QString ( " symbolLayer%1" ).arg ( mSymbolLayerCounter );
942+
943+ QVector<qreal> dashPattern = simpleLine->customDashVector ();
944+ double length = 0 ;
945+ QVector<qreal>::const_iterator dashIt = dashPattern.constBegin ();
946+ for ( ; dashIt != dashPattern.constEnd (); ++dashIt )
947+ {
948+ length += *dashIt;
949+ }
950+
951+ stream << " LTYPE\n " ;
952+ stream << " 2\n " ;
953+
954+ stream << QString ( " %1\n " ).arg ( name );
955+ stream << " 70\n " ;
956+ stream << " 64\n " ;
957+ stream << " 3\n " ;
958+ stream << " \n " ;
959+ stream << " 72\n " ;
960+ stream << " 65\n " ;
961+ stream << " 73\n " ;
962+ stream << QString ( " %1\n " ).arg ( dashPattern.size () ); // number of segments
963+ stream << " 40\n " ; // todo: add segments in group 49
964+ stream << QString ( " %1\n " ).arg ( length );
965+
966+ dashIt = dashPattern.constBegin ();
967+ bool isSpace = false ;
968+ for ( ; dashIt != dashPattern.constEnd (); ++dashIt )
969+ {
970+ stream << " 49\n " ;
971+
972+ // map units or mm?
973+ double segmentLength = ( isSpace ? -*dashIt : *dashIt );
974+ segmentLength *= mapUnitScaleFactor ( mSymbologyScaleDenominator , simpleLine->customDashPatternUnit (), mMapUnits );
975+ stream << QString ( " %1\n " ).arg ( segmentLength );
976+ isSpace = !isSpace;
977+ }
978+ mLineStyles .insert ( symbolLayer, name );
979+ }
980+ }
981+ }
982+
983+ int QgsDxfExport::nLineTypes ( const QList<QgsSymbolLayerV2*>& symbolLayers )
984+ {
985+ int nLineTypes = 0 ;
986+ QList<QgsSymbolLayerV2*>::const_iterator slIt = symbolLayers.constBegin ();
987+ for ( ; slIt != symbolLayers.constEnd (); ++slIt )
988+ {
989+ const QgsSimpleLineSymbolLayerV2* simpleLine = dynamic_cast < const QgsSimpleLineSymbolLayerV2* >( *slIt );
990+ if ( simpleLine )
991+ {
992+ if ( simpleLine->useCustomDashPattern () )
993+ {
994+ ++nLineTypes;
995+ }
996+ }
997+ }
998+ return nLineTypes;
999+ }
0 commit comments