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

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 &center, qreal radiusX, qreal radiusY,
qreal sin, qreal cos,
const QPointF &sectorStart, const QPointF &sectorEnd)
{
// 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;
}
} }