/** * @RDE_HEADER@ * Interface-Implementation of GeoImage * $Id$ * $HeadURL$ * $Author$ */ // Own #include "geo_image_impl.h" #include #include #include // ESRI // Qt #include #include #include #include #include namespace SituationMap { class GeoImageImpl::Private { public: Private() = default; ~Private() = default; // ESRI data: // Own data: SimpleValue m_geoImageData; QSharedPointer m_gopmPin; }; // class GeoImageImpl::Private //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // class GeoImageImpl //----------------------------------------------------------------------------- GeoImageImpl::GeoImageImpl(const QString &debugInfo) : GeoImage() // Interface , BaseClass(debugInfo) // Implementation , d(new Private) , m_logger(getLogger("GeoImageImpl")) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } GeoImageImpl::~GeoImageImpl() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; delete d; TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } QString GeoImageImpl::toString() const { QString str; str.append(BaseClass::toString()); str.append(d->m_geoImageData.value().toString()); return str; } GeoImage::GeoImageData GeoImageImpl::geoImageData() const { return d->m_geoImageData.value(); } void GeoImageImpl::setGeoImageData(const GeoImageData &geoImageData) { d->m_geoImageData = geoImageData; } MarkerSymbolType GeoImageImpl::proxyMarker() const { return d->m_geoImageData.value().proxyMarker; } void GeoImageImpl::setProxyMarker(const MarkerSymbolType &proxyMarker) { if (d->m_geoImageData.value().proxyMarker != proxyMarker) d->m_geoImageData.refValue().proxyMarker = proxyMarker; } int GeoImageImpl::proxyMarkerSize() const { return d->m_geoImageData.value().proxyMarkerSize; } void GeoImageImpl::setProxyMarkerSize(int proxyMarkerSize) { if (d->m_geoImageData.value().proxyMarkerSize != proxyMarkerSize) d->m_geoImageData.refValue().proxyMarkerSize = proxyMarkerSize; } QColor GeoImageImpl::proxyMarkerColor() const { return d->m_geoImageData.value().proxyMarkerColor; } void GeoImageImpl::setProxyMarkerColor(const QColor &proxyMarkerColor) { if (d->m_geoImageData.value().proxyMarkerColor != proxyMarkerColor) d->m_geoImageData.refValue().proxyMarkerColor = proxyMarkerColor; } QImage GeoImageImpl::proxyImage() const { return d->m_geoImageData.value().proxyImage; } void GeoImageImpl::setProxyImage(const QImage &proxyImage, const QSize &proxyImageDefaultSize) { if (d->m_geoImageData.value().proxyImage != proxyImage) d->m_geoImageData.refValue().proxyImage = proxyImage; if (d->m_geoImageData.value().proxyImageDefaultSize != proxyImageDefaultSize) d->m_geoImageData.refValue().proxyImageDefaultSize = proxyImageDefaultSize; } QSize GeoImageImpl::proxyImageDefaultSize() const { return d->m_geoImageData.value().proxyImageDefaultSize; } QImage GeoImageImpl::mainImage() const { return d->m_geoImageData.value().mainImage; } void GeoImageImpl::setMainImage(const QImage &mainImage) { if (d->m_geoImageData.value().mainImage != mainImage) d->m_geoImageData.refValue().mainImage = mainImage; } QImage GeoImageImpl::previewImageTypical() const { if (!d->m_geoImageData.value().proxyImage.isNull()) return d->m_geoImageData.value().proxyImage; if (!d->m_geoImageData.value().mainImage.isNull()) return d->m_geoImageData.value().mainImage; return QImage(); } QString GeoImageImpl::description() const { return d->m_geoImageData.value().description; } void GeoImageImpl::setDescription(const QString &description) { if (d->m_geoImageData.value().description != description) d->m_geoImageData.refValue().description = description; } void GeoImageImpl::setPinEnabled(bool enablePin) { if (d->m_geoImageData.value().pinEnabled != enablePin) d->m_geoImageData.refValue().pinEnabled = enablePin; } bool GeoImageImpl::isPinEnabled() const { return d->m_geoImageData.value().pinEnabled; } QWidget *GeoImageImpl::createWidget(QWidget *parent) const { const GeoImageData &geoImageData = d->m_geoImageData.value(); if (geoImageData.mainImage.isNull()) return nullptr; QWidget *widget = new QWidget(parent); widget->setLayout(new QVBoxLayout()); QLabel *img = new QLabel(); img->setPixmap(QPixmap::fromImage(geoImageData.mainImage)); widget->layout()->addWidget(img); widget->layout()->addWidget(new QLabel(geoImageData.description)); // CloseButton QPushButton *pbClose = new QPushButton(QLatin1String("Close")); widget->layout()->addWidget(pbClose); pbClose->connect(pbClose, &QPushButton::clicked, widget, [widget]() { widget->deleteLater(); }); return widget; } bool GeoImageImpl::updateViewImpl() { TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " origin =" << this->origin() //.x() << ", " << this->origin().y() << " visibility=" << m_visibility << " visiTechn=" << m_visibilityTechnical << " visiTact=" << m_visibilityTactical; if (!m_graphicsLayer) { ERROR_LOG(m_logger) << LOGFUNCTION << " no graphicsLayer"; return false; } if (!m_mainGraphicalObject) { ERROR_LOG(m_logger) << LOGFUNCTION << " no m_mainGraphicalObject"; return false; } // Marker: GraphicalObjectPictureMarker *pMarker = static_cast(m_mainGraphicalObject); if (d->m_geoImageData.changed()) { const GeoImageData &geoImageData = d->m_geoImageData.value(); if (geoImageData.proxyImage.isNull()) { if (geoImageData.proxyMarker == MarkerSymbolType::Undefined) pMarker->setMarkerSymbol(MarkerSymbolType::Diamond, 20, Qt::red); else pMarker->setMarkerSymbol(geoImageData.proxyMarker, geoImageData.proxyMarkerSize, geoImageData.proxyMarkerColor); } else pMarker->setImage(geoImageData.proxyImage, geoImageData.proxyImageDefaultSize); // Pin if (m_mapImpl->mode() == Mode::Mode_3D) { if (geoImageData.pinEnabled) createPin(); else resetPin(); } } updateIdentifierPosition(); pMarker->setOrigin(this->originTranslated()); bool success = BaseClass::updateViewImpl(); // reset changed: d->m_geoImageData.reset(); onMapExtentChanged(); TRACE_LOG(m_logger) << LOGFUNCTION << " END, success=" << success; return success; } bool GeoImageImpl::init(MapImpl *mapImpl, const QString &logicalLayerName) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; bool success = BaseClass::init(mapImpl, logicalLayerName); if (success) { // create underlying object (to save most attributes only there) if (!m_mainGraphicalObject) m_mainGraphicalObject = new GraphicalObjectPictureMarker(m_mapImpl->getEsriGeoView(), m_graphicsLayer, m_debugInfo + QLatin1String("#Image"), m_uniqueMapId); } else ERROR_LOG(m_logger) << LOGFUNCTION << " init failed"; TRACE_LOG(m_logger) << LOGFUNCTION << " END, success=" << success; return success; } bool GeoImageImpl::onMapExtentChanged() { TRACE_LOG(m_logger) << " onMapExtentChanged"; if (m_graphicalObjectPin && m_mainGraphicalObject) // m_graphicalObjectPin exists only at Mode_3D { if (!d->m_gopmPin) { d->m_gopmPin = QSharedPointer (new GraphicalObjectPictureMarker(m_mapImpl->getEsriGeoView() , m_graphicsLayer , m_debugInfo + QStringLiteral("#PictureMarkerPin") , m_uniqueMapId) ); GraphicalObjectPictureMarker *pMarker = static_cast(m_mainGraphicalObject); if (pMarker) { const GeoImageData &geoImageData = d->m_geoImageData.value(); d->m_gopmPin->setImage(pMarker->image(), geoImageData.proxyImageDefaultSize); } } d->m_gopmPin->setScale(m_mainGraphicalObject->scale()); Point3D originTranslated = this->originTranslated(); DEBUG_LOG(m_logger) << " XXX originTranslatedORG = " << originTranslated; // GUEZE-2620 3D Sicht SOS Symbole // Bisher wurde die Höhe des SOS-Images und -Textes quasi getuned, wobei ja nun // unter bestimmten Umständen leider zu einem Höhenwert ausserhalb des // Sichtfensters kam. // Daher: // - Pflicht: SOS-Symbol und Text auf den Boden // - Kuer: Zudem versucht die SW, eine zweite Instanz des Images // (inkl. Verbindungslinie) zu positionieren. // Und zwar grob mittig zw. Erdoberfläche und oberen Kante des Sichtbereichs. // Leider funktioniert des dafür genutzte ESRI-Befehl nicht immer zuverlässig. // Meist dann, wenn sich der Augenpunkt (ViewPoint) dicht am Objekt befinden... // Noch ein bisschen Tuning, aber es verbleiben leider Fehlersituationen. if (m_mapImpl->scale() > 1500) { const double zVal = m_mapImpl->scale() * m_mapImpl->scale() * 0.0001; DEBUG_LOG(m_logger) << " zVal = " << zVal; originTranslated.rz() = zVal; // 1 ... 10000 (qBound ~ std::clamp) originTranslated.rz() = qBound(1.0, originTranslated.rz(), 10000.0); // check viewPort: // Note: unfortunately its dows not work perfect :-( int cnt = 0; static int s_counterMax = 10; while (m_mapImpl->mapCoordinateToViewPortWindowPoint3D(originTranslated).isNull() && (originTranslated.rz() > 1) && (cnt <= s_counterMax)) { originTranslated.rz() /= 2.0; ++cnt; } if (cnt == s_counterMax) originTranslated.rz() = 0; else originTranslated.rz() *= 0.5; // try to show in the middle between baseSurface and upper edge of window d->m_gopmPin->setVisibility(true); } else { // GUEZE-3460 - SOS Meldungen werden nicht korrekt angezeigt if (m_mapImpl->scale() < 500) originTranslated.rz() = 1.0; // meter else if (m_mapImpl->scale() < 1000) originTranslated.rz() = 2.5; // meter else originTranslated.rz() = 10.0; // meter d->m_gopmPin->setVisibility(true); } DEBUG_LOG(m_logger) << " originTranslated = " << originTranslated; d->m_gopmPin->setOrigin(originTranslated); if (!d->m_gopmPin->updateView()) ERROR_LOG(m_logger) << LOGFUNCTION << " updateView failed" << m_mainGraphicalObject->debugInfo(); // update m_identifierPositionCandidateTranslated , // it will be transfered to m_mainGraphicalObject via BaseClass::onMapExtentChanged() // m_identifierPositionCandidateTranslated = originTranslated; Point3D centerEarth = originTranslated; centerEarth.rz() = -100; // hopefully lower than lowest level of training area m_graphicalObjectPin->setPositions({originTranslated, centerEarth}); m_graphicalObjectPin->setVisibility(d->m_gopmPin->visibility()); if (!m_graphicalObjectPin->updateView()) ERROR_LOG(m_logger) << LOGFUNCTION << " updateView failed" << m_graphicalObjectPin->debugInfo(); } // if (m_graphicalObjectPin && m_mainGraphicalObject) return BaseClass::onMapExtentChanged(); } } // namespace SituationMap