Skip to content

Commit 7d2bf15

Browse files
committed
[FEATURE] Add option for simple line symbols to be drawn only inside a
polygon. Allows for creation of "national geographic" style borders on maps where a thick border does not overlap into neighbouring polygons.
1 parent 6d663c5 commit 7d2bf15

File tree

7 files changed

+89
-4
lines changed

7 files changed

+89
-4
lines changed

python/core/symbology-ng/qgslinesymbollayerv2.sip

+6
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ class QgsSimpleLineSymbolLayerV2 : QgsLineSymbolLayerV2
5555

5656
QVector<qreal> customDashVector() const;
5757
void setCustomDashVector( const QVector<qreal>& vector );
58+
59+
//Returns true if the line should only be drawn inside the polygon
60+
bool drawInsidePolygon() const;
61+
//Set to true if the line should only be drawn inside the polygon
62+
void setDrawInsidePolygon( bool drawInsidePolygon );
63+
5864
};
5965

6066
/////////

python/gui/symbology-ng/qgssymbollayerv2widget.sip

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class QgsSimpleLineSymbolLayerV2Widget : QgsSymbolLayerV2Widget
4343
void on_mOffsetUnitComboBox_currentIndexChanged( int index );
4444
void on_mDashPatternUnitComboBox_currentIndexChanged( int index );
4545
void on_mDataDefinedPropertiesButton_clicked();
46+
void on_mDrawInsideCheckBox_stateChanged( int state );
4647

4748
protected:
4849
//creates a new icon for the 'change pattern' button

src/core/symbology-ng/qgslinesymbollayerv2.cpp

+32-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
QgsSimpleLineSymbolLayerV2::QgsSimpleLineSymbolLayerV2( QColor color, double width, Qt::PenStyle penStyle )
3232
: mPenStyle( penStyle ), mPenJoinStyle( DEFAULT_SIMPLELINE_JOINSTYLE ), mPenCapStyle( DEFAULT_SIMPLELINE_CAPSTYLE ), mOffset( 0 ), mOffsetUnit( QgsSymbolV2::MM ),
33-
mUseCustomDashPattern( false ), mCustomDashPatternUnit( QgsSymbolV2::MM )
33+
mUseCustomDashPattern( false ), mCustomDashPatternUnit( QgsSymbolV2::MM ), mDrawInsidePolygon( false )
3434
{
3535
mColor = color;
3636
mWidth = width;
@@ -94,6 +94,11 @@ QgsSymbolLayerV2* QgsSimpleLineSymbolLayerV2::create( const QgsStringMap& props
9494
l->setCustomDashPatternUnit( QgsSymbolLayerV2Utils::decodeOutputUnit( props["customdash_unit"] ) );
9595
}
9696

97+
if ( props.contains( "draw_inside_polygon" ) )
98+
{
99+
l->setDrawInsidePolygon( props["draw_inside_polygon"].toInt() );
100+
}
101+
97102
//data defined properties
98103
if ( props.contains( "color_expression" ) )
99104
l->setDataDefinedProperty( "color", props["color_expression"] );
@@ -191,6 +196,15 @@ void QgsSimpleLineSymbolLayerV2::renderPolyline( const QPolygonF& points, QgsSym
191196
return;
192197
}
193198

199+
if ( mDrawInsidePolygon )
200+
{
201+
//only drawing the line on the interior of the polygon, so set clip path for painter
202+
p->save();
203+
QPainterPath clipPath;
204+
clipPath.addPolygon( points );
205+
p->setClipPath( clipPath, Qt::IntersectClip );
206+
}
207+
194208
if ( offset == 0 )
195209
{
196210
p->drawPolyline( points );
@@ -200,6 +214,12 @@ void QgsSimpleLineSymbolLayerV2::renderPolyline( const QPolygonF& points, QgsSym
200214
double scaledOffset = offset * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOffsetUnit );
201215
p->drawPolyline( ::offsetLine( points, scaledOffset ) );
202216
}
217+
218+
if ( mDrawInsidePolygon )
219+
{
220+
//restore painter to reset clip path
221+
p->restore();
222+
}
203223
}
204224

205225
QgsStringMap QgsSimpleLineSymbolLayerV2::properties() const
@@ -216,6 +236,7 @@ QgsStringMap QgsSimpleLineSymbolLayerV2::properties() const
216236
map["use_custom_dash"] = ( mUseCustomDashPattern ? "1" : "0" );
217237
map["customdash"] = QgsSymbolLayerV2Utils::encodeRealVector( mCustomDashVector );
218238
map["customdash_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( mCustomDashPatternUnit );
239+
map["draw_inside_polygon"] = ( mDrawInsidePolygon ? "1" : "0" );
219240
saveDataDefinedProperties( map );
220241
return map;
221242
}
@@ -231,6 +252,7 @@ QgsSymbolLayerV2* QgsSimpleLineSymbolLayerV2::clone() const
231252
l->setPenCapStyle( mPenCapStyle );
232253
l->setUseCustomDashPattern( mUseCustomDashPattern );
233254
l->setCustomDashVector( mCustomDashVector );
255+
l->setDrawInsidePolygon( mDrawInsidePolygon );
234256
copyDataDefinedProperties( l );
235257
return l;
236258
}
@@ -387,7 +409,15 @@ void QgsSimpleLineSymbolLayerV2::applyDataDefinedSymbology( QgsSymbolV2RenderCon
387409

388410
double QgsSimpleLineSymbolLayerV2::estimateMaxBleed() const
389411
{
390-
return ( mWidth / 2.0 ) + mOffset;
412+
if ( mDrawInsidePolygon )
413+
{
414+
//set to clip line to the interior of polygon, so we expect no bleed
415+
return 0;
416+
}
417+
else
418+
{
419+
return ( mWidth / 2.0 ) + mOffset;
420+
}
391421
}
392422

393423
QVector<qreal> QgsSimpleLineSymbolLayerV2::dxfCustomDashPattern( QgsSymbolV2::OutputUnit& unit ) const

src/core/symbology-ng/qgslinesymbollayerv2.h

+7
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ class CORE_EXPORT QgsSimpleLineSymbolLayerV2 : public QgsLineSymbolLayerV2
9191
QVector<qreal> customDashVector() const { return mCustomDashVector; }
9292
void setCustomDashVector( const QVector<qreal>& vector ) { mCustomDashVector = vector; }
9393

94+
//Returns true if the line should only be drawn inside the polygon
95+
bool drawInsidePolygon() const { return mDrawInsidePolygon; }
96+
//Set to true if the line should only be drawn inside the polygon
97+
void setDrawInsidePolygon( bool drawInsidePolygon ) { mDrawInsidePolygon = drawInsidePolygon; }
98+
9499
QVector<qreal> dxfCustomDashPattern( QgsSymbolV2::OutputUnit& unit ) const;
95100

96101
double dxfWidth( const QgsDxfExport& e, const QgsSymbolV2RenderContext& context ) const;
@@ -112,6 +117,8 @@ class CORE_EXPORT QgsSimpleLineSymbolLayerV2 : public QgsLineSymbolLayerV2
112117
/**Vector with an even number of entries for the */
113118
QVector<qreal> mCustomDashVector;
114119

120+
bool mDrawInsidePolygon;
121+
115122
private:
116123
//helper functions for data defined symbology
117124
void applyDataDefinedSymbology( QgsSymbolV2RenderContext& context, QPen& pen, QPen& selPen, double& offset );

src/gui/symbology-ng/qgssymbollayerv2widget.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ QgsSimpleLineSymbolLayerV2Widget::QgsSimpleLineSymbolLayerV2Widget( const QgsVec
5252

5353
setupUi( this );
5454

55+
if ( vl && vl->geometryType() != QGis::Polygon )
56+
{
57+
//draw inside polygon checkbox only makes sense for polygon layers
58+
mDrawInsideCheckBox->hide();
59+
}
60+
5561
connect( spinWidth, SIGNAL( valueChanged( double ) ), this, SLOT( penWidthChanged() ) );
5662
connect( btnChangeColor, SIGNAL( colorChanged( const QColor& ) ), this, SLOT( colorChanged( const QColor& ) ) );
5763
connect( cboPenStyle, SIGNAL( currentIndexChanged( int ) ), this, SLOT( penStyleChanged() ) );
@@ -104,6 +110,13 @@ void QgsSimpleLineSymbolLayerV2Widget::setSymbolLayer( QgsSymbolLayerV2* layer )
104110
mCustomCheckBox->blockSignals( true );
105111
mCustomCheckBox->setCheckState( useCustomDashPattern ? Qt::Checked : Qt::Unchecked );
106112
mCustomCheckBox->blockSignals( false );
113+
114+
//draw inside polygon?
115+
bool drawInsidePolygon = mLayer->drawInsidePolygon();
116+
mDrawInsideCheckBox->blockSignals( true );
117+
mDrawInsideCheckBox->setCheckState( drawInsidePolygon ? Qt::Checked : Qt::Unchecked );
118+
mDrawInsideCheckBox->blockSignals( false );
119+
107120
updatePatternIcon();
108121
}
109122

@@ -189,6 +202,13 @@ void QgsSimpleLineSymbolLayerV2Widget::on_mDashPatternUnitComboBox_currentIndexC
189202
emit changed();
190203
}
191204

205+
void QgsSimpleLineSymbolLayerV2Widget::on_mDrawInsideCheckBox_stateChanged( int state )
206+
{
207+
bool checked = ( state == Qt::Checked );
208+
mLayer->setDrawInsidePolygon( checked );
209+
emit changed();
210+
}
211+
192212
void QgsSimpleLineSymbolLayerV2Widget::on_mDataDefinedPropertiesButton_clicked()
193213
{
194214
if ( !mLayer )

src/gui/symbology-ng/qgssymbollayerv2widget.h

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class GUI_EXPORT QgsSimpleLineSymbolLayerV2Widget : public QgsSymbolLayerV2Widge
7171
void on_mOffsetUnitComboBox_currentIndexChanged( int index );
7272
void on_mDashPatternUnitComboBox_currentIndexChanged( int index );
7373
void on_mDataDefinedPropertiesButton_clicked();
74+
void on_mDrawInsideCheckBox_stateChanged( int state );
7475

7576
protected:
7677
QgsSimpleLineSymbolLayerV2* mLayer;

src/ui/symbollayer/widget_simpleline.ui

+22-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,16 @@
2323
<property name="horizontalSpacing">
2424
<number>28</number>
2525
</property>
26-
<property name="margin">
26+
<property name="leftMargin">
27+
<number>1</number>
28+
</property>
29+
<property name="topMargin">
30+
<number>1</number>
31+
</property>
32+
<property name="rightMargin">
33+
<number>1</number>
34+
</property>
35+
<property name="bottomMargin">
2736
<number>1</number>
2837
</property>
2938
<item row="0" column="0">
@@ -242,7 +251,7 @@
242251
</item>
243252
</widget>
244253
</item>
245-
<item row="8" column="0" colspan="2">
254+
<item row="11" column="0" colspan="2">
246255
<widget class="QPushButton" name="mDataDefinedPropertiesButton">
247256
<property name="sizePolicy">
248257
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
@@ -255,6 +264,17 @@
255264
</property>
256265
</widget>
257266
</item>
267+
<item row="9" column="0" colspan="2">
268+
<layout class="QHBoxLayout" name="horizontalLayout_4">
269+
<item>
270+
<widget class="QCheckBox" name="mDrawInsideCheckBox">
271+
<property name="text">
272+
<string>Draw line only inside polygon</string>
273+
</property>
274+
</widget>
275+
</item>
276+
</layout>
277+
</item>
258278
</layout>
259279
</widget>
260280
<customwidgets>

0 commit comments

Comments
 (0)