570 lines
22 KiB
C++
Executable File
570 lines
22 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* ViewshedGeoProcessing
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*/
|
|
|
|
// Own
|
|
#include "viewshed_geo_processing.h"
|
|
|
|
#include "map_impl.h"
|
|
#include <GraphicalObjects/graphical_object_path.h>
|
|
#include <Map/situation_map_utils.h>
|
|
#include <MapImpl/layer_factory_impl.h>
|
|
#include <LtsWidgets/lts_global_wait_dialog.h>
|
|
|
|
|
|
// ESRI
|
|
#include <arcgis/Map.h>
|
|
#include <arcgis/GraphicsOverlay.h>
|
|
#include <arcgis/Graphic.h>
|
|
#include <arcgis/GeoprocessingTask.h>
|
|
#include <arcgis/GeoprocessingJob.h>
|
|
#include <arcgis/GeoprocessingFeatures.h>
|
|
#include <arcgis/GeoprocessingRaster.h>
|
|
#include <arcgis/GeoprocessingParameter.h>
|
|
#include <arcgis/GeoprocessingParameters.h>
|
|
#include <arcgis/GeoprocessingResult.h>
|
|
#include <arcgis/FeatureCollectionTable.h>
|
|
#include <arcgis/Feature.h>
|
|
#include <arcgis/SimpleMarkerSymbol.h>
|
|
#include <arcgis/SimpleFillSymbol.h>
|
|
|
|
#include <arcgis/GeoprocessingLinearUnit.h>
|
|
#include <arcgis/ImageServiceRaster.h>
|
|
#include <arcgis/RasterLayer.h>
|
|
#include <arcgis/GeometryEngine.h>
|
|
|
|
// Qt
|
|
#include <QDebug>
|
|
#include <QMessageBox>
|
|
|
|
|
|
namespace SituationMap
|
|
{
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// class ViewshedBase
|
|
//-----------------------------------------------------------------------------
|
|
ViewshedGeoProcessing::ViewshedGeoProcessing(const QString &url,
|
|
Esri::ArcGISRuntime::GraphicsOverlay *graphicsLayer,
|
|
const Esri::ArcGISRuntime::SpatialReference &spatialReference,
|
|
QObject *parent)
|
|
: ViewshedBase(parent)
|
|
, m_url(url)
|
|
, m_resultsOverlay(graphicsLayer)
|
|
, m_srMap(spatialReference)
|
|
, m_logger(getLogger("ViewshedGeoProcessing"))
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
|
}
|
|
|
|
ViewshedGeoProcessing::~ViewshedGeoProcessing()
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
|
clearGraphics();
|
|
delete m_viewshedTask;
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
|
}
|
|
|
|
bool ViewshedGeoProcessing::init(SituationMap::MapImpl *mapImpl)
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
|
|
|
// check viewshedContraint (V100.2.1: disable usage of GPU to avoid failure:
|
|
/*
|
|
2018-03-21 13:06:15.911 ERROR ViewshedGeoProcessing |#| void SituationMap::ViewshedGeoProcessing::onErrorOccuredGeoprocessingJob(const Esri::ArcGISRuntime::Error &) GeoprocessingJob -> EsriError occured: sender= 'GeoprocessingJob', code=400, domain=0, extendedErrorType=0, message='Unable to complete operation.', additionalMessage='Error executing tool. Viewshed2Feature : ERROR 010151: No features found in C:\users\ctc\Temp\arcgisruntime_8\LegatusBremen201803151510.gpk\jobs\_\j5a4e467cb51047c28a463a703c2f2bcd\scratch\scratch.gdb\Viewshed_Polygon. Possible empty feature class.
|
|
Failed to execute (Raster to Polygon).
|
|
Failed to execute (Viewshed2Feature).
|
|
Failed to execute (Viewshed2Feature).' (pl/viewshed_geo_processing.cpp:529)
|
|
2018-03-21 13:06:15.911 ERROR Qt |#| Geoprocessing Task failed (ication/ngl_qt_msg_handler.inc:26)
|
|
2018-03-21 13:06:15.911 ERROR Qt |#| Geoprocessing Task failed message: code = 400 domain = 0 message = "Unable to complete operation." additionalMessage = "Error executing tool. Viewshed2Feature : ERROR 010151: No features found in C:\\users\\ctc\\Temp\\arcgisruntime_8\\LegatusBremen201803151510.gpk\\jobs\\_\\j5a4e467cb51047c28a463a703c2f2bcd\\scratch\\scratch.gdb\\Viewshed_Polygon. Possible empty feature class.\nFailed to execute (Raster to Polygon).\nFailed to execute (Viewshed2Feature).\nFailed to execute (Viewshed2Feature)." extendedErrorType = 0 (ication/ngl_qt_msg_handler.inc:26)
|
|
2018-03-21 13:06:15.911 INFO ViewshedGeoProcessing |#| void SituationMap::ViewshedGeoProcessing::onJobStatusChanged() jobStatusChanged is now (m_jobStatus): Job failed (pl/viewshed_geo_processing.cpp:256)
|
|
*/
|
|
|
|
{
|
|
const char cuda[] = "CUDA_VISIBLE_DEVICES";
|
|
bool ok = qEnvironmentVariableIsSet(cuda) &&
|
|
(qEnvironmentVariableIsEmpty(cuda) || qEnvironmentVariableIntValue(cuda) == -1);
|
|
|
|
if (ok)
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " VIEWSHED_CONTRAINT fulfilled: "
|
|
<< cuda << " = '" << qgetenv(cuda) << "'";
|
|
else
|
|
{
|
|
FATAL_LOG(m_logger) << LOGFUNCTION << " VIEWSHED_CONTRAINT NOT fulfilled: " << cuda << " = '" << qgetenv(cuda) << "'";
|
|
|
|
QMessageBox::critical(nullptr,
|
|
tr("Configuration Error"),
|
|
tr("Environmentvariable '%1' is not set to deactivate GPU. Operations can fail").arg(QString::fromLatin1(cuda)),
|
|
QMessageBox::Ok);
|
|
}
|
|
}
|
|
|
|
|
|
if (m_url.isEmpty())
|
|
{
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " url is empty";
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
|
return false;
|
|
}
|
|
|
|
m_mapImpl = mapImpl; // mapImpl is required only if processRasterResults is used
|
|
|
|
delete m_viewshedTask;
|
|
m_viewshedTask = new Esri::ArcGISRuntime::GeoprocessingTask(QUrl(m_url), this);
|
|
m_viewshedTask->setObjectName(QLatin1String("GeoprocessingTask"));
|
|
|
|
// Handle errors of GeoprocessingTask:
|
|
connect(m_viewshedTask, &Esri::ArcGISRuntime::GeoprocessingTask::errorOccurred,
|
|
this, &ViewshedGeoProcessing::onErrorOccuredGeoprocessingTask);
|
|
|
|
m_initialized = true;
|
|
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_initialized=" << m_initialized;
|
|
return m_initialized;
|
|
}
|
|
|
|
|
|
bool ViewshedGeoProcessing::execute(const QPointF &viewshedPoint_map, double outerRadius, double observerOffset)
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
|
<< " viewshedPoint_map=" << viewshedPoint_map
|
|
<< " m_srMap.wkid=" << m_srMap.wkid()
|
|
<< " outerRadius=" << outerRadius
|
|
<< " observerOffset=" << observerOffset
|
|
<< " m_viewshedInProgress=" << m_viewshedInProgress
|
|
<< " url='" << m_url << "'";
|
|
|
|
// check point is the viewshed point
|
|
Esri::ArcGISRuntime::Point esriViewshedPoint(viewshedPoint_map.x(), viewshedPoint_map.y(), m_srMap); // Esri::ArcGISRuntime::SpatialReference::webMercator());
|
|
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " esriViewshedPoint.toJson: " << esriViewshedPoint.toJson();
|
|
|
|
m_viewshedInProgress = true;
|
|
|
|
createInputGraphic(esriViewshedPoint);
|
|
createExtentGraphic(esriViewshedPoint, outerRadius);
|
|
clearResultGraphics();
|
|
|
|
// Create a new feature collection table based upon point geometries using the current map view spatial reference
|
|
Esri::ArcGISRuntime::FeatureCollectionTable *inputFeatures =
|
|
new Esri::ArcGISRuntime::FeatureCollectionTable(QList<Esri::ArcGISRuntime::Field>()
|
|
, Esri::ArcGISRuntime::GeometryType::Point
|
|
, m_srMap
|
|
, this);
|
|
|
|
// Create a new feature from the feature collection table. It will not have a coordinate location (x,y) yet
|
|
Esri::ArcGISRuntime::Feature *inputFeature = inputFeatures->createFeature(this);
|
|
|
|
// Assign a physical location to the new point feature based upon where the user clicked on the map view
|
|
inputFeature->setGeometry(esriViewshedPoint);
|
|
|
|
// connect to addFeature status changed signal
|
|
connect(inputFeatures, &Esri::ArcGISRuntime::FeatureCollectionTable::addFeatureCompleted, this, [this, inputFeatures, outerRadius, observerOffset](QUuid, bool success)
|
|
{
|
|
INFO_LOG(m_logger) << LOGFUNCTION << " addFeatureCompleted...";
|
|
|
|
if (!success)
|
|
{
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " no success";
|
|
return;
|
|
}
|
|
|
|
// Create the parameters that are passed to the used geoprocessing task
|
|
Esri::ArcGISRuntime::GeoprocessingParameters viewshedParameters =
|
|
Esri::ArcGISRuntime::GeoprocessingParameters(Esri::ArcGISRuntime::GeoprocessingExecutionType::SynchronousExecute); // AsynchronousSubmit | SynchronousExecute
|
|
// GeoprocessingExecutionType should match Esri::ArcGISRuntime::GeoprocessingServiceType of LocalGeoprocessingService
|
|
|
|
|
|
// Request the output features to use the same SpatialReference as the map view
|
|
viewshedParameters.setOutputSpatialReference(m_srMap);
|
|
|
|
// Add an input location to the geoprocessing parameters
|
|
QMap<QString, Esri::ArcGISRuntime::GeoprocessingParameter *> inputs;
|
|
inputs[QLatin1String("Input_point_or_polyline_observer_features")] = new Esri::ArcGISRuntime::GeoprocessingFeatures(inputFeatures, this);
|
|
|
|
// Radius
|
|
inputs[QLatin1String("Inner_radius")] = new Esri::ArcGISRuntime::GeoprocessingLinearUnit(55.0, Esri::ArcGISRuntime::GeoprocessingLinearUnits::Meter, this);
|
|
inputs[QLatin1String("Outer_radius")] = new Esri::ArcGISRuntime::GeoprocessingLinearUnit(outerRadius, Esri::ArcGISRuntime::GeoprocessingLinearUnits::Meter, this);
|
|
|
|
// Observer
|
|
// //!!! DO NOT DEFINE, keep elevation of ellipsoid in mind // inputs[QLatin1String("Observer_elevation")] = new Esri::ArcGISRuntime::GeoprocessingLinearUnit(0.0, Esri::ArcGISRuntime::GeoprocessingLinearUnits::Meter, this);
|
|
inputs[QLatin1String("Observer_offset")] = new Esri::ArcGISRuntime::GeoprocessingLinearUnit(observerOffset, Esri::ArcGISRuntime::GeoprocessingLinearUnits::Meter, this);
|
|
|
|
// Target
|
|
inputs[QLatin1String("Surface_offset")] = new Esri::ArcGISRuntime::GeoprocessingLinearUnit(0.0, Esri::ArcGISRuntime::GeoprocessingLinearUnits::Meter, this);
|
|
|
|
// setInputs
|
|
viewshedParameters.setInputs(inputs);
|
|
|
|
// Print geoprocessingParameters for debugging purpose:
|
|
QMapIterator<QString, Esri::ArcGISRuntime::GeoprocessingParameter *> inputsIt(inputs);
|
|
while (inputsIt.hasNext())
|
|
{
|
|
inputsIt.next();
|
|
QString value(QLatin1String("-"));
|
|
Esri::ArcGISRuntime::GeoprocessingParameter *gpPara = inputsIt.value();
|
|
Esri::ArcGISRuntime::GeoprocessingLinearUnit *gpParaLU = dynamic_cast<Esri::ArcGISRuntime::GeoprocessingLinearUnit *>(gpPara);
|
|
if (gpParaLU)
|
|
value = QStringLiteral("%1 %2").arg(gpParaLU->distance()).arg(gpParaLU->linearUnit().name());
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " key= '" << inputsIt.key() << "'" << " value= '" << value << "'";
|
|
} // while
|
|
|
|
|
|
|
|
// Create the job that handles the communication between the application and the geoprocessing task
|
|
m_viewshedJob = m_viewshedTask->createJob(viewshedParameters);
|
|
m_viewshedJob->setObjectName(QLatin1String("GeoprocessingJob"));
|
|
|
|
// Handle errors of GeoprocessingJob:
|
|
connect(m_viewshedJob, &Esri::ArcGISRuntime::GeoprocessingJob::errorOccurred, this, &ViewshedGeoProcessing::onErrorOccuredGeoprocessingJob);
|
|
|
|
// Create signal handler for the job
|
|
|
|
#if ACRGIS_VERSION >= 0x640E00 // 100.14.0
|
|
// since V100.14
|
|
connect(m_viewshedJob, &Esri::ArcGISRuntime::GeoprocessingJob::statusChanged, this, &ViewshedGeoProcessing::onJobStatusChangedWithJsParameter);
|
|
#else
|
|
// until V100.14:
|
|
connect(m_viewshedJob, &Esri::ArcGISRuntime::GeoprocessingJob::jobStatusChanged, this, &ViewshedGeoProcessing::onJobStatusChanged);
|
|
#endif // ACRGIS_VERSION
|
|
|
|
|
|
// start the job
|
|
if (m_viewshedJob->start())
|
|
LtsWidgets::LtsGlobalWaitDialog::getInstance()->wait();
|
|
else
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " viewshedJob->start() failed";
|
|
|
|
});
|
|
// Add the new feature with (x,y) location to the feature collection table
|
|
inputFeatures->addFeature(inputFeature);
|
|
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_viewshedInProgress=" << m_viewshedInProgress;
|
|
return true;
|
|
}
|
|
|
|
void ViewshedGeoProcessing::onJobStatusChanged()
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
|
|
|
// qCritical() << "jobStatusChanged... viewshedJob->jobStatus()=" << (int)viewshedJob->jobStatus();
|
|
|
|
bool viewshedInProgressOld = m_viewshedInProgress;
|
|
|
|
switch (m_viewshedJob->jobStatus())
|
|
{
|
|
case Esri::ArcGISRuntime::JobStatus::NotStarted:
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << "Geoprocessing Task failed";
|
|
m_viewshedInProgress = false;
|
|
m_jobStatus = QLatin1String("Job NotStarted");
|
|
break;
|
|
case Esri::ArcGISRuntime::JobStatus::Failed:
|
|
{
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << "Geoprocessing Task failed";
|
|
|
|
const Esri::ArcGISRuntime::Error &err = m_viewshedJob->error();
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << "Geoprocessing Task failed message: " << err;
|
|
|
|
m_viewshedInProgress = false;
|
|
m_jobStatus = QLatin1String("Job failed");
|
|
}
|
|
break;
|
|
case Esri::ArcGISRuntime::JobStatus::Started:
|
|
m_viewshedInProgress = true;
|
|
m_jobStatus = QLatin1String("Job in progress...");
|
|
break;
|
|
case Esri::ArcGISRuntime::JobStatus::Paused:
|
|
m_viewshedInProgress = false;
|
|
m_jobStatus = QLatin1String("Job paused...");
|
|
break;
|
|
case Esri::ArcGISRuntime::JobStatus::Succeeded:
|
|
m_viewshedInProgress = false;
|
|
m_jobStatus = QLatin1String("Job succeeded");
|
|
// handle the results
|
|
processResults(m_viewshedJob->result());
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " jobStatusChanged is now (m_jobStatus): " << m_jobStatus;
|
|
|
|
if ((m_viewshedInProgress == false) && (viewshedInProgressOld != m_viewshedInProgress))
|
|
LtsWidgets::LtsGlobalWaitDialog::getInstance()->done();
|
|
|
|
// emit signals
|
|
// emit viewshedInProgressChanged();
|
|
// emit jobStatusChanged();
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
|
}
|
|
|
|
#if ACRGIS_VERSION >= 0x640E00 // 100.14.0
|
|
void ViewshedGeoProcessing::onJobStatusChangedWithJsParameter(const Esri::ArcGISRuntime::JobStatus &/*newStatus*/)
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
|
onJobStatusChanged();
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
|
}
|
|
#endif // ACRGIS_VERSION
|
|
|
|
|
|
bool ViewshedGeoProcessing::processResults(Esri::ArcGISRuntime::GeoprocessingResult *results)
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
|
|
|
if (!results)
|
|
{
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " no results";
|
|
return false;
|
|
}
|
|
|
|
const QMap<QString, Esri::ArcGISRuntime::GeoprocessingParameter *> &outputsMap = results->outputs();
|
|
|
|
if (outputsMap.isEmpty())
|
|
{
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " no keys, outputsMap is empty ";
|
|
return false;
|
|
}
|
|
|
|
// clear graphics:
|
|
clearResultGraphics();
|
|
|
|
|
|
QString key;
|
|
|
|
key = QStringLiteral("Output_polygon_features");
|
|
if (outputsMap.contains(key))
|
|
{
|
|
// Get the results from the outputs as GeoprocessingFeatures
|
|
Esri::ArcGISRuntime::GeoprocessingFeatures *viewshedResultFeatures =
|
|
static_cast<Esri::ArcGISRuntime::GeoprocessingFeatures *>(outputsMap[key]);
|
|
|
|
return processFeatureResults(viewshedResultFeatures);
|
|
}
|
|
|
|
key = QStringLiteral("Output_raster");
|
|
if (outputsMap.contains(key))
|
|
{
|
|
Esri::ArcGISRuntime::GeoprocessingRaster *viewshedResultRaster =
|
|
static_cast<Esri::ArcGISRuntime::GeoprocessingRaster *>(outputsMap[key]);
|
|
return processRasterResults(viewshedResultRaster);
|
|
}
|
|
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " failure, no known keyword found in outputsMap"
|
|
<< ", outputsMap.size() " << outputsMap.size();
|
|
return false;
|
|
}
|
|
|
|
bool ViewshedGeoProcessing::processFeatureResults(Esri::ArcGISRuntime::GeoprocessingFeatures *viewshedResultFeatures)
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " processFeatureResults";
|
|
|
|
if (!viewshedResultFeatures)
|
|
{
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " no viewshedResultFeatures";
|
|
return false;
|
|
}
|
|
|
|
Esri::ArcGISRuntime::SimpleFillSymbol sfsVisi (Esri::ArcGISRuntime::SimpleFillSymbolStyle::Solid, QColor(0, 226, 0, 255), this);
|
|
Esri::ArcGISRuntime::SimpleFillSymbol sfsInVisi(Esri::ArcGISRuntime::SimpleFillSymbolStyle::Solid, QColor(226, 0, 0, 255), this);
|
|
|
|
// Add all the features from the result feature set as a graphics to the map
|
|
Esri::ArcGISRuntime::FeatureIterator features = viewshedResultFeatures->features()->iterator();
|
|
while (features.hasNext())
|
|
{
|
|
Esri::ArcGISRuntime::Feature *feat = features.next(this);
|
|
|
|
const QString &attKey(QLatin1String("gridcode"));
|
|
if (feat->attributes()->containsAttribute(attKey))
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " attributes()->attributeValue=== " << feat->attributes()->attributeValue(attKey).toString();
|
|
|
|
if (feat->attributes()->attributeValue(attKey).toInt())
|
|
m_resultGraphics.append(new Esri::ArcGISRuntime::Graphic(feat->geometry(), &sfsVisi));
|
|
else
|
|
m_resultGraphics.append(new Esri::ArcGISRuntime::Graphic(feat->geometry(), &sfsInVisi));
|
|
|
|
// ERROR_LOG(m_logger) << LOGFUNCTION << " attributeValue " << feat->attributes()->attributeValue(attKey).toInt();
|
|
} else
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " no key attributeValue ";
|
|
|
|
}
|
|
|
|
// transfer from own container to resultsOverlay:
|
|
m_resultsOverlay->graphics()->append(m_resultGraphics);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ViewshedGeoProcessing::processRasterResults(Esri::ArcGISRuntime::GeoprocessingRaster *viewshedResultRaster)
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " viewshedResultRaster -> url = " << viewshedResultRaster->url().toString();
|
|
|
|
connect(viewshedResultRaster, &Esri::ArcGISRuntime::GeoprocessingRaster::fetchFileCompleted, this, [this] (QUuid, const QString& filePath) {
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " filePath=" << filePath;
|
|
|
|
Esri::ArcGISRuntime::Raster *raster = new Esri::ArcGISRuntime::Raster(filePath, this);
|
|
if (!raster)
|
|
{
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " raster failed";
|
|
return;
|
|
}
|
|
connect(raster, &Esri::ArcGISRuntime::Raster::errorOccurred, this, [this] (const Esri::ArcGISRuntime::Error &error) {
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " raster EsriError occured: " << error;
|
|
});
|
|
connect(raster, &Esri::ArcGISRuntime::Raster::loadStatusChanged, this, [this, raster] (Esri::ArcGISRuntime::LoadStatus loadStatus) {
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " raster loadStatus=" << loadStatus;
|
|
|
|
if (loadStatus == Esri::ArcGISRuntime::LoadStatus::Loaded)
|
|
{
|
|
|
|
|
|
Esri::ArcGISRuntime::RasterLayer *rl = new Esri::ArcGISRuntime::RasterLayer(raster, this);
|
|
if (!rl)
|
|
{
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " rl failed";
|
|
return;
|
|
}
|
|
connect(rl, &Esri::ArcGISRuntime::RasterLayer::errorOccurred, this, [this] (const Esri::ArcGISRuntime::Error &error) {
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " RasterLayer EsriError occured: " << error;
|
|
});
|
|
connect(rl, &Esri::ArcGISRuntime::RasterLayer::loadStatusChanged, this, [this] (Esri::ArcGISRuntime::LoadStatus loadStatus) {
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " RasterLayer loadStatus=" << loadStatus;
|
|
});
|
|
|
|
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " getEsriMap()->operationalLayers()->size" << m_mapImpl->getEsriMap()->operationalLayers()->size();
|
|
m_mapImpl->getEsriMap()->operationalLayers()->append(rl);
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " getEsriMap()->operationalLayers()->size" << m_mapImpl->getEsriMap()->operationalLayers()->size();
|
|
|
|
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " rasterLayer loading ...";
|
|
rl->load();
|
|
}
|
|
});
|
|
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " raster loading ...";
|
|
raster->load();
|
|
});
|
|
|
|
Esri::ArcGISRuntime::TaskWatcher tw = viewshedResultRaster->fetchFile(QStringLiteral("/tmp/viewshedFetched.tif"));
|
|
if (!tw.isValid())
|
|
{
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " m_mapImpl failed";
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
void ViewshedGeoProcessing::clearGraphics()
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << this;
|
|
clearInputGraphics();
|
|
clearExtentGraphics();
|
|
clearResultGraphics();
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
|
}
|
|
|
|
void ViewshedGeoProcessing::createInputGraphic(const Esri::ArcGISRuntime::Point &origin)
|
|
{
|
|
if (!m_originGraphic)
|
|
{
|
|
m_originGraphic = new Esri::ArcGISRuntime::Graphic(this);
|
|
m_resultsOverlay->graphics()->append(m_originGraphic);
|
|
}
|
|
|
|
m_originGraphic->setGeometry(origin);
|
|
|
|
Esri::ArcGISRuntime::SimpleMarkerSymbol sms(Esri::ArcGISRuntime::SimpleMarkerSymbolStyle::Circle, QColor("red"), 12.0);
|
|
m_originGraphic->setSymbol(&sms);
|
|
m_originGraphic->setZIndex(std::numeric_limits<int>::max());
|
|
}
|
|
|
|
void ViewshedGeoProcessing::createExtentGraphic(const Esri::ArcGISRuntime::Point &origin, double radius)
|
|
{
|
|
if (!m_extentGraphic)
|
|
{
|
|
m_extentGraphic = new Esri::ArcGISRuntime::Graphic(this);
|
|
m_resultsOverlay->graphics()->append(m_extentGraphic);
|
|
}
|
|
|
|
const Esri::ArcGISRuntime::Polygon &circlePoly = Esri::ArcGISRuntime::GeometryEngine::buffer(origin, radius); // circlePoly.parts().part(0).pointCount(); -> 96
|
|
|
|
m_extentGraphic->setGeometry(circlePoly);
|
|
|
|
Esri::ArcGISRuntime::SimpleLineSymbol sls(Esri::ArcGISRuntime::SimpleLineSymbolStyle::Solid, QColor("red"), 3.0);
|
|
m_extentGraphic->setSymbol(&sls);
|
|
m_extentGraphic->setZIndex(std::numeric_limits<int>::max());
|
|
}
|
|
|
|
void ViewshedGeoProcessing::clearInputGraphics()
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << this;
|
|
if (m_originGraphic)
|
|
{
|
|
m_resultsOverlay->graphics()->removeOne(m_originGraphic);
|
|
delete m_originGraphic;
|
|
m_originGraphic = nullptr;
|
|
}
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
|
}
|
|
|
|
void ViewshedGeoProcessing::clearExtentGraphics()
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << this;
|
|
if (m_extentGraphic)
|
|
{
|
|
m_resultsOverlay->graphics()->removeOne(m_extentGraphic);
|
|
delete m_extentGraphic;
|
|
m_extentGraphic = nullptr;
|
|
}
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
|
}
|
|
|
|
|
|
void ViewshedGeoProcessing::clearResultGraphics()
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << this;
|
|
|
|
for (auto graphic : qAsConst(m_resultGraphics))
|
|
{
|
|
m_resultsOverlay->graphics()->removeOne(graphic);
|
|
delete graphic;
|
|
}
|
|
m_resultGraphics.clear();
|
|
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
|
}
|
|
|
|
void ViewshedGeoProcessing::onErrorOccuredGeoprocessingTask(const Esri::ArcGISRuntime::Error &error)
|
|
{
|
|
QString senderName;
|
|
Esri::ArcGISRuntime::GeoprocessingTask *senderObj = qobject_cast<Esri::ArcGISRuntime::GeoprocessingTask *>(sender());
|
|
if (senderObj)
|
|
senderName = senderObj->objectName();
|
|
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " GeoprocessingTask -> EsriError occured: " << error
|
|
<< ", sender= '" << senderName << "'";
|
|
}
|
|
|
|
void ViewshedGeoProcessing::onErrorOccuredGeoprocessingJob(const Esri::ArcGISRuntime::Error &error)
|
|
{
|
|
QString senderName;
|
|
Esri::ArcGISRuntime::GeoprocessingJob *senderObj = qobject_cast<Esri::ArcGISRuntime::GeoprocessingJob *>(sender());
|
|
if (senderObj)
|
|
senderName = senderObj->objectName();
|
|
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " GeoprocessingJob -> EsriError occured: " << error
|
|
<< ", sender= '" << senderName << "'";
|
|
}
|
|
|
|
|
|
} // namespace SituationMap
|