/** * @RDE_HEADER@ * GraphicalObjectPath * $Id$ * $HeadURL$ * $Author$ */ // Own #include "graphical_object_multi_path.h" #include // operator<< // ESRI #include #include #include #include #include #include #include // Qt namespace SituationMap { GraphicalObjectMultiPath::GraphicalObjectMultiPath(const GraphicalObjectPathType type , const Esri::ArcGISRuntime::GeoView *geoView , Esri::ArcGISRuntime::GraphicsOverlay *graphicsLayer , const QString &debugInfo , UniqueMapId uniqueMapId) : BaseClass(geoView, graphicsLayer, debugInfo, uniqueMapId) , m_pathType(type) , m_logger(getLogger("GraphicalObjectMultiPath")) { TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'" << " m_pathType=" << m_pathType; TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'" << " m_pathType=" << m_pathType; } GraphicalObjectMultiPath::~GraphicalObjectMultiPath() { TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'" << " m_pathType=" << m_pathType; TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'" << " m_pathType=" << m_pathType; } PositionCont GraphicalObjectMultiPath::path(int pathIndex) const { TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'" << " pathIndex=" << pathIndex; if (hasPosCont(pathIndex)) return getPosCont(pathIndex).value(); return {}; } void GraphicalObjectMultiPath::setPath(int pathIndex, const PositionCont &positions) { TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'" << " pathIndex=" << pathIndex << " positions=" << positions; m_positionsCont[pathIndex] = positions; TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'"; } void GraphicalObjectMultiPath::clearPath(int pathIndex) { TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'" << " pathIndex=" << pathIndex; if (pathIndex == -1) { m_positions.refValue().clear(); m_positionsCont.clear(); } else { if (hasPosCont(pathIndex)) { // Do not remove the whole entry to let changed() work m_positionsCont[pathIndex].refValue().clear(); } } TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'"; } void GraphicalObjectMultiPath::clearAllPaths() { TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'"; m_positions.refValue().clear(); m_positionsCont.clear(); TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'"; } void GraphicalObjectMultiPath::reduceTo(const QList &remainingPathIndexes) { TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'" << " remainingPathIndexes=" << remainingPathIndexes; QList keys = m_positionsCont.keys(); for (int key : qAsConst(keys)) { if (!remainingPathIndexes.contains(key)) { // Do not remove the whole entry to let chanded() work m_positionsCont[key].refValue().clear(); } } TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'"; } QList GraphicalObjectMultiPath::pathIndexInUse() { TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'"; QList ret; ///// ret << 0; // pathIndex=0 -> m_positions QMapIterator > mapIt(m_positionsCont); while (mapIt.hasNext()) { mapIt.next(); const SimpleValue &posData = mapIt.value(); const PositionCont &posCont = posData.value(); if (! posCont.isEmpty()) ret += mapIt.key(); } // while TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'"; return ret; } bool GraphicalObjectMultiPath::create() { TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'"; bool success = BaseClass::create(); if (!success) { ERROR_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'" << " create failed"; return false; } TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'"; return success; } bool GraphicalObjectMultiPath::updateViewImpl() { TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'"; bool success = create(); if (!success) { ERROR_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'" << " create failed"; return false; } success = BaseClass::updateViewImpl(); if (!success) { ERROR_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'" << " updateView failed"; return false; } success = updatePositions(); TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'" << " success = " << success << " drawOrder = " << m_graphic->zIndex(); return success; } bool GraphicalObjectMultiPath::updatePositions() { TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'"; bool success = true; int pathIdxToInsert = 0; const int minPoints = this->pathType() == GraphicalObjectPathType::Polyline ? 2 : 3; QSharedPointer builder; // some preparations: ( do no check isMultiPoint / isArea: m_positions should typically be empty!!! switch (m_pathType) { case GraphicalObjectPathType::Polyline: builder = QSharedPointer(new Esri::ArcGISRuntime::PolylineBuilder(spatialReference())); break; case GraphicalObjectPathType::Polygon: builder = QSharedPointer(new Esri::ArcGISRuntime::PolygonBuilder(spatialReference())); break; } // switch QSharedPointer partCollection = QSharedPointer(new Esri::ArcGISRuntime::PartCollection(builder->spatialReference())); TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'" << ", m_positionsCont.size() /#rings=" << m_positionsCont.size(); QMutableMapIterator > mapIt(m_positionsCont); // // LOOP PER SINGLE POLY // while (mapIt.hasNext()) { mapIt.next(); const int key = mapIt.key(); const SimpleValue &posData = mapIt.value(); const PositionCont &posCont = posData.value(); TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'" << ", key / #ring=" << key << ", rings.size()=" << posCont.size(); // maybe some pathIdx are cleared by clearPath() or similar: if (posCont.isEmpty()) { DEBUG_LOG(m_logger) << LOGFUNCTION << " posCont empty, cleared? -> remove/cleanup" << " pathIdxToInsert = " << pathIdxToInsert << " mapIt.key() = " << key; mapIt.remove(); continue; } if (posCont.count() < minPoints) { ERROR_LOG(m_logger) << LOGFUNCTION << " incorrect number of positions" << " (" << posCont.count() << ")" << ", minPoints=" << minPoints << ", pathIdxToInsert = " << pathIdxToInsert << ", mapIt.key() = " << key << ", m_debugInfo = " << m_debugInfo; success = false; } else { Esri::ArcGISRuntime::Part part(builder->spatialReference()); // // LOOP PER POINT // for (auto pos : qAsConst(posCont)) { part.addPoint(pos.x(), pos.y(), pos.z()); TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'" << ", key / #ring=" << key << ", addPoint=" << pos; } partCollection->addPart(&part); } // if (posCont.count() < minPoints) } // while builder->setParts(partCollection.get()); // // builder to geometry; // switch (m_pathType) { case GraphicalObjectPathType::Polyline: { const Esri::ArcGISRuntime::Polyline &multipartPolyline = static_cast(builder.data())->toPolyline(); m_graphic->setGeometry(multipartPolyline); assignLineStyleToGraphic(); } break; case GraphicalObjectPathType::Polygon: { const Esri::ArcGISRuntime::Polygon &multipartPolygon = static_cast(builder.data())->toPolygon(); m_graphic->setGeometry(multipartPolygon); //assignLineStyleToGraphic(); assignFillStyleToGraphic(); } break; } // switch DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'"; success = addUpdateGraphic(); TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'" << " success = " << success << " drawOrder = " << m_graphic->zIndex(); return success; } bool GraphicalObjectMultiPath::hasPosCont(int idx) const { return m_positionsCont.contains(idx); } SimpleValue &GraphicalObjectMultiPath::getPosCont(int idx) { return m_positionsCont[idx]; } const SimpleValue GraphicalObjectMultiPath::getPosCont(int idx) const { return m_positionsCont[idx]; } } // namespace SituationMap