/** * @RDE_HEADER@ * MapInitializer * $Id$ * $HeadURL$ * $Author$ */ #pragma once // Own #include "map.h" #include "map_settings.h" #include #include #include // Qt #include #include //---------------------------------------------------------------------------- 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 &urls) { m_mapUrls = urls; } void setSceneUrls(const QVector &urls) { m_sceneUrls = urls; } void setSceneObjectUrls(const QVector &urls) { m_sceneObjectUrls = urls; } void setElevationUrls(const QVector &urls) { m_elevationUrls = urls; } const QVector &getMapUrls() const { return m_mapUrls; } const QVector &getSceneUrls() const { return m_sceneUrls; } const QVector &getSceneObjectUrls() const { return m_sceneObjectUrls; } const QVector &getElevationUrls() const { return m_elevationUrls; } private: QVector m_mapUrls; QVector m_sceneUrls; QVector m_sceneObjectUrls; QVector m_elevationUrls; }; //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- /** * @brief The MapInitializer class is based on the template method idiom. * It´s designed for easy initializing of a SituationMap::Map. * * 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() ); ... 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 ( new SituationMap::MapSettings(iniFilePath) ); d->m_mapInitializer = QSharedPointer ( 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 more than on map, 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 idGen( new SituationMap::IdGenerator ); QSharedPointer objectCont1( new SituationMap::ObjectContainerCTC(idGen) ); d->m_map1->setObjectContainer( objectCont1 ); QSharedPointer 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 &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. * * This method has to be overloaded to make clear the order of this content and the application-specific portion. */ 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