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

205 lines
5.5 KiB
C++
Executable File

/**
* @RDE_HEADER@
* LocationToElevationHelper
* $Id$
* $HeadURL$
* $Author$
*/
// Own
#include "location_to_elevation_helper.h"
#include "Map/situation_map_utils.h"
//
// NOTE: define should be in the headerfile to switch location_to_elevation_bulk also
//
#ifdef USE_ELEVATION_MAP_AS_WORKAROUND
#include "Map/coord_translation_functor.h" // ToDo: remove if Esri-Surface will work under windows without crash
#include "MapImpl/map_impl.h"
#include <ElevationMap/elevation_map_manager.h>
#endif // USE_ELEVATION_MAP_AS_WORKAROUND
// ESRI
#include <arcgis/Surface.h>
#include <arcgis/Point.h>
// Qt
#include <QPointer>
//----------------------------------------------------------------------------
namespace SituationMap
{
//----------------------------------------------------------------------------
class LocationToElevationHelper::Private
{
public:
Private() = default;
~Private() = default;
// ESRI data:
QPointer<Esri::ArcGISRuntime::Surface> m_surface;
Esri::ArcGISRuntime::Point m_location;
Esri::ArcGISRuntime::SpatialReference m_spatialReference;
#ifdef USE_ELEVATION_MAP_AS_WORKAROUND
CoordTranslationFunctor *m_coordTransFunctor; // ToDo: remove once Esri-Surface will work under windows without crash
QPointer<ElevationMapManager> m_elevationMapManager;
#endif // USE_ELEVATION_MAP_AS_WORKAROUND
};
//----------------------------------------------------------------------------
LocationToElevationHelper::LocationToElevationHelper(QObject *parent)
: BaseClass(parent)
, m_logger(getLogger("LocationToElevationHelper"))
, d(new Private)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
LocationToElevationHelper::~LocationToElevationHelper()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
this->stop();
delete d;
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
bool LocationToElevationHelper::init(Map *map,
Esri::ArcGISRuntime::Surface *surface,
const Esri::ArcGISRuntime::SpatialReference &spatialReference)
{
this->stop();
connect(map, &Map::beginDestroy, this, &LocationToElevationHelper::stop);
d->m_surface = surface;
d->m_spatialReference = spatialReference;
#ifdef USE_ELEVATION_MAP_AS_WORKAROUND
d->m_elevationMapManager = static_cast<MapImpl*>(map)->getElevationMapManager().get(); // ToDo: remove (?) if Esri-Surface will work under windows without crash
d->m_coordTransFunctor = map->coordTranslationFunctor();
if (!d->m_elevationMapManager)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " no ElevationMapManager";
return false;
}
#endif // USE_ELEVATION_MAP_AS_WORKAROUND
if (!d->m_surface)
return false;
INFO_LOG(m_logger) << LOGFUNCTION << " m_spatialReference.wkid = " << d->m_spatialReference.wkid();
// be prepared in case of destruction:
connect(d->m_surface.data(), &Esri::ArcGISRuntime::Surface::destroyed, this, &LocationToElevationHelper::stop);
// assume that m_surface is loaded:
QMetaObject::Connection con;
if (d->m_surface)
con = connect(d->m_surface.data(), &Esri::ArcGISRuntime::Surface::locationToElevationCompleted,
this, &LocationToElevationHelper::onLocationToElevationCompleted);
if (!con)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " connect failed";
return false;
}
return true;
}
void LocationToElevationHelper::stop()
{
if (d->m_surface)
d->m_surface->disconnect(this);
this->disconnect(this);
BaseClass::stop();
d->m_surface.clear();
}
void LocationToElevationHelper::locationToElevation(const QPointF &mapLocation)
{
locationToElevation(Esri::ArcGISRuntime::Point(mapLocation.x(), mapLocation.y(), d->m_spatialReference));
}
void LocationToElevationHelper::locationToElevation(const Esri::ArcGISRuntime::Point &esriMapLocation)
{
#ifdef USE_ELEVATION_MAP_AS_WORKAROUND
if (d->m_elevationMapManager) // ToDo: remove (?) if Esri-Surface will work under windows without crash
{
double lon = esriMapLocation.x();
double lat = esriMapLocation.y();
if ((d->m_coordTransFunctor) && (!d->m_coordTransFunctor->mapIsGeographic()))
{
const QPointF & geoLoc = d->m_coordTransFunctor->mapToGeographic(lon, lat);
lon = geoLoc.x();
lat = geoLoc.y();
}
const double ele = d->m_elevationMapManager->elevation(lon,lat);
emit elevationCompleted(ele);
return;
}
#endif // USE_ELEVATION_MAP_AS_WORKAROUND
d->m_location = esriMapLocation;
// this->cancel(); // cancel all former:
BaseClass::newComputationRequested();
}
void LocationToElevationHelper::mainComputation()
{
if (!d->m_surface)
return;
if (d->m_surface->loadStatus() != Esri::ArcGISRuntime::LoadStatus::Loaded)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " surface not loaded yet";
return;
}
const Esri::ArcGISRuntime::TaskWatcher &tw = d->m_surface->locationToElevation(Esri::ArcGISRuntime::Point(d->m_location));
if (!insertTask(tw))
ERROR_LOG(m_logger) << LOGFUNCTION << " locationToElevation failed";
}
void LocationToElevationHelper::onLocationToElevationCompleted(const QUuid &taskId, double elevation)
{
// INFO_LOG(m_logger) << LOGFUNCTION << " locationToElevation onLocationToElevationCompleted, elevation= " << elevation;
if (!this->removeTask(taskId))
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " not our task -> skip;";
return;
}
emit elevationCompleted(elevation);
}
} // namespace SituationMap