QGIS API Documentation  3.21.0-Master (5b68dc587e)
qgsmapinfosymbolconverter.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmapinfosymbolconverter.cpp
3  --------------------------------------
4  Date : March 2021
5  Copyright : (C) 2021 by Nyall Dawson
6  Email : nyall dot dawson at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 #include "qgslogger.h"
18 #include "qgslinesymbollayer.h"
19 #include "qgsmarkersymbollayer.h"
20 #include "qgsfillsymbollayer.h"
21 #include "qgssymbol.h"
22 #include "qgslinesymbol.h"
23 #include "qgsfillsymbol.h"
24 #include "qgsmarkersymbol.h"
25 
26 //
27 // QgsMapInfoSymbolConversionContext
28 //
29 void QgsMapInfoSymbolConversionContext::pushWarning( const QString &warning )
30 {
31  QgsDebugMsg( warning );
32  mWarnings << warning;
33 }
34 
35 
36 QgsLineSymbol *QgsMapInfoSymbolConverter::convertLineSymbol( int identifier, QgsMapInfoSymbolConversionContext &context, const QColor &foreColor, double size, QgsUnitTypes::RenderUnit sizeUnit, bool interleaved )
37 {
38  std::unique_ptr< QgsSimpleLineSymbolLayer > simpleLine = std::make_unique< QgsSimpleLineSymbolLayer >( foreColor, size );
39  simpleLine->setWidthUnit( sizeUnit );
40  simpleLine->setPenCapStyle( Qt::RoundCap );
41  simpleLine->setPenJoinStyle( Qt::RoundJoin );
42 
43  QVector< qreal > dashPattern;
44  double patternOffset = 0;
45  switch ( identifier )
46  {
47  case 1:
48  case 57:
49  case 58:
50  case 82:
51  case 90:
52  case 98:
53  case 106:
54  // no pen
55  simpleLine->setPenStyle( Qt::NoPen );
56  break;
57 
58  case 2:
59  case 38:
60  // solid line
61  break;
62 
63  case 3:
64  dashPattern << 1 << 2.2;
65  break;
66 
67  case 4:
68  dashPattern << 2 << 2;
69  break;
70 
71  case 5:
72  dashPattern << 4 << 2;
73  break;
74 
75  case 6:
76  dashPattern << 8 << 2;
77  break;
78 
79  case 7:
80  dashPattern << 16 << 4;
81  break;
82 
83  case 8:
84  dashPattern << 32 << 8;
85  break;
86 
87  case 9:
88  dashPattern << 10.5 << 4.5;
89  break;
90 
91  case 10:
92  dashPattern << 1 << 13.5 / 2;
93  break;
94 
95  case 11:
96  dashPattern << 4 << 8;
97  break;
98 
99  case 12:
100  dashPattern << 8 << 8;
101  break;
102 
103  case 13:
104  dashPattern << 16 << 16;
105  break;
106 
107  case 14:
108  dashPattern << 10 << 5 << 1 << 5;
109  break;
110 
111  case 15:
112  dashPattern << 18 << 3 << 1 << 3;
113  break;
114 
115  case 16:
116  dashPattern << 20 << 3 << 4 << 3;
117  break;
118 
119  case 17:
120  dashPattern << 32 << 12 << 6 << 12;
121  break;
122 
123  case 18:
124  dashPattern << 32 << 6 << 4 << 6 << 4 << 6;
125  break;
126 
127  case 19:
128  dashPattern << 32 << 6 << 4 << 6 << 4 << 6 << 4 << 6;
129  break;
130 
131  case 20:
132  dashPattern << 11 << 5 << 1 << 5 << 1 << 5;
133  break;
134 
135  case 21:
136  dashPattern << 20 << 4 << 1 << 4 << 1 << 4;
137  break;
138 
139  case 22:
140  dashPattern << 20 << 4 << 1 << 4 << 1 << 4 << 1 << 4;
141  break;
142 
143  case 23:
144  dashPattern << 6 << 2 << 1 << 2;
145  break;
146 
147  case 24:
148  dashPattern << 6 << 2 << 1 << 2 << 1 << 2;
149  break;
150 
151  case 25:
152  dashPattern << 10.5 << 2 << 1 << 2 << 4 << 2 << 1 << 2;
153  break;
154 
155  case 32:
156  case 33:
157  case 34:
158  case 35:
159  dashPattern << 18 << 4;
160  break;
161 
162  case 36:
163  dashPattern << 7 << 4;
164  break;
165 
166  case 37:
167  dashPattern << 16 << 6;
168  break;
169 
170  case 26:
171  case 27:
172  case 28:
173  case 29:
174  case 30:
175  case 31:
176  break;
177 
178  case 39:
179  case 40:
180  dashPattern << 20 << 15;
181  break;
182 
183  case 41:
184  case 42:
185  case 43:
186  case 44:
187  case 45:
188  case 46:
189  break;
190 
191  case 47:
192  dashPattern << 4 << 8;
193  break;
194 
195  case 48:
196  case 49:
197  case 50:
198  case 51:
199  break;
200 
201  case 52:
202  case 53:
203  dashPattern << 15 << 4;
204  break;
205 
206  case 54:
207  case 55:
208  case 56:
209  case 59:
210  case 60:
211  case 61:
212  case 62:
213  case 63:
214  case 64:
215  case 65:
216  case 66:
217  case 67:
218  break;
219 
220  case 68:
221  dashPattern << 10 << 5;
222  break;
223 
224  case 69:
225  case 70:
226  break;
227 
228  case 71:
229  dashPattern << 12 << 20;
230  break;
231 
232  case 72:
233  dashPattern << 20 << 8;
234  break;
235 
236  case 73:
237  case 74:
238  case 75:
239  case 76:
240  case 77:
241  case 78:
242  case 79:
243  case 80:
244  case 81:
245  break;
246 
247  case 83:
248  case 91:
249  case 99:
250  case 107:
251  dashPattern << 0 << 4 << 1 << 4;
252  patternOffset = 2;
253  break;
254 
255  case 84:
256  case 85:
257  case 86:
258  case 87:
259  case 88:
260  case 89:
261  case 92:
262  case 93:
263  case 94:
264  case 95:
265  case 96:
266  case 97:
267  case 100:
268  case 101:
269  case 102:
270  case 103:
271  case 104:
272  case 105:
273  case 108:
274  case 109:
275  break;
276 
277  case 110:
278  case 111:
279  case 112:
280  case 113:
281  // these four are zig-zaggy patterns which can't be reproduced in QGIS!
282  context.pushWarning( QObject::tr( "The line style is not supported in QGIS" ) );
283  return nullptr;
284 
285  case 114:
286  case 115:
287  case 116:
288  simpleLine->setWidth( simpleLine->width() * 2 );
289  break;
290 
291  case 117:
292  case 118:
293  break;
294 
295  default:
296  QgsDebugMsg( QStringLiteral( "Unknown line symbol identifier %1" ).arg( identifier ) );
297  return nullptr;
298  }
299 
300  if ( !dashPattern.isEmpty() )
301  {
302  // scale dash pattern -- sizes above expect a 1 pt width line
303  for ( int i = 0; i < dashPattern.size() ; ++i )
304  dashPattern[ i ] *= size;
305 
306  simpleLine->setCustomDashVector( dashPattern );
307  simpleLine->setUseCustomDashPattern( true );
308  simpleLine->setCustomDashPatternUnit( sizeUnit );
309 
310  simpleLine->setDashPatternOffset( patternOffset * size );
311  simpleLine->setDashPatternOffsetUnit( sizeUnit );
312  }
313 
314  std::unique_ptr< QgsLineSymbol > symbol = std::make_unique< QgsLineSymbol >( QgsSymbolLayerList() << simpleLine.release() );
315 
316  if ( ( identifier >= 26 && identifier < 29 ) || ( identifier >= 31 && identifier < 34 ) || ( identifier >= 36 && identifier < 38 ) || ( identifier >= 47 && identifier <= 53 ) || identifier == 118 )
317  {
318  std::unique_ptr< QgsHashedLineSymbolLayer > hash = std::make_unique< QgsHashedLineSymbolLayer >();
319 
320  double spacing = 1;
321  double offset = 1;
322  double lineOffset = 0;
323  double length = 3.5;
324  switch ( identifier )
325  {
326  case 26:
327  spacing = 10;
328  offset = 5;
329  length = 3.5;
330  break;
331 
332  case 27:
333  spacing = 16;
334  offset = 5;
335  length = 3.5;
336  break;
337 
338  case 28:
339  case 31:
340  spacing = 24;
341  offset = 5;
342  length = 3.5;
343  break;
344 
345  case 32:
346  case 33:
347  spacing = 22;
348  offset = 9;
349  length = 3.5;
350  break;
351 
352  case 36:
353  spacing = 11;
354  offset = 0;
355  length = 2;
356  break;
357 
358  case 37:
359  spacing = 22;
360  offset = 0;
361  length = 2;
362  break;
363 
364  case 47:
365  spacing = 12;
366  offset = 0;
367  length = 2;
368  break;
369 
370  case 48:
371  spacing = 3;
372  offset = 0;
373  lineOffset = -1.5;
374  length = 3;
375  break;
376 
377  case 49:
378  spacing = 3;
379  offset = 0;
380  lineOffset = 1.5;
381  length = 3;
382  break;
383 
384  case 50:
385  spacing = 6;
386  offset = 0;
387  lineOffset = -1.5;
388  length = 3;
389  break;
390 
391  case 51:
392  spacing = 6;
393  offset = 0;
394  lineOffset = 1.5;
395  length = 3;
396  break;
397 
398  case 52:
399  spacing = 19;
400  offset = 5;
401  lineOffset = -1;
402  length = 2;
403  break;
404 
405  case 53:
406  spacing = 19;
407  offset = 5;
408  lineOffset = 1;
409  length = 2;
410  break;
411 
412  case 118:
413  spacing = 5;
414  offset = 0;
415  lineOffset = 0;
416  length = 8;
417  break;
418 
419  default:
420  break;
421  }
422 
423  hash->setInterval( spacing * size );
424  hash->setIntervalUnit( sizeUnit );
425 
426  hash->setOffset( lineOffset * size );
427  hash->setOffsetUnit( sizeUnit );
428 
429  hash->setOffsetAlongLine( offset * size );
430  hash->setOffsetAlongLineUnit( sizeUnit );
431 
432  hash->setHashLength( length * size );
433  hash->setHashLengthUnit( sizeUnit );
434 
435  std::unique_ptr< QgsSimpleLineSymbolLayer > subSimpleLine = std::make_unique< QgsSimpleLineSymbolLayer >( foreColor, size );
436  subSimpleLine->setWidthUnit( sizeUnit );
437  subSimpleLine->setPenCapStyle( Qt::RoundCap );
438  subSimpleLine->setPenJoinStyle( Qt::RoundJoin );
439 
440  std::unique_ptr< QgsLineSymbol > subSymbol = std::make_unique< QgsLineSymbol >( QgsSymbolLayerList() << subSimpleLine.release() );
441  hash->setSubSymbol( subSymbol.release() );
442 
443  if ( identifier == 31 || identifier == 33 )
444  {
445  std::unique_ptr< QgsHashedLineSymbolLayer > hash2( hash->clone() );
446  hash->setOffsetAlongLine( hash->offsetAlongLine() - size );
447  hash2->setOffsetAlongLine( hash2->offsetAlongLine() + size );
448  symbol->appendSymbolLayer( hash2.release() );
449  }
450  else if ( identifier == 36 || identifier == 37 )
451  {
452  std::unique_ptr< QgsHashedLineSymbolLayer > hash2( hash->clone() );
453  hash2->setOffsetAlongLine( dashPattern.at( 0 ) );
454  symbol->appendSymbolLayer( hash2.release() );
455  }
456  else if ( identifier == 52 || identifier == 53 )
457  {
458  std::unique_ptr< QgsHashedLineSymbolLayer > hash2( hash->clone() );
459  hash2->setOffsetAlongLine( hash->offsetAlongLine() * 2 );
460  symbol->appendSymbolLayer( hash2.release() );
461  }
462  else if ( identifier == 118 )
463  {
464  qgis::down_cast< QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->setColor( QColor( 0, 0, 0 ) );
465  qgis::down_cast< QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->setWidth( 0 );
466  symbol->symbolLayer( 0 )->setLocked( true );
467 
468  std::unique_ptr<QgsSimpleLineSymbolLayer > secondRail( qgis::down_cast< QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->clone() );
469  const double offset = 2 * size;
470  qgis::down_cast< QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->setOffset( offset );
471  qgis::down_cast< QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->setOffsetUnit( sizeUnit );
472  secondRail->setOffset( -offset );
473  secondRail->setOffsetUnit( sizeUnit );
474 
475  secondRail->setLocked( true );
476  symbol->appendSymbolLayer( secondRail.release() );
477  }
478  symbol->appendSymbolLayer( hash.release() );
479  }
480  else if ( ( identifier >= 29 && identifier < 31 ) || ( identifier >= 34 && identifier < 36 ) )
481  {
482  double spacing = 1;
483  double offset = 1;
484  switch ( identifier )
485  {
486  case 29:
487  case 30:
488  spacing = 10;
489  offset = 5;
490  break;
491 
492  case 34:
493  case 35:
494  spacing = 22;
495  offset = 9;
496  break;
497 
498  default:
499  break;
500  }
501 
502  std::unique_ptr< QgsHashedLineSymbolLayer > hash = std::make_unique< QgsHashedLineSymbolLayer >();
503  hash->setInterval( spacing * size * 2 );
504  hash->setIntervalUnit( sizeUnit );
505 
506  hash->setOffsetAlongLine( offset * size );
507  hash->setOffsetAlongLineUnit( sizeUnit );
508 
509  hash->setHashLength( 3.5 * size * 0.5 );
510  hash->setHashLengthUnit( sizeUnit );
511 
512  std::unique_ptr< QgsSimpleLineSymbolLayer > subSimpleLine = std::make_unique< QgsSimpleLineSymbolLayer >( foreColor, size );
513  subSimpleLine->setWidthUnit( sizeUnit );
514  subSimpleLine->setPenCapStyle( Qt::RoundCap );
515  subSimpleLine->setPenJoinStyle( Qt::RoundJoin );
516 
517  std::unique_ptr< QgsLineSymbol > subSymbol = std::make_unique< QgsLineSymbol >( QgsSymbolLayerList() << subSimpleLine.release() );
518  hash->setSubSymbol( subSymbol.release() );
519  std::unique_ptr< QgsHashedLineSymbolLayer > hash2( hash->clone() );
520 
521  hash->setOffset( -hash->hashLength() );
522  hash->setOffsetUnit( hash->hashLengthUnit() );
523  hash2->setOffset( hash->hashLength() );
524  hash2->setOffsetUnit( hash->hashLengthUnit() );
525  hash2->setOffsetAlongLine( hash2->offsetAlongLine() + hash2->interval() * 0.5 );
526 
527  switch ( identifier )
528  {
529  case 29:
530  case 34:
531  symbol->appendSymbolLayer( hash.release() );
532  symbol->appendSymbolLayer( hash2.release() );
533  break;
534 
535  case 30:
536  case 35:
537  {
538  std::unique_ptr< QgsHashedLineSymbolLayer > hash3( hash->clone() );
539  std::unique_ptr< QgsHashedLineSymbolLayer > hash4( hash2->clone() );
540 
541  hash->setOffsetAlongLine( hash->offsetAlongLine() - size );
542  hash3->setOffsetAlongLine( hash3->offsetAlongLine() + size );
543  hash2->setOffsetAlongLine( hash2->offsetAlongLine() - size );
544  hash4->setOffsetAlongLine( hash4->offsetAlongLine() + size );
545 
546  symbol->appendSymbolLayer( hash.release() );
547  symbol->appendSymbolLayer( hash2.release() );
548  symbol->appendSymbolLayer( hash3.release() );
549  symbol->appendSymbolLayer( hash4.release() );
550  break;
551  }
552  }
553  }
554  else if ( ( identifier >= 38 && identifier < 41 ) || ( identifier >= 54 && identifier <= 61 ) || ( identifier >= 78 && identifier <= 109 ) || ( identifier >= 114 && identifier <= 117 ) )
555  {
556  std::unique_ptr< QgsMarkerLineSymbolLayer > marker = std::make_unique< QgsMarkerLineSymbolLayer >();
557 
558  double spacing = 1;
559  double offset = 1;
560  double markerSize = 1;
561  double angle = 0;
562  double lineOffset = 0;
565  switch ( identifier )
566  {
567  case 38:
568  spacing = 35;
569  offset = 25;
570  markerSize = 3;
572  break;
573 
574  case 39:
575  spacing = 35;
576  offset = 27.5;
577  markerSize = 3;
579  break;
580 
581  case 40:
582  spacing = 35;
583  offset = 27.5;
584  markerSize = 3.2;
586  break;
587 
588  case 54:
589  spacing = 12;
590  offset = 4;
591  markerSize = 6;
593  break;
594 
595  case 55:
596  spacing = 12;
597  offset = 0;
598  markerSize = 6;
600  angle = 180;
601  break;
602 
603  case 56:
604  spacing = 31;
605  offset = 4;
606  markerSize = 6;
608  angle = 180;
609  break;
610 
611  case 57:
612  spacing = 10;
613  offset = 4;
614  markerSize = 6;
616  break;
617 
618  case 58:
619  spacing = 10;
620  offset = 0;
621  markerSize = 6;
623  angle = 180;
624  break;
625 
626  case 59:
627  case 61:
628  offset = 0;
629  markerSize = 6;
632  break;
633 
634  case 60:
635  offset = 0;
636  markerSize = 6;
639  angle = 180;
640  break;
641 
642  case 78:
643  case 80:
644  offset = 2;
645  markerSize = 4;
648  angle = 0;
649  break;
650 
651  case 79:
652  offset = 2;
653  markerSize = 4;
656  angle = 0;
657  break;
658 
659  case 81:
660  case 82:
661  case 83:
662  case 84:
663  case 85:
664  spacing = 9;
665  offset = 2;
666  markerSize = 4;
669  angle = 0;
670  break;
671 
672  case 86:
673  case 88:
674  offset = 2;
675  markerSize = 4;
678  angle = 0;
679  break;
680 
681  case 87:
682  offset = 2;
683  markerSize = 4;
686  angle = 0;
687  break;
688 
689  case 89:
690  case 90:
691  case 91:
692  case 92:
693  case 93:
694  spacing = 9;
695  offset = 2;
696  markerSize = 4;
699  angle = 0;
700  break;
701 
702  case 94:
703  case 96:
704  offset = 2;
705  markerSize = 4;
708  angle = 0;
709  break;
710 
711  case 95:
712  offset = 2;
713  markerSize = 4;
716  angle = 180;
717  break;
718 
719  case 97:
720  case 98:
721  case 99:
722  case 100:
723  case 101:
724  spacing = 9;
725  offset = 2;
726  markerSize = 4;
729  angle = 0;
730  break;
731 
732  case 102:
733  case 104:
734  offset = 2;
735  markerSize = 4;
738  angle = 0;
739  break;
740 
741  case 103:
742  offset = 2;
743  markerSize = 4;
746  angle = 180;
747  break;
748 
749  case 105:
750  case 106:
751  case 107:
752  case 108:
753  case 109:
754  spacing = 9;
755  offset = 2;
756  markerSize = 4;
759  angle = 0;
760  break;
761 
762  case 114:
763  spacing = 18;
764  offset = 9;
765  markerSize = 8;
768  angle = 0;
769  lineOffset = -0.8;
770  break;
771 
772  case 115:
773  spacing = 16;
774  offset = 8;
775  markerSize = 8;
778  angle = 0;
779  lineOffset = -2;
780  break;
781 
782  case 116:
783  spacing = 23;
784  offset = 8;
785  markerSize = 8;
788  angle = 0;
789  lineOffset = -0.8;
790  break;
791 
792  case 117:
793  spacing = 9;
794  offset = 2;
795  markerSize = 4;
798  angle = 0;
799  lineOffset = -2;
800  break;
801 
802  default:
803  break;
804  }
805 
806  if ( identifier >= 78 && identifier <= 109 )
807  {
808  qgis::down_cast< QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->setColor( QColor( 0, 0, 0 ) );
809  qgis::down_cast< QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->setWidth( 0 );
810  symbol->symbolLayer( 0 )->setLocked( true );
811 
812  if ( ( identifier >= 84 && identifier <= 85 ) || ( identifier >= 92 && identifier <= 93 ) || ( identifier >= 100 && identifier <= 101 ) || ( identifier >= 108 && identifier <= 109 ) )
813  {
814  std::unique_ptr<QgsSimpleLineSymbolLayer > secondRail( qgis::down_cast< QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->clone() );
815 
816  double offset = 2 * size;
817  if ( identifier == 85 || identifier == 93 || identifier == 101 || identifier == 109 )
818  offset = 3 * size;
819 
820  qgis::down_cast< QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->setOffset( offset );
821  qgis::down_cast< QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->setOffsetUnit( sizeUnit );
822  secondRail->setOffset( -offset );
823  secondRail->setOffsetUnit( sizeUnit );
824 
825  secondRail->setLocked( true );
826  symbol->appendSymbolLayer( secondRail.release() );
827  }
828  }
829 
830  marker->setPlacement( placement );
831  marker->setInterval( spacing * size );
832  marker->setIntervalUnit( sizeUnit );
833 
834  marker->setOffsetAlongLine( offset * size );
835  marker->setOffsetAlongLineUnit( sizeUnit );
836 
837  marker->setOffset( lineOffset * size );
838  marker->setOffsetUnit( sizeUnit );
839 
840  std::unique_ptr< QgsSimpleMarkerSymbolLayer > subSimpleMarker = std::make_unique< QgsSimpleMarkerSymbolLayer >( shape, markerSize * size );
841  subSimpleMarker->setColor( foreColor );
842  subSimpleMarker->setSizeUnit( sizeUnit );
843  subSimpleMarker->setStrokeWidth( size );
844  subSimpleMarker->setStrokeWidthUnit( sizeUnit );
845  subSimpleMarker->setAngle( angle );
846 
847  subSimpleMarker->setPenJoinStyle( Qt::RoundJoin );
848  subSimpleMarker->setPenCapStyle( Qt::RoundCap );
849 
855  {
856  subSimpleMarker->setStrokeStyle( Qt::NoPen );
857  }
858 
859  std::unique_ptr< QgsMarkerSymbol > subSymbol = std::make_unique< QgsMarkerSymbol >( QgsSymbolLayerList() << subSimpleMarker.release() );
860  marker->setSubSymbol( subSymbol.release() );
861 
862  if ( identifier == 56 )
863  {
864  std::unique_ptr< QgsMarkerLineSymbolLayer > marker2( marker->clone() );
865  marker2->setOffsetAlongLine( 19 * size );
866  qgis::down_cast< QgsMarkerSymbol * >( marker2->subSymbol() )->setAngle( 0 );
867  symbol->appendSymbolLayer( marker2.release() );
868  }
869  else if ( identifier == 61 )
870  {
871  std::unique_ptr< QgsMarkerLineSymbolLayer > marker2( marker->clone() );
872  marker2->setPlacement( QgsMarkerLineSymbolLayer::FirstVertex );
873  qgis::down_cast< QgsMarkerSymbol * >( marker2->subSymbol() )->setAngle( 180 );
874  symbol->appendSymbolLayer( marker2.release() );
875  }
876  else if ( identifier == 80 || identifier == 88 || identifier == 96 || identifier == 104 )
877  {
878  std::unique_ptr< QgsMarkerLineSymbolLayer > marker2( marker->clone() );
879  marker2->setPlacement( QgsMarkerLineSymbolLayer::LastVertex );
880  qgis::down_cast< QgsMarkerSymbol * >( marker2->subSymbol() )->setAngle( 180 );
881  symbol->appendSymbolLayer( marker2.release() );
882  }
883 
884  if ( identifier == 116 )
885  {
886  std::unique_ptr< QgsMarkerLineSymbolLayer > marker2( marker->clone() );
887 
888  qgis::down_cast< QgsSimpleMarkerSymbolLayer * >( marker2->subSymbol()->symbolLayer( 0 ) )->setShape( QgsSimpleMarkerSymbolLayer::EquilateralTriangle );
889  marker2->setOffsetAlongLine( 16 * size );
890  marker2->setOffset( -1.5 * size );
891  symbol->appendSymbolLayer( marker2.release() );
892  }
893 
894  symbol->appendSymbolLayer( marker.release() );
895  }
896  else if ( identifier >= 41 && identifier < 45 )
897  {
898  const int count = identifier - 40;
899  QgsSimpleLineSymbolLayer *simpleLine = dynamic_cast< QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) );
900  simpleLine->setCustomDashVector( QVector< qreal >() << 0 << 5.25 * size << 4 * size << ( 3.25 * size + ( count - 1 ) * ( 7.25 * size ) ) );
901  simpleLine->setCustomDashPatternUnit( sizeUnit );
902  simpleLine->setUseCustomDashPattern( true );
903 
904  for ( int i = 1 ; i < count; ++i )
905  {
906  std::unique_ptr< QgsSimpleLineSymbolLayer > dashLine( simpleLine->clone() );
907 
908  dashLine->setCustomDashVector( QVector< qreal >() << 0 << 5.25 * size + ( i * 7.25 * size ) << 4 * size << ( 3.25 * size + ( count - 1 - i ) * ( 7.25 * size ) ) );
909  symbol->appendSymbolLayer( dashLine.release() );
910  }
911 
912  std::unique_ptr< QgsSimpleLineSymbolLayer > simpleLine2 = std::make_unique< QgsSimpleLineSymbolLayer >( foreColor, 1.6 * size );
913  simpleLine2->setWidthUnit( sizeUnit );
914  simpleLine2->setPenCapStyle( Qt::RoundCap );
915  simpleLine2->setPenJoinStyle( Qt::RoundJoin );
916 
917  simpleLine2->setCustomDashVector( QVector< qreal >() << 2 * size << 10.5 * size + ( count - 1 ) * ( 7.25 * size ) );
918  simpleLine2->setUseCustomDashPattern( true );
919  simpleLine2->setCustomDashPatternUnit( sizeUnit );
920 
921  symbol->appendSymbolLayer( simpleLine2.release() );
922  }
923  else if ( identifier == 45 )
924  {
925  std::unique_ptr< QgsSimpleLineSymbolLayer > simpleLine2 = std::make_unique< QgsSimpleLineSymbolLayer >( foreColor, 1.6 * size );
926  simpleLine2->setWidthUnit( sizeUnit );
927  simpleLine2->setPenCapStyle( Qt::RoundCap );
928  simpleLine2->setPenJoinStyle( Qt::RoundJoin );
929 
930  simpleLine2->setCustomDashVector( QVector< qreal >() << 0 << 2 * size << 1.25 * size << 6.5 * size );
931  simpleLine2->setUseCustomDashPattern( true );
932  simpleLine2->setCustomDashPatternUnit( sizeUnit );
933 
934  symbol->appendSymbolLayer( simpleLine2.release() );
935  }
936  else if ( identifier == 46 )
937  {
938  std::unique_ptr< QgsHashedLineSymbolLayer > hashLine = std::make_unique< QgsHashedLineSymbolLayer >();
939 
940  hashLine->setInterval( 4 * size );
941  hashLine->setIntervalUnit( sizeUnit );
942  hashLine->setOffsetAlongLine( 2 * size );
943  hashLine->setOffsetAlongLineUnit( sizeUnit );
944  hashLine->setHashLength( 3.8 * size );
945  hashLine->setHashLengthUnit( sizeUnit );
946 
947  hashLine->setSubSymbol( symbol.release() );
948 
949  symbol = std::make_unique< QgsLineSymbol >( QgsSymbolLayerList() << hashLine.release() );
950  }
951  else if ( identifier == 62 )
952  {
953  std::unique_ptr< QgsMarkerLineSymbolLayer > markerLine = std::make_unique< QgsMarkerLineSymbolLayer >();
954  markerLine->setPlacement( QgsMarkerLineSymbolLayer::FirstVertex );
955  markerLine->setOffsetAlongLine( 2 * size );
956  markerLine->setOffsetAlongLineUnit( sizeUnit );
957 
958  std::unique_ptr< QgsSimpleMarkerSymbolLayer > subSimpleMarker = std::make_unique< QgsSimpleMarkerSymbolLayer >( QgsSimpleMarkerSymbolLayer::Line, size * 4 );
959  subSimpleMarker->setColor( foreColor );
960  subSimpleMarker->setSizeUnit( sizeUnit );
961  subSimpleMarker->setStrokeWidth( 1.25 * size );
962  subSimpleMarker->setStrokeWidthUnit( sizeUnit );
963  subSimpleMarker->setAngle( 90 );
964 
965  subSimpleMarker->setPenJoinStyle( Qt::RoundJoin );
966  subSimpleMarker->setPenCapStyle( Qt::RoundCap );
967 
968  std::unique_ptr< QgsMarkerSymbol > subSymbol = std::make_unique< QgsMarkerSymbol >( QgsSymbolLayerList() << subSimpleMarker.release() );
969  markerLine->setSubSymbol( subSymbol.release() );
970 
971  symbol->appendSymbolLayer( markerLine.release() );
972  }
973  else if ( ( identifier >= 63 && identifier <= 69 ) || ( identifier >= 72 && identifier <= 77 ) )
974  {
975  std::unique_ptr< QgsSimpleLineSymbolLayer > upperLine( qgis::down_cast< QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->clone() );
976  upperLine->setUseCustomDashPattern( false );
977 
978  if ( identifier < 65 || ( identifier >= 68 && identifier <= 69 ) || identifier == 73 )
979  {
980  upperLine->setColor( QColor( 255, 255, 255 ) );
981  upperLine->setLocked( true );
982  }
983  else if ( identifier < 67 || identifier == 72 || identifier == 75 || identifier == 76 )
984  {
985  qgis::down_cast< QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->setColor( QColor( 0, 0, 0 ) );
986  symbol->symbolLayer( 0 )->setLocked( true );
987  }
988  else if ( identifier <= 69 || identifier == 77 )
989  {
990  upperLine->setColor( QColor( 0, 0, 0 ) );
991  upperLine->setLocked( true );
992  }
993  upperLine->setWidth( upperLine->width() * 0.9 );
994  if ( interleaved )
995  {
996  upperLine->setRenderingPass( 1 );
997  }
998 
999  if ( identifier >= 73 && identifier <= 75 )
1000  {
1001  upperLine->setCustomDashVector( QVector< qreal >() << 0 << 10 * size << 12 * size << 2 * size );
1002  upperLine->setUseCustomDashPattern( true );
1003  upperLine->setCustomDashPatternUnit( sizeUnit );
1004  }
1005  else if ( identifier == 76 )
1006  {
1007  upperLine->setCustomDashVector( QVector< qreal >() << 0 << 10 * size << 24 * size << 14 * size );
1008  upperLine->setUseCustomDashPattern( true );
1009  upperLine->setCustomDashPatternUnit( sizeUnit );
1010  }
1011 
1012  if ( identifier == 75 || identifier == 76 )
1013  {
1014  std::unique_ptr< QgsSimpleLineSymbolLayer > middleLine = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 255, 255, 255 ), upperLine->width() );
1015  middleLine->setWidthUnit( sizeUnit );
1016  middleLine->setLocked( true );
1017  middleLine->setPenCapStyle( Qt::RoundCap );
1018  middleLine->setPenJoinStyle( Qt::RoundJoin );
1019 
1020  if ( interleaved )
1021  {
1022  middleLine->setRenderingPass( 1 );
1023  upperLine->setRenderingPass( 2 );
1024  }
1025  symbol->appendSymbolLayer( middleLine.release() );
1026  }
1027 
1028  symbol->appendSymbolLayer( upperLine.release() );
1029 
1030  if ( identifier == 64 || identifier == 66 )
1031  {
1032  std::unique_ptr< QgsSimpleLineSymbolLayer > middleLine = std::make_unique< QgsSimpleLineSymbolLayer >( identifier == 64 ? foreColor : QColor( 0, 0, 0 ), 0 );
1033  if ( identifier == 66 )
1034  middleLine->setLocked( true );
1035 
1036  if ( interleaved )
1037  {
1038  middleLine->setRenderingPass( 2 );
1039  }
1040  symbol->appendSymbolLayer( middleLine.release() );
1041  }
1042 
1043  else if ( identifier == 69 )
1044  {
1045  std::unique_ptr< QgsHashedLineSymbolLayer > hashedLine = std::make_unique< QgsHashedLineSymbolLayer >();
1046 
1047  std::unique_ptr< QgsSimpleLineSymbolLayer > middleLine = std::make_unique< QgsSimpleLineSymbolLayer >( foreColor, 0 );
1048  hashedLine->setSubSymbol( new QgsLineSymbol( { middleLine.release() } ) );
1049  hashedLine->setInterval( 18 * size );
1050  hashedLine->setIntervalUnit( sizeUnit );
1051  hashedLine->setOffsetAlongLine( 4 * size );
1052  hashedLine->setOffsetAlongLineUnit( sizeUnit );
1053  hashedLine->setHashLength( 8 * size );
1054  hashedLine->setHashLengthUnit( sizeUnit );
1055 
1056  if ( interleaved )
1057  {
1058  hashedLine->setRenderingPass( 2 );
1059  }
1060  symbol->appendSymbolLayer( hashedLine.release() );
1061  }
1062  else if ( identifier == 77 )
1063  {
1064  std::unique_ptr< QgsSimpleLineSymbolLayer > middleLine = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 255, 255, 255 ), qgis::down_cast< QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 1 ) )->width() );
1065  middleLine->setWidthUnit( sizeUnit );
1066  middleLine->setLocked( true );
1067  middleLine->setPenCapStyle( Qt::RoundCap );
1068  middleLine->setPenJoinStyle( Qt::RoundJoin );
1069  middleLine->setCustomDashVector( QVector< qreal >() << 0 << 10 * size << 12 * size << 2 * size );
1070  middleLine->setUseCustomDashPattern( true );
1071  middleLine->setCustomDashPatternUnit( sizeUnit );
1072  if ( interleaved )
1073  {
1074  middleLine->setRenderingPass( 2 );
1075  }
1076  symbol->appendSymbolLayer( middleLine.release() );
1077  }
1078  }
1079  else if ( identifier >= 70 && identifier <= 71 )
1080  {
1081  qgis::down_cast< QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->setColor( QColor( 0, 0, 0 ) );
1082  qgis::down_cast< QgsSimpleLineSymbolLayer * >( symbol->symbolLayer( 0 ) )->setLocked( true );
1083 
1084  std::unique_ptr< QgsSimpleLineSymbolLayer > simpleLine2 = std::make_unique< QgsSimpleLineSymbolLayer >( foreColor, size );
1085  simpleLine2->setWidthUnit( sizeUnit );
1086  simpleLine2->setPenCapStyle( Qt::RoundCap );
1087  simpleLine2->setPenJoinStyle( Qt::RoundJoin );
1088 
1089  if ( identifier == 70 )
1090  simpleLine2->setCustomDashVector( QVector< qreal >() << 0 << 12 * size << 12 * size << 0 );
1091  else if ( identifier == 71 )
1092  simpleLine2->setCustomDashVector( QVector< qreal >() << 0 << 16 * size << 12 * size << 4 * size );
1093 
1094  simpleLine2->setUseCustomDashPattern( true );
1095  simpleLine2->setCustomDashPatternUnit( sizeUnit );
1096 
1097  symbol->appendSymbolLayer( simpleLine2.release() );
1098  }
1099 
1100  return symbol.release();
1101 }
1102 
1103 QgsFillSymbol *QgsMapInfoSymbolConverter::convertFillSymbol( int identifier, QgsMapInfoSymbolConversionContext &context, const QColor &foreColor, const QColor &backColor )
1104 {
1105  Qt::BrushStyle style = Qt::SolidPattern;
1106 
1107  bool useLineFill = false;
1108  bool crossFill = false;
1109  double lineAngle = 0;
1110  double lineWidth = 0;
1111  double lineSpacing = 1;
1112  switch ( identifier )
1113  {
1114  case 0:
1115  case 1:
1116  style = Qt::NoBrush;
1117  break;
1118 
1119  case 2:
1120  style = Qt::SolidPattern;
1121  break;
1122 
1123  case 3:
1124  case 19:
1125  style = Qt::HorPattern;
1126  break;
1127 
1128  case 4:
1129  case 24:
1130  style = Qt::VerPattern;
1131  break;
1132 
1133  case 5:
1134  case 34:
1135  style = Qt::FDiagPattern;
1136  break;
1137 
1138  case 6:
1139  case 29:
1140  style = Qt::BDiagPattern;
1141  break;
1142 
1143  case 7:
1144  case 39:
1145  style = Qt::CrossPattern;
1146  break;
1147 
1148  case 8:
1149  case 44:
1150  style = Qt::DiagCrossPattern;
1151  break;
1152 
1153  case 12:
1154  style = Qt::Dense1Pattern;
1155  break;
1156 
1157  case 13:
1158  style = Qt::Dense2Pattern;
1159  break;
1160 
1161  case 14:
1162  style = Qt::Dense3Pattern;
1163  break;
1164 
1165  case 15:
1166  style = Qt::Dense4Pattern;
1167  break;
1168 
1169  case 16:
1170  style = Qt::Dense5Pattern;
1171  break;
1172 
1173  case 17:
1174  style = Qt::Dense6Pattern;
1175  break;
1176 
1177  case 18:
1178  style = Qt::Dense7Pattern;
1179  break;
1180 
1181  case 20:
1182  useLineFill = true;
1183  lineAngle = 0;
1184  lineSpacing = 6;
1185  lineWidth = 1.2;
1186  break;
1187 
1188  case 21:
1189  useLineFill = true;
1190  lineAngle = 0;
1191  lineSpacing = 4;
1192  lineWidth = 0.8;
1193  break;
1194 
1195  case 22:
1196  useLineFill = true;
1197  lineAngle = 0;
1198  lineSpacing = 3.4;
1199  lineWidth = 1.2;
1200  break;
1201 
1202  case 23:
1203  useLineFill = true;
1204  lineAngle = 0;
1205  lineSpacing = 3.0;
1206  lineWidth = 1.0;
1207  break;
1208 
1209  case 25:
1210  useLineFill = true;
1211  lineAngle = 90;
1212  lineSpacing = 6;
1213  lineWidth = 1.2;
1214  break;
1215 
1216  case 26:
1217  useLineFill = true;
1218  lineAngle = 90;
1219  lineSpacing = 4;
1220  lineWidth = 0.8;
1221  break;
1222 
1223  case 27:
1224  useLineFill = true;
1225  lineAngle = 90;
1226  lineSpacing = 3.4;
1227  lineWidth = 1.2;
1228  break;
1229 
1230  case 28:
1231  useLineFill = true;
1232  lineAngle = 90;
1233  lineSpacing = 3.0;
1234  lineWidth = 1.0;
1235  break;
1236 
1237  case 30:
1238  useLineFill = true;
1239  lineAngle = 45;
1240  lineSpacing = 6;
1241  lineWidth = 1.2;
1242  break;
1243 
1244  case 31:
1245  useLineFill = true;
1246  lineAngle = 45;
1247  lineSpacing = 4;
1248  lineWidth = 0.8;
1249  break;
1250 
1251  case 32:
1252  useLineFill = true;
1253  lineAngle = 45;
1254  lineSpacing = 3.4;
1255  lineWidth = 1.2;
1256  break;
1257 
1258  case 33:
1259  useLineFill = true;
1260  lineAngle = 45;
1261  lineSpacing = 3.0;
1262  lineWidth = 1.0;
1263  break;
1264 
1265  case 35:
1266  useLineFill = true;
1267  lineAngle = 135;
1268  lineSpacing = 6;
1269  lineWidth = 1.2;
1270  break;
1271 
1272  case 36:
1273  useLineFill = true;
1274  lineAngle = 135;
1275  lineSpacing = 4;
1276  lineWidth = 0.8;
1277  break;
1278 
1279  case 37:
1280  useLineFill = true;
1281  lineAngle = 135;
1282  lineSpacing = 3.4;
1283  lineWidth = 1.2;
1284  break;
1285 
1286  case 38:
1287  useLineFill = true;
1288  lineAngle = 135;
1289  lineSpacing = 3.0;
1290  lineWidth = 1.0;
1291  break;
1292 
1293  case 40:
1294  useLineFill = true;
1295  crossFill = true;
1296  lineAngle = 0;
1297  lineSpacing = 6;
1298  lineWidth = 1.2;
1299  break;
1300 
1301  case 41:
1302  useLineFill = true;
1303  crossFill = true;
1304  lineAngle = 0;
1305  lineSpacing = 4;
1306  lineWidth = 0.8;
1307  break;
1308 
1309  case 42:
1310  useLineFill = true;
1311  crossFill = true;
1312  lineAngle = 0;
1313  lineSpacing = 3.4;
1314  lineWidth = 1.2;
1315  break;
1316 
1317  case 43:
1318  useLineFill = true;
1319  crossFill = true;
1320  lineAngle = 0;
1321  lineSpacing = 3.0;
1322  lineWidth = 1.0;
1323  break;
1324 
1325  case 45:
1326  useLineFill = true;
1327  crossFill = true;
1328  lineAngle = 45;
1329  lineSpacing = 6;
1330  lineWidth = 1.2;
1331  break;
1332 
1333  case 46:
1334  useLineFill = true;
1335  crossFill = true;
1336  lineAngle = 45;
1337  lineSpacing = 4;
1338  lineWidth = 0.8;
1339  break;
1340 
1341  case 47:
1342  useLineFill = true;
1343  crossFill = true;
1344  lineAngle = 45;
1345  lineSpacing = 3.4;
1346  lineWidth = 1.2;
1347  break;
1348 
1349  default:
1350  context.pushWarning( QObject::tr( "The brush style is not supported in QGIS" ) );
1351  return nullptr;
1352  }
1353 
1354  QgsSymbolLayerList layers;
1355  if ( backColor.isValid() && style != Qt::SolidPattern && ( useLineFill || style != Qt::NoBrush ) )
1356  {
1357  std::unique_ptr< QgsSimpleFillSymbolLayer > backgroundFill = std::make_unique< QgsSimpleFillSymbolLayer >( backColor );
1358  backgroundFill->setLocked( true );
1359  backgroundFill->setStrokeStyle( Qt::NoPen );
1360  layers << backgroundFill.release();
1361  }
1362 
1363  if ( !useLineFill )
1364  {
1365  std::unique_ptr< QgsSimpleFillSymbolLayer > foregroundFill = std::make_unique< QgsSimpleFillSymbolLayer >( foreColor );
1366  foregroundFill->setBrushStyle( style );
1367  foregroundFill->setStrokeStyle( Qt::NoPen );
1368  layers << foregroundFill.release();
1369  }
1370  else
1371  {
1372  std::unique_ptr< QgsLinePatternFillSymbolLayer > lineFill = std::make_unique< QgsLinePatternFillSymbolLayer >();
1373 
1374  std::unique_ptr< QgsSimpleLineSymbolLayer > simpleLine = std::make_unique< QgsSimpleLineSymbolLayer >( foreColor, lineWidth );
1375  simpleLine->setWidthUnit( QgsUnitTypes::RenderPoints );
1376  lineFill->setSubSymbol( new QgsLineSymbol( QgsSymbolLayerList() << simpleLine.release() ) );
1377 
1378  lineFill->setDistance( lineSpacing );
1379  lineFill->setDistanceUnit( QgsUnitTypes::RenderPoints );
1380  lineFill->setLineAngle( lineAngle );
1381 
1382  if ( crossFill )
1383  {
1384  std::unique_ptr< QgsLinePatternFillSymbolLayer > lineFill2( lineFill->clone() );
1385  lineFill2->setLineAngle( lineFill->lineAngle() + 90 );
1386  layers << lineFill2.release();
1387  }
1388 
1389  layers << lineFill.release();
1390  }
1391  return new QgsFillSymbol( layers );
1392 }
1393 
1395 {
1397  bool isFilled = true;
1398  bool isNull = false;
1399  bool hasShadow = false;
1400  double angle = 0;
1402  QPointF shadowOffset;
1403  switch ( identifier )
1404  {
1405  case 31:
1406  // null symbol
1407  shape = QgsSimpleMarkerSymbolLayer::Shape::Square; // to initialize the variable
1408  isNull = true;
1409  break;
1410 
1411  case 32:
1412  shape = QgsSimpleMarkerSymbolLayer::Shape::Square;
1413  break;
1414 
1415  case 33:
1416  shape = QgsSimpleMarkerSymbolLayer::Shape::Diamond;
1417  break;
1418 
1419  case 34:
1420  shape = QgsSimpleMarkerSymbolLayer::Shape::Circle;
1421  break;
1422 
1423  case 35:
1424  shape = QgsSimpleMarkerSymbolLayer::Shape::Star;
1425  break;
1426 
1427  case 36:
1428  shape = QgsSimpleMarkerSymbolLayer::Shape::Triangle;
1429  break;
1430 
1431  case 37:
1432  shape = QgsSimpleMarkerSymbolLayer::Shape::Triangle;
1433  angle = 180;
1434  break;
1435 
1436  case 38:
1437  shape = QgsSimpleMarkerSymbolLayer::Shape::Square;
1438  isFilled = false;
1439  break;
1440 
1441  case 39:
1442  shape = QgsSimpleMarkerSymbolLayer::Shape::Diamond;
1443  isFilled = false;
1444  break;
1445 
1446  case 40:
1447  shape = QgsSimpleMarkerSymbolLayer::Shape::Circle;
1448  isFilled = false;
1449  break;
1450 
1451  case 41:
1452  shape = QgsSimpleMarkerSymbolLayer::Shape::Star;
1453  isFilled = false;
1454  break;
1455 
1456  case 42:
1457  shape = QgsSimpleMarkerSymbolLayer::Shape::Triangle;
1458  isFilled = false;
1459  break;
1460 
1461  case 43:
1462  shape = QgsSimpleMarkerSymbolLayer::Shape::Triangle;
1463  angle = 180;
1464  isFilled = false;
1465  break;
1466 
1467  case 44:
1468  shape = QgsSimpleMarkerSymbolLayer::Shape::Square;
1469  hasShadow = true;
1470  shadowOffset = QPointF( size * 0.1, size * 0.1 );
1471  break;
1472 
1473  case 45:
1474  shape = QgsSimpleMarkerSymbolLayer::Shape::Triangle;
1475  shadowOffset = QPointF( size * 0.2, size * 0.1 );
1476  hasShadow = true;
1477  break;
1478 
1479  case 46:
1480  shape = QgsSimpleMarkerSymbolLayer::Shape::Circle;
1481  shadowOffset = QPointF( size * 0.1, size * 0.1 );
1482  hasShadow = true;
1483  break;
1484 
1485  case 47:
1486  shape = QgsSimpleMarkerSymbolLayer::Shape::Arrow;
1487  size *= 0.66666;
1488  angle = 45;
1489  vertAlign = QgsMarkerSymbolLayer::Top;
1490  break;
1491 
1492  case 48:
1493  shape = QgsSimpleMarkerSymbolLayer::Shape::Arrow;
1494  size *= 0.66666;
1495  angle = 225;
1496  vertAlign = QgsMarkerSymbolLayer::Top;
1497  break;
1498 
1499  case 49:
1500  shape = QgsSimpleMarkerSymbolLayer::Shape::Cross;
1501  break;
1502 
1503  case 50:
1504  shape = QgsSimpleMarkerSymbolLayer::Shape::Cross2;
1505  break;
1506 
1507  case 51:
1508  shape = QgsSimpleMarkerSymbolLayer::Shape::Cross;
1509  break;
1510 
1511  default:
1512  context.pushWarning( QObject::tr( "The symbol is not supported in QGIS" ) );
1513  return nullptr;
1514  }
1515 
1516  std::unique_ptr< QgsSimpleMarkerSymbolLayer > simpleMarker = std::make_unique< QgsSimpleMarkerSymbolLayer >( shape, size );
1517  simpleMarker->setSizeUnit( sizeUnit );
1518  simpleMarker->setAngle( angle );
1519  simpleMarker->setVerticalAnchorPoint( vertAlign );
1520 
1521  if ( isNull )
1522  {
1523  simpleMarker->setFillColor( QColor( 0, 0, 0, 0 ) );
1524  simpleMarker->setStrokeStyle( Qt::NoPen );
1525  }
1526  else if ( isFilled && QgsSimpleMarkerSymbolLayer::shapeIsFilled( shape ) )
1527  {
1528  simpleMarker->setColor( color );
1529  simpleMarker->setStrokeColor( QColor( 0, 0, 0 ) );
1530  simpleMarker->setStrokeWidth( 0 );
1531  }
1532  else
1533  {
1534  simpleMarker->setFillColor( QColor( 0, 0, 0, 0 ) );
1535  simpleMarker->setStrokeColor( color );
1536  }
1537 
1538  QgsSymbolLayerList symbols;
1539  if ( hasShadow )
1540  {
1541  std::unique_ptr< QgsSimpleMarkerSymbolLayer > shadow( simpleMarker->clone() );
1542  shadow->setColor( QColor( 0, 0, 0 ) );
1543  shadow->setLocked( true );
1544  shadow->setOffset( shadowOffset );
1545  shadow->setOffsetUnit( sizeUnit );
1546 
1547  symbols << shadow.release();
1548  symbols << simpleMarker.release();
1549  }
1550  else
1551  {
1552  if ( identifier == 51 )
1553  {
1554  std::unique_ptr< QgsSimpleMarkerSymbolLayer > second( simpleMarker->clone() );
1555  second->setShape( QgsSimpleMarkerSymbolLayer::Shape::Cross2 );
1556  symbols << second.release();
1557  }
1558  symbols << simpleMarker.release();
1559  }
1560 
1561  return new QgsMarkerSymbol( symbols );
1562 }
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Definition: qgsfillsymbol.h:30
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgslinesymbol.h:30
Context for a MapInfo symbol conversion operation.
void pushWarning(const QString &warning)
Pushes a warning message generated during the conversion.
static QgsFillSymbol * convertFillSymbol(int identifier, QgsMapInfoSymbolConversionContext &context, const QColor &foreColor, const QColor &backColor=QColor())
Converts the MapInfo fill symbol with the specified identifier to a QgsFillSymbol.
static QgsLineSymbol * convertLineSymbol(int identifier, QgsMapInfoSymbolConversionContext &context, const QColor &foreColor, double size, QgsUnitTypes::RenderUnit sizeUnit, bool interleaved=false)
Converts the MapInfo line symbol with the specified identifier to a QgsLineSymbol.
static QgsMarkerSymbol * convertMarkerSymbol(int identifier, QgsMapInfoSymbolConversionContext &context, const QColor &color, double size, QgsUnitTypes::RenderUnit sizeUnit)
Converts the MapInfo marker symbol with the specified identifier to a QgsMarkerSymbol.
VerticalAnchorPoint
Symbol vertical anchor points.
@ VCenter
Align to vertical center of symbol.
@ Top
Align to top of symbol.
A marker symbol type, for rendering Point and MultiPoint geometries.
A simple line symbol layer, which renders lines using a line in a variety of styles (e....
void setCustomDashPatternUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for lengths used in the custom dash pattern.
void setUseCustomDashPattern(bool b)
Sets whether the line uses a custom dash pattern.
void setCustomDashVector(const QVector< qreal > &vector)
Sets the custom dash vector, which is the pattern of alternating drawn/skipped lengths used while ren...
QgsSimpleLineSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
static bool shapeIsFilled(QgsSimpleMarkerSymbolLayerBase::Shape shape)
Returns true if a symbol shape has a fill.
@ ArrowHead
Right facing arrow head (unfilled, lines only)
@ Octagon
Octagon (since QGIS 3.18)
@ Cross2
Rotated cross (lines only), "x" shape.
@ EquilateralTriangle
Equilateral triangle.
@ SemiCircle
Semi circle (top half)
Placement
Defines how/where the templated symbol should be placed on the line.
@ LastVertex
Place symbols on the last vertex in the line.
@ FirstVertex
Place symbols on the first vertex in the line.
@ Interval
Place symbols at regular intervals.
RenderUnit
Rendering size units.
Definition: qgsunittypes.h:168
@ RenderPoints
Points (e.g., for font sizes)
Definition: qgsunittypes.h:173
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
Definition: MathUtils.cpp:786
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QList< QgsSymbolLayer * > QgsSymbolLayerList
Definition: qgssymbol.h:27