Skip to content

Commit

Permalink
[labeling][FEATURE] Add a dedicated polygon placement mode for "outside"
Browse files Browse the repository at this point in the history
When selected, labels will always be placed outside of polygons for the
layer

Sponsored by QGIS Swiss user group
  • Loading branch information
nyalldawson committed May 3, 2020
1 parent 9fb85d3 commit e10c9f3
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 45 deletions.
1 change: 1 addition & 0 deletions python/core/auto_generated/labeling/qgspallabeling.sip.in
Expand Up @@ -99,6 +99,7 @@ class QgsPalLayerSettings
Free,
OrderedPositionsAroundPoint,
PerimeterCurved,
OutsidePolygons,
};

enum PredefinedPointPosition
Expand Down
1 change: 1 addition & 0 deletions src/core/labeling/qgspallabeling.h
Expand Up @@ -225,6 +225,7 @@ class CORE_EXPORT QgsPalLayerSettings
Free, //!< Arranges candidates scattered throughout a polygon feature. Candidates are rotated to respect the polygon's orientation. Applies to polygon layers only.
OrderedPositionsAroundPoint, //!< Candidates are placed in predefined positions around a point. Preference is given to positions with greatest cartographic appeal, e.g., top right, bottom right, etc. Applies to point layers only.
PerimeterCurved, //!< Arranges candidates following the curvature of a polygon's boundary. Applies to polygon layers only.
OutsidePolygons, //!< Candidates are placed outside of polygon boundaries. Applies to polygon layers only. Since QGIS 3.14
};

//TODO QGIS 4.0 - move to QgsLabelingEngine
Expand Down
1 change: 1 addition & 0 deletions src/core/labeling/qgsvectorlayerlabeling.cpp
Expand Up @@ -353,6 +353,7 @@ void QgsAbstractVectorLayerLabeling::writeTextSymbolizer( QDomNode &parent, QgsP
break;
case QgsPalLayerSettings::Horizontal:
case QgsPalLayerSettings::Free:
case QgsPalLayerSettings::OutsidePolygons:
{
// still a point placement (for "free" it's a fallback, there is no SLD equivalent)
QDomElement pointPlacement = doc.createElement( "se:PointPlacement" );
Expand Down
2 changes: 1 addition & 1 deletion src/core/pal/feature.cpp
Expand Up @@ -2034,7 +2034,7 @@ std::vector< std::unique_ptr< LabelPosition > > FeaturePart::createCandidates( P
const bool allowInside = mLF->polygonPlacementFlags() & QgsLabeling::PolygonPlacementFlag::AllowPlacementInsideOfPolygon;
//check width/height of bbox is sufficient for label

if ( allowOutside && !allowInside )
if ( ( allowOutside && !allowInside ) || ( mLF->layer()->arrangement() == QgsPalLayerSettings::OutsidePolygons ) )
{
// only allowed to place outside of polygon
createCandidatesOutsidePolygon( lPos, pal );
Expand Down
7 changes: 7 additions & 0 deletions src/gui/labeling/qgslabelinggui.cpp
Expand Up @@ -327,6 +327,9 @@ void QgsLabelingGui::setLayer( QgsMapLayer *mapLayer )
case QgsPalLayerSettings::PerimeterCurved:
radPolygonPerimeterCurved->setChecked( true );
break;
case QgsPalLayerSettings::OutsidePolygons:
radPolygonOutside->setChecked( true );
break;
}

// Label repeat distance
Expand Down Expand Up @@ -530,6 +533,10 @@ QgsPalLayerSettings QgsLabelingGui::layerSettings()
{
lyr.placement = QgsPalLayerSettings::Free;
}
else if ( radPolygonOutside->isChecked() )
{
lyr.placement = QgsPalLayerSettings::OutsidePolygons;
}
else
{
qFatal( "Invalid settings" );
Expand Down
4 changes: 3 additions & 1 deletion src/gui/qgstextformatwidget.cpp
Expand Up @@ -286,6 +286,7 @@ void QgsTextFormatWidget::initWidget()
mPlacePolygonBtnGrp->addButton( radPolygonFree, static_cast<int>( QgsPalLayerSettings::Free ) );
mPlacePolygonBtnGrp->addButton( radPolygonPerimeter, static_cast<int>( QgsPalLayerSettings::Line ) );
mPlacePolygonBtnGrp->addButton( radPolygonPerimeterCurved, static_cast<int>( QgsPalLayerSettings::PerimeterCurved ) );
mPlacePolygonBtnGrp->addButton( radPolygonOutside, static_cast<int>( QgsPalLayerSettings::OutsidePolygons ) );
mPlacePolygonBtnGrp->setExclusive( true );
connect( mPlacePolygonBtnGrp, static_cast<void ( QButtonGroup::* )( int )>( &QButtonGroup::buttonClicked ), this, &QgsTextFormatWidget::updatePlacementWidgets );

Expand Down Expand Up @@ -459,6 +460,7 @@ void QgsTextFormatWidget::initWidget()
<< radPolygonHorizontal
<< radPolygonPerimeter
<< radPolygonPerimeterCurved
<< radPolygonOutside
<< radPredefinedOrder
<< mFieldExpressionWidget
<< mCheckBoxSubstituteText
Expand Down Expand Up @@ -1275,7 +1277,7 @@ void QgsTextFormatWidget::updatePlacementWidgets()
bool showDistanceFrame = false;
bool showRotationFrame = false;
bool showMaxCharAngleFrame = false;
bool showPolygonPlacementOptions = ( curWdgt == pagePolygon && !radPolygonPerimeter->isChecked() && !radPolygonPerimeterCurved->isChecked() );
bool showPolygonPlacementOptions = ( curWdgt == pagePolygon && !radPolygonPerimeter->isChecked() && !radPolygonPerimeterCurved->isChecked() && !radPolygonOutside->isChecked() );

bool enableMultiLinesFrame = true;

Expand Down
93 changes: 50 additions & 43 deletions src/ui/qgstextformatwidgetbase.ui
Expand Up @@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>880</width>
<width>612</width>
<height>589</height>
</rect>
</property>
Expand Down Expand Up @@ -172,7 +172,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>858</width>
<width>590</width>
<height>300</height>
</rect>
</property>
Expand Down Expand Up @@ -723,8 +723,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>317</width>
<height>260</height>
<width>323</width>
<height>292</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1">
Expand Down Expand Up @@ -1303,8 +1303,8 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>348</width>
<height>624</height>
<width>373</width>
<height>708</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_42">
Expand Down Expand Up @@ -2187,8 +2187,8 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>284</width>
<height>273</height>
<width>299</width>
<height>308</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_12">
Expand Down Expand Up @@ -2533,8 +2533,8 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>830</width>
<height>376</height>
<width>294</width>
<height>291</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_121">
Expand Down Expand Up @@ -2811,8 +2811,8 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>816</width>
<height>696</height>
<width>440</width>
<height>786</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_21">
Expand Down Expand Up @@ -3572,8 +3572,8 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>816</width>
<height>406</height>
<width>324</width>
<height>457</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_22">
Expand Down Expand Up @@ -4000,8 +4000,8 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>830</width>
<height>376</height>
<width>833</width>
<height>368</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_46">
Expand Down Expand Up @@ -4150,8 +4150,8 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>431</width>
<height>1108</height>
<width>562</width>
<height>1266</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_11">
Expand Down Expand Up @@ -4321,6 +4321,33 @@ font-style: italic;</string>
</widget>
<widget class="QWidget" name="pagePolygon">
<layout class="QGridLayout" name="gridLayout_18">
<item row="1" column="1">
<widget class="QRadioButton" name="radPolygonFree">
<property name="text">
<string>Free (angled)</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QRadioButton" name="radPolygonOutside">
<property name="text">
<string>Outside polygons</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QRadioButton" name="radPolygonPerimeterCurved">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Using perimeter (curved)</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QRadioButton" name="radOverCentroid">
<property name="sizePolicy">
Expand All @@ -4337,13 +4364,6 @@ font-style: italic;</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QRadioButton" name="radPolygonHorizontal">
<property name="text">
<string>Horizontal</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="radAroundCentroid">
<property name="sizePolicy">
Expand All @@ -4357,13 +4377,6 @@ font-style: italic;</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QRadioButton" name="radPolygonFree">
<property name="text">
<string>Free</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QRadioButton" name="radPolygonPerimeter">
<property name="sizePolicy">
Expand All @@ -4377,20 +4390,14 @@ font-style: italic;</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QRadioButton" name="radPolygonPerimeterCurved">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item row="0" column="1">
<widget class="QRadioButton" name="radPolygonHorizontal">
<property name="text">
<string>Using perimeter (curved)</string>
<string>Horizontal</string>
</property>
</widget>
</item>
<item row="1" column="2">
<item row="1" column="3">
<spacer name="horizontalSpacer_26">
<property name="orientation">
<enum>Qt::Horizontal</enum>
Expand Down Expand Up @@ -6039,7 +6046,7 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>819</width>
<width>430</width>
<height>708</height>
</rect>
</property>
Expand Down

0 comments on commit e10c9f3

Please sign in to comment.