Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

@@ -0,0 +1,603 @@
/**
**
** @RDE_HEADER@
** Handles aggregation of participant layer
** $Id$
** $HeadURL$
** $Author$
**
** -----------------------------------------------------------------------------------------------
**
** Hardware-Environment: Intel-PC
** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5
**
** Language ........: C++ 11
**
** -----------------------------------------------------------------------------------------------
**
** Author ...........: Jörg Turla, SPD G, Tel. 3132
**
** -----------------------------------------------------------------------------------------------
**
** Notes .........:
**
** 16.08.2017, JT : first edition
**
** -----------------------------------------------------------------------------------------------
*/
#include "layer_aggregation_widget.h"
#include <Map/map.h>
#include <Map/layer_parameter.h>
#include <LtsWidgets/lts_message_dialog.h>
#include <Common/situation_map_logging.h>
#include <QtCore/QMap>
#include <QtCore/QRegularExpression>
#include <QtCore/QString>
#include <QtCore/QVector>
#include <QtWidgets/QCheckBox>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QGridLayout>
#include <cmath>
using namespace SituationMap;
struct AggregationData
{
QString layerName;
QString displayName;
double minScale = LayerParameter::UNDEFINED_SCALE; // 0
double maxScale = LayerParameter::UNDEFINED_SCALE; // 0
bool minScaleValid = false;
bool maxScaleValid = false;
}; // AggregationData
struct AggregationWidgets
{
QCheckBox *cbMinScaleValid = nullptr;
QPushButton *pbMinScale = nullptr;
QPushButton *pbMinScaleTo = nullptr;
QCheckBox *cbMaxScaleValid = nullptr;
QPushButton *pbMaxScale = nullptr;
QPushButton *pbMaxScaleTo = nullptr;
QPushButton *pbReset = nullptr;
QPushButton *pbApply = nullptr;
};
class LayerAggregationWidget::InternalData
{
public:
Map *m_map = nullptr;
bool m_valid = false;
LayerType m_layerType;
QVector<AggregationData> m_aggregationList;
QMap<QString, AggregationData> m_aggregationReset;
QMap<QString, AggregationWidgets> m_aggregationWidgets;
LOGGER_T m_logger;
explicit InternalData(Map *map,LayerType layerType)
: m_map(map)
, m_layerType(layerType)
, m_logger(getLogger("LayerAggregation"))
{}
}; // LayerAggregationWidget::InternalData
//------------------------------------------------------------------------------
QString LayerAggregationWidget::scaleText(double scale)
{
return (scale >= 1) ? QStringLiteral("1:%1").arg(int(scale)) : tr("undefined");
} // QString LayerAggregationWidget::scaleText(double scale)
void LayerAggregationWidget::setMinScaleLabel(QPushButton *btn, double scale)
{
btn->setText(tr("Min. Scale from Map\n%1").arg(scaleText(scale)));
} // void LayerAggregationWidget::setMinScaleLabel(QPushButton * btn, double scale)
void LayerAggregationWidget::setMaxScaleLabel(QPushButton *btn, double scale)
{
btn->setText(tr("Max. Scale from Map\n%1").arg(scaleText(scale)));
} // void LayerAggregationWidget::setMaxScaleLabel(QPushButton * btn, double scale)
LayerAggregationWidget::LayerAggregationWidget(Map *map, LayerType layerType, const QRegularExpression &nameCondition, QWidget *parent)
: QWidget(parent), m_internal(new InternalData(map,layerType))
{
if (!nameCondition.isValid())
{
ERROR_LOG(m_internal->m_logger) << LOGFUNCTION << " Illegal regular expression in nameCondition.";
return;
}
if (map == nullptr)
{
ERROR_LOG(m_internal->m_logger) << LOGFUNCTION << " Invalid situation map, cannot initialize dialog";
return;
}
QGridLayout *layout = new QGridLayout(this);
layout->setSpacing(10);
const LayerFactory &layerFactory = map->layerFactory();
QIcon scaleToIcon(QStringLiteral("icon:search.svg"));
const auto ln = layerFactory.layernames(layerType);
for (const QString &layerName : ln)
{
if (nameCondition.match(layerName).hasMatch())
{
// get layer
AggregationData data;
AggregationWidgets &widgets = m_internal->m_aggregationWidgets[layerName];
const LayerParameter &layerPara = layerFactory.layerParameter(layerName);
data.layerName = layerName;
data.minScale = layerPara.minScale;
data.maxScale = layerPara.maxScale;
data.minScaleValid = layerPara.minScaleValid();
data.maxScaleValid = layerPara.maxScaleValid();
data.displayName = layerPara.displayName;
int row = m_internal->m_aggregationList.size();
QLabel *laName = new QLabel(layerPara.displayName.isEmpty() ? layerName : layerPara.displayName, this);
widgets.pbReset = new QPushButton(this);
widgets.pbApply = new QPushButton(this);
widgets.pbReset->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding));
widgets.pbApply->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding));
QHBoxLayout *minLayout = new QHBoxLayout();
minLayout->addSpacing(20);
minLayout->addWidget(widgets.cbMinScaleValid = new QCheckBox(QString(), this));
minLayout->addWidget(widgets.pbMinScale = new QPushButton(QString(), this));
minLayout->addWidget(widgets.pbMinScaleTo = new QPushButton(scaleToIcon, QString(), this));
minLayout->addSpacing(20);
setMinScaleLabel(widgets.pbMinScale, layerPara.minScale);
QHBoxLayout *maxLayout = new QHBoxLayout();
maxLayout->addWidget(widgets.cbMaxScaleValid = new QCheckBox(QString(), this));
maxLayout->addWidget(widgets.pbMaxScale = new QPushButton(QString(), this));
maxLayout->addWidget(widgets.pbMaxScaleTo = new QPushButton(scaleToIcon, QString(), this));
maxLayout->addSpacing(20);
setMaxScaleLabel(widgets.pbMaxScale, layerPara.maxScale);
widgets.pbMinScale->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding));
widgets.pbMaxScale->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding));
layout->addWidget(laName, row, 0);
layout->addLayout(minLayout, row, 1);
layout->addLayout(maxLayout, row, 2);
layout->addWidget(widgets.pbReset, row, 3);
layout->addWidget(widgets.pbApply, row, 4);
m_internal->m_aggregationList << data;
m_internal->m_aggregationReset[layerName] = data;
widgets.pbMinScale->setProperty("row", row);
widgets.pbMaxScale->setProperty("row", row);
widgets.cbMinScaleValid->setProperty("row", row);
widgets.cbMaxScaleValid->setProperty("row", row);
widgets.pbMinScaleTo->setProperty("row", row);
widgets.pbMaxScaleTo->setProperty("row", row);
widgets.pbReset->setProperty("row", row);
widgets.pbApply->setProperty("row", row);
connect(widgets.cbMinScaleValid, &QCheckBox::clicked, this, &LayerAggregationWidget::onSetValid);
connect(widgets.cbMaxScaleValid, &QCheckBox::clicked, this, &LayerAggregationWidget::onSetValid);
connect(widgets.pbMinScale, &QPushButton::clicked, this, &LayerAggregationWidget::onGetMinScale);
connect(widgets.pbMaxScale, &QPushButton::clicked, this, &LayerAggregationWidget::onGetMaxScale);
connect(widgets.pbMinScaleTo, &QPushButton::clicked, this, &LayerAggregationWidget::onZoomTo);
connect(widgets.pbMaxScaleTo, &QPushButton::clicked, this, &LayerAggregationWidget::onZoomTo);
connect(widgets.pbReset, &QPushButton::clicked, this, &LayerAggregationWidget::onReset);
connect(widgets.pbApply, &QPushButton::clicked, this, &LayerAggregationWidget::onApply);
widgets.cbMinScaleValid->setChecked(data.minScaleValid);
widgets.cbMinScaleValid->setEnabled(data.minScaleValid);
widgets.cbMaxScaleValid->setChecked(data.maxScaleValid);
widgets.cbMaxScaleValid->setEnabled(data.maxScaleValid);
widgets.pbMinScaleTo->setEnabled(data.minScaleValid);
widgets.pbMaxScaleTo->setEnabled(data.maxScaleValid);
widgets.pbReset->setEnabled(false);
widgets.pbApply->setEnabled(false);
}
}
retranslate();
if (m_internal->m_aggregationList.isEmpty())
{
QLabel *lbEmpty = new QLabel(tr("Can't find any layer"), this);
QPixmap icon(QStringLiteral("icon:overlays.svg"));
lbEmpty->setWindowIcon(icon);
layout->addWidget(lbEmpty, 0, 0, Qt::AlignCenter);
return;
}
} // LayerAggregation::LayerAggregation( Map * map, QObject * parent )
void LayerAggregationWidget::retranslate()
{
if (m_internal->m_map == nullptr)
return;
const LayerFactory &layerFactory = m_internal->m_map->layerFactory();
const auto ln = layerFactory.layernames(m_internal->m_layerType);
for (const QString &layerName : ln)
{
if (!m_internal->m_aggregationWidgets.contains(layerName)) continue;
AggregationWidgets &widgets = m_internal->m_aggregationWidgets[layerName];
widgets.pbReset->setText(tr("Reset"));
widgets.pbApply->setText(tr("Apply to Map"));
widgets.pbReset->setToolTip(tr("Restore initial scales of this level"));
widgets.pbApply->setToolTip(tr("Set scales to corresponding map layer temporarily"));
widgets.cbMinScaleValid->setToolTip(tr("Activate or deactivate this scale value"));
widgets.pbMinScale ->setToolTip(tr("Get current map scale of map view"));
widgets.pbMinScaleTo ->setToolTip(tr("Set this scale value to map view as current scale"));
widgets.cbMaxScaleValid->setToolTip(tr("Activate or deactivate this scale value"));
widgets.pbMaxScale ->setToolTip(tr("Get current map scale of map view"));
widgets.pbMaxScaleTo ->setToolTip(tr("Set this scale value to map view as current scale"));
}
} // void LayerAggregationWidget::retranslate()
LayerAggregationWidget::~LayerAggregationWidget()
{
delete m_internal; m_internal = nullptr;
} // LayerAggregationWidget::~LayerAggregationWidget()
void LayerAggregationWidget::onZoomTo()
{
QPushButton *senderButton = qobject_cast<QPushButton *>(sender());
if (nullptr == senderButton) return;
int row = senderButton->property("row").toInt();
if ((row < 0) || (row >= m_internal->m_aggregationList.size()))
return;
const AggregationData &data = m_internal->m_aggregationList[row];
const AggregationWidgets &widgets = m_internal->m_aggregationWidgets[data.layerName];
double scale = 0.0;
if ((widgets.pbMinScaleTo == senderButton) && (data.minScaleValid))
scale = data.minScale;
if ((widgets.pbMaxScaleTo == senderButton) && (data.maxScaleValid))
scale = data.maxScale;
if (scale < 1)
return;
m_internal->m_map->setScale(scale);
} // void LayerAggregationWidget::onZoomTo()
void LayerAggregationWidget::onGetMinScale()
{
QPushButton *senderButton = qobject_cast<QPushButton *>(sender());
if (nullptr == senderButton) return;
int row = senderButton->property("row").toInt();
if ((row < 0) || (row >= m_internal->m_aggregationList.size()))
return;
double scale = m_internal->m_map->scale();
AggregationData &data = m_internal->m_aggregationList[row];
if (data.maxScaleValid && (data.maxScale >= scale))
{
const QString &msg = tr("Chosen scale is too small");
LtsWidgets::LtsMessageDialog::showMessage(this, msg, tr("Layer Aggregation"));
return;
}
data.minScale = scale;
data.minScaleValid = true;
setMinScaleLabel(senderButton, data.minScale);
const AggregationWidgets &widgets = m_internal->m_aggregationWidgets[data.layerName];
widgets.cbMinScaleValid->setChecked(true);
widgets.cbMinScaleValid->setEnabled(true);
widgets.pbMinScaleTo->setEnabled(true);
widgets.pbReset->setEnabled(true);
widgets.pbApply->setEnabled(true);
emit changesMade();
} // void LayerAggregationWidget::onGetMinScale()
void LayerAggregationWidget::onGetMaxScale()
{
QPushButton *senderButton = qobject_cast<QPushButton *>(sender());
if (nullptr == senderButton) return;
int row = senderButton->property("row").toInt();
if ((row < 0) || (row >= m_internal->m_aggregationList.size()))
return;
double scale = m_internal->m_map->scale();
AggregationData &data = m_internal->m_aggregationList[row];
if (data.minScaleValid && (data.minScale <= scale))
{
const QString &msg = tr("Chosen scale is too large");
LtsWidgets::LtsMessageDialog::showMessage(this, msg, tr("Layer Aggregation"));
return;
}
data.maxScale = scale;
data.maxScaleValid = true;
setMaxScaleLabel(senderButton, data.maxScale);
const AggregationWidgets &widgets = m_internal->m_aggregationWidgets[data.layerName];
widgets.cbMaxScaleValid->setChecked(true);
widgets.cbMaxScaleValid->setEnabled(true);
widgets.pbMaxScaleTo->setEnabled(true);
widgets.pbReset->setEnabled(true);
widgets.pbApply->setEnabled(true);
emit changesMade();
} // void LayerAggregationWidget::onGetMaxScale()
void LayerAggregationWidget::onSetValid(bool value)
{
QCheckBox *senderButton = qobject_cast<QCheckBox *>(sender());
if (nullptr == senderButton) return;
int row = senderButton->property("row").toInt();
if ((row < 0) || (row >= m_internal->m_aggregationList.size()))
return;
AggregationData &data = m_internal->m_aggregationList[row];
const AggregationWidgets &widgets = m_internal->m_aggregationWidgets[data.layerName];
if (senderButton == widgets.cbMinScaleValid)
{
if (data.maxScaleValid && value && (data.maxScale >= data.minScale))
{
senderButton->setChecked(false);
const QString &msg = tr("Minimum scale is too small");
LtsWidgets::LtsMessageDialog::showMessage(this, msg, tr("Layer Aggregation"));
return;
}
data.minScaleValid = value;
}
if (senderButton == widgets.cbMaxScaleValid)
{
if (data.minScaleValid && value && (data.minScale <= data.maxScale))
{
senderButton->setChecked(false);
const QString &msg = tr("Maximum scale is too large");
LtsWidgets::LtsMessageDialog::showMessage(this, msg, tr("Layer Aggregation"));
return;
}
data.maxScaleValid = value;
}
widgets.pbMinScaleTo->setEnabled(data.minScaleValid);
widgets.pbMaxScaleTo->setEnabled(data.maxScaleValid);
widgets.pbReset->setEnabled(true);
widgets.pbApply->setEnabled(true);
emit changesMade();
} // void LayerAggregationWidget::onSetValid(bool value)
void LayerAggregationWidget::doReset(int row)
{
if ((row < 0) || (row >= m_internal->m_aggregationList.size()))
return;
AggregationData &data = m_internal->m_aggregationList[row];
data = m_internal->m_aggregationReset[data.layerName];
const AggregationWidgets &widgets = m_internal->m_aggregationWidgets[data.layerName];
setMinScaleLabel(widgets.pbMinScale, data.minScale);
setMaxScaleLabel(widgets.pbMaxScale, data.maxScale);
widgets.cbMinScaleValid->setChecked(data.minScaleValid);
widgets.cbMinScaleValid->setEnabled(data.minScaleValid);
widgets.cbMaxScaleValid->setChecked(data.maxScaleValid);
widgets.cbMaxScaleValid->setEnabled(data.maxScaleValid);
widgets.pbMinScaleTo->setEnabled(data.minScaleValid);
widgets.pbMaxScaleTo->setEnabled(data.maxScaleValid);
widgets.pbReset->setEnabled(false);
widgets.pbApply->setEnabled(!widgets.pbApply->isEnabled());
} // void doReset(SituationMap::Map * map, const AggregationData & data)
void LayerAggregationWidget::onReset()
{
QObject *senderObj = sender();
if (nullptr == senderObj) return;
int row = senderObj->property("row").toInt();
if ((row < 0) || (row >= m_internal->m_aggregationList.size()))
return;
doReset(row);
} // void LayerAggregationWidget::onReset()
static void doApply(SituationMap::Map *map, const AggregationData &data)
{
LayerFactory &layerFactory = map->layerFactory();
LayerParameter layerParamter = layerFactory.layerParameter(data.layerName);
layerParamter.minScale = data.minScaleValid ? data.minScale : LayerParameter::UNDEFINED_SCALE; // 0;
layerParamter.maxScale = data.maxScaleValid ? data.maxScale : LayerParameter::UNDEFINED_SCALE; // 0;
layerFactory.setLayerParameter(data.layerName, layerParamter);
} // void doApply(SituationMap::Map * map, const AggregationData & data)
void LayerAggregationWidget::onApply()
{
QObject *senderObj = sender();
if (!senderObj)
return;
int row = senderObj->property("row").toInt();
if ((row < 0) || (row >= m_internal->m_aggregationList.size()))
return;
const AggregationData &data = m_internal->m_aggregationList[row];
doApply(m_internal->m_map, data);
const AggregationWidgets &widgets = m_internal->m_aggregationWidgets[data.layerName];
widgets.pbApply->setEnabled(false);
} // void LayerAggregationWidget::onApply()
void LayerAggregationWidget::onApplyAll()
{
for (const AggregationData &data : qAsConst(m_internal->m_aggregationList))
{
const AggregationWidgets &widgets = m_internal->m_aggregationWidgets[data.layerName];
if (widgets.pbApply->isEnabled())
{
doApply(m_internal->m_map, data);
widgets.pbApply->setEnabled(false);
}
}
} // void LayerAggregationWidget::onApplyAll()
void LayerAggregationWidget::onResetAll()
{
for (const auto &aggData : qAsConst(m_internal->m_aggregationList))
{
const AggregationWidgets &widgets = m_internal->m_aggregationWidgets[aggData.layerName];
doReset(widgets.pbApply->property("row").toInt());
doApply(m_internal->m_map, aggData);
widgets.pbApply->setEnabled(false);
}
} // void LayerAggregationWidget::onResetAll()
void LayerAggregationWidget::onSetDefaultScales()
{
if (m_internal->m_aggregationList.isEmpty())
return;
// Calculate scale defaults here ...
double mapMinScaleSQRT = sqrt(m_internal->m_map->minScale());
double mapMaxScaleSQRT = sqrt(m_internal->m_map->maxScale());
const int aggregationListCount = m_internal->m_aggregationList.size();
double stepScaleSQRT = (mapMinScaleSQRT - mapMaxScaleSQRT) / static_cast<double>(aggregationListCount);
unsigned int step = 0;
for (auto &aggData : m_internal->m_aggregationList)
{
double dScaleSQRT = mapMaxScaleSQRT + (step * stepScaleSQRT);
aggData.maxScaleValid = true;
aggData.maxScale = dScaleSQRT * dScaleSQRT;
dScaleSQRT = mapMaxScaleSQRT + ((step + 1) * stepScaleSQRT);
aggData.minScaleValid = true;
aggData.minScale = dScaleSQRT * dScaleSQRT;
} // for
// disable start and end
if (aggregationListCount > 0)
{
// front -> max
m_internal->m_aggregationList.front().maxScale = 0;
m_internal->m_aggregationList.front().maxScaleValid = false;
// back -> min
m_internal->m_aggregationList.back().minScale = 0;
m_internal->m_aggregationList.back().minScaleValid = false;
} // if
// update ui to m_aggregationList:
for (const auto &aggData : qAsConst(m_internal->m_aggregationList))
{
const AggregationWidgets &widgets = m_internal->m_aggregationWidgets[aggData.layerName];
widgets.cbMinScaleValid->setEnabled(aggData.minScaleValid);
widgets.cbMinScaleValid->setChecked(aggData.minScaleValid);
widgets.pbMinScaleTo->setEnabled(aggData.minScaleValid);
widgets.cbMaxScaleValid->setEnabled(aggData.maxScaleValid);
widgets.cbMaxScaleValid->setChecked(aggData.maxScaleValid);
widgets.pbMaxScaleTo->setEnabled(aggData.maxScaleValid);
widgets.pbApply->setEnabled(true);
widgets.pbReset->setEnabled(true);
setMinScaleLabel(widgets.pbMinScale, aggData.minScale);
setMaxScaleLabel(widgets.pbMaxScale, aggData.maxScale);
} // for
emit changesMade();
} // void LayerAggregationWidget::onSetDefaultScales()