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