Skip to content
Permalink
Browse files

[labeling][FEATURE] Add a dedicated polygon placement mode for "outside"

When selected, labels will always be placed outside of polygons for the
layer

Sponsored by QGIS Swiss user group
  • Loading branch information
nyalldawson committed Apr 30, 2020
1 parent 9fb85d3 commit e10c9f3b19cac38e716ebcd1a18209de82f653f9
@@ -99,6 +99,7 @@ class QgsPalLayerSettings
Free,
OrderedPositionsAroundPoint,
PerimeterCurved,
OutsidePolygons,
};

enum PredefinedPointPosition
@@ -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
@@ -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" );
@@ -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 );
@@ -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
@@ -530,6 +533,10 @@ QgsPalLayerSettings QgsLabelingGui::layerSettings()
{
lyr.placement = QgsPalLayerSettings::Free;
}
else if ( radPolygonOutside->isChecked() )
{
lyr.placement = QgsPalLayerSettings::OutsidePolygons;
}
else
{
qFatal( "Invalid settings" );
@@ -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 );

@@ -459,6 +460,7 @@ void QgsTextFormatWidget::initWidget()
<< radPolygonHorizontal
<< radPolygonPerimeter
<< radPolygonPerimeterCurved
<< radPolygonOutside
<< radPredefinedOrder
<< mFieldExpressionWidget
<< mCheckBoxSubstituteText
@@ -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;

@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>880</width>
<width>612</width>
<height>589</height>
</rect>
</property>
@@ -172,7 +172,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>858</width>
<width>590</width>
<height>300</height>
</rect>
</property>
@@ -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">
@@ -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">
@@ -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">
@@ -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">
@@ -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">
@@ -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">
@@ -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">
@@ -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">
@@ -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">
@@ -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">
@@ -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">
@@ -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>
@@ -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>

0 comments on commit e10c9f3

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