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