/** * @RDE_HEADER@ * ScreenToLocationHelper * $Id$ * $HeadURL$ * $Author$ */ // Own #include "screen_to_location_helper.h" #include "Map/situation_map_utils.h" // ESRI #include // Qt #include // 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 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