/** * @RDE_HEADER@ * Implementation of AbstractMapObject * $Id$ * $HeadURL$ * $Author$ */ #pragma once // Own #include // Interface #include // for AesEffectState #include #include #include #include #include // Qt #include #include #include // forward: namespace Esri { namespace ArcGISRuntime { class Graphic; class GraphicsOverlay; class Geometry; } } //---------------------------------------------------------------------------- namespace SituationMap { struct ExtraData; class MapImpl; class MapConnector; class AbstractGraphicalObject; class GraphicalObjectText; class GraphicalObjectPath; class TacticalAppearance; class GraphicalObjectCube; //---------------------------------------------------------------------------- class OriginPositionChangedCallback { public: virtual ~OriginPositionChangedCallback() = default; virtual void onOriginPositionChanged() = 0; }; //---------------------------------------------------------------------------- /** * @brief The AbstractMapObjectImpl class is the main base class of all MapObject instances. * Therefore it supports typical parameters/functionality and avoids redundant code. * As consequence AbstractMapObjectImpl supports functionality, which is not used in every subclass. * The typical parameters/functionality is: * - UniqueMapId * - debugInfo * - partyId, partyColor * - aesState (aes = AreaEffectSimulation) * - drawOrder * - (tact.) symbol * - visibility (major|techn|tact.) * - pickability * - selected * - mainGraphicalObject (displaying the main techn. Appearance) * - mainGraphicalObjectText (displaying the text/name) * - tacticalAppearance (displaying the tact. Appearance) * - m_graphicalObjectExtrusion (displaying the extrusion (3D)) * - mainGraphicalObjectPin (displaying a pin/needle to the ground) * * After an parameter changes, the method updateView() hat to be called. */ // inherent 'public virtual' to get that interface class SITUATIONMAP_EXPORT AbstractMapObjectImpl : public virtual AbstractMapObject { public: explicit AbstractMapObjectImpl(const QString &debugInfo = QString()); virtual ~AbstractMapObjectImpl(); void removeMySelf() override; AbstractMapObjectImpl(const AbstractMapObjectImpl &other) = delete; AbstractMapObjectImpl &operator=(AbstractMapObjectImpl &other) = delete; // emulate QObject::property : bool setProperty(const char *name, const QVariant &value) override; QVariant property(const char *name) const override; // : emulate QObject::property UniqueMapId uniqueMapId() const override; QString debugInfo() const override; void setDebugInfo(const QString &debugInfo) override; QString toString() const override; // Data access: void boundingBox(BoundingBox &bbox) const override; QColor majorColor() const override; QString identifier() const override; void setIdentifier(const QString &identifier) override; bool identifierVisible() const override; void setIdentifierVisible(bool identifierVisible) override; int partyId() const override; bool isPartyIdValid() const override; void setPartyId(int partyId) override; bool setPartyIdChanged(int partyId = -1) override; void forcePartyColor(const QColor &partyColorToForce) override; bool useLightColor() const override; ///< Only for Participants void setUseLightColor(bool useLightColor) override; ///< Only for Participants virtual AesEffectState aesState() const; virtual void setAesState(AesEffectState aesState); TextStyle textStyle() const override; TextStyle &rTextStyle() override; void setTextStyle(const TextStyle &textStyle) override; virtual LineStyle lineStyle() const; virtual LineStyle &rLineStyle(); virtual void setLineStyle(const LineStyle &lineStyle); virtual FillStyle fillStyle() const; virtual FillStyle &rFillStyle(); virtual void setFillStyle(const FillStyle &fillStyle); // Scale : float scale() const override; void setScale(float scale) override; bool isScaleEnabled() const override; void setScaleEnable(bool enabled) override; // : Scale // Layer QString layer() const override; int drawOrder() const override; /** * @brief Set drawOrder. * Caused by internal dependencies, the value MUST within -3000...+3000. (INT_MAX=+32767 / 10 = 3276 -> ~3000). * \n Otherwise the internal graphics will be disordered. * \internal Background: Due to missing relative drawOrder an absolute drawOrder has to be used.\n * To create an absolute drawOrder the specified drawOrder is multiplied with 10. * The components (usually GraphicalObjects) receive that multiplied valued added by s small offset. * drawOrder() is not influenced by this and will return the value you set before. * @param drawOrder new value. */ void setDrawOrder(int drawOrder) override; // Visibility : // Prio 1: bool visibility() const override; void setVisibility(bool visibility) override; // Prio 2 bool visibility(ObjectAppearance appearance) const override; void setVisibility(ObjectAppearance appearance, bool visibility) override; bool visibilityOfGeometry() const; void setVisibilityOfGeometry(bool visiGeometry); // : Visibility // Selection, Picking : bool selected() const override; void setSelected(bool selected) override; bool pickable() const override; void setPickable(bool pickable) override; // : Selection, Picking // Symbol : SymbolData symbol() const override; void setSymbol(const SymbolData &symbol) override; void reRenderSymbol() override; SymbolDataToRender symbolDataToRender() const override; SymbolImage symbolImage() const override; QImage previewImage() const override; QImage previewImageTypical() const override; QImage previewImageSpecific() const override; void setForceMajorColor(const QColor &majorColor) override; // : Symbol /*! \name Some methods regarding extrusion (renderer approach) */ //@{ double extrusionHeight() const override; void setExtrusionHeight(double extrusionHeight = std::nan("")) override; bool extrusionHeightValid() const; const QString extrusionColorName() const override; void setExtrusionColorName(const QString &extrusionColorName) override; //@} // Geometry : bool geometryIntersect(const MathUtils::GeometryEngine::Geometry &intersector_polyline) const override; bool geometryIsInHull(const MathUtils::GeometryEngine::Geometry &hull_polygon) const override; Esri::ArcGISRuntime::Geometry getEsriGeometry() const; // : Geometry // Define default text style for all MapObjects: static TextStyle defaultTextStyle(); /** * @brief updateView * transfer values to view * @return true on success */ bool updateView() override { return updateViewImplPre() && updateViewImpl() && updateViewImplPost(); } virtual MapImpl *mapImpl() { return m_mapImpl; } int numberOfValuesChanged(); ///< For Unit/Module Test protected: virtual bool updateViewImplPre(); virtual bool updateViewImpl() = 0; virtual bool updateViewImplPost(); friend class ObjectFactory; // deriving classes MUST overload init and create an GraphicalObject!!! // (to use whose identifier, textStyle) virtual bool init(MapImpl *mapImpl, const QString &logicalLayerName = QStringLiteral("GraphicsLayer")); virtual void setUniqueId(const UniqueMapId &uniqueId); QString logicalLayerName() const; bool setLogicalLayerName(const QString &logicalLayerName); // internal/admin void createTacticalAppearance(); void resetTacticalAppearanceDrawOrderOffset(); virtual bool updateTacticalAppearance(); // Extrusion void createGraphicalObjectExtrusion(); void resetGraphicalObjectExtrusion(); bool updateGraphicalObjectExtrusion(); // pin/needle void createPin(); void resetPin(); bool updatePin(); virtual void updateIdentifierPosition(); friend class MapConnector; virtual bool onMapExtentChanged(); MapConnector *m_mapConnector = nullptr; class VisibilityScale { public: VisibilityScale() { resetToInitial(); } void resetToInitial() { scale_zoomOutCurrent = scale_zoomOutInitialized; } void resetToMax() { scale_zoomOutCurrent = std::numeric_limits::max(); } void setInitial(double newValue) { scale_zoomOutInitialized = newValue; resetToInitial(); } bool scaleHasVisibility(double curScale) const { if (scale_zoomOutCurrent <= 0) return true; return (curScale < scale_zoomOutCurrent); } private: double scale_zoomOutCurrent = 0; double scale_zoomOutInitialized = 70000; }; VisibilityScale m_visibilityScaleRange; // static value 's_scaleHasVisibilityValue' is located in the interface UniqueMapId m_uniqueMapId = SituationMap::INVALID_MAP_ID; ///< for identification QString m_debugInfo; ///< for debugging MapImpl *m_mapImpl = nullptr; QString m_logicalLayerName; Esri::ArcGISRuntime::GraphicsOverlay *m_graphicsLayer = nullptr; // party : struct party { SimpleValue partyId = -1; SimpleValue useLightColor = false; // useful for Participants mutable QColor partyColor; SimpleValue forcedPartyColor; bool changed() const { return partyId.changed() || useLightColor.changed() || forcedPartyColor.changed(); } void reset() { partyId.reset(); useLightColor.reset(); forcedPartyColor.reset(); } }; party m_party; bool partyChanged() const { return m_party.changed(); } void partyReset() { m_party.reset(); } virtual const QColor &partyColor() const; virtual QColor partyColor(int partyId, bool useLightColor) const; virtual AdvancedSymbology::Role partyRole(bool roleIdentityAssumed = false) const; // : party // state : SimpleValue m_aesState{AesEffectState::Unknown}; // : state private: int m_drawOrder{0}; // logical drawOrder protected: int m_internalDrawOrder{0}; // m_mainGraphicalObject will store LineStyle (color/width/pattern), FillStyle (color/pattern): AbstractGraphicalObject *m_mainGraphicalObject{nullptr}; bool m_enableScale{true}; // m_mainGraphicalText will store TextStyle (color/width/size...) GraphicalObjectText *m_mainGraphicalObjectText{nullptr}; Point3D m_identifierPositionCandidateTranslated; SimpleValue m_identiferVisible{true}; TacticalAppearance *m_tacticalAppearance{nullptr}; int m_tacticalAppearanceDrawOrderOffset{2}; // for 3D Extrusion: GraphicalObjectCube *m_graphicalObjectExtrusion{nullptr}; double m_extrusionHeight{std::nan("")}; QString m_extrusionColorName; // For Pin GraphicalObjectPath *m_graphicalObjectPin{nullptr}; double m_defaultZValue{0}; SimpleValue m_symbol; SymbolImage m_symbolImage; QColor m_forcedMajorColor; // Update ObjectIndicator : protected: bool m_updateObjectIndicator{false}; QVector m_originPositionChangedCb; public: void addChangedCallback(OriginPositionChangedCallback *cb); void removeChangedCallback(OriginPositionChangedCallback *cb); // : Update ObjectIndicator protected: bool m_visibility = true; bool m_visibilityTechnical = true; bool m_visibilityTechnicalGeometry = true; // Special case bool m_visibilityTactical = true; bool m_selected = false; bool m_pickable = true; bool m_editorMode = false; bool m_lineColorFromParty = true; int m_fillColorAlpha = 255; private: ExtraData *m_extraData = nullptr; void createGraphicalObjectText(); LOGGER_T m_logger; ///< Interface of the Logging-Facility }; QString toString(const AesEffectState value); std::ostream &operator<< (std::ostream &stream, const AesEffectState &value); } // namespace SituationMap