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