661 lines
23 KiB
C++
Executable File
661 lines
23 KiB
C++
Executable File
/**
|
|
**
|
|
** @RDE_HEADER@
|
|
** Implementation of rubberband class to define point feature geometry in 3d
|
|
** $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 <limits>
|
|
|
|
#include "rubberband_multi_point_feature_3d.h"
|
|
#include "rubberband_base_internal.h"
|
|
|
|
#include "event_mouse_navigator.h"
|
|
|
|
#include <Map/map.h>
|
|
#include <Map/layer_factory.h>
|
|
|
|
#include <MapImpl/map_impl.h>
|
|
#include <MapImpl/coordinate_translation.h>
|
|
#include <MapImpl/screen_to_location_helper.h>
|
|
#include <MapImpl/location_to_elevation_helper.h>
|
|
|
|
#include <MathUtils/math_const.h>
|
|
|
|
#include <GraphicalObjects/graphical_object_picture_marker.h>
|
|
#include <GraphicalObjects/graphical_object_path.h>
|
|
|
|
#include <QtGui/QGuiApplication>
|
|
|
|
#include <arcgis/IdentifyGraphicsOverlayResult.h>
|
|
|
|
namespace SituationMap { namespace RB
|
|
{
|
|
|
|
class RubberbandMultiPointFeature3D::InternalData
|
|
{
|
|
public:
|
|
|
|
QVector<GraphicalObjectPictureMarker*> m_marker;
|
|
GraphicalObjectPath *m_path;
|
|
|
|
QVector<QPointF> m_coordinates;
|
|
|
|
int m_currentIndex;
|
|
int m_selectionIndex;
|
|
Esri::ArcGISRuntime::TaskWatcher m_pickingTask;
|
|
Esri::ArcGISRuntime::TaskWatcher m_selectionTask;
|
|
QPoint m_pickingPoint;
|
|
QPointF * m_startMove;
|
|
ScreenToLocationHelper * m_screenToMap;
|
|
QPointer<LocationToElevationHelper> m_toElevation;
|
|
PositionCont m_positionList3D;
|
|
bool m_doCompleteAction;
|
|
|
|
|
|
InternalData()
|
|
: m_marker()
|
|
, m_path(nullptr)
|
|
, m_coordinates()
|
|
, m_currentIndex(-1)
|
|
, m_selectionIndex(-1)
|
|
, m_pickingTask()
|
|
, m_selectionTask()
|
|
, m_pickingPoint()
|
|
, m_startMove(nullptr)
|
|
, m_screenToMap()
|
|
, m_toElevation(nullptr)
|
|
, m_positionList3D()
|
|
, m_doCompleteAction(false)
|
|
{
|
|
m_marker.reserve(100);
|
|
m_coordinates.reserve(100);
|
|
} // InternalData()
|
|
|
|
~InternalData()
|
|
{
|
|
delete m_startMove;
|
|
for (auto marker : qAsConst(m_marker))
|
|
delete marker;
|
|
delete m_path;
|
|
delete m_screenToMap;
|
|
} // ~InternalData()
|
|
|
|
}; // RubberbandPointFeature3D::InternalData
|
|
|
|
|
|
RubberbandMultiPointFeature3D::RubberbandMultiPointFeature3D( SituationMap::Map * map, QObject * parent, bool isActive )
|
|
: Rubberband3D(map,parent,isActive)
|
|
, _internal( new RubberbandMultiPointFeature3D::InternalData() )
|
|
, _isClosed(false)
|
|
, _isCircular(false)
|
|
{
|
|
MapImpl *mapImpl = static_cast<MapImpl*>(_baseInternal->_map.data());
|
|
Esri::ArcGISRuntime::SceneGraphicsView *view = mapImpl->getEsriSceneGraphicsView();
|
|
|
|
connect( view, &Esri::ArcGISRuntime::SceneGraphicsView::identifyGraphicsOverlaysCompleted, this, &RubberbandMultiPointFeature3D::onGetPickingResult );
|
|
_internal->m_screenToMap = new ScreenToLocationHelper(view);
|
|
connect( _internal->m_screenToMap, &ScreenToLocationHelper::mouseScenePositionChanged, this, &RubberbandMultiPointFeature3D::onMapPosition ); // ToDO
|
|
|
|
} // RubberbandMultiPointFeature3D::RubberbandMultiPointFeature3D( SituationMap::Map * map, QObject * parent = nullptr, bool isActive )
|
|
|
|
|
|
RubberbandMultiPointFeature3D::~RubberbandMultiPointFeature3D()
|
|
{
|
|
delete _internal;
|
|
_internal = nullptr;
|
|
} // RubberbandMultiPointFeature3D::~RubberbandMultiPointFeature3D()
|
|
|
|
void RubberbandMultiPointFeature3D::activateButtons()
|
|
{
|
|
_baseInternal->_hasUndoButton = false;
|
|
_baseInternal->_undoIsPossible = false;
|
|
_baseInternal->_applyIsPossible = (_internal->m_coordinates.size() > ((_isClosed && !_isCircular) ? 2 : 1));
|
|
|
|
RubberbandBase::activateButtons();
|
|
|
|
} /* RubberbandMultiPointFeature3D::activateButtons */
|
|
|
|
|
|
void circleShape( GraphicalObjectPath *pathObj, const PositionCont &positionList )
|
|
{
|
|
if (positionList.size() < 2) return;
|
|
|
|
PositionCont circleShape;
|
|
|
|
double cx = positionList[0].x();
|
|
double cy = positionList[0].y();
|
|
double rx = positionList[1].x()-cx;
|
|
double ry = positionList[1].y()-cy;
|
|
|
|
double corrLon = cos(cy / 57.2957795147); // correct factor from nautic simulation to get a real circle
|
|
double dPhi = MathConst::pi / 50; // delta angle to rasterize the circle to a polyline
|
|
|
|
auto sqr = [](double x) -> double { return x * x; };
|
|
double r = sqrt(sqr(rx*corrLon) + sqr(ry) );
|
|
|
|
double phi = 0.0;
|
|
while (phi < MathConst::pi_two)
|
|
{
|
|
double sinPhi = sin(phi);
|
|
double cosPhi = cos(phi);
|
|
double px = cx + r * cosPhi / corrLon;
|
|
double py = cy + r*sinPhi;
|
|
|
|
circleShape.append(Point3D(px, py, 0.0));
|
|
phi += dPhi;
|
|
}
|
|
|
|
pathObj->setPositions(circleShape);
|
|
|
|
} // circleShape
|
|
|
|
|
|
void RubberbandMultiPointFeature3D::onMapPosition(const Point3D &mapCoordinate)
|
|
{
|
|
if (_internal->m_currentIndex < 0) return;
|
|
|
|
if (qIsNaN(mapCoordinate.x())) return; // illegal map position
|
|
if (qIsNaN(mapCoordinate.y())) return;
|
|
|
|
if ((!_internal->m_toElevation) && (RubberbandBase::_baseInternal->_map->layerFactory().elevationAvailable()))
|
|
{
|
|
_internal->m_toElevation = RubberbandBase::_baseInternal->_map->layerFactory().locationToElevation(); // layerFactory has ownership
|
|
}
|
|
|
|
if ((std::numeric_limits<int>::max()) == _internal->m_currentIndex)
|
|
{
|
|
// move all coordinates
|
|
if (_internal->m_startMove)
|
|
{
|
|
QPointF deltaMove = mapCoordinate.toPointF() - *(_internal->m_startMove);
|
|
|
|
_internal->m_positionList3D.clear();
|
|
_internal->m_positionList3D.reserve(_internal->m_coordinates.size());
|
|
|
|
for (int i = 0; i < _internal->m_coordinates.size(); ++i)
|
|
{
|
|
const QPointF & pos = _internal->m_coordinates[i] += deltaMove;
|
|
_internal->m_marker[i]->setOrigin( pos );
|
|
|
|
if (_internal->m_toElevation)
|
|
{
|
|
QMetaObject::Connection conn;
|
|
|
|
conn = connect(_internal->m_toElevation.data(), &SituationMap::LocationToElevationHelper::elevationCompleted, this, [this,pos,conn](double elevation)
|
|
{
|
|
disconnect(conn);
|
|
_internal->m_positionList3D << Point3D(pos.x(),pos.y(),elevation);
|
|
if (_internal->m_positionList3D.size() == _internal->m_coordinates.size())
|
|
{
|
|
if (_internal->m_path) _internal->m_path->setPositions( _internal->m_positionList3D );
|
|
update();
|
|
}
|
|
|
|
// qCritical() << "elevation at (" << pos.x() << " , " << pos.y() << ") : " << elevation;
|
|
|
|
});
|
|
_internal->m_toElevation->locationToElevation(pos);
|
|
}
|
|
else
|
|
{
|
|
_internal->m_positionList3D << Point3D::fromQPointF(pos);
|
|
}
|
|
}
|
|
|
|
if (_internal->m_toElevation)
|
|
{
|
|
if (_internal->m_path) _internal->m_path->setPositions( _internal->m_positionList3D );
|
|
update();
|
|
}
|
|
}
|
|
else _internal->m_startMove = new QPointF(mapCoordinate.toPointF());
|
|
return;
|
|
}
|
|
|
|
if (_internal->m_currentIndex >= _internal->m_coordinates.size()) return;
|
|
|
|
MapImpl *mapImpl = static_cast<MapImpl*>(_baseInternal->_map.data());
|
|
Esri::ArcGISRuntime::SceneGraphicsView *view = mapImpl->getEsriSceneGraphicsView();
|
|
Esri::ArcGISRuntime::GraphicsOverlay *graphicsLayer = mapImpl->getGraphicsLayer(mapImpl->layerFactory().rubberbandLayer());
|
|
|
|
if (nullptr == view) return;
|
|
|
|
for (int idx = _internal->m_positionList3D.size(); idx <= _internal->m_currentIndex; ++idx)
|
|
{
|
|
_internal->m_positionList3D << mapCoordinate;
|
|
}
|
|
_internal->m_coordinates[_internal->m_currentIndex] = mapCoordinate.toPointF();
|
|
_internal->m_positionList3D[_internal->m_currentIndex] = mapCoordinate;
|
|
|
|
// qCritical() << "elevation idx=" << _internal->m_currentIndex <<" at (" << mapCoordinate.x() << " , " << mapCoordinate.y() << ") : " << mapCoordinate.z();
|
|
|
|
GraphicalObjectPictureMarker *&marker = _internal->m_marker[_internal->m_currentIndex];
|
|
|
|
if (nullptr == marker)
|
|
{
|
|
marker = new GraphicalObjectPictureMarker( view, graphicsLayer, QStringLiteral("RubberbandMultiPointFeature3D"), INVALID_MAP_ID );
|
|
|
|
marker->setImage(markerImage());
|
|
marker->setOrigin( mapCoordinate );
|
|
marker->updateView();
|
|
marker->setPickable(true);
|
|
|
|
Esri::ArcGISRuntime::Graphic *graphic = marker->graphic();
|
|
if (graphic)
|
|
{
|
|
Esri::ArcGISRuntime::AttributeListModel *attLisModel = graphic->attributes();
|
|
if (attLisModel)
|
|
{
|
|
// qCritical() << "Rubberband3D-Item =" << _internal->m_currentIndex;
|
|
attLisModel->insertAttribute(QStringLiteral("Rubberband3D-Item"),_internal->m_currentIndex);
|
|
}
|
|
}
|
|
}
|
|
else marker->setOrigin( mapCoordinate );
|
|
|
|
if (_internal->m_coordinates.size() > ((_isClosed && !_isCircular) ? 2 : 1))
|
|
{
|
|
|
|
if (nullptr == _internal->m_path)
|
|
{
|
|
bool isPolygon = (_isClosed || _isCircular);
|
|
|
|
_internal->m_path = new GraphicalObjectPath(isPolygon ? GraphicalObjectPathType::Polygon : GraphicalObjectPathType::Polyline, view, graphicsLayer, QStringLiteral("RubberbandMultiPointFeature3D"), INVALID_MAP_ID);
|
|
|
|
_internal->m_path->rLineStyle().setLineColor(_handleDrawColor);
|
|
_internal->m_path->rLineStyle().setLinePattern(LinePattern::Solid);
|
|
_internal->m_path->rLineStyle().setLineWidth(3);
|
|
_internal->m_path->setPickable(false);
|
|
if (isPolygon)
|
|
{
|
|
_internal->m_path->rFillStyle().setFillColor(_frameFillColor);
|
|
}
|
|
|
|
if (_isCircular)
|
|
{
|
|
circleShape(_internal->m_path, _internal->m_positionList3D);
|
|
}
|
|
else _internal->m_path->setPositions(_internal->m_positionList3D);
|
|
|
|
_internal->m_path->updateView();
|
|
}
|
|
else
|
|
{
|
|
if (_isCircular)
|
|
{
|
|
circleShape(_internal->m_path, _internal->m_positionList3D);
|
|
}
|
|
else _internal->m_path->setPositions(_internal->m_positionList3D);
|
|
}
|
|
}
|
|
|
|
if (_isCircular && (0 == _internal->m_currentIndex) && (1 == _internal->m_coordinates.size()))
|
|
{
|
|
_internal->m_coordinates << _internal->m_coordinates.first();
|
|
_internal->m_positionList3D << _internal->m_positionList3D.first();
|
|
_internal->m_marker << nullptr;
|
|
_internal->m_currentIndex++;
|
|
|
|
// qCritical() << QCursor::pos() << " != " << view->viewport()->mapToGlobal(_internal->m_pickingPoint);
|
|
|
|
_internal->m_doCompleteAction = (QCursor::pos() != view->viewport()->mapToGlobal(_internal->m_pickingPoint));
|
|
|
|
if (!_internal->m_doCompleteAction)
|
|
{
|
|
// Click with out moving the mouse, set a default size of the circle and let the user do some editing
|
|
// The rubberband doesn't complete automatically in this case.
|
|
_internal->m_screenToMap->screenToLocation(_internal->m_pickingPoint.x()+100, _internal->m_pickingPoint.y());
|
|
}
|
|
}
|
|
|
|
update();
|
|
|
|
if (!QGuiApplication::mouseButtons().testFlag(Qt::MouseButton::LeftButton))
|
|
{
|
|
if (_isCircular && _internal->m_doCompleteAction && (1 == _internal->m_currentIndex))
|
|
{
|
|
completeStateAction(nullptr, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
updateButtonPosition();
|
|
activateButtons();
|
|
}
|
|
}
|
|
|
|
} // void RubberbandMultiPointFeature3D::onMapPosition(const QPointF &mapCoordinate)
|
|
|
|
|
|
void RubberbandMultiPointFeature3D::onGetPickingResult(const QUuid &taskId, const QList<Esri::ArcGISRuntime::IdentifyGraphicsOverlayResult*> &identifyResults)
|
|
{
|
|
if (_internal->m_pickingTask.taskId() == taskId)
|
|
{
|
|
for (auto iResult : identifyResults)
|
|
{
|
|
const QList<Esri::ArcGISRuntime::Graphic*> &gResults = iResult->graphics();
|
|
for (auto pickedGraphic : gResults)
|
|
{
|
|
if (pickedGraphic->attributes())
|
|
{
|
|
bool ok = false;
|
|
int pickedIndex = pickedGraphic->attributes()->attributeValue(QStringLiteral("Rubberband3D-Item")).toInt(&ok);
|
|
|
|
if (ok)
|
|
{
|
|
qCritical() << "Picking index " << pickedIndex;
|
|
_internal->m_currentIndex = pickedIndex;
|
|
_internal->m_screenToMap->screenToLocation(_internal->m_pickingPoint.x(), _internal->m_pickingPoint.y());
|
|
|
|
if (pickedIndex < _internal->m_marker.size())
|
|
{
|
|
GraphicalObjectPictureMarker *&marker = _internal->m_marker[pickedIndex];
|
|
|
|
if (marker)
|
|
{
|
|
marker->setImage(markerSelectionImage());
|
|
marker->updateView();
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
} // foreach pickedGraphic
|
|
} // foreach iResult
|
|
|
|
if ((!_isCircular) || (_internal->m_coordinates.size() < 2))
|
|
{
|
|
// add new coordinate and calculate map location
|
|
_internal->m_currentIndex = _internal->m_marker.size();
|
|
_internal->m_marker << nullptr;
|
|
_internal->m_coordinates << QPointF();
|
|
|
|
_internal->m_screenToMap->screenToLocation(_internal->m_pickingPoint.x(), _internal->m_pickingPoint.y());
|
|
}
|
|
}
|
|
|
|
if (_internal->m_selectionTask.taskId() == taskId)
|
|
{
|
|
for (auto iResult : identifyResults)
|
|
{
|
|
const QList<Esri::ArcGISRuntime::Graphic*> &gResults = iResult->graphics();
|
|
for (auto pickedGraphic : gResults)
|
|
{
|
|
if (pickedGraphic->attributes())
|
|
{
|
|
bool ok = false;
|
|
int pickedIndex = pickedGraphic->attributes()->attributeValue(QStringLiteral("Rubberband3D-Item")).toInt(&ok);
|
|
|
|
if ((ok) && (pickedIndex < _internal->m_marker.size()))
|
|
{
|
|
GraphicalObjectPictureMarker *&marker = _internal->m_marker[pickedIndex];
|
|
|
|
if (marker)
|
|
{
|
|
_internal->m_selectionIndex = pickedIndex;
|
|
marker->setImage(markerSelectionImage());
|
|
marker->updateView();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ((_internal->m_selectionIndex >= 0) && (_internal->m_selectionIndex < _internal->m_marker.size()))
|
|
{
|
|
GraphicalObjectPictureMarker *&marker = _internal->m_marker[_internal->m_selectionIndex];
|
|
|
|
if (marker)
|
|
{
|
|
marker->setImage(markerImage());
|
|
marker->updateView();
|
|
}
|
|
_internal->m_selectionIndex = -1;
|
|
}
|
|
} // void RubberbandMultiPointFeature3D::onGetPickingResult(const QUuid &taskId, const QList<Esri::ArcGISRuntime::IdentifyGraphicsOverlayResult*> &identifyResults)
|
|
|
|
|
|
bool RubberbandMultiPointFeature3D::selectAction(AbstractEventDispatcher *, int x, int y)
|
|
{
|
|
delete _internal->m_startMove;
|
|
_internal->m_startMove = nullptr;
|
|
|
|
if (rubberbandIsAlive())
|
|
{
|
|
if (_baseInternal->buttonProxyActive(QPointF(x,y))) return false;
|
|
|
|
MapImpl *mapImpl = static_cast<MapImpl*>(_baseInternal->_map.data());
|
|
|
|
_internal->m_pickingTask.cancel(); // cancel old task
|
|
_internal->m_pickingPoint = QPoint(x,y);
|
|
_internal->m_pickingTask = mapImpl->getEsriGeoView()->identifyGraphicsOverlays(x,y,EventMouseNavigator::pickTolerance(),false,std::numeric_limits<int>::max());
|
|
_internal->m_currentIndex = -1;
|
|
|
|
return true;
|
|
}
|
|
return false;
|
|
} // bool RubberbandMultiPointFeature3D::selectAction(AbstractEventDispatcher *, int x, int y)
|
|
|
|
|
|
bool RubberbandMultiPointFeature3D::setCoordinateAction(AbstractEventDispatcher *, int x, int y)
|
|
{
|
|
delete _internal->m_startMove;
|
|
_internal->m_startMove = nullptr;
|
|
|
|
if (rubberbandIsAlive())
|
|
{
|
|
_baseInternal->_lastClickPosition = QPointF(x,y);
|
|
|
|
if (_baseInternal->buttonProxyActive(_baseInternal->_lastClickPosition)) return false;
|
|
|
|
_internal->m_screenToMap->screenToLocation(x,y);
|
|
|
|
if ((_internal->m_currentIndex >= 0) && (_internal->m_currentIndex < _internal->m_marker.size()))
|
|
{
|
|
GraphicalObjectPictureMarker *&marker = _internal->m_marker[_internal->m_currentIndex];
|
|
|
|
if (marker)
|
|
{
|
|
marker->setImage(markerImage());
|
|
marker->updateView();
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
return false;
|
|
} // bool RubberbandMultiPointFeature3D::setCoordinateAction(AbstractEventDispatcher *, int x, int y)
|
|
|
|
|
|
bool RubberbandMultiPointFeature3D::movePickedAction(AbstractEventDispatcher *, int x, int y)
|
|
{
|
|
if (rubberbandIsAlive())
|
|
{
|
|
_internal->m_screenToMap->screenToLocation(x,y);
|
|
return true;
|
|
}
|
|
return false;
|
|
} // bool RubberbandMultiPointFeature3D::movePickedAction(AbstractEventDispatcher *, int x, int y)
|
|
|
|
|
|
bool RubberbandMultiPointFeature3D::moveAction( AbstractEventDispatcher*, int x, int y )
|
|
{
|
|
if (rubberbandIsAlive())
|
|
{
|
|
if (_baseInternal->buttonProxyActive(QPointF(x,y))) return false;
|
|
|
|
MapImpl *mapImpl = static_cast<MapImpl*>(_baseInternal->_map.data());
|
|
|
|
_internal->m_selectionTask.cancel(); // cancel old task
|
|
_internal->m_selectionTask = mapImpl->getEsriGeoView()->identifyGraphicsOverlays(x,y,EventMouseNavigator::pickTolerance(),false,std::numeric_limits<int>::max());
|
|
|
|
if ((_internal->m_selectionIndex >= 0) && (_internal->m_selectionIndex < _internal->m_marker.size()))
|
|
{
|
|
GraphicalObjectPictureMarker *&marker = _internal->m_marker[_internal->m_selectionIndex];
|
|
|
|
if (marker)
|
|
{
|
|
marker->setImage(markerImage());
|
|
marker->updateView();
|
|
}
|
|
}
|
|
_internal->m_selectionIndex = -1;
|
|
}
|
|
return false;
|
|
} // bool RubberbandMultiPointFeature3D::moveAction(AbstractEventDispatcher*,int,int)
|
|
|
|
|
|
|
|
bool RubberbandMultiPointFeature3D::completeStateAction ( AbstractEventDispatcher * causer, int x, int y )
|
|
{
|
|
if (_internal->m_coordinates.size() > ((_isClosed && !_isCircular) ? 2 : 1))
|
|
{
|
|
return applyAndEndAction(causer,x,y);
|
|
}
|
|
return false;
|
|
} // bool RubberbandMultiPointFeature3D::completeStateAction ( AbstractEventDispatcher * causer, int x, int y )
|
|
|
|
|
|
bool RubberbandMultiPointFeature3D::contextMenuAction ( AbstractEventDispatcher*,int,int ) { return rubberbandIsAlive(); }
|
|
bool RubberbandMultiPointFeature3D::deleteAction ( AbstractEventDispatcher*,int,int ) { return rubberbandIsAlive(); }
|
|
bool RubberbandMultiPointFeature3D::undoAction ( AbstractEventDispatcher*,int,int ) { return rubberbandIsAlive(); }
|
|
|
|
|
|
unsigned int RubberbandMultiPointFeature3D::coordinateCount() const
|
|
{
|
|
return (_internal->m_coordinates.size());
|
|
} // unsigned int RubberbandMultiPointFeature3D::coordinateCount() const
|
|
|
|
|
|
void RubberbandMultiPointFeature3D::update()
|
|
{
|
|
for (auto marker : qAsConst(_internal->m_marker))
|
|
if (marker) marker->updateView();
|
|
if (_internal->m_path)
|
|
_internal->m_path->updateView();
|
|
|
|
externalUpdate();
|
|
|
|
} // RubberbandMultiPointFeature3D::update()
|
|
|
|
|
|
QVector<QPointF> RubberbandMultiPointFeature3D::coordinateVector( CoordinateSystem cs ) const
|
|
{
|
|
QVector<QPointF> coordinateVector;
|
|
coordinateVector.reserve(_internal->m_coordinates.size());
|
|
|
|
for (const auto &mapCoordinate : qAsConst(_internal->m_coordinates))
|
|
coordinateVector << projectCoordinateFromMap( cs, mapCoordinate );
|
|
return coordinateVector;
|
|
} // QVector<QPointF> RubberbandMultiPointFeature3D::coordinateVector( CoordinateSystem cs ) const
|
|
|
|
|
|
QPointF RubberbandMultiPointFeature3D::singleCoordinate( unsigned int idx, CoordinateSystem cs ) const
|
|
{
|
|
if (coordinateCount() > idx)
|
|
return coordinateVector(cs).at(idx);
|
|
|
|
return QPointF();
|
|
} // QPointF RubberbandMultiPointFeature3D::singleCoordinate( unsigned int idx, CoordinateSystem cs ) const
|
|
|
|
|
|
void RubberbandMultiPointFeature3D::setCoordinateVector( const QVector<QPointF> & coordinateVector, CoordinateSystem cs )
|
|
{
|
|
_internal->m_coordinates.clear();
|
|
for (const auto &geoCoordinate : coordinateVector)
|
|
_internal->m_coordinates << projectCoordinateToMap( cs, geoCoordinate );
|
|
|
|
if ((!_internal->m_toElevation) && (_baseInternal->_map->layerFactory().elevationAvailable()))
|
|
{
|
|
_internal->m_toElevation = _baseInternal->_map->layerFactory().locationToElevation(); // layerFactory has ownership
|
|
}
|
|
|
|
// now get elevations
|
|
_internal->m_positionList3D.clear();
|
|
for (const auto &pos : qAsConst(_internal->m_coordinates))
|
|
{
|
|
if (_internal->m_toElevation)
|
|
{
|
|
QMetaObject::Connection conn;
|
|
|
|
conn = connect(_internal->m_toElevation.data(), &SituationMap::LocationToElevationHelper::elevationCompleted, this, [this,pos,conn](double elevation)
|
|
{
|
|
disconnect(conn);
|
|
|
|
_internal->m_positionList3D << Point3D(pos.x(),pos.y(),elevation);
|
|
if (_internal->m_positionList3D.size() == _internal->m_coordinates.size())
|
|
{
|
|
if (_internal->m_path) _internal->m_path->setPositions( _internal->m_positionList3D );
|
|
update();
|
|
}
|
|
});
|
|
_internal->m_toElevation->locationToElevation(pos);
|
|
}
|
|
else _internal->m_positionList3D << Point3D::fromQPointF(pos);
|
|
}
|
|
} // void RubberbandMultiPointFeature3D::setCoordinateVector( const QVector<QPointF> & coordinateVector, CoordinateSystem cs )
|
|
|
|
|
|
void RubberbandMultiPointFeature3D::setCoordinateVector(const QVector<Point3D> & coordinateVector, CoordinateSystem cs)
|
|
{
|
|
_internal->m_coordinates.clear();
|
|
_internal->m_positionList3D.clear();
|
|
|
|
for (const auto &geoCoordinate : coordinateVector)
|
|
{
|
|
const QPointF & projCoordinate = projectCoordinateToMap( cs, geoCoordinate.toPointF() );
|
|
_internal->m_coordinates << projCoordinate;
|
|
_internal->m_positionList3D << Point3D(projCoordinate.x(),projCoordinate.y(),geoCoordinate.z());
|
|
}
|
|
} // void RubberbandMultiPointFeature3D::setCoordinateVector(const QVector<Point3D> & coordinateVector, CoordinateSystem cs)
|
|
|
|
|
|
QVector<Point3D> RubberbandMultiPointFeature3D::coordinateVector3D(CoordinateSystem cs) const
|
|
{
|
|
QVector<Point3D> coordinateVector;
|
|
|
|
coordinateVector.reserve(_internal->m_coordinates.size());
|
|
|
|
for (const auto &mapCoordinate : qAsConst(_internal->m_coordinates))
|
|
coordinateVector << Point3D::fromQPointF( projectCoordinateFromMap(cs,mapCoordinate) );
|
|
|
|
return coordinateVector;
|
|
} // QVector<Point3D> RubberbandMultiPointFeature3D::coordinateVector3D(CoordinateSystem cs) const
|
|
|
|
|
|
Point3D RubberbandMultiPointFeature3D::singleCoordinate3D(unsigned int idx, CoordinateSystem cs) const
|
|
{
|
|
if (coordinateCount() > idx)
|
|
{
|
|
return coordinateVector3D(cs).at(idx);
|
|
}
|
|
return Point3D();
|
|
} // Point3D RubberbandMultiPointFeature3D::singleCoordinate3D(unsigned int idx, CoordinateSystem cs) const
|
|
|
|
|
|
|
|
} } /* namespace SituationMap::RB */
|