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 
16 #include "qgsmapinfosymbolconverter.h"
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 //
pushWarning(const QString & warning)29 void QgsMapInfoSymbolConversionContext::pushWarning( const QString &warning )
30 {
31   QgsDebugMsg( warning );
32   mWarnings << warning;
33 }
34 
35 
convertLineSymbol(int identifier,QgsMapInfoSymbolConversionContext & context,const QColor & foreColor,double size,QgsUnitTypes::RenderUnit sizeUnit,bool interleaved)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;
563     QgsMarkerLineSymbolLayer::Placement placement = QgsMarkerLineSymbolLayer::Interval;
564     QgsSimpleMarkerSymbolLayerBase::Shape shape = QgsSimpleMarkerSymbolLayerBase::Circle;
565     switch ( identifier )
566     {
567       case 38:
568         spacing = 35;
569         offset = 25;
570         markerSize = 3;
571         shape = QgsSimpleMarkerSymbolLayer::Cross2;
572         break;
573 
574       case 39:
575         spacing = 35;
576         offset = 27.5;
577         markerSize = 3;
578         shape = QgsSimpleMarkerSymbolLayer::Cross2;
579         break;
580 
581       case 40:
582         spacing = 35;
583         offset = 27.5;
584         markerSize = 3.2;
585         shape = QgsSimpleMarkerSymbolLayer::Cross;
586         break;
587 
588       case 54:
589         spacing = 12;
590         offset = 4;
591         markerSize = 6;
592         shape = QgsSimpleMarkerSymbolLayer::ArrowHead;
593         break;
594 
595       case 55:
596         spacing = 12;
597         offset = 0;
598         markerSize = 6;
599         shape = QgsSimpleMarkerSymbolLayer::ArrowHead;
600         angle = 180;
601         break;
602 
603       case 56:
604         spacing = 31;
605         offset = 4;
606         markerSize = 6;
607         shape = QgsSimpleMarkerSymbolLayer::ArrowHead;
608         angle = 180;
609         break;
610 
611       case 57:
612         spacing = 10;
613         offset = 4;
614         markerSize = 6;
615         shape = QgsSimpleMarkerSymbolLayer::ArrowHead;
616         break;
617 
618       case 58:
619         spacing = 10;
620         offset = 0;
621         markerSize = 6;
622         shape = QgsSimpleMarkerSymbolLayer::ArrowHead;
623         angle = 180;
624         break;
625 
626       case 59:
627       case 61:
628         offset = 0;
629         markerSize = 6;
630         shape = QgsSimpleMarkerSymbolLayer::ArrowHead;
631         placement = QgsMarkerLineSymbolLayer::LastVertex;
632         break;
633 
634       case 60:
635         offset = 0;
636         markerSize = 6;
637         shape = QgsSimpleMarkerSymbolLayer::ArrowHead;
638         placement = QgsMarkerLineSymbolLayer::FirstVertex;
639         angle = 180;
640         break;
641 
642       case 78:
643       case 80:
644         offset = 2;
645         markerSize = 4;
646         shape = QgsSimpleMarkerSymbolLayer::Octagon;
647         placement = QgsMarkerLineSymbolLayer::FirstVertex;
648         angle = 0;
649         break;
650 
651       case 79:
652         offset = 2;
653         markerSize = 4;
654         shape = QgsSimpleMarkerSymbolLayer::Octagon;
655         placement = QgsMarkerLineSymbolLayer::LastVertex;
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;
667         shape = QgsSimpleMarkerSymbolLayer::Octagon;
668         placement = QgsMarkerLineSymbolLayer::Interval;
669         angle = 0;
670         break;
671 
672       case 86:
673       case 88:
674         offset = 2;
675         markerSize = 4;
676         shape = QgsSimpleMarkerSymbolLayer::Square;
677         placement = QgsMarkerLineSymbolLayer::FirstVertex;
678         angle = 0;
679         break;
680 
681       case 87:
682         offset = 2;
683         markerSize = 4;
684         shape = QgsSimpleMarkerSymbolLayer::Square;
685         placement = QgsMarkerLineSymbolLayer::LastVertex;
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;
697         shape = QgsSimpleMarkerSymbolLayer::Square;
698         placement = QgsMarkerLineSymbolLayer::Interval;
699         angle = 0;
700         break;
701 
702       case 94:
703       case 96:
704         offset = 2;
705         markerSize = 4;
706         shape = QgsSimpleMarkerSymbolLayer::EquilateralTriangle;
707         placement = QgsMarkerLineSymbolLayer::FirstVertex;
708         angle = 0;
709         break;
710 
711       case 95:
712         offset = 2;
713         markerSize = 4;
714         shape = QgsSimpleMarkerSymbolLayer::EquilateralTriangle;
715         placement = QgsMarkerLineSymbolLayer::LastVertex;
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;
727         shape = QgsSimpleMarkerSymbolLayer::Diamond;
728         placement = QgsMarkerLineSymbolLayer::Interval;
729         angle = 0;
730         break;
731 
732       case 102:
733       case 104:
734         offset = 2;
735         markerSize = 4;
736         shape = QgsSimpleMarkerSymbolLayer::Diamond;
737         placement = QgsMarkerLineSymbolLayer::FirstVertex;
738         angle = 0;
739         break;
740 
741       case 103:
742         offset = 2;
743         markerSize = 4;
744         shape = QgsSimpleMarkerSymbolLayer::Diamond;
745         placement = QgsMarkerLineSymbolLayer::LastVertex;
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;
757         shape = QgsSimpleMarkerSymbolLayer::Diamond;
758         placement = QgsMarkerLineSymbolLayer::Interval;
759         angle = 0;
760         break;
761 
762       case 114:
763         spacing = 18;
764         offset = 9;
765         markerSize = 8;
766         shape = QgsSimpleMarkerSymbolLayer::SemiCircle;
767         placement = QgsMarkerLineSymbolLayer::Interval;
768         angle = 0;
769         lineOffset = -0.8;
770         break;
771 
772       case 115:
773         spacing = 16;
774         offset = 8;
775         markerSize = 8;
776         shape = QgsSimpleMarkerSymbolLayer::EquilateralTriangle;
777         placement = QgsMarkerLineSymbolLayer::Interval;
778         angle = 0;
779         lineOffset = -2;
780         break;
781 
782       case 116:
783         spacing = 23;
784         offset = 8;
785         markerSize = 8;
786         shape = QgsSimpleMarkerSymbolLayer::SemiCircle;
787         placement = QgsMarkerLineSymbolLayer::Interval;
788         angle = 0;
789         lineOffset = -0.8;
790         break;
791 
792       case 117:
793         spacing = 9;
794         offset = 2;
795         markerSize = 4;
796         shape = QgsSimpleMarkerSymbolLayer::Square;
797         placement = QgsMarkerLineSymbolLayer::Interval;
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 
850     if ( shape == QgsSimpleMarkerSymbolLayer::Octagon
851          || shape == QgsSimpleMarkerSymbolLayer::Square
852          || shape == QgsSimpleMarkerSymbolLayer::EquilateralTriangle
853          || shape == QgsSimpleMarkerSymbolLayer::Diamond
854          || shape == QgsSimpleMarkerSymbolLayer::SemiCircle )
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 
convertFillSymbol(int identifier,QgsMapInfoSymbolConversionContext & context,const QColor & foreColor,const QColor & backColor)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 
convertMarkerSymbol(int identifier,QgsMapInfoSymbolConversionContext & context,const QColor & color,double size,QgsUnitTypes::RenderUnit sizeUnit)1394 QgsMarkerSymbol *QgsMapInfoSymbolConverter::convertMarkerSymbol( int identifier, QgsMapInfoSymbolConversionContext &context, const QColor &color, double size, QgsUnitTypes::RenderUnit sizeUnit )
1395 {
1396   QgsSimpleMarkerSymbolLayerBase::Shape shape;
1397   bool isFilled = true;
1398   bool isNull = false;
1399   bool hasShadow = false;
1400   double angle = 0;
1401   QgsMarkerSymbolLayer::VerticalAnchorPoint vertAlign = QgsMarkerSymbolLayer::VCenter;
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 }
1563