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