@@ -371,6 +371,16 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineInterval( const QPolygonF& points
371
371
372
372
}
373
373
374
+ static double _averageAngle ( const QPointF& prevPt, const QPointF& pt, const QPointF& nextPt )
375
+ {
376
+ // calc average angle between the previous and next point
377
+ double a1 = MyLine ( prevPt, pt ).angle ();
378
+ double a2 = MyLine ( pt, nextPt ).angle ();
379
+ double unitX = cos ( a1 ) + cos ( a2 ), unitY = sin ( a1 ) + sin ( a2 );
380
+
381
+ return atan2 ( unitY, unitX );
382
+ }
383
+
374
384
void QgsMarkerLineSymbolLayerV2::renderPolylineVertex ( const QPolygonF& points, QgsSymbolV2RenderContext& context )
375
385
{
376
386
QPointF lastPt = points[0 ];
@@ -379,6 +389,7 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
379
389
double origAngle = mMarker ->angle ();
380
390
double angle;
381
391
int i, maxCount;
392
+ bool isRing = false ;
382
393
383
394
if ( mPlacement == FirstVertex )
384
395
{
@@ -394,6 +405,8 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
394
405
{
395
406
i = 0 ;
396
407
maxCount = points.count ();
408
+ if ( points.first () == points.last () )
409
+ isRing = true ;
397
410
}
398
411
399
412
for ( ; i < maxCount; ++i )
@@ -405,30 +418,50 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
405
418
{
406
419
if ( i == 0 )
407
420
{
408
- const QPointF& nextPt = points[i+1 ];
409
- if ( pt == nextPt )
410
- continue ;
411
- angle = MyLine ( pt, nextPt ).angle ();
421
+ if ( !isRing )
422
+ {
423
+ // use first segment's angle
424
+ const QPointF& nextPt = points[i+1 ];
425
+ if ( pt == nextPt )
426
+ continue ;
427
+ angle = MyLine ( pt, nextPt ).angle ();
428
+ }
429
+ else
430
+ {
431
+ // closed ring: use average angle between first and last segment
432
+ const QPointF& prevPt = points[points.count () - 2 ];
433
+ const QPointF& nextPt = points[1 ];
434
+ if ( prevPt == pt || nextPt == pt )
435
+ continue ;
436
+
437
+ angle = _averageAngle ( prevPt, pt, nextPt );
438
+ }
412
439
}
413
440
else if ( i == points.count () - 1 )
414
441
{
415
- const QPointF& prevPt = points[i-1 ];
416
- if ( pt == prevPt )
442
+ if ( !isRing )
443
+ {
444
+ // use last segment's angle
445
+ const QPointF& prevPt = points[i-1 ];
446
+ if ( pt == prevPt )
447
+ continue ;
448
+ angle = MyLine ( prevPt, pt ).angle ();
449
+ }
450
+ else
451
+ {
452
+ // don't draw the last marker - it has been drawn already
417
453
continue ;
418
- angle = MyLine ( prevPt, pt ). angle ();
454
+ }
419
455
}
420
456
else
421
457
{
458
+ // use average angle
422
459
const QPointF& prevPt = points[i-1 ];
423
460
const QPointF& nextPt = points[i+1 ];
424
461
if ( prevPt == pt || nextPt == pt )
425
462
continue ;
426
463
427
- // calc average angle between the previous and next point
428
- double a1 = MyLine ( prevPt, pt ).angle ();
429
- double a2 = MyLine ( pt, nextPt ).angle ();
430
- double unitX = cos ( a1 ) + cos ( a2 ), unitY = sin ( a1 ) + sin ( a2 );
431
- angle = atan2 ( unitY, unitX );
464
+ angle = _averageAngle ( prevPt, pt, nextPt );
432
465
}
433
466
mMarker ->setAngle ( origAngle + angle * 180 / M_PI );
434
467
}
0 commit comments