Skip to content

Commit 01b6217

Browse files
author
wonder
committed
[FEATURE] Option to put marker on the central point of a line
git-svn-id: http://svn.osgeo.org/qgis/trunk@14838 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 0dacde9 commit 01b6217

File tree

4 files changed

+84
-6
lines changed

4 files changed

+84
-6
lines changed

src/core/symbology-ng/qgslinesymbollayerv2.cpp

+54
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ QgsSymbolLayerV2* QgsMarkerLineSymbolLayerV2::create( const QgsStringMap& props
245245
x->setPlacement( LastVertex );
246246
else if ( props["placement"] == "firstvertex" )
247247
x->setPlacement( FirstVertex );
248+
else if ( props["placement"] == "centralpoint" )
249+
x->setPlacement( CentralPoint );
248250
else
249251
x->setPlacement( Interval );
250252
return x;
@@ -288,6 +290,8 @@ void QgsMarkerLineSymbolLayerV2::renderPolyline( const QPolygonF& points, QgsSym
288290
{
289291
if ( mPlacement == Interval )
290292
renderPolylineInterval( points, context );
293+
else if ( mPlacement == CentralPoint )
294+
renderPolylineCentral( points, context );
291295
else
292296
renderPolylineVertex( points, context );
293297
}
@@ -296,6 +300,8 @@ void QgsMarkerLineSymbolLayerV2::renderPolyline( const QPolygonF& points, QgsSym
296300
QPolygonF points2 = ::offsetLine( points, context.outputLineWidth( mOffset ) );
297301
if ( mPlacement == Interval )
298302
renderPolylineInterval( points2, context );
303+
else if ( mPlacement == CentralPoint )
304+
renderPolylineCentral( points2, context );
299305
else
300306
renderPolylineVertex( points2, context );
301307
}
@@ -429,6 +435,52 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
429435
mMarker->setAngle( origAngle );
430436
}
431437

438+
void QgsMarkerLineSymbolLayerV2::renderPolylineCentral( const QPolygonF& points, QgsSymbolV2RenderContext& context )
439+
{
440+
// calc length
441+
qreal length = 0;
442+
QPolygonF::const_iterator it = points.constBegin();
443+
QPointF last = *it;
444+
for ( ++it; it != points.constEnd(); ++it )
445+
{
446+
length += sqrt(( last.x() - it->x() ) * ( last.x() - it->x() ) +
447+
( last.y() - it->y() ) * ( last.y() - it->y() ) );
448+
last = *it;
449+
}
450+
451+
// find the segment where the central point lies
452+
it = points.constBegin();
453+
last = *it;
454+
qreal last_at = 0, next_at;
455+
QPointF next;
456+
int segment = 0;
457+
for ( ++it; it != points.constEnd(); ++it )
458+
{
459+
next = *it;
460+
next_at += sqrt(( last.x() - it->x() ) * ( last.x() - it->x() ) +
461+
( last.y() - it->y() ) * ( last.y() - it->y() ) );
462+
if ( next_at >= length / 2 )
463+
break; // we have reached the center
464+
last = *it;
465+
last_at = next_at;
466+
segment++;
467+
}
468+
469+
// find out the central point on segment
470+
MyLine l( last, next ); // for line angle
471+
qreal k = ( length * 0.5 - last_at ) / ( next_at - last_at );
472+
QPointF pt = last + ( next - last ) * k;
473+
474+
// draw the marker
475+
double origAngle = mMarker->angle();
476+
if ( mRotateMarker )
477+
mMarker->setAngle( origAngle + l.angle() * 180 / M_PI );
478+
mMarker->renderPoint( pt, context.renderContext(), -1, context.selected() );
479+
if ( mRotateMarker )
480+
mMarker->setAngle( origAngle );
481+
}
482+
483+
432484
QgsStringMap QgsMarkerLineSymbolLayerV2::properties() const
433485
{
434486
QgsStringMap map;
@@ -441,6 +493,8 @@ QgsStringMap QgsMarkerLineSymbolLayerV2::properties() const
441493
map["placement"] = "lastvertex";
442494
else if ( mPlacement == FirstVertex )
443495
map["placement"] = "firstvertex";
496+
else if ( mPlacement == CentralPoint )
497+
map["placement"] = "centralpoint";
444498
else
445499
map["placement"] = "interval";
446500
return map;

src/core/symbology-ng/qgslinesymbollayerv2.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ class CORE_EXPORT QgsMarkerLineSymbolLayerV2 : public QgsLineSymbolLayerV2
9090
Interval,
9191
Vertex,
9292
LastVertex,
93-
FirstVertex
93+
FirstVertex,
94+
CentralPoint
9495
};
9596

9697
// static stuff
@@ -137,6 +138,7 @@ class CORE_EXPORT QgsMarkerLineSymbolLayerV2 : public QgsLineSymbolLayerV2
137138

138139
void renderPolylineInterval( const QPolygonF& points, QgsSymbolV2RenderContext& context );
139140
void renderPolylineVertex( const QPolygonF& points, QgsSymbolV2RenderContext& context );
141+
void renderPolylineCentral( const QPolygonF& points, QgsSymbolV2RenderContext& context );
140142

141143
bool mRotateMarker;
142144
double mInterval;

src/gui/symbology-ng/qgssymbollayerv2widget.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ QgsMarkerLineSymbolLayerV2Widget::QgsMarkerLineSymbolLayerV2Widget( QWidget* par
363363
connect( radVertex, SIGNAL( clicked() ), this, SLOT( setPlacement() ) );
364364
connect( radVertexLast, SIGNAL( clicked() ), this, SLOT( setPlacement() ) );
365365
connect( radVertexFirst, SIGNAL( clicked() ), this, SLOT( setPlacement() ) );
366+
connect( radCentralPoint, SIGNAL( clicked() ), this, SLOT( setPlacement() ) );
366367
}
367368

368369
void QgsMarkerLineSymbolLayerV2Widget::setSymbolLayer( QgsSymbolLayerV2* layer )
@@ -383,6 +384,8 @@ void QgsMarkerLineSymbolLayerV2Widget::setSymbolLayer( QgsSymbolLayerV2* layer )
383384
radVertex->setChecked( true );
384385
else if ( mLayer->placement() == QgsMarkerLineSymbolLayerV2::LastVertex )
385386
radVertexLast->setChecked( true );
387+
else if ( mLayer->placement() == QgsMarkerLineSymbolLayerV2::CentralPoint )
388+
radCentralPoint->setChecked( true );
386389
else
387390
radVertexFirst->setChecked( true );
388391
updateMarker();
@@ -440,8 +443,10 @@ void QgsMarkerLineSymbolLayerV2Widget::setPlacement()
440443
mLayer->setPlacement( QgsMarkerLineSymbolLayerV2::Vertex );
441444
else if ( radVertexLast->isChecked() )
442445
mLayer->setPlacement( QgsMarkerLineSymbolLayerV2::LastVertex );
443-
else
446+
else if ( radVertexFirst->isChecked() )
444447
mLayer->setPlacement( QgsMarkerLineSymbolLayerV2::FirstVertex );
448+
else
449+
mLayer->setPlacement( QgsMarkerLineSymbolLayerV2::CentralPoint );
445450

446451
emit changed();
447452
}

src/ui/symbollayer/widget_markerline.ui

+21-4
Original file line numberDiff line numberDiff line change
@@ -95,21 +95,21 @@
9595
</property>
9696
</widget>
9797
</item>
98-
<item row="6" column="0" colspan="2">
98+
<item row="8" column="0" colspan="2">
9999
<widget class="QCheckBox" name="chkRotateMarker">
100100
<property name="text">
101101
<string>Rotate marker</string>
102102
</property>
103103
</widget>
104104
</item>
105-
<item row="7" column="0">
105+
<item row="9" column="0">
106106
<widget class="QLabel" name="label_3">
107107
<property name="text">
108108
<string>Line offset</string>
109109
</property>
110110
</widget>
111111
</item>
112-
<item row="7" column="1">
112+
<item row="9" column="1">
113113
<widget class="QDoubleSpinBox" name="spinOffset">
114114
<property name="decimals">
115115
<number>2</number>
@@ -122,7 +122,7 @@
122122
</property>
123123
</widget>
124124
</item>
125-
<item row="8" column="0" colspan="3">
125+
<item row="10" column="0" colspan="3">
126126
<spacer>
127127
<property name="orientation">
128128
<enum>Qt::Vertical</enum>
@@ -135,13 +135,30 @@
135135
</property>
136136
</spacer>
137137
</item>
138+
<item row="7" column="0" colspan="3">
139+
<widget class="Line" name="line">
140+
<property name="orientation">
141+
<enum>Qt::Horizontal</enum>
142+
</property>
143+
</widget>
144+
</item>
145+
<item row="6" column="0">
146+
<widget class="QRadioButton" name="radCentralPoint">
147+
<property name="text">
148+
<string>on central point</string>
149+
</property>
150+
</widget>
151+
</item>
138152
</layout>
139153
</widget>
140154
<tabstops>
141155
<tabstop>btnChangeMarker</tabstop>
142156
<tabstop>radInterval</tabstop>
143157
<tabstop>spinInterval</tabstop>
144158
<tabstop>radVertex</tabstop>
159+
<tabstop>radVertexLast</tabstop>
160+
<tabstop>radVertexFirst</tabstop>
161+
<tabstop>radCentralPoint</tabstop>
145162
<tabstop>chkRotateMarker</tabstop>
146163
<tabstop>spinOffset</tabstop>
147164
</tabstops>

0 commit comments

Comments
 (0)