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