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