268 lines
9.3 KiB
C++
Executable File
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 */
|