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

444 lines
13 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Implementation of AbstractMapObject
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
// Own
#include <Map/abstract_map_object.h> // Interface
#include <Map/abstract_effect_simulation.h> // for AesEffectState
#include <Map/line_style.h>
#include <Map/fill_style.h>
#include <Common/simple_value.h>
#include <Common/situation_map_logging.h>
#include <Common/ref_pointer.h>
// Qt
#include <QString>
#include <QColor>
#include <limits>
// 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<double>::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<int> partyId = -1;
SimpleValue<bool> useLightColor = false; // useful for Participants
mutable QColor partyColor;
SimpleValue<QColor> 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<AesEffectState> 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<bool> 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<SymbolData> m_symbol;
SymbolImage m_symbolImage;
QColor m_forcedMajorColor;
// Update ObjectIndicator :
protected:
bool m_updateObjectIndicator{false};
QVector<OriginPositionChangedCallback *> 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