Skip to content

Commit e125e98

Browse files
committed
[FEATURE] Fix #6482, options for showing upside-down labels
- Adv Labeling option to 'Show upside-down labels': never, when rotation defined, or always - 'Never' (default) option is same as before, labels with 90 <= angle < 270 are turned so their text is always upright - 'When rotation defined' option shows upside-down labels if their rotation is layer- or data-defined (dynamic labels are turned upright) - 'Always' option shows upside-down labels at layer- or data-defined rotations and for dynamic labels
1 parent f262caa commit e125e98

8 files changed

+280
-119
lines changed

python/core/qgspallabeling.sip

+8
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ class QgsPalLayerSettings
2727
MapOrientation = 8
2828
};
2929

30+
enum UpsideDownLabels
31+
{
32+
Upright, // upside-down labels (90 <= angle < 270) are shown upright
33+
ShowDefined, // show upside down when rotation is layer- or data-defined
34+
ShowAll // show upside down for all labels, including dynamic ones
35+
};
36+
3037
// increment iterator in _writeDataDefinedPropertyMap() when adding more
3138
enum DataDefinedProperties
3239
{
@@ -105,6 +112,7 @@ class QgsPalLayerSettings
105112
// Adds '<' or '>' to the label string pointing to the direction of the line / polygon ring
106113
// Works only if Placement == Line
107114
bool addDirectionSymbol;
115+
unsigned int upsidedownLabels; // whether, or how, to show upsidedown labels
108116
bool fontSizeInMapUnits; //true if font size is in map units (otherwise in points)
109117
bool bufferSizeInMapUnits; //true if buffer is in map units (otherwise in mm)
110118
bool labelOffsetInMapUnits; //true if label offset is in map units (otherwise in mm)

src/app/qgslabelinggui.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,24 @@ QgsLabelingGui::QgsLabelingGui( QgsPalLabeling* lbl, QgsVectorLayer* layer, QgsM
173173
chkMergeLines->setChecked( lyr.mergeLines );
174174
mMinSizeSpinBox->setValue( lyr.minFeatureSize );
175175
chkAddDirectionSymbol->setChecked( lyr.addDirectionSymbol );
176+
177+
// upside-down labels
178+
switch ( lyr.upsidedownLabels )
179+
{
180+
case QgsPalLayerSettings::Upright:
181+
mUpsidedownRadioOff->setChecked( true );
182+
break;
183+
case QgsPalLayerSettings::ShowDefined:
184+
mUpsidedownRadioDefined->setChecked( true );
185+
break;
186+
case QgsPalLayerSettings::ShowAll:
187+
mUpsidedownRadioAll->setChecked( true );
188+
break;
189+
default:
190+
mUpsidedownRadioOff->setChecked( true );
191+
break;
192+
}
193+
176194
wrapCharacterEdit->setText( lyr.wrapChar );
177195
chkPreserveRotation->setChecked( lyr.preserveRotation );
178196

@@ -428,6 +446,18 @@ QgsPalLayerSettings QgsLabelingGui::layerSettings()
428446
{
429447
lyr.addDirectionSymbol = false;
430448
}
449+
if ( mUpsidedownRadioOff->isChecked() )
450+
{
451+
lyr.upsidedownLabels = QgsPalLayerSettings::Upright;
452+
}
453+
else if ( mUpsidedownRadioDefined->isChecked() )
454+
{
455+
lyr.upsidedownLabels = QgsPalLayerSettings::ShowDefined;
456+
}
457+
else if ( mUpsidedownRadioAll->isChecked() )
458+
{
459+
lyr.upsidedownLabels = QgsPalLayerSettings::ShowAll;
460+
}
431461
lyr.minFeatureSize = mMinSizeSpinBox->value();
432462
lyr.fontSizeInMapUnits = ( mFontSizeUnitComboBox->currentIndex() == 1 );
433463
lyr.wrapChar = wrapCharacterEdit->text();

src/core/pal/feature.h

+4
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,10 @@ namespace pal
276276
double getLabelDistance() const { return f->distlabel; }
277277
void setLabelInfo( LabelInfo* info ) { f->labelInfo = info; }
278278

279+
bool getFixedRotation() { return f->fixedRotation; }
280+
double getLabelAngle() { return f->fixedAngle; }
281+
bool getFixedPosition() { return f->fixedPos; }
282+
279283
int getNumSelfObstacles() const { return nbHoles; }
280284
PointSet* getSelfObstacle( int i ) { return holes[i]; }
281285

src/core/pal/labelposition.cpp

+42-17
Original file line numberDiff line numberDiff line change
@@ -93,30 +93,55 @@ namespace pal
9393
if ( feature->getLayer()->getArrangement() != P_CURVED &&
9494
this->alpha > M_PI / 2 && this->alpha <= 3*M_PI / 2 )
9595
{
96-
tx = x[0];
97-
ty = y[0];
96+
bool uprightLabel = false;
9897

99-
x[0] = x[2];
100-
y[0] = y[2];
98+
switch ( feature->getLayer()->getUpsidedownLabels() )
99+
{
100+
case Layer::Upright:
101+
uprightLabel = true;
102+
break;
103+
case Layer::ShowDefined:
104+
// upright only dynamic labels
105+
if ( !feature->getFixedRotation() || ( !feature->getFixedPosition() && feature->getLabelAngle() == 0.0 ) )
106+
{
107+
uprightLabel = true;
108+
}
109+
break;
110+
case Layer::ShowAll:
111+
break;
112+
default:
113+
uprightLabel = true;
114+
}
115+
116+
if ( uprightLabel )
117+
{
118+
tx = x[0];
119+
ty = y[0];
120+
121+
x[0] = x[2];
122+
y[0] = y[2];
101123

102-
x[2] = tx;
103-
y[2] = ty;
124+
x[2] = tx;
125+
y[2] = ty;
104126

105-
tx = x[1];
106-
ty = y[1];
127+
tx = x[1];
128+
ty = y[1];
107129

108-
x[1] = x[3];
109-
y[1] = y[3];
130+
x[1] = x[3];
131+
y[1] = y[3];
110132

111-
x[3] = tx;
112-
y[3] = ty;
133+
x[3] = tx;
134+
y[3] = ty;
113135

114-
upsideDown = true;
136+
if ( this->alpha < M_PI )
137+
this->alpha += M_PI;
138+
else
139+
this->alpha -= M_PI;
115140

116-
if ( this->alpha < M_PI )
117-
this->alpha += M_PI;
118-
else
119-
this->alpha -= M_PI;
141+
// labels with text shown upside down are not classified as upsideDown,
142+
// only those whose boundary points have been inverted
143+
upsideDown = true;
144+
}
120145
}
121146
}
122147

src/core/pal/layer.h

+12
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,13 @@ namespace pal
7575

7676
public:
7777
enum LabelMode { LabelPerFeature, LabelPerFeaturePart };
78+
enum UpsideDownLabels
79+
{
80+
Upright, // upside-down labels (90 <= angle < 270) are shown upright
81+
ShowDefined, // show upside down when rotation is layer- or data-defined
82+
ShowAll // show upside down for all labels, including dynamic ones
83+
};
84+
7885
bool getDisplayAll() const { return displayAll; }
7986

8087
protected:
@@ -106,6 +113,8 @@ namespace pal
106113
LabelMode mode;
107114
bool mergeLines;
108115

116+
UpsideDownLabels upsidedownLabels;
117+
109118
// indexes (spatial and id)
110119
RTree<FeaturePart*, double, 2, double, 8, 4> *rtree;
111120
HashTable<Feature*> *hashtable;
@@ -279,6 +288,9 @@ namespace pal
279288
void setMergeConnectedLines( bool m ) { mergeLines = m; }
280289
bool getMergeConnectedLines() const { return mergeLines; }
281290

291+
void setUpsidedownLabels( UpsideDownLabels ud ) { upsidedownLabels = ud; }
292+
UpsideDownLabels getUpsidedownLabels() const { return upsidedownLabels; }
293+
282294
/**
283295
* \brief register a feature in the layer
284296
*

src/core/qgspallabeling.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ QgsPalLayerSettings::QgsPalLayerSettings()
174174
vectorScaleFactor = 1.0;
175175
rasterCompressFactor = 1.0;
176176
addDirectionSymbol = false;
177+
upsidedownLabels = Upright;
177178
fontSizeInMapUnits = false;
178179
bufferSizeInMapUnits = false;
179180
labelOffsetInMapUnits = true;
@@ -221,6 +222,7 @@ QgsPalLayerSettings::QgsPalLayerSettings( const QgsPalLayerSettings& s )
221222
vectorScaleFactor = s.vectorScaleFactor;
222223
rasterCompressFactor = s.rasterCompressFactor;
223224
addDirectionSymbol = s.addDirectionSymbol;
225+
upsidedownLabels = s.upsidedownLabels;
224226
fontSizeInMapUnits = s.fontSizeInMapUnits;
225227
bufferSizeInMapUnits = s.bufferSizeInMapUnits;
226228
distInMapUnits = s.distInMapUnits;
@@ -400,6 +402,7 @@ void QgsPalLayerSettings::readFromLayer( QgsVectorLayer* layer )
400402
displayAll = layer->customProperty( "labeling/displayAll", QVariant( false ) ).toBool();
401403
mergeLines = layer->customProperty( "labeling/mergeLines" ).toBool();
402404
addDirectionSymbol = layer->customProperty( "labeling/addDirectionSymbol" ).toBool();
405+
upsidedownLabels = ( UpsideDownLabels ) layer->customProperty( "labeling/upsidedownLabels", QVariant( Upright ) ).toUInt();
403406
minFeatureSize = layer->customProperty( "labeling/minFeatureSize" ).toDouble();
404407
fontSizeInMapUnits = layer->customProperty( "labeling/fontSizeInMapUnits" ).toBool();
405408
bufferSizeInMapUnits = layer->customProperty( "labeling/bufferSizeInMapUnits" ).toBool();
@@ -458,6 +461,7 @@ void QgsPalLayerSettings::writeToLayer( QgsVectorLayer* layer )
458461
layer->setCustomProperty( "labeling/displayAll", displayAll );
459462
layer->setCustomProperty( "labeling/mergeLines", mergeLines );
460463
layer->setCustomProperty( "labeling/addDirectionSymbol", addDirectionSymbol );
464+
layer->setCustomProperty( "labeling/upsidedownLabels", ( unsigned int )upsidedownLabels );
461465
layer->setCustomProperty( "labeling/minFeatureSize", minFeatureSize );
462466
layer->setCustomProperty( "labeling/fontSizeInMapUnits", fontSizeInMapUnits );
463467
layer->setCustomProperty( "labeling/bufferSizeInMapUnits", bufferSizeInMapUnits );
@@ -1064,6 +1068,17 @@ int QgsPalLabeling::prepareLayer( QgsVectorLayer* layer, QSet<int>& attrIndices,
10641068
// set whether adjacent lines should be merged
10651069
l->setMergeConnectedLines( lyr.mergeLines );
10661070

1071+
// set how to show upside-down labels
1072+
Layer::UpsideDownLabels upsdnlabels;
1073+
switch ( lyr.upsidedownLabels )
1074+
{
1075+
case QgsPalLayerSettings::Upright: upsdnlabels = Layer::Upright; break;
1076+
case QgsPalLayerSettings::ShowDefined: upsdnlabels = Layer::ShowDefined; break;
1077+
case QgsPalLayerSettings::ShowAll: upsdnlabels = Layer::ShowAll; break;
1078+
default: Q_ASSERT( "unsupported upside-down label setting" && 0 ); return 0;
1079+
}
1080+
l->setUpsidedownLabels( upsdnlabels );
1081+
10671082
// fix for font size in map units causing font to show pointsize at small map scales
10681083
int pixelFontSize = lyr.sizeToPixel( lyr.textFont.pointSizeF(), ctx );
10691084

src/core/qgspallabeling.h

+8
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,13 @@ class CORE_EXPORT QgsPalLayerSettings
8181
MapOrientation = 8
8282
};
8383

84+
enum UpsideDownLabels
85+
{
86+
Upright, // upside-down labels (90 <= angle < 270) are shown upright
87+
ShowDefined, // show upside down when rotation is layer- or data-defined
88+
ShowAll // show upside down for all labels, including dynamic ones
89+
};
90+
8491
// increment iterator in _writeDataDefinedPropertyMap() when adding more
8592
enum DataDefinedProperties
8693
{
@@ -159,6 +166,7 @@ class CORE_EXPORT QgsPalLayerSettings
159166
// Adds '<' or '>' to the label string pointing to the direction of the line / polygon ring
160167
// Works only if Placement == Line
161168
bool addDirectionSymbol;
169+
unsigned int upsidedownLabels; // whether, or how, to show upsidedown labels
162170
bool fontSizeInMapUnits; //true if font size is in map units (otherwise in points)
163171
bool bufferSizeInMapUnits; //true if buffer is in map units (otherwise in mm)
164172
bool labelOffsetInMapUnits; //true if label offset is in map units (otherwise in mm)

0 commit comments

Comments
 (0)