/** * @RDE_HEADER@ * Implementation of AbstractMapObject * $Id$ * $HeadURL$ * $Author$ */ // Own #include "overview_map_handler_impl.h" #include #include #include #include #include #include // ESRI #include #include #include #include #include #include #include #include #include //---------------------------------------------------------------------------- namespace SituationMap { //----------------------------------------------------------------------------- class OverviewMapHandlerImpl::Private { public: Private() = default; ~Private() = default; // ESRI data: // Own data: QPointer m_builtInOverviewMap; MapImpl *m_mainMap = nullptr; QColor m_color = Qt::red; }; // class OverviewMapHandlerImpl::Private //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- OverviewMapHandlerImpl::OverviewMapHandlerImpl(Map *map) : BaseClass(map) , m_logger(getLogger("OverviewMapHandlerImpl")) , d(new Private) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; d->m_mainMap = static_cast(map); if (d->m_mainMap) { // d->m_color = d->m_mainMap->palette().color(QPalette::WindowText); // RDE_DARK_BLUE // REGG-4125 - Karte: Bereichsauswahl verdrängt Übersichtskarte // EventDispatcher und EventDelegater scheinen die OverviewMap zu verdrängen. // OverviewMap per QGraphicsProxyWidget (QGraphicsView()->scene()->addWidget) schlägt auch fehl // Daher dieser einfacher workaround: // Raise nach dem Zerstören eines Rubberbands (und damit Entfernen von EventDispatcher und EventDelegater): connect(&d->m_mainMap->rubberbandFactory(), &RB::RubberbandFactory::rubberbandDestroyed, this, &OverviewMapHandlerImpl::onMainMapRectChanged); } else ERROR_LOG(m_logger) << LOGFUNCTION << " error no mainMap "; TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } OverviewMapHandlerImpl::~OverviewMapHandlerImpl() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; delete d; TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } void OverviewMapHandlerImpl::createBuiltInOverviewMap() { if (d->m_builtInOverviewMap) { DEBUG_LOG(m_logger) << LOGFUNCTION << " already exists"; return; } d->m_builtInOverviewMap = QPointer(new OverviewMap(this)); d->m_builtInOverviewMap->init(d->m_mainMap, d->m_color); if (! d->m_builtInOverviewMap->createBasicOverviewMap()) ERROR_LOG(m_logger) << LOGFUNCTION << " createBasicOverviewMap failed"; if (! d->m_builtInOverviewMap->widget()) { ERROR_LOG(m_logger) << LOGFUNCTION << " d->m_builtInOverviewMap->widget() failed"; return; } // confgure widget: // disable mouse: d->m_builtInOverviewMap->widget()->setAttribute(Qt::WA_TransparentForMouseEvents); d->m_builtInOverviewMap->widget()->setFocusPolicy(Qt::NoFocus); d->m_builtInOverviewMap->widget()->setMinimumSize(QSize(100, 100)); d->m_builtInOverviewMap->widget()->setStyleSheet(QLatin1String("border: 1px solid gray")); d->m_builtInOverviewMap->widget()->show(); // take care of position: connect(d->m_mainMap, &MapImpl::rectChanged, this, &OverviewMapHandlerImpl::onMainMapRectChanged); onMainMapRectChanged(); d->m_mainMap->emitVisualComponentChanged(VisualComponent::OverviewMap); // to update onOffCheckbox } void OverviewMapHandlerImpl::removeBuiltInOverviewMap() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; if (d->m_builtInOverviewMap) { QPointer localPtr = d->m_builtInOverviewMap; d->m_builtInOverviewMap.clear(); localPtr->deleteLater(); d->m_mainMap->emitVisualComponentChanged(VisualComponent::OverviewMap); } TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } QWidget *OverviewMapHandlerImpl::builtInOverviewMapWidget() { if (! d->m_builtInOverviewMap) return nullptr; return d->m_builtInOverviewMap->widget(); } void OverviewMapHandlerImpl::removeAll() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; removeBuiltInOverviewMap(); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } void OverviewMapHandlerImpl::onMainMapRectChanged() { if (! d->m_builtInOverviewMap) return; if (! d->m_builtInOverviewMap->widget()) return; const QSize &mainSize = d->m_mainMap->size(); const QSize &overviewSize = d->m_builtInOverviewMap->widget()->size(); QSize diff = mainSize - overviewSize - QSize(10, 10); // additional border d->m_builtInOverviewMap->widget()->move(diff.width(), diff.height()); d->m_builtInOverviewMap->widget()->raise(); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- OverviewMap::OverviewMap(QObject *parent) : BaseClass(parent) , m_logger(getLogger("OverviewMap")) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } OverviewMap::~OverviewMap() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; if (m_graphicsView) m_graphicsView->deleteLater(); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } void OverviewMap::init(MapImpl *mainMap, const QColor &color) { m_mainMap = mainMap; m_color = color; } QWidget *OverviewMap::widget() { return m_graphicsView.data(); } bool OverviewMap::createBasicOverviewMap() { if (m_graphicsView) return true; // create required objects: m_graphicsView = QPointer(new Esri::ArcGISRuntime::MapGraphicsView(m_mainMap)); m_graphicsView->setAttributionTextVisible(false); QObject *parent = this; QString tiledBaseMapLayer = SituationMap::getResourcePath() + QLatin1String("Topographic.tpk"); QFile f(tiledBaseMapLayer); if (!f.exists()) { ERROR_LOG(m_logger) << LOGFUNCTION << " file does not exist: tiledBaseMapLayer='" << tiledBaseMapLayer << "'"; return false; } INFO_LOG(m_logger) << LOGFUNCTION << " tiledBaseMapLayer='" << tiledBaseMapLayer << "'"; Esri::ArcGISRuntime::TileCache *tpkCache = new Esri::ArcGISRuntime::TileCache(tiledBaseMapLayer, parent); tpkCache->setObjectName(QLatin1String("OverviewMap-TPK-tpkCache")); Esri::ArcGISRuntime::ArcGISTiledLayer *tiledLayer = new Esri::ArcGISRuntime::ArcGISTiledLayer(tpkCache, parent); tiledLayer->setName(QLatin1String("OverviewMap-TPK-tiledLayer")); Esri::ArcGISRuntime::Basemap *basemap = new Esri::ArcGISRuntime::Basemap(tiledLayer, parent); basemap->setName(QLatin1String("TPK-Basemap")); // connect signals // loadStatusChanged -> connect(tpkCache, &Esri::ArcGISRuntime::TileCache::loadStatusChanged, this, [this](Esri::ArcGISRuntime::LoadStatus loadStatus) { DEBUG_LOG(m_logger) << LOGFUNCTION << " OverviewMap-TileCache: " << "loadStatus changed to: " << loadStatus; }); connect(tiledLayer, &Esri::ArcGISRuntime::ArcGISTiledLayer::loadStatusChanged, this, [this](Esri::ArcGISRuntime::LoadStatus loadStatus) { DEBUG_LOG(m_logger) << LOGFUNCTION << " OverviewMap-ArcGISTiledLayer: " << "loadStatus changed to: " << loadStatus; if (loadStatus == Esri::ArcGISRuntime::LoadStatus::Loaded) { DEBUG_LOG(m_logger) << LOGFUNCTION << " loaded -> setToFullExtent"; setToFullExtent(); } }); connect(basemap, &Esri::ArcGISRuntime::Basemap::loadStatusChanged, this, [this](Esri::ArcGISRuntime::LoadStatus loadStatus) { DEBUG_LOG(m_logger) << LOGFUNCTION << " OverviewMap-Basemap: " << "loadStatus changed to: " << loadStatus; }); // Map: Esri::ArcGISRuntime::Map *overviewMap = new Esri::ArcGISRuntime::Map(basemap, parent); overviewMap->setObjectName(QLatin1String("OverviewMap-EsriMap")); // will start esris cascading load dependecies... m_graphicsView->setMap(overviewMap); // GraphicsOverlay: Esri::ArcGISRuntime::GraphicsOverlay *graphicalOverlay = new Esri::ArcGISRuntime::GraphicsOverlay(parent); m_graphicsView->graphicsOverlays()->append(graphicalOverlay); QColor color = m_color; // create symbol Esri::ArcGISRuntime::SimpleLineSymbol *sls = new Esri::ArcGISRuntime::SimpleLineSymbol(Esri::ArcGISRuntime::SimpleLineSymbolStyle::Solid, color, 1, parent); color.setAlpha(100); Esri::ArcGISRuntime::SimpleFillSymbol *sfs = new Esri::ArcGISRuntime::SimpleFillSymbol(Esri::ArcGISRuntime::SimpleFillSymbolStyle::Solid, color, sls, parent); // create renderer Esri::ArcGISRuntime::SimpleRenderer *renderer = new Esri::ArcGISRuntime::SimpleRenderer(sfs, parent); // Handle errors of renderer: connect(renderer, &Esri::ArcGISRuntime::SimpleRenderer::errorOccurred, this, [this](const Esri::ArcGISRuntime::Error & error) { ERROR_LOG(m_logger) << LOGFUNCTION << " EsriError occured: " << error; }); // set Renderer to layer: graphicalOverlay->setRenderer(renderer); // prepare graphic m_graphic = new Esri::ArcGISRuntime::Graphic(graphicalOverlay); graphicalOverlay->graphics()->append(m_graphic); // update first time onMainMapExtentChanged(); // execute on extentChanged connect(m_mainMap, &MapImpl::extentChangedDelayed, this, &OverviewMap::onMainMapExtentChanged); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; return true; } void OverviewMap::onMainMapExtentChanged() { if (! m_graphic) return; Esri::ArcGISRuntime::GeoView *geoView = m_mainMap->getEsriGeoView(); if (! geoView) return; setToFullExtent(); const Esri::ArcGISRuntime::Viewpoint curVp = geoView->currentViewpoint(Esri::ArcGISRuntime::ViewpointType::BoundingGeometry); m_graphic->setGeometry(curVp.targetGeometry()); // curVp.targetGeometry() should be a rectangle } void OverviewMap::setToFullExtent() { if (!m_graphicsView || !m_mainMap) return; // zoom to fullExtent: Esri::ArcGISRuntime::Envelope fullExtent = m_mainMap->layerFactoryImpl().fullExtentOfBasemaps(0.2); // add margin Esri::ArcGISRuntime::Viewpoint vp(fullExtent); m_graphicsView->setViewpointAndWait(vp); } } // namespace SituationMap