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

255 lines
8.2 KiB
Objective-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@
* Rubberband class to define multiple ellipse/circle
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "rubberband.h"
namespace SituationMap
{
namespace RB
{
class RubberbandHandle;
class RubberbandFrameHandle;
class DrawableEllipse;
/**
@class RubberbandMultiEllipseFeature rubberband_multi_circle_feature.h
@brief Implementation of a rubberband to input multi point features, like areals or linears
@see Rubberband
*/
class SITUATIONMAP_EXPORT RubberbandMultiEllipseFeature : public Rubberband
{
Q_OBJECT
public:
/**
@name Construction & Destruction
@{
*/
private:
friend class RubberbandFactory;
friend class RubberbandArrow;
friend class RubberbandCorridor;
friend class RubberbandPolylineWidth;
friend class RubberbandSmoothLine;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Constructor delegation doesn't work with Visual Studio 2013
explicit RubberbandMultiEllipseFeature( SituationMap::Map * map );
explicit RubberbandMultiEllipseFeature( SituationMap::Map * map, bool complexGeometry );
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/**
Construction of RubberbandMultiEllipseFeature in most common cases. The parameter parent is
optional.
*/
explicit RubberbandMultiEllipseFeature(SituationMap::Map *map, QObject *parent = nullptr);
/**
Construction of RubberbandMultiEllipseFeature in case of controlling complex geometry objects, like
splines or multi point symbols. In this case set complexGeometry true.
*/
explicit RubberbandMultiEllipseFeature(SituationMap::Map *map, bool complexGeometry, QObject *parent = nullptr);
public:
~RubberbandMultiEllipseFeature();
/** @} */
bool selectAction(AbstractEventDispatcher *causer, int x, int y) override;
bool setCoordinateAction(AbstractEventDispatcher *causer, int x, int y) override;
bool moveAction(AbstractEventDispatcher *causer, int x, int y) override;
bool movePickedAction(AbstractEventDispatcher *causer, int x, int y) override;
void resetAction(AbstractEventDispatcher *causer, int x, int y) override;
bool contextMenuAction(AbstractEventDispatcher *causer, int x, int y) override;
bool completeStateAction(AbstractEventDispatcher *causer, int x, int y) override;
bool deleteAction(AbstractEventDispatcher *causer, int x, int y) override;
bool undoAction(AbstractEventDispatcher *causer, int x, int y) override;
bool applyAndEndAction(AbstractEventDispatcher *causer, int x, int y) override;
/**
* @brief If set to true only quadratic rectangles can be created.
*/
void constrainQuadratic( bool on );
/**
@name Setting Constrains
@{
*/
/**
Defines minimum count of verticies that has to be defined by users input to complete the rubberband with apply signal. The default value is 2.
*/
inline void minimumRadiusCount(unsigned int x)
{
_minimumPointCount = x+1;
}
/**
Defines maximum count of verticies that can be aceppted by the rubberband. A values of 0 stands for undefined. The default is 0.
*/
inline void maximumRadiusCount(unsigned int x)
{
_maximumPointCount = x+1;
}
/**
Defines the maximum length of a segment (distance between to adjaced verticies). A value of 0 stands for no limit is set. The default is 0.
*/
inline void maximumSegmentLength(qreal x) { _maximumSegmentLength = (x > 0) ? x : 0.0; }
inline qreal getMaximumSegmentLength() const { return _maximumSegmentLength; }
/**
Defines the maximum length of the complete polyline. \c enableClosed must be set to false. A value of 0 stands for no limit is set. The default is 0.
*/
inline void maximumLength(qreal x) { _maximumLength = (x > 0) ? x : 0.0; }
/** @} */
inline qreal getMaximumLength() const { return _maximumLength; }
QPointF centerCoordinate(CoordinateSystem cs = CoordinateSystem::Geo) const;
/**
* @brief radii get vector of radius (QPointF containing radiusX and radius Y in meter)
* @return radii
*/
QVector<QPointF> radii() const;
QPointF getBiggestRadius() const;
struct RadiusWithContraints
{
// to be able to supply int, avoid explicit:
RadiusWithContraints(double radius = 0.0, double minRadius = 0.0, double maxRadius = 0.0)
: m_radius(radius),
m_minRadius(minRadius),
m_maxRadius(maxRadius)
{}
double m_radius{0};
double m_minRadius{0};
double m_maxRadius{0};
};
bool setCenterAndRadii(const QPointF &center, CoordinateSystem cs, const QVector<QPointF> &radii); // no constraints
bool setCenterAndRadii2(const QPointF &center, CoordinateSystem cs,
const QVector<RubberbandMultiEllipseFeature::RadiusWithContraints> &radiiWithConstraints);
void prepareFixedNumberOfRadiiWithConstraints(const QVector<RubberbandMultiEllipseFeature::RadiusWithContraints> &radiiContraints);
// get SectorStartEnd
QPointF getRotatedPoint(const QPointF &sector)const;
void enableSector(bool on);
bool isSectorEnabled() const;
/**
* @brief sectorStart in mathematical sense (starts counter-clockwise from 3 o'clock)
* @return sectorStart
*/
QPointF sectorStart() const;
qreal sectorStartDegMath() const; // in mathematical sense (starts counter-clockwise from 3 o'clock)
/**
* @brief sectorEnd in mathematical sense (starts counter-clockwise from 3 o'clock)
* @return sectorEnd
*/
QPointF sectorEnd() const;
qreal sectorEndDegMath() const; // in mathematical sense (starts counter-clockwise from 3 o'clock)
void setSectorStart(qreal sinPhi, qreal cosPhi);
void setSectorEnd(qreal sinPhi, qreal cosPhi);
void setSectorAngleFixed(bool on); // true: start and end sectors positon can't be modifed
bool isSectorFixedAngeEnabled() const;
virtual QVector<QPointF> coordinateVector(CoordinateSystem cs = CoordinateSystem::Geo) const override;
virtual QPointF singleCoordinate( unsigned int idx = 0, CoordinateSystem cs = CoordinateSystem::Geo ) const override;
virtual void setCoordinateVector(const QVector<QPointF> &, CoordinateSystem cs = CoordinateSystem::Geo) override;
signals:
/**
The signal will be emitted, when the mouse cursor has changed and the rubberband is in construction mode and is accepting new input coordinates.
*/
void currentCursorPositionChanged(const Point3D &mapCoord);
protected:
/*
Forward declaration of InternalData to hold private member variables. Be careful the base class Rubberband
has similary a class for internal data member with name "InternalData". Don't be confused it is not the same.
*/
struct InternalData;
InternalData *_internal;
bool _isClosed{false};
unsigned int _minimumRadius = 0;
unsigned int _maximumRadius = 0;
unsigned int _minimumPointCount{2}; // 2 Punkte == 1 Kreis
unsigned int _maximumPointCount{0};
qreal _maximumSegmentLength;
qreal _maximumLength;
void activateButtons() override;
void update() override;
void updateFrameHandle(const QPointF &sceneCoordinate); // Unfortunately, RubberbandCoordinate can´t be forwarded, so use sceneCoordinate
void getSceneRotation(qreal &sinA, qreal &cosA) const;
void updateSectorHandles();
void updateRotationHandle();
QPointF getScenePositionRotationHandle() const;
QPointF getSceneOffsetRotationHandle(qreal margin);
// some helper methodes
bool getRadiusXY(const QPointF &scenePos, qreal &radiusX_out, qreal &radiusY_out);
RubberbandHandle *constructPoint(const QPointF &scenePos);
void constructPoint(const QPointF &point, CoordinateSystem cs);
bool selectHandles(int x, int y, const QPointF &scenePos);
void updateHandles(const QPointF &scenePos, const QPointF &deltaMove);
bool checkLengthConstrains(unsigned int checkHandleIdx, const QPointF &scenePos);
bool checkLengthConstrains(const QPointF &scenePos, const QPointF &deltaScenePos);
bool checkMinMaxRadiusConstraint(const QPointF &curScenePos);
bool checkMinMaxRadiusConstraint(qreal radiusX, qreal radiusY, int idxOfConstraint = -1);
void updatePreviewEllipse(const QPointF &scenePosition);
RubberbandFrameHandle *getFrameHandle() const;
}; /* RubberbandMultiEllipseFeature */
}
} /* namespace SituationMap::RB */