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

247 lines
8.5 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Interface-Implementation of LocationDisplay
* $Id$
* $HeadURL$
* $Author$
*/
// Own
#include "location_display_impl.h"
#include "map_impl.h"
#include <Map/situation_map_utils.h>
#include <MapImpl/coordinate_translation.h>
// ESRI
#include <arcgis/arcgisversion.h> // This file is created by RME, not ESRI
#include <arcgis/Map.h>
#include <arcgis/MapGraphicsView.h>
#if ACRGIS_VERSION >= 0x640800 // 100.8.0 / Update 8
# define HAS_LOCATION_DISPLAY
#endif // ACRGIS_VERSION
#ifdef HAS_LOCATION_DISPLAY
# include <arcgis/LocationDisplay.h>
# include <arcgis/SimulatedLocationDataSource.h>
#endif // HAS_LOCATION_DISPLAY
// Qt
namespace SituationMap
{
#ifdef HAS_LOCATION_DISPLAY
class LocationDisplayImpl::Private
{
public:
Private() = default;
~Private() = default;
// ESRI data:
// Own data:
SituationMap::MapImpl *m_mapImpl{nullptr};
OriginTranslated m_originTranslated;
Esri::ArcGISRuntime::LocationDisplay *m_locationDisplay{nullptr};
Esri::ArcGISRuntime::SimulatedLocationDataSource *m_locationDataSource{nullptr};
}; // class LocationDisplayImpl::Private
//-----------------------------------------------------------------------------
LocationDisplayImpl::LocationDisplayImpl(SituationMap::MapImpl *mapImpl)
: m_logger(getLogger("LocationDisplayImpl"))
, d(new Private)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
d->m_mapImpl = mapImpl;
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
LocationDisplayImpl::~LocationDisplayImpl()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
delete d;
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
bool LocationDisplayImpl::init()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
if (!d->m_mapImpl)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " no map";
return false;
}
if (d->m_mapImpl->mode() != Mode::Mode_2D)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " LocationDisplay only supported at Mode2D";
return false;
}
// setup coordTranslationFunctor
d->m_originTranslated.setCoordTransFunctor(d->m_mapImpl->coordTranslationFunctor());
d->m_locationDisplay = d->m_mapImpl->getEsriMapGraphicsView()->locationDisplay();
if (!d->m_locationDisplay)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " no locationDisplay";
return false;
}
// setup LocationDisplay:
if (d->m_locationDisplay->objectName().isEmpty())
d->m_locationDisplay->setObjectName(QStringLiteral("EsriLocationDisplay"));
QObject::connect(d->m_locationDisplay, &Esri::ArcGISRuntime::LocationDisplay::errorOccurred, d->m_locationDisplay, [this](const Esri::ArcGISRuntime::Error &error) {
ERROR_LOG(m_logger) << LOGFUNCTION << " error on LocationDisplay, error " << error;
});
if (m_logger.isDebugEnabled())
QObject::connect(d->m_locationDisplay, &Esri::ArcGISRuntime::LocationDisplay::locationChanged, d->m_locationDisplay, [this](const Esri::ArcGISRuntime::Location &location) {
DEBUG_LOG(m_logger) << LOGFUNCTION << " Location changed: " << location.position().toJson();
});
// setup DataSource:
d->m_locationDataSource = new Esri::ArcGISRuntime::SimulatedLocationDataSource(d->m_mapImpl);
d->m_locationDataSource->setObjectName(QStringLiteral("SimulatedLocationDataSource"));
QObject::connect(d->m_locationDataSource, &Esri::ArcGISRuntime::SimulatedLocationDataSource::errorOccurred, d->m_locationDisplay, [this](const Esri::ArcGISRuntime::Error &error) {
ERROR_LOG(m_logger) << LOGFUNCTION << " error on SimulatedLocationDataSource, error " << error;
});
// Maybe reduce animation rate:
// d->m_locationDataSource->setIterationRate(0.25);
d->m_locationDisplay->setDataSource(d->m_locationDataSource);
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return (d->m_locationDisplay);
}
bool LocationDisplayImpl::setCurrentLocation(const Point3D & currentLocation,
double horizontalAccuracy,
double velocity,
double course,
bool lastKnown)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, currentLocation=" << currentLocation
<< ", horizontalAccuracy=" << horizontalAccuracy
<< ", velocity=" << velocity
<< ", course=" << course
<< ", lastKnown=" << lastKnown;
if (!d->m_mapImpl)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " no map";
return false;
}
if (!d->m_locationDataSource)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " no locationDataSource";
return false;
}
// convert using coordTranslationFunctor (wrapped by OriginTranslated)
d->m_originTranslated.setOrigin(currentLocation);
const Point3D &origionTranslated = d->m_originTranslated.originTranslated();
Esri::ArcGISRuntime::Point point(origionTranslated.x(), origionTranslated.y(), origionTranslated.z(), d->m_mapImpl->getEsriSpatialReference());
DEBUG_LOG(m_logger) << LOGFUNCTION << " point=" << point.toJson();
// const int velocity = 0; // 0 => kein Richtungsinformation in der Darstellung
Esri::ArcGISRuntime::Location location(point,
0, // The horizontal accuracy in meters. Positive values or NaN are supported
velocity, // The location's velocity in meters per second
course, // The location's course in degrees (clockwise), 0 being true North.
lastKnown // (false->blue ; true -> gray)
);
d->m_locationDataSource->setLocations({location});
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return true;
}
bool LocationDisplayImpl::setOutdated(bool lastKnown)
{
return setCurrentLocation(d->m_originTranslated.origin(),0.0 ,0.0 ,0.0 ,lastKnown);
}
bool LocationDisplayImpl::start()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
// 2023, N.Thoden: V100.15: use LocationDisplay instead of LocationDataSource
if (!d->m_locationDisplay)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " no locationDisplay";
return false;
}
// d->m_locationDisplay->setAutoPanMode(Esri::ArcGISRuntime::LocationDisplayAutoPanMode::Recenter);
// d->m_locationDisplay->setInitialZoomScale(8123);
d->m_locationDisplay->start();
// d->m_locationDataSource->start();
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return true;
}
void LocationDisplayImpl::stop()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
// 2023, N.Thoden: V100.15: use LocationDisplay instead of LocationDataSource
if (!d->m_locationDisplay)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " no locationDisplay";
return;
}
d->m_locationDisplay->stop();
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
bool LocationDisplayImpl::isStarted()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
// 2023, N.Thoden: V100.15: avoid deprecated, use LocationDisplay instead of LocationDataSource
if (!d->m_locationDisplay)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " no locationDisplay";
return false;
}
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return d->m_locationDisplay->isStarted();
}
#else // HAS_LOCATION_DISPLAY
LocationDisplayImpl::LocationDisplayImpl(SituationMap::MapImpl *mapImpl)
: m_logger(getLogger("LocationDisplayImpl"))
, d(nullptr)
{ Q_UNUSED(mapImpl); }
LocationDisplayImpl::~LocationDisplayImpl() {}
bool LocationDisplayImpl::init() {return false; }
bool LocationDisplayImpl::setCurrentLocation(const Point3D & /*currentLocation*/,
double /*horizontalAccuracy*/,
double /*velocity*/,
double /*course*/,
bool /*lastKnown*/)
{ return false; }
bool LocationDisplayImpl::start() { return false; }
void LocationDisplayImpl::stop() { }
bool LocationDisplayImpl::isStarted() { return false; }
bool LocationDisplayImpl::setOutdated(bool lastKnown) { return lastKnown; }
#endif // HAS_LOCATION_DISPLAY
} // namespace SituationMap