From 11b9f842e5262b2f0c5c0c4d58963d44641dda4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Sun, 26 May 2024 11:19:19 +0200 Subject: [PATCH] Added hillshading settings --- src/GUI/gui.cpp | 31 ++++++++++++++++++++ src/GUI/optionsdialog.cpp | 49 ++++++++++++++++++++++++++++++-- src/GUI/optionsdialog.h | 10 +++++++ src/GUI/settings.cpp | 5 ++++ src/GUI/settings.h | 5 ++++ src/map/IMG/rastertile.cpp | 13 +++++---- src/map/hillshading.cpp | 17 +++++++---- src/map/hillshading.h | 18 ++++++++++-- src/map/mapsforge/rastertile.cpp | 12 +++++--- 9 files changed, 140 insertions(+), 20 deletions(-) diff --git a/src/GUI/gui.cpp b/src/GUI/gui.cpp index fd857b3d..2e22fcbf 100644 --- a/src/GUI/gui.cpp +++ b/src/GUI/gui.cpp @@ -36,6 +36,7 @@ #include "map/maplist.h" #include "map/emptymap.h" #include "map/crs.h" +#include "map/hillshading.h" #include "icons.h" #include "keys.h" #include "settings.h" @@ -2632,6 +2633,11 @@ void GUI::writeSettings() WRITE(demAuthentication, _options.demAuthorization); WRITE(demUsername, _options.demUsername); WRITE(demPassword, _options.demPassword); + WRITE(hillshadingAlpha, _options.hillshadingAlpha); + WRITE(hillshadingBlur, _options.hillshadingBlur); + WRITE(hillshadingAzimuth, _options.hillshadingAzimuth); + WRITE(hillshadingAltitude, _options.hillshadingAltitude); + WRITE(hillshadingZFactor, _options.hillshadingZFactor); WRITE(positionPlugin(), _options.plugin); WRITE(positionPluginParameters, _options.pluginParams); WRITE(useOpenGL, _options.useOpenGL); @@ -2932,6 +2938,11 @@ void GUI::readSettings(QString &activeMap, QStringList &disabledPOIs, _options.demAuthorization = READ(demAuthentication).toBool(); _options.demUsername = READ(demUsername).toString(); _options.demPassword = READ(demPassword).toString(); + _options.hillshadingAlpha = READ(hillshadingAlpha).toInt(); + _options.hillshadingBlur = READ(hillshadingBlur).toInt(); + _options.hillshadingAzimuth = READ(hillshadingAzimuth).toInt(); + _options.hillshadingAltitude = READ(hillshadingAltitude).toInt(); + _options.hillshadingZFactor = READ(hillshadingZFactor).toDouble(); _options.plugin = READ(positionPlugin()).toString(); _options.pluginParams = READ(positionPluginParameters); _options.useOpenGL = READ(useOpenGL).toBool(); @@ -3026,6 +3037,12 @@ void GUI::loadOptions() DEM::setCacheSize(_options.demCache * 1024); DEM::unlock(); + HillShading::setAlpha(_options.hillshadingAlpha); + HillShading::setBlur(_options.hillshadingBlur); + HillShading::setAzimuth(_options.hillshadingAzimuth); + HillShading::setAltitude(_options.hillshadingAltitude); + HillShading::setZFactor(_options.hillshadingZFactor); + _poi->setRadius(_options.poiRadius); _dem->setUrl(_options.demURL); @@ -3062,8 +3079,14 @@ void GUI::updateOptions(const Options &options) Waypoint::action(options.option); \ reload = true; \ } +#define SET_HS_OPTION(option, action) \ + if (options.option != _options.option) { \ + HillShading::action(options.option); \ + redraw = true; \ + } bool reload = false; + bool redraw = false; SET_VIEW_OPTION(palette, setPalette); SET_VIEW_OPTION(mapOpacity, setMapOpacity); @@ -3155,6 +3178,12 @@ void GUI::updateOptions(const Options &options) DEM::unlock(); } + SET_HS_OPTION(hillshadingAlpha, setAlpha); + SET_HS_OPTION(hillshadingBlur, setBlur); + SET_HS_OPTION(hillshadingAzimuth, setAzimuth); + SET_HS_OPTION(hillshadingAltitude, setAltitude); + SET_HS_OPTION(hillshadingZFactor, setZFactor); + if (options.connectionTimeout != _options.connectionTimeout) Downloader::setTimeout(options.connectionTimeout); if (options.enableHTTP2 != _options.enableHTTP2) @@ -3169,6 +3198,8 @@ void GUI::updateOptions(const Options &options) if (reload) reloadFiles(); + if (redraw) + _mapView->setMap(_map); _options = options; diff --git a/src/GUI/optionsdialog.cpp b/src/GUI/optionsdialog.cpp index 4205acc0..88fa66e9 100644 --- a/src/GUI/optionsdialog.cpp +++ b/src/GUI/optionsdialog.cpp @@ -135,18 +135,21 @@ QWidget *OptionsDialog::createAppearancePage() { // Tracks _trackWidth = new QSpinBox(); - _trackWidth->setValue(_options.trackWidth); _trackWidth->setMinimum(1); + _trackWidth->setSuffix(UNIT_SPACE + tr("px")); + _trackWidth->setValue(_options.trackWidth); _trackStyle = new StyleComboBox(); _trackStyle->setValue(_options.trackStyle); // Routes _routeWidth = new QSpinBox(); - _routeWidth->setValue(_options.routeWidth); _routeWidth->setMinimum(1); + _routeWidth->setSuffix(UNIT_SPACE + tr("px")); + _routeWidth->setValue(_options.routeWidth); _routeStyle = new StyleComboBox(); _routeStyle->setValue(_options.routeStyle); // Areas _areaWidth = new QSpinBox(); + _areaWidth->setSuffix(UNIT_SPACE + tr("px")); _areaWidth->setValue(_options.areaWidth); _areaStyle = new StyleComboBox(); _areaStyle->setValue(_options.areaStyle); @@ -214,12 +217,14 @@ QWidget *OptionsDialog::createAppearancePage() // Waypoints _waypointSize = new QSpinBox(); _waypointSize->setMinimum(1); + _waypointSize->setSuffix(UNIT_SPACE + tr("px")); _waypointSize->setValue(_options.waypointSize); _waypointColor = new ColorBox(); _waypointColor->setColor(_options.waypointColor); // POI _poiSize = new QSpinBox(); _poiSize->setMinimum(1); + _poiSize->setSuffix(UNIT_SPACE + tr("px")); _poiSize->setValue(_options.poiSize); _poiColor = new ColorBox(); _poiColor->setColor(_options.poiColor); @@ -256,8 +261,9 @@ QWidget *OptionsDialog::createAppearancePage() _sliderColor = new ColorBox(); _sliderColor->setColor(_options.sliderColor); _graphWidth = new QSpinBox(); - _graphWidth->setValue(_options.graphWidth); _graphWidth->setMinimum(1); + _graphWidth->setSuffix(UNIT_SPACE + tr("px")); + _graphWidth->setValue(_options.graphWidth); _graphAA = new QCheckBox(tr("Use anti-aliasing")); _graphAA->setChecked(_options.graphAntiAliasing); @@ -612,8 +618,39 @@ QWidget *OptionsDialog::createDEMPage() sourceTab->setLayout(sourceLayout); #endif // Q_OS_MAC + _hillshadingAlpha = new PercentSlider(); + _hillshadingAlpha->setValue(qRound((_options.hillshadingAlpha / 255.0) + * 100)); + _hillshadingBlur = new QSpinBox(); + _hillshadingBlur->setMaximum(10); + _hillshadingBlur->setSuffix(UNIT_SPACE + tr("px")); + _hillshadingBlur->setValue(_options.hillshadingBlur); + _hillshadingAzimuth = new QSpinBox(); + _hillshadingAzimuth->setMaximum(360); + _hillshadingAzimuth->setSuffix(UNIT_SPACE + QChar(0x00B0)); + _hillshadingAzimuth->setValue(_options.hillshadingAzimuth); + _hillshadingAltitude = new QSpinBox(); + _hillshadingAltitude->setMaximum(90); + _hillshadingAltitude->setSuffix(UNIT_SPACE + QChar(0x00B0)); + _hillshadingAltitude->setValue(_options.hillshadingAltitude); + _hillshadingZFactor = new QDoubleSpinBox(); + _hillshadingZFactor->setDecimals(1); + _hillshadingZFactor->setSingleStep(0.1); + _hillshadingZFactor->setValue(_options.hillshadingZFactor); + + QFormLayout *hillshadingLayout = new QFormLayout(); + hillshadingLayout->addRow(tr("Opacity:"), _hillshadingAlpha); + hillshadingLayout->addRow(tr("Blur radius:"), _hillshadingBlur); + hillshadingLayout->addItem(new QSpacerItem(10, 10)); + hillshadingLayout->addRow(tr("Azimuth:"), _hillshadingAzimuth); + hillshadingLayout->addRow(tr("Altitude:"), _hillshadingAltitude); + hillshadingLayout->addRow(tr("Z Factor:"), _hillshadingZFactor); + QWidget *hillshadingTab = new QWidget(); + hillshadingTab->setLayout(hillshadingLayout); + QTabWidget *demPage = new QTabWidget(); demPage->addTab(sourceTab, tr("Source")); + demPage->addTab(hillshadingTab, tr("Hillshading")); return demPage; } @@ -948,6 +985,12 @@ void OptionsDialog::accept() _options.demAuthorization = _demAuth->isEnabled(); _options.demUsername = _demAuth->username(); _options.demPassword = _demAuth->password(); + _options.hillshadingAlpha = qRound((_hillshadingAlpha->value() / 100.0) + * 255); + _options.hillshadingBlur = _hillshadingBlur->value(); + _options.hillshadingAzimuth = _hillshadingAzimuth->value(); + _options.hillshadingAltitude = _hillshadingAltitude->value(); + _options.hillshadingZFactor = _hillshadingZFactor->value(); _options.plugin = _positionPlugin->currentText(); #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) diff --git a/src/GUI/optionsdialog.h b/src/GUI/optionsdialog.h index 847f9252..23a228ac 100644 --- a/src/GUI/optionsdialog.h +++ b/src/GUI/optionsdialog.h @@ -72,6 +72,11 @@ struct Options { QString demUsername; QString demPassword; bool demAuthorization; + int hillshadingAlpha; + int hillshadingBlur; + int hillshadingAzimuth; + int hillshadingAltitude; + double hillshadingZFactor; // Position QString plugin; QMap pluginParams; @@ -176,6 +181,11 @@ private: // DEM QLineEdit *_demURL; AuthenticationWidget *_demAuth; + PercentSlider *_hillshadingAlpha; + QSpinBox *_hillshadingBlur; + QSpinBox *_hillshadingAzimuth; + QSpinBox *_hillshadingAltitude; + QDoubleSpinBox *_hillshadingZFactor; // Position QComboBox *_positionPlugin; #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) diff --git a/src/GUI/settings.cpp b/src/GUI/settings.cpp index 1e6a41e3..a5950271 100644 --- a/src/GUI/settings.cpp +++ b/src/GUI/settings.cpp @@ -244,6 +244,11 @@ SETTING(demURL, "demURL", DEM_TILES_URL ); SETTING(demAuthentication, "demAuthentication", false ); SETTING(demUsername, "demUsername", "" ); SETTING(demPassword, "demPassword", "" ); +SETTING(hillshadingAlpha, "hillshadingAlpha", 102 ); +SETTING(hillshadingBlur, "hillshadingBlur", 3 ); +SETTING(hillshadingAzimuth, "hillshadingAzimuth", 315 ); +SETTING(hillshadingAltitude, "hillshadingAltitude", 45 ); +SETTING(hillshadingZFactor, "hillshadingZFactor", 0.6 ); SETTING(useOpenGL, "useOpenGL", false ); SETTING(enableHTTP2, "enableHTTP2", true ); SETTING(pixmapCache, "pixmapCache", PIXMAP_CACHE ); diff --git a/src/GUI/settings.h b/src/GUI/settings.h index 1ab70acb..fdf58680 100644 --- a/src/GUI/settings.h +++ b/src/GUI/settings.h @@ -196,6 +196,11 @@ public: static const Setting demAuthentication; static const Setting demUsername; static const Setting demPassword; + static const Setting hillshadingAlpha; + static const Setting hillshadingBlur; + static const Setting hillshadingAzimuth; + static const Setting hillshadingAltitude; + static const Setting hillshadingZFactor; static const Setting useOpenGL; static const Setting enableHTTP2; static const Setting pixmapCache; diff --git a/src/map/IMG/rastertile.cpp b/src/map/IMG/rastertile.cpp index 2d6cf953..e4e0503a 100644 --- a/src/map/IMG/rastertile.cpp +++ b/src/map/IMG/rastertile.cpp @@ -29,8 +29,6 @@ using namespace IMG; #define ROAD 0 #define WATER 1 -#define BLUR_RADIUS 3 - static const QColor textColor(Qt::black); static const QColor haloColor(Qt::white); static const QColor shieldColor(Qt::white); @@ -498,9 +496,14 @@ MatrixD RasterTile::elevation(int extend) const void RasterTile::drawHillShading(QPainter *painter) const { if (_hillShading && _zoom >= 18 && _zoom <= 24) { - MatrixD dem(Filter::blur(elevation(BLUR_RADIUS + 1), BLUR_RADIUS)); - QImage img(HillShading::render(dem, BLUR_RADIUS + 1)); - painter->drawImage(_rect.x(), _rect.y(), img); + if (HillShading::blur()) { + MatrixD dem(Filter::blur(elevation(HillShading::blur() + 1), + HillShading::blur())); + QImage img(HillShading::render(dem, HillShading::blur() + 1)); + painter->drawImage(_rect.x(), _rect.y(), img); + } else + painter->drawImage(_rect.x(), _rect.y(), + HillShading::render(elevation(1), 1)); } } diff --git a/src/map/hillshading.cpp b/src/map/hillshading.cpp index c0b80625..66baf8f5 100644 --- a/src/map/hillshading.cpp +++ b/src/map/hillshading.cpp @@ -26,6 +26,12 @@ struct Derivatives double dzdy; }; +int HillShading::_alpha = 96; +int HillShading::_blur = 3; +int HillShading::_azimuth = 315; +int HillShading::_altitude = 45; +double HillShading::_z = 0.6; + static void getConstants(double azimuth, double elevation, Constants &c) { double alpha = (M_PI / 180.0) * azimuth; @@ -59,8 +65,7 @@ static void getSubmatrix(int x, int y, const MatrixD &m, SubMatrix &sm) sm.z9 = m.at(bottom, right); } -QImage HillShading::render(const MatrixD &m, int extend, quint8 alpha, double z, - double azimuth, double elevation) +QImage HillShading::render(const MatrixD &m, int extend) { QImage img(m.w() - 2 * extend, m.h() - 2 * extend, QImage::Format_ARGB32_Premultiplied); @@ -71,12 +76,12 @@ QImage HillShading::render(const MatrixD &m, int extend, quint8 alpha, double z, SubMatrix sm; Derivatives d; - getConstants(azimuth, elevation, c); + getConstants(_azimuth, _altitude, c); for (int y = extend; y < m.h() - extend; y++) { for (int x = extend; x < m.w() - extend; x++) { getSubmatrix(x, y, m, sm); - getDerivativesHorn(sm, z, d); + getDerivativesHorn(sm, _z, d); double L = (c.a1 - c.a2 * d.dzdx - c.a3 * d.dzdy) / sqrt(1.0 + d.dzdx * d.dzdx + d.dzdy * d.dzdy); @@ -86,8 +91,8 @@ QImage HillShading::render(const MatrixD &m, int extend, quint8 alpha, double z, pixel = 0; else { L = sqrt(L * 0.8 + 0.2); - quint8 val = (L < 0) ? 0 : L * alpha; - pixel = (alpha - val)<<24; + quint8 val = (L < 0) ? 0 : L * _alpha; + pixel = (_alpha - val)<<24; } *(quint32*)(bits + (y - extend) * bpl + (x - extend) * 4) = pixel; diff --git a/src/map/hillshading.h b/src/map/hillshading.h index 549da1d4..a3bfab1e 100644 --- a/src/map/hillshading.h +++ b/src/map/hillshading.h @@ -7,8 +7,22 @@ class HillShading { public: - static QImage render(const MatrixD &m, int extend, quint8 alpha = 96, - double z = 0.6, double azimuth = 315, double elevation = 45); + static QImage render(const MatrixD &m, int extend); + + static int blur() {return _blur;} + + static void setAlpha(int alpha) {_alpha = alpha;} + static void setBlur(int blur) {_blur = blur;} + static void setAzimuth(int azimuth) {_azimuth = azimuth;} + static void setAltitude(int altitude) {_altitude = altitude;} + static void setZFactor(double z) {_z = z;} + +private: + static int _alpha; + static int _blur; + static int _azimuth; + static int _altitude; + static double _z; }; #endif // HILLSHADING_H diff --git a/src/map/mapsforge/rastertile.cpp b/src/map/mapsforge/rastertile.cpp index 3170d22f..e068e755 100644 --- a/src/map/mapsforge/rastertile.cpp +++ b/src/map/mapsforge/rastertile.cpp @@ -442,10 +442,14 @@ void RasterTile::drawPaths(QPainter *painter, const QList &paths, painter->drawEllipse(ll2xy(point->coordinates), radius, radius); } else { if (_hillShading) { - MatrixD dem(Filter::blur(elevation(BLUR_RADIUS + 1), - BLUR_RADIUS)); - QImage img(HillShading::render(dem, BLUR_RADIUS + 1)); - painter->drawImage(_rect.x(), _rect.y(), img); + if (HillShading::blur()) { + MatrixD dem(Filter::blur(elevation(HillShading::blur() + 1), + HillShading::blur())); + QImage img(HillShading::render(dem, HillShading::blur() + 1)); + painter->drawImage(_rect.x(), _rect.y(), img); + } else + painter->drawImage(_rect.x(), _rect.y(), + HillShading::render(elevation(1), 1)); } } }