/** * @RDE_HEADER@ * PathContainer * $Id$ * $HeadURL$ * $Author$ */ // Own #include "path_container.h" #include #include #include // ESRI #include #include // Qt #include namespace SituationMap { //----------------------------------------------------------------------------- // class PathData //----------------------------------------------------------------------------- class PathData { public: PathData() = default; PositionsTranslated &pathTrans() { return m_path; } bool setPath(const PositionCont &path) { if (m_path.positions() != path) m_changed = true; m_path.setPositions(path); return m_changed; } bool visibility() const { return m_visibility.value(); } void setVisibility(bool onOff) { m_visibility = onOff; } bool changed() const { return m_changed || m_visibility.changed(); } void resetChanged() { m_changed = false; m_visibility.reset(); } ~PathData() { } public: private: PositionsTranslated m_path; SimpleValue m_visibility{true}; bool m_changed{true}; }; class PathContainer::Private { public: Private() = default; ~Private() = default; // ESRI data: Esri::ArcGISRuntime::GeoView *m_geoView{nullptr}; Esri::ArcGISRuntime::GraphicsOverlay *m_graphicsLayer{nullptr}; // Own data: CoordTranslationFunctor *m_coordTransFunctor{nullptr}; QString m_debugInfo; // will be appended by consecutive number UniqueMapId m_uniqueMapId; SimpleValue m_lineStyle; SimpleValue m_fillStyle; SimpleValue m_drawOrder{0}; SimpleValue m_selected{false}; QSharedPointer m_multiPath; #ifdef LTS_DEBUG static long m_counter; #endif private: QHash> m_map; public: QSharedPointer getPathData(int key) { auto it = m_map.find(key); if (it != m_map.end()) return it.value(); auto ret = QSharedPointer(new PathData()); m_map[key] = ret; return ret; } bool remove(int key) { auto it = m_map.find(key); if (it == m_map.end()) return false; m_map.erase(it); return true; } void clear() { m_map.clear(); } int size() const { return m_map.size(); } QList keys() const { return m_map.keys(); } bool contains(int key) const { return m_map.contains(key); } const QHash> &container() const { return m_map; } }; // class PathContainer::Private #ifdef LTS_DEBUG long PathContainer::Private::m_counter = 0; #endif //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // class PathContainer //----------------------------------------------------------------------------- PathContainer::PathContainer(const Esri::ArcGISRuntime::GeoView *geoView, Esri::ArcGISRuntime::GraphicsOverlay *graphicsLayer, CoordTranslationFunctor *coordTransFunctor, const UniqueMapId &uniqueMapId) : QObject() , m_logger(getLogger("PathContainer")) , d(new Private) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; d->m_geoView = const_cast(geoView); d->m_graphicsLayer = graphicsLayer; d->m_coordTransFunctor = coordTransFunctor; d->m_uniqueMapId = uniqueMapId; QString debugInfo = QStringLiteral("%1#PathContainerPolyline").arg(d->m_debugInfo); DEBUG_LOG(m_logger) << LOGFUNCTION << " create new Object: " << debugInfo; d->m_multiPath = QSharedPointer (new GraphicalObjectMultiPath(GraphicalObjectPathType::Polyline, d->m_geoView, d->m_graphicsLayer, debugInfo, d->m_uniqueMapId)); #ifdef LTS_DEBUG INFO_LOG(m_logger) << " ctor PathContainer-Polyline counter = " << d->m_counter++ << ", debugInfo = " << debugInfo; #endif // LTS_DEBUG TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } PathContainer::PathContainer(const GraphicalObjectPathType pathType, const Esri::ArcGISRuntime::GeoView *geoView, Esri::ArcGISRuntime::GraphicsOverlay *graphicsLayer, CoordTranslationFunctor *coordTransFunctor, const UniqueMapId &uniqueMapId) : QObject() , m_logger(getLogger("PathContainer")) , d(new Private) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; d->m_geoView = const_cast(geoView); d->m_graphicsLayer = graphicsLayer; d->m_coordTransFunctor = coordTransFunctor; d->m_uniqueMapId = uniqueMapId; QString debugInfo = QStringLiteral("%1#PathContainerPolygon").arg(d->m_debugInfo); DEBUG_LOG(m_logger) << LOGFUNCTION << " create new Object: " << debugInfo; d->m_multiPath = QSharedPointer (new GraphicalObjectMultiPath(pathType, d->m_geoView, d->m_graphicsLayer, debugInfo, d->m_uniqueMapId)); #ifdef LTS_DEBUG INFO_LOG(m_logger) << " ctor PathContainer-Polygon counter = " << d->m_counter++ << ", debugInfo = " << debugInfo; #endif // LTS_DEBUG TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } PathContainer::~PathContainer() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; d->clear(); delete d; #ifdef LTS_DEBUG INFO_LOG(m_logger) << " dtor PathContainer counter =" << --d->m_counter; #endif // LTS_DEBUG TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } QString PathContainer::debugInfo() const { return d->m_debugInfo; } void PathContainer::setDebugInfo(const QString &debugInfo) { d->m_debugInfo = debugInfo; d->m_multiPath->setDebugInfo(QStringLiteral("%1#PathContainer").arg(d->m_debugInfo)); } PositionCont PathContainer::path(int idx) const { return d->getPathData(idx)->pathTrans().positions(); } bool PathContainer::setPath(int idx, const PositionCont &path) { TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " idx=" << idx << " path.size=" << path.size(); bool hasChanged = false; if (path.isEmpty()) hasChanged = d->remove(idx); else hasChanged = d->getPathData(idx)->setPath(path); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; return hasChanged; } void PathContainer::clear(int idx) { d->remove(idx); } void PathContainer::clearAll() { d->clear(); } LineStyle PathContainer::lineStyle() const { return d->m_lineStyle.value(); } void PathContainer::setLineStyle(const LineStyle &lineStyle) { d->m_lineStyle = lineStyle; } FillStyle PathContainer::fillStyle() const { return d->m_fillStyle.value(); } void PathContainer::setFillStyle(const FillStyle &fillStyle) { d->m_fillStyle = fillStyle; } int PathContainer::drawOrder() const { return d->m_drawOrder.value(); } void PathContainer::setDrawOrder(int drawOrder) { d->m_drawOrder = drawOrder; } bool PathContainer::selected() const { return d->m_selected.value(); } void PathContainer::setSelected(bool selected) { d->m_selected = selected; } bool PathContainer::visibility(int idx) const { return d->getPathData(idx)->visibility(); } void PathContainer::setVisibility(int idx, bool onOff) { d->getPathData(idx)->setVisibility(onOff); } int PathContainer::getPathCount() const { return d->size(); } QList PathContainer::getIndicationIndexList() const { return d->keys(); } bool PathContainer::updateView() { TRACE_LOG(m_logger) << LOGFUNCTION << " START" << ", debugInfo='" << d->m_debugInfo << "'" << ", d->m_map.size()= " << d->size(); bool success = true; bool bDoUpdateView = false; if (d->m_lineStyle.changed() || d->m_fillStyle.changed() || d->m_drawOrder.changed() || d->m_selected.changed()) { d->m_multiPath->setLineStyle(d->m_lineStyle.value()); d->m_multiPath->setFillStyle(d->m_fillStyle.value()); d->m_multiPath->setDrawOrder(d->m_drawOrder.value()); d->m_multiPath->setSelected(d->m_selected.value()); bDoUpdateView = true; } // is something removed? if (d->m_multiPath->pathIndexInUse() != d->keys()) { d->m_multiPath->reduceTo(d->keys()); bDoUpdateView = true; } for (auto it = d->container().begin(); it != d->container().end(); ++it) { QSharedPointer pathData = it.value(); if (pathData->changed()) { const int idx = it.key(); pathData->pathTrans().setCoordTransFunctor(d->m_coordTransFunctor); if (pathData->visibility()) { const PositionCont &pathTrans = pathData->pathTrans().positionsTranslated(); d->m_multiPath->setPath(idx, pathTrans); } else { // a cleared path will not be transfered to ESRI::Graphic, see GraphicalObjectMultiPath // So clearPath is sufficiant d->m_multiPath->clearPath(idx); } bDoUpdateView = true; pathData->resetChanged(); } } // for if (bDoUpdateView) { bool updated = d->m_multiPath->updateView(); success = updated; } // reset d->m_lineStyle.reset(); d->m_fillStyle.reset(); d->m_drawOrder.reset(); d->m_selected.reset(); TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " debugInfo='" << d->m_debugInfo << "'" << " success=" << success; return success; } } // namespace SituationMap