/** ** ** @RDE_HEADER@ ** Definition of rubberband class to define point feature geoemtry ** $Id$ ** $HeadURL$ ** $Author$ ** ** ----------------------------------------------------------------------------------------------- ** ** Hardware-Environment: Intel-PC ** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5 ** ** Language ........: C++ 11 ** ** ----------------------------------------------------------------------------------------------- ** ** Author ...........: Jörg Turla, SPD G, Tel. 3132 ** ** ----------------------------------------------------------------------------------------------- ** ** Notes .........: ** ** 17.06.2015, JT : First edition for use with Qt5 ** ** ----------------------------------------------------------------------------------------------- */ #pragma once #include "rubberband.h" #include namespace SituationMap { namespace RB { class RubberbandPointHandle; /** @class RubberbandRectangle rubberband_rectangle.h @brief Implementation of a rectangle rubberband @see Rubberband */ class SITUATIONMAP_EXPORT RubberbandRectangle : public Rubberband { Q_OBJECT /** @name Construction & Destruction @} */ friend class RubberbandFactory; friend class RubberbandEllipse; friend class RubberbandTransform; explicit RubberbandRectangle( SituationMap::Map * map, QObject * parent = nullptr ); public: ~RubberbandRectangle(); /** @} */ bool selectAction ( AbstractEventDispatcher * causer, int x, int y ) override; bool multiSelectActionPress ( AbstractEventDispatcher * causer, int x, int y ) override; bool multiSelectActionRelease( 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; 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; /** @see rectangleVerticies */ bool coordinatesAreValid() const override { return rectangleIsValid(); } /** * @brief Get 4 verticies of rectangle */ QVector coordinateVector( CoordinateSystem cs = CoordinateSystem::Geo ) const override; /** * @brief Get center point of rectangle, see methode centerPoint */ QPointF singleCoordinate( unsigned int idx = 0, CoordinateSystem cs = CoordinateSystem::Geo ) const override; /** * @brief Set 4 verticies of rectangle */ void setCoordinateVector( const QVector &, CoordinateSystem cs = CoordinateSystem::Geo ) override; /** * @brief Returns center point of rectangle */ QPointF centerPoint( CoordinateSystem cs = CoordinateSystem::Geo ) const; /** * @brief Sets center point of rectangle */ void centerPoint(const QPointF ¢erPoint, CoordinateSystem cs = CoordinateSystem::Geo ); /** * @brief Get 4 verticies of rectangle */ QVector rectangleVerticies( CoordinateSystem cs = CoordinateSystem::Geo ) const; /** * @brief Set 4 verticies of rectangle */ void rectangleVerticies( const QVector &, CoordinateSystem cs = CoordinateSystem::Geo ); /** * @brief Returns true if a valid rectangle has been set with method \c rectangleVerticies * The rectangle rubberband is expecting input coordinates defining a rectangle in map coordinate system. Otherwise * a similar as possible rectangle is used for rubberbanding and the coordinates returned by \c coordinateVector() * will be different from input coordinates. */ bool rectangleIsValid() const; /** * @brief Pass back the rectangle parameter * For convenience some times it would be an asset to get the parameter like center, width, height and rotation. This * function pass back these parameter. A coordinate transformation or projection will \b not be done. All values are related to * the coordinate system of the map. * Warning, if the map coordinate system doesn't use the same geographical projection as the simulation coordinate system * the returned parameter may be all wrong. * * @param center Center point of the rectangle in map coordinates. * @param width Width of the rectangle. * @param height Height of the rectangle. * @param direction Normalized direction vector related to width axis. */ void rectangleParameter( QPointF & center, qreal & width, qreal & height, QPointF & direction, CoordinateSystem cs = CoordinateSystem::Geo ); /** * @brief Build rectangle from rectangle parameter * For convenience some times it would be an asset to initialize a rectangle rubberband from rectangle the parameter like width, height and rotation. * A coordinate transformation or projection will \b not be done. All values are related to the coordinate system of the map. * Warning, if the map coordinate system doesn't use the same geographical projection as the simulation coordinate system all parameter may be wrong. * * @param center Center of the rectangle in \b cs coordinate. * @param width Width of the rectangle. * @param height Height of the rectangle. * @param direction Normalized direction vector related to width axis. * @param cs Coordinate System. */ void buildFromRectangleParamter( const QPointF & center, qreal width, qreal height, const QPointF & direction, CoordinateSystem cs = CoordinateSystem::Geo ); /** * @brief Build rectangle relative to the bottom left corner * For convenience some times it would be an asset to initialize a rectangle rubberband from rectangle the parameter like width, height and rotation. * A coordinate transformation or projection will \b not be done. All values are related to the coordinate system of the map. * Warning, if the map coordinate system doesn't use the same geographical projection as the simulation coordinate system all parameter may be wrong. * * @param bottomLeft Bottom left corner of the rectangle in \b cs coordinates. * @param width Width of the rectangle. * @param height Height of the rectangle. * @param direction Normalized direction vector related to width axis. * @param cs Coordinate System. */ void buildRectangleRelativeToBottomLeftCorner( const QPointF & bottomLeft, qreal width, qreal height, const QPointF & direction, CoordinateSystem cs = CoordinateSystem::Geo ); /** * @brief If set to true only quadratic rectangles can be created. */ void constrainQuadratic( bool on ); /** * @brief Returns the setting for quadratic constrain. */ bool constrainQuadratic() const; /** * @brief If set to true the rectangle can not be rotated. */ void constrainOrthogonal( bool on ); /** * @brief Returns the setting fpr orthogonsl constrain. */ bool constrainOrthogonal() const; /** @name Setting Constrains for Width and Height To define a constrain value a postive values has to be assigned. Negative values will reset the constrain setting to undefined state. @{ */ void minWidth ( qreal x ); void maxWidth ( qreal x ); void minHeight( qreal x ); void maxHeight( qreal x ); /** @} */ protected: /* Forward declaration of InternalData to hold private member variables. Becareful 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 _rectangleIsValid; /* Coordinate matrix to describe the change of coordinates of the last user input */ MathUtils::Matrix2D _lastCoordinateChange; /* ModificationMode is used internally to restrict input for special purposes. It will be defined by derived class */ enum class ModificationMode { NoneRestriction, NoneRotation, TranslationOnly, ScalingOnly, RotationOnly }; void setModificationMode( ModificationMode ); void activateButtons() override; void constructHandles(); void updateHandles( const QPointF & scenePos, QPointF deltaMove ); bool adjustLine( QPointF & deltaMove, bool & constrainsComplied ); void adjustNeighbouringPoints( RubberbandPointHandle * handlePointPtr, unsigned int handleIdx, QPointF deltaMove ); bool checkMinMaxConstrains(const QPointF & vertexScene, QPointF & deltaMovePtr ); bool checkMinMaxConstrains(const QPointF & vertexScene, bool isVertical ); bool constrainsSatisfied( RubberbandPointHandle * handlePointPtr, unsigned int handleIdx, QPointF & deltaMove, bool & constrainsComplied ); void useDottedLineHandles( bool on = true ); void update() override; QPointF getSceneCenter() const; qreal getSceneWidth() const; qreal getSceneHeight() const; QPointF getCenter() const; qreal getWidth() const; qreal getHeight() const; void getSceneRotation( qreal & sinA, qreal & cosA ) const; void getMapRotation ( qreal & sinA, qreal & cosA ) const; void buildTmpConstructionPath(const QPointF & start, const QPointF & end, QVector & path, QPointF & sceneCenter, qreal & sceneWidth, qreal & sceneHeight ); virtual void buildTmpConstruction( SituationMap::RefPointer & tmpGraphic, QPointF & start, QPointF & end ); virtual void getTmpConstructionParameter( const QPointF & start, const QPointF & end, QPointF & sceneCenter, qreal & sceneWidth, qreal & sceneHeight ); private: void setButtonPosition(); }; /* RubberbandRectangle */ } } /* namespace SituationMap::RB */