237 lines
6.3 KiB
C++
Executable File
237 lines
6.3 KiB
C++
Executable File
|
|
/**
|
|
**
|
|
** @RDE_HEADER@
|
|
** Implementation of base class for rubberband handles
|
|
** $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_ellipse_handle.h"
|
|
#include <MathUtils/math_const.h>
|
|
|
|
#include <arcgis/MapGraphicsView.h>
|
|
#include <arcgis/Map.h>
|
|
|
|
#include <QtWidgets/QGraphicsScene>
|
|
#include <QtWidgets/QGraphicsEllipseItem>
|
|
|
|
#include <math.h>
|
|
|
|
namespace SituationMap { namespace RB
|
|
{
|
|
|
|
RubberbandEllipseHandle::RubberbandEllipseHandle(Esri::ArcGISRuntime::MapGraphicsView * mapView, QGraphicsScene *scene)
|
|
: RubberbandHandle(mapView, scene)
|
|
{
|
|
zBufferPlane( ZBufferPlane::LineHandle );
|
|
updateGraphic();
|
|
}
|
|
|
|
RubberbandEllipseHandle::~RubberbandEllipseHandle()
|
|
{
|
|
if (!_scene)
|
|
return;
|
|
|
|
if (_ellipseSymbol)
|
|
{
|
|
_scene->removeItem(_ellipseSymbol);
|
|
delete _ellipseSymbol;
|
|
}
|
|
}
|
|
|
|
void RubberbandEllipseHandle::adjustCoordinates()
|
|
{
|
|
_center.mapToScene(_mapView);
|
|
updateGraphic();
|
|
|
|
emit adjusted();
|
|
}
|
|
|
|
|
|
void RubberbandEllipseHandle::adjustWindow( const QRectF& )
|
|
{
|
|
onDo_adjustCoordinates();
|
|
}
|
|
|
|
qreal length(const QPointF &p)
|
|
{
|
|
return sqrt(p.x()*p.x()+p.y()*p.y());
|
|
}
|
|
|
|
|
|
void RubberbandEllipseHandle::updateGraphic()
|
|
{
|
|
if (_scene)
|
|
{
|
|
if (!_ellipseSymbol)
|
|
{
|
|
_ellipseSymbol = new QGraphicsEllipseItem();
|
|
_scene->addItem(_ellipseSymbol);
|
|
_ellipseSymbol->setFlags( QGraphicsItem::ItemIgnoresTransformations );
|
|
}
|
|
|
|
_ellipseSymbol->setZValue(_zValue);
|
|
|
|
// Style
|
|
makeLineStyle( _dottedLine, _lineStyle );
|
|
|
|
if (_isSelected)
|
|
{
|
|
_lineStyle.setWidth( _lineStyle.width() + 1 );
|
|
_lineStyle.setColor( _selectionColor );
|
|
}
|
|
|
|
_ellipseSymbol->setPen(_lineStyle);
|
|
|
|
if (isSelected())
|
|
_ellipseSymbol->setBrush( QBrush(_selectionColor) );
|
|
else
|
|
_ellipseSymbol->setBrush( QBrush(_fillColor) );
|
|
|
|
_ellipseSymbol->setVisible(_isVisible);
|
|
|
|
// geometry:
|
|
{
|
|
_center.mapToScene(_mapView);
|
|
|
|
QPointF mapCenter( _center._mapCoordinate.x(), _center._mapCoordinate.y() );
|
|
|
|
qreal mapRotatePhi = _mapView->mapRotation() * MathConst::pi / 180.0;
|
|
|
|
qreal sinMap = sin(mapRotatePhi);
|
|
qreal cosMap = cos(mapRotatePhi);
|
|
|
|
qreal sinPhi = _sinRect * cosMap + _cosRect * sinMap;
|
|
qreal cosPhi = _cosRect * cosMap - _sinRect * sinMap;
|
|
|
|
|
|
RubberbandCoordinate x0y0(_mapView, convert( mapCenter+QPointF(-_radiusX,-_radiusY), _mapView->map()->spatialReference()) );
|
|
RubberbandCoordinate x1y0(_mapView, convert( mapCenter+QPointF( _radiusX,-_radiusY), _mapView->map()->spatialReference()) );
|
|
RubberbandCoordinate x0y1(_mapView, convert( mapCenter+QPointF(-_radiusX, _radiusY), _mapView->map()->spatialReference()) );
|
|
|
|
const qreal width = length(x1y0._sceneCoordinate-x0y0._sceneCoordinate);
|
|
const qreal height = length(x0y1._sceneCoordinate-x0y0._sceneCoordinate);
|
|
|
|
// honor sector??
|
|
|
|
if (_sectorStart != _sectorEnd)
|
|
{
|
|
auto getAngle = [](qreal sinPhi, qreal cosPhi) -> int
|
|
{
|
|
qreal phi = acos( cosPhi );
|
|
if (sinPhi < 0) phi = MathConst::pi_two - phi;
|
|
return int( (phi * 180.0 / MathConst::pi) * 16);
|
|
}; // getAngle
|
|
|
|
int startAngle = getAngle(_sectorStart.y(), _sectorStart.x());
|
|
int endAngle = getAngle( _sectorEnd.y(), _sectorEnd.x());
|
|
int spanAngle = (endAngle > startAngle) ? endAngle-startAngle : 5760-startAngle+endAngle;
|
|
|
|
QColor fillColor = transparentFillColor();
|
|
_ellipseSymbol->setRect(-width*0.5, -height*0.5, width, height);
|
|
_ellipseSymbol->setPen(_lineStyle );
|
|
_ellipseSymbol->setBrush( (fillColor.alpha() > 0) ? QBrush(fillColor) : QBrush() );
|
|
_ellipseSymbol->setTransform( QTransform( cosPhi, -sinPhi, sinPhi, cosPhi, _center._sceneCoordinate.x(), _center._sceneCoordinate.y() ));
|
|
_ellipseSymbol->setStartAngle(startAngle );
|
|
_ellipseSymbol->setSpanAngle(spanAngle);
|
|
_ellipseSymbol->setVisible(true);
|
|
}
|
|
|
|
_ellipseSymbol->setRect(-width*0.5, -height*0.5, width, height);
|
|
_ellipseSymbol->setTransform( QTransform( cosPhi, -sinPhi, sinPhi, cosPhi, _center._sceneCoordinate.x(), _center._sceneCoordinate.y()) );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
QPointF RubberbandEllipseHandle::getRadius()
|
|
{
|
|
return {_radiusX, _radiusY};
|
|
}
|
|
|
|
|
|
void RubberbandEllipseHandle::setRect(const RubberbandCoordinate ¢er, qreal radiusX, qreal radiusY,
|
|
qreal sin, qreal cos,
|
|
const QPointF §orStart, const QPointF §orEnd)
|
|
{
|
|
// p1,p2 = corner points of unrotated ellipse in scene coordinates
|
|
_center = center;
|
|
_radiusX = radiusX;
|
|
_radiusY = radiusY;
|
|
|
|
_sinRect = sin;
|
|
_cosRect = cos;
|
|
|
|
_sectorStart = sectorStart;
|
|
_sectorEnd = sectorEnd;
|
|
|
|
updateGraphic();
|
|
}
|
|
|
|
|
|
bool RubberbandEllipseHandle::isPositionInside(const QPointF &scenePosition) const
|
|
{
|
|
if (_ellipseSymbol)
|
|
{
|
|
if (_ellipseSymbol->contains( scenePosition ))
|
|
{
|
|
return true;
|
|
}
|
|
// else
|
|
// {
|
|
// // Ok, Qt's methodes doesn't work safely
|
|
// // if it fails do some own calculations
|
|
|
|
// QPointF V0 = _coordinates[0]._sceneCoordinate;
|
|
// QPointF V1 = _coordinates[1]._sceneCoordinate;
|
|
// QPointF R = V1-V0;
|
|
// QPointF P = scenePosition-V0;
|
|
// qreal lenR = R.x() * R.x() + R.y() * R.y();
|
|
// qreal lenP = P.x() * P.x() + P.y() * P.y();
|
|
|
|
// if ((lenR == 0) || (lenP > lenR)) return false; // scene Position is to far away
|
|
|
|
// // now check the direction
|
|
|
|
// lenR = sqrt(lenR);
|
|
// lenP = sqrt(lenP);
|
|
|
|
// R /= lenR;
|
|
// P /= lenP;
|
|
|
|
// qreal cosPhi = QPointF::dotProduct(R,P);
|
|
|
|
// if (cosPhi < 0) return false;
|
|
|
|
// qreal epsilon = sqrt(1.0-cosPhi*cosPhi) * lenR;
|
|
|
|
// return (epsilon < qreal(_pickingRatio));
|
|
// }
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
} }
|