Files
qt5-legatus-legacy/Lts/Viewer/SituationMap/Map/map_initializer.h
T
2026-08-13 18:33:10 +02:00

351 lines
11 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @RDE_HEADER@
* MapInitializer
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
// Own
#include "map.h"
#include "map_settings.h"
#include <Map/viewpoint2D.h>
#include <Common/situation_map_logging.h>
#include <situation_map_export.h>
// Qt
#include <QString>
#include <QJsonObject>
//----------------------------------------------------------------------------
namespace SituationMap
{
//----------------------------------------------------------------------------
class SITUATIONMAP_EXPORT BaseUrl
{
public:
BaseUrl(const QString &url = QString(),
double minScale = -1, double maxScale = -1);
QString url() const { return m_url; }
void setUrl(const QString &url) { m_url = url; }
QString name() const { return m_name; }
void setName(const QString &name) { m_name = name; }
QString description() const { return m_description; }
void setDescription(const QString &description) { m_description = description; }
BasemapType basemapType() const { return m_basemapType; }
void setBasemapType(const BasemapType &basemapType) { m_basemapType = basemapType; }
double minScale() const { return m_minScale; }
void setMinScale(double minScale) { m_minScale = minScale; }
double maxScale() const { return m_maxScale; }
void setMaxScale(double maxScale) { m_maxScale = maxScale; }
double altitudeOffset() const { return m_altitudeOffset; }
void setAltitudeOffset(double altitudeOffset) { m_altitudeOffset = altitudeOffset; }
static BaseUrl read(const QJsonObject &json);
QJsonObject toJsonObject() const;
private:
QString m_url;
QString m_name;
QString m_description;
BasemapType m_basemapType = BasemapType::Undefined;
double m_minScale = -1;
double m_maxScale = -1;
double m_altitudeOffset{0.0}; // relevant for slpk (used at AHTC)
};
//----------------------------------------------------------------------------
class SITUATIONMAP_EXPORT MapSettingsJson
{
public:
MapSettingsJson() = default;
QJsonObject toJsonObject() const;
bool fromJsonObject(const QJsonObject &json);
void setMapUrls(const QVector<BaseUrl> &urls) { m_mapUrls = urls; }
void setSceneUrls(const QVector<BaseUrl> &urls) { m_sceneUrls = urls; }
void setSceneObjectUrls(const QVector<BaseUrl> &urls) { m_sceneObjectUrls = urls; }
void setElevationUrls(const QVector<BaseUrl> &urls) { m_elevationUrls = urls; }
const QVector<BaseUrl> &getMapUrls() const { return m_mapUrls; }
const QVector<BaseUrl> &getSceneUrls() const { return m_sceneUrls; }
const QVector<BaseUrl> &getSceneObjectUrls() const { return m_sceneObjectUrls; }
const QVector<BaseUrl> &getElevationUrls() const { return m_elevationUrls; }
private:
QVector<BaseUrl> m_mapUrls;
QVector<BaseUrl> m_sceneUrls;
QVector<BaseUrl> m_sceneObjectUrls;
QVector<BaseUrl> m_elevationUrls;
};
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
/**
* @brief The MapInitializer class is based on the template method idiom.
* <b> It´s designed for easy initializing of a SituationMap::Map. </b>
*
* Typical usage could look like:
*
* \code
*
// Part I: derive from MapInitializer:
class myMapInitializer : public SituationMap::MapInitializer
{
using BaseClass SituationMap::MapInitializer;
public:
explicit myMapInitializer(SituationMap::Map &map
, SituationMap::MapSettings &mapSettings
, const QString &debugName)
:BaseClass(map, mapSettings, debugName) {}
bool initializeObjectFactory() override
{
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::MapObjectIndicator), new SituationMap::GenericObjectFactory<SituationMap::MapObjectIndicatorImpl>() );
...
return true;
}
protected slots:
virtual void onMapReady()
{
BaseClass::onMapReady();
// own things should be added here
}
};
//-----------------------------------------------------------------------------
// Part II: Connect Map, MapSetting using MapInitializer:
d->m_map = SituationMap::Map::create(this);
d->m_mainLayout->addWidget(d->m_map, 1, 0);
connect(d->m_map, &SituationMap::Map::mapObjectsClicked, this, &SitMap::onMapObjectClicked );
QString iniFilePath = QCoreApplication::applicationDirPath(); // /../build-product/bin
iniFilePath.append(QLatin1String("/situation_map_defaults.ini"));
d->m_mapSettings = QSharedPointer<SituationMap::MapSettings> ( new SituationMap::MapSettings(iniFilePath) );
d->m_mapInitializer = QSharedPointer<myMapInitializer>
( new myMapInitializer(*d->m_map, *d->m_mapSettings, QLatin1String("SitMapExample")) );
if (d->m_mapInitializer->hasErrors())
{
FATAL_LOG(m_logger) << LOGFUNCTION << " MapInitializer-filename='" << d->m_mapInitializer->filename()
<< "'' has following errors: "
<< " exists = " << exists()
<< " accessError = " << d->m_mapInitializer->accessError()
<< " formatError = " << d->m_mapInitializer->formatError();
return;
} else {
if (d->m_mapInitializer->initMap())
{
INFO_LOG(m_logger) << LOGFUNCTION << " MapInitializer::initMap() ok";
} else {
ERROR_LOG(m_logger) << LOGFUNCTION << " MapInitializer::initMap() failed";
}
}
*
* \endcode
*
* If you are using <b>more than on map</b>, you should think about the IdGenerator and ObjectContainer.
* \n Sharing \b one IdGenerator by all maps is recommended to avoid misusing a UniqueMapId between different maps.
* \n But ist also strongly recommended that every map has it own ObjectContainer.
* To achieve this you could write:
*
* \code
* // IdGenerator & ObjectContainer:
QSharedPointer<SituationMap::IdGenerator> idGen( new SituationMap::IdGenerator );
QSharedPointer<SituationMap::ObjectContainerCTC> objectCont1( new SituationMap::ObjectContainerCTC(idGen) );
d->m_map1->setObjectContainer( objectCont1 );
QSharedPointer<SituationMap::ObjectContainerCTC> objectCont2( new SituationMap::ObjectContainerCTC(idGen) );
d->m_map2->setObjectContainer( objectCont2 );
\endcode
* This can be a) prior, b) within or c) after the MapInitializer. It depends on the circumstances.
* It seems to be easiest to do prior the MapInitalizer.
*
*
* \section secLifetime Lifetime of the MapInitializer
* Unfortunatly the MapInitializer must not be destroyed after call to initMap().
* \n The signal mapReady is - what a surprise - fired later. And parameters like centerPoint, scale and so on requires the map to be ready!
* Therefore it is forbidden to create the MapInitializer on the stack.
*/
class SITUATIONMAP_EXPORT MapInitializer : public QObject
{
Q_OBJECT
public:
/*! \name Construction, Destruction */
//@{
protected:
/**
* @brief MapInitializer must be created on the heap. See \ref secLifetime.
* @param map
* @param mapSettings
* @param debugName
* @param parent
*/
explicit MapInitializer(Map &map
, MapSettings &mapSettings
, const QString &debugName
, QObject *parent = nullptr);
public:
/**
* @brief set MapSettingsJson haveing priority compared to mapSettings
* @param mapSettingJson
*/
void setMapSettingsJson(const MapSettingsJson &mapSettingJson);
/**
* @brief ~MapInitializer destructor
*/
virtual ~MapInitializer();
/**
* @brief Copy constructor - deleted
* @param other
*/
MapInitializer(const MapInitializer &other) = delete;
/**
* @brief Assignment constructor - deleted
* @param other
*/
MapInitializer &operator=(const MapInitializer &other) = delete;
//@}
/*! \name Error handling*/
//@{
QString filename() const;
bool hasErrors() const;
bool exists() const;
bool accessError() const;
bool formatError() const;
//@}
/*! \name 'template method' defining the skeleton of an algorithm. */
//@{
/**
* @brief initMap is the 'template method'.
* It defines a skeleton of an algorithm, here the initialization of the map.
* @param mapMode to be choosen
* @return True on success, otherwise false.
*/
virtual bool initMap(Mode mapMode = Mode::Mode_2D);
//@}
Viewpoint2D viewPoint() const { return m_viewPoint; }
void setViewPoint(const Viewpoint2D &viewPoint) { m_viewPoint = viewPoint; }
protected:
/*! \name 'Placeholder' or 'concrete methods' (to be overloaded if necessary)
* They are called by the 'template method' (here initMap).
*/
//@{
virtual bool applyLicense();
virtual bool applyNetworkCache();
virtual bool setSymbologyType();
virtual bool setBasemapLayernamePrefix();
virtual bool setParticipantLayername();
// The following method may be overwritten to ease using a UI element
virtual AdvancedSymbology::SymbologyType symbologyType() const;
virtual bool initalizeLocalMapFile();
virtual bool initializeBasemaps(Mode mapMode); // mode to use mapUrls or sceneUrls
virtual bool initializeBasemapsQSettings(Mode mapMode); // mode to use mapUrls or sceneUrls
virtual bool initializeBasemapsJson(const QVector<BaseUrl> &baseUrls); // use mapUrls or sceneUrls
virtual bool initializeSceneObjectLayers();
virtual bool initializeSceneObjectLayersJson();
virtual bool initializeElevationSources();
virtual bool initializeElevationSourcesQSettings();
virtual bool initializeElevationSourcesJson();
virtual bool initialzeInitialViewpoint();
virtual bool initializeOperationalLayers();
virtual bool initializeUniqueValueRendererForCubes();
virtual bool initializeExtraSymbolDirectory();
virtual bool initializeAnimations();
virtual bool initializeGrid();
virtual bool initializeObjectFactory();
virtual bool initializeRubberFactory();
virtual bool setObjectContainer();
virtual bool initializeCoordTranslationFunctor();
virtual bool initializeMapWidgets();
virtual bool initializeSideBar();
virtual bool setViewshedUrl();
//@}
protected slots:
/**
* @brief onMapReady is implemented and called if the map fires mapReady.
* The implementation is setting centerPoint, scale and min/max scale using the values of MapSettings.
*
* <b> This method has to be overloaded to make clear the order of this content and the application-specific portion. </b>
*/
virtual void onMapReady();
protected:
Mode m_mapMode = Mode::Undefined;
Map &m_map;
MapSettingsJson m_mapSettingJson;
MapSettings &m_mapSettings;
QString m_debugName;
Viewpoint2D m_viewPoint;
LOGGER_T m_logger; ///< Interface of the Logging-Facility
};
} // namespace SituationMap