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