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