/** * @RDE_HEADER@ * Class MovementTrackManager * $Id$ * $HeadURL$ * $Author$ */ // Own #include "movement_track_manager.h" // Qt #include #include #include #include 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 MovementTrackManager::setCurrentTimeMsec(qint64 timeMsec) { // TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " timeMsec=" << timeMsec; QSet modifiedMapObjects; if (m_currentTimeMsec == timeMsec) return modifiedMapObjects; // forward or backward? bool forward = timeMsec > m_currentTimeMsec; m_currentTimeMsec = timeMsec; QVectorIterator 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 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 &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 &mt = MovementTrack::read(objTemp); if (!mt) continue; if (mt->trackId() >= 0) m_cont.append(mt); } // for // send signals for all tracks: for (const QSharedPointer &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 MovementTrackManager::activeTrackIds() const { QVector trackIds; trackIds.reserve(m_cont.size()); for (const auto &item : m_cont) { if (item && item->isActive()) trackIds.append(item->trackId()); } return trackIds; } QVector MovementTrackManager::deactiveTrackIds() const { QVector 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