Skip to content

Commit e0960e4

Browse files
author
wonder
committed
Marker line - vertex placement - behave correctly with polygon's rings.
git-svn-id: http://svn.osgeo.org/qgis/trunk@14871 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 4001fa0 commit e0960e4

File tree

1 file changed

+45
-12
lines changed

1 file changed

+45
-12
lines changed

src/core/symbology-ng/qgslinesymbollayerv2.cpp

+45-12
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,16 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineInterval( const QPolygonF& points
371371

372372
}
373373

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+
374384
void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points, QgsSymbolV2RenderContext& context )
375385
{
376386
QPointF lastPt = points[0];
@@ -379,6 +389,7 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
379389
double origAngle = mMarker->angle();
380390
double angle;
381391
int i, maxCount;
392+
bool isRing = false;
382393

383394
if ( mPlacement == FirstVertex )
384395
{
@@ -394,6 +405,8 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
394405
{
395406
i = 0;
396407
maxCount = points.count();
408+
if ( points.first() == points.last() )
409+
isRing = true;
397410
}
398411

399412
for ( ; i < maxCount; ++i )
@@ -405,30 +418,50 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
405418
{
406419
if ( i == 0 )
407420
{
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+
}
412439
}
413440
else if ( i == points.count() - 1 )
414441
{
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
417453
continue;
418-
angle = MyLine( prevPt, pt ).angle();
454+
}
419455
}
420456
else
421457
{
458+
// use average angle
422459
const QPointF& prevPt = points[i-1];
423460
const QPointF& nextPt = points[i+1];
424461
if ( prevPt == pt || nextPt == pt )
425462
continue;
426463

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 );
432465
}
433466
mMarker->setAngle( origAngle + angle * 180 / M_PI );
434467
}

0 commit comments

Comments
 (0)