mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
[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
This commit is contained in:
parent
f262caae06
commit
e125e98eb4
@ -27,6 +27,13 @@ class QgsPalLayerSettings
|
||||
MapOrientation = 8
|
||||
};
|
||||
|
||||
enum UpsideDownLabels
|
||||
{
|
||||
Upright, // upside-down labels (90 <= angle < 270) are shown upright
|
||||
ShowDefined, // show upside down when rotation is layer- or data-defined
|
||||
ShowAll // show upside down for all labels, including dynamic ones
|
||||
};
|
||||
|
||||
// increment iterator in _writeDataDefinedPropertyMap() when adding more
|
||||
enum DataDefinedProperties
|
||||
{
|
||||
@ -105,6 +112,7 @@ class QgsPalLayerSettings
|
||||
// Adds '<' or '>' to the label string pointing to the direction of the line / polygon ring
|
||||
// Works only if Placement == Line
|
||||
bool addDirectionSymbol;
|
||||
unsigned int upsidedownLabels; // whether, or how, to show upsidedown labels
|
||||
bool fontSizeInMapUnits; //true if font size is in map units (otherwise in points)
|
||||
bool bufferSizeInMapUnits; //true if buffer is in map units (otherwise in mm)
|
||||
bool labelOffsetInMapUnits; //true if label offset is in map units (otherwise in mm)
|
||||
|
@ -173,6 +173,24 @@ QgsLabelingGui::QgsLabelingGui( QgsPalLabeling* lbl, QgsVectorLayer* layer, QgsM
|
||||
chkMergeLines->setChecked( lyr.mergeLines );
|
||||
mMinSizeSpinBox->setValue( lyr.minFeatureSize );
|
||||
chkAddDirectionSymbol->setChecked( lyr.addDirectionSymbol );
|
||||
|
||||
// upside-down labels
|
||||
switch ( lyr.upsidedownLabels )
|
||||
{
|
||||
case QgsPalLayerSettings::Upright:
|
||||
mUpsidedownRadioOff->setChecked( true );
|
||||
break;
|
||||
case QgsPalLayerSettings::ShowDefined:
|
||||
mUpsidedownRadioDefined->setChecked( true );
|
||||
break;
|
||||
case QgsPalLayerSettings::ShowAll:
|
||||
mUpsidedownRadioAll->setChecked( true );
|
||||
break;
|
||||
default:
|
||||
mUpsidedownRadioOff->setChecked( true );
|
||||
break;
|
||||
}
|
||||
|
||||
wrapCharacterEdit->setText( lyr.wrapChar );
|
||||
chkPreserveRotation->setChecked( lyr.preserveRotation );
|
||||
|
||||
@ -428,6 +446,18 @@ QgsPalLayerSettings QgsLabelingGui::layerSettings()
|
||||
{
|
||||
lyr.addDirectionSymbol = false;
|
||||
}
|
||||
if ( mUpsidedownRadioOff->isChecked() )
|
||||
{
|
||||
lyr.upsidedownLabels = QgsPalLayerSettings::Upright;
|
||||
}
|
||||
else if ( mUpsidedownRadioDefined->isChecked() )
|
||||
{
|
||||
lyr.upsidedownLabels = QgsPalLayerSettings::ShowDefined;
|
||||
}
|
||||
else if ( mUpsidedownRadioAll->isChecked() )
|
||||
{
|
||||
lyr.upsidedownLabels = QgsPalLayerSettings::ShowAll;
|
||||
}
|
||||
lyr.minFeatureSize = mMinSizeSpinBox->value();
|
||||
lyr.fontSizeInMapUnits = ( mFontSizeUnitComboBox->currentIndex() == 1 );
|
||||
lyr.wrapChar = wrapCharacterEdit->text();
|
||||
|
@ -276,6 +276,10 @@ namespace pal
|
||||
double getLabelDistance() const { return f->distlabel; }
|
||||
void setLabelInfo( LabelInfo* info ) { f->labelInfo = info; }
|
||||
|
||||
bool getFixedRotation() { return f->fixedRotation; }
|
||||
double getLabelAngle() { return f->fixedAngle; }
|
||||
bool getFixedPosition() { return f->fixedPos; }
|
||||
|
||||
int getNumSelfObstacles() const { return nbHoles; }
|
||||
PointSet* getSelfObstacle( int i ) { return holes[i]; }
|
||||
|
||||
|
@ -93,30 +93,55 @@ namespace pal
|
||||
if ( feature->getLayer()->getArrangement() != P_CURVED &&
|
||||
this->alpha > M_PI / 2 && this->alpha <= 3*M_PI / 2 )
|
||||
{
|
||||
tx = x[0];
|
||||
ty = y[0];
|
||||
bool uprightLabel = false;
|
||||
|
||||
x[0] = x[2];
|
||||
y[0] = y[2];
|
||||
switch ( feature->getLayer()->getUpsidedownLabels() )
|
||||
{
|
||||
case Layer::Upright:
|
||||
uprightLabel = true;
|
||||
break;
|
||||
case Layer::ShowDefined:
|
||||
// upright only dynamic labels
|
||||
if ( !feature->getFixedRotation() || ( !feature->getFixedPosition() && feature->getLabelAngle() == 0.0 ) )
|
||||
{
|
||||
uprightLabel = true;
|
||||
}
|
||||
break;
|
||||
case Layer::ShowAll:
|
||||
break;
|
||||
default:
|
||||
uprightLabel = true;
|
||||
}
|
||||
|
||||
x[2] = tx;
|
||||
y[2] = ty;
|
||||
if ( uprightLabel )
|
||||
{
|
||||
tx = x[0];
|
||||
ty = y[0];
|
||||
|
||||
tx = x[1];
|
||||
ty = y[1];
|
||||
x[0] = x[2];
|
||||
y[0] = y[2];
|
||||
|
||||
x[1] = x[3];
|
||||
y[1] = y[3];
|
||||
x[2] = tx;
|
||||
y[2] = ty;
|
||||
|
||||
x[3] = tx;
|
||||
y[3] = ty;
|
||||
tx = x[1];
|
||||
ty = y[1];
|
||||
|
||||
upsideDown = true;
|
||||
x[1] = x[3];
|
||||
y[1] = y[3];
|
||||
|
||||
if ( this->alpha < M_PI )
|
||||
this->alpha += M_PI;
|
||||
else
|
||||
this->alpha -= M_PI;
|
||||
x[3] = tx;
|
||||
y[3] = ty;
|
||||
|
||||
if ( this->alpha < M_PI )
|
||||
this->alpha += M_PI;
|
||||
else
|
||||
this->alpha -= M_PI;
|
||||
|
||||
// labels with text shown upside down are not classified as upsideDown,
|
||||
// only those whose boundary points have been inverted
|
||||
upsideDown = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,6 +75,13 @@ namespace pal
|
||||
|
||||
public:
|
||||
enum LabelMode { LabelPerFeature, LabelPerFeaturePart };
|
||||
enum UpsideDownLabels
|
||||
{
|
||||
Upright, // upside-down labels (90 <= angle < 270) are shown upright
|
||||
ShowDefined, // show upside down when rotation is layer- or data-defined
|
||||
ShowAll // show upside down for all labels, including dynamic ones
|
||||
};
|
||||
|
||||
bool getDisplayAll() const { return displayAll; }
|
||||
|
||||
protected:
|
||||
@ -106,6 +113,8 @@ namespace pal
|
||||
LabelMode mode;
|
||||
bool mergeLines;
|
||||
|
||||
UpsideDownLabels upsidedownLabels;
|
||||
|
||||
// indexes (spatial and id)
|
||||
RTree<FeaturePart*, double, 2, double, 8, 4> *rtree;
|
||||
HashTable<Feature*> *hashtable;
|
||||
@ -279,6 +288,9 @@ namespace pal
|
||||
void setMergeConnectedLines( bool m ) { mergeLines = m; }
|
||||
bool getMergeConnectedLines() const { return mergeLines; }
|
||||
|
||||
void setUpsidedownLabels( UpsideDownLabels ud ) { upsidedownLabels = ud; }
|
||||
UpsideDownLabels getUpsidedownLabels() const { return upsidedownLabels; }
|
||||
|
||||
/**
|
||||
* \brief register a feature in the layer
|
||||
*
|
||||
|
@ -174,6 +174,7 @@ QgsPalLayerSettings::QgsPalLayerSettings()
|
||||
vectorScaleFactor = 1.0;
|
||||
rasterCompressFactor = 1.0;
|
||||
addDirectionSymbol = false;
|
||||
upsidedownLabels = Upright;
|
||||
fontSizeInMapUnits = false;
|
||||
bufferSizeInMapUnits = false;
|
||||
labelOffsetInMapUnits = true;
|
||||
@ -221,6 +222,7 @@ QgsPalLayerSettings::QgsPalLayerSettings( const QgsPalLayerSettings& s )
|
||||
vectorScaleFactor = s.vectorScaleFactor;
|
||||
rasterCompressFactor = s.rasterCompressFactor;
|
||||
addDirectionSymbol = s.addDirectionSymbol;
|
||||
upsidedownLabels = s.upsidedownLabels;
|
||||
fontSizeInMapUnits = s.fontSizeInMapUnits;
|
||||
bufferSizeInMapUnits = s.bufferSizeInMapUnits;
|
||||
distInMapUnits = s.distInMapUnits;
|
||||
@ -400,6 +402,7 @@ void QgsPalLayerSettings::readFromLayer( QgsVectorLayer* layer )
|
||||
displayAll = layer->customProperty( "labeling/displayAll", QVariant( false ) ).toBool();
|
||||
mergeLines = layer->customProperty( "labeling/mergeLines" ).toBool();
|
||||
addDirectionSymbol = layer->customProperty( "labeling/addDirectionSymbol" ).toBool();
|
||||
upsidedownLabels = ( UpsideDownLabels ) layer->customProperty( "labeling/upsidedownLabels", QVariant( Upright ) ).toUInt();
|
||||
minFeatureSize = layer->customProperty( "labeling/minFeatureSize" ).toDouble();
|
||||
fontSizeInMapUnits = layer->customProperty( "labeling/fontSizeInMapUnits" ).toBool();
|
||||
bufferSizeInMapUnits = layer->customProperty( "labeling/bufferSizeInMapUnits" ).toBool();
|
||||
@ -458,6 +461,7 @@ void QgsPalLayerSettings::writeToLayer( QgsVectorLayer* layer )
|
||||
layer->setCustomProperty( "labeling/displayAll", displayAll );
|
||||
layer->setCustomProperty( "labeling/mergeLines", mergeLines );
|
||||
layer->setCustomProperty( "labeling/addDirectionSymbol", addDirectionSymbol );
|
||||
layer->setCustomProperty( "labeling/upsidedownLabels", ( unsigned int )upsidedownLabels );
|
||||
layer->setCustomProperty( "labeling/minFeatureSize", minFeatureSize );
|
||||
layer->setCustomProperty( "labeling/fontSizeInMapUnits", fontSizeInMapUnits );
|
||||
layer->setCustomProperty( "labeling/bufferSizeInMapUnits", bufferSizeInMapUnits );
|
||||
@ -1064,6 +1068,17 @@ int QgsPalLabeling::prepareLayer( QgsVectorLayer* layer, QSet<int>& attrIndices,
|
||||
// set whether adjacent lines should be merged
|
||||
l->setMergeConnectedLines( lyr.mergeLines );
|
||||
|
||||
// set how to show upside-down labels
|
||||
Layer::UpsideDownLabels upsdnlabels;
|
||||
switch ( lyr.upsidedownLabels )
|
||||
{
|
||||
case QgsPalLayerSettings::Upright: upsdnlabels = Layer::Upright; break;
|
||||
case QgsPalLayerSettings::ShowDefined: upsdnlabels = Layer::ShowDefined; break;
|
||||
case QgsPalLayerSettings::ShowAll: upsdnlabels = Layer::ShowAll; break;
|
||||
default: Q_ASSERT( "unsupported upside-down label setting" && 0 ); return 0;
|
||||
}
|
||||
l->setUpsidedownLabels( upsdnlabels );
|
||||
|
||||
// fix for font size in map units causing font to show pointsize at small map scales
|
||||
int pixelFontSize = lyr.sizeToPixel( lyr.textFont.pointSizeF(), ctx );
|
||||
|
||||
|
@ -81,6 +81,13 @@ class CORE_EXPORT QgsPalLayerSettings
|
||||
MapOrientation = 8
|
||||
};
|
||||
|
||||
enum UpsideDownLabels
|
||||
{
|
||||
Upright, // upside-down labels (90 <= angle < 270) are shown upright
|
||||
ShowDefined, // show upside down when rotation is layer- or data-defined
|
||||
ShowAll // show upside down for all labels, including dynamic ones
|
||||
};
|
||||
|
||||
// increment iterator in _writeDataDefinedPropertyMap() when adding more
|
||||
enum DataDefinedProperties
|
||||
{
|
||||
@ -159,6 +166,7 @@ class CORE_EXPORT QgsPalLayerSettings
|
||||
// Adds '<' or '>' to the label string pointing to the direction of the line / polygon ring
|
||||
// Works only if Placement == Line
|
||||
bool addDirectionSymbol;
|
||||
unsigned int upsidedownLabels; // whether, or how, to show upsidedown labels
|
||||
bool fontSizeInMapUnits; //true if font size is in map units (otherwise in points)
|
||||
bool bufferSizeInMapUnits; //true if buffer is in map units (otherwise in mm)
|
||||
bool labelOffsetInMapUnits; //true if label offset is in map units (otherwise in mm)
|
||||
|
@ -1494,114 +1494,13 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>686</width>
|
||||
<height>521</height>
|
||||
<height>553</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_13">
|
||||
<property name="margin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="2" column="0">
|
||||
<widget class="QgsCollapsibleGroupBox" name="mOptionsGroupBox">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Options</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_12">
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="chkMergeLines">
|
||||
<property name="text">
|
||||
<string>Merge connected lines to avoid duplicate labels</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="chkLabelPerFeaturePart">
|
||||
<property name="text">
|
||||
<string>Label every part of multi-part features</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="chkAddDirectionSymbol">
|
||||
<property name="text">
|
||||
<string>Add direction symbol</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_19">
|
||||
<property name="text">
|
||||
<string>Suppress labeling of features smaller than</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="mMinSizeSpinBox">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_20">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="chkNoObstacle">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Features don't act as obstacles for labels</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnEngineSettings">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Automated placement settings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="mPalShowAllLabelsForLayerChkBx">
|
||||
<property name="text">
|
||||
<string>Show all labels for this layer (i.e. including colliding labels)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QgsCollapsibleGroupBox" name="mPriorityGroupBox">
|
||||
<property name="maximumSize">
|
||||
@ -2268,6 +2167,166 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QgsCollapsibleGroupBox" name="mOptionsGroupBox">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Options</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_12">
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="chkMergeLines">
|
||||
<property name="text">
|
||||
<string>Merge connected lines to avoid duplicate labels</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="chkLabelPerFeaturePart">
|
||||
<property name="text">
|
||||
<string>Label every part of multi-part features</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="chkAddDirectionSymbol">
|
||||
<property name="text">
|
||||
<string>Add direction symbol</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_19">
|
||||
<property name="text">
|
||||
<string>Suppress labeling of features smaller than</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="mMinSizeSpinBox">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_20">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="chkNoObstacle">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Features don't act as obstacles for labels</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnEngineSettings">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Automated placement settings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="mPalShowAllLabelsForLayerChkBx">
|
||||
<property name="text">
|
||||
<string>Show all labels for this layer (i.e. including colliding labels)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_16">
|
||||
<item>
|
||||
<widget class="QLabel" name="mUpsidedownLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show upside-down labels</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="mUpsidedownRadioOff">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>never</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="mUpsidedownRadioDefined">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>when rotation defined</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="mUpsidedownRadioAll">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>always</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
|
Loading…
x
Reference in New Issue
Block a user