QGIS API Documentation  2.99.0-Master (13a3f2f)
qgsdxfexport.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsdxfexport.cpp
3  ----------------
4  begin : September 2013
5  copyright : (C) 2013 by Marco Hugentobler
6  email : marco at sourcepole dot ch
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 // Specs:
19 // AutoCAD 2000: http://www.autodesk.com/techpubs/autocad/acad2000/dxf/
20 // AutoCAD 2002: http://www.autodesk.com/techpubs/autocad/dxf/dxf2002.pdf
21 // AutoCAD 2004: http://atrey.karlin.mff.cuni.cz/projekty/vrr/doc/dxf14.pdf
22 // AutoCAD 2006: http://images.autodesk.com/adsk/files/dxf_format.pdf
23 // AutoCAD 2008: http://images.autodesk.com/adsk/files/acad_dxf0.pdf
24 // AutoCAD 2009: http://images.autodesk.com/adsk/files/acad_dxf.pdf
25 // AutoCAD 2011: http://images.autodesk.com/adsk/files/acad_dxf2.pdf
26 // AutoCAD 2012: http://images.autodesk.com/adsk/files/autocad_2012_pdf_dxf-reference_enu.pdf
27 // AutoCAD 2014: http://images.autodesk.com/adsk/files/autocad_2014_pdf_dxf_reference_enu.pdf
28 
29 #include "qgsdxfexport.h"
30 #include "qgsdxfpallabeling.h"
31 #include "qgsvectordataprovider.h"
32 #include "qgspoint.h"
33 #include "qgsproject.h"
34 #include "qgsrenderer.h"
35 #include "qgssymbollayer.h"
36 #include "qgsfillsymbollayer.h"
37 #include "qgsfeatureiterator.h"
38 #include "qgslinesymbollayer.h"
39 #include "qgsvectorlayer.h"
40 #include "qgsunittypes.h"
41 #include "qgstextlabelfeature.h"
42 #include "qgscrscache.h"
43 #include "qgslogger.h"
45 
46 #include "qgswkbtypes.h"
47 #include "qgspointv2.h"
48 #include "qgsgeos.h"
49 
50 #include "pal/feature.h"
51 #include "pal/pointset.h"
52 #include "pal/labelposition.h"
53 
54 #include <QIODevice>
55 
56 #define DXF_HANDSEED 100
57 #define DXF_HANDMAX 9999999
58 #define DXF_HANDPLOTSTYLE 0xf
59 
60 // dxf color palette
61 int QgsDxfExport::sDxfColors[][3] =
62 {
63  { 255, 255, 255 },
64  { 255, 0, 0 },
65  { 255, 255, 0 },
66  { 0, 255, 0 },
67  { 0, 255, 255 },
68  { 0, 0, 255 },
69  { 255, 0, 255 },
70  { 0, 0, 0 },
71  { 128, 128, 128 },
72  { 192, 192, 192 },
73  { 255, 0, 0 },
74  { 255, 127, 127 },
75  { 204, 0, 0 },
76  { 204, 102, 102 },
77  { 153, 0, 0 },
78  { 153, 76, 76 },
79  { 127, 0, 0 },
80  { 127, 63, 63 },
81  { 76, 0, 0 },
82  { 76, 38, 38 },
83  { 255, 63, 0 },
84  { 255, 159, 127 },
85  { 204, 51, 0 },
86  { 204, 127, 102 },
87  { 153, 38, 0 },
88  { 153, 95, 76 },
89  { 127, 31, 0 },
90  { 127, 79, 63 },
91  { 76, 19, 0 },
92  { 76, 47, 38 },
93  { 255, 127, 0 },
94  { 255, 191, 127 },
95  { 204, 102, 0 },
96  { 204, 153, 102 },
97  { 153, 76, 0 },
98  { 153, 114, 76 },
99  { 127, 63, 0 },
100  { 127, 95, 63 },
101  { 76, 38, 0 },
102  { 76, 57, 38 },
103  { 255, 191, 0 },
104  { 255, 223, 127 },
105  { 204, 153, 0 },
106  { 204, 178, 102 },
107  { 153, 114, 0 },
108  { 153, 133, 76 },
109  { 127, 95, 0 },
110  { 127, 111, 63 },
111  { 76, 57, 0 },
112  { 76, 66, 38 },
113  { 255, 255, 0 },
114  { 255, 255, 127 },
115  { 204, 204, 0 },
116  { 204, 204, 102 },
117  { 153, 153, 0 },
118  { 153, 153, 76 },
119  { 127, 127, 0 },
120  { 127, 127, 63 },
121  { 76, 76, 0 },
122  { 76, 76, 38 },
123  { 191, 255, 0 },
124  { 223, 255, 127 },
125  { 153, 204, 0 },
126  { 178, 204, 102 },
127  { 114, 153, 0 },
128  { 133, 153, 76 },
129  { 95, 127, 0 },
130  { 111, 127, 63 },
131  { 57, 76, 0 },
132  { 66, 76, 38 },
133  { 127, 255, 0 },
134  { 191, 255, 127 },
135  { 102, 204, 0 },
136  { 153, 204, 102 },
137  { 76, 153, 0 },
138  { 114, 153, 76 },
139  { 63, 127, 0 },
140  { 95, 127, 63 },
141  { 38, 76, 0 },
142  { 57, 76, 38 },
143  { 63, 255, 0 },
144  { 159, 255, 127 },
145  { 51, 204, 0 },
146  { 127, 204, 102 },
147  { 38, 153, 0 },
148  { 95, 153, 76 },
149  { 31, 127, 0 },
150  { 79, 127, 63 },
151  { 19, 76, 0 },
152  { 47, 76, 38 },
153  { 0, 255, 0 },
154  { 127, 255, 127 },
155  { 0, 204, 0 },
156  { 102, 204, 102 },
157  { 0, 153, 0 },
158  { 76, 153, 76 },
159  { 0, 127, 0 },
160  { 63, 127, 63 },
161  { 0, 76, 0 },
162  { 38, 76, 38 },
163  { 0, 255, 63 },
164  { 127, 255, 159 },
165  { 0, 204, 51 },
166  { 102, 204, 127 },
167  { 0, 153, 38 },
168  { 76, 153, 95 },
169  { 0, 127, 31 },
170  { 63, 127, 79 },
171  { 0, 76, 19 },
172  { 38, 76, 47 },
173  { 0, 255, 127 },
174  { 127, 255, 191 },
175  { 0, 204, 102 },
176  { 102, 204, 153 },
177  { 0, 153, 76 },
178  { 76, 153, 114 },
179  { 0, 127, 63 },
180  { 63, 127, 95 },
181  { 0, 76, 38 },
182  { 38, 76, 57 },
183  { 0, 255, 191 },
184  { 127, 255, 223 },
185  { 0, 204, 153 },
186  { 102, 204, 178 },
187  { 0, 153, 114 },
188  { 76, 153, 133 },
189  { 0, 127, 95 },
190  { 63, 127, 111 },
191  { 0, 76, 57 },
192  { 38, 76, 66 },
193  { 0, 255, 255 },
194  { 127, 255, 255 },
195  { 0, 204, 204 },
196  { 102, 204, 204 },
197  { 0, 153, 153 },
198  { 76, 153, 153 },
199  { 0, 127, 127 },
200  { 63, 127, 127 },
201  { 0, 76, 76 },
202  { 38, 76, 76 },
203  { 0, 191, 255 },
204  { 127, 223, 255 },
205  { 0, 153, 204 },
206  { 102, 178, 204 },
207  { 0, 114, 153 },
208  { 76, 133, 153 },
209  { 0, 95, 127 },
210  { 63, 111, 127 },
211  { 0, 57, 76 },
212  { 38, 66, 76 },
213  { 0, 127, 255 },
214  { 127, 191, 255 },
215  { 0, 102, 204 },
216  { 102, 153, 204 },
217  { 0, 76, 153 },
218  { 76, 114, 153 },
219  { 0, 63, 127 },
220  { 63, 95, 127 },
221  { 0, 38, 76 },
222  { 38, 57, 76 },
223  { 0, 63, 255 },
224  { 127, 159, 255 },
225  { 0, 51, 204 },
226  { 102, 127, 204 },
227  { 0, 38, 153 },
228  { 76, 95, 153 },
229  { 0, 31, 127 },
230  { 63, 79, 127 },
231  { 0, 19, 76 },
232  { 38, 47, 76 },
233  { 0, 0, 255 },
234  { 127, 127, 255 },
235  { 0, 0, 204 },
236  { 102, 102, 204 },
237  { 0, 0, 153 },
238  { 76, 76, 153 },
239  { 0, 0, 127 },
240  { 63, 63, 127 },
241  { 0, 0, 76 },
242  { 38, 38, 76 },
243  { 63, 0, 255 },
244  { 159, 127, 255 },
245  { 51, 0, 204 },
246  { 127, 102, 204 },
247  { 38, 0, 153 },
248  { 95, 76, 153 },
249  { 31, 0, 127 },
250  { 79, 63, 127 },
251  { 19, 0, 76 },
252  { 47, 38, 76 },
253  { 127, 0, 255 },
254  { 191, 127, 255 },
255  { 102, 0, 204 },
256  { 153, 102, 204 },
257  { 76, 0, 153 },
258  { 114, 76, 153 },
259  { 63, 0, 127 },
260  { 95, 63, 127 },
261  { 38, 0, 76 },
262  { 57, 38, 76 },
263  { 191, 0, 255 },
264  { 223, 127, 255 },
265  { 153, 0, 204 },
266  { 178, 102, 204 },
267  { 114, 0, 153 },
268  { 133, 76, 153 },
269  { 95, 0, 127 },
270  { 111, 63, 127 },
271  { 57, 0, 76 },
272  { 66, 38, 76 },
273  { 255, 0, 255 },
274  { 255, 127, 255 },
275  { 204, 0, 204 },
276  { 204, 102, 204 },
277  { 153, 0, 153 },
278  { 153, 76, 153 },
279  { 127, 0, 127 },
280  { 127, 63, 127 },
281  { 76, 0, 76 },
282  { 76, 38, 76 },
283  { 255, 0, 191 },
284  { 255, 127, 223 },
285  { 204, 0, 153 },
286  { 204, 102, 178 },
287  { 153, 0, 114 },
288  { 153, 76, 133 },
289  { 127, 0, 95 },
290  { 127, 63, 111 },
291  { 76, 0, 57 },
292  { 76, 38, 66 },
293  { 255, 0, 127 },
294  { 255, 127, 191 },
295  { 204, 0, 102 },
296  { 204, 102, 153 },
297  { 153, 0, 76 },
298  { 153, 76, 114 },
299  { 127, 0, 63 },
300  { 127, 63, 95 },
301  { 76, 0, 38 },
302  { 76, 38, 57 },
303  { 255, 0, 63 },
304  { 255, 127, 159 },
305  { 204, 0, 51 },
306  { 204, 102, 127 },
307  { 153, 0, 38 },
308  { 153, 76, 95 },
309  { 127, 0, 31 },
310  { 127, 63, 79 },
311  { 76, 0, 19 },
312  { 76, 38, 47 },
313  { 51, 51, 51 },
314  { 91, 91, 91 },
315  { 132, 132, 132 },
316  { 173, 173, 173 },
317  { 214, 214, 214 },
318  { 255, 255, 255 },
319 };
320 
321 const char *QgsDxfExport::DXF_ENCODINGS[][2] =
322 {
323  { "ASCII", "" },
324  { "8859_1", "ISO-8859-1" },
325  { "8859_2", "ISO-8859-2" },
326  { "8859_3", "ISO-8859-3" },
327  { "8859_4", "ISO-8859-4" },
328  { "8859_5", "ISO-8859-5" },
329  { "8859_6", "ISO-8859-6" },
330  { "8859_7", "ISO-8859-7" },
331  { "8859_8", "ISO-8859-8" },
332  { "8859_9", "ISO-8859-9" },
333 // { "DOS437", "" },
334  { "DOS850", "CP850" },
335 // { "DOS852", "" },
336 // { "DOS855", "" },
337 // { "DOS857", "" },
338 // { "DOS860", "" },
339 // { "DOS861", "" },
340 // { "DOS863", "" },
341 // { "DOS864", "" },
342 // { "DOS865", "" },
343 // { "DOS869", "" },
344 // { "DOS932", "" },
345  { "MACINTOSH", "MacRoman" },
346  { "BIG5", "Big5" },
347  { "KSC5601", "ksc5601.1987-0" },
348 // { "JOHAB", "" },
349  { "DOS866", "CP866" },
350  { "ANSI_1250", "CP1250" },
351  { "ANSI_1251", "CP1251" },
352  { "ANSI_1252", "CP1252" },
353  { "GB2312", "GB2312" },
354  { "ANSI_1253", "CP1253" },
355  { "ANSI_1254", "CP1254" },
356  { "ANSI_1255", "CP1255" },
357  { "ANSI_1256", "CP1256" },
358  { "ANSI_1257", "CP1257" },
359  { "ANSI_874", "CP874" },
360  { "ANSI_932", "Shift_JIS" },
361  { "ANSI_936", "CP936" },
362  { "ANSI_949", "cp949" },
363  { "ANSI_950", "CP950" },
364 // { "ANSI_1361", "" },
365 // { "ANSI_1200", "" },
366  { "ANSI_1258", "CP1258" },
367 };
368 
370  : mSymbologyScaleDenominator( 1.0 )
371  , mSymbologyExport( NoSymbology )
372  , mMapUnits( QgsUnitTypes::DistanceMeters )
373  , mLayerTitleAsName( false )
374  , mSymbolLayerCounter( 0 )
375  , mNextHandleId( DXF_HANDSEED )
376  , mBlockCounter( 0 )
377  , mFactor( 1 )
378 {
379 }
380 
382 {
383  *this = dxfExport;
384 }
385 
387 {
388  mMapSettings = dxfExport.mMapSettings;
389  mLayerNameAttribute = dxfExport.mLayerNameAttribute;
390  mSymbologyScaleDenominator = dxfExport.mSymbologyScaleDenominator;
391  mSymbologyExport = dxfExport.mSymbologyExport;
392  mMapUnits = dxfExport.mMapUnits;
393  mLayerTitleAsName = dxfExport.mLayerTitleAsName;
394  mSymbolLayerCounter = 0; // internal counter
395  mNextHandleId = 0;
396  mBlockCounter = 0;
398  mFactor = dxfExport.mFactor;
399  return *this;
400 }
401 
403 {
404  mMapSettings = settings;
405 }
406 
407 void QgsDxfExport::addLayers( const QList< QPair< QgsVectorLayer *, int > > &layers )
408 {
409  QList<QgsMapLayer *> layerList;
410 
411  mLayerNameAttribute.clear();
412 
413  QList< QPair< QgsVectorLayer *, int > >::const_iterator layerIt = layers.constBegin();
414  for ( ; layerIt != layers.constEnd(); ++layerIt )
415  {
416  layerList << layerIt->first;
417  if ( layerIt->second >= 0 )
418  mLayerNameAttribute.insert( layerIt->first->id(), layerIt->second );
419  }
420 
421  mMapSettings.setLayers( layerList );
422 }
423 
424 void QgsDxfExport::writeGroup( int code, int i )
425 {
426  writeGroupCode( code );
427  writeInt( i );
428 }
429 
430 void QgsDxfExport::writeGroup( int code, double d )
431 {
432  writeGroupCode( code );
433  writeDouble( d );
434 }
435 
436 void QgsDxfExport::writeGroup( int code, const QString &s )
437 {
438  writeGroupCode( code );
439  writeString( s );
440 }
441 
442 void QgsDxfExport::writeGroup( int code, const QgsPointV2 &p )
443 {
444  writeGroup( code + 10, p.x() );
445  writeGroup( code + 20, p.y() );
446  if ( p.is3D() && qIsFinite( p.z() ) )
447  writeGroup( code + 30, p.z() );
448 }
449 
450 void QgsDxfExport::writeGroup( const QColor &color, int exactMatchCode, int rgbCode, int transparencyCode )
451 {
452  int minDistAt = -1;
453  int minDist = INT_MAX;
454 
455  for ( int i = 1; i < static_cast< int >( sizeof( sDxfColors ) / sizeof( *sDxfColors ) ) && minDist > 0; ++i )
456  {
457  int dist = color_distance( color.rgba(), i );
458  if ( dist >= minDist )
459  continue;
460 
461  minDistAt = i;
462  minDist = dist;
463  }
464 
465  if ( minDist == 0 && minDistAt != 7 )
466  {
467  // exact full opaque match, not black/white
468  writeGroup( exactMatchCode, minDistAt );
469  if ( color.alpha() == 255 )
470  return;
471  }
472 
473  int c = ( color.red() & 0xff ) * 0x10000 + ( color.green() & 0xff ) * 0x100 + ( color.blue() & 0xff );
474  writeGroup( rgbCode, c );
475  if ( transparencyCode != -1 && color.alpha() < 255 )
476  writeGroup( transparencyCode, 0x2000000 | color.alpha() );
477 }
478 
480 {
481  mTextStream << QStringLiteral( "%1\n" ).arg( code, 3, 10, QChar( ' ' ) );
482 }
483 
485 {
486  mTextStream << QStringLiteral( "%1\n" ).arg( i, 6, 10, QChar( ' ' ) );
487 }
488 
490 {
491  QString s( qgsDoubleToString( d ) );
492  if ( !s.contains( '.' ) )
493  s += QLatin1String( ".0" );
494  mTextStream << s << '\n';
495 }
496 
497 void QgsDxfExport::writeString( const QString &s )
498 {
499  mTextStream << s << '\n';
500 }
501 
502 int QgsDxfExport::writeToFile( QIODevice *d, const QString &encoding )
503 {
504  if ( !d )
505  {
506  return 1;
507  }
508 
509  if ( !d->isOpen() && !d->open( QIODevice::WriteOnly ) )
510  {
511  return 2;
512  }
513 
514  mTextStream.setDevice( d );
515  mTextStream.setCodec( encoding.toLocal8Bit() );
516 
517  if ( mExtent.isEmpty() )
518  {
519  Q_FOREACH ( QgsMapLayer *ml, mMapSettings.layers() )
520  {
521  QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( ml );
522  if ( !vl )
523  continue;
524 
525  QgsRectangle layerExtent = vl->extent();
526  layerExtent = mMapSettings.layerToMapCoordinates( vl, layerExtent );
527 
528  if ( mExtent.isEmpty() )
529  {
530  mExtent = layerExtent;
531  }
532  else
533  {
534  mExtent.combineExtentWith( layerExtent );
535  }
536  }
537  }
538 
540  mMapSettings.setExtent( mExtent );
541 
542  int dpi = 96;
543  mFactor = 1000 * dpi / mSymbologyScaleDenominator / 25.4 * QgsUnitTypes::fromUnitToUnitFactor( mapUnits, QgsUnitTypes::DistanceMeters );
544  mMapSettings.setOutputSize( QSize( mExtent.width() * mFactor, mExtent.height() * mFactor ) );
545  mMapSettings.setOutputDpi( dpi );
546  if ( mCrs.isValid() )
547  mMapSettings.setDestinationCrs( mCrs );
548 
549  writeHeader( dxfEncoding( encoding ) );
550  writeTables();
551  writeBlocks();
552  writeEntities();
553  writeEndFile();
554 
555  return 0;
556 }
557 
559 {
560  return mMapUnits;
561 }
562 
563 void QgsDxfExport::writeHeader( const QString &codepage )
564 {
565  writeGroup( 999, QStringLiteral( "DXF created from QGIS" ) );
566 
567  startSection();
568  writeGroup( 2, QStringLiteral( "HEADER" ) );
569 
570  // ACADVER
571  writeGroup( 9, QStringLiteral( "$ACADVER" ) );
572  writeGroup( 1, QStringLiteral( "AC1015" ) );
573 
574  // EXTMIN
575  writeGroup( 9, QStringLiteral( "$EXTMIN" ) );
576  writeGroup( 0, QgsPointV2( QgsWkbTypes::PointZ, mExtent.xMinimum(), mExtent.yMinimum() ) );
577 
578  // EXTMAX
579  writeGroup( 9, QStringLiteral( "$EXTMAX" ) );
580  writeGroup( 0, QgsPointV2( QgsWkbTypes::PointZ, mExtent.xMaximum(), mExtent.yMaximum() ) );
581 
582  // Global linetype scale
583  writeGroup( 9, QStringLiteral( "$LTSCALE" ) );
584  writeGroup( 40, 1.0 );
585 
586  // Point display mode (33 = circle)
587  writeGroup( 9, QStringLiteral( "$PDMODE" ) );
588  writeGroup( 70, 33 );
589 
590  // Point display size
591  writeGroup( 9, QStringLiteral( "$PDSIZE" ) );
592  writeGroup( 40, 1 );
593 
594  // Controls paper space linetype scaling (1 = No special linetype scaling, 0 = Viewport scaling governs linetype scaling)
595  writeGroup( 9, QStringLiteral( "$PSLTSCALE" ) );
596  writeGroup( 70, 0 );
597 
598  writeGroup( 9, QStringLiteral( "$HANDSEED" ) );
599  writeGroup( 5, DXF_HANDMAX );
600 
601  writeGroup( 9, QStringLiteral( "$DWGCODEPAGE" ) );
602  writeGroup( 3, codepage );
603 
604  endSection();
605 }
606 
607 int QgsDxfExport::writeHandle( int code, int handle )
608 {
609  if ( handle == 0 )
610  handle = mNextHandleId++;
611 
612  Q_ASSERT_X( handle < DXF_HANDMAX, "QgsDxfExport::writeHandle(int, int)", "DXF handle too large" );
613 
614  writeGroup( code, QStringLiteral( "%1" ).arg( handle, 0, 16 ) );
615  return handle;
616 }
617 
618 void QgsDxfExport::writeTables()
619 {
620  startSection();
621  writeGroup( 2, QStringLiteral( "TABLES" ) );
622 
623  // Iterate through all layers and get symbol layer pointers
624  QgsRenderContext context = renderContext();
625  QList< QPair< QgsSymbolLayer *, QgsSymbol * > > slList;
626  if ( mSymbologyExport != NoSymbology )
627  {
628  slList = symbolLayers( context );
629  }
630 
631  // Line types
632  mLineStyles.clear();
633  writeGroup( 0, QStringLiteral( "TABLE" ) );
634  writeGroup( 2, QStringLiteral( "LTYPE" ) );
635  writeHandle();
636  writeGroup( 100, QStringLiteral( "AcDbSymbolTable" ) );
637  writeGroup( 70, nLineTypes( slList ) + 5 );
638 
639  writeDefaultLinetypes();
640 
641  // Add custom linestyles
642  QList< QPair< QgsSymbolLayer *, QgsSymbol *> >::const_iterator slIt = slList.constBegin();
643  for ( ; slIt != slList.constEnd(); ++slIt )
644  {
645  writeSymbolLayerLinetype( slIt->first );
646  }
647 
648  writeGroup( 0, QStringLiteral( "ENDTAB" ) );
649 
650  // BLOCK_RECORD
651  writeGroup( 0, QStringLiteral( "TABLE" ) );
652  writeGroup( 2, QStringLiteral( "BLOCK_RECORD" ) );
653  writeHandle();
654 
655  writeGroup( 100, QStringLiteral( "AcDbSymbolTable" ) );
656  writeGroup( 70, 0 );
657 
658  Q_FOREACH ( const QString &block, QStringList() << "*Model_Space" << "*Paper_Space" << "*Paper_Space0" )
659  {
660  writeGroup( 0, QStringLiteral( "BLOCK_RECORD" ) );
661  mBlockHandles.insert( block, writeHandle() );
662  writeGroup( 100, QStringLiteral( "AcDbSymbolTableRecord" ) );
663  writeGroup( 100, QStringLiteral( "AcDbBlockTableRecord" ) );
664  writeGroup( 2, block );
665  }
666 
667  int i = 0;
668  slIt = slList.constBegin();
669  for ( ; slIt != slList.constEnd(); ++slIt )
670  {
671  QgsMarkerSymbolLayer *ml = dynamic_cast< QgsMarkerSymbolLayer *>( slIt->first );
672  if ( !ml )
673  continue;
674 
675  if ( hasDataDefinedProperties( ml, slIt->second ) )
676  continue;
677 
678  QString name = QStringLiteral( "symbolLayer%1" ).arg( i++ );
679  writeGroup( 0, QStringLiteral( "BLOCK_RECORD" ) );
680  mBlockHandles.insert( name, writeHandle() );
681  writeGroup( 100, QStringLiteral( "AcDbSymbolTableRecord" ) );
682  writeGroup( 100, QStringLiteral( "AcDbBlockTableRecord" ) );
683  writeGroup( 2, name );
684  }
685 
686  writeGroup( 0, QStringLiteral( "ENDTAB" ) );
687 
688  // APPID
689  writeGroup( 0, QStringLiteral( "TABLE" ) );
690  writeGroup( 2, QStringLiteral( "APPID" ) );
691  writeHandle();
692  writeGroup( 100, QStringLiteral( "AcDbSymbolTable" ) );
693  writeGroup( 70, 1 );
694  writeGroup( 0, QStringLiteral( "APPID" ) );
695  writeHandle();
696  writeGroup( 100, QStringLiteral( "AcDbSymbolTableRecord" ) );
697  writeGroup( 100, QStringLiteral( "AcDbRegAppTableRecord" ) );
698  writeGroup( 2, QStringLiteral( "ACAD" ) );
699  writeGroup( 70, 0 );
700  writeGroup( 0, QStringLiteral( "ENDTAB" ) );
701 
702  // VIEW
703  writeGroup( 0, QStringLiteral( "TABLE" ) );
704  writeGroup( 2, QStringLiteral( "VIEW" ) );
705  writeHandle();
706  writeGroup( 100, QStringLiteral( "AcDbSymbolTable" ) );
707  writeGroup( 70, 0 );
708  writeGroup( 0, QStringLiteral( "ENDTAB" ) );
709 
710  // UCS
711  writeGroup( 0, QStringLiteral( "TABLE" ) );
712  writeGroup( 2, QStringLiteral( "UCS" ) );
713  writeHandle();
714  writeGroup( 100, QStringLiteral( "AcDbSymbolTable" ) );
715  writeGroup( 70, 0 );
716  writeGroup( 0, QStringLiteral( "ENDTAB" ) );
717 
718  // VPORT
719  writeGroup( 0, QStringLiteral( "TABLE" ) );
720  writeGroup( 2, QStringLiteral( "VPORT" ) );
721  writeHandle();
722  writeGroup( 100, QStringLiteral( "AcDbSymbolTable" ) );
723 
724  writeGroup( 0, QStringLiteral( "VPORT" ) );
725  writeHandle();
726  writeGroup( 100, QStringLiteral( "AcDbSymbolTableRecord" ) );
727  writeGroup( 100, QStringLiteral( "AcDbViewportTableRecord" ) );
728  writeGroup( 2, QStringLiteral( "*ACTIVE" ) );
729  writeGroup( 70, 0 ); // flags
730  writeGroup( 0, QgsPointV2( 0.0, 0.0 ) ); // lower left
731  writeGroup( 1, QgsPointV2( 1.0, 1.0 ) ); // upper right
732  writeGroup( 2, QgsPointV2( 0.0, 0.0 ) ); // view center point
733  writeGroup( 3, QgsPointV2( 0.0, 0.0 ) ); // snap base point
734  writeGroup( 4, QgsPointV2( 1.0, 1.0 ) ); // snap spacing
735  writeGroup( 5, QgsPointV2( 1.0, 1.0 ) ); // grid spacing
736  writeGroup( 6, QgsPointV2( QgsWkbTypes::PointZ, 0.0, 0.0, 1.0 ) ); // view direction from target point
737  writeGroup( 7, QgsPointV2( mExtent.center() ) ); // view target point
738  writeGroup( 40, mExtent.height() ); // view height
739  writeGroup( 41, mExtent.width() / mExtent.height() ); // view aspect ratio
740  writeGroup( 42, 50.0 ); // lens length
741  writeGroup( 43, 0.0 ); // front clipping plane
742  writeGroup( 44, 0.0 ); // back clipping plane
743  writeGroup( 50, 0.0 ); // snap rotation
744  writeGroup( 51, 0.0 ); // view twist angle
745  writeGroup( 71, 0 ); // view mode (0 = deactivates)
746  writeGroup( 72, 100 ); // circle zoom percent
747  writeGroup( 73, 1 ); // fast zoom setting
748  writeGroup( 74, 1 ); // UCSICON setting
749  writeGroup( 75, 0 ); // snapping off
750  writeGroup( 76, 0 ); // grid off
751  writeGroup( 77, 0 ); // snap style
752  writeGroup( 78, 0 ); // snap isopair
753  writeGroup( 281, 0 ); // render mode (0 = 2D optimized)
754  writeGroup( 65, 1 ); // value of UCSVP for this viewport
755  writeGroup( 100, QgsPointV2( QgsWkbTypes::PointZ ) ); // UCS origin
756  writeGroup( 101, QgsPointV2( QgsWkbTypes::PointZ, 1.0 ) ); // UCS x axis
757  writeGroup( 102, QgsPointV2( QgsWkbTypes::PointZ, 0.0, 1.0 ) ); // UCS y axis
758  writeGroup( 79, 0 ); // Orthographic type of UCS (0 = UCS is not orthographic)
759  writeGroup( 146, 0.0 ); // Elevation
760 
761  writeGroup( 70, 0 );
762  writeGroup( 0, QStringLiteral( "ENDTAB" ) );
763 
764  // DIMSTYLE
765  writeGroup( 0, QStringLiteral( "TABLE" ) );
766  writeGroup( 2, QStringLiteral( "DIMSTYLE" ) );
767  writeHandle();
768  writeGroup( 100, QStringLiteral( "AcDbSymbolTable" ) );
769  writeGroup( 100, QStringLiteral( "AcDbDimStyleTable" ) );
770  writeGroup( 70, 0 );
771  writeGroup( 0, QStringLiteral( "ENDTAB" ) );
772 
773  QSet<QString> layerNames;
774  Q_FOREACH ( QgsMapLayer *ml, mMapSettings.layers() )
775  {
776  if ( !layerIsScaleBasedVisible( ml ) )
777  continue;
778 
779  QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( ml );
780  if ( !vl )
781  continue;
782 
783  int attrIdx = mLayerNameAttribute.value( vl->id(), -1 );
784  if ( attrIdx < 0 )
785  {
786  layerNames << dxfLayerName( layerName( vl ) );
787  }
788  else
789  {
790  QList<QVariant> values;
791  vl->uniqueValues( attrIdx, values );
792  Q_FOREACH ( const QVariant &v, values )
793  {
794  layerNames << dxfLayerName( v.toString() );
795  }
796  }
797  }
798 
799  // Layers
800  // TODO: iterate features of all layer to produce a data-defined layer list
801  writeGroup( 0, QStringLiteral( "TABLE" ) );
802  writeGroup( 2, QStringLiteral( "LAYER" ) );
803  writeHandle();
804  writeGroup( 100, QStringLiteral( "AcDbSymbolTable" ) );
805  writeGroup( 70, layerNames.size() + 1 );
806 
807  writeGroup( 0, QStringLiteral( "LAYER" ) );
808  writeHandle();
809  writeGroup( 100, QStringLiteral( "AcDbSymbolTableRecord" ) );
810  writeGroup( 100, QStringLiteral( "AcDbLayerTableRecord" ) );
811  writeGroup( 2, QStringLiteral( "0" ) );
812  writeGroup( 70, 64 );
813  writeGroup( 62, 1 );
814  writeGroup( 6, QStringLiteral( "CONTINUOUS" ) );
816 
817  Q_FOREACH ( const QString &layerName, layerNames )
818  {
819  writeGroup( 0, QStringLiteral( "LAYER" ) );
820  writeHandle();
821  writeGroup( 100, QStringLiteral( "AcDbSymbolTableRecord" ) );
822  writeGroup( 100, QStringLiteral( "AcDbLayerTableRecord" ) );
823  writeGroup( 2, layerName );
824  writeGroup( 70, 64 );
825  writeGroup( 62, 1 );
826  writeGroup( 6, QStringLiteral( "CONTINUOUS" ) );
828  }
829  writeGroup( 0, QStringLiteral( "ENDTAB" ) );
830 
831  // Text styles
832  writeGroup( 0, QStringLiteral( "TABLE" ) );
833  writeGroup( 2, QStringLiteral( "STYLE" ) );
834  writeHandle();
835  writeGroup( 100, QStringLiteral( "AcDbSymbolTable" ) );
836  writeGroup( 70, 1 );
837 
838  // Provide only standard font for the moment
839  writeGroup( 0, QStringLiteral( "STYLE" ) );
840  writeHandle();
841  writeGroup( 100, QStringLiteral( "AcDbSymbolTableRecord" ) );
842  writeGroup( 100, QStringLiteral( "AcDbTextStyleTableRecord" ) );
843  writeGroup( 2, QStringLiteral( "STANDARD" ) );
844  writeGroup( 70, 64 );
845  writeGroup( 40, 0.0 );
846  writeGroup( 41, 1.0 );
847  writeGroup( 50, 0.0 );
848  writeGroup( 71, 0 );
849  writeGroup( 42, 5.0 );
850  writeGroup( 3, QStringLiteral( "romans.shx" ) );
851  writeGroup( 4, QLatin1String( "" ) );
852 
853  writeGroup( 0, QStringLiteral( "ENDTAB" ) );
854 
855  endSection();
856 }
857 
858 void QgsDxfExport::writeBlocks()
859 {
860  startSection();
861  writeGroup( 2, QStringLiteral( "BLOCKS" ) );
862 
863  Q_FOREACH ( const QString &block, QStringList() << "*Model_Space" << "*Paper_Space" << "*Paper_Space0" )
864  {
865  writeGroup( 0, QStringLiteral( "BLOCK" ) );
866  writeHandle();
867  writeGroup( 330, QStringLiteral( "%1" ).arg( mBlockHandles[ block ], 0, 16 ) );
868  writeGroup( 100, QStringLiteral( "AcDbEntity" ) );
869  writeGroup( 8, QStringLiteral( "0" ) );
870  writeGroup( 100, QStringLiteral( "AcDbBlockBegin" ) );
871  writeGroup( 2, block );
872  writeGroup( 70, 0 );
874  writeGroup( 3, block );
875  writeGroup( 1, QLatin1String( "" ) );
876  writeGroup( 0, QStringLiteral( "ENDBLK" ) );
877  writeHandle();
878  writeGroup( 100, QStringLiteral( "AcDbEntity" ) );
879  writeGroup( 8, QStringLiteral( "0" ) );
880  writeGroup( 100, QStringLiteral( "AcDbBlockEnd" ) );
881  }
882 
883  QgsRenderContext ct = renderContext();
884 
885  // Iterate through all layers and get symbol layer pointers
886  QList< QPair< QgsSymbolLayer *, QgsSymbol * > > slList;
887  if ( mSymbologyExport != NoSymbology )
888  {
889  slList = symbolLayers( ct );
890  }
891 
892  QList< QPair< QgsSymbolLayer *, QgsSymbol * > >::const_iterator slIt = slList.constBegin();
893  for ( ; slIt != slList.constEnd(); ++slIt )
894  {
895  QgsMarkerSymbolLayer *ml = dynamic_cast< QgsMarkerSymbolLayer *>( slIt->first );
896  if ( !ml )
897  continue;
898 
899  // if point symbol layer and no data defined properties: write block
900  QgsSymbolRenderContext ctx( ct, QgsUnitTypes::RenderMapUnits, slIt->second->alpha(), false, slIt->second->renderHints(), nullptr );
901  ml->startRender( ctx );
902 
903  // markers with data defined properties are inserted inline
904  if ( hasDataDefinedProperties( ml, slIt->second ) )
905  {
906  continue;
907  // ml->stopRender( ctx );
908  }
909 
910  QString block( QStringLiteral( "symbolLayer%1" ).arg( mBlockCounter++ ) );
911  mBlockHandle = QStringLiteral( "%1" ).arg( mBlockHandles[ block ], 0, 16 );
912 
913  writeGroup( 0, QStringLiteral( "BLOCK" ) );
914  writeHandle();
915  writeGroup( 330, mBlockHandle );
916  writeGroup( 100, QStringLiteral( "AcDbEntity" ) );
917  writeGroup( 8, QStringLiteral( "0" ) );
918  writeGroup( 100, QStringLiteral( "AcDbBlockBegin" ) );
919  writeGroup( 2, block );
920  writeGroup( 70, 0 );
921 
922  // x/y/z coordinates of reference point
923  // todo: consider anchor point
924  // double size = ml->size();
925  // size *= mapUnitScaleFactor( mSymbologyScaleDenominator, ml->sizeUnit(), mMapUnits );
927  writeGroup( 3, block );
928  writeGroup( 1, QLatin1String( "" ) );
929 
930  // maplayer 0 -> block receives layer from INSERT statement
931  ml->writeDxf( *this, mapUnitScaleFactor( mSymbologyScaleDenominator, ml->sizeUnit(), mMapUnits ), QStringLiteral( "0" ), ctx );
932 
933  writeGroup( 0, QStringLiteral( "ENDBLK" ) );
934  writeHandle();
935  writeGroup( 100, QStringLiteral( "AcDbEntity" ) );
936  writeGroup( 8, QStringLiteral( "0" ) );
937  writeGroup( 100, QStringLiteral( "AcDbBlockEnd" ) );
938 
939  mPointSymbolBlocks.insert( ml, block );
940  ml->stopRender( ctx );
941  }
942  endSection();
943 }
944 
945 
946 void QgsDxfExport::writeEntities()
947 {
948  startSection();
949  writeGroup( 2, QStringLiteral( "ENTITIES" ) );
950 
951  mBlockHandle = QStringLiteral( "%1" ).arg( mBlockHandles[ QStringLiteral( "*Model_Space" )], 0, 16 );
952 
953  QImage image( 10, 10, QImage::Format_ARGB32_Premultiplied );
954  image.setDotsPerMeterX( 96 / 25.4 * 1000 );
955  image.setDotsPerMeterY( 96 / 25.4 * 1000 );
956  QPainter painter( &image );
957 
958  QgsRenderContext ctx;
959  ctx.setPainter( &painter );
960  ctx.setRendererScale( mSymbologyScaleDenominator );
961  ctx.setExtent( mExtent );
962 
963  ctx.setScaleFactor( 96.0 / 25.4 );
964  ctx.setMapToPixel( QgsMapToPixel( 1.0 / mFactor, mExtent.center().x(), mExtent.center().y(), mExtent.width() * mFactor,
965  mExtent.height() * mFactor, 0 ) );
966 
967  // label engine
968  QgsLabelingEngine engine;
969  engine.setMapSettings( mMapSettings );
970 
971  // iterate through the maplayers
972  Q_FOREACH ( QgsMapLayer *ml, mMapSettings.layers() )
973  {
974  QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( ml );
975  if ( !vl || !layerIsScaleBasedVisible( vl ) )
976  {
977  continue;
978  }
979 
980  bool hasStyleOverride = mMapSettings.layerStyleOverrides().contains( vl->id() );
981  if ( hasStyleOverride )
982  {
983  QgsDebugMsg( QString( "%1: apply override style" ).arg( vl->id() ) );
984  vl->styleManager()->setOverrideStyle( mMapSettings.layerStyleOverrides().value( vl->id() ) );
985  }
986  else
987  {
988  QgsDebugMsg( QString( "%1: not override style" ).arg( vl->id() ) );
989  }
990 
991  QgsSymbolRenderContext sctx( ctx, QgsUnitTypes::RenderMillimeters, 1.0, false, 0, nullptr );
992  QgsFeatureRenderer *renderer = vl->renderer();
993  if ( !renderer )
994  {
995  if ( hasStyleOverride )
997  continue;
998  }
999  renderer->startRender( ctx, vl->fields() );
1000 
1001  QSet<QString> attributes = renderer->usedAttributes( ctx );
1002  int attrIdx = mLayerNameAttribute.value( vl->id(), 1 );
1003  if ( vl->fields().exists( attrIdx ) )
1004  {
1005  QString layerAttr = vl->fields().at( attrIdx ).name();
1006  attributes << layerAttr;
1007  }
1008 
1009  const QgsAbstractVectorLayerLabeling *labeling = vl->labeling();
1010  QgsDxfLabelProvider *lp = nullptr;
1011  QgsDxfRuleBasedLabelProvider *rblp = nullptr;
1012  if ( const QgsRuleBasedLabeling *rbl = dynamic_cast<const QgsRuleBasedLabeling *>( labeling ) )
1013  {
1014  rblp = new QgsDxfRuleBasedLabelProvider( *rbl, vl, this );
1015  rblp->reinit( vl );
1016  engine.addProvider( rblp );
1017 
1018  if ( !rblp->prepare( ctx, attributes ) )
1019  {
1020  engine.removeProvider( rblp );
1021  rblp = nullptr;
1022  }
1023  }
1024  else
1025  {
1026  lp = new QgsDxfLabelProvider( vl, QString(), this, nullptr );
1027  engine.addProvider( lp );
1028 
1029  if ( !lp->prepare( ctx, attributes ) )
1030  {
1031  engine.removeProvider( lp );
1032  lp = nullptr;
1033  }
1034  }
1035 
1036  if ( mSymbologyExport == QgsDxfExport::SymbolLayerSymbology &&
1037  ( renderer->capabilities() & QgsFeatureRenderer::SymbolLevels ) &&
1038  renderer->usingSymbolLevels() )
1039  {
1040  writeEntitiesSymbolLevels( vl );
1041  renderer->stopRender( ctx );
1042 
1043  if ( hasStyleOverride )
1045 
1046  continue;
1047  }
1048 
1049  QgsFeatureRequest freq = QgsFeatureRequest().setSubsetOfAttributes( attributes, vl->fields() ).setExpressionContext( ctx.expressionContext() );
1050  freq.setFilterRect( mMapSettings.mapToLayerCoordinates( vl, mExtent ) );
1051 
1052  QgsFeatureIterator featureIt = vl->getFeatures( freq );
1053 
1054  QgsCoordinateTransform ct = mMapSettings.layerTransform( vl );
1055 
1056  QgsFeature fet;
1057  while ( featureIt.nextFeature( fet ) )
1058  {
1059  ctx.expressionContext().setFeature( fet );
1060  QString lName( dxfLayerName( attrIdx < 0 ? layerName( vl ) : fet.attribute( attrIdx ).toString() ) );
1061 
1062  sctx.setFeature( &fet );
1063  if ( mSymbologyExport == NoSymbology )
1064  {
1065  addFeature( sctx, ct, lName, nullptr, nullptr ); // no symbology at all
1066  }
1067  else
1068  {
1069  QgsSymbolList symbolList = renderer->symbolsForFeature( fet, ctx );
1070  if ( symbolList.size() < 1 )
1071  {
1072  continue;
1073  }
1074 
1075  if ( mSymbologyExport == QgsDxfExport::SymbolLayerSymbology ) // symbol layer symbology, but layer does not use symbol levels
1076  {
1077  QgsSymbolList::iterator symbolIt = symbolList.begin();
1078  for ( ; symbolIt != symbolList.end(); ++symbolIt )
1079  {
1080  int nSymbolLayers = ( *symbolIt )->symbolLayerCount();
1081  for ( int i = 0; i < nSymbolLayers; ++i )
1082  {
1083  addFeature( sctx, ct, lName, ( *symbolIt )->symbolLayer( i ), *symbolIt );
1084  }
1085  }
1086  }
1087  else
1088  {
1089  // take first symbollayer from first symbol
1090  QgsSymbol *s = symbolList.first();
1091  if ( !s || s->symbolLayerCount() < 1 )
1092  {
1093  continue;
1094  }
1095  addFeature( sctx, ct, lName, s->symbolLayer( 0 ), s );
1096  }
1097 
1098  if ( lp )
1099  {
1100  lp->registerDxfFeature( fet, ctx, lName );
1101  }
1102  else if ( rblp )
1103  {
1104  rblp->registerDxfFeature( fet, ctx, lName );
1105  }
1106  }
1107  }
1108 
1109  renderer->stopRender( ctx );
1110 
1111  if ( hasStyleOverride )
1113  }
1114 
1115  engine.run( ctx );
1116 
1117  endSection();
1118 }
1119 
1120 void QgsDxfExport::writeEntitiesSymbolLevels( QgsVectorLayer *layer )
1121 {
1122  if ( !layer )
1123  {
1124  return;
1125  }
1126 
1127  QgsFeatureRenderer *renderer = layer->renderer();
1128  if ( !renderer )
1129  {
1130  // TODO return error
1131  return;
1132  }
1133  QHash< QgsSymbol *, QList<QgsFeature> > features;
1134 
1135  QgsRenderContext ctx = renderContext();
1137  QgsSymbolRenderContext sctx( ctx, QgsUnitTypes::RenderMillimeters, 1.0, false, 0, nullptr );
1138  renderer->startRender( ctx, layer->fields() );
1139 
1140  // get iterator
1141  QgsFeatureRequest req;
1142  if ( layer->wkbType() == QgsWkbTypes::NoGeometry )
1143  {
1145  }
1146  req.setSubsetOfAttributes( renderer->usedAttributes( ctx ), layer->fields() );
1147  req.setFilterRect( mMapSettings.mapToLayerCoordinates( layer, mExtent ) );
1148 
1149  QgsFeatureIterator fit = layer->getFeatures( req );
1150 
1151  // fetch features
1152  QgsFeature fet;
1153  QgsSymbol *featureSymbol = nullptr;
1154  while ( fit.nextFeature( fet ) )
1155  {
1156  ctx.expressionContext().setFeature( fet );
1157  featureSymbol = renderer->symbolForFeature( fet, ctx );
1158  if ( !featureSymbol )
1159  {
1160  continue;
1161  }
1162 
1163  QHash< QgsSymbol *, QList<QgsFeature> >::iterator it = features.find( featureSymbol );
1164  if ( it == features.end() )
1165  {
1166  it = features.insert( featureSymbol, QList<QgsFeature>() );
1167  }
1168  it.value().append( fet );
1169  }
1170 
1171  // find out order
1172  QgsSymbolLevelOrder levels;
1173  QgsSymbolList symbols = renderer->symbols( ctx );
1174  for ( int i = 0; i < symbols.count(); i++ )
1175  {
1176  QgsSymbol *sym = symbols[i];
1177  for ( int j = 0; j < sym->symbolLayerCount(); j++ )
1178  {
1179  int level = sym->symbolLayer( j )->renderingPass();
1180  if ( level < 0 || level >= 1000 ) // ignore invalid levels
1181  continue;
1182  QgsSymbolLevelItem item( sym, j );
1183  while ( level >= levels.count() ) // append new empty levels
1184  levels.append( QgsSymbolLevel() );
1185  levels[level].append( item );
1186  }
1187  }
1188 
1189  QgsCoordinateTransform ct = mMapSettings.layerTransform( layer );
1190 
1191  // export symbol layers and symbology
1192  for ( int l = 0; l < levels.count(); l++ )
1193  {
1194  QgsSymbolLevel &level = levels[l];
1195  for ( int i = 0; i < level.count(); i++ )
1196  {
1197  QgsSymbolLevelItem &item = level[i];
1198  QHash< QgsSymbol *, QList<QgsFeature> >::iterator levelIt = features.find( item.symbol() );
1199  if ( levelIt == features.end() )
1200  {
1201  QgsDebugMsg( QString( "No feature found for symbol on %1 %2.%3" ).arg( layer->id() ).arg( l ).arg( i ) );
1202  continue;
1203  }
1204 
1205  int llayer = item.layer();
1206  QList<QgsFeature> &featureList = levelIt.value();
1207  QList<QgsFeature>::iterator featureIt = featureList.begin();
1208  for ( ; featureIt != featureList.end(); ++featureIt )
1209  {
1210  sctx.setFeature( &*featureIt );
1211  addFeature( sctx, ct, layer->name(), levelIt.key()->symbolLayer( llayer ), levelIt.key() );
1212  }
1213  }
1214  }
1215  renderer->stopRender( ctx );
1216 }
1217 
1218 void QgsDxfExport::writeEndFile()
1219 {
1220  // From GDAL trailer.dxf
1221  mTextStream << "\
1222  0\n\
1223 SECTION\n\
1224  2\n\
1225 OBJECTS\n\
1226  0\n\
1227 DICTIONARY\n\
1228  5\n\
1229 C\n\
1230 330\n\
1231 0\n\
1232 100\n\
1233 AcDbDictionary\n\
1234 281\n\
1235  1\n\
1236  3\n\
1237 ACAD_GROUP\n\
1238 350\n\
1239 D\n\
1240  3\n\
1241 ACAD_LAYOUT\n\
1242 350\n\
1243 1A\n\
1244  3\n\
1245 ACAD_MLEADERSTYLE\n\
1246 350\n\
1247 43\n\
1248  3\n\
1249 ACAD_MLINESTYLE\n\
1250 350\n\
1251 17\n\
1252  3\n\
1253 ACAD_PLOTSETTINGS\n\
1254 350\n\
1255 19\n\
1256  3\n\
1257 ACAD_PLOTSTYLENAME\n\
1258 350\n\
1259 E\n\
1260  3\n\
1261 ACAD_TABLESTYLE\n\
1262 350\n\
1263 42\n\
1264  3\n\
1265 ACAD_VISUALSTYLE\n\
1266 350\n\
1267 2A\n\
1268  0\n\
1269 DICTIONARY\n\
1270  5\n\
1271 D\n\
1272 102\n\
1273 {ACAD_REACTORS\n\
1274 330\n\
1275 C\n\
1276 102\n\
1277 }\n\
1278 330\n\
1279 C\n\
1280 100\n\
1281 AcDbDictionary\n\
1282 281\n\
1283  1\n\
1284  0\n\
1285 DICTIONARY\n\
1286  5\n\
1287 1A\n\
1288 102\n\
1289 {ACAD_REACTORS\n\
1290 330\n\
1291 C\n\
1292 102\n\
1293 }\n\
1294 330\n\
1295 C\n\
1296 100\n\
1297 AcDbDictionary\n\
1298 281\n\
1299  1\n\
1300  3\n\
1301 Layout1\n\
1302 350\n\
1303 1E\n\
1304  3\n\
1305 Layout2\n\
1306 350\n\
1307 26\n\
1308  3\n\
1309 Model\n\
1310 350\n\
1311 22\n\
1312  0\n\
1313 DICTIONARY\n\
1314  5\n\
1315 43\n\
1316 102\n\
1317 {ACAD_REACTORS\n\
1318 330\n\
1319 C\n\
1320 102\n\
1321 }\n\
1322 330\n\
1323 C\n\
1324 100\n\
1325 AcDbDictionary\n\
1326 281\n\
1327  1\n\
1328  0\n\
1329 DICTIONARY\n\
1330  5\n\
1331 17\n\
1332 102\n\
1333 {ACAD_REACTORS\n\
1334 330\n\
1335 C\n\
1336 102\n\
1337 }\n\
1338 330\n\
1339 C\n\
1340 100\n\
1341 AcDbDictionary\n\
1342 281\n\
1343  1\n\
1344  3\n\
1345 Standard\n\
1346 350\n\
1347 18\n\
1348  0\n\
1349 DICTIONARY\n\
1350  5\n\
1351 19\n\
1352 102\n\
1353 {ACAD_REACTORS\n\
1354 330\n\
1355 C\n\
1356 102\n\
1357 }\n\
1358 330\n\
1359 C\n\
1360 100\n\
1361 AcDbDictionary\n\
1362 281\n\
1363  1\n\
1364  0\n\
1365 ACDBDICTIONARYWDFLT\n\
1366  5\n\
1367 E\n\
1368 102\n\
1369 {ACAD_REACTORS\n\
1370 330\n\
1371 C\n\
1372 102\n\
1373 }\n\
1374 330\n\
1375 C\n\
1376 100\n\
1377 AcDbDictionary\n\
1378 281\n\
1379  1\n\
1380  3\n\
1381 Normal\n\
1382 350\n\
1383 F\n\
1384 100\n\
1385 AcDbDictionaryWithDefault\n\
1386 340\n\
1387 F\n\
1388  0\n\
1389 DICTIONARY\n\
1390  5\n\
1391 42\n\
1392 102\n\
1393 {ACAD_REACTORS\n\
1394 330\n\
1395 C\n\
1396 102\n\
1397 }\n\
1398 330\n\
1399 C\n\
1400 100\n\
1401 AcDbDictionary\n\
1402 281\n\
1403  1\n\
1404  0\n\
1405 DICTIONARY\n\
1406  5\n\
1407 2A\n\
1408 102\n\
1409 {ACAD_REACTORS\n\
1410 330\n\
1411 C\n\
1412 102\n\
1413 }\n\
1414 330\n\
1415 C\n\
1416 100\n\
1417 AcDbDictionary\n\
1418 281\n\
1419  1\n\
1420  3\n\
1421 2dWireframe\n\
1422 350\n\
1423 2F\n\
1424  3\n\
1425 3D Hidden\n\
1426 350\n\
1427 31\n\
1428  3\n\
1429 3dWireframe\n\
1430 350\n\
1431 30\n\
1432  3\n\
1433 Basic\n\
1434 350\n\
1435 32\n\
1436  3\n\
1437 Brighten\n\
1438 350\n\
1439 36\n\
1440  3\n\
1441 ColorChange\n\
1442 350\n\
1443 3A\n\
1444  3\n\
1445 Conceptual\n\
1446 350\n\
1447 34\n\
1448  3\n\
1449 Dim\n\
1450 350\n\
1451 35\n\
1452  3\n\
1453 Facepattern\n\
1454 350\n\
1455 39\n\
1456  3\n\
1457 Flat\n\
1458 350\n\
1459 2B\n\
1460  3\n\
1461 FlatWithEdges\n\
1462 350\n\
1463 2C\n\
1464  3\n\
1465 Gouraud\n\
1466 350\n\
1467 2D\n\
1468  3\n\
1469 GouraudWithEdges\n\
1470 350\n\
1471 2E\n\
1472  3\n\
1473 Linepattern\n\
1474 350\n\
1475 38\n\
1476  3\n\
1477 Realistic\n\
1478 350\n\
1479 33\n\
1480  3\n\
1481 Thicken\n\
1482 350\n\
1483 37\n\
1484  0\n\
1485 LAYOUT\n\
1486  5\n\
1487 1E\n\
1488 102\n\
1489 {ACAD_REACTORS\n\
1490 330\n\
1491 1A\n\
1492 102\n\
1493 }\n\
1494 330\n\
1495 1A\n\
1496 100\n\
1497 AcDbPlotSettings\n\
1498  1\n\
1499 \n\
1500  2\n\
1501 none_device\n\
1502  4\n\
1503 \n\
1504  6\n\
1505 \n\
1506  40\n\
1507 0.0\n\
1508  41\n\
1509 0.0\n\
1510  42\n\
1511 0.0\n\
1512  43\n\
1513 0.0\n\
1514  44\n\
1515 0.0\n\
1516  45\n\
1517 0.0\n\
1518  46\n\
1519 0.0\n\
1520  47\n\
1521 0.0\n\
1522  48\n\
1523 0.0\n\
1524  49\n\
1525 0.0\n\
1526 140\n\
1527 0.0\n\
1528 141\n\
1529 0.0\n\
1530 142\n\
1531 1.0\n\
1532 143\n\
1533 1.0\n\
1534  70\n\
1535  688\n\
1536  72\n\
1537  0\n\
1538  73\n\
1539  0\n\
1540  74\n\
1541  5\n\
1542  7\n\
1543 \n\
1544  75\n\
1545  16\n\
1546  76\n\
1547  0\n\
1548  77\n\
1549  2\n\
1550  78\n\
1551  300\n\
1552 147\n\
1553 1.0\n\
1554 148\n\
1555 0.0\n\
1556 149\n\
1557 0.0\n\
1558 100\n\
1559 AcDbLayout\n\
1560  1\n\
1561 Layout1\n\
1562  70\n\
1563  1\n\
1564  71\n\
1565  1\n\
1566  10\n\
1567 0.0\n\
1568  20\n\
1569 0.0\n\
1570  11\n\
1571 12.0\n\
1572  21\n\
1573 9.0\n\
1574  12\n\
1575 0.0\n\
1576  22\n\
1577 0.0\n\
1578  32\n\
1579 0.0\n\
1580  14\n\
1581 1.000000000000000E+20\n\
1582  24\n\
1583 1.000000000000000E+20\n\
1584  34\n\
1585 1.000000000000000E+20\n\
1586  15\n\
1587 -1.000000000000000E+20\n\
1588  25\n\
1589 -1.000000000000000E+20\n\
1590  35\n\
1591 -1.000000000000000E+20\n\
1592 146\n\
1593 0.0\n\
1594  13\n\
1595 0.0\n\
1596  23\n\
1597 0.0\n\
1598  33\n\
1599 0.0\n\
1600  16\n\
1601 1.0\n\
1602  26\n\
1603 0.0\n\
1604  36\n\
1605 0.0\n\
1606  17\n\
1607 0.0\n\
1608  27\n\
1609 1.0\n\
1610  37\n\
1611 0.0\n\
1612  76\n\
1613  0\n\
1614 330\n\
1615 1B\n\
1616  0\n\
1617 LAYOUT\n\
1618  5\n\
1619 26\n\
1620 102\n\
1621 {ACAD_REACTORS\n\
1622 330\n\
1623 1A\n\
1624 102\n\
1625 }\n\
1626 330\n\
1627 1A\n\
1628 100\n\
1629 AcDbPlotSettings\n\
1630  1\n\
1631 \n\
1632  2\n\
1633 none_device\n\
1634  4\n\
1635 \n\
1636  6\n\
1637 \n\
1638  40\n\
1639 0.0\n\
1640  41\n\
1641 0.0\n\
1642  42\n\
1643 0.0\n\
1644  43\n\
1645 0.0\n\
1646  44\n\
1647 0.0\n\
1648  45\n\
1649 0.0\n\
1650  46\n\
1651 0.0\n\
1652  47\n\
1653 0.0\n\
1654  48\n\
1655 0.0\n\
1656  49\n\
1657 0.0\n\
1658 140\n\
1659 0.0\n\
1660 141\n\
1661 0.0\n\
1662 142\n\
1663 1.0\n\
1664 143\n\
1665 1.0\n\
1666  70\n\
1667  688\n\
1668  72\n\
1669  0\n\
1670  73\n\
1671  0\n\
1672  74\n\
1673  5\n\
1674  7\n\
1675 \n\
1676  75\n\
1677  16\n\
1678  76\n\
1679  0\n\
1680  77\n\
1681  2\n\
1682  78\n\
1683  300\n\
1684 147\n\
1685 1.0\n\
1686 148\n\
1687 0.0\n\
1688 149\n\
1689 0.0\n\
1690 100\n\
1691 AcDbLayout\n\
1692  1\n\
1693 Layout2\n\
1694  70\n\
1695  1\n\
1696  71\n\
1697  2\n\
1698  10\n\
1699 0.0\n\
1700  20\n\
1701 0.0\n\
1702  11\n\
1703 0.0\n\
1704  21\n\
1705 0.0\n\
1706  12\n\
1707 0.0\n\
1708  22\n\
1709 0.0\n\
1710  32\n\
1711 0.0\n\
1712  14\n\
1713 0.0\n\
1714  24\n\
1715 0.0\n\
1716  34\n\
1717 0.0\n\
1718  15\n\
1719 0.0\n\
1720  25\n\
1721 0.0\n\
1722  35\n\
1723 0.0\n\
1724 146\n\
1725 0.0\n\
1726  13\n\
1727 0.0\n\
1728  23\n\
1729 0.0\n\
1730  33\n\
1731 0.0\n\
1732  16\n\
1733 1.0\n\
1734  26\n\
1735 0.0\n\
1736  36\n\
1737 0.0\n\
1738  17\n\
1739 0.0\n\
1740  27\n\
1741 1.0\n\
1742  37\n\
1743 0.0\n\
1744  76\n\
1745  0\n\
1746 330\n\
1747 23\n\
1748  0\n\
1749 LAYOUT\n\
1750  5\n\
1751 22\n\
1752 102\n\
1753 {ACAD_REACTORS\n\
1754 330\n\
1755 1A\n\
1756 102\n\
1757 }\n\
1758 330\n\
1759 1A\n\
1760 100\n\
1761 AcDbPlotSettings\n\
1762  1\n\
1763 \n\
1764  2\n\
1765 none_device\n\
1766  4\n\
1767 \n\
1768  6\n\
1769 \n\
1770  40\n\
1771 0.0\n\
1772  41\n\
1773 0.0\n\
1774  42\n\
1775 0.0\n\
1776  43\n\
1777 0.0\n\
1778  44\n\
1779 0.0\n\
1780  45\n\
1781 0.0\n\
1782  46\n\
1783 0.0\n\
1784  47\n\
1785 0.0\n\
1786  48\n\
1787 0.0\n\
1788  49\n\
1789 0.0\n\
1790 140\n\
1791 0.0\n\
1792 141\n\
1793 0.0\n\
1794 142\n\
1795 1.0\n\
1796 143\n\
1797 1.0\n\
1798  70\n\
1799  1712\n\
1800  72\n\
1801  0\n\
1802  73\n\
1803  0\n\
1804  74\n\
1805  0\n\
1806  7\n\
1807 \n\
1808  75\n\
1809  0\n\
1810  76\n\
1811  0\n\
1812  77\n\
1813  2\n\
1814  78\n\
1815  300\n\
1816 147\n\
1817 1.0\n\
1818 148\n\
1819 0.0\n\
1820 149\n\
1821 0.0\n\
1822 100\n\
1823 AcDbLayout\n\
1824  1\n\
1825 Model\n\
1826  70\n\
1827  1\n\
1828  71\n\
1829  0\n\
1830  10\n\
1831 0.0\n\
1832  20\n\
1833 0.0\n\
1834  11\n\
1835 12.0\n\
1836  21\n\
1837 9.0\n\
1838  12\n\
1839 0.0\n\
1840  22\n\
1841 0.0\n\
1842  32\n\
1843 0.0\n\
1844  14\n\
1845 30.0\n\
1846  24\n\
1847 49.75\n\
1848  34\n\
1849 0.0\n\
1850  15\n\
1851 130.5\n\
1852  25\n\
1853 163.1318914119703\n\
1854  35\n\
1855 0.0\n\
1856 146\n\
1857 0.0\n\
1858  13\n\
1859 0.0\n\
1860  23\n\
1861 0.0\n\
1862  33\n\
1863 0.0\n\
1864  16\n\
1865 1.0\n\
1866  26\n\
1867 0.0\n\
1868  36\n\
1869 0.0\n\
1870  17\n\
1871 0.0\n\
1872  27\n\
1873 1.0\n\
1874  37\n\
1875 0.0\n\
1876  76\n\
1877  0\n\
1878 330\n\
1879 1F\n\
1880 331\n\
1881 29\n\
1882  0\n\
1883 MLINESTYLE\n\
1884  5\n\
1885 18\n\
1886 102\n\
1887 {ACAD_REACTORS\n\
1888 330\n\
1889 17\n\
1890 102\n\
1891 }\n\
1892 330\n\
1893 17\n\
1894 100\n\
1895 AcDbMlineStyle\n\
1896  2\n\
1897 Standard\n\
1898  70\n\
1899  0\n\
1900  3\n\
1901 \n\
1902  62\n\
1903  256\n\
1904  51\n\
1905 90.0\n\
1906  52\n\
1907 90.0\n\
1908  71\n\
1909  2\n\
1910  49\n\
1911 0.5\n\
1912  62\n\
1913  256\n\
1914  6\n\
1915 BYLAYER\n\
1916  49\n\
1917 -0.5\n\
1918  62\n\
1919  256\n\
1920  6\n\
1921 BYLAYER\n\
1922  0\n\
1923 ACDBPLACEHOLDER\n\
1924  5\n\
1925 F\n\
1926 102\n\
1927 {ACAD_REACTORS\n\
1928 330\n\
1929 E\n\
1930 102\n\
1931 }\n\
1932 330\n\
1933 E\n\
1934  0\n\
1935 VISUALSTYLE\n\
1936  5\n\
1937 2F\n\
1938 102\n\
1939 {ACAD_REACTORS\n\
1940 330\n\
1941 2A\n\
1942 102\n\
1943 }\n\
1944 330\n\
1945 2A\n\
1946 100\n\
1947 AcDbVisualStyle\n\
1948  2\n\
1949 2dWireframe\n\
1950  70\n\
1951  4\n\
1952  71\n\
1953  0\n\
1954  72\n\
1955  2\n\
1956  73\n\
1957  0\n\
1958  90\n\
1959  0\n\
1960  40\n\
1961 -0.6\n\
1962  41\n\
1963 -30.0\n\
1964  62\n\
1965  5\n\
1966  63\n\
1967  7\n\
1968 421\n\
1969  16777215\n\
1970  74\n\
1971  1\n\
1972  91\n\
1973  4\n\
1974  64\n\
1975  7\n\
1976  65\n\
1977  257\n\
1978  75\n\
1979  1\n\
1980 175\n\
1981  1\n\
1982  42\n\
1983 1.0\n\
1984  92\n\
1985  0\n\
1986  66\n\
1987  257\n\
1988  43\n\
1989 1.0\n\
1990  76\n\
1991  1\n\
1992  77\n\
1993  6\n\
1994  78\n\
1995  2\n\
1996  67\n\
1997  7\n\
1998  79\n\
1999  5\n\
2000 170\n\
2001  0\n\
2002 171\n\
2003  0\n\
2004 290\n\
2005  0\n\
2006 174\n\
2007  0\n\
2008  93\n\
2009  1\n\
2010  44\n\
2011 0.0\n\
2012 173\n\
2013  0\n\
2014 291\n\
2015  0\n\
2016  45\n\
2017 0.0\n\
2018 1001\n\
2019 ACAD\n\
2020 1000\n\
2021 AcDbSavedByObjectVersion\n\
2022 1070\n\
2023  0\n\
2024  0\n\
2025 VISUALSTYLE\n\
2026  5\n\
2027 31\n\
2028 102\n\
2029 {ACAD_REACTORS\n\
2030 330\n\
2031 2A\n\
2032 102\n\
2033 }\n\
2034 330\n\
2035 2A\n\
2036 100\n\
2037 AcDbVisualStyle\n\
2038  2\n\
2039 3D Hidden\n\
2040  70\n\
2041  6\n\
2042  71\n\
2043  1\n\
2044  72\n\
2045  2\n\
2046  73\n\
2047  2\n\
2048  90\n\
2049  0\n\
2050  40\n\
2051 -0.6\n\
2052  41\n\
2053 -30.0\n\
2054  62\n\
2055  5\n\
2056  63\n\
2057  7\n\
2058 421\n\
2059  16777215\n\
2060  74\n\
2061  2\n\
2062  91\n\
2063  2\n\
2064  64\n\
2065  7\n\
2066  65\n\
2067  257\n\
2068  75\n\
2069  2\n\
2070 175\n\
2071  1\n\
2072  42\n\
2073 40.0\n\
2074  92\n\
2075  0\n\
2076  66\n\
2077  257\n\
2078  43\n\
2079 1.0\n\
2080  76\n\
2081  1\n\
2082  77\n\
2083  6\n\
2084  78\n\
2085  2\n\
2086  67\n\
2087  7\n\
2088  79\n\
2089  3\n\
2090 170\n\
2091  0\n\
2092 171\n\
2093  0\n\
2094 290\n\
2095  0\n\
2096 174\n\
2097  0\n\
2098  93\n\
2099  1\n\
2100  44\n\
2101 0.0\n\
2102 173\n\
2103  0\n\
2104 291\n\
2105  0\n\
2106  45\n\
2107 0.0\n\
2108 1001\n\
2109 ACAD\n\
2110 1000\n\
2111 AcDbSavedByObjectVersion\n\
2112 1070\n\
2113  0\n\
2114  0\n\
2115 VISUALSTYLE\n\
2116  5\n\
2117 30\n\
2118 102\n\
2119 {ACAD_REACTORS\n\
2120 330\n\
2121 2A\n\
2122 102\n\
2123 }\n\
2124 330\n\
2125 2A\n\
2126 100\n\
2127 AcDbVisualStyle\n\
2128  2\n\
2129 3dWireframe\n\
2130  70\n\
2131  5\n\
2132  71\n\
2133  0\n\
2134  72\n\
2135  2\n\
2136  73\n\
2137  0\n\
2138  90\n\
2139  0\n\
2140  40\n\
2141 -0.6\n\
2142  41\n\
2143 -30.0\n\
2144  62\n\
2145  5\n\
2146  63\n\
2147  7\n\
2148 421\n\
2149  16777215\n\
2150  74\n\
2151  1\n\
2152  91\n\
2153  4\n\
2154  64\n\
2155  7\n\
2156  65\n\
2157  257\n\
2158  75\n\
2159  1\n\
2160 175\n\
2161  1\n\
2162  42\n\
2163 1.0\n\
2164  92\n\
2165  0\n\
2166  66\n\
2167  257\n\
2168  43\n\
2169 1.0\n\
2170  76\n\
2171  1\n\
2172  77\n\
2173  6\n\
2174  78\n\
2175  2\n\
2176  67\n\
2177  7\n\
2178  79\n\
2179  5\n\
2180 170\n\
2181  0\n\
2182 171\n\
2183  0\n\
2184 290\n\
2185  0\n\
2186 174\n\
2187  0\n\
2188  93\n\
2189  1\n\
2190  44\n\
2191 0.0\n\
2192 173\n\
2193  0\n\
2194 291\n\
2195  0\n\
2196  45\n\
2197 0.0\n\
2198 1001\n\
2199 ACAD\n\
2200 1000\n\
2201 AcDbSavedByObjectVersion\n\
2202 1070\n\
2203  0\n\
2204  0\n\
2205 VISUALSTYLE\n\
2206  5\n\
2207 32\n\
2208 102\n\
2209 {ACAD_REACTORS\n\
2210 330\n\
2211 2A\n\
2212 102\n\
2213 }\n\
2214 330\n\
2215 2A\n\
2216 100\n\
2217 AcDbVisualStyle\n\
2218  2\n\
2219 Basic\n\
2220  70\n\
2221  7\n\
2222  71\n\
2223  1\n\
2224  72\n\
2225  0\n\
2226  73\n\
2227  1\n\
2228  90\n\
2229  0\n\
2230  40\n\
2231 -0.6\n\
2232  41\n\
2233 -30.0\n\
2234  62\n\
2235  5\n\
2236  63\n\
2237  7\n\
2238 421\n\
2239  16777215\n\
2240  74\n\
2241  0\n\
2242  91\n\
2243  4\n\
2244  64\n\
2245  7\n\
2246  65\n\
2247  257\n\
2248  75\n\
2249  1\n\
2250 175\n\
2251  1\n\
2252  42\n\
2253 1.0\n\
2254  92\n\
2255  8\n\
2256  66\n\
2257  7\n\
2258  43\n\
2259 1.0\n\
2260  76\n\
2261  1\n\
2262  77\n\
2263  6\n\
2264  78\n\
2265  2\n\
2266  67\n\
2267  7\n\
2268  79\n\
2269  5\n\
2270 170\n\
2271  0\n\
2272 171\n\
2273  0\n\
2274 290\n\
2275  0\n\
2276 174\n\
2277  0\n\
2278  93\n\
2279  1\n\
2280  44\n\
2281 0.0\n\
2282 173\n\
2283  0\n\
2284 291\n\
2285  1\n\
2286  45\n\
2287 0.0\n\
2288 1001\n\
2289 ACAD\n\
2290 1000\n\
2291 AcDbSavedByObjectVersion\n\
2292 1070\n\
2293  0\n\
2294  0\n\
2295 VISUALSTYLE\n\
2296  5\n\
2297 36\n\
2298 102\n\
2299 {ACAD_REACTORS\n\
2300 330\n\
2301 2A\n\
2302 102\n\
2303 }\n\
2304 330\n\
2305 2A\n\
2306 100\n\
2307 AcDbVisualStyle\n\
2308  2\n\
2309 Brighten\n\
2310  70\n\
2311  12\n\
2312  71\n\
2313  2\n\
2314  72\n\
2315  2\n\
2316  73\n\
2317  0\n\
2318  90\n\
2319  0\n\
2320  40\n\
2321 -0.6\n\
2322  41\n\
2323 -30.0\n\
2324  62\n\
2325  5\n\
2326  63\n\
2327  7\n\
2328 421\n\
2329  16777215\n\
2330  74\n\
2331  1\n\
2332  91\n\
2333  4\n\
2334  64\n\
2335  7\n\
2336  65\n\
2337  257\n\
2338  75\n\
2339  1\n\
2340 175\n\
2341  1\n\
2342  42\n\
2343 1.0\n\
2344  92\n\
2345  8\n\
2346  66\n\
2347  7\n\
2348  43\n\
2349 1.0\n\
2350  76\n\
2351  1\n\
2352  77\n\
2353  6\n\
2354  78\n\
2355  2\n\
2356  67\n\
2357  7\n\
2358  79\n\
2359  5\n\
2360 170\n\
2361  0\n\
2362 171\n\
2363  0\n\
2364 290\n\
2365  0\n\
2366 174\n\
2367  0\n\
2368  93\n\
2369  1\n\
2370  44\n\
2371 50.0\n\
2372 173\n\
2373  0\n\
2374 291\n\
2375  1\n\
2376  45\n\
2377 0.0\n\
2378 1001\n\
2379 ACAD\n\
2380 1000\n\
2381 AcDbSavedByObjectVersion\n\
2382 1070\n\
2383  0\n\
2384  0\n\
2385 VISUALSTYLE\n\
2386  5\n\
2387 3A\n\
2388 102\n\
2389 {ACAD_REACTORS\n\
2390 330\n\
2391 2A\n\
2392 102\n\
2393 }\n\
2394 330\n\
2395 2A\n\
2396 100\n\
2397 AcDbVisualStyle\n\
2398  2\n\
2399 ColorChange\n\
2400  70\n\
2401  16\n\
2402  71\n\
2403  2\n\
2404  72\n\
2405  2\n\
2406  73\n\
2407  3\n\
2408  90\n\
2409  0\n\
2410  40\n\
2411 -0.6\n\
2412  41\n\
2413 -30.0\n\
2414  62\n\
2415  5\n\
2416  63\n\
2417  8\n\
2418 421\n\
2419  8421504\n\
2420  74\n\
2421  1\n\
2422  91\n\
2423  4\n\
2424  64\n\
2425  7\n\
2426  65\n\
2427  257\n\
2428  75\n\
2429  1\n\
2430 175\n\
2431  1\n\
2432  42\n\
2433 1.0\n\
2434  92\n\
2435  8\n\
2436  66\n\
2437  8\n\
2438 424\n\
2439  8421504\n\
2440  43\n\
2441 1.0\n\
2442  76\n\
2443  1\n\
2444  77\n\
2445  6\n\
2446  78\n\
2447  2\n\
2448  67\n\
2449  7\n\
2450  79\n\
2451  5\n\
2452 170\n\
2453  0\n\
2454 171\n\
2455  0\n\
2456 290\n\
2457  0\n\
2458 174\n\
2459  0\n\
2460  93\n\
2461  1\n\
2462  44\n\
2463 0.0\n\
2464 173\n\
2465  0\n\
2466 291\n\
2467  1\n\
2468  45\n\
2469 0.0\n\
2470 1001\n\
2471 ACAD\n\
2472 1000\n\
2473 AcDbSavedByObjectVersion\n\
2474 1070\n\
2475  0\n\
2476  0\n\
2477 VISUALSTYLE\n\
2478  5\n\
2479 34\n\
2480 102\n\
2481 {ACAD_REACTORS\n\
2482 330\n\
2483 2A\n\
2484 102\n\
2485 }\n\
2486 330\n\
2487 2A\n\
2488 100\n\
2489 AcDbVisualStyle\n\
2490  2\n\
2491 Conceptual\n\
2492  70\n\
2493  9\n\
2494  71\n\
2495  3\n\
2496  72\n\
2497  2\n\
2498  73\n\
2499  0\n\
2500  90\n\
2501  0\n\
2502  40\n\
2503 -0.6\n\
2504  41\n\
2505 -30.0\n\
2506  62\n\
2507  5\n\
2508  63\n\
2509  7\n\
2510 421\n\
2511  16777215\n\
2512  74\n\
2513  2\n\
2514  91\n\
2515  2\n\
2516  64\n\
2517  7\n\
2518  65\n\
2519  257\n\
2520  75\n\
2521  1\n\
2522 175\n\
2523  1\n\
2524  42\n\
2525 40.0\n\
2526  92\n\
2527  8\n\
2528  66\n\
2529  7\n\
2530  43\n\
2531 1.0\n\
2532  76\n\
2533  1\n\
2534  77\n\
2535  6\n\
2536  78\n\
2537  2\n\
2538  67\n\
2539  7\n\
2540  79\n\
2541  3\n\
2542 170\n\
2543  0\n\
2544 171\n\
2545  0\n\
2546 290\n\
2547  0\n\
2548 174\n\
2549  0\n\
2550  93\n\
2551  1\n\
2552  44\n\
2553 0.0\n\
2554 173\n\
2555  0\n\
2556 291\n\
2557  0\n\
2558  45\n\
2559 0.0\n\
2560 1001\n\
2561 ACAD\n\
2562 1000\n\
2563 AcDbSavedByObjectVersion\n\
2564 1070\n\
2565  0\n\
2566  0\n\
2567 VISUALSTYLE\n\
2568  5\n\
2569 35\n\
2570 102\n\
2571 {ACAD_REACTORS\n\
2572 330\n\
2573 2A\n\
2574 102\n\
2575 }\n\
2576 330\n\
2577 2A\n\
2578 100\n\
2579 AcDbVisualStyle\n\
2580  2\n\
2581 Dim\n\
2582  70\n\
2583  11\n\
2584  71\n\
2585  2\n\
2586  72\n\
2587  2\n\
2588  73\n\
2589  0\n\
2590  90\n\
2591  0\n\
2592  40\n\
2593 -0.6\n\
2594  41\n\
2595 -30.0\n\
2596  62\n\
2597  5\n\
2598  63\n\
2599  7\n\
2600 421\n\
2601  16777215\n\
2602  74\n\
2603  1\n\
2604  91\n\
2605  4\n\
2606  64\n\
2607  7\n\
2608  65\n\
2609  257\n\
2610  75\n\
2611  1\n\
2612 175\n\
2613  1\n\
2614  42\n\
2615 1.0\n\
2616  92\n\
2617  8\n\
2618  66\n\
2619  7\n\
2620  43\n\
2621 1.0\n\
2622  76\n\
2623  1\n\
2624  77\n\
2625  6\n\
2626  78\n\
2627  2\n\
2628  67\n\
2629  7\n\
2630  79\n\
2631  5\n\
2632 170\n\
2633  0\n\
2634 171\n\
2635  0\n\
2636 290\n\
2637  0\n\
2638 174\n\
2639  0\n\
2640  93\n\
2641  1\n\
2642  44\n\
2643 -50.0\n\
2644 173\n\
2645  0\n\
2646 291\n\
2647  1\n\
2648  45\n\
2649 0.0\n\
2650 1001\n\
2651 ACAD\n\
2652 1000\n\
2653 AcDbSavedByObjectVersion\n\
2654 1070\n\
2655  0\n\
2656  0\n\
2657 VISUALSTYLE\n\
2658  5\n\
2659 39\n\
2660 102\n\
2661 {ACAD_REACTORS\n\
2662 330\n\
2663 2A\n\
2664 102\n\
2665 }\n\
2666 330\n\
2667 2A\n\
2668 100\n\
2669 AcDbVisualStyle\n\
2670  2\n\
2671 Facepattern\n\
2672  70\n\
2673  15\n\
2674  71\n\
2675  2\n\
2676  72\n\
2677  2\n\
2678  73\n\
2679  0\n\
2680  90\n\
2681  0\n\
2682  40\n\
2683 -0.6\n\
2684  41\n\
2685 -30.0\n\
2686  62\n\
2687  5\n\
2688  63\n\
2689  7\n\
2690 421\n\
2691  16777215\n\
2692  74\n\
2693  1\n\
2694  91\n\
2695  4\n\
2696  64\n\
2697  7\n\
2698  65\n\
2699  257\n\
2700  75\n\
2701  1\n\
2702 175\n\
2703  1\n\
2704  42\n\
2705 1.0\n\
2706  92\n\
2707  8\n\
2708  66\n\
2709  7\n\
2710  43\n\
2711 1.0\n\
2712  76\n\
2713  1\n\
2714  77\n\
2715  6\n\
2716  78\n\
2717  2\n\
2718  67\n\
2719  7\n\
2720  79\n\
2721  5\n\
2722 170\n\
2723  0\n\
2724 171\n\
2725  0\n\
2726 290\n\
2727  0\n\
2728 174\n\
2729  0\n\
2730  93\n\
2731  1\n\
2732  44\n\
2733 0.0\n\
2734 173\n\
2735  0\n\
2736 291\n\
2737  1\n\
2738  45\n\
2739 0.0\n\
2740 1001\n\
2741 ACAD\n\
2742 1000\n\
2743 AcDbSavedByObjectVersion\n\
2744 1070\n\
2745  0\n\
2746  0\n\
2747 VISUALSTYLE\n\
2748  5\n\
2749 2B\n\
2750 102\n\
2751 {ACAD_REACTORS\n\
2752 330\n\
2753 2A\n\
2754 102\n\
2755 }\n\
2756 330\n\
2757 2A\n\
2758 100\n\
2759 AcDbVisualStyle\n\
2760  2\n\
2761 Flat\n\
2762  70\n\
2763  0\n\
2764  71\n\
2765  2\n\
2766  72\n\
2767  1\n\
2768  73\n\
2769  1\n\
2770  90\n\
2771  2\n\
2772  40\n\
2773 -0.6\n\
2774  41\n\
2775 30.0\n\
2776  62\n\
2777  5\n\
2778  63\n\
2779  7\n\
2780 421\n\
2781  16777215\n\
2782  74\n\
2783  0\n\
2784  91\n\
2785  4\n\
2786  64\n\
2787  7\n\
2788  65\n\
2789  257\n\
2790  75\n\
2791  1\n\
2792 175\n\
2793  1\n\
2794  42\n\
2795 1.0\n\
2796  92\n\
2797  8\n\
2798  66\n\
2799  7\n\
2800  43\n\
2801 1.0\n\
2802  76\n\
2803  1\n\
2804  77\n\
2805  6\n\
2806  78\n\
2807  2\n\
2808  67\n\
2809  7\n\
2810  79\n\
2811  5\n\
2812 170\n\
2813  0\n\
2814 171\n\
2815  0\n\
2816 290\n\
2817  0\n\
2818 174\n\
2819  0\n\
2820  93\n\
2821  13\n\
2822  44\n\
2823 0.0\n\
2824 173\n\
2825  0\n\
2826 291\n\
2827  1\n\
2828  45\n\
2829 0.0\n\
2830 1001\n\
2831 ACAD\n\
2832 1000\n\
2833 AcDbSavedByObjectVersion\n\
2834 1070\n\
2835  0\n\
2836  0\n\
2837 VISUALSTYLE\n\
2838  5\n\
2839 2C\n\
2840 102\n\
2841 {ACAD_REACTORS\n\
2842 330\n\
2843 2A\n\
2844 102\n\
2845 }\n\
2846 330\n\
2847 2A\n\
2848 100\n\
2849 AcDbVisualStyle\n\
2850  2\n\
2851 FlatWithEdges\n\
2852  70\n\
2853  1\n\
2854  71\n\
2855  2\n\
2856  72\n\
2857  1\n\
2858  73\n\
2859  1\n\
2860  90\n\
2861  2\n\
2862  40\n\
2863 -0.6\n\
2864  41\n\
2865 30.0\n\
2866  62\n\
2867  5\n\
2868  63\n\
2869  7\n\
2870 421\n\
2871  16777215\n\
2872  74\n\
2873  1\n\
2874  91\n\
2875  4\n\
2876  64\n\
2877  7\n\
2878  65\n\
2879  257\n\
2880  75\n\
2881  1\n\
2882 175\n\
2883  1\n\
2884  42\n\
2885 1.0\n\
2886  92\n\
2887  0\n\
2888  66\n\
2889  257\n\
2890  43\n\
2891 1.0\n\
2892  76\n\
2893  1\n\
2894  77\n\
2895  6\n\
2896  78\n\
2897  2\n\
2898  67\n\
2899  7\n\
2900  79\n\
2901  5\n\
2902 170\n\
2903  0\n\
2904 171\n\
2905  0\n\
2906 290\n\
2907  0\n\
2908 174\n\
2909  0\n\
2910  93\n\
2911  13\n\
2912  44\n\
2913 0.0\n\
2914 173\n\
2915  0\n\
2916 291\n\
2917  1\n\
2918  45\n\
2919 0.0\n\
2920 1001\n\
2921 ACAD\n\
2922 1000\n\
2923 AcDbSavedByObjectVersion\n\
2924 1070\n\
2925  0\n\
2926  0\n\
2927 VISUALSTYLE\n\
2928  5\n\
2929 2D\n\
2930 102\n\
2931 {ACAD_REACTORS\n\
2932 330\n\
2933 2A\n\
2934 102\n\
2935 }\n\
2936 330\n\
2937 2A\n\
2938 100\n\
2939 AcDbVisualStyle\n\
2940  2\n\
2941 Gouraud\n\
2942  70\n\
2943  2\n\
2944  71\n\
2945  2\n\
2946  72\n\
2947  2\n\
2948  73\n\
2949  1\n\
2950  90\n\
2951  2\n\
2952  40\n\
2953 -0.6\n\
2954  41\n\
2955 30.0\n\
2956  62\n\
2957  5\n\
2958  63\n\
2959  7\n\
2960 421\n\
2961  16777215\n\
2962  74\n\
2963  0\n\
2964  91\n\
2965  4\n\
2966  64\n\
2967  7\n\
2968  65\n\
2969  257\n\
2970  75\n\
2971  1\n\
2972 175\n\
2973  1\n\
2974  42\n\
2975 1.0\n\
2976  92\n\
2977  0\n\
2978  66\n\
2979  7\n\
2980  43\n\
2981 1.0\n\
2982  76\n\
2983  1\n\
2984  77\n\
2985  6\n\
2986  78\n\
2987  2\n\
2988  67\n\
2989  7\n\
2990  79\n\
2991  5\n\
2992 170\n\
2993  0\n\
2994 171\n\
2995  0\n\
2996 290\n\
2997  0\n\
2998 174\n\
2999  0\n\
3000  93\n\
3001  13\n\
3002  44\n\
3003 0.0\n\
3004 173\n\
3005  0\n\
3006 291\n\
3007  1\n\
3008  45\n\
3009 0.0\n\
3010 1001\n\
3011 ACAD\n\
3012 1000\n\
3013 AcDbSavedByObjectVersion\n\
3014 1070\n\
3015  0\n\
3016  0\n\
3017 VISUALSTYLE\n\
3018  5\n\
3019 2E\n\
3020 102\n\
3021 {ACAD_REACTORS\n\
3022 330\n\
3023 2A\n\
3024 102\n\
3025 }\n\
3026 330\n\
3027 2A\n\
3028 100\n\
3029 AcDbVisualStyle\n\
3030  2\n\
3031 GouraudWithEdges\n\
3032  70\n\
3033  3\n\
3034  71\n\
3035  2\n\
3036  72\n\
3037  2\n\
3038  73\n\
3039  1\n\
3040  90\n\
3041  2\n\
3042  40\n\
3043 -0.6\n\
3044  41\n\
3045 30.0\n\
3046  62\n\
3047  5\n\
3048  63\n\
3049  7\n\
3050 421\n\
3051  16777215\n\
3052  74\n\
3053  1\n\
3054  91\n\
3055  4\n\
3056  64\n\
3057  7\n\
3058  65\n\
3059  257\n\
3060  75\n\
3061  1\n\
3062 175\n\
3063  1\n\
3064  42\n\
3065 1.0\n\
3066  92\n\
3067  0\n\
3068  66\n\
3069  257\n\
3070  43\n\
3071 1.0\n\
3072  76\n\
3073  1\n\
3074  77\n\
3075  6\n\
3076  78\n\
3077  2\n\
3078  67\n\
3079  7\n\
3080  79\n\
3081  5\n\
3082 170\n\
3083  0\n\
3084 171\n\
3085  0\n\
3086 290\n\
3087  0\n\
3088 174\n\
3089  0\n\
3090  93\n\
3091  13\n\
3092  44\n\
3093 0.0\n\
3094 173\n\
3095  0\n\
3096 291\n\
3097  1\n\
3098  45\n\
3099 0.0\n\
3100 1001\n\
3101 ACAD\n\
3102 1000\n\
3103 AcDbSavedByObjectVersion\n\
3104 1070\n\
3105  0\n\
3106  0\n\
3107 VISUALSTYLE\n\
3108  5\n\
3109 38\n\
3110 102\n\
3111 {ACAD_REACTORS\n\
3112 330\n\
3113 2A\n\
3114 102\n\
3115 }\n\
3116 330\n\
3117 2A\n\
3118 100\n\
3119 AcDbVisualStyle\n\
3120  2\n\
3121 Linepattern\n\
3122  70\n\
3123  14\n\
3124  71\n\
3125  2\n\
3126  72\n\
3127  2\n\
3128  73\n\
3129  0\n\
3130  90\n\
3131  0\n\
3132  40\n\
3133 -0.6\n\
3134  41\n\
3135 -30.0\n\
3136  62\n\
3137  5\n\
3138  63\n\
3139  7\n\
3140 421\n\
3141  16777215\n\
3142  74\n\
3143  1\n\
3144  91\n\
3145  4\n\
3146  64\n\
3147  7\n\
3148  65\n\
3149  257\n\
3150  75\n\
3151  7\n\
3152 175\n\
3153  7\n\
3154  42\n\
3155 1.0\n\
3156  92\n\
3157  8\n\
3158  66\n\
3159  7\n\
3160  43\n\
3161 1.0\n\
3162  76\n\
3163  1\n\
3164  77\n\
3165  6\n\
3166  78\n\
3167  2\n\
3168  67\n\
3169  7\n\
3170  79\n\
3171  5\n\
3172 170\n\
3173  0\n\
3174 171\n\
3175  0\n\
3176 290\n\
3177  0\n\
3178 174\n\
3179  0\n\
3180  93\n\
3181  1\n\
3182  44\n\
3183 0.0\n\
3184 173\n\
3185  0\n\
3186 291\n\
3187  1\n\
3188  45\n\
3189 0.0\n\
3190 1001\n\
3191 ACAD\n\
3192 1000\n\
3193 AcDbSavedByObjectVersion\n\
3194 1070\n\
3195  0\n\
3196  0\n\
3197 VISUALSTYLE\n\
3198  5\n\
3199 33\n\
3200 102\n\
3201 {ACAD_REACTORS\n\
3202 330\n\
3203 2A\n\
3204 102\n\
3205 }\n\
3206 330\n\
3207 2A\n\
3208 100\n\
3209 AcDbVisualStyle\n\
3210  2\n\
3211 Realistic\n\
3212  70\n\
3213  8\n\
3214  71\n\
3215  2\n\
3216  72\n\
3217  2\n\
3218  73\n\
3219  0\n\
3220  90\n\
3221  0\n\
3222  40\n\
3223 -0.6\n\
3224  41\n\
3225 -30.0\n\
3226  62\n\
3227  5\n\
3228  63\n\
3229  7\n\
3230 421\n\
3231  16777215\n\
3232  74\n\
3233  1\n\
3234  91\n\
3235  0\n\
3236  64\n\
3237  7\n\
3238  65\n\
3239  257\n\
3240  75\n\
3241  1\n\
3242 175\n\
3243  1\n\
3244  42\n\
3245 1.0\n\
3246  92\n\
3247  8\n\
3248  66\n\
3249  8\n\
3250 424\n\
3251  7895160\n\
3252  43\n\
3253 1.0\n\
3254  76\n\
3255  1\n\
3256  77\n\
3257  6\n\
3258  78\n\
3259  2\n\
3260  67\n\
3261  7\n\
3262  79\n\
3263  5\n\
3264 170\n\
3265  0\n\
3266 171\n\
3267  0\n\
3268 290\n\
3269  0\n\
3270 174\n\
3271  0\n\
3272  93\n\
3273  13\n\
3274  44\n\
3275 0.0\n\
3276 173\n\
3277  0\n\
3278 291\n\
3279  0\n\
3280  45\n\
3281 0.0\n\
3282 1001\n\
3283 ACAD\n\
3284 1000\n\
3285 AcDbSavedByObjectVersion\n\
3286 1070\n\
3287  0\n\
3288  0\n\
3289 VISUALSTYLE\n\
3290  5\n\
3291 37\n\
3292 102\n\
3293 {ACAD_REACTORS\n\
3294 330\n\
3295 2A\n\
3296 102\n\
3297 }\n\
3298 330\n\
3299 2A\n\
3300 100\n\
3301 AcDbVisualStyle\n\
3302  2\n\
3303 Thicken\n\
3304  70\n\
3305  13\n\
3306  71\n\
3307  2\n\
3308  72\n\
3309  2\n\
3310  73\n\
3311  0\n\
3312  90\n\
3313  0\n\
3314  40\n\
3315 -0.6\n\
3316  41\n\
3317 -30.0\n\
3318  62\n\
3319  5\n\
3320  63\n\
3321  7\n\
3322 421\n\
3323  16777215\n\
3324  74\n\
3325  1\n\
3326  91\n\
3327  4\n\
3328  64\n\
3329  7\n\
3330  65\n\
3331  257\n\
3332  75\n\
3333  1\n\
3334 175\n\
3335  1\n\
3336  42\n\
3337 1.0\n\
3338  92\n\
3339  12\n\
3340  66\n\
3341  7\n\
3342  43\n\
3343 1.0\n\
3344  76\n\
3345  1\n\
3346  77\n\
3347  6\n\
3348  78\n\
3349  2\n\
3350  67\n\
3351  7\n\
3352  79\n\
3353  5\n\
3354 170\n\
3355  0\n\
3356 171\n\
3357  0\n\
3358 290\n\
3359  0\n\
3360 174\n\
3361  0\n\
3362  93\n\
3363  1\n\
3364  44\n\
3365 0.0\n\
3366 173\n\
3367  0\n\
3368 291\n\
3369  1\n\
3370  45\n\
3371 0.0\n\
3372 1001\n\
3373 ACAD\n\
3374 1000\n\
3375 AcDbSavedByObjectVersion\n\
3376 1070\n\
3377  0\n\
3378  0\n\
3379 ENDSEC\n\
3380 ";
3381 
3382  writeGroup( 0, QStringLiteral( "EOF" ) );
3383 }
3384 
3385 void QgsDxfExport::startSection()
3386 {
3387  writeGroup( 0, QStringLiteral( "SECTION" ) );
3388 }
3389 
3390 void QgsDxfExport::endSection()
3391 {
3392  writeGroup( 0, QStringLiteral( "ENDSEC" ) );
3393 }
3394 
3395 void QgsDxfExport::writePoint( const QgsPointV2 &pt, const QString &layer, const QColor &color, QgsSymbolRenderContext &ctx, const QgsSymbolLayer *symbolLayer, const QgsSymbol *symbol, double angle )
3396 {
3397 #if 0
3398  // debug: draw rectangle for debugging
3399  const QgsMarkerSymbolLayer *msl = dynamic_cast< const QgsMarkerSymbolLayer * >( symbolLayer );
3400  if ( msl )
3401  {
3402  double halfSize = msl->size() * mapUnitScaleFactor( mSymbologyScaleDenominator,
3403  msl->sizeUnit(), mMapUnits ) / 2.0;
3404  writeGroup( 0, "SOLID" );
3405  writeGroup( 8, layer );
3406  writeGroup( 62, 1 );
3407  writeGroup( 0, QgsPointV2( QgsWkbTypes::PointZ, pt.x() - halfSize, pt.y() - halfSize ) );
3408  writeGroup( 1, QgsPointV2( QgsWkbTypes::PointZ, pt.x() + halfSize, pt.y() - halfSize ) );
3409  writeGroup( 2, QgsPointV2( QgsWkbTypes::PointZ, pt.x() - halfSize, pt.y() + halfSize ) );
3410  writeGroup( 3, QgsPointV2( QgsWkbTypes::PointZ, pt.x() + halfSize, pt.y() + halfSize ) );
3411  }
3412 #endif // 0
3413 
3414  // insert block or write point directly?
3415  QHash< const QgsSymbolLayer *, QString >::const_iterator blockIt = mPointSymbolBlocks.constFind( symbolLayer );
3416  if ( !symbolLayer || blockIt == mPointSymbolBlocks.constEnd() )
3417  {
3418  // write symbol directly here
3419  const QgsMarkerSymbolLayer *msl = dynamic_cast< const QgsMarkerSymbolLayer * >( symbolLayer );
3420  if ( msl && symbol )
3421  {
3422  if ( symbolLayer->writeDxf( *this, mapUnitScaleFactor( mSymbologyScaleDenominator, msl->sizeUnit(), mMapUnits ), layer, ctx, QPointF( pt.x(), pt.y() ) ) )
3423  {
3424  return;
3425  }
3426  }
3427  writePoint( layer, color, pt ); // write default point symbol
3428  }
3429  else
3430  {
3431  // insert block reference
3432  writeGroup( 0, QStringLiteral( "INSERT" ) );
3433  writeHandle();
3434  writeGroup( 100, QStringLiteral( "AcDbEntity" ) );
3435  writeGroup( 100, QStringLiteral( "AcDbBlockReference" ) );
3436  writeGroup( 8, layer );
3437  writeGroup( 2, blockIt.value() ); // Block name
3438  writeGroup( 50, angle ); // angle
3439  writeGroup( 0, pt ); // Insertion point (in OCS)
3440  }
3441 }
3442 
3443 void QgsDxfExport::writePolyline( const QgsPointSequence &line, const QString &layer, const QString &lineStyleName, const QColor &color, double width )
3444 {
3445  int n = line.size();
3446  if ( n == 0 )
3447  {
3448  QgsDebugMsg( QString( "writePolyline: empty line layer=%1 lineStyleName=%2" ).arg( layer, lineStyleName ) );
3449  return;
3450  }
3451 
3452  bool polygon = line[0] == line[ line.size() - 1 ];
3453  if ( polygon )
3454  --n;
3455  if ( n < 2 )
3456  {
3457  QgsDebugMsg( QString( "writePolyline: line too short layer=%1 lineStyleName=%2" ).arg( layer, lineStyleName ) );
3458  return;
3459  }
3460 
3461  if ( !line.at( 0 ).is3D() )
3462  {
3463  writeGroup( 0, QStringLiteral( "LWPOLYLINE" ) );
3464  writeHandle();
3465  writeGroup( 8, layer );
3466  writeGroup( 100, QStringLiteral( "AcDbEntity" ) );
3467  writeGroup( 100, QStringLiteral( "AcDbPolyline" ) );
3468  writeGroup( 6, lineStyleName );
3469  writeGroup( color );
3470 
3471  writeGroup( 90, n );
3472  writeGroup( 70, polygon ? 1 : 0 );
3473  writeGroup( 43, width );
3474 
3475  for ( int i = 0; i < n; i++ )
3476  writeGroup( 0, line[i] );
3477  }
3478  else
3479  {
3480  writeGroup( 0, QStringLiteral( "POLYLINE" ) );
3481  int plHandle = writeHandle();
3482  writeGroup( 330, mBlockHandle );
3483  writeGroup( 100, QStringLiteral( "AcDbEntity" ) );
3484  writeGroup( 8, layer );
3485  writeGroup( 6, lineStyleName );
3486  writeGroup( color );
3487  writeGroup( 100, QStringLiteral( "AcDb3dPolyline" ) );
3489  writeGroup( 70, 8 );
3490 
3491  for ( int i = 0; i < n; i++ )
3492  {
3493  writeGroup( 0, QStringLiteral( "VERTEX" ) );
3494  writeHandle();
3495  writeGroup( 330, plHandle );
3496  writeGroup( 100, QStringLiteral( "AcDbEntity" ) );
3497  writeGroup( 8, layer );
3498  writeGroup( color );
3499  writeGroup( 100, QStringLiteral( "AcDbVertex" ) );
3500  writeGroup( 100, QStringLiteral( "AcDb3dPolylineVertex" ) );
3501  writeGroup( 0, line[i] );
3502  writeGroup( 70, 32 );
3503  }
3504 
3505  writeGroup( 0, QStringLiteral( "SEQEND" ) );
3506  writeHandle();
3507  writeGroup( 330, plHandle );
3508  writeGroup( 100, QStringLiteral( "AcDbEntity" ) );
3509  writeGroup( 8, layer );
3510  writeGroup( color );
3511  }
3512 }
3513 
3514 void QgsDxfExport::writePolygon( const QgsRingSequence &polygon, const QString &layer, const QString &hatchPattern, const QColor &color )
3515 {
3516  writeGroup( 0, QStringLiteral( "HATCH" ) ); // Entity type
3517  writeHandle();
3518  writeGroup( 330, mBlockHandle );
3519  writeGroup( 100, QStringLiteral( "AcDbEntity" ) );
3520  writeGroup( 8, layer ); // Layer name
3521  writeGroup( color ); // Color
3522  writeGroup( 100, QStringLiteral( "AcDbHatch" ) );
3523 
3524  writeGroup( 0, QgsPointV2( QgsWkbTypes::PointZ ) ); // Elevation point (in OCS)
3525  writeGroup( 200, QgsPointV2( QgsWkbTypes::PointZ, 0.0, 0.0, 1.0 ) );
3526 
3527  writeGroup( 2, hatchPattern ); // Hatch pattern name
3528  writeGroup( 70, hatchPattern == QLatin1String( "SOLID" ) ); // Solid fill flag (solid fill = 1; pattern fill = 0)
3529  writeGroup( 71, 0 ); // Associativity flag (associative = 1; non-associative = 0)
3530 
3531  writeGroup( 91, polygon.size() ); // Number of boundary paths (loops)
3532  for ( int i = 0; i < polygon.size(); ++i )
3533  {
3534  writeGroup( 92, 2 ); // Boundary path type flag (bit coded): 0 = Default; 1 = External; 2 = Polyline 4 = Derived; 8 = Textbox; 16 = Outermost
3535  writeGroup( 72, 0 ); // Has bulge flag
3536  writeGroup( 73, 1 ); // Is closed flag
3537  writeGroup( 93, polygon[i].size() ); // Number of edges in this boundary path (only if boundary is not a polyline
3538 
3539  for ( int j = 0; j < polygon[i].size(); ++j )
3540  {
3541  writeGroup( 0, polygon[i][j] ); // Vertex location (in OCS)
3542  }
3543 
3544  writeGroup( 97, 0 ); // Number of source boundary objects
3545  }
3546 
3547  writeGroup( 75, 0 ); // Hatch style: 0 = Hatch "odd parity" area (Normal style), 1 = Hatch outermost area only (Outer style), 2 = Hatch through entire area (Ignore style)
3548  writeGroup( 76, 1 ); // Hatch pattern type: 0 = User-defined; 1 = Predefined; 2 = Custom
3549 
3550  writeGroup( 98, 0 ); // Number of seed points
3551 }
3552 
3553 void QgsDxfExport::writeLine( const QgsPointV2 &pt1, const QgsPointV2 &pt2, const QString &layer, const QString &lineStyleName, const QColor &color, double width )
3554 {
3555  writePolyline( QgsPointSequence() << pt1 << pt2, layer, lineStyleName, color, width );
3556 }
3557 
3558 void QgsDxfExport::writePoint( const QString &layer, const QColor &color, const QgsPointV2 &pt )
3559 {
3560  writeGroup( 0, QStringLiteral( "POINT" ) );
3561  writeHandle();
3562  writeGroup( 100, QStringLiteral( "AcDbEntity" ) );
3563  writeGroup( 100, QStringLiteral( "AcDbPoint" ) );
3564  writeGroup( 8, layer );
3565  writeGroup( color );
3566  writeGroup( 0, pt );
3567 }
3568 
3569 void QgsDxfExport::writeFilledCircle( const QString &layer, const QColor &color, const QgsPointV2 &pt, double radius )
3570 {
3571  writeGroup( 0, QStringLiteral( "HATCH" ) ); // Entity type
3572  writeHandle();
3573  writeGroup( 330, mBlockHandle );
3574  writeGroup( 100, QStringLiteral( "AcDbEntity" ) );
3575  writeGroup( 8, layer ); // Layer name
3576  writeGroup( color ); // Color (0 by block, 256 by layer)
3577  writeGroup( 100, QStringLiteral( "AcDbHatch" ) );
3578 
3579  writeGroup( 0, QgsPointV2( QgsWkbTypes::PointZ ) ); // Elevation point (in OCS)
3580  writeGroup( 200, QgsPointV2( QgsWkbTypes::PointZ, 0.0, 0.0, 1.0 ) );
3581 
3582  writeGroup( 2, QStringLiteral( "SOLID" ) ); // Hatch pattern name
3583  writeGroup( 70, 1 ); // Solid fill flag (solid fill = 1; pattern fill = 0)
3584  writeGroup( 71, 0 ); // Associativity flag (associative = 1; non-associative = 0)
3585 
3586  writeGroup( 91, 1 ); // Number of boundary paths (loops)
3587 
3588  writeGroup( 92, 3 ); // Boundary path type flag (bit coded): 0 = Default; 1 = External; 2 = Polyline 4 = Derived; 8 = Textbox; 16 = Outermost
3589  writeGroup( 72, 1 );
3590  writeGroup( 73, 1 ); // Is closed flag
3591  writeGroup( 93, 2 ); // Number of polyline vertices
3592 
3593  writeGroup( 0, QgsPointV2( QgsWkbTypes::Point, pt.x() - radius, pt.y() ) );
3594  writeGroup( 42, 1.0 );
3595 
3596  writeGroup( 0, QgsPointV2( QgsWkbTypes::Point, pt.x() + radius, pt.y() ) );
3597  writeGroup( 42, 1.0 );
3598 
3599  writeGroup( 97, 0 ); // Number of source boundary objects
3600 
3601  writeGroup( 75, 0 ); // Hatch style: 0 = Hatch "odd parity" area (Normal style), 1 = Hatch outermost area only (Outer style), 2 = Hatch through entire area (Ignore style)
3602  writeGroup( 76, 1 ); // Hatch pattern type: 0 = User-defined; 1 = Predefined; 2 = Custom
3603  writeGroup( 98, 0 ); // Number of seed points
3604 }
3605 
3606 void QgsDxfExport::writeCircle( const QString &layer, const QColor &color, const QgsPointV2 &pt, double radius, const QString &lineStyleName, double width )
3607 {
3608  writeGroup( 0, QStringLiteral( "LWPOLYLINE" ) );
3609  writeHandle();
3610  writeGroup( 330, mBlockHandle );
3611  writeGroup( 8, layer );
3612  writeGroup( 100, QStringLiteral( "AcDbEntity" ) );
3613  writeGroup( 100, QStringLiteral( "AcDbPolyline" ) );
3614  writeGroup( 6, lineStyleName );
3615  writeGroup( color );
3616 
3617  writeGroup( 90, 2 );
3618 
3619  writeGroup( 70, 1 );
3620  writeGroup( 43, width );
3621 
3622  writeGroup( 0, QgsPointV2( pt.x() - radius, pt.y() ) );
3623  writeGroup( 42, 1.0 );
3624  writeGroup( 0, QgsPointV2( pt.x() + radius, pt.y() ) );
3625  writeGroup( 42, 1.0 );
3626 }
3627 
3628 void QgsDxfExport::writeText( const QString &layer, const QString &text, const QgsPointV2 &pt, double size, double angle, const QColor &color )
3629 {
3630  writeGroup( 0, QStringLiteral( "TEXT" ) );
3631  writeHandle();
3632  writeGroup( 100, QStringLiteral( "AcDbEntity" ) );
3633  writeGroup( 100, QStringLiteral( "AcDbText" ) );
3634  writeGroup( 8, layer );
3635  writeGroup( color );
3636  writeGroup( 0, pt );
3637  writeGroup( 40, size );
3638  writeGroup( 1, text );
3639  writeGroup( 50, angle );
3640  writeGroup( 7, QStringLiteral( "STANDARD" ) ); // so far only support for standard font
3641 }
3642 
3643 void QgsDxfExport::writeMText( const QString &layer, const QString &text, const QgsPointV2 &pt, double width, double angle, const QColor &color )
3644 {
3645  if ( !mTextStream.codec()->canEncode( text ) )
3646  {
3647  // TODO return error
3648  QgsDebugMsg( QString( "could not encode:%1" ).arg( text ) );
3649  return;
3650  }
3651 
3652  writeGroup( 0, QStringLiteral( "MTEXT" ) );
3653  writeHandle();
3654  writeGroup( 100, QStringLiteral( "AcDbEntity" ) );
3655  writeGroup( 100, QStringLiteral( "AcDbMText" ) );
3656  writeGroup( 8, layer );
3657  writeGroup( color );
3658 
3659  writeGroup( 0, pt );
3660 
3661  QString t( text );
3662  while ( t.length() > 250 )
3663  {
3664  writeGroup( 3, t.left( 250 ) );
3665  t = t.mid( 250 );
3666  }
3667  writeGroup( 1, text );
3668 
3669  writeGroup( 50, angle ); // Rotation angle in radians
3670  writeGroup( 41, width * 1.1 ); // Reference rectangle width
3671 
3672  // Attachment point:
3673  // 1 2 3
3674  // 4 5 6
3675  // 7 8 9
3676  writeGroup( 71, 7 );
3677 
3678  writeGroup( 7, QStringLiteral( "STANDARD" ) ); // so far only support for standard font
3679 }
3680 
3681 void QgsDxfExport::addFeature( QgsSymbolRenderContext &ctx, const QgsCoordinateTransform &ct, const QString &layer, const QgsSymbolLayer *symbolLayer, const QgsSymbol *symbol )
3682 {
3683  const QgsFeature *fet = ctx.feature();
3684  if ( !fet )
3685  return;
3686 
3687  if ( !fet->hasGeometry() )
3688  return;
3689 
3690  std::unique_ptr<QgsAbstractGeometry> geom( fet->geometry().geometry()->clone() );
3691  if ( ct.isValid() )
3692  {
3693  geom->transform( ct );
3694  }
3695 
3696  QgsWkbTypes::Type geometryType = geom->wkbType();
3697 
3698  QColor penColor;
3699  QColor brushColor;
3700  if ( mSymbologyExport != NoSymbology && symbolLayer )
3701  {
3702  penColor = colorFromSymbolLayer( symbolLayer, ctx );
3703  brushColor = symbolLayer->dxfBrushColor( ctx );
3704  }
3705 
3706  Qt::PenStyle penStyle( Qt::SolidLine );
3707  Qt::BrushStyle brushStyle( Qt::NoBrush );
3708  double width = -1;
3709  double offset = 0.0;
3710  double angle = 0.0;
3711  if ( mSymbologyExport != NoSymbology && symbolLayer )
3712  {
3713  width = symbolLayer->dxfWidth( *this, ctx );
3714  offset = symbolLayer->dxfOffset( *this, ctx );
3715  angle = symbolLayer->dxfAngle( ctx );
3716  penStyle = symbolLayer->dxfPenStyle();
3717  brushStyle = symbolLayer->dxfBrushStyle();
3718 
3719  if ( qgsDoubleNear( offset, 0.0 ) )
3720  offset = 0.0;
3721  }
3722 
3723  QString lineStyleName = QStringLiteral( "CONTINUOUS" );
3724  if ( mSymbologyExport != NoSymbology )
3725  {
3726  lineStyleName = lineStyleFromSymbolLayer( symbolLayer );
3727  }
3728 
3729  // single point
3730  if ( QgsWkbTypes::flatType( geometryType ) == QgsWkbTypes::Point )
3731  {
3732  writePoint( geom->coordinateSequence().at( 0 ).at( 0 ).at( 0 ), layer, penColor, ctx, symbolLayer, symbol, angle );
3733  return;
3734  }
3735 
3736  if ( QgsWkbTypes::flatType( geometryType ) == QgsWkbTypes::MultiPoint )
3737  {
3738  const QgsCoordinateSequence &cs = geom->coordinateSequence();
3739  for ( int i = 0; i < cs.size(); i++ )
3740  {
3741  writePoint( cs.at( i ).at( 0 ).at( 0 ), layer, penColor, ctx, symbolLayer, symbol, angle );
3742  }
3743  return;
3744  }
3745 
3746  if ( penStyle != Qt::NoPen )
3747  {
3748  const QgsAbstractGeometry *tempGeom = geom.get();
3749 
3750  switch ( QgsWkbTypes::flatType( geometryType ) )
3751  {
3754  tempGeom = geom->segmentize();
3755  if ( !tempGeom )
3756  break;
3757  FALLTHROUGH;
3759  if ( !qgsDoubleNear( offset, 0.0 ) )
3760  {
3761  QgsGeos geos( tempGeom );
3762  if ( tempGeom != geom.get() )
3763  delete tempGeom;
3764  tempGeom = geos.offsetCurve( offset, 0, GEOSBUF_JOIN_MITRE, 2.0 );
3765  if ( !tempGeom )
3766  tempGeom = geom.get();
3767  }
3768 
3769  writePolyline( tempGeom->coordinateSequence().at( 0 ).at( 0 ), layer, lineStyleName, penColor, width );
3770 
3771  break;
3772 
3774  tempGeom = geom->segmentize();
3775  if ( !tempGeom )
3776  break;
3777  FALLTHROUGH;
3779  {
3780  if ( !qgsDoubleNear( offset, 0.0 ) )
3781  {
3782  QgsGeos geos( tempGeom );
3783  if ( tempGeom != geom.get() )
3784  delete tempGeom;
3785  tempGeom = geos.offsetCurve( offset, 0, GEOSBUF_JOIN_MITRE, 2.0 );
3786  if ( !tempGeom )
3787  tempGeom = geom.get();
3788  }
3789 
3790  const QgsCoordinateSequence &cs = tempGeom->coordinateSequence();
3791  for ( int i = 0; i < cs.size(); i++ )
3792  {
3793  writePolyline( cs.at( i ).at( 0 ), layer, lineStyleName, penColor, width );
3794  }
3795 
3796  break;
3797  }
3798 
3800  tempGeom = geom->segmentize();
3801  if ( !tempGeom )
3802  break;
3803  FALLTHROUGH;
3804  case QgsWkbTypes::Polygon:
3805  {
3806  if ( !qgsDoubleNear( offset, 0.0 ) )
3807  {
3808  QgsGeos geos( tempGeom );
3809  if ( tempGeom != geom.get() )
3810  delete tempGeom;
3811  tempGeom = geos.buffer( offset, 0, GEOSBUF_CAP_FLAT, GEOSBUF_JOIN_MITRE, 2.0 );
3812  if ( !tempGeom )
3813  tempGeom = geom.get();
3814  }
3815 
3816  const QgsCoordinateSequence &cs = tempGeom->coordinateSequence();
3817  for ( int i = 0; i < cs.at( 0 ).size(); i++ )
3818  {
3819  writePolyline( cs.at( 0 ).at( i ), layer, lineStyleName, penColor, width );
3820  }
3821 
3822  break;
3823  }
3824 
3826  {
3827  if ( !qgsDoubleNear( offset, 0.0 ) )
3828  {
3829  QgsGeos geos( tempGeom );
3830  if ( tempGeom != geom.get() )
3831  delete tempGeom;
3832  tempGeom = geos.buffer( offset, 0, GEOSBUF_CAP_FLAT, GEOSBUF_JOIN_MITRE, 2.0 );
3833  if ( !tempGeom )
3834  tempGeom = geom.get();
3835  }
3836 
3837  const QgsCoordinateSequence &cs = tempGeom->coordinateSequence();
3838  for ( int i = 0; i < cs.size(); i++ )
3839  for ( int j = 0; j < cs.at( i ).size(); j++ )
3840  writePolyline( cs.at( i ).at( j ), layer, lineStyleName, penColor, width );
3841 
3842  break;
3843  }
3844 
3845  default:
3846  break;
3847  }
3848 
3849  if ( tempGeom != geom.get() )
3850  delete tempGeom;
3851  }
3852 
3853  if ( brushStyle != Qt::NoBrush )
3854  {
3855  const QgsAbstractGeometry *tempGeom = geom.get();
3856 
3857  switch ( QgsWkbTypes::flatType( geometryType ) )
3858  {
3860  tempGeom = tempGeom->segmentize();
3861  if ( !tempGeom )
3862  break;
3863  FALLTHROUGH;
3864  case QgsWkbTypes::Polygon:
3865  writePolygon( tempGeom->coordinateSequence().at( 0 ), layer, QStringLiteral( "SOLID" ), brushColor );
3866  break;
3867 
3869  {
3870  const QgsCoordinateSequence &cs = geom->coordinateSequence();
3871  for ( int i = 0; i < cs.size(); i++ )
3872  {
3873  writePolygon( cs.at( i ), layer, QStringLiteral( "SOLID" ), brushColor );
3874  }
3875  break;
3876  }
3877 
3878  default:
3879  break;
3880 
3881  }
3882 
3883  if ( tempGeom != geom.get() )
3884  delete tempGeom;
3885  }
3886 }
3887 
3888 QColor QgsDxfExport::colorFromSymbolLayer( const QgsSymbolLayer *symbolLayer, QgsSymbolRenderContext &ctx )
3889 {
3890  if ( !symbolLayer )
3891  return QColor();
3892 
3893  return symbolLayer->dxfColor( ctx );
3894 }
3895 
3896 QString QgsDxfExport::lineStyleFromSymbolLayer( const QgsSymbolLayer *symbolLayer )
3897 {
3898  QString lineStyleName = QStringLiteral( "CONTINUOUS" );
3899  if ( !symbolLayer )
3900  {
3901  return lineStyleName;
3902  }
3903 
3904  QHash< const QgsSymbolLayer *, QString >::const_iterator lineTypeIt = mLineStyles.constFind( symbolLayer );
3905  if ( lineTypeIt != mLineStyles.constEnd() )
3906  {
3907  lineStyleName = lineTypeIt.value();
3908  return lineStyleName;
3909  }
3910  else
3911  {
3912  return lineNameFromPenStyle( symbolLayer->dxfPenStyle() );
3913  }
3914 }
3915 
3917 {
3918  int idx = 0;
3919  int current_distance = INT_MAX;
3920  for ( int i = 1; i < static_cast< int >( sizeof( sDxfColors ) / sizeof( *sDxfColors ) ); ++i )
3921  {
3922  int dist = color_distance( pixel, i );
3923  if ( dist < current_distance )
3924  {
3925  current_distance = dist;
3926  idx = i;
3927  if ( dist == 0 )
3928  break;
3929  }
3930  }
3931  return idx;
3932 }
3933 
3934 int QgsDxfExport::color_distance( QRgb p1, int index )
3935 {
3936  if ( index > 255 || index < 0 )
3937  {
3938  return 0;
3939  }
3940 
3941  double redDiff = qRed( p1 ) - sDxfColors[index][0];
3942  double greenDiff = qGreen( p1 ) - sDxfColors[index][1];
3943  double blueDiff = qBlue( p1 ) - sDxfColors[index][2];
3944 #if 0
3945  QgsDebugMsg( QString( "color_distance( r:%1 g:%2 b:%3 <=> i:%4 r:%5 g:%6 b:%7 ) => %8" )
3946  .arg( qRed( p1 ) ).arg( qGreen( p1 ) ).arg( qBlue( p1 ) )
3947  .arg( index )
3948  .arg( mDxfColors[index][0] )
3949  .arg( mDxfColors[index][1] )
3950  .arg( mDxfColors[index][2] )
3951  .arg( redDiff * redDiff + greenDiff * greenDiff + blueDiff * blueDiff ) );
3952 #endif
3953  return redDiff * redDiff + greenDiff * greenDiff + blueDiff * blueDiff;
3954 }
3955 
3956 QRgb QgsDxfExport::createRgbEntry( qreal r, qreal g, qreal b )
3957 {
3958  return QColor::fromRgbF( r, g, b ).rgb();
3959 }
3960 
3961 QgsRenderContext QgsDxfExport::renderContext() const
3962 {
3963  QgsRenderContext context;
3964  context.setRendererScale( mSymbologyScaleDenominator );
3965  return context;
3966 }
3967 
3969 {
3970  if ( symbolUnits == QgsUnitTypes::RenderMapUnits )
3971  {
3972  return 1.0;
3973  }
3974  // MM symbol unit
3975  return scaleDenominator * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceMeters, mapUnits ) / 1000.0;
3976 }
3977 
3978 QList< QPair< QgsSymbolLayer *, QgsSymbol * > > QgsDxfExport::symbolLayers( QgsRenderContext &context )
3979 {
3980  QList< QPair< QgsSymbolLayer *, QgsSymbol * > > symbolLayers;
3981 
3982  Q_FOREACH ( QgsMapLayer *ml, mMapSettings.layers() )
3983  {
3984  QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( ml );
3985  if ( !vl )
3986  {
3987  continue;
3988  }
3989 
3990  // get renderer
3991  QgsFeatureRenderer *r = vl->renderer();
3992  if ( !r )
3993  {
3994  continue;
3995  }
3996 
3997  // get all symbols
3998  QgsSymbolList symbols = r->symbols( context );
3999  QgsSymbolList::iterator symbolIt = symbols.begin();
4000  for ( ; symbolIt != symbols.end(); ++symbolIt )
4001  {
4002  int maxSymbolLayers = ( *symbolIt )->symbolLayerCount();
4003  if ( mSymbologyExport != SymbolLayerSymbology )
4004  {
4005  maxSymbolLayers = 1;
4006  }
4007  for ( int i = 0; i < maxSymbolLayers; ++i )
4008  {
4009  symbolLayers.append( qMakePair( ( *symbolIt )->symbolLayer( i ), *symbolIt ) );
4010  }
4011  }
4012  }
4013 
4014  return symbolLayers;
4015 }
4016 
4017 void QgsDxfExport::writeDefaultLinetypes()
4018 {
4019  // continuous (Qt solid line)
4020  Q_FOREACH ( const QString &ltype, QStringList() << "ByLayer" << "ByBlock" << "CONTINUOUS" )
4021  {
4022  writeGroup( 0, QStringLiteral( "LTYPE" ) );
4023  writeHandle();
4024  writeGroup( 100, QStringLiteral( "AcDbSymbolTableRecord" ) );
4025  writeGroup( 100, QStringLiteral( "AcDbLinetypeTableRecord" ) );
4026  writeGroup( 2, ltype );
4027  writeGroup( 70, 64 );
4028  writeGroup( 3, QStringLiteral( "Defaultstyle" ) );
4029  writeGroup( 72, 65 );
4030  writeGroup( 73, 0 );
4031  writeGroup( 40, 0.0 );
4032  }
4033 
4034  double das = dashSize();
4035  double dss = dashSeparatorSize();
4036  double dos = dotSize();
4037 
4038  QVector<qreal> dashVector( 2 );
4039  dashVector[0] = das;
4040  dashVector[1] = dss;
4041  writeLinetype( QStringLiteral( "DASH" ), dashVector, QgsUnitTypes::RenderMapUnits );
4042 
4043  QVector<qreal> dotVector( 2 );
4044  dotVector[0] = dos;
4045  dotVector[1] = dss;
4046  writeLinetype( QStringLiteral( "DOT" ), dotVector, QgsUnitTypes::RenderMapUnits );
4047 
4048  QVector<qreal> dashDotVector( 4 );
4049  dashDotVector[0] = das;
4050  dashDotVector[1] = dss;
4051  dashDotVector[2] = dos;
4052  dashDotVector[3] = dss;
4053  writeLinetype( QStringLiteral( "DASHDOT" ), dashDotVector, QgsUnitTypes::RenderMapUnits );
4054 
4055  QVector<qreal> dashDotDotVector( 6 );
4056  dashDotDotVector[0] = das;
4057  dashDotDotVector[1] = dss;
4058  dashDotDotVector[2] = dos;
4059  dashDotDotVector[3] = dss;
4060  dashDotDotVector[4] = dos;
4061  dashDotDotVector[5] = dss;
4062  writeLinetype( QStringLiteral( "DASHDOTDOT" ), dashDotDotVector, QgsUnitTypes::RenderMapUnits );
4063 }
4064 
4065 void QgsDxfExport::writeSymbolLayerLinetype( const QgsSymbolLayer *symbolLayer )
4066 {
4067  if ( !symbolLayer )
4068  {
4069  return;
4070  }
4071 
4073  QVector<qreal> customLinestyle = symbolLayer->dxfCustomDashPattern( unit );
4074  if ( !customLinestyle.isEmpty() )
4075  {
4076  QString name = QStringLiteral( "symbolLayer%1" ).arg( mSymbolLayerCounter++ );
4077  writeLinetype( name, customLinestyle, unit );
4078  mLineStyles.insert( symbolLayer, name );
4079  }
4080 }
4081 
4082 int QgsDxfExport::nLineTypes( const QList< QPair< QgsSymbolLayer *, QgsSymbol * > > &symbolLayers )
4083 {
4084  int nLineTypes = 0;
4085  QList< QPair< QgsSymbolLayer *, QgsSymbol *> >::const_iterator slIt = symbolLayers.constBegin();
4086  for ( ; slIt != symbolLayers.constEnd(); ++slIt )
4087  {
4088  const QgsSimpleLineSymbolLayer *simpleLine = dynamic_cast< const QgsSimpleLineSymbolLayer * >( slIt->first );
4089  if ( simpleLine )
4090  {
4091  if ( simpleLine->useCustomDashPattern() )
4092  {
4093  ++nLineTypes;
4094  }
4095  }
4096  }
4097  return nLineTypes;
4098 }
4099 
4100 void QgsDxfExport::writeLinetype( const QString &styleName, const QVector<qreal> &pattern, QgsUnitTypes::RenderUnit u )
4101 {
4102  double length = 0;
4103  QVector<qreal>::const_iterator dashIt = pattern.constBegin();
4104  for ( ; dashIt != pattern.constEnd(); ++dashIt )
4105  {
4106  length += ( *dashIt * mapUnitScaleFactor( mSymbologyScaleDenominator, u, mMapUnits ) );
4107  }
4108 
4109  writeGroup( 0, QStringLiteral( "LTYPE" ) );
4110  writeHandle();
4111  // 330 5
4112  writeGroup( 100, QStringLiteral( "AcDbSymbolTableRecord" ) );
4113  writeGroup( 100, QStringLiteral( "AcDbLinetypeTableRecord" ) );
4114  writeGroup( 2, styleName );
4115  writeGroup( 70, 64 ); // 0?
4116  writeGroup( 3, QLatin1String( "" ) );
4117  writeGroup( 72, 65 );
4118  writeGroup( 73, pattern.size() );
4119  writeGroup( 40, length );
4120 
4121  dashIt = pattern.constBegin();
4122  bool isGap = false;
4123  for ( ; dashIt != pattern.constEnd(); ++dashIt )
4124  {
4125  // map units or mm?
4126  double segmentLength = ( isGap ? -*dashIt : *dashIt );
4127  segmentLength *= mapUnitScaleFactor( mSymbologyScaleDenominator, u, mMapUnits );
4128  writeGroup( 49, segmentLength );
4129  writeGroup( 74, 0 );
4130  isGap = !isGap;
4131  }
4132 }
4133 
4134 bool QgsDxfExport::hasDataDefinedProperties( const QgsSymbolLayer *sl, const QgsSymbol *symbol )
4135 {
4136  if ( !sl || !symbol )
4137  {
4138  return false;
4139  }
4140 
4141  if ( symbol->renderHints() & QgsSymbol::DynamicRotation )
4142  {
4143  return true;
4144  }
4145 
4147 }
4148 
4149 double QgsDxfExport::dashSize() const
4150 {
4151  double size = mSymbologyScaleDenominator * 0.002;
4152  return sizeToMapUnits( size );
4153 }
4154 
4155 double QgsDxfExport::dotSize() const
4156 {
4157  double size = mSymbologyScaleDenominator * 0.0006;
4158  return sizeToMapUnits( size );
4159 }
4160 
4161 double QgsDxfExport::dashSeparatorSize() const
4162 {
4163  double size = mSymbologyScaleDenominator * 0.0006;
4164  return sizeToMapUnits( size );
4165 }
4166 
4167 double QgsDxfExport::sizeToMapUnits( double s ) const
4168 {
4169  double size = s * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceMeters, mMapUnits );
4170  return size;
4171 }
4172 
4173 QString QgsDxfExport::lineNameFromPenStyle( Qt::PenStyle style )
4174 {
4175  switch ( style )
4176  {
4177  case Qt::DashLine:
4178  return QStringLiteral( "DASH" );
4179  case Qt::DotLine:
4180  return QStringLiteral( "DOT" );
4181  case Qt::DashDotLine:
4182  return QStringLiteral( "DASHDOT" );
4183  case Qt::DashDotDotLine:
4184  return QStringLiteral( "DASHDOTDOT" );
4185  case Qt::SolidLine:
4186  default:
4187  return QStringLiteral( "CONTINUOUS" );
4188  }
4189 }
4190 
4191 QString QgsDxfExport::dxfLayerName( const QString &name )
4192 {
4193  if ( name.isEmpty() )
4194  return QStringLiteral( "0" );
4195 
4196  // dxf layers can be max 255 characters long
4197  QString layerName = name.left( 255 );
4198 
4199  // replaced restricted characters with underscore
4200  // < > / \ " : ; ? * | = '
4201  // See http://docs.autodesk.com/ACD/2010/ENU/AutoCAD%202010%20User%20Documentation/index.html?url=WS1a9193826455f5ffa23ce210c4a30acaf-7345.htm,topicNumber=d0e41665
4202  layerName.replace( '<', '_' );
4203  layerName.replace( '>', '_' );
4204  layerName.replace( '/', '_' );
4205  layerName.replace( '\\', '_' );
4206  layerName.replace( '\"', '_' );
4207  layerName.replace( ':', '_' );
4208  layerName.replace( ';', '_' );
4209  layerName.replace( '?', '_' );
4210  layerName.replace( '*', '_' );
4211  layerName.replace( '|', '_' );
4212  layerName.replace( '=', '_' );
4213  layerName.replace( '\'', '_' );
4214 
4215  // also remove newline characters (#15067)
4216  layerName.replace( QLatin1String( "\r\n" ), QLatin1String( "_" ) );
4217  layerName.replace( '\r', '_' );
4218  layerName.replace( '\n', '_' );
4219 
4220  return layerName.trimmed();
4221 }
4222 
4223 bool QgsDxfExport::layerIsScaleBasedVisible( const QgsMapLayer *layer ) const
4224 {
4225  if ( !layer )
4226  return false;
4227 
4228  if ( mSymbologyExport == QgsDxfExport::NoSymbology )
4229  return true;
4230 
4231  return layer->isInScaleRange( mSymbologyScaleDenominator );
4232 }
4233 
4234 QString QgsDxfExport::layerName( const QString &id, const QgsFeature &f ) const
4235 {
4236  Q_FOREACH ( QgsMapLayer *ml, mMapSettings.layers() )
4237  {
4238  QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( ml );
4239  if ( vl && vl->id() == id )
4240  {
4241  int attrIdx = mLayerNameAttribute.value( vl->id(), -1 );
4242  return dxfLayerName( attrIdx < 0 ? layerName( vl ) : f.attribute( attrIdx ).toString() );
4243  }
4244  }
4245 
4246  return QStringLiteral( "0" );
4247 }
4248 
4249 QString QgsDxfExport::dxfEncoding( const QString &name )
4250 {
4251  Q_FOREACH ( const QByteArray &codec, QTextCodec::availableCodecs() )
4252  {
4253  if ( name != codec )
4254  continue;
4255 
4256  int i;
4257  for ( i = 0; i < static_cast< int >( sizeof( DXF_ENCODINGS ) / sizeof( *DXF_ENCODINGS ) ) && name != DXF_ENCODINGS[i][1]; ++i )
4258  ;
4259 
4260  if ( i == static_cast< int >( sizeof( DXF_ENCODINGS ) / sizeof( *DXF_ENCODINGS ) ) )
4261  continue;
4262 
4263  return DXF_ENCODINGS[i][0];
4264  }
4265 
4266  return QString::null;
4267 }
4268 
4270 {
4271  QStringList encodings;
4272  Q_FOREACH ( QByteArray codec, QTextCodec::availableCodecs() )
4273  {
4274  int i;
4275  for ( i = 0; i < static_cast< int >( sizeof( DXF_ENCODINGS ) / sizeof( *DXF_ENCODINGS ) ) && strcmp( codec.data(), DXF_ENCODINGS[i][1] ) != 0; ++i )
4276  ;
4277 
4278  if ( i < static_cast< int >( sizeof( DXF_ENCODINGS ) / sizeof( *DXF_ENCODINGS ) ) )
4279  encodings << codec.data();
4280  }
4281  return encodings;
4282 }
4283 
4285 {
4286  Q_ASSERT( vl );
4287  return mLayerTitleAsName && !vl->title().isEmpty() ? vl->title() : vl->name();
4288 }
4289 
4290 void QgsDxfExport::drawLabel( const QString &layerId, QgsRenderContext &context, pal::LabelPosition *label, const QgsPalLayerSettings &settings )
4291 {
4292  Q_UNUSED( context );
4293 
4294  if ( !settings.drawLabels )
4295  return;
4296 
4297  QgsTextLabelFeature *lf = dynamic_cast<QgsTextLabelFeature *>( label->getFeaturePart()->feature() );
4298 
4299  // Copy to temp, editable layer settings
4300  // these settings will be changed by any data defined values, then used for rendering label components
4301  // settings may be adjusted during rendering of components
4302  QgsPalLayerSettings tmpLyr( settings );
4303 
4304  // apply any previously applied data defined settings for the label
4305  const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues = lf->dataDefinedValues();
4306 
4307  //font
4308  QFont dFont = lf->definedFont();
4309  QgsDebugMsgLevel( QString( "PAL font tmpLyr: %1, Style: %2" ).arg( tmpLyr.format().font().toString(), tmpLyr.format().font().styleName() ), 4 );
4310  QgsDebugMsgLevel( QString( "PAL font definedFont: %1, Style: %2" ).arg( dFont.toString(), dFont.styleName() ), 4 );
4311 
4312  QgsTextFormat format = tmpLyr.format();
4313  format.setFont( dFont );
4314  tmpLyr.setFormat( format );
4315 
4317  {
4318  //calculate font alignment based on label quadrant
4319  switch ( label->getQuadrant() )
4320  {
4325  break;
4330  break;
4335  break;
4336  }
4337  }
4338 
4339  // update tmpLyr with any data defined text style values
4340  QgsPalLabeling::dataDefinedTextStyle( tmpLyr, ddValues );
4341 
4342  // update tmpLyr with any data defined text buffer values
4343  QgsPalLabeling::dataDefinedTextBuffer( tmpLyr, ddValues );
4344 
4345  // update tmpLyr with any data defined text formatting values
4346  QgsPalLabeling::dataDefinedTextFormatting( tmpLyr, ddValues );
4347 
4348  // add to the results
4349  QString txt = label->getFeaturePart()->feature()->labelText();
4350 
4351  QgsFeatureId fid = label->getFeaturePart()->featureId();
4352  QString dxfLayer = mDxfLayerNames[layerId][fid];
4353 
4354  QString wrapchr = tmpLyr.wrapChar.isEmpty() ? QStringLiteral( "\n" ) : tmpLyr.wrapChar;
4355 
4356  //add the direction symbol if needed
4357  if ( !txt.isEmpty() && tmpLyr.placement == QgsPalLayerSettings::Line && tmpLyr.addDirectionSymbol )
4358  {
4359  bool prependSymb = false;
4360  QString symb = tmpLyr.rightDirectionSymbol;
4361 
4362  if ( label->getReversed() )
4363  {
4364  prependSymb = true;
4365  symb = tmpLyr.leftDirectionSymbol;
4366  }
4367 
4368  if ( tmpLyr.reverseDirectionSymbol )
4369  {
4370  if ( symb == tmpLyr.rightDirectionSymbol )
4371  {
4372  prependSymb = true;
4373  symb = tmpLyr.leftDirectionSymbol;
4374  }
4375  else
4376  {
4377  prependSymb = false;
4378  symb = tmpLyr.rightDirectionSymbol;
4379  }
4380  }
4381 
4383  {
4384  prependSymb = true;
4385  symb = symb + wrapchr;
4386  }
4388  {
4389  prependSymb = false;
4390  symb = wrapchr + symb;
4391  }
4392 
4393  if ( prependSymb )
4394  {
4395  txt.prepend( symb );
4396  }
4397  else
4398  {
4399  txt.append( symb );
4400  }
4401  }
4402 
4403  txt = txt.replace( wrapchr, QLatin1String( "\\P" ) );
4404 
4405  if ( tmpLyr.format().font().underline() )
4406  {
4407  txt.prepend( "\\L" ).append( "\\l" );
4408  }
4409 
4410  if ( tmpLyr.format().font().overline() )
4411  {
4412  txt.prepend( "\\O" ).append( "\\o" );
4413  }
4414 
4415  if ( tmpLyr.format().font().strikeOut() )
4416  {
4417  txt.prepend( "\\K" ).append( "\\k" );
4418  }
4419 
4420  txt.prepend( QStringLiteral( "\\f%1|i%2|b%3;\\H%4;" )
4421  .arg( tmpLyr.format().font().family() )
4422  .arg( tmpLyr.format().font().italic() ? 1 : 0 )
4423  .arg( tmpLyr.format().font().bold() ? 1 : 0 )
4424  .arg( label->getHeight() / ( 1 + txt.count( QStringLiteral( "\\P" ) ) ) * 0.75 ) );
4425 
4426  writeMText( dxfLayer, txt, QgsPointV2( label->getX(), label->getY() ), label->getWidth(), label->getAlpha() * 180.0 / M_PI, tmpLyr.format().color() );
4427 }
4428 
4429 
4430 void QgsDxfExport::registerDxfLayer( const QString &layerId, QgsFeatureId fid, const QString &layerName )
4431 {
4432  if ( !mDxfLayerNames.contains( layerId ) )
4433  mDxfLayerNames[ layerId ] = QMap<QgsFeatureId, QString>();
4434 
4435  mDxfLayerNames[layerId][fid] = layerName;
4436 }
4437 
4439 {
4440  mCrs = crs;
4441  mMapUnits = crs.mapUnits();
4442 }
4443 
4445 {
4446  return mCrs;
4447 }
bool restoreOverrideStyle()
Restore the original store after a call to setOverrideStyle()
void uniqueValues(int index, QList< QVariant > &uniqueValues, int limit=-1) const
Calculates a list of unique values contained within an attribute in the layer.
virtual QVector< qreal > dxfCustomDashPattern(QgsUnitTypes::RenderUnit &unit) const
get dash pattern
Wrapper for iterator of features from vector data provider or vector layer.
QString labelText() const
Text of the label.
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
sets destination coordinate reference system
A rectangle specified with double values.
Definition: qgsrectangle.h:38
Base class for all map layer types.
Definition: qgsmaplayer.h:54
void setExtent(const QgsRectangle &rect, bool magnified=true)
Set coordinates of the rectangle which should be rendered.
double y
Definition: qgspoint.h:42
QgsAbstractGeometry * offsetCurve(double distance, int segments, int joinStyle, double mitreLimit, QString *errorMsg=nullptr) const override
Definition: qgsgeos.cpp:1709
QgsPoint center() const
Returns the center point of the rectangle.
Definition: qgsrectangle.h:146
QList< QgsPointV2 > QgsPointSequence
void addProvider(QgsAbstractLabelProvider *provider)
Add provider of label features. Takes ownership of the provider.
QgsFeatureId featureId() const
Returns the unique ID of the feature.
Definition: feature.cpp:155
QString name
Definition: qgsfield.h:54
void removeProvider(QgsAbstractLabelProvider *provider)
Remove provider if the provider&#39;s initialization failed. Provider instance is deleted.
QgsLabelFeature * feature()
Returns the parent feature.
Definition: feature.h:111
static void dataDefinedTextBuffer(QgsPalLayerSettings &tmpLyr, const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues)
Update temporary QgsPalLayerSettings with any data defined text buffer values.
virtual double dxfOffset(const QgsDxfExport &e, QgsSymbolRenderContext &context) const
get offset
void addLayers(const QList< QPair< QgsVectorLayer *, int > > &layers)
Add layers to export.
void writeGroup(int code, int i)
Write a tuple of group code and integer value.
void writePolyline(const QgsPointSequence &line, const QString &layer, const QString &lineStyleName, const QColor &color, double width=-1)
Draw dxf primitives (LWPOLYLINE)
Place direction symbols on below label.
void writeCircle(const QString &layer, const QColor &color, const QgsPointV2 &pt, double radius, const QString &lineStyleName, double width)
Write circle (as polyline)
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
bool exists(int i) const
Return if a field index is valid.
Definition: qgsfields.cpp:125
#define QgsDebugMsg(str)
Definition: qgslogger.h:37
double getY(int i=0) const
get the down-left y coordinate
void startRender(QgsSymbolRenderContext &context) override
void writeMText(const QString &layer, const QString &text, const QgsPointV2 &pt, double width, double angle, const QColor &color)
Write mtext (MTEXT)
Implements a derived label provider for rule based labels internally used for DXF export...
Helper functions for various unit types.
Definition: qgsunittypes.h:36
void setRendererScale(double scale)
Sets the renderer map scale.
void setFont(const QFont &font)
Sets the font used for rendering text.
const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > & dataDefinedValues() const
Get data-defined values.
QgsAbstractGeometry * buffer(double distance, int segments, QString *errorMsg=nullptr) const override
Definition: qgsgeos.cpp:1299
void setOutputDpi(double dpi)
Set DPI used for conversion between real world units (e.g. mm) and pixels.
QgsPoint mapToLayerCoordinates(const QgsMapLayer *layer, QgsPoint point) const
transform point coordinates from output CRS to layer&#39;s CRS
void registerDxfLayer(const QString &layerId, QgsFeatureId fid, const QString &layer)
Register name of layer for feature.
static int closestColorMatch(QRgb color)
Get DXF palette index of nearest entry for given color.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QColor color() const
Returns the color that text will be rendered in.
Class that adds extra information to QgsLabelFeature for text labels.
static QStringList encodings()
return list of available DXF encodings
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
void setMapSettings(const QgsMapSettings &mapSettings)
Associate map settings instance.
void registerDxfFeature(QgsFeature &feature, QgsRenderContext &context, const QString &dxfLayerName)
Registration method that keeps track of DXF layer names of individual features.
bool drawLabels
Whether to draw labels for this layer.
MultiLineAlign multilineAlign
QgsUnitTypes::DistanceUnit mapUnits() const
Retrieve map units.
virtual double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const
get line width
FeaturePart * getFeaturePart()
return the feature corresponding to this labelposition
QList< QgsMapLayer * > layers() const
Get list of layers for map rendering The layers are stored in the reverse order of how they are rende...
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:61
double z() const
Returns the point&#39;s z-coordinate.
Definition: qgspointv2.h:97
double y() const
Returns the point&#39;s y-coordinate.
Definition: qgspointv2.h:91
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:190
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
void setExtent(const QgsRectangle &extent)
Rotation of symbol may be changed during rendering and symbol should not be cached.
Definition: qgssymbol.h:90
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
Definition: qgis.h:193
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
void writeInt(int i)
Write an integer value.
void setFormat(const QgsTextFormat &format)
Sets the label text formatting settings, e.g., font settings, buffer settings, etc.
void writePolygon(const QgsRingSequence &polygon, const QString &layer, const QString &hatchPattern, const QColor &color)
Draw dxf filled polygon (HATCH)
QgsFields fields() const
Returns the list of fields of this layer.
QgsField at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:135
QList< QgsSymbolLevel > QgsSymbolLevelOrder
Definition: qgsrenderer.h:78
The QgsMapSettings class contains configuration for rendering of the map.
QgsMapLayerStyleManager * styleManager() const
Get access to the layer&#39;s style manager.
QgsPoint layerToMapCoordinates(const QgsMapLayer *layer, QgsPoint point) const
transform point coordinates from layer&#39;s CRS to output CRS
void setMapSettings(const QgsMapSettings &settings)
Set map settings and assign layer name attributes.
void writeString(const QString &s)
Write a string value.
QgsCoordinateTransform layerTransform(const QgsMapLayer *layer) const
Return coordinate transform from layer&#39;s CRS to destination CRS.
void reinit(QgsVectorLayer *layer)
Reinitialize the subproviders with QgsDxfLabelProviders.
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)=0
Needs to be called when a new render cycle is started.
int writeToFile(QIODevice *d, const QString &codec)
Export to a dxf file in the given encoding.
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:35
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const =0
Return a list of attributes required by this renderer.
QgsWkbTypes::Type wkbType() const
Returns the WKBType or WKBUnknown in case of error.
int renderingPass() const
#define DXF_HANDMAX
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:66
QList< QgsSymbol * > QgsSymbolList
Definition: qgsrenderer.h:43
void setOutputSize(QSize size)
Set the size of the resulting map image.
void writeText(const QString &layer, const QString &text, const QgsPointV2 &pt, double size, double angle, const QColor &color)
Write text (TEXT)
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
QString id() const
Returns the layer&#39;s unique ID, which is used to access this layer from QgsProject.
virtual QgsSymbolList symbolsForFeature(QgsFeature &feat, QgsRenderContext &context)
Returns list of symbols used for rendering the feature.
virtual bool prepare(const QgsRenderContext &context, QSet< QString > &attributeNames) override
Prepare for registration of features.
virtual bool prepare(const QgsRenderContext &context, QSet< QString > &attributeNames)
Prepare for registration of features.
#define FALLTHROUGH
Definition: qgis.h:377
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
Set destination CRS.
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:38
QgsRectangle extent() const override
Return the extent of the layer.
bool isEmpty() const
Returns true if the rectangle is empty.
double getHeight() const
double size() const
Returns the symbol size.
void writeGroupCode(int code)
Write a group code.
double width() const
Returns the width of the rectangle.
Definition: qgsrectangle.h:118
Point geometry type, with support for z-dimension and m-values.
Definition: qgspointv2.h:37
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:181
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const
Query the layer for features specified in request.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer&#39;s property collection, used for data defined overrides...
virtual Qt::BrushStyle dxfBrushStyle() const
get brush/fill style
int symbolLayerCount()
Returns total number of symbol layers contained in the symbol.
Definition: qgssymbol.h:126
#define M_PI
This class wraps a request for features to a vector layer (or directly its vector data provider)...
Quadrant getQuadrant() const
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
double x() const
Returns the point&#39;s x-coordinate.
Definition: qgspointv2.h:85
void writeFilledCircle(const QString &layer, const QColor &color, const QgsPointV2 &pt, double radius)
Write filled circle (as hatch)
static double mapUnitScaleFactor(double scaleDenominator, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits)
Calculates a scaling factor to convert from map units to a specified symbol unit. ...
QgsFeatureRenderer * renderer()
Return renderer.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer&#39;s project and layer.
const QgsAbstractVectorLayerLabeling * labeling() const
Access to labeling configuration.
#define DXF_HANDSEED
Abstract base class for all geometries.
QgsGeometry geometry() const
Returns the geometry associated with this feature.
Definition: qgsfeature.cpp:101
Does vector analysis using the geos library and handles import, export, exception handling*...
Definition: qgsgeos.h:31
QgsSymbolLayer * symbolLayer(int layer)
Returns a specific symbol layers contained in the symbol.
Definition: qgssymbol.cpp:312
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination CRS, or an invalid CRS if no reprojection will be done.
static QString dxfEncoding(const QString &name)
return DXF encoding for Qt encoding
const QgsTextFormat & format() const
Returns the label text formatting settings, e.g., font settings, buffer settings, etc...
QString layerName(const QString &id, const QgsFeature &f) const
Get layer name for feature.
static void dataDefinedTextFormatting(QgsPalLayerSettings &tmpLyr, const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues)
Update temporary QgsPalLayerSettings with any data defined text formatting values.
virtual QColor dxfBrushColor(QgsSymbolRenderContext &context) const
get brush/fill color
QString title() const
Returns the title of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:183
Place direction symbols on above label.
void drawLabel(const QString &layerId, QgsRenderContext &context, pal::LabelPosition *label, const QgsPalLayerSettings &settings)
Output the label.
Rendering with symbol levels (i.e. implements symbols(), symbolForFeature())
Definition: qgsrenderer.h:192
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:106
QgsExpressionContext & expressionContext()
Gets the expression context.
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:42
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:91
void setFeature(const QgsFeature *f)
Definition: qgssymbol.h:432
void combineExtentWith(const QgsRectangle &rect)
Expand the rectangle so that covers both the original rectangle and the given rectangle.
virtual Qt::PenStyle dxfPenStyle() const
get pen style
virtual QgsCoordinateSequence coordinateSequence() const =0
Retrieves the sequence of geometries, rings and nodes.
static QString dxfLayerName(const QString &name)
Return cleaned layer name for use in DXF.
virtual QgsSymbolList symbols(QgsRenderContext &context)
Returns list of symbols used by the renderer.
Definition: qgsrenderer.h:218
The QgsLabelingEngine class provides map labeling functionality.
void run(QgsRenderContext &context)
compute the labeling with given map settings and providers
virtual QgsSymbol * symbolForFeature(QgsFeature &feature, QgsRenderContext &context)=0
To be overridden.
Arranges candidates over a point (or centroid of a polygon), or at a preset offset from the point...
Contains information about the context of a rendering operation.
Abstract base class for marker symbol layers.
QFont definedFont()
Font to be used for rendering.
QMap< QString, QString > layerStyleOverrides() const
Get map of map layer style overrides (key: layer ID, value: style name) where a different style shoul...
virtual void stopRender(QgsRenderContext &context)=0
Needs to be called when a render cycle has finished to clean up.
bool usingSymbolLevels() const
Definition: qgsrenderer.h:220
QList< QgsSymbolLevelItem > QgsSymbolLevel
Definition: qgsrenderer.h:75
double getAlpha() const
get alpha
static void dataDefinedTextStyle(QgsPalLayerSettings &tmpLyr, const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues)
Update temporary QgsPalLayerSettings with any data defined text style values.
virtual void stopRender(QgsSymbolRenderContext &context)=0
virtual double dxfAngle(QgsSymbolRenderContext &context) const
get angle
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the symbol&#39;s size.
double getWidth() const
double getX(int i=0) const
get the down-left x coordinate
#define DXF_HANDPLOTSTYLE
virtual QColor dxfColor(QgsSymbolRenderContext &context) const
get color
RenderHints renderHints() const
Returns the rendering hint flags for the symbol.
Definition: qgssymbol.h:241
const QgsFeature * feature() const
Current feature being rendered - may be null.
Definition: qgssymbol.h:434
This class represents a coordinate reference system (CRS).
void writeDouble(double d)
Write a floating point value.
void setMapToPixel(const QgsMapToPixel &mtp)
Abstract base class - its implementations define different approaches to the labeling of a vector lay...
QList< QgsPointSequence > QgsRingSequence
Class for doing transforms between two map coordinate systems.
LabelPosition is a candidate feature label position.
Definition: labelposition.h:52
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:96
void setLayers(const QList< QgsMapLayer *> &layers)
Set list of layers for map rendering.
qint64 QgsFeatureId
Definition: qgsfeature.h:37
void registerDxfFeature(QgsFeature &feature, QgsRenderContext &context, const QString &dxfLayerName)
Registration method that keeps track of DXF layer names of individual features.
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:101
bool hasActiveProperties() const override
Returns true if the collection has any active properties, or false if all properties within the colle...
QString name
Definition: qgsmaplayer.h:58
bool setOverrideStyle(const QString &styleDef)
Temporarily apply a different style to the layer.
void appendScopes(const QList< QgsExpressionContextScope *> &scopes)
Appends a list of scopes to the end of the context.
virtual Capabilities capabilities()
Returns details about internals of this renderer.
Definition: qgsrenderer.h:212
void writePoint(const QString &layer, const QColor &color, const QgsPointV2 &pt)
Write point.
QList< QgsRingSequence > QgsCoordinateSequence
bool getReversed() const
bool nextFeature(QgsFeature &f)
Implements a derived label provider internally used for DXF export.
virtual bool writeDxf(QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift=QPointF(0.0, 0.0)) const
write as DXF
Container for all settings relating to text rendering.
Geometry is not required. It may still be returned if e.g. required for a filter condition.
int writeHandle(int code=5, int handle=0)
Write a tuple of group code and a handle.
static Q_INVOKABLE double fromUnitToUnitFactor(QgsUnitTypes::DistanceUnit fromUnit, QgsUnitTypes::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
Represents a vector layer which manages a vector based data sets.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:255
static Type flatType(Type type)
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:423
virtual QgsAbstractGeometry * segmentize(double tolerance=M_PI/180., SegmentationToleranceType toleranceType=MaximumAngle) const
Returns a version of the geometry without curves.
double ANALYSIS_EXPORT angle(Point3D *p1, Point3D *p2, Point3D *p3, Point3D *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
Definition: MathUtils.cc:857
QgsSymbol * symbol()
Definition: qgsrenderer.h:67
QFont font() const
Returns the font used for rendering text.
QgsAbstractGeometry * geometry() const
Returns the underlying geometry store.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rect)
Set rectangle from which features will be taken.
QgsDxfExport & operator=(const QgsDxfExport &dxfExport)
RenderUnit
Rendering size units.
Definition: qgsunittypes.h:95
void writeLine(const QgsPointV2 &pt1, const QgsPointV2 &pt2, const QString &layer, const QString &lineStyleName, const QColor &color, double width=-1)
Write line (as a polyline)
double height() const
Returns the height of the rectangle.
Definition: qgsrectangle.h:125
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Set flags that affect how features will be fetched.
DirectionSymbols placeDirectionSymbol
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
double x
Definition: qgspoint.h:41