/** * @RDE_HEADER@ * PlanModel - Renderer * $Id$ * $HeadURL$ * $Author$ */ #include "geometry_model_renderer_esri.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace SituationMap { GeometryModelRendererEsri::GeometryModelRendererEsri(Map *map, const QString &layerName, GeometryModel &geometryModel, QObject *parent) : GeometryModelRenderer(map, layerName, geometryModel, parent) , m_editorMode(false) , m_delayedRenderTimer(new QTimer(this)) , m_delayedRenderIds() { m_delayedRenderTimer->setInterval(10); m_delayedRenderTimer->setSingleShot(true); connect(m_delayedRenderTimer, &QTimer::timeout, this, &GeometryModelRendererEsri::onDelayedRenderNodes); connect(&geometryModel, &GeometryModel::nodeCleanup , this, &GeometryModelRendererEsri::onCleanupMapObjects); connect(&geometryModel, &GeometryModel::userDataCleanup, this, &GeometryModelRendererEsri::onRemoveMapObject); connect(&geometryModel, &GeometryModel::changed , this, &GeometryModelRendererEsri::onUpdate); } // GeometryModelRendererEsri::GeometryModelRendererEsri bool GeometryModelRendererEsri::editorMode() const { return m_editorMode; } void GeometryModelRendererEsri::setEditorMode(bool on) { m_editorMode = on; } class CleanUpMapObjectsVisitor : public GeometryNodeVisitor { SituationMap::Map *m_map; public: CleanUpMapObjectsVisitor(SituationMap::Map *map, SituationMap::GeometryModel *geoModel) : GeometryNodeVisitor(geoModel), m_map(map) { ; } virtual ~CleanUpMapObjectsVisitor() = default; bool apply(SituationMap::GeometryModel *geoModel, const SituationMap::GeometryModel::Node &node, SituationMap::GeometryModel::PrimitiveType primitiveType) override { switch (primitiveType) { case GeometryModel::PrimitiveType::RootNode: case GeometryModel::PrimitiveType::Node: break; default: { if (geoModel->hasUserData(node)) { bool ok = false; int uid = geoModel->getUserData(node, &ok); if (ok) { SituationMap::AbstractMapObject *mapObj = m_map->objectFactory().idToMapObject(uid); if (mapObj) mapObj->removeMySelf(); } } } break; } return true; } // bool apply(SituationMap::GeometryModel * geoModel, const SituationMap::GeometryModel::Node & node, SituationMap::GeometryModel::PrimitiveType primitiveType ) }; // CleanUpMapObjectsVisitor void GeometryModelRendererEsri::onCleanupMapObjects(const SituationMap::GeometryModel::Node &node) { if (m_map) { GeometryModel::Node p = node; if (!p.isValid()) { p = m_geometryModel.getRootNode(); } CleanUpMapObjectsVisitor visitor(m_map, &m_geometryModel); visitor.traverse(p); } } // GeometryModelRendererEsri::onCleanupMapObjects void GeometryModelRendererEsri::onRemoveMapObject(int uid) { if (m_map) { SituationMap::AbstractMapObject *mapObj = m_map->objectFactory().idToMapObject(uid); // crash see comment in abstract_map_object_impl.cpp 2016/01/08 JT // SituationMap::RefPointer mapObj( m_map->objectFactory().idToMapObject( uid ) ); if (mapObj != nullptr) { mapObj->removeMySelf(); } } } // GeometryModelRendererEsri::onRemoveMapObject void GeometryModelRendererEsri::onUpdate(const SituationMap::GeometryModel::Node &node, SituationMap::GeometryModel::Attribute /*att*/, bool /*coordsChanged*/) { if (m_geometryModel.hasUserData(node)) { SituationMap::AbstractMapObject *mapObj = nullptr; bool ok = false; int uid = m_geometryModel.getUserData(node, &ok); if (ok) mapObj = m_map->objectFactory().idToMapObject(uid); if (mapObj) { // render node later if (!m_delayedRenderIds.contains(uid)) m_delayedRenderIds += uid; m_delayedRenderTimer->start(); return; } } renderNode(node); } // GeometryModelRendererEsri::onUpdate(const SituationMap::GeometryModel::Node & node, SituationMap::GeometryModel::Attribute att, bool coordsChanged) void GeometryModelRendererEsri::onDelayedRenderNodes() { for (auto uid : qAsConst(m_delayedRenderIds)) { SituationMap::AbstractMapObject *mapObj = m_map->objectFactory().idToMapObject(uid); renderNode(getAssociatedNode(mapObj)); } m_delayedRenderIds.clear(); } // GeometryModelRendererEsri::onDelayedRenderNodes() bool GeometryModelRendererEsri::render(QPixmap &drawable) { Q_UNUSED(drawable); return false; } // GeometryModelRendererEsri::render( QPixmap & drawable ) bool GeometryModelRendererEsri::render() { return renderNode(m_geometryModel.getRootNode()); } bool GeometryModelRendererEsri::renderNode(const GeometryModel::Node &node) { bool ok = false; if (!node.isValid()) { const GeometryModel::Node &root = m_geometryModel.getRootNode(); ok = drawNodesRecursive(root); } else ok = drawNodesRecursive(node); return ok; } // GeometryModelRendererEsri::renderNode( Map * map, const GeometryModel::Node & node, const QString & layername ) template uint GeometryModelRendererEsri::setLineStyle(const GeometryModel::Node &p, MapObjectClass *objPtr) const { SituationMap::LineStyle &&objLineStyle = objPtr->lineStyle(); const QColor &lineColor = m_geometryModel.getAttribute(p, GeometryModel::Attribute::Color).value(); uint lineWidth = m_geometryModel.getAttribute(p, GeometryModel::Attribute::LineWidth).toUInt(); GeometryModel::LineStyle lineStyle = GeometryModel::LineStyle((m_geometryModel.getAttribute(p, GeometryModel::Attribute::LineStyle).toInt())); objLineStyle.setLineColor(lineColor); objLineStyle.setLineWidth((lineWidth > 0) ? lineWidth : 1); switch (lineStyle) { case GeometryModel::LineStyle::Dashed : objLineStyle.setLinePattern(LinePattern::Dash); break; case GeometryModel::LineStyle::DashedDotted : objLineStyle.setLinePattern(LinePattern::DashDot); break; case GeometryModel::LineStyle::Dotted : objLineStyle.setLinePattern(LinePattern::Dot); break; case GeometryModel::LineStyle::LineSolid : objLineStyle.setLinePattern(LinePattern::Solid); break; default : objLineStyle.setLinePattern(LinePattern::Solid); break; } objPtr->setLineStyle(objLineStyle); return lineWidth; } // template uint GeometryModelRendererEsri::setLineStyle( const GeometryModel::Node & p, MapObjectClass * objPtr ) const template void GeometryModelRendererEsri::setFillStyle(const GeometryModel::Node &p, MapObjectClass *objPtr) const { SituationMap::FillStyle &&objFillStyle = objPtr->fillStyle(); GeometryModel::FillPattern fillPattern = GeometryModel::FillPattern((m_geometryModel.getAttribute(p, GeometryModel::Attribute::FillPattern).toInt())); const QColor &fillColor = m_geometryModel.getAttribute(p, GeometryModel::Attribute::FillColor).value(); objFillStyle.setFillColor(fillColor); switch (fillPattern) { case GeometryModel::FillPattern::Diag1 : objFillStyle.setFillPattern(FillPattern::BackwardDiagonal); break; case GeometryModel::FillPattern::Diag2 : objFillStyle.setFillPattern(FillPattern::ForwardDiagonal); break; case GeometryModel::FillPattern::Hor1 : objFillStyle.setFillPattern(FillPattern::BackwardDiagonal); break; case GeometryModel::FillPattern::Hor2 : objFillStyle.setFillPattern(FillPattern::Horizontal); break; case GeometryModel::FillPattern::Solid : objFillStyle.setFillPattern(FillPattern::Solid); break; case GeometryModel::FillPattern::Ver1 : case GeometryModel::FillPattern::Ver2 : objFillStyle.setFillPattern(FillPattern::Vertical); break; case GeometryModel::FillPattern::Dots : default : objFillStyle.setFillPattern(FillPattern::Null); break; } objPtr->setFillStyle(objFillStyle); } // template void GeometryModelRendererEsri::setFillStyle( const GeometryModel::Node & p, MapObjectClass * objPtr ) const class RenderMapObjectsVisitor : public GeometryNodeVisitor { GeometryModelRendererEsri *m_gmr; public: RenderMapObjectsVisitor(GeometryModelRendererEsri *gmr, SituationMap::GeometryModel *geoModel) : GeometryNodeVisitor(geoModel), m_gmr(gmr) { ; } virtual ~RenderMapObjectsVisitor() = default; bool apply(SituationMap::GeometryModel *geoModel, const SituationMap::GeometryModel::Node &node, SituationMap::GeometryModel::PrimitiveType primitiveType) override { SituationMap::AbstractMapObject *mapObj = nullptr; if (geoModel->hasUserData(node)) { bool ok = false; int uid = geoModel->getUserData(node, &ok); if (ok) mapObj = m_gmr->m_map->objectFactory().idToMapObject(uid); } switch (primitiveType) { case GeometryModel::PrimitiveType::ParticipantSymbol : m_gmr->drawParticipantSymbol( node, m_gmr->m_layerName, mapObj); break; case GeometryModel::PrimitiveType::DictionarySymbol : m_gmr->drawDictionarySymbol ( node, m_gmr->m_layerName, mapObj); break; case GeometryModel::PrimitiveType::Ellipse : m_gmr->drawEllipse ( node, m_gmr->m_layerName, mapObj); break; case GeometryModel::PrimitiveType::Line : m_gmr->drawLine ( node, m_gmr->m_layerName, mapObj); break; case GeometryModel::PrimitiveType::Polyline : m_gmr->drawPolyline ( node, m_gmr->m_layerName, mapObj); break; case GeometryModel::PrimitiveType::Rectangle : m_gmr->drawRectangle ( node, m_gmr->m_layerName, mapObj); break; case GeometryModel::PrimitiveType::Spline : m_gmr->drawSpline ( node, m_gmr->m_layerName, mapObj); break; case GeometryModel::PrimitiveType::Symbol : m_gmr->drawSymbol ( node, m_gmr->m_layerName, mapObj); break; case GeometryModel::PrimitiveType::Text : m_gmr->drawText ( node, m_gmr->m_layerName, mapObj); break; case GeometryModel::PrimitiveType::RootNode : break; case GeometryModel::PrimitiveType::Node : break; case GeometryModel::PrimitiveType::Unknown : break; default : break; } return true; } // bool apply(SituationMap::GeometryModel * geoModel, const SituationMap::GeometryModel::Node & node, SituationMap::GeometryModel::PrimitiveType primitiveType ) }; // RenderMapObjectsVisitor bool GeometryModelRendererEsri::drawNodesRecursive(const GeometryModel::Node &p) { if (!p.isValid()) return false; TRACE_LOG(m_logger) << LOGFUNCTION << " START"; ++m_stats.m_drawElementsRecursiveCount; RenderMapObjectsVisitor visitor(this, &m_geometryModel); visitor.traverse(p); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; return true; } // void GeometryModelRendererEsri::drawNodesRecursive UniqueMapId GeometryModelRendererEsri::getIdFromNode(const GeometryModel::Node &node) const { SituationMap::UniqueMapId mapId = SituationMap::INVALID_MAP_ID; if (m_geometryModel.hasUserData(node)) { bool ok; int userData = m_geometryModel.getUserData(node, &ok); if (!ok) DEBUG_LOG(m_logger) << LOGFUNCTION << " getUserData failed"; else mapId = userData; } return mapId; } // UniqueMapId GeometryModelRendererEsri::getIdFromNode() const GeometryModel::Node GeometryModelRendererEsri::getAssociatedNode(const AbstractMapObject *mapObject) { if (mapObject == nullptr) return GeometryModel::Node(); SituationMap::UniqueMapId mapId = mapObject->uniqueMapId(); if (mapId == SituationMap::INVALID_MAP_ID) return GeometryModel::Node(); return m_geometryModel.findPrimitive(mapId); } // getAssociatedNode( const AbstractMapObject * mapObject ) bool GeometryModelRendererEsri::getNodesPickable() const { return m_nodesPickable; } void GeometryModelRendererEsri::setNodesPickable(bool nodesPickable) { m_nodesPickable = nodesPickable; } void GeometryModelRendererEsri::drawParticipantSymbol(const GeometryModel::Node &p, const QString &layer, SituationMap::AbstractMapObject *mapObj) { QList points = m_geometryModel.getPrimitivePoints(p); SituationMap::UniqueMapId mapId = getIdFromNode(p); if (points.size() == 0) { DEBUG_LOG(m_logger) << LOGFUNCTION << "Primitive Dictionary Symbol don't have any coordinates!" << " (" << mapId << ")"; return; } bool ok; const QString & sidc = m_geometryModel.getAttribute(p, GeometryModel::Attribute::SIDC).toString(); const QString & sidcAttributes = m_geometryModel.getAttribute(p, GeometryModel::Attribute::SIDC_Attributes).toString(); int symbolForceId = m_geometryModel.getAttribute(p, GeometryModel::Attribute::ForceId).toInt(&ok); if (!ok) symbolForceId = -1; int symbolInjuryId = m_geometryModel.getAttribute(p, GeometryModel::Attribute::DamageForceId).toInt(&ok); if (!ok) symbolInjuryId = -1; int symbolInjury = m_geometryModel.getAttribute(p, GeometryModel::Attribute::Injury).toInt(&ok); if (!ok) symbolInjury = static_cast(AdvancedSymbology::Injury::NoInjury); const QVector &partyIds = m_map->partyIdToColorFunctor().partyIds(); if (!partyIds.contains(symbolForceId)) symbolForceId = -1; if (!partyIds.contains(symbolInjuryId)) symbolInjuryId = -1; SituationMap::ObjectFactory & objFac = m_map->objectFactory(); SituationMap::Participant * objPtr = dynamic_cast(mapObj); if (objPtr == nullptr) { if (mapObj) mapObj -> removeMySelf(); objPtr = objFac.create (layer, QStringLiteral("Plan-ParticipantSymbol:sidc=%1").arg(sidc)).get(); if (objPtr == nullptr) { ERROR_LOG(m_logger) << LOGFUNCTION << " objFac.create failed"; return; } } ++m_stats.m_drawDictionarySymbolCount; m_stats.m_timer.restart(); SituationMap::SymbolData symbolData; symbolData.sidc = sidc; objPtr->setVisibility(true); objPtr->setPickable(m_nodesPickable); objPtr->setOrigin(SituationMap::Point3D::fromQPointF(points.first())); objPtr->setSymbol(symbolData); objPtr->setPartyId(symbolForceId); objPtr->setInjury(static_cast(symbolInjury), symbolInjuryId ); objPtr->setTextModifier( SituationMap::Participant::TextModifier::W_DateTimeGroup , m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_W).toString()); objPtr->setTextModifier( SituationMap::Participant::TextModifier::T_UniqueDesignation , m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_T).toString()); objPtr->setTextModifier( SituationMap::Participant::TextModifier::M_HigherFormation , m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_M).toString()); objPtr->setTextModifier( SituationMap::Participant::TextModifier::EF_ReinforcedReduced , m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_EF).toString()); objPtr->setTextModifier( SituationMap::Participant::TextModifier::XY_AltitudeLocation , m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_XY).toString()); objPtr->setTextModifier( SituationMap::Participant::TextModifier::V_Type , m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_V).toString()); objPtr->setTextModifier( SituationMap::Participant::TextModifier::Z_Speed , m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_Z).toString()); objPtr->setTextModifier( SituationMap::Participant::TextModifier::G_StaffComments , m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_G).toString()); objPtr->setTextModifier( SituationMap::Participant::TextModifier::H_AdditionalInformation , m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_H).toString()); objPtr->setTextModifier( SituationMap::Participant::TextModifier::JKLNP , m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_KLNPJ).toString()); QMap attrMap; m_geometryModel.parseSymbolAttributeString(sidcAttributes, attrMap); const auto tm = Participant::textModifiers(); for (auto textModifier : tm) objPtr->setTextModifierVisibility(textModifier, true); bool success = objPtr->updateView(); if (!success) ERROR_LOG(m_logger) << LOGFUNCTION << " failed"; DEBUG_LOG(m_logger) << LOGFUNCTION << " uniqueMapId=" << objPtr->uniqueMapId(); // Store id in primitive m_geometryModel.setUserData(p, objPtr->uniqueMapId()); int ms = m_stats.m_timer.elapsed(); m_stats.m_msDictionarySymbol += ms; m_stats.m_msDictionarySymbolMin = std::min(ms, m_stats.m_msDictionarySymbolMin); m_stats.m_msDictionarySymbolMax = std::max(ms, m_stats.m_msDictionarySymbolMax); } // void GeometryModelRendererEsri::drawParticipantSymbol(const GeometryModel::Node &p, const QString &layer, SituationMap::AbstractMapObject *mapObj) void GeometryModelRendererEsri::drawDictionarySymbol(const GeometryModel::Node &p, const QString &layer, SituationMap::AbstractMapObject *mapObj) { QList points = m_geometryModel.getPrimitivePoints(p); SituationMap::UniqueMapId mapId = getIdFromNode(p); if (points.size() == 0) { DEBUG_LOG(m_logger) << LOGFUNCTION << "Primitive Dictionary Symbol don't have any coordinates!" << " (" << mapId << ")"; return; } const QString & sidc = m_geometryModel.getAttribute(p, GeometryModel::Attribute::SIDC).toString(); const QString & sidcAttributes = m_geometryModel.getAttribute(p, GeometryModel::Attribute::SIDC_Attributes).toString(); SituationMap::ObjectFactory & objFac = m_map->objectFactory(); SituationMap::SidcSymbol * objPtr = dynamic_cast(mapObj); if (objPtr == nullptr) { if (mapObj) mapObj -> removeMySelf(); objPtr = objFac.create (layer, QStringLiteral("Plan-TacticalSymbol:sidc=%1").arg(sidc)).get(); if (objPtr == nullptr) { ERROR_LOG(m_logger) << LOGFUNCTION << " objFac.create failed"; return; } } ++m_stats.m_drawDictionarySymbolCount; m_stats.m_timer.restart(); DEBUG_LOG(m_logger) << LOGFUNCTION << "TacticalAppearanceAttrList: " << sidcAttributes; QMap attrMap; m_geometryModel.parseSymbolAttributeString(sidcAttributes, attrMap); objPtr->setVisibility(true); objPtr->setPickable(m_nodesPickable); objPtr->defineSymbol(sidc, SituationMap::convert2D3D(points), attrMap ); bool success = objPtr->updateView(); if (!success) ERROR_LOG(m_logger) << LOGFUNCTION << " failed"; DEBUG_LOG(m_logger) << LOGFUNCTION << " uniqueMapId=" << objPtr->uniqueMapId(); // Store id in primitive m_geometryModel.setUserData(p, objPtr->uniqueMapId()); int ms = m_stats.m_timer.elapsed(); m_stats.m_msDictionarySymbol += ms; m_stats.m_msDictionarySymbolMin = std::min(ms, m_stats.m_msDictionarySymbolMin); m_stats.m_msDictionarySymbolMax = std::max(ms, m_stats.m_msDictionarySymbolMax); } // GeometryModelRendererEsri::drawDictionarySymbol void GeometryModelRendererEsri::drawEllipse(const GeometryModel::Node &p, const QString &layer, SituationMap::AbstractMapObject *mapObj) { SituationMap::CoordTranslationFunctor *ctf = m_map->coordTranslationFunctor(); if (nullptr == ctf) { DEBUG_LOG(m_logger) << LOGFUNCTION << "Map don't have defined any map projection! Can't render ellipse ..."; return; } QList points = m_geometryModel.getPrimitivePoints(p); if (points.size() != 4) { DEBUG_LOG(m_logger) << LOGFUNCTION << "Primitive Ellipse has wrong count of geo coordinates!"; return; } ++m_stats.m_drawEllipseCount; m_stats.m_timer.restart(); double radiusX = m_geometryModel.getAttribute(p, GeometryModel::Attribute::Width).toDouble() * 0.5; double radiusY = m_geometryModel.getAttribute(p, GeometryModel::Attribute::Height).toDouble() * 0.5; double phi = m_geometryModel.getAttribute(p, GeometryModel::Attribute::Rotate).toDouble() * (M_PI / 180.0); double start = m_geometryModel.getAttribute(p, GeometryModel::Attribute::Start).toDouble(); double extent = m_geometryModel.getAttribute(p, GeometryModel::Attribute::Extent).toDouble(); bool fullCircle = (fabs(extent) > 359.5); if (fullCircle) { start = 0.0; extent = 360.0; } start *= (M_PI / 180.0); extent *= (M_PI / 180.0); QPointF centerPoint(points.first()); for (int i = 1; i < 4; ++i) centerPoint += points.at(i); centerPoint /= 4; centerPoint = ctf->geographicToMap(centerPoint); points.clear(); qreal referenceLon = 9999; if (ctf->mapIsGeographic()) { referenceLon = centerPoint.x(); points << centerPoint; ctf->geographicToUtm( referenceLon, points); centerPoint = points.first(); points.clear(); } SituationMap::MathUtils::Ellipse ellipseCurve(centerPoint, radiusX, radiusY, phi, start, start + extent); std::unique_ptr pathRasterer(ellipseCurve.createPathRaster()); pathRasterer->epsilon(0.25 * m_map->pixelSizeMeter()); pathRasterer->maxVertexCount(1000); pathRasterer->rasterize(ellipseCurve.minimumCurveParameter(), ellipseCurve.maximumCurveParameter(), points); if (!fullCircle) { GeometryModel::FillStyle fillStyle = (GeometryModel::FillStyle)(m_geometryModel.getAttribute(p, GeometryModel::Attribute::FillStyle).toInt()); switch (fillStyle) { case GeometryModel::FillStyle::Pieslice: points.append(centerPoint); break; case GeometryModel::FillStyle::Chord: break; case GeometryModel::FillStyle::Open: break; } } if (ctf->mapIsGeographic()) { ctf->utmToGeographic(referenceLon, points); } drawPolyline(p, layer, points, mapObj, false); int ms = m_stats.m_timer.elapsed(); m_stats.m_msEllipse += ms; m_stats.m_msEllipseMin = std::min(ms, m_stats.m_msEllipseMin); m_stats.m_msEllipseMax = std::max(ms, m_stats.m_msEllipseMax); } // void GeometryModelRendererEsri::drawEllipse void GeometryModelRendererEsri::drawLine(const GeometryModel::Node &p, const QString &layer, SituationMap::AbstractMapObject *mapObj) { ++m_stats.m_drawLineCount; m_stats.m_timer.restart(); drawPolyline(p, layer, mapObj); int ms = m_stats.m_timer.elapsed(); m_stats.m_msLine += ms; m_stats.m_msLineMin = std::min(ms, m_stats.m_msLineMin); m_stats.m_msLineMax = std::max(ms, m_stats.m_msLineMax); } // void GeometryModelRendererEsri::drawLine void GeometryModelRendererEsri::drawPolyline(const GeometryModel::Node &p, const QString &layer, SituationMap::AbstractMapObject *mapObj) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; ++m_stats.m_drawPolylineCount; m_stats.m_timer.restart(); drawPolyline(p, layer, m_geometryModel.getPrimitivePoints(p), mapObj); int ms = m_stats.m_timer.elapsed(); m_stats.m_msPolyline += ms; m_stats.m_msPolylineMin = std::min(ms, m_stats.m_msPolylineMin); m_stats.m_msPolylineMax = std::max(ms, m_stats.m_msPolylineMax); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } /* GeometryModelRendererEsri::drawPolyline */ void GeometryModelRendererEsri::drawPolyline( const GeometryModel::Node & p , const QString & layer , const QList & points , SituationMap::AbstractMapObject * mapObj , bool geoCoordinates ) { bool isRectangle = (m_geometryModel.getType(p) == GeometryModel::PrimitiveType::Rectangle); bool isEllipse = (m_geometryModel.getType(p) == GeometryModel::PrimitiveType::Ellipse); bool isFilled = (points.size() > 2) && m_geometryModel.getAttribute(p, GeometryModel::Attribute::Fill).toBool(); bool isClosed = ((isEllipse) || (isRectangle) || ((points.size() > 2) && m_geometryModel.getAttribute(p, GeometryModel::Attribute::Close).toBool())); if ((points.size() > 2) || (isRectangle) || (isEllipse)) { GeometryModel::FillPattern fillPattern = GeometryModel::FillPattern((m_geometryModel.getAttribute(p, GeometryModel::Attribute::FillPattern).toInt())); if (isEllipse) { double extent = m_geometryModel.getAttribute(p, GeometryModel::Attribute::Extent).toDouble(); if (fabs(extent) <= 359.5) { GeometryModel::FillStyle fillStyle = GeometryModel::FillStyle((m_geometryModel.getAttribute(p, GeometryModel::Attribute::FillStyle).toInt())); switch (fillStyle) { case GeometryModel::FillStyle::Chord : isClosed = true; break; case GeometryModel::FillStyle::Pieslice : isClosed = true; break; case GeometryModel::FillStyle::Open : isClosed = false; break; } } else isClosed = true; } if (fillPattern == GeometryModel::FillPattern::None) isFilled = false; } SituationMap::RefPointer objPtr(mapObj); SituationMap::ObjectFactory &objFac = m_map->objectFactory(); bool createMapObj = false; bool selectMapObj = false; SituationMap::UniqueMapId removedUidMapObj = SituationMap::INVALID_MAP_ID; if (mapObj) { objPtr = (SituationMap::AbstractMultiPointMapObject *) dynamic_cast(mapObj); if (objPtr.valid()) { if (isClosed) { createMapObj = true; selectMapObj = objPtr->selected(); removedUidMapObj = objPtr->uniqueMapId(); objPtr->removeMySelf(); objPtr = nullptr; } } else { objPtr = (SituationMap::AbstractMultiPointMapObject *) dynamic_cast(mapObj); if (objPtr.valid()) { if (!isClosed) { createMapObj = true; selectMapObj = objPtr->selected(); removedUidMapObj = objPtr->uniqueMapId(); objPtr->removeMySelf(); objPtr = nullptr; } } else { createMapObj = true; selectMapObj = objPtr->selected(); removedUidMapObj = objPtr->uniqueMapId(); mapObj->removeMySelf(); } } } else createMapObj = true; if (createMapObj) { // re use the uid if the map object was removed before ... if (isClosed) objPtr = (SituationMap::AbstractMultiPointMapObject *) objFac.create ( removedUidMapObj, layer, QLatin1String("PlanElement")).get(); else objPtr = (SituationMap::AbstractMultiPointMapObject *) objFac.create( removedUidMapObj, layer, QLatin1String("PlanElement")).get(); if (!objPtr.valid()) { ERROR_LOG(m_logger) << LOGFUNCTION << " SituationMap::ObjectFactory.create() failed"; return; } objPtr->setSelected(selectMapObj); objPtr->setScaleEnable(false); // disable scaling (setScale, most of the time done by user) } objPtr->setPickable(m_nodesPickable); uint lineWidth = setLineStyle(p, objPtr.get()); Q_UNUSED(lineWidth); if (!isFilled) { SituationMap::FillStyle &&objFillStyle = objPtr->fillStyle(); objFillStyle.setFillPattern(SituationMap::FillPattern::Null); objPtr->setFillStyle(objFillStyle); } else setFillStyle(p, objPtr.get()); if ((!isClosed) && (!isEllipse)) { SituationMap::Polyline *lineObj = dynamic_cast(objPtr.get()); if (lineObj) { // adding arrows if defined lineObj -> setArrowHeadStart(false); lineObj -> setArrowHeadEnd(false); GeometryModel::Arrows arrows = (GeometryModel::Arrows) m_geometryModel.getAttribute(p, GeometryModel::Attribute::Arrows).toInt(); switch (arrows) { case GeometryModel::Arrows::Both : lineObj -> setArrowHeadEnd(true); Q_FALLTHROUGH(); case GeometryModel::Arrows::Start : lineObj -> setArrowHeadStart(true); break; case GeometryModel::Arrows::End : lineObj -> setArrowHeadEnd(true); break; case GeometryModel::Arrows::NoArrows : default : arrows = GeometryModel::Arrows::NoArrows; break; } if (arrows != GeometryModel::Arrows::NoArrows) { #ifdef NEVER double scale = (lineWidth < 2) ? 1.0 : double(lineWidth) * 0.5; double arrowWidth = scale * (m_geometryModel.getAttribute(p, GeometryModel::Attribute::ArrowWidth).toDouble()); double arrowHeight = scale * (m_geometryModel.getAttribute(p, GeometryModel::Attribute::ArrowHeight).toDouble()); double arrowClampHeight = scale * (m_geometryModel.getAttribute(p, GeometryModel::Attribute::ArrowClampHeight).toDouble()); Q_UNUSED(arrowWidth); Q_UNUSED(arrowHeight); Q_UNUSED(arrowClampHeight); #endif } } } (geoCoordinates) ? objPtr->setPositions(SituationMap::convert2D3D(points)) : objPtr->setPositionsTranslated(SituationMap::convert2D3D(points)); bool success = objPtr->updateView(); if (!success) ERROR_LOG(m_logger) << LOGFUNCTION << " failed"; DEBUG_LOG(m_logger) << LOGFUNCTION << " uniqueMapId=" << objPtr->uniqueMapId(); // Store id in primitive m_geometryModel.setUserData(p, objPtr->uniqueMapId()); } // void GeometryModelRendererEsri::drawPolyline void GeometryModelRendererEsri::drawRectangle(const GeometryModel::Node &p, const QString &layer, SituationMap::AbstractMapObject *mapObj) { QList points = m_geometryModel.getPrimitivePoints(p); if (points.size() != 4) { DEBUG_LOG(m_logger) << LOGFUNCTION << "Primitive Rectangle has wrong count of points!"; return; } ++m_stats.m_drawRectangleCount; m_stats.m_timer.restart(); GeometryModelRendererEsri::drawPolyline(p, layer, points, mapObj); int ms = m_stats.m_timer.elapsed(); m_stats.m_msRectangle += ms; m_stats.m_msRectangleMin = std::min(ms, m_stats.m_msRectangleMin); m_stats.m_msRectangleMax = std::max(ms, m_stats.m_msRectangleMax); } // void GeometryModelRendererEsri::drawRectangle void GeometryModelRendererEsri::drawSpline(const GeometryModel::Node &p, const QString &layer, SituationMap::AbstractMapObject *mapObj) { SituationMap::CoordTranslationFunctor *ctf = m_map->coordTranslationFunctor(); if (nullptr == ctf) { ERROR_LOG(m_logger) << LOGFUNCTION << "Map doesn't have defined any map projection! Can't render spline ..."; #if LTS_DEBUG abort(); #else return; #endif // LTS_DEBUG } ++m_stats.m_drawSplineCount; m_stats.m_timer.restart(); SituationMap::MathUtils::SmoothLine splineCurve; std::unique_ptr pathRasterer(splineCurve.createPathRaster()); bool isClosed(m_geometryModel.getAttribute(p, GeometryModel::Attribute::Close).toBool()); const auto & pointsMap = m_geometryModel.getPrimitivePoints(p); if (pointsMap.size() < 2) { DEBUG_LOG(m_logger) << LOGFUNCTION << "Too little count of occordiantes. Can't render spline ..."; return; } QList points; points.reserve(pointsMap.size()); for (int i = 0; i < pointsMap.size(); ++i) { points.push_back(ctf->geographicToMap(pointsMap.at(i))); } qreal referenceLon = 9999; if (ctf->mapIsGeographic()) { // In case of geographic coordinate system do rasterization in UTM coordinate system to avoid // trouble with termination threshold. referenceLon = points.first().x(); ctf->geographicToUtm( referenceLon, points ); } splineCurve.vertexVector(points.toVector(), isClosed); pathRasterer -> epsilon(0.25 * m_map->pixelSizeMeter()); pathRasterer -> maxVertexCount(1000); QList rasterizedPoints; pathRasterer -> rasterize(splineCurve.minimumCurveParameter(), splineCurve.maximumCurveParameter(), rasterizedPoints); if (ctf->mapIsGeographic()) ctf->utmToGeographic( referenceLon, rasterizedPoints ); if (rasterizedPoints.size() <= 2) { NOTICE_LOG(m_logger) << LOGFUNCTION << "< pointsMap.size() " << pointsMap.size() << "< points.size() " << points.size() << "< splineCurve.minimumCurveParameter() " << splineCurve.minimumCurveParameter() << "< splineCurve.maximumCurveParameter() " << splineCurve.maximumCurveParameter() << "< rasterizedPoints.size() === " << rasterizedPoints.size() << "< m_map->pixelSizeMeter()=" << m_map->pixelSizeMeter(); } drawPolyline(p, layer, rasterizedPoints, mapObj, false); int ms = m_stats.m_timer.elapsed(); m_stats.m_msSpline += ms; m_stats.m_msSplineMin = std::min(ms, m_stats.m_msSplineMin); m_stats.m_msSplineMax = std::max(ms, m_stats.m_msSplineMax); } // void GeometryModelRendererEsri::drawSpline void GeometryModelRendererEsri::drawSymbol(const GeometryModel::Node &p, const QString &layer, SituationMap::AbstractMapObject *mapObj) { if (nullptr == m_map->coordTranslationFunctor()) { ERROR_LOG(m_logger) << LOGFUNCTION << "Map doesn't have defined any map projection! Can't render symbol ..."; return; } const QVector &partyIds = m_map->partyIdToColorFunctor().partyIds(); if (partyIds.size() < 1) { ERROR_LOG(m_logger) << LOGFUNCTION << " Party colors are not defined. Can't render symbol ..."; return; } ++m_stats.m_drawSymbolCount; const auto & pointsMap = m_geometryModel.getPrimitivePoints(p); if (pointsMap.size() == 0) { ERROR_LOG(m_logger) << LOGFUNCTION << " Primitive Symbol has no points!"; return; } const QPointF & point = pointsMap.at(0); SituationMap::RefPointer objPtr; SituationMap::ObjectFactory &objFac = m_map->objectFactory(); bool createMapObj = false; if (mapObj) { objPtr = (SituationMap::Participant *) dynamic_cast(mapObj); if (!objPtr.valid()) { createMapObj = true; mapObj->removeMySelf(); } } else createMapObj = true; if (createMapObj) { objPtr = (SituationMap::Participant *) objFac.create (layer, QLatin1String("PlanElement")).get(); if (!objPtr.valid()) { ERROR_LOG(m_logger) << LOGFUNCTION << " SituationMap::ObjectFactory.create() failed"; return; } objPtr->setScaleEnable(false); // disable scaling (setScale, most of the time done by user) } bool ok; SituationMap::GeometryModel::t_vbg_et vbg = SituationMap::GeometryModel::t_vbg_et(m_geometryModel.getAttribute(p,SituationMap::GeometryModel::Attribute::att_vbg_et).toInt()); SymbologyXML::SymbolTypes::t_state state = SymbologyXML::SymbolTypes::t_state( m_geometryModel.getAttribute(p,SituationMap::GeometryModel::Attribute::SymbolState).toInt() ); SymbologyXML::SymbolTypes::t_uncertainty uncertainty = SymbologyXML::SymbolTypes::t_uncertainty( m_geometryModel.getAttribute(p,SituationMap::GeometryModel::Attribute::SymbolUncertainty).toInt() ); SymbologyXML::SymbolTypes::t_affil affil = SymbologyXML::SymbolTypes::t_affil(m_geometryModel.getAttribute(p,SituationMap::GeometryModel::Attribute::Affiliation).toInt()); SymbologyXML::SymbolTypes::t_mob mob = SymbologyXML::SymbolTypes::t_mob(m_geometryModel.getAttribute(p,SituationMap::GeometryModel::Attribute::Mobility).toInt()); // bool abcProtect = m_geometryModel.getAttribute(p,SituationMap::GeometryModel::Attribute::AbcProtection).toBool(); SymbolData symData; int symbolID = m_geometryModel.getAttribute(p, GeometryModel::Attribute::SymbolId).toInt(); if (symbolID < 0) { ERROR_LOG(m_logger) << LOGFUNCTION << "Primitive Symbol has undefinded symbol!"; return; } symData.sidc = AdvancedSymbology::SidcCodec::encodeCivilXmlSymbolId(uint(symbolID),state,uncertainty,affil,mob); /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int symbolOffsetX = m_geometryModel.getAttribute(p,SituationMap::GeometryModel::Attribute::SymbolOffsetX).toInt(&ok); if (!ok) symbolOffsetX = 0; int symbolOffsetY = m_geometryModel.getAttribute(p,SituationMap::GeometryModel::Attribute::SymbolOffsetY).toInt(&ok); if (!ok) symbolOffsetY = 0; int symbolDirection = m_geometryModel.getAttribute(p,SituationMap::GeometryModel::Attribute::SymbolDirection).toInt(&ok); if (!ok) symbolDirection = 0; * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ float symbolScale = m_geometryModel.getAttribute(p,SituationMap::GeometryModel::Attribute::SymbolExplicitScale).toFloat(&ok); if (!ok) symbolScale = 1.0f; int symbolForceId = m_geometryModel.getAttribute(p, GeometryModel::Attribute::ForceId).toInt(&ok); if (!ok) symbolForceId = -1; int symbolInjuryId = m_geometryModel.getAttribute(p, GeometryModel::Attribute::DamageForceId).toInt(&ok); if (!ok) symbolInjuryId = -1; if (!partyIds.contains(symbolForceId)) symbolForceId = partyIds.first(); if (!partyIds.contains(symbolInjuryId)) symbolInjuryId = partyIds.first(); symData.size = (symbolScale > 0) ? symbolScale : 1.0; objPtr->setOrigin( Point3D(point.x(),point.y(),0.0) ); objPtr->setPickable(m_nodesPickable); objPtr->setSymbol(symData); objPtr->setPartyId( symbolForceId ); AdvancedSymbology::Injury injury = AdvancedSymbology::Injury::NoInjury; switch (vbg) { case SituationMap::GeometryModel::t_vbg_et::ANNAEHENDER_TREFFER : case SituationMap::GeometryModel::t_vbg_et::TREFFER_OHNE_WIRKUNG : case SituationMap::GeometryModel::t_vbg_et::EINSATZBEREIT : injury = AdvancedSymbology::Injury::NoInjury; break; case SituationMap::GeometryModel::t_vbg_et::AUSFALL_WAFFENANLAGE : case SituationMap::GeometryModel::t_vbg_et::AUSFALL_WAFFENANLAGE_SICHTB : injury = AdvancedSymbology::Injury::WeaponKill; break; case SituationMap::GeometryModel::t_vbg_et::BEWEGUNGSUNFAEHIG : case SituationMap::GeometryModel::t_vbg_et::BEWEGUNGSUNFAEHIG_SICHTB : injury = AdvancedSymbology::Injury::MobilityKill; break; case SituationMap::GeometryModel::t_vbg_et::LEICHTER_TREFFER : case SituationMap::GeometryModel::t_vbg_et::MITTLERER_TREFFER : case SituationMap::GeometryModel::t_vbg_et::SCHWERER_TREFFER : injury = AdvancedSymbology::Injury::Hit; break; case SituationMap::GeometryModel::t_vbg_et::TOTALAUSFALL : injury = AdvancedSymbology::Injury::TotalKill; break; case SituationMap::GeometryModel::t_vbg_et::ZEITLICHER_AUSFALL : injury = AdvancedSymbology::Injury::TotalKill; break; } objPtr->setInjury( injury , symbolInjuryId ); objPtr->setTextModifier( SituationMap::Participant::TextModifier::W_DateTimeGroup , m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_W).toString()); objPtr->setTextModifier( SituationMap::Participant::TextModifier::T_UniqueDesignation , m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_T).toString()); objPtr->setTextModifier( SituationMap::Participant::TextModifier::M_HigherFormation , m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_M).toString()); objPtr->setTextModifier( SituationMap::Participant::TextModifier::EF_ReinforcedReduced , m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_EF).toString()); objPtr->setTextModifier( SituationMap::Participant::TextModifier::XY_AltitudeLocation , m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_XY).toString()); objPtr->setTextModifier( SituationMap::Participant::TextModifier::V_Type , m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_V).toString()); objPtr->setTextModifier( SituationMap::Participant::TextModifier::Z_Speed , m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_Z).toString()); objPtr->setTextModifier( SituationMap::Participant::TextModifier::G_StaffComments , m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_G).toString()); objPtr->setTextModifier( SituationMap::Participant::TextModifier::H_AdditionalInformation, m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_H).toString()); objPtr->setTextModifier( SituationMap::Participant::TextModifier::JKLNP , m_geometryModel.getAttribute(p, GeometryModel::Attribute::Text_KLNPJ).toString()); /* AdditionalSymbolType additionalSymbol; AdditionalSymbolType::NbcProtection, ///< Line at top left. AdditionalSymbolType::Manipulation, ///< Black and white dashed lines at bottom (1st of three) AdditionalSymbolType::NoPosition, ///< Red line at bottom (2nd of three) AdditionalSymbolType::BiteError ///< Yellow line at bottom. (3rd of three) objPtr->setAdditionalSymbol(additionalSymbol); */ bool success = objPtr->updateView(); if (!success) ERROR_LOG(m_logger) << LOGFUNCTION << " failed"; DEBUG_LOG(m_logger) << LOGFUNCTION << " uniqueMapId=" << objPtr->uniqueMapId(); // Store id in primitive m_geometryModel.setUserData(p, objPtr->uniqueMapId()); int ms = m_stats.m_timer.elapsed(); m_stats.m_msSymbol += ms; m_stats.m_msSymbolMin = std::min(ms, m_stats.m_msDictionarySymbolMin); m_stats.m_msSymbolMax = std::max(ms, m_stats.m_msDictionarySymbolMax); } // void GeometryModelRendererEsri::drawSymbol void GeometryModelRendererEsri::drawText(const GeometryModel::Node &p, const QString &layer, SituationMap::AbstractMapObject * /*mapObj*/) { QList points = m_geometryModel.getPrimitivePoints(p); if (points.size() != 1) { DEBUG_LOG(m_logger) << LOGFUNCTION << "Primitive TextBox doesn't have origin!"; return; } SituationMap::UniqueMapId mapId = getIdFromNode(p); SituationMap::ObjectFactory &objFac = m_map->objectFactory(); SituationMap::RefPointer objPtr; if (SituationMap::isUniqueMapIdValid(mapId)) objPtr = objFac.get(mapId).get(); if (!objPtr.valid()) { objPtr = objFac.create (layer, QLatin1String("PlanElement")).get(); if (!objPtr.valid()) { ERROR_LOG(m_logger) << LOGFUNCTION << " objFac.create failed"; return; } objPtr->setScaleEnable(false); // disable scaling (setScale, most of the time done by user) } ++m_stats.m_drawTextCount; m_stats.m_timer.restart(); double phi = m_geometryModel.getAttribute(p, GeometryModel::Attribute::Rotate).toDouble(); // *(M_PI/180.0); const QString & text = m_geometryModel.getTextData(p); double fontSize = m_geometryModel.getAttribute(p, GeometryModel::Attribute::FontSize).toDouble(); const QColor & textColor = m_geometryModel.getAttribute(p, GeometryModel::Attribute::Color).value(); const QColor & lineColor = m_geometryModel.getAttribute(p, GeometryModel::Attribute::LineColor).value(); QColor fillColor = m_geometryModel.getAttribute(p, GeometryModel::Attribute::FillColor).value(); int lineWidth = m_geometryModel.getAttribute(p, GeometryModel::Attribute::LineWidth).toInt(); bool fill = m_geometryModel.getAttribute(p, GeometryModel::Attribute::Fill).toBool(); bool bold = m_geometryModel.getAttribute(p, GeometryModel::Attribute::FontBold).toBool(); bool italic = m_geometryModel.getAttribute(p, GeometryModel::Attribute::FontItalic).toBool(); bool useBox = m_geometryModel.getAttribute(p, GeometryModel::Attribute::Box).toBool(); GeometryModel::Font pmFont = (GeometryModel::Font)(m_geometryModel.getAttribute(p, GeometryModel::Attribute::Font).toInt()); const GeometryModel::Node & td = p.firstChildNode(QLatin1String("text_data")); GeometryModel::HorizontalAlign pmAlign = (GeometryModel::HorizontalAlign)(m_geometryModel.getAttribute(td, GeometryModel::Attribute::Alignment).toInt()); GeometryModel::HorizontalAlign anchorH = (GeometryModel::HorizontalAlign)(m_geometryModel.getAttribute(p, GeometryModel::Attribute::AnchorHorizontal).toInt()); GeometryModel::VerticalAlign anchorV = (GeometryModel::VerticalAlign)(m_geometryModel.getAttribute(p, GeometryModel::Attribute::AnchorVertical).toInt()); int marginH = m_geometryModel.getAttribute(p, GeometryModel::Attribute::MarginHorizontal).toInt(); int marginV = m_geometryModel.getAttribute(p, GeometryModel::Attribute::MarginVertical).toInt(); if (fontSize <= 0) fontSize = 14.0; Q_UNUSED(useBox); Q_UNUSED(marginH); Q_UNUSED(marginV); QString fontName; switch (pmFont) { case GeometryModel::Font::SansSerif : fontName = QLatin1String("Arial"); break; case GeometryModel::Font::Serif : fontName = QLatin1String("Times New Roman"); break; case GeometryModel::Font::Fixed : fontName = QLatin1String("Courier New"); break; case GeometryModel::Font::Decorative : { QStringList fontFamilies = QFontDatabase().families(); fontName.clear(); for (const QLatin1String &fontFamilyName : { QLatin1String("Freestyle Script"), QLatin1String("MV Boli"), QLatin1String("URW Chancery L")}) { if (fontFamilies.contains(fontFamilyName)) { fontName = fontFamilyName; break; } } } break; default : fontName = QLatin1String("Wingdings"); break; } SituationMap::HorizontalAlignment fontAlignm = SituationMap::HorizontalAlignment::Left; SituationMap::HorizontalAlignment hAlignm = SituationMap::HorizontalAlignment::Center; SituationMap::VerticalAlignment vAlignm = SituationMap::VerticalAlignment::Middle; switch (pmAlign) { case GeometryModel::HorizontalAlign::Left : fontAlignm = SituationMap::HorizontalAlignment::Left; break; case GeometryModel::HorizontalAlign::HCenter : fontAlignm = SituationMap::HorizontalAlignment::Center; break; case GeometryModel::HorizontalAlign::Right : fontAlignm = SituationMap::HorizontalAlignment::Right; break; } Q_UNUSED(fontAlignm); switch (anchorV) { case GeometryModel::VerticalAlign::Bottom : vAlignm = SituationMap::VerticalAlignment::Bottom; break; case GeometryModel::VerticalAlign::VCenter : vAlignm = SituationMap::VerticalAlignment::Middle; break; case GeometryModel::VerticalAlign::Top : vAlignm = SituationMap::VerticalAlignment::Top; break; } switch (anchorH) { case GeometryModel::HorizontalAlign::Left : hAlignm = SituationMap::HorizontalAlignment::Left; break; case GeometryModel::HorizontalAlign::HCenter : hAlignm = SituationMap::HorizontalAlignment::Center; break; case GeometryModel::HorizontalAlign::Right : hAlignm = SituationMap::HorizontalAlignment::Right; break; } // uint lineWidth = setLineStyle( p, objPtr.get() ); setFillStyle(p, objPtr.get()); SituationMap::TextStyle &textStyle = objPtr->rTextStyle(); if (!fill) fillColor.setAlpha(0); textStyle.setTextColor(textColor); textStyle.setTextOutlineColor(lineColor); textStyle.setBackgroundColor(fillColor); textStyle.setTextOutlineWidth(lineWidth-1); // textStyle.setTextOutlineWidth(0.0f); textStyle.setFontFamily(fontName); textStyle.setSize(fontSize); textStyle.setAngle(phi); textStyle.setBold(bold); textStyle.setItalic(italic); textStyle.setHorizontalAlignment(hAlignm); textStyle.setVerticalAlignment(vAlignm); objPtr -> setIdentifier(text.isEmpty() ? QLatin1String("????????") : text); objPtr -> setPickable(m_nodesPickable); objPtr -> setOrigin(SituationMap::Point3D::fromQPointF(points.first())); objPtr -> setShowAnchorMarker(m_editorMode); bool success = objPtr->updateView(); if (!success) ERROR_LOG(m_logger) << LOGFUNCTION << " failed"; // Store id in primitive m_geometryModel.setUserData(p, objPtr->uniqueMapId()); int ms = m_stats.m_timer.elapsed(); m_stats.m_msText += ms; m_stats.m_msTextMin = std::min(ms, m_stats.m_msTextMin); m_stats.m_msTextMax = std::max(ms, m_stats.m_msTextMax); } // void GeometryModelRendererEsri::drawText } // namepace SituationMap