/** * @RDE_HEADER@ * GraphicalObjectEllipse * $Id$ * $HeadURL$ * $Author$ */ // Own #include "graphical_object_ellipse.h" #include // operator<< // ESRI #include #include #include #include #include // Qt #include namespace SituationMap { GraphicalObjectEllipse::GraphicalObjectEllipse(const Esri::ArcGISRuntime::GeoView *geoView , Esri::ArcGISRuntime::GraphicsOverlay *graphicsLayer , const QString &debugInfo , const UniqueMapId &uniqueMapId) : BaseClass(geoView, graphicsLayer, debugInfo, uniqueMapId) , m_logger(getLogger("GraphicalObjectEllipse")) { TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'"; TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'"; } GraphicalObjectEllipse::~GraphicalObjectEllipse() { TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'"; delete m_internalParameters; TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'"; } bool GraphicalObjectEllipse::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; } // real work: // empty TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'" // << " drawOrder = " << m_graphic->drawOrder() << " success = " << success; return success; } bool GraphicalObjectEllipse::updateViewImpl() { TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'"; // some checks: if (!this->isSinglePoint()) { ERROR_LOG(m_logger) << LOGFUNCTION << " incorrect number of positions" << " (" << this->positions().count() << ")"; return false; } if (!create()) { ERROR_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'" << " create failed"; return false; } if (!BaseClass::updateViewImpl()) { ERROR_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'" << " updateView failed"; return false; } if (!m_ellipseParameters.value().isValid()) { ERROR_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'" << " ellipseParameters not valid"; return false; } // real work: DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'" << " update geometry"; bool successEllipse = true; if (m_ellipseParameters.changed() || m_positions.changed()) { // apply attributes: parameterToInternal(); Esri::ArcGISRuntime::Polygon ellipse; successEllipse = createEllipse(ellipse); if (successEllipse) m_graphic->setGeometry(ellipse); else { ERROR_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'" << " createEllipse failed"; return false; } } assignFillStyleToGraphic(); DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'"; bool successGraphic = addUpdateGraphic(); TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'" << " drawOrder = " << m_graphic->zIndex() << " successEllipse = " << successEllipse << " successGraphic = " << successGraphic; return successEllipse && successGraphic; } void GraphicalObjectEllipse::parameterToInternal() { TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'"; if (!m_internalParameters) { m_internalParameters = new Esri::ArcGISRuntime::GeodesicEllipseParameters(); m_internalParameters->setGeometryType(Esri::ArcGISRuntime::GeometryType::Polygon); } // TODO !!??: set xy correct, calc maxSegLength... const EllipseParameters &ellipseParameterRef = m_ellipseParameters.value(); // 1a, 1b m_internalParameters->setMaxSegmentLength(ellipseParameterRef.maxSegmentLength()); m_internalParameters->setMaxPointCount(ellipseParameterRef.maxPointCount()); // 2 const Point3D &origin = this->origin(); Esri::ArcGISRuntime::Point mapPoint(origin.x(), origin.y(), origin.z(), spatialReference()); // center of ellipse Esri::ArcGISRuntime::Point normalizedPt = Esri::ArcGISRuntime::GeometryEngine::normalizeCentralMeridian(mapPoint); m_internalParameters->setCenter(normalizedPt); // m_internalParameters->setCenter(mapPoint); // 3, 4 m_internalParameters->setSemiAxis1Length(ellipseParameterRef.lengthX()); m_internalParameters->setSemiAxis2Length(ellipseParameterRef.lengthY()); // 5 m_internalParameters->setAxisDirection(ellipseParameterRef.directionDegree()); TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'"; } bool GraphicalObjectEllipse::createEllipse(Esri::ArcGISRuntime::Polygon &ellipse) { TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'"; bool success = createEllipsePolygon(*m_internalParameters, ellipse); TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'" << " success = " << success // << " pointCount = " << ellipse.pointCount() << " dimension = " << ellipse.dimension(); return success; } bool GraphicalObjectEllipse::createEllipsePolygon(const Esri::ArcGISRuntime::GeodesicEllipseParameters &ellipseParameters, Esri::ArcGISRuntime::Polygon &polygon) { LOGGER_T m_logger = getLogger("GraphicalObjectEllipse"); TRACE_LOG(m_logger) << LOGFUNCTION << " START"; QElapsedTimer timer; if (m_logger.isInfoEnabled()) timer.start(); bool success = false; Esri::ArcGISRuntime::Geometry ellipseGeometry = Esri::ArcGISRuntime::GeometryEngine::ellipseGeodesic(ellipseParameters); if (ellipseGeometry.isEmpty()) { ERROR_LOG(m_logger) << LOGFUNCTION << " There was an error computing the geodesic ellipse. Try a different segment length."; } else { polygon = Esri::ArcGISRuntime::Polygon(ellipseGeometry); success = true; } int count = AbstractGraphicalObject::countOfPolygonFirstPart(polygon); DEBUG_LOG(m_logger) << LOGFUNCTION << " count=" << count << " (semiAxis1Length=" << ellipseParameters.semiAxis1Length() << " , semiAxis2Length=" << ellipseParameters.semiAxis2Length() << " , maxPointCount=" << ellipseParameters.maxPointCount() << " , maxSegmentLength=" << ellipseParameters.maxSegmentLength() << " , dimension = " << polygon.dimension() << ")"; if (m_logger.isDebugEnabled()) { DEBUG_LOG(m_logger) << LOGFUNCTION << " took " << timer.elapsed() << "ms" << " (semiAxis1Length=" << ellipseParameters.semiAxis1Length() << " , semiAxis2Length=" << ellipseParameters.semiAxis2Length() << " , maxPointCount=" << ellipseParameters.maxPointCount() << " , maxSegmentLength=" << ellipseParameters.maxSegmentLength() << " , dimension = " << polygon.dimension() << ")"; } TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " success = " << success; return success; } bool GraphicalObjectEllipse::createCirclePolygon(const Esri::ArcGISRuntime::Point &originMap, float radius, unsigned int maxPointCount, Esri::ArcGISRuntime::Polygon &polygon) { LOGGER_T m_logger = getLogger("GraphicalObjectEllipse"); TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " origin=" << originMap.x() << " ; " << originMap.y() << " ; " << originMap.z() << " radius=" << radius; Esri::ArcGISRuntime::GeodesicEllipseParameters ePara; ePara.setGeometryType(Esri::ArcGISRuntime::GeometryType::Polygon); // 1 ePara.setMaxSegmentLength(10); if (maxPointCount == 0) ePara.setMaxPointCount(EllipseParameters::MAX_POINT_COUNT_DEFAULT); else ePara.setMaxPointCount(maxPointCount); // 2 const Esri::ArcGISRuntime::Point &mapPoint = originMap; // center of ellipse Esri::ArcGISRuntime::Point normalizedPt = Esri::ArcGISRuntime::GeometryEngine::normalizeCentralMeridian(mapPoint); ePara.setCenter(normalizedPt); // 3, 4 ePara.setSemiAxis1Length(radius); ePara.setSemiAxis2Length(radius); // 5 ePara.setAxisDirection(0); return createEllipsePolygon(ePara, polygon); } bool GraphicalObjectEllipse::createCirclePolygon(const Esri::ArcGISRuntime::Point &originMap, float radius, unsigned int maxPointCount, PositionCont &posCont) { Esri::ArcGISRuntime::Polygon circle; bool success = GraphicalObjectEllipse::createCirclePolygon(originMap, radius, maxPointCount, circle); if (success && !circle.isEmpty()) { posCont.clear(); const Esri::ArcGISRuntime::ImmutablePart &immutablePart = circle.parts().part(0); const int size = immutablePart.pointCount(); for (int i = 0; i < size; ++i) { const Esri::ArcGISRuntime::Point &p = immutablePart.point(i); posCont.append(Point3D(p.x(), p.y(), p.z())); } } return success; } EllipseParameters GraphicalObjectEllipse::ellipseParameters() const { return m_ellipseParameters.value(); } EllipseParameters &GraphicalObjectEllipse::rEllipseParameters() { return m_ellipseParameters.refValue(); } void GraphicalObjectEllipse::setEllipseParameters(const EllipseParameters &ellipseParameters) { m_ellipseParameters = ellipseParameters; } //----------------------------------------------------------------------------- // output operator: //----------------------------------------------------------------------------- std::ostream &operator<<(std::ostream &stream, const GraphicalObjectEllipse &value) { stream << value.toString(); return stream; } } // namespace SituationMap