Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

+102
View File
@@ -0,0 +1,102 @@
/**
* @RDE_HEADER@
* MouseMoveOverlay
* $Id$
* $HeadURL$
* $Author$
*/
#include "mouse_move_overlay.h"
// Own
#include <MapImpl/map_impl.h>
// ESRI
#include <arcgis/Map.h>
#include <arcgis/CoordinateConversion.h>
#include <arcgis/GeometryEngine.h>
// Qt
#include <QDebug>
#include <QGraphicsSceneHoverEvent>
namespace SituationMap
{
class MouseMoveOverlay::Private
{
public:
Private() = default;
~Private() = default;
// ESRI data:
EsriRuntimeQt::Map *m_map = nullptr;
// OWN data:
SituationMap::MapImpl *m_mapImpl = nullptr;
}; // class MouseMoveOverlay::Private
//-----------------------------------------------------------------------------
MouseMoveOverlay::MouseMoveOverlay(MapImpl *mapImpl)
: QGraphicsItem()
, d(new Private)
{
qDebug() << LOGFUNCTION;
// object to be called:
d->m_mapImpl = mapImpl;
if (d->m_mapImpl)
d->m_map = d->m_mapImpl->getEsriMap();
setAcceptHoverEvents(true);
}
MouseMoveOverlay::~MouseMoveOverlay()
{
qDebug() << LOGFUNCTION;
delete d;
}
QRectF MouseMoveOverlay::boundingRect() const
{
if (d->m_map)
return QRect(0, 0, d->m_map->width(), d->m_map->height());
return QRect(); // fallback
}
void MouseMoveOverlay::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
// No need to paint
Q_UNUSED(painter)
Q_UNUSED(option)
Q_UNUSED(widget)
}
void MouseMoveOverlay::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
// qDebug() << LOGFUNCTION;
if (d->m_map)
{
if (!d->m_map->isReady())
return;
QPointF scenePoint = event->scenePos();
int scenePointX = scenePoint.x();
int scenePointY = scenePoint.y();
if (scenePointX < 0 || scenePointY < 0)
return;
d->m_mapImpl->onHandleMouseMove(scenePointX, scenePointY);
}
}
} // namespace SituationMap
+57
View File
@@ -0,0 +1,57 @@
/**
* @RDE_HEADER@
* MouseMoveOverlay
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <QGraphicsItem>
namespace EsriRuntimeQt
{
class MapGraphicsView;
}
//----------------------------------------------------------------------------
namespace SituationMap
{
class MapImpl;
class MouseMoveOverlay : public QGraphicsItem
{
// Q_OBJECT
public:
explicit MouseMoveOverlay(MapImpl *mapImpl);
virtual ~MouseMoveOverlay();
signals:
// void mousePositionChanged(const QPointF& screenPos, QPointF& mapPos);
// void mousePositionChanged();
protected:
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
private :
MouseMoveOverlay(const MouseMoveOverlay &other) = delete;
MouseMoveOverlay &operator=(const MouseMoveOverlay &other) = delete;
class Private;
/**
* The private d-pointer to not break BC when changing internals of this class
*/
Private *d = nullptr;
};
} // namespace SituationMap
+268
View File
@@ -0,0 +1,268 @@
/**
* @RDE_HEADER@
* Class MovementTrack
* $Id$
* $HeadURL$
* $Author$
*/
// Own
#include "movement_track.h"
#include <LtsCoordTrans/lts_coord_trans.h>
// Qt
#include <QVector>
#include <QJsonObject>
#include <QJsonArray>
namespace SituationMap
{
int MovementTrack::m_count = 0;
MovementTrack::MovementTrack(int trackId)
// : m_logger(getLogger("MovementTrack", trackId))
: m_logger(getLogger("MovementTrack"))
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
<< " trackId/participantId=" << trackId
<< " m_count=" << m_count;
++m_count;
m_trackId = trackId;
m_active = true;
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_trackId=" << m_trackId << " m_count=" << m_count;
}
MovementTrack::~MovementTrack()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " m_trackId=" << m_trackId << " m_count=" << m_count;
--m_count;
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_trackId=" << m_trackId << " m_count=" << m_count;
}
void MovementTrack::setActive(bool active)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START " << " active=" << active << " m_count=" << m_count;
m_active = active;
}
bool MovementTrack::addPosition(const COORD_T &newPosition,
qint64 currentTimeMsec, double minDistance, int maxNumberOfPositions)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " START"
<< " currentTimeMsec=" << currentTimeMsec
<< " newPosition=" << newPosition
<< " #ofCoords=" << m_cont.size();
bool success = false;
// Very first access?
if (m_cont.isEmpty())
{
m_cont.insert(currentTimeMsec, newPosition);
success = true;
}
else
{
// Avoid identical values:
const COORD_T &lastPosition = m_cont.last();
// isEmpty already checked:
if (lastPosition != newPosition)
{
const double distance = LtsCoordTrans::distance(lastPosition.x(), lastPosition.y(),
newPosition.x(), newPosition.y());
DEBUG_LOG(m_logger) << LOGFUNCTION << " distance " << distance;
if (distance > minDistance)
{
m_cont.insert(currentTimeMsec, newPosition);
success = true;
}
} // if (lastPosition != newPosition)
}
if (!m_cont.isEmpty() &&
(m_cont.size() > maxNumberOfPositions) && (maxNumberOfPositions > 0))
{
// see QTBUG-59373
m_cont.erase(m_cont.begin());
}
TRACE_LOG(m_logger) << LOGFUNCTION << " END " << "success=" << success << " #ofCoords=" << m_cont.size();
return success;
}
bool MovementTrack::removeEntriesNewer(qint64 currentTimeMsec)
{
// TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " m_active=" << m_active << " m_count=" << m_count;
bool modified = false;
QMapIterator<KEY_T, COORD_T> mapIt(m_cont);
mapIt.toBack();
while (mapIt.hasPrevious())
{
mapIt.previous();
if (mapIt.key() > currentTimeMsec)
{
m_cont.remove(mapIt.key());
modified = true;
}
else
break;
} // while
// TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_active=" << m_active << " m_count=" << m_count << " modified=" << modified;
return modified;
}
bool MovementTrack::removeEntriesOlder(qint64 currentTimeMsec, qint64 maxAgeMsec)
{
// TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " m_active=" << m_active << " m_count=" << m_count << " currentTimeMsec=" << currentTimeMsec << " maxAgeMsec=" << maxAgeMsec;
bool modified = false;
auto it = m_cont.begin();
while (it != m_cont.end())
{
const KEY_T &ageMsec = currentTimeMsec - it.key();
if (ageMsec > maxAgeMsec)
{
it = m_cont.erase(it);
modified = true;
}
else
++it;
} // while
// TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_active=" << m_active << " m_count=" << m_count << " modified=" << modified;
return modified;
}
QVector<MovementTrack::COORD_T> MovementTrack::getTrack() const
{
QVector<MovementTrack::COORD_T> ret;
ret.reserve(m_cont.size());
for (const auto &pos : m_cont)
ret.push_back(pos);
return ret;
}
QVector<MovementTrack::COORD_T> MovementTrack::getVisibleTrack(qint64 currentTimeMsec,
qint64 maxAgeMsec,
qint64 maxViewAgeMsec)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " m_trackId=" << m_trackId << " currentTimeMsec=" << currentTimeMsec << " maxAgeMsec=" << maxAgeMsec << " maxViewAgeMsec=" << maxViewAgeMsec;
removeEntriesOlder(currentTimeMsec, maxAgeMsec);
// Auch wenn keine neuen Positionen eingegangen sind,
// hat sich die Spur evtl. wegen der modifizierten Zeit 'currentTimeMsec'
// geändert:
// uebertragen in validCoords
QVector<MovementTrack::COORD_T> validCoords;
validCoords.reserve(m_cont.size());
for (auto it = m_cont.cbegin(); it != m_cont.cend(); ++it)
{
const KEY_T &ageMsec = currentTimeMsec - it.key();
if (ageMsec > maxViewAgeMsec && maxViewAgeMsec > 0)
continue;
if (ageMsec < 0)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " age is negative!!! - "
<< " currentTimeMsec=" << currentTimeMsec
<< " m_trackId=" << m_trackId
<< " ageMsec=" << ageMsec
<< " - "
<< " size = " << m_cont.size()
<< ", dis = " << std::distance(m_cont.cbegin(), it);
if (ageMsec < -1500)
WARNING_LOG(m_logger) << LOGFUNCTION << " age is negative!!! - "
<< " currentTimeMsec=" << currentTimeMsec
<< " m_trackId=" << m_trackId
<< " ageMsec=" << ageMsec
<< " - "
<< " size = " << m_cont.size()
<< ", dis = " << std::distance(m_cont.cbegin(), it);
}
DEBUG_LOG(m_logger) << LOGFUNCTION << " m_trackId=" << m_trackId << " ageMsec=" << ageMsec << " coord=" << it.value();
validCoords.push_back(it.value());
} // for
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " validCoords.size()/m_cont.size(): " << validCoords.size() << " / " << m_cont.size();
return validCoords;
}
QSharedPointer<MovementTrack> MovementTrack::read(const QJsonObject &json)
{
if (!json.contains(QLatin1String("trackId")))
return nullptr;
int trackId = -1;
if (json.contains(QLatin1String("trackId")))
trackId = json[QLatin1String("trackId")].toInt();
if (trackId < 0)
return nullptr;
QSharedPointer<MovementTrack> mt =
QSharedPointer<MovementTrack>(new MovementTrack(trackId));
// active
if (json.contains(QLatin1String("active")))
mt->setActive(json[QLatin1String("active")].toBool());
// coordinates
QJsonArray jArray = json[QLatin1String("coordinates")].toArray();
for (int idx = 0; idx < jArray.size(); ++idx)
{
const QJsonObject &objTemp = jArray[idx].toObject();
const KEY_T &timeMsec = objTemp[QLatin1String("pointInTimeMsec")].toDouble(); // toDouble!!!
Point3D p3D;
p3D.rx() = objTemp[QLatin1String("loc_x_lon")].toDouble();
p3D.ry() = objTemp[QLatin1String("loc_y_lat")].toDouble();
if (json.contains(QLatin1String("loc_z")))
p3D.rz() = objTemp[QLatin1String("loc_z")].toDouble();
mt->addPosition(p3D, timeMsec, 0, 0);
} // for
return mt;
}
QJsonObject MovementTrack::toJsonObject() const
{
QJsonObject json;
json[QLatin1String("trackId")] = m_trackId;
json[QLatin1String("active")] = m_active;
QJsonArray jArray;
QMapIterator<KEY_T, COORD_T> it(m_cont);
while (it.hasNext())
{
it.next();
const KEY_T &key = it.key();
const COORD_T &coord = it.value();
QJsonObject jsonCoord;
jsonCoord[QLatin1String("loc_x_lon")] = coord.x();
jsonCoord[QLatin1String("loc_y_lat")] = coord.y();
jsonCoord[QLatin1String("loc_z")] = coord.z();
jsonCoord[QLatin1String("pointInTimeMsec")] = key;
jArray.append(jsonCoord);
}
json[QLatin1String("coordinates")] = jArray;
return json;
}
} // namespace SituationMap
+85
View File
@@ -0,0 +1,85 @@
/**
* @RDE_HEADER@
* Class MovementTrack
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
// Own
#include <Map/point3D.h>
#include <Common/situation_map_logging.h>
#include <situation_map_export.h>
// Qt
#include <QMap>
#include <QSharedPointer>
class QJsonObject;
//----------------------------------------------------------------------------
namespace SituationMap
{
class SITUATIONMAP_EXPORT MovementTrack
{
public:
using KEY_T = qint64; // msec
using COORD_T = Point3D; // lon, lat
using CONT_T = QMap<KEY_T, COORD_T>; // ordered by time [msec]
public:
/// Constructor
explicit MovementTrack(int trackId);
/// Destructor
virtual ~MovementTrack();
int trackId() const { return m_trackId; }
int size() const { return m_cont.size(); }
void clear() { m_cont.clear(); }
void setActive(bool active);
bool isActive() const { return m_active; }
bool addPosition(const COORD_T &newPosition,
qint64 currentTimeMsec, double minDistance, int maxNumberOfPositions);
const COORD_T lastPosition() const
{
if (this->m_cont.empty())
return COORD_T();
return this->m_cont.last();
}
bool removeEntriesOlder(qint64 currentTimeMsec, qint64 maxAgeMsec);
bool removeEntriesNewer(qint64 currentTimeMsec);
QVector<COORD_T> getTrack() const;
QVector<COORD_T> getVisibleTrack(qint64 currentTimeMsec, qint64 maxAgeMsec, qint64 maxViewAgeMsec);
static QSharedPointer<MovementTrack> read(const QJsonObject &json);
QJsonObject toJsonObject() const;
protected:
static int m_count;
int m_trackId; // UniqueMapId
bool m_active;
CONT_T m_cont;
private:
LOGGER_T m_logger; ///< Interface to the Logging-Facility
};
} // namespace SituationMap
+338
View File
@@ -0,0 +1,338 @@
/**
* @RDE_HEADER@
* Class MovementTrackManager
* $Id$
* $HeadURL$
* $Author$
*/
// Own
#include "movement_track_manager.h"
// Qt
#include <QVector>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
namespace SituationMap
{
MovementTrackManager::MovementTrackManager(QObject *parent)
: BaseClass(parent)
, m_logger(getLogger("MovementTrackManager"))
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
init();
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
MovementTrackManager::~MovementTrackManager()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " size=" << m_cont.size();
m_cont.clear();
TRACE_LOG(m_logger) << LOGFUNCTION << " END ";
}
void MovementTrackManager::init()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
m_cont.clear();
m_currentTimeMsec = 0;
m_maxNumberOfTracks = 10;
m_maxNumberOfPointsPerTrack = 600; // 600
// min sec msec
m_maxAgeMsec = 30 * 60 * 1000; // (30Min * 60 * 1000= 1 800 000sec)
m_maxViewAgeMsec = 30 * 60 * 1000; // (30Min * 60 * 1000= 1 800 000sec)
m_minDistance = 2; // 2 Meter
// just for testing:
// m_maxNumberOfTracks = 3;
// m_maxAgeMsec = 6000 * 60 * 1000;
// m_maxViewAgeMsec = 6000 * 60 * 1000;
// m_maxNumberOfPointsPerTrack = 10;
// m_minDistance = 0;
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
QSet<int> MovementTrackManager::setCurrentTimeMsec(qint64 timeMsec)
{
// TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " timeMsec=" << timeMsec;
QSet<int> modifiedMapObjects;
if (m_currentTimeMsec == timeMsec)
return modifiedMapObjects;
// forward or backward?
bool forward = timeMsec > m_currentTimeMsec;
m_currentTimeMsec = timeMsec;
QVectorIterator<DATA_T> vecIt(m_cont);
while (vecIt.hasNext())
{
DATA_T item = vecIt.next();
if (!item)
continue;
bool mod;
if (forward)
mod = item->removeEntriesOlder(timeMsec, m_maxAgeMsec);
else
mod = item->removeEntriesNewer(timeMsec); // set time backward -> remove all entries whose time is too new
if (mod)
{
int trackId = item->trackId();
DEBUG_LOG(m_logger) << LOGFUNCTION << " Track changes, simId/trackId=" << trackId
<< " (m_maxAgeMsec=" << m_maxAgeMsec << ")"
<< " (m_maxViewAgeMsec=" << m_maxViewAgeMsec << ")";
modifiedMapObjects.insert(trackId);
}
} // while
// TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " timeMsec=" << timeMsec << " modifiedMapObjects=" << modifiedMapObjects.size();
return modifiedMapObjects;
}
bool MovementTrackManager::addTrack(int trackId)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " size=" << m_cont.size() << " trackId=" << trackId;
if (hasTrack(trackId))
return false;
m_cont.push_back(DATA_T(new MovementTrack(trackId)));
if (!m_cont.isEmpty() && (m_cont.size() > m_maxNumberOfTracks))
{
const int trackIdSave = m_cont.first()->trackId();
m_cont.pop_front();
emit trackRemoved(trackIdSave);
}
TRACE_LOG(m_logger) << LOGFUNCTION << " END " << " size=" << m_cont.size() << " trackId=" << trackId;
return true;
}
MovementTrackManager::DATA_T MovementTrackManager::getTrack(int trackId) const
{
QVectorIterator<DATA_T> vecIt(m_cont);
while (vecIt.hasNext())
{
DATA_T item = vecIt.next();
if (item && item->trackId() == trackId)
return item;
} // while
return nullptr;
}
void MovementTrackManager::removeTrack(int trackId)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " size=" << m_cont.size() << " trackId=" << trackId;
for (int idx = m_cont.size() - 1; idx >= 0; --idx)
{
const DATA_T &item = m_cont.at(idx);
if (item && item->trackId() == trackId)
{
m_cont.removeAt(idx);
emit trackRemoved(trackId);
}
} // for
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " size=" << m_cont.size() << " trackId=" << trackId;
}
void MovementTrackManager::activateTrack(int trackId)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " size=" << m_cont.size() << " trackId=" << trackId;
// Eintrag finden
DATA_T track = getTrack(trackId);
if (track)
{
if (!track->isActive())
{
track->setActive(true);
emit trackActivityChanged(trackId, true);
}
}
else
{
addTrack(trackId); // new Track -> active
emit trackActivityChanged(trackId, true);
}
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " size=" << m_cont.size() << " trackId=" << trackId;
}
void MovementTrackManager::deactivateTrack(int trackId)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " size=" << m_cont.size() << " trackId=" << trackId;
// 1. find track and save:
DATA_T savedTrack = getTrack(trackId);
if (!savedTrack)
return;
if (!savedTrack->isActive()) // is already deactivated
return;
// 2. remove track:
for (int idx = m_cont.size() - 1; idx >= 0; --idx)
{
const DATA_T &item = m_cont.at(idx);
if (item && item->trackId() == trackId)
m_cont.removeAt(idx);
} // for
// 3. re-add savedTrack:
savedTrack->setActive(false);
m_cont.push_front(savedTrack); // front -> remove candidate / Guez: was push_back!?
emit trackActivityChanged(trackId, false);
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " size=" << m_cont.size() << " trackId=" << trackId;
}
bool MovementTrackManager::addPosition(int trackId, const MovementTrack::COORD_T &coord, qint64 timeMsec)
{
DATA_T track = getTrack(trackId);
if (track.isNull())
return false;
return track->addPosition(coord, timeMsec, m_minDistance, m_maxNumberOfPointsPerTrack);
}
PositionCont MovementTrackManager::activeAndVisibleTrack(int trackId) const
{
DATA_T track = getTrack(trackId);
if (!track || !track->isActive())
return PositionCont();
return track->getVisibleTrack(m_currentTimeMsec, m_maxAgeMsec, m_maxViewAgeMsec);
}
void MovementTrackManager::emit_activeSimIdsChanged(const QVector<int32_t> &activeSimIds)
{
emit activeSimIdsChanged(activeSimIds);
}
bool MovementTrackManager::read(const QJsonObject &json)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
this->init();
if (json.contains(QLatin1String("currentTimeMsec")))
this->setCurrentTimeMsec(json[QLatin1String("currentTimeMsec")].toDouble()); // qint64 -> toDouble
if (json.contains(QLatin1String("maxAgeMsec")))
this->setMaxAgeMsec(json[QLatin1String("maxAgeMsec")].toDouble()); // qint64 -> toDouble
if (json.contains(QLatin1String("maxViewAgeMsec")))
this->setMaxViewAgeMsec(json[QLatin1String("maxViewAgeMsec")].toDouble()); // qint64 -> toDouble
if (json.contains(QLatin1String("minDistance")))
this->setMinDistance(json[QLatin1String("minDistance")].toInt());
if (json.contains(QLatin1String("maxNumberOfTracks")))
this->setMaxNumberOfTracks(json[QLatin1String("maxNumberOfTracks")].toInt());
if (json.contains(QLatin1String("maxNumberOfPointsPerTrack")))
this->setMaxNumberOfPointsPerTrack(json[QLatin1String("maxNumberOfPointsPerTrack")].toInt());
// coords
const QJsonArray &jArray = json[QLatin1String("movementTracks")].toArray();
DEBUG_LOG(m_logger) << LOGFUNCTION << " movementTrack QJsonArray size=" << jArray.size();
for (int idx = 0; idx < jArray.size(); ++idx)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " movementTrack QJsonArray, idx=" << idx;
const QJsonObject &objTemp = jArray[idx].toObject();
const QSharedPointer<MovementTrack> &mt = MovementTrack::read(objTemp);
if (!mt)
continue;
if (mt->trackId() >= 0)
m_cont.append(mt);
} // for
// send signals for all tracks:
for (const QSharedPointer<MovementTrack> &mt : qAsConst(m_cont))
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " emit trackActivityChanged,"
<< " mt->trackId()=" << mt->trackId()
<< " mt->isActive()=" << mt->isActive();
emit trackActivityChanged(mt->trackId(), mt->isActive());
}
return true;
}
QJsonObject MovementTrackManager::toJsonObject() const
{
QJsonObject json;
json[QLatin1String("currentTimeMsec")] = m_currentTimeMsec;
json[QLatin1String("maxAgeMsec")] = m_maxAgeMsec;
json[QLatin1String("maxViewAgeMsec")] = m_maxViewAgeMsec;
json[QLatin1String("minDistance")] = m_minDistance;
json[QLatin1String("maxNumberOfTracks")] = m_maxNumberOfTracks;
json[QLatin1String("maxNumberOfPointsPerTrack")] = m_maxNumberOfPointsPerTrack;
QJsonArray jArray;
for (const auto &item : m_cont)
{
if (!item)
continue;
QJsonObject objTemp = item->toJsonObject();
jArray.append(objTemp);
}
json[QLatin1String("movementTracks")] = jArray;
return json;
}
QByteArray MovementTrackManager::toJson() const
{
// final - toJson
QJsonDocument jDoc(toJsonObject());
return jDoc.toJson();
}
QVector<int> MovementTrackManager::activeTrackIds() const
{
QVector<int> trackIds;
trackIds.reserve(m_cont.size());
for (const auto &item : m_cont)
{
if (item && item->isActive())
trackIds.append(item->trackId());
}
return trackIds;
}
QVector<int> MovementTrackManager::deactiveTrackIds() const
{
QVector<int> deactiveTrackIds;
deactiveTrackIds.reserve(m_cont.size());
for (const auto &item : m_cont)
{
if (item && !item->isActive())
deactiveTrackIds.append(item->trackId());
}
return deactiveTrackIds;
}
} // namespace GDW_CTC
+114
View File
@@ -0,0 +1,114 @@
/**
* @RDE_HEADER@
* Class MovementTrackManager
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
// Own
#include "movement_track.h"
#include <Map/situation_map_types.h>
// Qt
#include <QObject>
#include <QMap>
#include <QSharedPointer>
#include <QVector>
//----------------------------------------------------------------------------
namespace SituationMap
{
class SITUATIONMAP_EXPORT MovementTrackManager : public QObject
{
Q_OBJECT
public:
using COORD_T = MovementTrack::COORD_T;
using BaseClass = QObject;
/// Constructor
explicit MovementTrackManager(QObject *parent = nullptr);
/// Destructor
virtual ~MovementTrackManager();
void init();
qint64 currentTimeMsec() { return m_currentTimeMsec; }
QSet<int> setCurrentTimeMsec(qint64 timeMsec);
qint64 maxAgeMsec() { return m_maxAgeMsec; }
void setMaxAgeMsec(qint64 timeMsec) { m_maxAgeMsec = timeMsec; }
qint64 maxViewAgeMsec() { return m_maxViewAgeMsec; }
void setMaxViewAgeMsec(qint64 maxViewAgeMsec) { m_maxViewAgeMsec = maxViewAgeMsec; }
int maxNumberOfTracks() const { return m_maxNumberOfTracks; }
void setMaxNumberOfTracks(int maxNumberOfTracks) { m_maxNumberOfTracks = maxNumberOfTracks; }
int maxNumberOfPointsPerTrack() const { return m_maxNumberOfPointsPerTrack; }
void setMaxNumberOfPointsPerTrack(int maxPoints) { m_maxNumberOfPointsPerTrack = maxPoints; }
int minDistance() const { return m_minDistance; }
void setMinDistance(int minDistance) { m_minDistance = minDistance; }
bool addPosition(int trackId, const COORD_T &coord, qint64 timeMsec); // if track exists
void removeTrack(int trackId);
void activateTrack(int trackId);
void deactivateTrack(int trackId);
bool hasTrack(int trackId) const { return getTrack(trackId); }
int size() const { return m_cont.size(); }
QVector<int> activeTrackIds() const;
QVector<int> deactiveTrackIds() const;
PositionCont activeAndVisibleTrack(int trackId) const;
void emit_activeSimIdsChanged(const QVector<int32_t> &activeSimIds);
bool read(const QJsonObject &json);
QJsonObject toJsonObject() const;
QByteArray toJson() const;
Q_SIGNALS:
void trackActivityChanged(int trackId, bool active);
void trackRemoved(int trackId);
void activeSimIdsChanged(const QVector<int32_t> &activeSimIds);
private:
bool addTrack(int trackId);
using DATA_T = QSharedPointer<MovementTrack>;
using CONT_T = QVector<DATA_T>;
DATA_T getTrack(int trackId) const;
protected:
CONT_T m_cont;
qint64 m_currentTimeMsec;
qint64 m_maxAgeMsec;
qint64 m_maxViewAgeMsec;
int m_minDistance;
int m_maxNumberOfTracks;
int m_maxNumberOfPointsPerTrack;
private:
LOGGER_T m_logger; ///< Interface to the Logging-Facility
};
} // namespace SituationMap
+75
View File
@@ -0,0 +1,75 @@
/**
* @RDE_HEADER@
* TerrainProfileDialog/ Höhendialog
* $Id: zwmsui_TerrainProfileDialog.cpp 21168 2014-10-27 07:35:54Z ehrlicher $
* $HeadURL: svn://slssvn/TDS/branches/product/devel/vor_cleanup_zw_zs/ZW/ZWMS/ZWMSUI/zwmsui_TerrainProfileDialog.cpp $
* $Author: ehrlicher $
*/
#include "terrain_profile_dialog.h"
#include "ui_terrain_profile_dialog.h"
//#include <LtsCoordTrans/lts_coord_trans.h>
#include <Map/map.h>
namespace SituationMap
{
TerrainProfileDialog::TerrainProfileDialog(QWidget *parent, LtsWidgets::ButtonCombination buttonCombination)
: LtsWidgets::LtsDialog(parent, buttonCombination)
, m_ui(new Ui::TerrainProfile)
, m_logger(getLogger("TerrainProfileDialog"))
{
m_ui->setupUi(this);
connect(m_ui->heightPlotWidget, &LtsHeightPlotWidget::mousePositionChanged, this, &TerrainProfileDialog::onUpdatePosition);
// SIGNAL-SIGNAL um die Informationen nach aussen zu tragen
connect(m_ui->heightPlotWidget, &LtsHeightPlotWidget::mousePositionChanged, this, &TerrainProfileDialog::mousePositionChanged);
connect(m_ui->heightPlotWidget, &LtsHeightPlotWidget::startLineOfSight, this, &TerrainProfileDialog::startLineOfSight);
connect(m_ui->heightPlotWidget, &LtsHeightPlotWidget::stopLineOfSight, this, &TerrainProfileDialog::stopLineOfSight);
setOnlineHelpFilename(QStringLiteral("Situation-Start_Terrain_Profil"));
}
TerrainProfileDialog::~TerrainProfileDialog()
{
delete m_ui;
}
void TerrainProfileDialog::setMap(Map *map)
{
m_map = map;
}
void TerrainProfileDialog::retranslate()
{
translate(m_ui, QString(), false, tr("Terrain Profile"));
}
void TerrainProfileDialog::setData(const QVector<heightData> &data)
{
m_ui->heightPlotWidget->setData(data);
}
void TerrainProfileDialog::setMarks(const QVector<QPointF> &data)
{
m_ui->heightPlotWidget->setMarks(data);
}
void TerrainProfileDialog::setMarkerPen(const QPen &pen)
{
m_ui->heightPlotWidget->setMarkerPen(pen);
}
void TerrainProfileDialog::onUpdatePosition(const QPointF &position, double curHeight, double mouseHeight)
{
QString str; // = LtsCoordTrans::UtmCoordinate::fromGeographic(position).mgrs();
if (m_map)
str = m_map->mapToMgrsString(position);
m_ui->lblPosition->setText(str);
m_ui->lblHeight->setText(QString::number(curHeight, 'f', 2));
m_ui->lblHeightCursor->setText(QString::number(mouseHeight, 'f', 2));
}
} // namespace SituationMap
+61
View File
@@ -0,0 +1,61 @@
/**
* @RDE_HEADER@
* TerrainProfileDialog/ Höhendialog
* $Id: zwmsui_TerrainProfileDialog.h 4471 2010-06-15 06:56:51Z ehrlicher $
* $HeadURL: svn://slssvn/TDS/branches/product/devel/vor_cleanup_zw_zs/ZW/ZWMS/ZWMSUI/zwmsui_TerrainProfileDialog.h $
* $Author: ehrlicher $
*/
#pragma once
#include <LtsWidgets/lts_dialog.h>
#include <Common/situation_map_logging.h>
#include <situation_map_export.h>
namespace Ui
{
class TerrainProfile;
}
namespace QtCore
{
class QList;
class QPair;
class QPointF;
}
namespace SituationMap
{
class Map;
class SITUATIONMAP_EXPORT TerrainProfileDialog final : public LtsWidgets::LtsDialog
{
Q_OBJECT
public:
using heightData = QPair<QPointF, double>;
public:
explicit TerrainProfileDialog(QWidget *parent = nullptr, LtsWidgets::ButtonCombination buttonCombination = LtsWidgets::ButtonCombination::CloseOnly);
~TerrainProfileDialog();
void setMap(Map *map);
void setData(const QVector<heightData> &data);
void setMarks(const QVector<QPointF> &data);
void setMarkerPen(const QPen &pen);
void retranslate() override;
signals:
void mousePositionChanged(const QPointF &curPoint);
void startLineOfSight(const QPointF &startPoint);
void stopLineOfSight();
protected slots:
void onUpdatePosition(const QPointF &position, double curHeight, double mouseHeight);
private:
Ui::TerrainProfile *m_ui;
Map *m_map = nullptr;
LOGGER_T m_logger;
};
} // namespace SituationMap
+111
View File
@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TerrainProfile</class>
<widget class="QWidget" name="TerrainProfile">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Terrain Profile</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Position:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblPosition">
<property name="text">
<string notr="true">XXXXX YYYYY</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>17</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Height:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblHeight">
<property name="text">
<string notr="true">xxxx m</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>17</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Cursor height:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblHeightCursor">
<property name="text">
<string notr="true">xxxx m</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="LtsHeightPlotWidget" name="heightPlotWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LtsHeightPlotWidget</class>
<extends>QWidget</extends>
<header>LtsWidgets/lts_height_plot_widget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>