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