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

268 lines
9.3 KiB
C++
Executable File

/**
**
** @RDE_HEADER@
** Implementation 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 .........:
**
** 27.03.2015, JT : First edition for use with Qt5
**
** -----------------------------------------------------------------------------------------------
*/
#include "rubberband_free_hand.h"
#include "rubberband_point_handle.h"
#include "rubberband_drawable.h"
#include "drawable_line.h"
#include "drawable_painter_path.h"
#include "rubberband_handle_proxy.h"
#include "rubberband_internal.h"
#include "rubberband_base_internal.h"
#include <arcgis/MapGraphicsView.h>
namespace SituationMap { namespace RB
{
struct RubberbandFreeHand::InternalData
{
QVector<RubberbandDrawable::RubberbandCoordinate> _coordinateList;
QVector<unsigned int> _inOneGoIndex;
QPoint _lastWindowPos;
bool _coordinateRecordingActive = false;
SituationMap::RefPointer<DrawableLine> _cursorPreviewLine;
SituationMap::RefPointer<DrawableLine> _cursorPreviewCloseLine;
SituationMap::RefPointer<DrawablePainterPath> _pathItem;
}; /* RubberbandFreeHand::InternalData */
RubberbandFreeHand::RubberbandFreeHand( SituationMap::Map * map, QObject * parent )
: Rubberband(map,parent)
, _internal(new RubberbandFreeHand::InternalData)
, _isClosed(false)
{
} /* RubberbandFreeHand::RubberbandFreeHand */
RubberbandFreeHand::~RubberbandFreeHand()
{
delete _internal;
_internal = nullptr;
} /* RubberbandFreeHand::~RubberbandFreeHand */
bool RubberbandFreeHand::selectAction( AbstractEventDispatcher * causer, int x, int y )
{
if (Rubberband::selectAction(causer, x, y))
{
deactivateButtons();
_internal->_coordinateRecordingActive = true;
_internal->_inOneGoIndex << _internal->_coordinateList.size();
return movePickedAction(causer,x,y);
}
return false;
} /* RubberbandFreeHand::selectAction */
bool RubberbandFreeHand::movePickedAction( AbstractEventDispatcher *, int x, int y )
{
if (_internal->_coordinateRecordingActive)
{
QPointF scenePos(pixel2ScenePosition(x,y));
if (_internal->_coordinateList.isEmpty())
{
_internal->_lastWindowPos.setX(x);
_internal->_lastWindowPos.setY(y);
_internal->_coordinateList.append(RubberbandDrawable::RubberbandCoordinate(Rubberband::_internal->_mapView,scenePos));
return true;
}
if ((std::abs(_internal->_lastWindowPos.x() - x) > 2) || (std::abs(_internal->_lastWindowPos.y() - y) > 2))
{
_internal->_lastWindowPos.setX(x);
_internal->_lastWindowPos.setY(y);
_internal->_coordinateList.append(RubberbandDrawable::RubberbandCoordinate(Rubberband::_internal->_mapView,scenePos));
}
update();
return true;
}
return false;
} /* RubberbandFreeHand::movePickedAction */
bool RubberbandFreeHand::moveAction( AbstractEventDispatcher *, int x, int y )
{
if (!_internal->_coordinateList.isEmpty())
{
const RubberbandDrawable::RubberbandCoordinate & firstPos = _internal->_coordinateList.first();
const RubberbandDrawable::RubberbandCoordinate & lastPos = _internal->_coordinateList.last();
QPointF scenePos(pixel2ScenePosition(x,y));
if (!_internal->_cursorPreviewLine) _internal->_cursorPreviewLine = new DrawableLine( Rubberband::_internal->_mapView, Rubberband::_internal->_mapScene );
if ((isClosedEnabled()) && (!_internal->_cursorPreviewCloseLine))
{
_internal->_cursorPreviewCloseLine = new DrawableLine( Rubberband::_internal->_mapView, Rubberband::_internal->_mapScene );
}
_internal -> _cursorPreviewLine -> setVisibility( true );
_internal -> _cursorPreviewLine -> setDrawColor( _handleSelectionColor );
_internal -> _cursorPreviewLine -> setLine( lastPos, RubberbandDrawable::RubberbandCoordinate( Rubberband::_internal->_mapView, scenePos ));
if (_internal->_cursorPreviewCloseLine)
{
_internal -> _cursorPreviewCloseLine -> setVisibility( true );
_internal -> _cursorPreviewCloseLine -> setDrawColor( _handleSelectionColor );
_internal -> _cursorPreviewCloseLine -> setLine( firstPos, RubberbandDrawable::RubberbandCoordinate( Rubberband::_internal->_mapView, scenePos ));
}
}
return false;
} /* RubberbandFreeHand::moveAction */
bool RubberbandFreeHand::setCoordinateAction( AbstractEventDispatcher * causer, int x, int y )
{
_internal->_coordinateRecordingActive = false;
if (Rubberband::setCoordinateAction(causer,x,y))
{
QPointF scenePos(pixel2ScenePosition(x,y));
activateButtons();
_baseInternal->buttonProxyActive( scenePos );
}
return false;
} /* RubberbandFreeHand::setCoordinateAction */
void RubberbandFreeHand::activateButtons()
{
_baseInternal->_hasUndoButton = true;
_baseInternal->_applyIsPossible = true;
_baseInternal->_undoIsPossible = !_internal->_inOneGoIndex.isEmpty();
Rubberband::activateButtons();
} /* RubberbandFreeHand::activateButtons */
bool RubberbandFreeHand::undoAction( AbstractEventDispatcher*, int, int )
{
if (!_internal->_inOneGoIndex.isEmpty())
{
unsigned int coordinateIdx = _internal->_inOneGoIndex.takeLast();
while (coordinateIdx < (unsigned int)_internal->_coordinateList.size())
{
_internal->_coordinateList.removeLast();
}
update();
activateButtons();
}
return true;
} /* RubberbandFreeHand::undoAction */
bool RubberbandFreeHand::completeStateAction( AbstractEventDispatcher * causer, int x, int y )
{
if (rubberbandIsAlive())
{
return applyAndEndAction(causer,x,y);
}
return false;
} /* RubberbandFreeHand::completeStateAction */
unsigned int RubberbandFreeHand::coordinateCount() const
{
return _internal->_coordinateList.size();
} /* RubberbandFreeHand::coordinateCount */
QVector<QPointF> RubberbandFreeHand::coordinateVector( CoordinateSystem cs ) const
{
QVector<QPointF> coordinateVector;
coordinateVector.reserve(_internal->_coordinateList.size());
for (const RubberbandDrawable::RubberbandCoordinate &pos : qAsConst(_internal->_coordinateList))
coordinateVector.push_back(projectCoordinateFromMap( cs, pos._mapCoordinate ));
return coordinateVector;
} /* RubberbandFreeHand::coordinateVector */
QPointF RubberbandFreeHand::singleCoordinate(unsigned int idx, CoordinateSystem cs ) const
{
if (idx >= (unsigned int)_internal->_coordinateList.size()) return QPointF();
const Esri::ArcGISRuntime::Point & pos = _internal->_coordinateList.at(idx)._mapCoordinate;
return projectCoordinateFromMap( cs, pos );
} /* RubberbandFreeHand::singleCoordinate */
void RubberbandFreeHand::update()
{
if (_internal->_coordinateList.size() > 1)
{
if (!_internal->_pathItem)
{
_internal->_pathItem = new DrawablePainterPath( Rubberband::_internal->_mapView );
}
_internal -> _pathItem -> setVisibility(true);
_internal -> _pathItem -> setLineWidth( 2 );
_internal -> _pathItem -> enableClosedLine( _isClosed );
_internal -> _pathItem -> setDrawColor( _drawColor );
_internal -> _pathItem -> setFillColor( _fillColor );
_internal -> _pathItem -> setPath( _internal->_coordinateList );
}
else
{
if (_internal -> _pathItem) _internal->_pathItem->setVisibility(false);
if (_internal->_coordinateList.isEmpty())
{
if (_internal -> _cursorPreviewLine ) _internal -> _cursorPreviewLine -> setVisibility(false);
if (_internal -> _cursorPreviewCloseLine) _internal -> _cursorPreviewCloseLine -> setVisibility(false);
}
}
if (!_internal->_coordinateList.isEmpty())
{
QPointF bottomRight( std::numeric_limits<double>::min(), std::numeric_limits<double>::min() );
for (const RubberbandDrawable::RubberbandCoordinate &coordinate : qAsConst(_internal->_coordinateList))
{
const QPointF & p = coordinate._sceneCoordinate;
if (bottomRight.x() < p.x()) bottomRight.setX(p.x());
if (bottomRight.y() < p.y()) bottomRight.setY(p.y());
}
if (isButtonBoxPositionFixed())
{
RubberbandBase::_baseInternal->_buttonBoxSceneAnchor = bottomRight;
}
}
} /* RubberbandFreeHand::update */
} } /* namespace SituationMap::RB */