/** * @RDE_HEADER@ * CoordinateTranslation * $Id$ * $HeadURL$ * $Author$ */ // Own #include "coordinate_translation.h" #include #include #include #include // ESRI #include #include // Qt #include #include //---------------------------------------------------------------------------- namespace SituationMap { void TranslatedBase::setCoordTransFunctor(CoordTranslationFunctor *functor) { m_coordTransFunctor = functor; } void TranslatedBase::setMapObjectImpl(AbstractMapObjectImpl *mapObjectImpl) { m_mapObjectImpl = mapObjectImpl; } OriginTranslated::OriginTranslated() #ifdef WITH_LOGGING : m_logger(getLogger("OriginTranslated")) #endif {} Point3D OriginTranslated::origin() const { return m_origin; } bool OriginTranslated::setOrigin(const Point3D &origin) { bool changed = m_origin != origin; if (changed) { m_origin = origin; m_translated = false; } return changed; } const Point3D &OriginTranslated::originTranslated() const { #ifdef WITH_LOGGING TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " m_origin=" << m_origin ; #endif if (!m_translated) { // m_coordTransFunctor has priority, otherwise use functor of mapImpl: if (!m_coordTransFunctor) { if (m_mapObjectImpl && m_mapObjectImpl->mapImpl()) { // if useful, a MapObjectType specific functor can be prefered here: // like: if (m_mapObjectImpl->coordTranslationFunctor()) ctFunctor=m_mapObjectImpl->coordTranslationFunctor(); m_coordTransFunctor = m_mapObjectImpl->mapImpl()->coordTranslationFunctor(); } } if (m_coordTransFunctor) m_originTranslated = m_coordTransFunctor->geographicToMap(m_origin); else m_originTranslated = Point3D(); m_translated = true; } #ifdef WITH_LOGGING TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_originTranslated=" << m_originTranslated ; #endif return m_originTranslated; } PositionsTranslated::PositionsTranslated() : m_mutex(QMutex::Recursive) #ifdef WITH_LOGGING , m_logger(getLogger("PositionsTranslated")) #endif {} PositionCont PositionsTranslated::positions() const { QMutexLocker lock(&m_mutex); return m_positions + m_singlePositions; } bool PositionsTranslated::setPositions(const PositionCont &posCont) { QMutexLocker lock(&m_mutex); bool changed = m_positions != posCont; if (changed) { m_positions = posCont; m_translated = false; } m_singlePositions.clear(); return changed; } void PositionsTranslated::addSinglePosition(const Point3D &singlePositions) { QMutexLocker lock(&m_mutex); m_singlePositions.append(singlePositions); } bool PositionsTranslated::setPositionsTranslated(const PositionCont &posCont) { QMutexLocker lock(&m_mutex); if ((m_translated) && (m_positionsTranslated == posCont)) return true; m_positionsTranslated = posCont; m_positions.clear(); if (!m_coordTransFunctor) { if (m_mapObjectImpl && m_mapObjectImpl->mapImpl()) { // if useful, a MapObjectType specific functor can be prefered here: // like: if (m_mapObjectImpl->coordTranslationFunctor()) ctFunctor=m_mapObjectImpl->coordTranslationFunctor(); m_coordTransFunctor = m_mapObjectImpl->mapImpl()->coordTranslationFunctor(); } } if (m_coordTransFunctor) { m_positions.reserve(m_positionsTranslated.size()); for (int i = 0; i < m_positionsTranslated.count(); ++i) m_positions.push_back(m_coordTransFunctor->mapToGeographic(m_positionsTranslated.at(i))); // for } m_singlePositions.clear(); m_translated = true; return false; } // PositionsTranslated::setPositionsTranslated( const PositionCont & posCont ) int PositionsTranslated::size() const { QMutexLocker lock(&m_mutex); return m_positions.size() + m_singlePositions.size(); } bool PositionsTranslated::isEmpty() const { QMutexLocker lock(&m_mutex); return m_positions.isEmpty() && m_singlePositions.isEmpty(); } void PositionsTranslated::clear() { QMutexLocker lock(&m_mutex); m_positions.clear(); m_positionsTranslated.clear(); m_singlePositions.clear(); m_translated = false; } Point3D PositionsTranslated::first() { if (isEmpty()) return Point3D(); if (! m_positions.isEmpty()) return m_positions.first(); return m_singlePositions.first(); } Point3D PositionsTranslated::last() { if (isEmpty()) return Point3D(); if (! m_singlePositions.isEmpty()) return m_singlePositions.last(); return m_positions.last(); } const PositionCont &PositionsTranslated::positionsTranslated() const { #ifdef WITH_LOGGING TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " m_positions=" << m_positions; #endif QMutexLocker lock(&m_mutex); // !!! Important: consolidate !!! consolidate(); if (!m_translated) { // translate: m_positionsTranslated = geographicToMap(m_positions); m_translated = true; } #ifdef WITH_LOGGING TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_positionsTranslated=" << m_positionsTranslated; #endif return m_positionsTranslated; } PositionCont PositionsTranslated::geographicToMap(const PositionCont &positions) const { PositionCont ret; // m_coordTransFunctor has priority, otherwise use functor of mapImpl: if (!m_coordTransFunctor) { if (m_mapObjectImpl && m_mapObjectImpl->mapImpl()) { // if useful, a MapObjectType specific functor can be prefered here: // like: if (m_mapObjectImpl->coordTranslationFunctor()) ctFunctor=m_mapObjectImpl->coordTranslationFunctor(); m_coordTransFunctor = m_mapObjectImpl->mapImpl()->coordTranslationFunctor(); } } if (!m_coordTransFunctor) return ret; ret.reserve(positions.size()); for (int i = 0; i < positions.count(); ++i) { const Point3D &p = positions.at(i); ret.push_back(m_coordTransFunctor->geographicToMap(p)); } // for return ret; } const Point3D &PositionsTranslated::startPointTranslated() const { QMutexLocker lock(&m_mutex); // make sure that positions are translated: positionsTranslated(); return m_positionsTranslated.first(); } const Point3D &PositionsTranslated::endPointTranslated() const { QMutexLocker lock(&m_mutex); // make sure that positions are translated: positionsTranslated(); return m_positionsTranslated.back(); } double PositionsTranslated::angleOfStartSegment() const { QMutexLocker lock(&m_mutex); positionsTranslated(); const int size = m_positionsTranslated.size(); if (size < 2) return 0; // rechtwinkliges Koordinatensystem benutzen return MathUtils::getAngleDegreeNorth(m_positionsTranslated.at(0).toPointF(), m_positionsTranslated.at(1).toPointF()); } double PositionsTranslated::angleOfEndSegment() const { QMutexLocker lock(&m_mutex); positionsTranslated(); const int size = m_positionsTranslated.size(); if (size < 2) return 0; // rechtwinkliges Koordinatensystem benutzen return MathUtils::getAngleDegreeNorth(m_positionsTranslated.at(size - 2).toPointF(), m_positionsTranslated.at(size - 1).toPointF()); } double PositionsTranslated::angleOfClosingSegment() const { QMutexLocker lock(&m_mutex); positionsTranslated(); const int size = m_positionsTranslated.size(); if (size < 2) return 0; // rechtwinkliges Koordinatensystem benutzen return MathUtils::getAngleDegreeNorth(m_positionsTranslated.last().toPointF(), m_positionsTranslated.first().toPointF()); } void PositionsTranslated::consolidate() const { QMutexLocker lock(&m_mutex); if (m_translated) { // ok, m_positions is already translated to m_positionsTranslated // translate just the remaining m_singlePositions: // To do so // 1. add the m_singlePositions to m_positions m_positions += m_singlePositions; // 2. translate just the remaining m_singlePositions // 3. add the now translated singlePositions to m_positionsTranslated += geographicToMap(m_singlePositions); // 4. cleanup m_singlePositions: m_singlePositions.clear(); } else { // move m_singlePositions to m_positions m_positions += m_singlePositions; m_singlePositions.clear(); } } } // namespace SituationMap