Expose "at equator" scale method in widget

When this method is selected, we show a warning icon with an
explanatory tooltip:

"This method will calculate misleading scales when the map extent
is not close to the equator, however it ensures that the scale
remains constant and does not change as the map is panned."
This commit is contained in:
Nyall Dawson 2025-03-20 14:24:47 +10:00
parent 9eb1ab27be
commit 12a1be86f2
4 changed files with 61 additions and 3 deletions

View File

@ -9,6 +9,7 @@
class QgsScaleMethodWidget : QWidget
{
%Docstring(signature="appended")

View File

@ -9,6 +9,7 @@
class QgsScaleMethodWidget : QWidget
{
%Docstring(signature="appended")

View File

@ -16,8 +16,11 @@
***************************************************************************/
#include "qgsscalemethodwidget.h"
#include "qgsapplication.h"
#include "moc_qgsscalemethodwidget.cpp"
#include <QHBoxLayout>
#include <QComboBox>
#include <QLabel>
QgsScaleMethodWidget::QgsScaleMethodWidget( QWidget *parent )
: QWidget( parent )
@ -29,16 +32,36 @@ QgsScaleMethodWidget::QgsScaleMethodWidget( QWidget *parent )
mCombo->addItem( tr( "Calculate along Top of Map" ), QVariant::fromValue( Qgis::ScaleCalculationMethod::HorizontalTop ) );
mCombo->addItem( tr( "Calculate along Middle of Map" ), QVariant::fromValue( Qgis::ScaleCalculationMethod::HorizontalMiddle ) );
mCombo->addItem( tr( "Calculate along Bottom of Map" ), QVariant::fromValue( Qgis::ScaleCalculationMethod::HorizontalBottom ) );
mCombo->addItem( tr( "Always Calculate at Equator" ), QVariant::fromValue( Qgis::ScaleCalculationMethod::AtEquator ) );
QHBoxLayout *hLayout = new QHBoxLayout();
hLayout->setContentsMargins( 0, 0, 0, 0 );
hLayout->addWidget( mCombo );
hLayout->addWidget( mCombo, 1 );
// bit of fiddlyness here -- we want the initial spacing to only be visible
// when the warning label is shown, so it's embedded inside mWarningLabel
// instead of outside it
mWarningLabelContainer = new QWidget();
QHBoxLayout *warningLayout = new QHBoxLayout();
warningLayout->setContentsMargins( 0, 0, 0, 0 );
mWarningLabel = new QLabel();
const QIcon icon = QgsApplication::getThemeIcon( QStringLiteral( "mIconWarning.svg" ) );
const int size = static_cast<int>( std::max( 24.0, mCombo->minimumSize().height() * 0.5 ) );
mWarningLabel->setPixmap( icon.pixmap( icon.actualSize( QSize( size, size ) ) ) );
const int labelMargin = static_cast<int>( std::round( mCombo->fontMetrics().horizontalAdvance( 'X' ) ) );
warningLayout->insertSpacing( 0, labelMargin / 2 );
warningLayout->insertWidget( 1, mWarningLabel );
mWarningLabelContainer->setLayout( warningLayout );
hLayout->addWidget( mWarningLabelContainer );
mWarningLabelContainer->hide();
setLayout( hLayout );
setFocusPolicy( Qt::FocusPolicy::StrongFocus );
setFocusProxy( mCombo );
connect( mCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, &QgsScaleMethodWidget::methodChanged );
connect( mCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, &QgsScaleMethodWidget::updateWarning );
}
Qgis::ScaleCalculationMethod QgsScaleMethodWidget::scaleMethod() const
@ -49,4 +72,30 @@ Qgis::ScaleCalculationMethod QgsScaleMethodWidget::scaleMethod() const
void QgsScaleMethodWidget::setScaleMethod( Qgis::ScaleCalculationMethod method )
{
mCombo->setCurrentIndex( mCombo->findData( QVariant::fromValue( method ) ) );
updateWarning();
}
void QgsScaleMethodWidget::updateWarning()
{
switch ( scaleMethod() )
{
case Qgis::ScaleCalculationMethod::HorizontalTop:
case Qgis::ScaleCalculationMethod::HorizontalMiddle:
case Qgis::ScaleCalculationMethod::HorizontalBottom:
case Qgis::ScaleCalculationMethod::HorizontalAverage:
mWarningLabelContainer->hide();
break;
case Qgis::ScaleCalculationMethod::AtEquator:
{
mWarningLabelContainer->show();
const QString warning = QStringLiteral( "<p>%1</p><p>%2</p>" ).arg( tr( "This method will calculate misleading scales when the map extent is not close to the "
"equator, however it ensures that the scale remains constant and does not "
"change as the map is panned." ),
tr( "This setting is valid for maps in a geographic (latitude/longitude) CRS only." ) );
mWarningLabel->setToolTip( warning );
break;
}
}
}

View File

@ -18,10 +18,12 @@
#ifndef QGSSCALEMETHODWIDGET_H
#define QGSSCALEMETHODWIDGET_H
#include <QComboBox>
#include "qgis_sip.h"
#include <QPainter> // For QPainter::CompositionMode enum
#include "qgis_gui.h"
#include <QWidget>
class QLabel;
class QComboBox;
/**
* \ingroup gui
@ -56,6 +58,11 @@ class GUI_EXPORT QgsScaleMethodWidget : public QWidget
private:
QComboBox *mCombo = nullptr;
QWidget *mWarningLabelContainer = nullptr;
QLabel *mWarningLabel = nullptr;
private slots:
void updateWarning();
};
#endif // QGSSCALEMETHODWIDGET_H