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