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