345 lines
10 KiB
C++
Executable File
345 lines
10 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* Implementation of AbstractMapObject
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*/
|
|
|
|
|
|
// Own
|
|
#include "overview_map_handler_impl.h"
|
|
#include <Common/resource_path.h>
|
|
#include <MapImpl/map_impl.h>
|
|
#include <SymbologyImpl/symbol_dictionary_impl.h>
|
|
#include <Rubberbands/rubberband_factory.h>
|
|
#include <Map/situation_map_utils.h>
|
|
|
|
#include <MapImpl/layer_factory_impl.h>
|
|
|
|
|
|
// ESRI
|
|
#include <arcgis/Map.h>
|
|
#include <arcgis/MapGraphicsView.h>
|
|
#include <arcgis/TileCache.h>
|
|
#include <arcgis/ArcGISTiledLayer.h>
|
|
#include <arcgis/Basemap.h>
|
|
#include <arcgis/SimpleRenderer.h>
|
|
#include <arcgis/GraphicsOverlayListModel.h>
|
|
#include <arcgis/SimpleLineSymbol.h>
|
|
#include <arcgis/SimpleFillSymbol.h>
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
namespace SituationMap
|
|
{
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
class OverviewMapHandlerImpl::Private
|
|
{
|
|
public:
|
|
Private() = default;
|
|
~Private() = default;
|
|
|
|
// ESRI data:
|
|
|
|
// Own data:
|
|
QPointer<OverviewMap> 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<MapImpl *>(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<OverviewMap>(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<OverviewMap> 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<Esri::ArcGISRuntime::MapGraphicsView>(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
|
|
|