From e5f07edf5578f74018098a636ae2333f407cdd4e Mon Sep 17 00:00:00 2001 From: Larry Shaffer Date: Wed, 7 Nov 2012 17:45:40 -0700 Subject: [PATCH] Add pixel size limiting for labels defined in map units - Allows user to quickly set visibility thresholds based upon text legibility - By default initially on for map unit labels to skip rendering at sizes < 3 px --- python/core/qgspallabeling.sip | 3 + src/app/qgslabelinggui.cpp | 40 ++- src/app/qgslabelinggui.h | 3 + src/core/qgspallabeling.cpp | 62 +++-- src/core/qgspallabeling.h | 3 + src/ui/qgslabelingguibase.ui | 475 ++++++++++++++++++++++++--------- 6 files changed, 444 insertions(+), 142 deletions(-) diff --git a/python/core/qgspallabeling.sip b/python/core/qgspallabeling.sip index f3c9e8b7d93..bd07d4d65cc 100644 --- a/python/core/qgspallabeling.sip +++ b/python/core/qgspallabeling.sip @@ -121,6 +121,9 @@ class QgsPalLayerSettings 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 fontLimitPixelSize; // true is label should be limited by fontMinPixelSize/fontMaxPixelSize + int fontMinPixelSize; // minimum pixel size for showing rendered map unit labels (1 - 1000) + int fontMaxPixelSize; // maximum pixel size for showing rendered map unit labels (1 - 10000) 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) bool distInMapUnits; //true if distance is in map units (otherwise in mm) diff --git a/src/app/qgslabelinggui.cpp b/src/app/qgslabelinggui.cpp index 2a4efc338b4..61c05278e26 100644 --- a/src/app/qgslabelinggui.cpp +++ b/src/app/qgslabelinggui.cpp @@ -239,6 +239,12 @@ QgsLabelingGui::QgsLabelingGui( QgsPalLabeling* lbl, QgsVectorLayer* layer, QgsM chkPlusSign->setChecked( plusSign ); } + // set pixel size limiting checked state before unit choice so limiting can be + // turned on as a default for map units, if minimum trigger value of 0 is used + mFontLimitPixelGroupBox->setChecked( lyr.fontLimitPixelSize ); + mMinPixelLimit = lyr.fontMinPixelSize; // ignored after first settings save + mFontMinPixelSpinBox->setValue( lyr.fontMinPixelSize == 0 ? 3 : lyr.fontMinPixelSize ); + mFontMaxPixelSpinBox->setValue( lyr.fontMaxPixelSize ); if ( lyr.fontSizeInMapUnits ) { mFontSizeUnitComboBox->setCurrentIndex( 1 ); @@ -465,6 +471,9 @@ QgsPalLayerSettings QgsLabelingGui::layerSettings() } lyr.minFeatureSize = mMinSizeSpinBox->value(); lyr.fontSizeInMapUnits = ( mFontSizeUnitComboBox->currentIndex() == 1 ); + lyr.fontLimitPixelSize = mFontLimitPixelGroupBox->isChecked(); + lyr.fontMinPixelSize = mFontMinPixelSpinBox->value(); + lyr.fontMaxPixelSize = mFontMaxPixelSpinBox->value(); lyr.wrapChar = wrapCharacterEdit->text(); lyr.multilineHeight = mFontLineHeightSpinBox->value(); lyr.multilineAlign = ( QgsPalLayerSettings::MultiLineAlign ) mFontMultiLineComboBox->currentIndex(); @@ -1004,10 +1013,39 @@ void QgsLabelingGui::on_mFontLetterSpacingSpinBox_valueChanged( double spacing ) void QgsLabelingGui::on_mFontSizeUnitComboBox_currentIndexChanged( int index ) { - Q_UNUSED( index ); + // disable pixel size limiting for labels defined in points + if ( index == 0 ) + { + mFontLimitPixelGroupBox->setChecked( false ); + } + else if ( index == 1 && mMinPixelLimit == 0 ) + { + // initial minimum trigger value set, turn on pixel size limiting by default + // for labels defined in map units (ignored after first settings save) + mFontLimitPixelGroupBox->setChecked( true ); + } updateFont( mRefFont ); } +void QgsLabelingGui::on_mFontMinPixelSpinBox_valueChanged( int px ) +{ + // ensure max font pixel size for map unit labels can't be lower than min + mFontMaxPixelSpinBox->setMinimum( px ); + mFontMaxPixelSpinBox->update(); +} + +void QgsLabelingGui::on_mFontMaxPixelSpinBox_valueChanged( int px ) +{ + // ensure max font pixel size for map unit labels can't be lower than min + if ( px < mFontMinPixelSpinBox->value() ) + { + mFontMaxPixelSpinBox->blockSignals( true ); + mFontMaxPixelSpinBox->setValue( mFontMinPixelSpinBox->value() ); + mFontMaxPixelSpinBox->blockSignals( false ); + } + mFontMaxPixelSpinBox->setMinimum( mFontMinPixelSpinBox->value() ); +} + void QgsLabelingGui::on_mBufferUnitComboBox_currentIndexChanged( int index ) { Q_UNUSED( index ); diff --git a/src/app/qgslabelinggui.h b/src/app/qgslabelinggui.h index 4ed27965103..a8396ac2ecc 100644 --- a/src/app/qgslabelinggui.h +++ b/src/app/qgslabelinggui.h @@ -61,6 +61,8 @@ class QgsLabelingGui : public QWidget, private Ui::QgsLabelingGuiBase void on_mFontWordSpacingSpinBox_valueChanged( double spacing ); void on_mFontLetterSpacingSpinBox_valueChanged( double spacing ); void on_mFontSizeUnitComboBox_currentIndexChanged( int index ); + void on_mFontMinPixelSpinBox_valueChanged( int px ); + void on_mFontMaxPixelSpinBox_valueChanged( int px ); void on_mBufferUnitComboBox_currentIndexChanged( int index ); void on_mXCoordinateComboBox_currentIndexChanged( const QString & text ); void on_mYCoordinateComboBox_currentIndexChanged( const QString & text ); @@ -95,6 +97,7 @@ class QgsLabelingGui : public QWidget, private Ui::QgsLabelingGuiBase int mXQuadOffset; int mYQuadOffset; + int mMinPixelLimit; void disableDataDefinedAlignment(); void enableDataDefinedAlignment(); diff --git a/src/core/qgspallabeling.cpp b/src/core/qgspallabeling.cpp index bce04129500..9e9ffb65eb9 100644 --- a/src/core/qgspallabeling.cpp +++ b/src/core/qgspallabeling.cpp @@ -215,6 +215,9 @@ QgsPalLayerSettings::QgsPalLayerSettings() addDirectionSymbol = false; upsidedownLabels = Upright; fontSizeInMapUnits = false; + fontLimitPixelSize = false; + fontMinPixelSize = 0; //trigger to turn it on by default for map unit labels + fontMaxPixelSize = 10000; bufferSizeInMapUnits = false; labelOffsetInMapUnits = true; distInMapUnits = false; @@ -265,6 +268,9 @@ QgsPalLayerSettings::QgsPalLayerSettings( const QgsPalLayerSettings& s ) addDirectionSymbol = s.addDirectionSymbol; upsidedownLabels = s.upsidedownLabels; fontSizeInMapUnits = s.fontSizeInMapUnits; + fontLimitPixelSize = s.fontLimitPixelSize; + fontMinPixelSize = s.fontMinPixelSize; + fontMaxPixelSize = s.fontMaxPixelSize; bufferSizeInMapUnits = s.bufferSizeInMapUnits; distInMapUnits = s.distInMapUnits; labelOffsetInMapUnits = s.labelOffsetInMapUnits; @@ -448,6 +454,9 @@ void QgsPalLayerSettings::readFromLayer( QgsVectorLayer* layer ) upsidedownLabels = ( UpsideDownLabels ) layer->customProperty( "labeling/upsidedownLabels", QVariant( Upright ) ).toUInt(); minFeatureSize = layer->customProperty( "labeling/minFeatureSize" ).toDouble(); fontSizeInMapUnits = layer->customProperty( "labeling/fontSizeInMapUnits" ).toBool(); + fontLimitPixelSize = layer->customProperty( "labeling/fontLimitPixelSize", QVariant( false ) ).toBool(); + fontMinPixelSize = layer->customProperty( "labeling/fontMinPixelSize", QVariant( 0 ) ).toInt(); + fontMaxPixelSize = layer->customProperty( "labeling/fontMaxPixelSize", QVariant( 10000 ) ).toInt(); bufferSizeInMapUnits = layer->customProperty( "labeling/bufferSizeInMapUnits" ).toBool(); distInMapUnits = layer->customProperty( "labeling/distInMapUnits" ).toBool(); labelOffsetInMapUnits = layer->customProperty( "labeling/labelOffsetInMapUnits", QVariant( true ) ).toBool(); @@ -509,6 +518,9 @@ void QgsPalLayerSettings::writeToLayer( QgsVectorLayer* layer ) layer->setCustomProperty( "labeling/upsidedownLabels", ( unsigned int )upsidedownLabels ); layer->setCustomProperty( "labeling/minFeatureSize", minFeatureSize ); layer->setCustomProperty( "labeling/fontSizeInMapUnits", fontSizeInMapUnits ); + layer->setCustomProperty( "labeling/fontLimitPixelSize", fontLimitPixelSize ); + layer->setCustomProperty( "labeling/fontMinPixelSize", fontMinPixelSize ); + layer->setCustomProperty( "labeling/fontMaxPixelSize", fontMaxPixelSize ); layer->setCustomProperty( "labeling/bufferSizeInMapUnits", bufferSizeInMapUnits ); layer->setCustomProperty( "labeling/distInMapUnits", distInMapUnits ); layer->setCustomProperty( "labeling/labelOffsetInMapUnits", labelOffsetInMapUnits ); @@ -658,6 +670,33 @@ void QgsPalLayerSettings::registerFeature( QgsVectorLayer* layer, QgsFeature& f } } + QFont labelFont = textFont; + + //data defined label size? + QMap< DataDefinedProperties, int >::const_iterator it = dataDefinedProperties.find( QgsPalLayerSettings::Size ); + if ( it != dataDefinedProperties.constEnd() ) + { + //find out size + QVariant size = f.attributeMap().value( *it ); + if ( size.isValid() ) + { + double sizeDouble = size.toDouble(); + if ( sizeDouble <= 0.0 || sizeToPixel( sizeDouble, context ) < 1 ) + { + return; + } + labelFont.setPixelSize( sizeToPixel( sizeDouble, context ) ); + } + } + + // defined 'minimum/maximum pixel font size' option + // TODO: add any data defined setting to override fontMinPixelSize/fontMaxPixelSize + if ( fontLimitPixelSize && fontSizeInMapUnits && + ( fontMinPixelSize > labelFont.pixelSize() || labelFont.pixelSize() > fontMaxPixelSize ) ) + { + return; + } + QString labelText; // Check to see if we are a expression string. @@ -695,28 +734,9 @@ void QgsPalLayerSettings::registerFeature( QgsVectorLayer* layer, QgsFeature& f labelText = f.attributeMap()[fieldIndex].toString(); } - double labelX, labelY; // will receive label size - QFont labelFont = textFont; - - //data defined label size? - QMap< DataDefinedProperties, int >::const_iterator it = dataDefinedProperties.find( QgsPalLayerSettings::Size ); - if ( it != dataDefinedProperties.constEnd() ) - { - //find out size - QVariant size = f.attributeMap().value( *it ); - if ( size.isValid() ) - { - double sizeDouble = size.toDouble(); - if ( sizeDouble <= 0.0 || sizeToPixel( sizeDouble, context ) < 1 ) - { - return; - } - labelFont.setPixelSize( sizeToPixel( sizeDouble, context ) ); - } - } - - // this should come after any data defined option that affects font metrics + // this should come AFTER any data defined option that affects font metrics QFontMetricsF* labelFontMetrics = new QFontMetricsF( labelFont ); + double labelX, labelY; // will receive label size calculateLabelSize( labelFontMetrics, labelText, labelX, labelY ); QgsGeometry* geom = f.geometry(); diff --git a/src/core/qgspallabeling.h b/src/core/qgspallabeling.h index f06a211aff8..7660ece6ed6 100644 --- a/src/core/qgspallabeling.h +++ b/src/core/qgspallabeling.h @@ -175,6 +175,9 @@ class CORE_EXPORT QgsPalLayerSettings 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 fontLimitPixelSize; // true is label should be limited by fontMinPixelSize/fontMaxPixelSize + int fontMinPixelSize; // minimum pixel size for showing rendered map unit labels (1 - 1000) + int fontMaxPixelSize; // maximum pixel size for showing rendered map unit labels (1 - 10000) 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) bool distInMapUnits; //true if distance is in map units (otherwise in mm) diff --git a/src/ui/qgslabelingguibase.ui b/src/ui/qgslabelingguibase.ui index 377dc2ae5b4..96f6365b1a8 100644 --- a/src/ui/qgslabelingguibase.ui +++ b/src/ui/qgslabelingguibase.ui @@ -449,9 +449,9 @@ 0 - -162 + -365 686 - 628 + 714 @@ -461,7 +461,74 @@ 20 - + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Formatted numbers + + + true + + + + + + + 0 + 0 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 468 + 20 + + + + + + + + Decimal places + + + + + + + Qt::RightToLeft + + + Show plus sign + + + + + + + @@ -919,6 +986,28 @@ + + + + true + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Capitalization style of text + + + @@ -951,7 +1040,7 @@ true - + 0 0 @@ -986,24 +1075,14 @@ - - - - true - - - - 16777215 - 16777215 - - - - Capitalization style of text - - - + + + 0 + 0 + + Space in pixels or map units, relative to size unit choice @@ -1319,7 +1398,158 @@ - + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + Pixel size-based visibility + + + true + + + + + + + 0 + 0 + + + + Labels will not show if larger than this on screen + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + px + + + Maximum + + + 1 + + + 10000 + + + 10000 + + + + + + + + 0 + 0 + + + + Labels will not show if smaller than this on screen + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + px + + + Minimum + + + 1 + + + 1000 + + + 3 + + + + + + + + 0 + 0 + + + + < + + + + + + + + 0 + 0 + + + + background-color: rgb(243, 243, 243); + + + QFrame::StyledPanel + + + Label in Map Units + + + Qt::AlignCenter + + + 1 + + + + + + + + 0 + 0 + + + + < + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + @@ -1327,6 +1557,12 @@ 0 + + + 0 + 0 + + 16777215 @@ -1339,9 +1575,18 @@ true - + + + + 0 + 0 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Minimum @@ -1354,7 +1599,67 @@ + + + + 0 + 0 + + + + < + + + + + + + + 0 + 0 + + + + background-color: rgb(243, 243, 243); + + + QFrame::StyledPanel + + + Label + + + Qt::AlignCenter + + + 1 + + + + + + + + 0 + 0 + + + + < + + + + + + + 0 + 0 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Maximum @@ -1369,14 +1674,14 @@ - + Qt::Horizontal - 307 + 40 20 @@ -1385,76 +1690,6 @@ - - - - Qt::Vertical - - - - 20 - 0 - - - - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - Formatted numbers - - - true - - - - - - - - - Qt::Horizontal - - - - 468 - 20 - - - - - - - - Decimal places - - - - - - - Qt::RightToLeft - - - Show plus sign - - - - - - @@ -1493,7 +1728,7 @@ 0 0 - 636 + 686 553 @@ -2355,7 +2590,7 @@ 0 0 - 488 + 686 951 @@ -2823,8 +3058,8 @@ setEnabled(bool) - 84 - 33 + 94 + 30 214 @@ -2839,12 +3074,12 @@ setEnabled(bool) - 56 - 31 + 66 + 30 - 505 - 40 + 499 + 31 @@ -2855,8 +3090,8 @@ setEnabled(bool) - 50 - 31 + 60 + 30 172 @@ -2871,12 +3106,12 @@ setValue(int) - 319 - 408 + 336 + 120 - 393 - 410 + 410 + 122 @@ -2888,11 +3123,11 @@ 319 - 547 + 259 391 - 549 + 261 @@ -2904,11 +3139,11 @@ 391 - 549 + 261 319 - 547 + 259 @@ -2919,12 +3154,12 @@ setValue(int) - 393 - 410 + 410 + 122 - 319 - 408 + 336 + 120 @@ -2935,8 +3170,8 @@ setVisible(bool) - 105 - 154 + 117 + 127 362 @@ -2951,8 +3186,8 @@ setVisible(bool) - 141 - 187 + 117 + 130 404