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

149 lines
4.5 KiB
C++
Executable File

/**
* @RDE_HEADER@
* ScreenToLocationHelper
* $Id$
* $HeadURL$
* $Author$
*/
// Own
#include "screen_to_location_helper.h"
#include "Map/situation_map_utils.h"
// ESRI
#include <arcgis/TaskWatcher.h>
// Qt
#include <QPointer>
// V100.2.1: to guarante good accuracy of elevation we have to ignore 3d objects :-(
#define USE_SCREEN_TO_BASE_SURFACE
//----------------------------------------------------------------------------
namespace SituationMap
{
//----------------------------------------------------------------------------
class ScreenToLocationHelper::Private
{
public:
Private() = default;
~Private() = default;
// ESRI data:
QPointer<Esri::ArcGISRuntime::SceneGraphicsView> m_sceneGraphicsView;
int m_windowPosX = 0;
int m_windowPosY = 0;
};
//----------------------------------------------------------------------------
ScreenToLocationHelper::ScreenToLocationHelper(Esri::ArcGISRuntime::SceneGraphicsView *sceneGraphicsView)
: BaseClass(sceneGraphicsView)
, m_logger(getLogger("ScreenToLocationHelper"))
, d(new Private)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
d->m_sceneGraphicsView = sceneGraphicsView;
if (d->m_sceneGraphicsView)
connect(d->m_sceneGraphicsView.data(), &Esri::ArcGISRuntime::SceneGraphicsView::screenToLocationCompleted,
this, &ScreenToLocationHelper::onScreenToLocationCompleted);
}
ScreenToLocationHelper::~ScreenToLocationHelper()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
this->stop();
delete d;
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
void ScreenToLocationHelper::stop()
{
if (d->m_sceneGraphicsView)
d->m_sceneGraphicsView->disconnect(this);
disconnect(this);
BaseClass::stop();
}
void ScreenToLocationHelper::screenToLocation(int windowPosX, int windowPosY)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " windowPosX = " << windowPosX << " windowPosY = " << windowPosY;
d->m_windowPosX = windowPosX;
d->m_windowPosY = windowPosY;
BaseClass::newComputationRequested();
}
void ScreenToLocationHelper::mainComputation()
{
if (!d->m_sceneGraphicsView)
return;
#ifdef USE_SCREEN_TO_BASE_SURFACE
// BUG-000109976 - Segmentation fault on Scene Viewer destruction (Esri Case #02020238)
// BUG on destroy of SceneView. So use 'screenToBaseSurface' instead.
// Difference: screenToLocations takes Building and Features into account.
// screenToBaseSurface uses baseSurface only.
const Esri::ArcGISRuntime::Point &locationMap = d->m_sceneGraphicsView->screenToBaseSurface(d->m_windowPosX, d->m_windowPosY);
emit mouseScenePositionChanged(Point3D(locationMap.x(), locationMap.y(), locationMap.z()), !locationMap.isEmpty());
#else
// qCritical() << " ScreenX=" << d->m_windowPosX << " ScreenY=" << d->m_windowPosY;
const Esri::ArcGISRuntime::TaskWatcher &tw = d->m_sceneGraphicsView->screenToLocation(d->m_windowPosX, d->m_windowPosY);
if (!insertTask(tw))
ERROR_LOG(m_logger) << LOGFUNCTION << " screenToLocation failed";
TRACE_LOG(m_logger) << LOGFUNCTION << " screenToLocation"
<< " taskId = " << tw.taskId()
<< " (m_windowPosX " << d->m_windowPosX << " m_windowPosY " << d->m_windowPosY << ")...";
#endif // USE_SCREEN_TO_BASE_SURFACE
}
void ScreenToLocationHelper::onScreenToLocationCompleted(const QUuid &taskId, const Esri::ArcGISRuntime::Point &locationMap)
{
if (!this->removeTask(taskId))
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " not our task -> skip;";
return;
}
// qCritical() << " sceneLocation= " << " x:" << locationMap.x() << " y:" << locationMap.y() << " z:" << locationMap.z();
const Point3D mapCoordinate(locationMap.x(), locationMap.y(), locationMap.z());
// ^^^^^^^^^^^^^^^^^ depends on current map scale!?
// Case 02063359 [BOS] wrong Elevation with ElevationSource
// BUG-000111521 The elevation (z) value returned by SceneGraphicsView::screenToLocationCompleted() function depends on the current map scale
TRACE_LOG(m_logger) << LOGFUNCTION << " screenToLocationCompl "
<< " taskId = " << taskId
<< " (m_windowPosX " << d->m_windowPosX << " m_windowPosY " << d->m_windowPosY << ")..."
<< " (mapCoordinate " << mapCoordinate << ", z=" << locationMap.z() << ")";
emit mouseScenePositionChanged(mapCoordinate, !locationMap.isEmpty());
}
} // namespace SituationMap