/** * @RDE_HEADER@ * LocationToElevationBulk * $Id$ * $HeadURL$ * $Author$ */ #pragma once #include "screen_location_elevation_helper_base.h" #include #include // for ElevationMap-based calculation #include #include #include //ESRI #include #include #include // Qt #include #include #include #include namespace Esri { namespace ArcGISRuntime { class Surface; class Point; class SpatialReference; } } //---------------------------------------------------------------------------- namespace SituationMap { class LocationData : public QObject { Q_OBJECT public: explicit LocationData(const Esri::ArcGISRuntime::Point &esriMapLocation) : QObject() , m_esriMapLocation(esriMapLocation) {} ~LocationData() { cancel(); } /*! \name Prepare surface (ESRI-based) OR map (own class ElevationMap */ //@{ void setSurface(Esri::ArcGISRuntime::Surface *surface) { m_map.clear(); m_surface = QPointer(surface); connect(m_surface.data(), &Esri::ArcGISRuntime::Surface::locationToElevationCompleted, this, &LocationData::onLocationToElevationCompleted, Qt::UniqueConnection); } void setMap(Map *map) { m_surface.clear(); m_map = map; } //@} bool startLocationToElevation() { // ESRI-Surface-based calculation : if (m_surface) { m_taskWatcher = m_surface->locationToElevation(m_esriMapLocation); if (!m_taskWatcher.isValid()) { qCritical() << " locationToElevation failed, taskWatcher invalid"; return false; } return true; } // : ESRI-Surface-based calculation // ElevationMap-based calculation : if (m_map) { auto elevationMap = static_cast(m_map.data())->getElevationMapManager(); // ToDo: remove if Esri-Surface will work without crash if (!elevationMap) { qCritical() << " no ElevationMapManager"; return false; } double lon = m_esriMapLocation.x(); double lat = m_esriMapLocation.y(); CoordTranslationFunctor *coordTranslationFunctor = m_map->coordTranslationFunctor(); if ((coordTranslationFunctor) && (!coordTranslationFunctor->mapIsGeographic())) { const QPointF &geoLoc = coordTranslationFunctor->mapToGeographic(lon, lat); lon = geoLoc.x(); lat = geoLoc.y(); } m_elevation = elevationMap->elevation(lon, lat); emit elevationCompleted(); return true; } // : ElevationMap-based calculation return false; } bool cancel() { return m_taskWatcher.cancel(); } const Esri::ArcGISRuntime::Point &location() const { return m_esriMapLocation; } bool hasElevation() const { return std::isnan(m_elevation); } double elevation() const { return m_elevation; } void setElevation(double elevation) { m_elevation = elevation; } signals: void elevationCompleted(); protected slots: void onLocationToElevationCompleted(const QUuid &taskId, double elevation) { if (m_taskWatcher.taskId() != taskId) return; m_elevation = elevation; emit elevationCompleted(); } private: // In: Esri::ArcGISRuntime::Point m_esriMapLocation; // processing: QPointer m_surface; // for ESRI-Surface-based calculation QPointer m_map; // for ElevationMap-based calculation Esri::ArcGISRuntime::TaskWatcher m_taskWatcher; // out: double m_elevation = std::nan(""); }; // LocationData /** * @brief The LocationToElevationBulk class helps calculate a couple of locations to their corresponding elevation */ class SITUATIONMAP_EXPORT LocationToElevationBulk : public QObject { Q_OBJECT using BaseClass = QObject; public: /*! \name Construction, Destruction */ //@{ explicit LocationToElevationBulk(QObject *parent = nullptr); ~LocationToElevationBulk(); bool init(Map *map, Esri::ArcGISRuntime::Surface *surface); LocationToElevationBulk(const LocationToElevationBulk &other) = delete; LocationToElevationBulk &operator=(LocationToElevationBulk &other) = delete; //@} void addLocation(const Esri::ArcGISRuntime::Point &esriMapLocation); void start(); void stop(); void reset(); int size() const; QVector< QPair< QPointF, double > > results() const; Q_SIGNALS: void locationsToElevationsCompleted(); private Q_SLOTS: void onLocationDataCompleted(); protected: LOGGER_T m_logger; ///< Interface of the Logging-Facility class Private; /** * The private d->pointer to not break BC when changing internals of this class */ Private *d = nullptr; }; } // namespace SituationMap