Skip to content

Commit ae2b72b

Browse files
committedNov 8, 2013
Write linetypes for simple line with custom dash pattern
1 parent 4984ad6 commit ae2b72b

File tree

2 files changed

+156
-9
lines changed

2 files changed

+156
-9
lines changed
 

‎src/core/qgsdxfexport.cpp

Lines changed: 148 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
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+
}

‎src/core/qgsdxfexport.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ class QgsDxfExport
6666

6767
static double mDxfColors[][3];
6868

69+
int mSymbolLayerCounter; //internal counter
70+
QHash< const QgsSymbolLayerV2*, QString > mLineStyles; //symbol layer name types
71+
6972
void writeHeader( QTextStream& stream );
7073
void writeTables( QTextStream& stream );
7174
void writeEntities( QTextStream& stream );
@@ -75,7 +78,7 @@ class QgsDxfExport
7578
void startSection( QTextStream& stream );
7679
void endSection( QTextStream& stream );
7780

78-
void writePolyline( QTextStream& stream, const QgsPolyline& line, const QString& layer, int color,
81+
void writePolyline( QTextStream& stream, const QgsPolyline& line, const QString& layer, const QString& lineStyleName, int color,
7982
double width = -1, bool polygon = false );
8083
void writeVertex( QTextStream& stream, const QgsPoint& pt, const QString& layer );
8184

@@ -98,6 +101,10 @@ class QgsDxfExport
98101
void startRender( QgsVectorLayer* vl ) const;
99102
void stopRender( QgsVectorLayer* vl ) const;
100103
static double mapUnitScaleFactor( double scaleDenominator, QgsSymbolV2::OutputUnit symbolUnits, QGis::UnitType mapUnits );
104+
QList<QgsSymbolLayerV2*> symbolLayers();
105+
static int nLineTypes( const QList<QgsSymbolLayerV2*>& symbolLayers );
106+
107+
void writeSymbolLayerLinestyle( QTextStream& stream, const QgsSymbolLayerV2* symbolLayer );
101108
};
102109

103110
#endif // QGSDXFEXPORT_H

0 commit comments

Comments
 (0)
Please sign in to comment.