/** * @RDE_HEADER@ * GraphicalObjectPath * $Id$ * $HeadURL$ * $Author$ */ // Own #include "graphical_object_path.h" #include // operator<< // ESRI #include #include #include #include #include #include #include // Qt namespace SituationMap { QLatin1String toString(const GraphicalObjectPathType subType) { switch (subType) { case GraphicalObjectPathType::Polyline: return QLatin1String("Polyline"); break; case GraphicalObjectPathType::Polygon: return QLatin1String("Polygon"); break; } // switch return QLatin1String("GraphicalObjectPathTypeERROR"); } GraphicalObjectPath::GraphicalObjectPath(const GraphicalObjectPathType type , const Esri::ArcGISRuntime::GeoView *geoView , Esri::ArcGISRuntime::GraphicsOverlay *graphicsLayer , const QString &debugInfo , const UniqueMapId &uniqueMapId) : BaseClass(geoView, graphicsLayer, debugInfo, uniqueMapId) , m_pathType(type) , m_logger(getLogger("GraphicalObjectPath")) { 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; } GraphicalObjectPath::~GraphicalObjectPath() { 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; } bool GraphicalObjectPath::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 << "'" << " success = " << success // << " drawOrder = " << m_graphic->drawOrder() ; return success; } bool GraphicalObjectPath::updateViewImpl() { TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'" << " m_positions= " << m_positions.value() << ", m_maxSegmentLength=" << m_maxSegmentLength; QSharedPointer builder; // some checks: switch (m_pathType) { case GraphicalObjectPathType::Polyline: if (!this->isMultiPoint()) { ERROR_LOG(m_logger) << LOGFUNCTION << " incorrect number of positions" << " (" << this->positions().count() << ")"; return false; } builder = QSharedPointer(new Esri::ArcGISRuntime::PolylineBuilder(spatialReference())); break; case GraphicalObjectPathType::Polygon: if (!this->isArea()) { ERROR_LOG(m_logger) << LOGFUNCTION << " incorrect number of positions" << " (" << this->positions().count() << ")"; return false; } builder = QSharedPointer(new Esri::ArcGISRuntime::PolygonBuilder(spatialReference())); break; } // switch if (! builder) { ERROR_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'" << " no builder"; return false; } 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; } // real work: DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'" << " update geometry"; const PositionCont &posCont = m_positions.value(); for (const Point3D &pos : posCont) builder->addPoint(pos.x(), pos.y(), pos.z()); if (! builder->isSketchValid()) { ERROR_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'" << " builder -> sketch invalid"; return false; } // // apply attributes: // // N. Thoden, 13.02.2018 // Case #02062713 [BOS] BasicSceneView_lineNotComplete // If a line has a line of ~10km (Borderline) // the line may 'move' on the ground (3D, RenderMode::Dynamic, SurfarcePlacement::Draped) // To avoid these kind of effect, the advice is to densify the geometry // [similar: Case #02054233 [BOS] LineArtefacts in 3D -> // BUG-000111565 : Lines created on the GraphicsOverlay with "Dynamic" Rendering mode on 3D doesn't render completely when zooming in] // // N. Thoden, 29.03.2018 // Consulting with Luke Smallwood / using the V100.2.1. debug libs: // densify leads to an assert, so avoid densify // (until now densify does not lead to an improvement..) // // N. Thoden, 19.04.2021 // [GUEZE-495]: 3D Lagedarstellung Trefferlinien // Linie fehlt teilweise // jetzt (typeweise) per m_maxSegmentLength aktivierbar switch (m_pathType) { case GraphicalObjectPathType::Polyline: { const Esri::ArcGISRuntime::Polyline &polyline = static_cast(builder.data())->toPolyline(); if (m_maxSegmentLength > 0) { m_graphic->setGeometry(Esri::ArcGISRuntime::GeometryEngine::densifyGeodetic(polyline, m_maxSegmentLength, Esri::ArcGISRuntime::LinearUnit::meters(), Esri::ArcGISRuntime::GeodeticCurveType::Geodesic)); } else { m_graphic->setGeometry(polyline); } // if (densify) assignLineStyleToGraphic(); } break; case GraphicalObjectPathType::Polygon: { const Esri::ArcGISRuntime::Polygon &polygon = static_cast(builder.data())->toPolygon(); if (m_maxSegmentLength > 0) { m_graphic->setGeometry(Esri::ArcGISRuntime::GeometryEngine::densifyGeodetic(polygon, m_maxSegmentLength, Esri::ArcGISRuntime::LinearUnit::meters(), Esri::ArcGISRuntime::GeodeticCurveType::Geodesic)); } else { m_graphic->setGeometry(polygon); } assignFillStyleToGraphic(); } break; } // switch const int count = AbstractGraphicalObject::countOfPolygonFirstPart(m_graphic->geometry()); if (count > 1000) WARNING_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'" << ", huge amount of vertices, countOfPolygonFirstPart = " << count; else DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'" << ", amount of vertices, countOfPolygonFirstPart = " << count; success = addUpdateGraphic(); TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'" << " success = " << success << " drawOrder = " << m_graphic->zIndex(); return success; } double GraphicalObjectPath::maxSegmentLength() const { return m_maxSegmentLength; } void GraphicalObjectPath::setMaxSegmentLength(double maxSegmentLength) { m_maxSegmentLength = maxSegmentLength; } //----------------------------------------------------------------------------- // output operator: //----------------------------------------------------------------------------- std::ostream &operator<<(std::ostream &stream, const GraphicalObjectPathType &value) { stream << toString(value).latin1(); return stream; } } // namespace SituationMap