Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+801
@@ -0,0 +1,801 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* MapLayer
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
// Own
|
||||
#include "logical_layer.h"
|
||||
#include <Map/map.h>
|
||||
#include <Symbology/symbol_dictionary.h>
|
||||
#include <SymbologyImpl/symbol_dictionary_impl.h>
|
||||
#include <Map/situation_map_utils.h>
|
||||
|
||||
|
||||
// ESRI
|
||||
#include <arcgis/Layer.h>
|
||||
#include <arcgis/GraphicsOverlay.h>
|
||||
#include <arcgis/DictionaryRenderer.h>
|
||||
#include <arcgis/ArcGISTiledLayer.h>
|
||||
#include <arcgis/LayerSceneProperties.h>
|
||||
|
||||
|
||||
// Qt
|
||||
// #include <QDebug>
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
static_assert((int)SituationMap::SurfacePlacement::Draped == (int)Esri::ArcGISRuntime::SurfacePlacement::Draped, "SurfacePlacement mismatch");
|
||||
static_assert((int)SituationMap::SurfacePlacement::Absolute == (int)Esri::ArcGISRuntime::SurfacePlacement::Absolute, "SurfacePlacement mismatch");
|
||||
static_assert((int)SituationMap::SurfacePlacement::Relative == (int)Esri::ArcGISRuntime::SurfacePlacement::Relative, "SurfacePlacement mismatch");
|
||||
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
LogicalLayer::LogicalLayer(const QString &logicalName, QObject *parent)
|
||||
: BaseClass(parent),
|
||||
m_logicalName(logicalName),
|
||||
m_logger(getLogger("LogicalLayer"))
|
||||
{
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " m_logicalName='" << m_logicalName << "'";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_logicalName='" << m_logicalName << "'";
|
||||
}
|
||||
|
||||
LogicalLayer::~LogicalLayer()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " m_logicalName='" << m_logicalName << "'";
|
||||
fini();
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_logicalName='" << m_logicalName << "'";
|
||||
}
|
||||
|
||||
void LogicalLayer::init(SituationMap::Map *map,
|
||||
Esri::ArcGISRuntime::LayerListModel *layerListModel,
|
||||
Esri::ArcGISRuntime::GraphicsOverlayListModel *graphicsOverlayListModel)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " m_logicalName='" << m_logicalName << "'"
|
||||
<< " layerListModel=" << layerListModel
|
||||
<< " graphicsOverlayListModel=" << graphicsOverlayListModel;
|
||||
m_map = map;
|
||||
m_layerListModel = layerListModel;
|
||||
m_graphicsOverlayListModel = graphicsOverlayListModel;
|
||||
|
||||
|
||||
#ifdef LTS_DEBUG
|
||||
// sometimes getCreateGraphicalOverlay() has no m_graphicsOverlayListModel - hmm
|
||||
// happens for layer 'MountingfPoints'
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " m_logicalName='" << m_logicalName << "'"
|
||||
<< " m_map=" << m_map
|
||||
<< " m_map->isReady=" << m_map->isReady()
|
||||
<< " layerListModel=" << layerListModel
|
||||
<< " graphicsOverlayListModel=" << graphicsOverlayListModel;
|
||||
|
||||
Q_ASSERT(m_graphicsOverlayListModel);
|
||||
#endif // LTS_DEBUG
|
||||
|
||||
// set default order of GraphicalOverlays: (from bottom to top)
|
||||
setOrderOfGraphicalOverlays({ TechnicalLayerType::GraphicsLayer,
|
||||
TechnicalLayerType::GraphicsLayer_Dict,
|
||||
TechnicalLayerType::GraphicsLayer_3D_Extrusion,
|
||||
TechnicalLayerType::GraphicsLayer_3D_Absolute });
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void LogicalLayer::fini()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " m_logicalName='" << m_logicalName << "'"
|
||||
<< " layerListModel=" << m_layerListModel
|
||||
<< " graphicsOverlayListModel=" << m_graphicsOverlayListModel;
|
||||
|
||||
// process Layer (e.g. Basemap)
|
||||
// Esri::ArcGISRuntime::Layer
|
||||
if (m_layer && m_layerListModel)
|
||||
{
|
||||
m_layerListModel->removeOne(m_layer);
|
||||
delete m_layer;
|
||||
m_layer = nullptr;
|
||||
}
|
||||
|
||||
// process GraphicsOverlay
|
||||
if (m_graphicsOverlayListModel)
|
||||
{
|
||||
for (Esri::ArcGISRuntime::GraphicsOverlay *graphicsOverlay : qAsConst(m_graphicalOverlays))
|
||||
{
|
||||
// do some checks :
|
||||
{
|
||||
const int numberOfCurrentObjects = graphicsOverlay->graphics()->size();
|
||||
if (numberOfCurrentObjects != 0)
|
||||
{
|
||||
QString objectName;
|
||||
Esri::ArcGISRuntime::Graphic* g = graphicsOverlay->graphics()->first();
|
||||
if (g)
|
||||
objectName = g->objectName();
|
||||
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION
|
||||
<< " Attention, removing GraphicsOverlay still having objects!!!"
|
||||
<< ", graphicsOverlay='" << graphicsOverlay << "'"
|
||||
<< ", numberOfCurrentObjects=" << numberOfCurrentObjects
|
||||
<< ", m_logicalName='" << m_logicalName << "'"
|
||||
<< ", objectName of first='" << objectName << "'";
|
||||
}
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " m_logicalName='" << m_logicalName << "'"
|
||||
<< " numberOfCurrentObjects=" << numberOfCurrentObjects;
|
||||
}
|
||||
// : do some checks
|
||||
|
||||
m_graphicsOverlayListModel->removeOne(graphicsOverlay);
|
||||
delete graphicsOverlay;
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup internal container:
|
||||
m_graphicalOverlays.clear();
|
||||
m_graphicOverlayContainer.clear();
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||||
<< " m_logicalName='" << m_logicalName << "'"
|
||||
<< " layerListModel=" << m_layerListModel
|
||||
<< " graphicsOverlayListModel=" << m_graphicsOverlayListModel;
|
||||
}
|
||||
|
||||
|
||||
QString LogicalLayer::logicalName() const
|
||||
{
|
||||
return m_logicalName;
|
||||
}
|
||||
|
||||
void LogicalLayer::setLogicalName(const QString &logicalName)
|
||||
{
|
||||
m_logicalName = logicalName;
|
||||
}
|
||||
|
||||
|
||||
LayerType LogicalLayer::layerType() const
|
||||
{
|
||||
return m_layerType;
|
||||
}
|
||||
void LogicalLayer::setLayerType(const LayerType &layerType)
|
||||
{
|
||||
m_layerType = layerType;
|
||||
}
|
||||
BasemapType LogicalLayer::basemapType() const
|
||||
{
|
||||
return m_basemapType;
|
||||
}
|
||||
void LogicalLayer::setBasemapType(const BasemapType &basemapType)
|
||||
{
|
||||
m_basemapType = basemapType;
|
||||
}
|
||||
|
||||
|
||||
RenderingMode LogicalLayer::renderingMode() const
|
||||
{
|
||||
return m_graphicsOverlayRenderingMode;
|
||||
}
|
||||
void LogicalLayer::setRenderingMode(RenderingMode renderingMode)
|
||||
{
|
||||
m_graphicsOverlayRenderingMode = renderingMode;
|
||||
}
|
||||
|
||||
SurfacePlacement LogicalLayer::surfacePlacement() const
|
||||
{
|
||||
return m_surfacePlacement;
|
||||
}
|
||||
void LogicalLayer::setSurfacePlacement(SurfacePlacement surfacePlacement)
|
||||
{
|
||||
m_surfacePlacement = surfacePlacement;
|
||||
}
|
||||
|
||||
const LayerParameter &LogicalLayer::layerParameter() const
|
||||
{
|
||||
return m_layerParameter;
|
||||
}
|
||||
void LogicalLayer::setLayerParameter(const LayerParameter &layerParameter)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " m_logicalName='" << m_logicalName << "'"
|
||||
<< " layerParameter=" << layerParameter;
|
||||
bool changed = (m_layerParameter != layerParameter);
|
||||
|
||||
m_layerParameter = layerParameter;
|
||||
|
||||
if (changed)
|
||||
{
|
||||
// apply LayerParameters (visible, opca, brightness....)
|
||||
this->applyLayerParameterToEsri();
|
||||
|
||||
// trigger update of gui:
|
||||
emit layerParameterChanged(m_logicalName, m_layerParameter);
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||||
<< " m_logicalName='" << m_logicalName << "'"
|
||||
<< " changed=" << changed;
|
||||
}
|
||||
|
||||
Esri::ArcGISRuntime::Layer *LogicalLayer::layer() const
|
||||
{
|
||||
return m_layer;
|
||||
}
|
||||
void LogicalLayer::setLayer(Esri::ArcGISRuntime::Layer *layer)
|
||||
{
|
||||
m_layer = layer;
|
||||
|
||||
// Handle errors of layer:
|
||||
connect(m_layer, &Esri::ArcGISRuntime::Layer::errorOccurred,
|
||||
this, &LogicalLayer::onLayerError, Qt::UniqueConnection);
|
||||
|
||||
// Handle doneLoading:
|
||||
connect(m_layer, &Esri::ArcGISRuntime::Layer::doneLoading,
|
||||
this, &LogicalLayer::onLayerDoneLoading, Qt::UniqueConnection);
|
||||
|
||||
connect(m_layer, &Esri::ArcGISRuntime::Layer::loadStatusChanged,
|
||||
this, &LogicalLayer::onLayerLoadStatusChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
if (!m_layerListModel->contains(m_layer))
|
||||
m_layerListModel->append(m_layer);
|
||||
}
|
||||
|
||||
|
||||
QList<Esri::ArcGISRuntime::GraphicsOverlay *> LogicalLayer::getCurrentGraphicalOverlaysOrdered() const
|
||||
{
|
||||
QList<Esri::ArcGISRuntime::GraphicsOverlay *> orderedLayerList;
|
||||
|
||||
for (TechnicalLayerType techType : m_orderOfGraphicalOverlays)
|
||||
{
|
||||
const QString &esriLayerName = LogicalLayer::createInternalLayerName(m_logicalName, techType);
|
||||
if (!m_graphicOverlayContainer.contains(esriLayerName))
|
||||
continue;
|
||||
Esri::ArcGISRuntime::GraphicsOverlay *layer = m_graphicOverlayContainer[esriLayerName];
|
||||
if (layer)
|
||||
orderedLayerList.append(layer);
|
||||
} // for
|
||||
return orderedLayerList;
|
||||
}
|
||||
|
||||
QList<QPair<QString, Esri::ArcGISRuntime::GraphicsOverlay *> > LogicalLayer::getCurrentGraphicalOverlaysOrderedWithName() const
|
||||
{
|
||||
QList<QPair<QString, Esri::ArcGISRuntime::GraphicsOverlay *> > ret;
|
||||
|
||||
for (TechnicalLayerType techType : qAsConst(m_orderOfGraphicalOverlays))
|
||||
{
|
||||
const QString &esriLayerName = LogicalLayer::createInternalLayerName(m_logicalName, techType);
|
||||
if (!m_graphicOverlayContainer.contains(esriLayerName))
|
||||
continue;
|
||||
Esri::ArcGISRuntime::GraphicsOverlay *layer = m_graphicOverlayContainer[esriLayerName];
|
||||
if (!layer)
|
||||
continue;
|
||||
|
||||
QPair<QString, Esri::ArcGISRuntime::GraphicsOverlay *> foundPair(esriLayerName, layer);
|
||||
ret.append(foundPair);
|
||||
} // for
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int LogicalLayer::layerIndex() const
|
||||
{
|
||||
if (! m_layerListModel)
|
||||
return -1;
|
||||
|
||||
return m_layerListModel->indexOf(m_layer);
|
||||
}
|
||||
|
||||
Esri::ArcGISRuntime::GraphicsOverlay *LogicalLayer::getCreateGraphicalOverlay(const TechnicalLayerType &technicalLayerType)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " m_logicalName='" << m_logicalName << "'"
|
||||
<< " technicalLayerType=" << technicalLayerType;
|
||||
|
||||
// [GUEZE-496] RPL Nr 770: 3D Lagedarstellung Einfrieren der SW Appl.
|
||||
// Layer renderer does not support multipoint graphics (V100.8)
|
||||
// So turn back to 2 technical layers per logical layer. So The MineArea
|
||||
// is on a TechnicalLayerType::GraphicsLayer and MineArea/IndicationContainer
|
||||
// uses ONE GraphicalObjectPictureMarker/Esri::ArcGISRuntime::PictureMarkerSymbol
|
||||
// with multiple coordinates (multipoint)
|
||||
TechnicalLayerType technicalLayerTypeLocal = technicalLayerType;
|
||||
|
||||
if ((m_layerType == LayerType::Rubberband) ||
|
||||
(m_layerType == LayerType::Overlay) ||
|
||||
((m_layerType == LayerType::Operational) && (m_logicalName.compare(QStringLiteral("PlanEditorLayer")) == 0))
|
||||
)
|
||||
{
|
||||
technicalLayerTypeLocal = TechnicalLayerType::GraphicsLayer_Dict;
|
||||
}
|
||||
|
||||
if (! m_graphicsOverlayListModel)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " m_logicalName='" << m_logicalName << "'"
|
||||
<< " no m_graphicsOverlayListModel";
|
||||
|
||||
#ifdef LTS_DEBUG
|
||||
Q_ASSERT(m_graphicsOverlayListModel);
|
||||
#endif // LTS_DEBUG
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (! m_orderOfGraphicalOverlays.contains(technicalLayerTypeLocal))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " m_logicalName='" << m_logicalName << "'"
|
||||
<< " not allowed: technicalLayerType=" << technicalLayerTypeLocal;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
Esri::ArcGISRuntime::GraphicsOverlay *graphicsLayer = nullptr;
|
||||
|
||||
const QString &esriLayerName = LogicalLayer::createInternalLayerName(m_logicalName, technicalLayerTypeLocal);
|
||||
|
||||
// lookup in own container:
|
||||
if (m_graphicOverlayContainer.contains(esriLayerName))
|
||||
{
|
||||
graphicsLayer = m_graphicOverlayContainer[esriLayerName];
|
||||
|
||||
// make sure, that layer is still valid (within esri/model):
|
||||
if (graphicsLayer)
|
||||
{
|
||||
if (! m_graphicsOverlayListModel->contains(graphicsLayer))
|
||||
{
|
||||
m_graphicOverlayContainer.remove(esriLayerName);
|
||||
graphicsLayer = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create if not found
|
||||
if (! graphicsLayer)
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION
|
||||
<< " requested (logical) layername ='" << m_logicalName << "' not in esriMap"
|
||||
<< ", create on demand..."
|
||||
<< " (renderMode=" << m_graphicsOverlayRenderingMode << ")";
|
||||
graphicsLayer = createGraphicLayer(technicalLayerTypeLocal, m_graphicsOverlayRenderingMode);
|
||||
|
||||
//
|
||||
// post operations:
|
||||
//
|
||||
|
||||
// apply LayerParameters (visible, opca, brightness....)
|
||||
this->applyLayerParameterToEsri();
|
||||
|
||||
// trigger re-ordering
|
||||
emit layerCreatedOnDemand(m_logicalName);
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||||
<< " technicalLayerType=" << technicalLayerType;
|
||||
return graphicsLayer;
|
||||
}
|
||||
|
||||
void LogicalLayer::onLayerError(const Esri::ArcGISRuntime::Error &error)
|
||||
{
|
||||
if (error.code() == 404)
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " EsriError occured: " << error
|
||||
<< ", layerName=" << m_layerParameter.url.toString();
|
||||
else
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " EsriError occured: " << error
|
||||
<< ", layerName=" << m_layerParameter.url.toString();
|
||||
}
|
||||
|
||||
void LogicalLayer::onGraphicsOverlayLayerError(const Esri::ArcGISRuntime::Error &error)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " EsriError occured: " << error
|
||||
<< ", layerName=" << m_layerParameter.url.toString();
|
||||
}
|
||||
|
||||
void LogicalLayer::onRendererError(const Esri::ArcGISRuntime::Error &error)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " EsriError occured: " << error
|
||||
<< ", layerName=" << m_layerParameter.url.toString();
|
||||
}
|
||||
|
||||
void LogicalLayer::onLayerDoneLoading(const Esri::ArcGISRuntime::Error &loadError)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " m_logicalName='" << m_logicalName << "'";
|
||||
|
||||
if (!loadError.isEmpty())
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " m_logicalName='" << m_logicalName << "'"
|
||||
<< ", layerName = '" << m_layerParameter.url.toString() << "'"
|
||||
<< ", loadError: " << loadError;
|
||||
|
||||
Esri::ArcGISRuntime::Layer *layer = qobject_cast<Esri::ArcGISRuntime::Layer *>(sender());
|
||||
if (layer)
|
||||
{
|
||||
const int maxRetry = 2;
|
||||
if (m_retryCounter<=maxRetry)
|
||||
{
|
||||
++m_retryCounter;
|
||||
QTimer::singleShot(1000 + (m_retryCounter+1000), this, std::bind(&Esri::ArcGISRuntime::Layer::retryLoad, layer));
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " schedule retryLoad for '" << m_logicalName << "'" << " (m_retryCounter=" << m_retryCounter << ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " max number of retries (" << maxRetry << ") exceeded, give up" << ", m_logicalName='" << m_logicalName << "'";
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION
|
||||
<< " qobject_cast failed m_logicalName='" << m_logicalName << "'";
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Esri::ArcGISRuntime::Layer *layer = qobject_cast<Esri::ArcGISRuntime::Layer *>(sender());
|
||||
if (!layer)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION
|
||||
<< " qobject_cast failed m_logicalName='" << m_logicalName << "'";
|
||||
return;
|
||||
}
|
||||
|
||||
// Esri::ArcGISRuntime::Item *item = layer->item();
|
||||
// if (!item)
|
||||
// FATAL_LOG(m_logger) << LOGFUNCTION << " no item!!!! " << m_logicalName << "'";
|
||||
|
||||
|
||||
const QString layername(layer->name());
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " esriLayer of LogicalLayer: '" << layername << "' is loaded now #1: ESRI-Layer: "
|
||||
<< " minScale()=" << layer->minScale()
|
||||
<< ", maxScale()=" << layer->maxScale()
|
||||
<< " (m_retryCounter=" << m_retryCounter << ")";
|
||||
|
||||
// minScale, maxScale at 3D returns always '0' for basemaps, so skip
|
||||
if ((m_layerType == LayerType::Basemap) && (m_map->mode() == Mode::Mode_2D))
|
||||
{
|
||||
if (!m_layerParameter.minScaleValid())
|
||||
m_layerParameter.minScale = layer->minScale();
|
||||
if (!m_layerParameter.minMaxScaleValid())
|
||||
m_layerParameter.maxScale = layer->maxScale();
|
||||
}
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " esriLayer of LogicalLayer: '" << layername << "' is loaded now #2: LogicalLayer"
|
||||
<< ", minScale = " << m_layerParameter.minScale
|
||||
<< ", maxScale = " << m_layerParameter.maxScale;
|
||||
|
||||
Esri::ArcGISRuntime::ArcGISTiledLayer *arcGISTiledLayer = qobject_cast<Esri::ArcGISRuntime::ArcGISTiledLayer *>(sender());
|
||||
if (arcGISTiledLayer)
|
||||
{
|
||||
const Esri::ArcGISRuntime::ArcGISMapServiceInfo &mapSvcInfo = arcGISTiledLayer->mapServiceInfo();
|
||||
if (m_layerParameter.displayName.isEmpty()) // if not already set use mapName of Service
|
||||
m_layerParameter.displayName = mapSvcInfo.mapName();
|
||||
m_layerParameter.description = mapSvcInfo.description();
|
||||
m_layerParameter.svcDescription = mapSvcInfo.serviceDescription();
|
||||
} // if (arcGISTiledLayer)
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " doneLoading: '" << layername << "'"
|
||||
<< " new m_layerParameter:" << m_layerParameter;
|
||||
|
||||
|
||||
// maybe the para weren`t applied because not loaded..
|
||||
// so do it here (again);
|
||||
applyLayerParameterToEsri();
|
||||
|
||||
// trigger reCalulation of minMaxScale:
|
||||
emit layerDoneLoading(m_logicalName);
|
||||
|
||||
// trigger update of gui:
|
||||
emit layerParameterChanged(m_logicalName, m_layerParameter);
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " doneLoading: '" << layername << "'";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void LogicalLayer::onLayerLoadStatusChanged(const Esri::ArcGISRuntime::LoadStatus &loadStatus)
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " START" << " m_logicalName='" << m_logicalName << "'"
|
||||
<< " new loadStatus=" << loadStatus;
|
||||
}
|
||||
|
||||
|
||||
Esri::ArcGISRuntime::GraphicsOverlay *LogicalLayer::createGraphicLayer(const TechnicalLayerType &technicalLayerType,
|
||||
RenderingMode renderingMode)
|
||||
{
|
||||
Esri::ArcGISRuntime::GraphicsOverlay *graphicalOverlay =
|
||||
createGraphicLayerInternal(technicalLayerType, renderingMode);
|
||||
|
||||
if (technicalLayerType != TechnicalLayerType::GraphicsLayer_Dict)
|
||||
return graphicalOverlay;
|
||||
|
||||
// get access to esri dictionary:
|
||||
const AdvancedSymbology::SymbolDictionary &dict = m_map->symbolDictionary();
|
||||
const AdvancedSymbology::SymbolDictionaryImpl &dictImpl = static_cast<const AdvancedSymbology::SymbolDictionaryImpl &>(dict);
|
||||
Esri::ArcGISRuntime::DictionarySymbolStyle *esriDict = const_cast<Esri::ArcGISRuntime::DictionarySymbolStyle *>(dictImpl.getEsriSymbolDictionary());
|
||||
|
||||
if (!esriDict)
|
||||
return graphicalOverlay;
|
||||
|
||||
// make sure, that dict is already loaded:
|
||||
if (esriDict->loadStatus() == Esri::ArcGISRuntime::LoadStatus::Loaded)
|
||||
{
|
||||
// create renderer
|
||||
Esri::ArcGISRuntime::DictionaryRenderer *dictRenderer =
|
||||
new Esri::ArcGISRuntime::DictionaryRenderer(esriDict, this);
|
||||
|
||||
// Handle errors of DictionaryRenderer:
|
||||
connect(dictRenderer, &Esri::ArcGISRuntime::DictionaryRenderer::errorOccurred,
|
||||
this, &LogicalLayer::onRendererError);
|
||||
|
||||
dictRenderer->setTextVisible(true);
|
||||
|
||||
// set Renderer to layer:
|
||||
|
||||
// take care that the old one is deleted:
|
||||
Esri::ArcGISRuntime::Renderer *oldRenderer = graphicalOverlay->renderer();
|
||||
if (oldRenderer)
|
||||
{
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " replace/destroy/remove old renderer, is this intended???";
|
||||
oldRenderer->deleteLater(); // Qt-Doc: 'It is safe to call this function more than once;'
|
||||
}
|
||||
// assign new:
|
||||
graphicalOverlay->setRenderer(dictRenderer);
|
||||
INFO_LOG(m_logger) << LOGFUNCTION
|
||||
<< " requested (logical) layername ='" << m_logicalName << "' -> with Renderer"
|
||||
<< " of symbologyType=" << dict.symbologyType();
|
||||
}
|
||||
else
|
||||
{
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " SymbolDictionary not loaded!!!";
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " SymbolDictionary not loaded!!!";
|
||||
FATAL_LOG(m_logger) << LOGFUNCTION << " SymbolDictionary not loaded!!!";
|
||||
// do not return 'nullptr' to avoid crash on further operations
|
||||
}
|
||||
return graphicalOverlay;
|
||||
}
|
||||
|
||||
QString LogicalLayer::createInternalLayerName(const QString &logicalLayerName, const TechnicalLayerType &technicalLayerType)
|
||||
{
|
||||
return logicalLayerName + QLatin1Char('#') + toString(technicalLayerType);
|
||||
}
|
||||
|
||||
Esri::ArcGISRuntime::GraphicsOverlay *LogicalLayer::createGraphicLayerInternal(const TechnicalLayerType &technicalLayerType,
|
||||
RenderingMode renderingMode)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " m_logicalName='" << m_logicalName << "'"
|
||||
<< " technicalLayerType=" << technicalLayerType
|
||||
<< " m_graphicalOverlays.size()=" << m_graphicalOverlays.size()
|
||||
<< " m_graphicsOverlayListModel.size()=" << m_graphicsOverlayListModel->size();
|
||||
|
||||
if (! m_graphicsOverlayListModel)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no m_graphicsOverlayListModel";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const QString &esriLayername = createInternalLayerName(m_logicalName, technicalLayerType);
|
||||
|
||||
Esri::ArcGISRuntime::GraphicsOverlay *graphicalOverlay =
|
||||
new Esri::ArcGISRuntime::GraphicsOverlay();
|
||||
|
||||
graphicalOverlay->setOverlayId(esriLayername);
|
||||
|
||||
static long s_counter = 0;
|
||||
graphicalOverlay->setObjectName(QStringLiteral("GraphicsOverlay_%1_'%2'").arg(s_counter++).arg(esriLayername));
|
||||
connect(graphicalOverlay, &Esri::ArcGISRuntime::GraphicsOverlay::destroyed, this, [this, graphicalOverlay] () {
|
||||
INFO_LOG(m_logger) << " GraphicsOverlay is destroyed , objectName='" << graphicalOverlay->objectName() << "'";
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Extrusion requires
|
||||
// a) GraphicsRenderingMode::Dynamic and
|
||||
// b) SurfacePlacement::Relative
|
||||
|
||||
if (technicalLayerType == TechnicalLayerType::GraphicsLayer_3D_Extrusion)
|
||||
{
|
||||
graphicalOverlay->setRenderingMode(Esri::ArcGISRuntime::GraphicsRenderingMode::Dynamic);
|
||||
} else {
|
||||
switch (renderingMode)
|
||||
{
|
||||
case RenderingMode::Dynamic:
|
||||
graphicalOverlay->setRenderingMode(Esri::ArcGISRuntime::GraphicsRenderingMode::Dynamic);
|
||||
break;
|
||||
case RenderingMode::Static:
|
||||
graphicalOverlay->setRenderingMode(Esri::ArcGISRuntime::GraphicsRenderingMode::Static);
|
||||
break;
|
||||
default:
|
||||
// empty
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if ACRGIS_VERSION < 0x640500 // 100.5.0 / Update 5
|
||||
// deprecated in V100.5, replaced by GeoView::setSelectionProperties()
|
||||
graphicalOverlay->setSelectionColor(Qt::magenta);
|
||||
#endif // ACRGIS_VERSION
|
||||
|
||||
m_graphicalOverlays.append(graphicalOverlay);
|
||||
m_graphicsOverlayListModel->append(graphicalOverlay);
|
||||
|
||||
// store it for lookup in own container:
|
||||
m_graphicOverlayContainer[esriLayername] = graphicalOverlay;
|
||||
|
||||
|
||||
// set SurfacePlacement
|
||||
Esri::ArcGISRuntime::LayerSceneProperties lsp = graphicalOverlay->sceneProperties();
|
||||
|
||||
|
||||
// Extrusion requires
|
||||
// a) GraphicsRenderingMode::Dynamic and
|
||||
// b) SurfacePlacement::Relative
|
||||
|
||||
if (technicalLayerType == TechnicalLayerType::GraphicsLayer_3D_Extrusion)
|
||||
lsp.setSurfacePlacement(Esri::ArcGISRuntime::SurfacePlacement::Relative);
|
||||
else if (technicalLayerType == TechnicalLayerType::GraphicsLayer_3D_Absolute)
|
||||
lsp.setSurfacePlacement(Esri::ArcGISRuntime::SurfacePlacement::Absolute);
|
||||
else
|
||||
lsp.setSurfacePlacement(static_cast<Esri::ArcGISRuntime::SurfacePlacement>(m_surfacePlacement)); // save due to static_assert
|
||||
graphicalOverlay->setSceneProperties(lsp);
|
||||
|
||||
Esri::ArcGISRuntime::GraphicsRenderingMode esriRenderingMode = graphicalOverlay->renderingMode();
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " created GraphicsOverlay: "
|
||||
<< " logicalName='" << m_logicalName << "'"
|
||||
<< " technicalLayerType=" << technicalLayerType
|
||||
<< " esriLayerName='" << esriLayername << "'"
|
||||
<< " esriRenderModeStr=" << esriRenderingMode // Check operator
|
||||
<< " surfacePlacement=" << m_surfacePlacement
|
||||
<< " curIdx=" << m_graphicsOverlayListModel->indexOf(graphicalOverlay)
|
||||
<< " graphicalOverlay=" << graphicalOverlay;
|
||||
|
||||
// Handle errors of layer:
|
||||
connect(graphicalOverlay, &Esri::ArcGISRuntime::GraphicsOverlay::errorOccurred,
|
||||
this, &LogicalLayer::onGraphicsOverlayLayerError);
|
||||
|
||||
// GraphicsOverlay need no doneLoading :-)
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||||
<< " m_logicalName='" << m_logicalName << "'"
|
||||
<< " technicalLayerType=" << technicalLayerType
|
||||
<< " m_graphicalOverlays.size()=" << m_graphicalOverlays.size()
|
||||
<< " m_graphicsOverlayListModel.size()=" << m_graphicsOverlayListModel->size();
|
||||
return graphicalOverlay;
|
||||
}
|
||||
|
||||
void LogicalLayer::applyLayerParameterToEsri()
|
||||
{
|
||||
int graphicsOverlayListModelSize = -1;
|
||||
|
||||
if (m_graphicsOverlayListModel)
|
||||
graphicsOverlayListModelSize = m_graphicsOverlayListModel->size();
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " m_logicalName='" << m_logicalName << "'"
|
||||
<< " m_layer=" << m_layer
|
||||
<< " m_graphicalOverlays.size()=" << m_graphicalOverlays.size()
|
||||
<< " m_graphicsOverlayListModel.size()=" << graphicsOverlayListModelSize
|
||||
<< " lp=" << m_layerParameter;
|
||||
|
||||
// process Layer (e.g. Basemap)
|
||||
// Esri::ArcGISRuntime::Layer
|
||||
Esri::ArcGISRuntime::Layer *esriLayer = m_layer;
|
||||
if (esriLayer)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " m_logicalName='" << m_logicalName << "'"
|
||||
<< " CURRENT loadStatus =" << esriLayer->loadStatus();
|
||||
if (esriLayer->loadStatus() != Esri::ArcGISRuntime::LoadStatus::Loaded)
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " not loaded yet, skip"
|
||||
<< " m_logicalName='" << m_logicalName << "'"
|
||||
<< " m_layer=" << m_layer
|
||||
<< " lp=" << m_layerParameter;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
esriLayer->setVisible(m_layerParameter.visible);
|
||||
esriLayer->setOpacity(m_layerParameter.opacity / 100.0f);
|
||||
|
||||
if (m_layerParameter.minScaleValid())
|
||||
esriLayer->setMinScale(m_layerParameter.minScale);
|
||||
else
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " minScale not valid, set to '0'"
|
||||
<< " m_logicalName='" << m_logicalName << "'";
|
||||
esriLayer->setMinScale(0);
|
||||
}
|
||||
|
||||
// Sonderfall (leider)
|
||||
// Für 3D wird maxScale hart auf '0' gesetzt, damit beim Neigen keine basemap
|
||||
// (besser basemapkachel) ausgeblendet wird.
|
||||
if ((m_layerType == LayerType::Basemap) &&
|
||||
(m_map->mode() == Mode::Mode_3D)
|
||||
)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " set maxScale to '0', because Basemap and Mode_3D for: "
|
||||
<< "m_logicalName='" << m_logicalName << "'";
|
||||
esriLayer->setMaxScale(0);
|
||||
} else {
|
||||
if (m_layerParameter.maxScaleValid())
|
||||
esriLayer->setMaxScale(m_layerParameter.maxScale);
|
||||
else
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " maxScale not valid, set to '0'"
|
||||
<< " m_logicalName='" << m_logicalName << "'";
|
||||
esriLayer->setMaxScale(0);
|
||||
}
|
||||
} // : Sonderfall
|
||||
|
||||
// for layer supporting bightness, contrast, gamma:
|
||||
if (esriLayer->layerType() == Esri::ArcGISRuntime::LayerType::ArcGISTiledLayer)
|
||||
{
|
||||
Esri::ArcGISRuntime::ArcGISTiledLayer *tiledLayer =
|
||||
static_cast<Esri::ArcGISRuntime::ArcGISTiledLayer *>(esriLayer);
|
||||
|
||||
tiledLayer->setBrightness(m_layerParameter.brightness);
|
||||
tiledLayer->setContrast(m_layerParameter.contrast);
|
||||
tiledLayer->setGamma(m_layerParameter.gamma);
|
||||
}
|
||||
} // if (esriLayer)
|
||||
|
||||
|
||||
// process GraphicsOverlay
|
||||
for (Esri::ArcGISRuntime::GraphicsOverlay *graphicsOverlay : qAsConst(m_graphicalOverlays))
|
||||
{
|
||||
graphicsOverlay->setVisible(m_layerParameter.visible);
|
||||
graphicsOverlay->setOpacity(m_layerParameter.opacity / 100.0);
|
||||
|
||||
if (m_layerParameter.minScaleValid())
|
||||
graphicsOverlay->setMinScale(m_layerParameter.minScale);
|
||||
if (m_layerParameter.maxScaleValid())
|
||||
graphicsOverlay->setMaxScale(m_layerParameter.maxScale);
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||||
<< " m_logicalName='" << m_logicalName << "'";
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogicalLayer::setOrderOfGraphicalOverlays(const QVector<TechnicalLayerType> &orderOfGraphicalOverlays)
|
||||
{
|
||||
m_orderOfGraphicalOverlays = orderOfGraphicalOverlays;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
QLatin1String toString(const TechnicalLayerType &value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case TechnicalLayerType::GraphicsLayer:
|
||||
return QLatin1String("GraphicsLayer");
|
||||
case TechnicalLayerType::GraphicsLayer_Dict:
|
||||
return QLatin1String("GraphicsLayer_Dict");
|
||||
case TechnicalLayerType::GraphicsLayer_3D_Extrusion:
|
||||
return QLatin1String("GraphicsLayer_3DExtrusion");
|
||||
case TechnicalLayerType::GraphicsLayer_3D_Absolute:
|
||||
return QLatin1String("GraphicsLayer_3D_Absolute");
|
||||
}
|
||||
|
||||
return QLatin1String("TechnicalLayerTypeERROR");
|
||||
}
|
||||
|
||||
|
||||
std::ostream &operator<<(std::ostream &stream, const TechnicalLayerType &value)
|
||||
{
|
||||
stream << toString(value).latin1();
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
} // namespace SituationMap
|
||||
Reference in new issue
Block a user