QGIS API Documentation  2.8.2-Wien
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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,
3342  double width, bool polygon )
3343 {
3344  writeGroup( 0, "LWPOLYLINE" );
3345  writeHandle();
3346  writeGroup( 8, layer );
3347  writeGroup( 100, "AcDbEntity" );
3348  writeGroup( 100, "AcDbPolyline" );
3349  writeGroup( 6, lineStyleName );
3350  writeGroup( color );
3351 
3352  writeGroup( 90, line.size() );
3353 
3354  writeGroup( 70, polygon ? 1 : 0 );
3355  writeGroup( 43, width );
3356 
3357  QgsPolyline::const_iterator lineIt = line.constBegin();
3358  for ( ; lineIt != line.constEnd(); ++lineIt )
3359  {
3360  writeGroup( 0, *lineIt );
3361  }
3362 }
3363 
3364 void QgsDxfExport::writePolygon( const QgsPolygon& polygon, const QString& layer, const QString& hatchPattern, QColor color )
3365 {
3366  writeGroup( 0, "HATCH" ); // Entity type
3367  writeHandle();
3368  writeGroup( 330, mModelSpaceBR );
3369  writeGroup( 100, "AcDbEntity" );
3370  writeGroup( 8, layer ); // Layer name
3371  writeGroup( color ); // Color
3372  writeGroup( 100, "AcDbHatch" );
3373 
3374  writeGroup( 0, QgsPoint( 0, 0 ) ); // Elevation point (in OCS)
3375  writeGroup( 200, QgsPoint( 0, 0 ), 1.0 );
3376 
3377  writeGroup( 2, hatchPattern ); // Hatch pattern name
3378  writeGroup( 70, hatchPattern == "SOLID" ); // Solid fill flag (solid fill = 1; pattern fill = 0)
3379  writeGroup( 71, 0 ); // Associativity flag (associative = 1; non-associative = 0)
3380 
3381  writeGroup( 91, polygon.size() ); // Number of boundary paths (loops)
3382  for ( int i = 0; i < polygon.size(); ++i )
3383  {
3384  writeGroup( 92, 2 ); // Boundary path type flag (bit coded): 0 = Default; 1 = External; 2 = Polyline 4 = Derived; 8 = Textbox; 16 = Outermost
3385  writeGroup( 72, 0 ); // Has bulge flag
3386  writeGroup( 73, 1 ); // Is closed flag
3387  writeGroup( 93, polygon[i].size() ); // Number of edges in this boundary path (only if boundary is not a polyline
3388 
3389  for ( int j = 0; j < polygon[i].size(); ++j )
3390  {
3391  writeGroup( 0, polygon[i][j], 0.0, true ); // Vertex location (in OCS)
3392  }
3393 
3394  writeGroup( 97, 0 ); // Number of source boundary objects
3395  }
3396 
3397  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)
3398  writeGroup( 76, 1 ); // Hatch pattern type: 0 = User-defined; 1 = Predefined; 2 = Custom
3399 
3400  writeGroup( 98, 0 ); // Number of seed points
3401 }
3402 
3403 void QgsDxfExport::writeLine( const QgsPoint& pt1, const QgsPoint& pt2, const QString& layer, const QString& lineStyleName, QColor color, double width )
3404 {
3405  QgsPolyline line( 2 );
3406  line[0] = pt1;
3407  line[1] = pt2;
3408  writePolyline( line, layer, lineStyleName, color, width, false );
3409 }
3410 
3411 void QgsDxfExport::writePoint( const QString& layer, QColor color, const QgsPoint& pt )
3412 {
3413  writeGroup( 0, "POINT" );
3414  writeHandle();
3415  writeGroup( 100, "AcDbEntity" );
3416  writeGroup( 100, "AcDbPoint" );
3417  writeGroup( 8, layer );
3418  writeGroup( color );
3419  writeGroup( 0, pt );
3420 }
3421 
3422 void QgsDxfExport::writeFilledCircle( const QString &layer, QColor color, const QgsPoint &pt, double radius )
3423 {
3424  writeGroup( 0, "HATCH" ); // Entity type
3425  writeHandle();
3426  writeGroup( 330, mModelSpaceBR );
3427  writeGroup( 100, "AcDbEntity" );
3428  writeGroup( 100, "AcDbHatch" );
3429 
3430  writeGroup( 8, layer ); // Layer name
3431  writeGroup( 0, QgsPoint( 0, 0 ), 0.0 ); // Elevation point (in OCS)
3432  writeGroup( 200, QgsPoint( 0, 0 ), 1.0 );
3433 
3434  writeGroup( 2, "SOLID" ); // Hatch pattern name
3435  writeGroup( 70, 1 ); // Solid fill flag (solid fill = 1; pattern fill = 0)
3436  writeGroup( 71, 0 ); // Associativity flag (associative = 1; non-associative = 0)
3437 
3438  writeGroup( color ); // Color (0 by block, 256 by layer)
3439 
3440  writeGroup( 91, 1 ); // Number of boundary paths (loops)
3441 
3442  writeGroup( 92, 7 ); // Boundary path type flag (bit coded): 0 = Default; 1 = External; 2 = Polyline 4 = Derived; 8 = Textbox; 16 = Outermost
3443  writeGroup( 72, 2 );
3444  writeGroup( 73, 1 ); // Is closed flag
3445  writeGroup( 93, 2 ); // Number of polyline vertices
3446 
3447  writeGroup( 0, QgsPoint( pt.x() - radius, pt.y() ) );
3448  writeGroup( 42, 1.0 );
3449 
3450  writeGroup( 0, QgsPoint( pt.x() + radius, pt.y() ) );
3451  writeGroup( 42, 1.0 );
3452 
3453  writeGroup( 97, 0 ); // Number of source boundary objects
3454 
3455  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)
3456  writeGroup( 76, 1 ); // Hatch pattern type: 0 = User-defined; 1 = Predefined; 2 = Custom
3457  writeGroup( 47, 0.0059696789328105 ); // Pixel size
3458 
3459  writeGroup( 98, 0 ); // Number of seed points
3460 }
3461 
3462 void QgsDxfExport::writeCircle( const QString& layer, QColor color, const QgsPoint& pt, double radius, const QString &lineStyleName, double width )
3463 {
3464  writeGroup( 0, "LWPOLYLINE" );
3465  writeHandle();
3466  writeGroup( 330, mModelSpaceBR );
3467  writeGroup( 8, layer );
3468  writeGroup( 100, "AcDbEntity" );
3469  writeGroup( 100, "AcDbPolyline" );
3470  writeGroup( 6, lineStyleName );
3471  writeGroup( color );
3472 
3473  writeGroup( 90, 2 );
3474 
3475  writeGroup( 70, 1 );
3476  writeGroup( 43, width );
3477 
3478  writeGroup( 0, QgsPoint( pt.x() - radius, pt.y() ) );
3479  writeGroup( 42, 1.0 );
3480  writeGroup( 0, QgsPoint( pt.x() + radius, pt.y() ) );
3481  writeGroup( 42, 1.0 );
3482 }
3483 
3484 void QgsDxfExport::writeText( const QString& layer, const QString& text, const QgsPoint& pt, double size, double angle, QColor color )
3485 {
3486  writeGroup( 0, "TEXT" );
3487  writeHandle();
3488  writeGroup( 100, "AcDbEntity" );
3489  writeGroup( 100, "AcDbText" );
3490  writeGroup( 8, layer );
3491  writeGroup( color );
3492  writeGroup( 0, pt );
3493  writeGroup( 40, size );
3494  writeGroup( 1, text );
3495  writeGroup( 50, angle );
3496  writeGroup( 7, "STANDARD" ); // so far only support for standard font
3497 }
3498 
3499 void QgsDxfExport::writeMText( const QString& layer, const QString& text, const QgsPoint& pt, double width, double angle, QColor color )
3500 {
3501  if ( !mTextStream.codec()->canEncode( text ) )
3502  {
3503  // TODO return error
3504  return;
3505  }
3506 
3507  writeGroup( 0, "MTEXT" );
3508  writeHandle();
3509  writeGroup( 100, "AcDbEntity" );
3510  writeGroup( 100, "AcDbMText" );
3511  writeGroup( 8, layer );
3512  writeGroup( color );
3513 
3514  writeGroup( 0, pt );
3515 
3516  QString t( text );
3517  while ( t.length() > 250 )
3518  {
3519  writeGroup( 3, t.left( 250 ) );
3520  t = t.mid( 250 );
3521  }
3522  writeGroup( 1, text );
3523 
3524  writeGroup( 50, angle ); // Rotation angle in radians
3525  writeGroup( 41, width * 1.1 ); // Reference rectangle width
3526 
3527  // Attachment point:
3528  // 1 2 3
3529  // 4 5 6
3530  // 7 8 9
3531  writeGroup( 71, 7 );
3532 
3533  writeGroup( 7, "STANDARD" ); // so far only support for standard font
3534 }
3535 
3536 void QgsDxfExport::writeSolid( const QString& layer, QColor color, const QgsPoint& pt1, const QgsPoint& pt2, const QgsPoint& pt3, const QgsPoint& pt4 )
3537 {
3538  writeGroup( 0, "SOLID" );
3539  writeHandle();
3540  writeGroup( 100, "AcDbEntity" );
3541  writeGroup( 100, "AcDbTrace" );
3542  writeGroup( 8, layer );
3543  writeGroup( color );
3544  writeGroup( 0, pt1 );
3545  writeGroup( 1, pt2 );
3546  writeGroup( 2, pt3 );
3547  writeGroup( 3, pt4 );
3548 }
3549 
3550 void QgsDxfExport::writeVertex( const QgsPoint& pt, const QString& layer )
3551 {
3552  writeGroup( 0, "VERTEX" );
3553  writeHandle();
3554  writeGroup( 100, "AcDbEntity" );
3555  writeGroup( 100, "AcDbVertex" );
3556  writeGroup( 100, "AcDb2dVertex" );
3557  writeGroup( 8, layer );
3558  writeGroup( 0, pt, 0.0, false );
3559 }
3560 
3561 QgsRectangle QgsDxfExport::dxfExtent() const
3562 {
3564  QList< QPair<QgsVectorLayer*, int> >::const_iterator layerIt = mLayers.constBegin();
3565  for ( ; layerIt != mLayers.constEnd(); ++layerIt )
3566  {
3567  if ( layerIt->first )
3568  {
3569  if ( extent.isEmpty() )
3570  {
3571  extent = layerIt->first->extent();
3572  }
3573  else
3574  {
3575  QgsRectangle layerExtent = layerIt->first->extent();
3576  extent.combineExtentWith( &layerExtent );
3577  }
3578  }
3579  }
3580  return extent;
3581 }
3582 
3583 void QgsDxfExport::addFeature( const QgsSymbolV2RenderContext& ctx, const QString& layer, const QgsSymbolLayerV2* symbolLayer, const QgsSymbolV2* symbol )
3584 {
3585  const QgsFeature* fet = ctx.feature();
3586  if ( !fet )
3587  return;
3588 
3589  QgsGeometry *geom = fet->geometry();
3590  if ( !geom )
3591  return;
3592 
3593  QGis::WkbType geometryType = geom->wkbType();
3594 
3595  QColor penColor;
3596  QColor brushColor;
3597  if ( mSymbologyExport != NoSymbology )
3598  {
3599  penColor = colorFromSymbolLayer( symbolLayer, ctx );
3600  brushColor = symbolLayer->dxfBrushColor( ctx );
3601  }
3602 
3603  Qt::PenStyle penStyle( Qt::SolidLine );
3604  Qt::BrushStyle brushStyle( Qt::NoBrush );
3605  double width = -1;
3606  double offset = 0.0;
3607  if ( mSymbologyExport != NoSymbology && symbolLayer )
3608  {
3609  width = symbolLayer->dxfWidth( *this, ctx );
3610  offset = symbolLayer->dxfOffset( *this, ctx );
3611  penStyle = symbolLayer->dxfPenStyle();
3612  brushStyle = symbolLayer->dxfBrushStyle();
3613 
3614  if ( qgsDoubleNear( offset, 0.0 ) )
3615  offset = 0.0;
3616  }
3617 
3618  QString lineStyleName = "CONTINUOUS";
3619  if ( mSymbologyExport != NoSymbology )
3620  {
3621  lineStyleName = lineStyleFromSymbolLayer( symbolLayer );
3622  }
3623 
3624  // single point
3625  if ( geometryType == QGis::WKBPoint || geometryType == QGis::WKBPoint25D )
3626  {
3627  writePoint( geom->asPoint(), layer, penColor, fet, symbolLayer, symbol );
3628  return;
3629  }
3630 
3631  // multipoint
3632  if ( geometryType == QGis::WKBMultiPoint || geometryType == QGis::WKBMultiPoint25D )
3633  {
3634  QgsMultiPoint multiPoint = geom->asMultiPoint();
3635  QgsMultiPoint::const_iterator it = multiPoint.constBegin();
3636  for ( ; it != multiPoint.constEnd(); ++it )
3637  {
3638  writePoint( *it, layer, penColor, fet, symbolLayer, symbol );
3639  }
3640 
3641  return;
3642  }
3643 
3644  if ( penStyle != Qt::NoPen )
3645  {
3646  // single line
3647  if ( geometryType == QGis::WKBLineString || geometryType == QGis::WKBLineString25D )
3648  {
3649  QgsGeometry *offsetLine = offset == 0.0 ? geom : geom->offsetCurve( offset, 0, GEOSBUF_JOIN_MITRE, 2.0 );
3650  if ( !offsetLine )
3651  offsetLine = geom;
3652 
3653  writePolyline( offsetLine->asPolyline(), layer, lineStyleName, penColor, width, false );
3654 
3655  if ( offsetLine != geom )
3656  delete offsetLine;
3657  }
3658 
3659  // multiline
3660  if ( geometryType == QGis::WKBMultiLineString || geometryType == QGis::WKBMultiLineString25D )
3661  {
3662  QgsGeometry *offsetLine = offset == 0.0 ? geom : geom->offsetCurve( offset, 0, GEOSBUF_JOIN_MITRE, 2.0 );
3663  if ( !offsetLine )
3664  offsetLine = geom;
3665 
3666  QgsMultiPolyline multiLine = offsetLine->asMultiPolyline();
3667  QgsMultiPolyline::const_iterator lIt = multiLine.constBegin();
3668  for ( ; lIt != multiLine.constEnd(); ++lIt )
3669  {
3670  writePolyline( *lIt, layer, lineStyleName, penColor, width, false );
3671  }
3672 
3673  if ( offsetLine != geom )
3674  delete offsetLine;
3675  }
3676 
3677  // polygon
3678  if ( geometryType == QGis::WKBPolygon || geometryType == QGis::WKBPolygon25D )
3679  {
3680  QgsGeometry *offsetPolygon = offset == 0.0 ? geom : geom->buffer( -offset, 0, GEOSBUF_CAP_FLAT, GEOSBUF_JOIN_MITRE, 2.0 );
3681  if ( !offsetPolygon )
3682  offsetPolygon = geom;
3683 
3684  QgsPolygon polygon = offsetPolygon->asPolygon();
3685  QgsPolygon::const_iterator polyIt = polygon.constBegin();
3686  for ( ; polyIt != polygon.constEnd(); ++polyIt ) // iterate over rings
3687  {
3688  writePolyline( *polyIt, layer, lineStyleName, penColor, width, false );
3689  }
3690 
3691  if ( offsetPolygon != geom )
3692  delete offsetPolygon;
3693  }
3694 
3695  // multipolygon or polygon
3696  if ( geometryType == QGis::WKBMultiPolygon || geometryType == QGis::WKBMultiPolygon25D )
3697  {
3698  QgsGeometry *offsetPolygon = offset == 0.0 ? geom : geom->buffer( -offset, 0, GEOSBUF_CAP_FLAT, GEOSBUF_JOIN_MITRE, 2.0 );
3699  if ( !offsetPolygon )
3700  offsetPolygon = geom;
3701 
3702  QgsMultiPolygon mp = offsetPolygon->asMultiPolygon();
3703  QgsMultiPolygon::const_iterator mpIt = mp.constBegin();
3704  for ( ; mpIt != mp.constEnd(); ++mpIt )
3705  {
3706  QgsPolygon::const_iterator polyIt = mpIt->constBegin();
3707  for ( ; polyIt != mpIt->constEnd(); ++polyIt )
3708  {
3709  writePolyline( *polyIt, layer, lineStyleName, penColor, width, true );
3710  }
3711  }
3712 
3713  if ( offsetPolygon != geom )
3714  delete offsetPolygon;
3715  }
3716  }
3717 
3718  if ( brushStyle != Qt::NoBrush )
3719  {
3720  // polygon
3721  if ( geometryType == QGis::WKBPolygon || geometryType == QGis::WKBPolygon25D )
3722  {
3723  QgsPolygon polygon = geom->asPolygon();
3724  writePolygon( polygon, layer, "SOLID", brushColor );
3725  }
3726 
3727  // multipolygon or polygon
3728  if ( geometryType == QGis::WKBMultiPolygon || geometryType == QGis::WKBMultiPolygon25D )
3729  {
3730  QgsMultiPolygon mp = geom->asMultiPolygon();
3731  QgsMultiPolygon::const_iterator mpIt = mp.constBegin();
3732  for ( ; mpIt != mp.constEnd(); ++mpIt )
3733  {
3734  writePolygon( *mpIt, layer, "SOLID", brushColor );
3735  }
3736  }
3737  }
3738 }
3739 
3740 QColor QgsDxfExport::colorFromSymbolLayer( const QgsSymbolLayerV2* symbolLayer, const QgsSymbolV2RenderContext& ctx )
3741 {
3742  if ( !symbolLayer )
3743  return QColor();
3744 
3745  return symbolLayer->dxfColor( ctx );
3746 }
3747 
3748 QString QgsDxfExport::lineStyleFromSymbolLayer( const QgsSymbolLayerV2* symbolLayer )
3749 {
3750  QString lineStyleName = "CONTINUOUS";
3751  if ( !symbolLayer )
3752  {
3753  return lineStyleName;
3754  }
3755 
3756  QHash< const QgsSymbolLayerV2*, QString >::const_iterator lineTypeIt = mLineStyles.find( symbolLayer );
3757  if ( lineTypeIt != mLineStyles.constEnd() )
3758  {
3759  lineStyleName = lineTypeIt.value();
3760  return lineStyleName;
3761  }
3762  else
3763  {
3764  return lineNameFromPenStyle( symbolLayer->dxfPenStyle() );
3765  }
3766 }
3767 
3769 {
3770  int idx = 0;
3771  int current_distance = INT_MAX;
3772  for ( size_t i = 1; i < sizeof( mDxfColors ) / sizeof( *mDxfColors ); ++i )
3773  {
3774  int dist = color_distance( pixel, i );
3775  if ( dist < current_distance )
3776  {
3777  current_distance = dist;
3778  idx = i;
3779  if ( dist == 0 )
3780  break;
3781  }
3782  }
3783  return idx;
3784 }
3785 
3786 int QgsDxfExport::color_distance( QRgb p1, int index )
3787 {
3788  if ( index > 255 || index < 0 )
3789  {
3790  return 0;
3791  }
3792 
3793  double redDiff = qRed( p1 ) - mDxfColors[index][0];
3794  double greenDiff = qGreen( p1 ) - mDxfColors[index][1];
3795  double blueDiff = qBlue( p1 ) - mDxfColors[index][2];
3796 #if 0
3797  QgsDebugMsg( QString( "color_distance( r:%1 g:%2 b:%3 <=> i:%4 r:%5 g:%6 b:%7 ) => %8" )
3798  .arg( qRed( p1 ) ).arg( qGreen( p1 ) ).arg( qBlue( p1 ) )
3799  .arg( index )
3800  .arg( mDxfColors[index][0] )
3801  .arg( mDxfColors[index][1] )
3802  .arg( mDxfColors[index][2] )
3803  .arg( redDiff * redDiff + greenDiff * greenDiff + blueDiff * blueDiff ) );
3804 #endif
3805  return redDiff * redDiff + greenDiff * greenDiff + blueDiff * blueDiff;
3806 }
3807 
3808 QRgb QgsDxfExport::createRgbEntry( qreal r, qreal g, qreal b )
3809 {
3810  return QColor::fromRgbF( r, g, b ).rgb();
3811 }
3812 
3813 QgsRenderContext QgsDxfExport::renderContext() const
3814 {
3815  QgsRenderContext context;
3816  context.setRendererScale( mSymbologyScaleDenominator );
3817  return context;
3818 }
3819 
3820 double QgsDxfExport::mapUnitScaleFactor( double scaleDenominator, QgsSymbolV2::OutputUnit symbolUnits, QGis::UnitType mapUnits )
3821 {
3822  if ( symbolUnits == QgsSymbolV2::MapUnit )
3823  {
3824  return 1.0;
3825  }
3826  // MM symbol unit
3827  return scaleDenominator * QGis::fromUnitToUnitFactor( QGis::Meters, mapUnits ) / 1000.0;
3828 }
3829 
3830 QList< QPair< QgsSymbolLayerV2*, QgsSymbolV2* > > QgsDxfExport::symbolLayers()
3831 {
3832  QList< QPair< QgsSymbolLayerV2*, QgsSymbolV2* > > symbolLayers;
3833 
3834  QList< QPair< QgsVectorLayer*, int> >::iterator lIt = mLayers.begin();
3835  for ( ; lIt != mLayers.end(); ++lIt )
3836  {
3837  // cast to vector layer
3838  QgsVectorLayer* vl = lIt->first;
3839  if ( !vl )
3840  {
3841  continue;
3842  }
3843 
3844  // get rendererv2
3845  QgsFeatureRendererV2* r = vl->rendererV2();
3846  if ( !r )
3847  {
3848  continue;
3849  }
3850 
3851  // get all symbols
3852  QgsSymbolV2List symbols = r->symbols();
3853  QgsSymbolV2List::iterator symbolIt = symbols.begin();
3854  for ( ; symbolIt != symbols.end(); ++symbolIt )
3855  {
3856  int maxSymbolLayers = ( *symbolIt )->symbolLayerCount();
3857  if ( mSymbologyExport != SymbolLayerSymbology )
3858  {
3859  maxSymbolLayers = 1;
3860  }
3861  for ( int i = 0; i < maxSymbolLayers; ++i )
3862  {
3863  symbolLayers.append( qMakePair(( *symbolIt )->symbolLayer( i ), *symbolIt ) );
3864  }
3865  }
3866  }
3867 
3868  return symbolLayers;
3869 }
3870 
3871 void QgsDxfExport::writeDefaultLinetypes()
3872 {
3873  // continuous (Qt solid line)
3874  foreach ( QString ltype, QStringList() << "ByLayer" << "ByBlock" << "CONTINUOUS" )
3875  {
3876  writeGroup( 0, "LTYPE" );
3877  writeHandle();
3878  writeGroup( 100, "AcDbSymbolTableRecord" );
3879  writeGroup( 100, "AcDbLinetypeTableRecord" );
3880  writeGroup( 2, ltype );
3881  writeGroup( 70, 64 );
3882  writeGroup( 3, "Defaultstyle" );
3883  writeGroup( 72, 65 );
3884  writeGroup( 73, 0 );
3885  writeGroup( 40, 0.0 );
3886  }
3887 
3888  double das = dashSize();
3889  double dss = dashSeparatorSize();
3890  double dos = dotSize();
3891 
3892  QVector<qreal> dashVector( 2 );
3893  dashVector[0] = das;
3894  dashVector[1] = dss;
3895  writeLinetype( "DASH", dashVector, QgsSymbolV2::MapUnit );
3896 
3897  QVector<qreal> dotVector( 2 );
3898  dotVector[0] = dos;
3899  dotVector[1] = dss;
3900  writeLinetype( "DOT", dotVector, QgsSymbolV2::MapUnit );
3901 
3902  QVector<qreal> dashDotVector( 4 );
3903  dashDotVector[0] = das;
3904  dashDotVector[1] = dss;
3905  dashDotVector[2] = dos;
3906  dashDotVector[3] = dss;
3907  writeLinetype( "DASHDOT", dashDotVector, QgsSymbolV2::MapUnit );
3908 
3909  QVector<qreal> dashDotDotVector( 6 );
3910  dashDotDotVector[0] = das;
3911  dashDotDotVector[1] = dss;
3912  dashDotDotVector[2] = dos;
3913  dashDotDotVector[3] = dss;
3914  dashDotDotVector[4] = dos;
3915  dashDotDotVector[5] = dss;
3916  writeLinetype( "DASHDOTDOT", dashDotDotVector, QgsSymbolV2::MapUnit );
3917 }
3918 
3919 void QgsDxfExport::writeSymbolLayerLinetype( const QgsSymbolLayerV2* symbolLayer )
3920 {
3921  if ( !symbolLayer )
3922  {
3923  return;
3924  }
3925 
3927  QVector<qreal> customLinestyle = symbolLayer->dxfCustomDashPattern( unit );
3928  if ( customLinestyle.size() > 0 )
3929  {
3930  QString name = QString( "symbolLayer%1" ).arg( mSymbolLayerCounter++ );
3931  writeLinetype( name, customLinestyle, unit );
3932  mLineStyles.insert( symbolLayer, name );
3933  }
3934 }
3935 
3936 int QgsDxfExport::nLineTypes( const QList< QPair< QgsSymbolLayerV2*, QgsSymbolV2* > >& symbolLayers )
3937 {
3938  int nLineTypes = 0;
3939  QList< QPair< QgsSymbolLayerV2*, QgsSymbolV2*> >::const_iterator slIt = symbolLayers.constBegin();
3940  for ( ; slIt != symbolLayers.constEnd(); ++slIt )
3941  {
3942  const QgsSimpleLineSymbolLayerV2* simpleLine = dynamic_cast< const QgsSimpleLineSymbolLayerV2* >( slIt->first );
3943  if ( simpleLine )
3944  {
3945  if ( simpleLine->useCustomDashPattern() )
3946  {
3947  ++nLineTypes;
3948  }
3949  }
3950  }
3951  return nLineTypes;
3952 }
3953 
3954 void QgsDxfExport::writeLinetype( const QString& styleName, const QVector<qreal>& pattern, QgsSymbolV2::OutputUnit u )
3955 {
3956  double length = 0;
3957  QVector<qreal>::const_iterator dashIt = pattern.constBegin();
3958  for ( ; dashIt != pattern.constEnd(); ++dashIt )
3959  {
3960  length += ( *dashIt * mapUnitScaleFactor( mSymbologyScaleDenominator, u, mMapUnits ) );
3961  }
3962 
3963  writeGroup( 0, "LTYPE" );
3964  writeHandle();
3965  // 330 5
3966  writeGroup( 100, "AcDbSymbolTableRecord" );
3967  writeGroup( 100, "AcDbLinetypeTableRecord" );
3968  writeGroup( 2, styleName );
3969  writeGroup( 70, 64 ); // 0?
3970  writeGroup( 3, "" );
3971  writeGroup( 72, 65 );
3972  writeGroup( 73, pattern.size() );
3973  writeGroup( 40, length );
3974 
3975  dashIt = pattern.constBegin();
3976  bool isGap = false;
3977  for ( ; dashIt != pattern.constEnd(); ++dashIt )
3978  {
3979  // map units or mm?
3980  double segmentLength = ( isGap ? -*dashIt : *dashIt );
3981  segmentLength *= mapUnitScaleFactor( mSymbologyScaleDenominator, u, mMapUnits );
3982  writeGroup( 49, segmentLength );
3983  writeGroup( 74, 0 );
3984  isGap = !isGap;
3985  }
3986 }
3987 
3988 bool QgsDxfExport::hasDataDefinedProperties( const QgsSymbolLayerV2* sl, const QgsSymbolV2* symbol )
3989 {
3990  if ( !sl || !symbol )
3991  {
3992  return false;
3993  }
3994 
3997  {
3998  return true;
3999  }
4000 
4001  return sl->hasDataDefinedProperties();
4002 }
4003 
4004 double QgsDxfExport::dashSize() const
4005 {
4006  double size = mSymbologyScaleDenominator * 0.002;
4007  return sizeToMapUnits( size );
4008 }
4009 
4010 double QgsDxfExport::dotSize() const
4011 {
4012  double size = mSymbologyScaleDenominator * 0.0006;
4013  return sizeToMapUnits( size );
4014 }
4015 
4016 double QgsDxfExport::dashSeparatorSize() const
4017 {
4018  double size = mSymbologyScaleDenominator * 0.0006;
4019  return sizeToMapUnits( size );
4020 }
4021 
4022 double QgsDxfExport::sizeToMapUnits( double s ) const
4023 {
4024  double size = s * QGis::fromUnitToUnitFactor( QGis::Meters, mMapUnits );
4025  return size;
4026 }
4027 
4028 QString QgsDxfExport::lineNameFromPenStyle( Qt::PenStyle style )
4029 {
4030  switch ( style )
4031  {
4032  case Qt::DashLine:
4033  return "DASH";
4034  case Qt::DotLine:
4035  return "DOT";
4036  case Qt::DashDotLine:
4037  return "DASHDOT";
4038  case Qt::DashDotDotLine:
4039  return "DASHDOTDOT";
4040  case Qt::SolidLine:
4041  default:
4042  return "CONTINUOUS";
4043  }
4044 }
4045 
4046 QString QgsDxfExport::dxfLayerName( const QString& name )
4047 {
4048  if ( name.isEmpty() )
4049  return "0";
4050 
4051  // dxf layers can be max 255 characters long
4052  QString layerName = name.left( 255 );
4053 
4054  // replaced restricted characters with underscore
4055  // < > / \ " : ; ? * | = '
4056  // See http://docs.autodesk.com/ACD/2010/ENU/AutoCAD%202010%20User%20Documentation/index.html?url=WS1a9193826455f5ffa23ce210c4a30acaf-7345.htm,topicNumber=d0e41665
4057  layerName.replace( "<", "_" );
4058  layerName.replace( ">", "_" );
4059  layerName.replace( "/", "_" );
4060  layerName.replace( "\\", "_" );
4061  layerName.replace( "\"", "_" );
4062  layerName.replace( ":", "_" );
4063  layerName.replace( ";", "_" );
4064  layerName.replace( "?", "_" );
4065  layerName.replace( "*", "_" );
4066  layerName.replace( "|", "_" );
4067  layerName.replace( "=", "_" );
4068  layerName.replace( "\'", "_" );
4069 
4070  return layerName;
4071 }
4072 
4073 bool QgsDxfExport::layerIsScaleBasedVisible( const QgsMapLayer* layer ) const
4074 {
4075  if ( !layer )
4076  return false;
4077 
4078  if ( mSymbologyExport == QgsDxfExport::NoSymbology || !layer->hasScaleBasedVisibility() )
4079  return true;
4080 
4081  return layer->minimumScale() < mSymbologyScaleDenominator &&
4082  layer->maximumScale() > mSymbologyScaleDenominator;
4083 }
4084 
4085 QString QgsDxfExport::layerName( const QString &id, const QgsFeature &f ) const
4086 {
4087  QList< QPair<QgsVectorLayer*, int> >::const_iterator layerIt = mLayers.constBegin();
4088  for ( ; layerIt != mLayers.constEnd(); ++layerIt )
4089  {
4090  if ( layerIt->first && layerIt->first->id() == id )
4091  return dxfLayerName( layerIt->second < 0 ? layerIt->first->name() : f.attribute( layerIt->second ).toString() );
4092  }
4093 
4094  return "0";
4095 }
4096 
4097 QString QgsDxfExport::dxfEncoding( const QString &name )
4098 {
4099  foreach ( QByteArray codec, QTextCodec::availableCodecs() )
4100  {
4101  if ( name != codec )
4102  continue;
4103 
4104  int i;
4105  for ( i = 0; i < ( int )( sizeof( mDxfEncodings ) / sizeof( *mDxfEncodings ) ) && name != mDxfEncodings[i][1]; ++i )
4106  ;
4107 
4108  if ( i == ( int )( sizeof( mDxfEncodings ) / sizeof( *mDxfEncodings ) ) )
4109  continue;
4110 
4111  return mDxfEncodings[i][0];
4112  }
4113 
4114  return QString::null;
4115 }
4116 
4118 {
4119  QStringList encodings;
4120  foreach ( QByteArray codec, QTextCodec::availableCodecs() )
4121  {
4122  int i;
4123  for ( i = 0; i < ( int )( sizeof( mDxfEncodings ) / sizeof( *mDxfEncodings ) ) && strcmp( codec.data(), mDxfEncodings[i][1] ) != 0; ++i )
4124  ;
4125 
4126  if ( i < ( int )( sizeof( mDxfEncodings ) / sizeof( *mDxfEncodings ) ) )
4127  encodings << codec.data();
4128  }
4129  return encodings;
4130 }