339 lines
9.4 KiB
C++
Executable File
339 lines
9.4 KiB
C++
Executable File
/**
|
|
* @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
|