351 lines
11 KiB
C++
Executable File
351 lines
11 KiB
C++
Executable File
/**
|
||
* @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
|
||
|