Skip to content
Permalink
Browse files

[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
  • Loading branch information
wonder
wonder committed Dec 4, 2010
1 parent 0dacde9 commit 01b621777cc129d8a1d4f0687e6478e1400758a0
@@ -245,6 +245,8 @@ QgsSymbolLayerV2* QgsMarkerLineSymbolLayerV2::create( const QgsStringMap& props
x->setPlacement( LastVertex );
else if ( props["placement"] == "firstvertex" )
x->setPlacement( FirstVertex );
else if ( props["placement"] == "centralpoint" )
x->setPlacement( CentralPoint );
else
x->setPlacement( Interval );
return x;
@@ -288,6 +290,8 @@ void QgsMarkerLineSymbolLayerV2::renderPolyline( const QPolygonF& points, QgsSym
{
if ( mPlacement == Interval )
renderPolylineInterval( points, context );
else if ( mPlacement == CentralPoint )
renderPolylineCentral( points, context );
else
renderPolylineVertex( points, context );
}
@@ -296,6 +300,8 @@ void QgsMarkerLineSymbolLayerV2::renderPolyline( const QPolygonF& points, QgsSym
QPolygonF points2 = ::offsetLine( points, context.outputLineWidth( mOffset ) );
if ( mPlacement == Interval )
renderPolylineInterval( points2, context );
else if ( mPlacement == CentralPoint )
renderPolylineCentral( points2, context );
else
renderPolylineVertex( points2, context );
}
@@ -429,6 +435,52 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
mMarker->setAngle( origAngle );
}

void QgsMarkerLineSymbolLayerV2::renderPolylineCentral( const QPolygonF& points, QgsSymbolV2RenderContext& context )
{
// calc length
qreal length = 0;
QPolygonF::const_iterator it = points.constBegin();
QPointF last = *it;
for ( ++it; it != points.constEnd(); ++it )
{
length += sqrt(( last.x() - it->x() ) * ( last.x() - it->x() ) +
( last.y() - it->y() ) * ( last.y() - it->y() ) );
last = *it;
}

// find the segment where the central point lies
it = points.constBegin();
last = *it;
qreal last_at = 0, next_at;
QPointF next;
int segment = 0;
for ( ++it; it != points.constEnd(); ++it )
{
next = *it;
next_at += sqrt(( last.x() - it->x() ) * ( last.x() - it->x() ) +
( last.y() - it->y() ) * ( last.y() - it->y() ) );
if ( next_at >= length / 2 )
break; // we have reached the center
last = *it;
last_at = next_at;
segment++;
}

// find out the central point on segment
MyLine l( last, next ); // for line angle
qreal k = ( length * 0.5 - last_at ) / ( next_at - last_at );
QPointF pt = last + ( next - last ) * k;

// draw the marker
double origAngle = mMarker->angle();
if ( mRotateMarker )
mMarker->setAngle( origAngle + l.angle() * 180 / M_PI );
mMarker->renderPoint( pt, context.renderContext(), -1, context.selected() );
if ( mRotateMarker )
mMarker->setAngle( origAngle );
}


QgsStringMap QgsMarkerLineSymbolLayerV2::properties() const
{
QgsStringMap map;
@@ -441,6 +493,8 @@ QgsStringMap QgsMarkerLineSymbolLayerV2::properties() const
map["placement"] = "lastvertex";
else if ( mPlacement == FirstVertex )
map["placement"] = "firstvertex";
else if ( mPlacement == CentralPoint )
map["placement"] = "centralpoint";
else
map["placement"] = "interval";
return map;
@@ -90,7 +90,8 @@ class CORE_EXPORT QgsMarkerLineSymbolLayerV2 : public QgsLineSymbolLayerV2
Interval,
Vertex,
LastVertex,
FirstVertex
FirstVertex,
CentralPoint
};

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

void renderPolylineInterval( const QPolygonF& points, QgsSymbolV2RenderContext& context );
void renderPolylineVertex( const QPolygonF& points, QgsSymbolV2RenderContext& context );
void renderPolylineCentral( const QPolygonF& points, QgsSymbolV2RenderContext& context );

bool mRotateMarker;
double mInterval;
@@ -363,6 +363,7 @@ QgsMarkerLineSymbolLayerV2Widget::QgsMarkerLineSymbolLayerV2Widget( QWidget* par
connect( radVertex, SIGNAL( clicked() ), this, SLOT( setPlacement() ) );
connect( radVertexLast, SIGNAL( clicked() ), this, SLOT( setPlacement() ) );
connect( radVertexFirst, SIGNAL( clicked() ), this, SLOT( setPlacement() ) );
connect( radCentralPoint, SIGNAL( clicked() ), this, SLOT( setPlacement() ) );
}

void QgsMarkerLineSymbolLayerV2Widget::setSymbolLayer( QgsSymbolLayerV2* layer )
@@ -383,6 +384,8 @@ void QgsMarkerLineSymbolLayerV2Widget::setSymbolLayer( QgsSymbolLayerV2* layer )
radVertex->setChecked( true );
else if ( mLayer->placement() == QgsMarkerLineSymbolLayerV2::LastVertex )
radVertexLast->setChecked( true );
else if ( mLayer->placement() == QgsMarkerLineSymbolLayerV2::CentralPoint )
radCentralPoint->setChecked( true );
else
radVertexFirst->setChecked( true );
updateMarker();
@@ -440,8 +443,10 @@ void QgsMarkerLineSymbolLayerV2Widget::setPlacement()
mLayer->setPlacement( QgsMarkerLineSymbolLayerV2::Vertex );
else if ( radVertexLast->isChecked() )
mLayer->setPlacement( QgsMarkerLineSymbolLayerV2::LastVertex );
else
else if ( radVertexFirst->isChecked() )
mLayer->setPlacement( QgsMarkerLineSymbolLayerV2::FirstVertex );
else
mLayer->setPlacement( QgsMarkerLineSymbolLayerV2::CentralPoint );

emit changed();
}
@@ -95,21 +95,21 @@
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<item row="8" column="0" colspan="2">
<widget class="QCheckBox" name="chkRotateMarker">
<property name="text">
<string>Rotate marker</string>
</property>
</widget>
</item>
<item row="7" column="0">
<item row="9" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Line offset</string>
</property>
</widget>
</item>
<item row="7" column="1">
<item row="9" column="1">
<widget class="QDoubleSpinBox" name="spinOffset">
<property name="decimals">
<number>2</number>
@@ -122,7 +122,7 @@
</property>
</widget>
</item>
<item row="8" column="0" colspan="3">
<item row="10" column="0" colspan="3">
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -135,13 +135,30 @@
</property>
</spacer>
</item>
<item row="7" column="0" colspan="3">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QRadioButton" name="radCentralPoint">
<property name="text">
<string>on central point</string>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>btnChangeMarker</tabstop>
<tabstop>radInterval</tabstop>
<tabstop>spinInterval</tabstop>
<tabstop>radVertex</tabstop>
<tabstop>radVertexLast</tabstop>
<tabstop>radVertexFirst</tabstop>
<tabstop>radCentralPoint</tabstop>
<tabstop>chkRotateMarker</tabstop>
<tabstop>spinOffset</tabstop>
</tabstops>

0 comments on commit 01b6217

Please sign in to comment.
You can’t perform that action at this time.