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