Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

@@ -0,0 +1,556 @@
/**
* @RDE_HEADER@
* Declaration/Definition
* $Id$
* $HeadURL$
* $Author$
*/
#include "Viewshed.h"
// Qt
#include <QDebug>
#include <QDialog>
#include <QPushButton>
#include <QGridLayout>
#include <QLabel>
#include <QMessageBox>
// Esri
#include <arcgis/ArcGISRuntime.h>
#include <arcgis/MapGraphicsView.h>
#include <arcgis/SimpleMarkerSymbol.h>
#include <arcgis/SimpleFillSymbol.h>
#include <arcgis/UserCredentials.h>
#include <arcgis/ProxySetup.h>
// Uncomment if needed
//#include <Graphic.h>
//#include <SimpleMarkerSymbol.h>
//#include <PictureMarkerSymbol.h>
//#include <Point.h>
//#include <Polyline.h>
//#include <MultiPath.h>
//#define USE_SAMPLE_SERVER
EsriRuntimeQt::SpatialReference sr(102100);
mainwindow::mainwindow(QWidget *parent)
: QMainWindow(parent)
{
m_map = new EsriRuntimeQt::Map(this);
connect(m_map, SIGNAL(mapReady()), this, SLOT(onMapReady()));
m_mapGraphicsView = EsriRuntimeQt::MapGraphicsView::create(m_map, this);
setCentralWidget(m_mapGraphicsView);
m_map->setWrapAroundEnabled(false);
// create and add the tiled layer
EsriRuntimeQt::ArcGISTiledMapServiceLayer* mapServiceLayer =
new EsriRuntimeQt::ArcGISTiledMapServiceLayer(QLatin1String("http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer"), this);
m_map->addLayer(mapServiceLayer);
QString path = EsriRuntimeQt::ArcGISRuntime::installDirectory();
path.append(QLatin1String("/sdk/samples/data"));
QDir dataDir(path); // using QDir to convert to correct file separator
QString pathSampleData = dataDir.path() + QDir::separator();
qDebug() << " installDirectory='" << path << "'";
QString tiledBaseMapLayer = pathSampleData + QLatin1String("tpks/Topographic.tpk");
qDebug() << " tiledBaseMapLayer='" << tiledBaseMapLayer << "'";
// m_tiledLayer = new EsriRuntimeQt::ArcGISLocalTiledLayer(tiledBaseMapLayer, this);
// m_tiledLayer->setName( QLatin1String("ArcGISLocalTiledLayer") );
// m_map->addLayer(m_tiledLayer);
// Create Graphics Layer
m_graphicsLayer = new EsriRuntimeQt::GraphicsLayer(this);
m_graphicsLayer -> setName(QLatin1String("GraphicsLayer"));
m_map->addLayer(m_graphicsLayer);
// {
// //
// // Create red circle at maps origin
// //
// EsriRuntimeQt::Point nullPoint(0, 0, m_map->spatialReference());
// EsriRuntimeQt::SimpleMarkerSymbol redCircle(Qt::red, 20, EsriRuntimeQt::SimpleMarkerSymbolStyle::Circle);
// EsriRuntimeQt::Graphic* graphic1 = new EsriRuntimeQt::Graphic( nullPoint, redCircle);
// qint64 gId = m_graphicsLayer->addGraphic(graphic1);
// //
// // Get access to graphic and hide: -> Works fine :-)
// //
// EsriRuntimeQt::Graphic* graphicRetrieved = m_graphicsLayer->graphic(gId);
// if (graphicRetrieved)
// {
// graphicRetrieved->setVisible(false);
// } else {
// qWarning() << LOGFUNCTION << "could NOT retrieve graphic" ;
// }
// }
QString url;
#ifdef USE_SAMPLE_SERVER
url = QLatin1String("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Elevation/ESRI_Elevation_World/GPServer/Viewshed");
#else
url = QLatin1String("http://elevation.arcgis.com/arcgis/rest/services/Tools/Elevation/GPServer/Viewshed");
#endif
qDebug() << LOGFUNCTION << " url='" << url << "'";
// create a Geoprocessor that points to the remote geoprocessing service.
EsriRuntimeQt::UserCredentials *ucEsri = new EsriRuntimeQt::UserCredentials;
ucEsri->setUserAccount("norbert.thoden", "RDEESRI7");
m_geoprocessor = new EsriRuntimeQt::Geoprocessor(url,
ucEsri,
this);
connect(m_geoprocessor,
SIGNAL(gpError(const EsriRuntimeQt::ServiceError&)), this,
SLOT(onGpError(const EsriRuntimeQt::ServiceError&)));
#ifdef USE_SAMPLE_SERVER
connect(m_geoprocessor,
SIGNAL(gpExecuteComplete(const QList<EsriRuntimeQt::GPParameter*>&)), this,
SLOT(onGpExecuteComplete(const QList<EsriRuntimeQt::GPParameter*>&)));
#else
connect(m_geoprocessor,
SIGNAL(gpSubmitJobComplete(const EsriRuntimeQt::GPJobResource&)), this,
SLOT(onGpSubmitJobComplete(const EsriRuntimeQt::GPJobResource&)));
// used:
connect(m_geoprocessor,
SIGNAL(gpJobStatusComplete(const EsriRuntimeQt::GPJobResource&)), this,
SLOT(onGpJobStatusComplete(const EsriRuntimeQt::GPJobResource&)));
// used:
connect(m_geoprocessor,
SIGNAL(gpResultComplete(EsriRuntimeQt::GPParameter*)), this,
SLOT(onGpResultComplete(EsriRuntimeQt::GPParameter*)));
// unused!?
connect(m_geoprocessor,
SIGNAL(gpServiceInfoComplete(EsriRuntimeQt::GPServiceInfo)), this,
SLOT(onGpServiceInfoComplete(EsriRuntimeQt::GPServiceInfo)));
// unused!?
connect(m_geoprocessor,
SIGNAL(gpSubmitJobAndGetResultComplete(const EsriRuntimeQt::GPJobResource&, const QList<EsriRuntimeQt::GPParameter*>&)), this,
SLOT(onGpSubmitJobAndGetResultComplete(const EsriRuntimeQt::GPJobResource&, const QList<EsriRuntimeQt::GPParameter*>&)));
// unused!?
connect(m_geoprocessor,
SIGNAL(statusUpdated(const EsriRuntimeQt::GPJobResource&, const QList<EsriRuntimeQt::GPMessage>&)), this,
SLOT(onStatusUpdated(const EsriRuntimeQt::GPJobResource&, const QList<EsriRuntimeQt::GPMessage>&)));
// unused!?
connect(m_geoprocessor,
SIGNAL(gpTaskInfoComplete(EsriRuntimeQt::GPTaskInfo)), this,
SLOT(onGpTaskInfoComplete(const EsriRuntimeQt::GPTaskInfo&)));
#endif
// connect signals
connect(m_map, SIGNAL(mapReady()), this, SLOT(onMapReady()));
connect(m_map, SIGNAL(mousePressRelease(QMouseEvent&)), this, SLOT(onMousePressRelease(QMouseEvent&)));
// // set up progress bar
// m_progressDialog = new QProgressDialog();
// m_progressDialog->setBaseSize(280, 20);
// m_progressDialog->setRange(0, 0);
// m_progressDialog->setValue(0);
// m_progressDialog->setCancelButton(0);
// connect(m_mapGraphicsView->scene(), SIGNAL(sceneRectChanged(QRectF)), this, SLOT(onResizeProgressBar()));
// m_progressDialog->setLabelText("");
// m_progressDialog->setAttribute(Qt::WA_NoBackground);
// m_progressDialog->setAutoFillBackground(false);
// m_progressDialog->setVisible(false);
// WidgetPanel* widget = new WidgetPanel();
// QLabel* instructionsLabel = new QLabel(
// QString("Click on the map to set the viewshed point. The viewshed will be computed ") +
// QString("from the specified buffer area around the viewshed point. "));
// instructionsLabel->setWordWrap(true);
// QFont font;
// font.setPixelSize(11);
// instructionsLabel->setFont(font);
// instructionsLabel->setMargin(5);
// instructionsLabel->setObjectName("instructions");
// instructionsLabel->setStyleSheet("QLabel#instructions { background: rgba(0,0,0, 192); color: #ddd; }");
// instructionsLabel->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding));
//
// QVBoxLayout* layout = new QVBoxLayout();
// layout->setMargin(0);
//// layout->addWidget(instructionsLabel, Qt::AlignLeft);
// QHBoxLayout* horizontalBox = new QHBoxLayout();
// horizontalBox->setMargin(1);
// QFont font;
// font.setPixelSize(12);
// QLabel* distanceLabel = new QLabel("Viewshed Buffer (miles):");
// distanceLabel->setFixedSize(180, 25);
// distanceLabel->setFont(font);
// distanceLabel->setMargin(5);
// horizontalBox->addWidget(distanceLabel, Qt::AlignRight);
// m_textDistanceLineEdit = new QLineEdit("9");
// m_textDistanceLineEdit->setFixedSize(60, 25);
// m_textDistanceLineEdit->setFont(font);
// horizontalBox->addWidget(m_textDistanceLineEdit, Qt::AlignLeft);
// layout->addLayout(horizontalBox);
//// widget->setFixedSize(210, 105);
//// widget->setLayout(layout);
// QGraphicsProxyWidget *proxy = m_mapGraphicsView->scene()->addWidget(widget);
// proxy->setPos(10, 10);
// proxy->setAcceptedMouseButtons(Qt::LeftButton);
// proxy->setFlag(QGraphicsItem::ItemIsFocusable, true);
// proxy->setFlag(QGraphicsItem::ItemIsSelectable, true);
// proxy->setFlag(QGraphicsItem::ItemAcceptsInputMethod, true);
// proxy->setOpacity(0.85);
// m_proxyProgressBar = m_mapGraphicsView->scene()->addWidget(m_progressDialog);
// m_proxyProgressBar->setAcceptedMouseButtons(Qt::NoButton);
// m_proxyProgressBar->setFlag(QGraphicsItem::ItemIsSelectable, false);
// m_viewShed = new
// SituationMap::ViewshedBase(
// m_geoprocessor->url()
// , *m_graphicsLayer,
// this);
// bool init = m_viewShed->init();
// qDebug() << LOGFUNCTION << " init=" << init;
} /* mainwindow::mainwindow */
mainwindow::~mainwindow()
{
}
void mainwindow::onMapReady()
{
qDebug() << LOGFUNCTION << " ready";
// m_map->setExtent(EsriRuntimeQt::Envelope(-10000, -10000, 10000, 10000, sr));
m_map->setExtent(EsriRuntimeQt::Envelope(-13386516, 4516694, -13236394, 4616827, m_map->spatialReference()));
m_srMap = m_map->spatialReference();
}
void mainwindow::onMousePressRelease(QMouseEvent &event)
{
qDebug() << LOGFUNCTION;
if (event.button() != Qt::LeftButton)
return;
if (m_inProgress)
return;
QPoint scenePosition = event.pos();
// // make sure the mouse didn't move - if so it was a pan so do nothing
// QGraphicsItem * graphicsItem = nullptr;
// graphicsItem = itemFromQGraphicsScene(m_mapGraphicsView->scene(), scenePosition);
// if (graphicsItem)
// return; // Clicked item box
// remove viewshed from previous computation
m_graphicsLayer->removeAll();
int inputValue = 10;
// inputValue = m_textDistanceLineEdit->text().toInt();
if (inputValue > 12 || inputValue < 1)
{
if (m_progressDialog)
m_progressDialog->setVisible(false);
QMessageBox::warning(this, "Invalid Distance", "Please enter an integer from 1 to 12.");
return;
}
// the click point is the viewshed point
EsriRuntimeQt::Point viewshedPoint = m_map->toMapPoint(scenePosition.x(), scenePosition.y());
qDebug() << LOGFUNCTION<< " esriViewshedPoint.x=" << viewshedPoint.x()
<< " ;y=" << viewshedPoint.y()
<< " wkid=" << viewshedPoint.spatialReference().wkid()
<< " m_inProgress=" << m_inProgress
;
// make sure it is a point on the map
if (!EsriRuntimeQt::GeometryEngine::within(viewshedPoint, m_map->extent()))
return;
m_inProgress = true;
if (m_progressDialog)
{
m_progressDialog->setLabelText("Computing the viewshed...");
m_progressDialog->setVisible(true);
}
EsriRuntimeQt::Graphic* viewshedPointGraphic = new EsriRuntimeQt::Graphic(viewshedPoint, EsriRuntimeQt::SimpleMarkerSymbol(QColor("Black"), 14, EsriRuntimeQt::SimpleMarkerSymbolStyle::X));
m_graphicsLayer->addGraphic(viewshedPointGraphic);
// initialize the input parameters. refer to help link in the geoprocessing service URL.
m_geoprocessor->setProcessSR(m_srMap);
m_geoprocessor->setOutSR(m_srMap);
QList<EsriRuntimeQt::GPParameter*> gpInputParams;
#ifdef USE_SAMPLE_SERVER
EsriRuntimeQt::GPFeatureRecordSetLayer* gpInputViewshedPoint =
new EsriRuntimeQt::GPFeatureRecordSetLayer("Input_Observation_Point", this);
#else
EsriRuntimeQt::GPFeatureRecordSetLayer* gpInputViewshedPoint =
new EsriRuntimeQt::GPFeatureRecordSetLayer("InputPoints", this);
#endif
gpInputViewshedPoint->setSpatialReference(m_srMap);
gpInputViewshedPoint->addGraphic(qobject_cast<EsriRuntimeQt::Graphic*>(viewshedPointGraphic->clone(this)));
#ifdef USE_SAMPLE_SERVER
EsriRuntimeQt::GPLinearUnit* gpInputViewshedDistance =
new EsriRuntimeQt::GPLinearUnit("Viewshed_Distance", this);
gpInputViewshedDistance->setUnits("esriMiles");
gpInputViewshedDistance->setDistance(inputValue);
gpInputParams.append(gpInputViewshedPoint);
gpInputParams.append(gpInputViewshedDistance);
#else
EsriRuntimeQt::GPDouble* gpInputMaxDistance =
new EsriRuntimeQt::GPDouble("MaximumDistance", this);
gpInputMaxDistance->setValue(inputValue);
EsriRuntimeQt::GPString* gpInputMaxDistanceUnits =
new EsriRuntimeQt::GPString("MaximumDistanceUnits", this);
gpInputMaxDistanceUnits->setValue(QLatin1String("Miles"));
EsriRuntimeQt::GPDouble* gpInputObserverHeight =
new EsriRuntimeQt::GPDouble("ObserverHeight", this);
gpInputObserverHeight->setValue(3000); // [Meter]
EsriRuntimeQt::GPBoolean* gpInputGeneralize =
new EsriRuntimeQt::GPBoolean("GeneralizeViewshedPolygons", this);
gpInputGeneralize->setValue(false);
gpInputParams.append(gpInputViewshedPoint);
gpInputParams.append(gpInputMaxDistance);
gpInputParams.append(gpInputMaxDistanceUnits);
gpInputParams.append(gpInputObserverHeight);
// gpInputParams.append(gpInputGeneralize);
#endif
// execute the geoprocessing request
// -------------------------------------------------------------------------------------
// Option 1 - execute sync
// Client execution will happen in this thread. It will be blocked on server.
// Client side result collection will happen in this thread. It will be blocked on server.
//
// This is ideal for jobs that take less processing time and whose result size is small.
// This will freeze the UI.
// -------------------------------------------------------------------------------------
/*QList<EsriRuntimeQt::GPParameter*> result = m_geoprocessor->execute(gpInputParams);
processResult(result);*/
// -------------------------------------------------------------------------------------
// Option 2 - execute async
// Client execution will happen in a new thread. It will be blocked on server.
// Client side result collection will happen on that thread. It will be blocked on server.
//
// This is ideal for jobs that take relatively more processing time than option 1
// and whose result size is small.
// -------------------------------------------------------------------------------------
// m_geoprocessor->execute(gpInputParams);
m_geoprocessor->setStatusPollingInterval(10);
#ifdef USE_SAMPLE_SERVER
m_geoprocessor->execute( gpInputParams );
#else
m_geoprocessor->submitJob(gpInputParams);
#endif
}
void mainwindow::onGpExecuteComplete(const QList<EsriRuntimeQt::GPParameter *> &result)
{
qDebug() << LOGFUNCTION << " result.size()=" << result.size();
foreach (EsriRuntimeQt::GPParameter* outputParameter, result)
{
if (!outputParameter)
continue;
EsriRuntimeQt::GPFeatureRecordSetLayer* gpLayer = qobject_cast<EsriRuntimeQt::GPFeatureRecordSetLayer*>(outputParameter);
if (gpLayer)
{
qDebug() << LOGFUNCTION << " gpLayer->graphics().size=" << gpLayer->graphics().size();
// get all the graphics and add them to the graphics layer.
foreach (EsriRuntimeQt::Graphic* resultGraphic, gpLayer->graphics())
{
EsriRuntimeQt::Graphic* theGraphic = new EsriRuntimeQt::Graphic(resultGraphic->geometry(), EsriRuntimeQt::SimpleFillSymbol(QColor(255, 0, 0, 80), EsriRuntimeQt::SimpleFillSymbolStyle::Solid, EsriRuntimeQt::SimpleLineSymbol(QColor("Red"), 0.5)));
// add to the graphics layer
m_graphicsLayer->addGraphic(theGraphic);
}
}
outputParameter->deleteLater();
}
if (m_progressDialog)
m_progressDialog->setVisible(false);
m_inProgress = false;
}
void mainwindow::onGpError(const EsriRuntimeQt::ServiceError &error)
{
if (m_progressDialog)
m_progressDialog->setVisible(false);
qWarning() << LOGFUNCTION << QString("Service Error, code: %1, message: %2, details: %3").arg(QString::number(error.code()), error.message(), error.details());
m_inProgress = false;
}
void mainwindow::onGpSubmitJobComplete(const EsriRuntimeQt::GPJobResource &jobResource)
{
qWarning() << "\n";
qWarning() << LOGFUNCTION << " isEmpty=" << jobResource.isEmpty();
qWarning() << LOGFUNCTION << " jobId='" << jobResource.jobId() << "'";
qWarning() << LOGFUNCTION << " jobStatus='" << (int)jobResource.jobStatus() << "'";
qWarning() << LOGFUNCTION << " inputParameters().size()='" << (int)jobResource.inputParameters().size() << "'";
qWarning() << LOGFUNCTION << " outputParameters().size()='" << (int)jobResource.outputParameters().size() << "'";
qWarning() << LOGFUNCTION << " messages().size()='" << (int)jobResource.messages().size() << "'";
delete m_timer;
m_timer = new QTimer;
connect(m_timer, &QTimer::timeout, [=]() {
qWarning() << " jobStatus() ...";
m_geoprocessor->jobStatus();
} );
qWarning() << "\n starting timer...";
m_timer->start(1000);
}
void mainwindow::onGpJobStatusComplete(const EsriRuntimeQt::GPJobResource &jobResource)
{
qWarning() << "\n";
qWarning() << LOGFUNCTION << " isEmpty=" << jobResource.isEmpty();
qWarning() << LOGFUNCTION << " jobId='" << jobResource.jobId() << "'";
qWarning() << LOGFUNCTION << " jobStatus='" << (int)jobResource.jobStatus() << "'";
qWarning() << LOGFUNCTION << " inputParameters().size()='" << (int)jobResource.inputParameters().size() << "'";
qWarning() << LOGFUNCTION << " outputParameters().size()='" << (int)jobResource.outputParameters().size() << "'";
qWarning() << LOGFUNCTION << " messages().size()='" << (int)jobResource.messages().size() << "'";
if (jobResource.jobStatus() == EsriRuntimeQt::JobStatus::Succeeded)
{
qWarning() << " Succeeded :-)";
if (m_timer)
m_timer->stop();
m_geoprocessor->result(jobResource,
QLatin1String("OutputViewshed"),
true); // GetAsImageResult
}
}
void mainwindow::onGpResultComplete(EsriRuntimeQt::GPParameter *outputParameter)
{
qWarning() << "\n";
qWarning() << LOGFUNCTION << " outputParameter=" << outputParameter;
if (outputParameter)
{
EsriRuntimeQt::GPFeatureRecordSetLayer* gpLayer = qobject_cast<EsriRuntimeQt::GPFeatureRecordSetLayer*>(outputParameter);
if (gpLayer)
{
qDebug() << LOGFUNCTION << " gpLayer->graphics().size=" << gpLayer->graphics().size();
// get all the graphics and add them to the graphics layer.
foreach (EsriRuntimeQt::Graphic* resultGraphic, gpLayer->graphics())
{
EsriRuntimeQt::Graphic* theGraphic =
new EsriRuntimeQt::Graphic(resultGraphic->geometry(),
EsriRuntimeQt::SimpleFillSymbol(QColor(0, 255, 0, 80), EsriRuntimeQt::SimpleFillSymbolStyle::Solid,
EsriRuntimeQt::SimpleLineSymbol(QColor("Red"), 0.5)));
// add to the graphics layer
m_graphicsLayer->addGraphic(theGraphic);
}
}
outputParameter->deleteLater();
}
}
void mainwindow::onGpServiceInfoComplete(EsriRuntimeQt::GPServiceInfo serviceInfo)
{
qWarning() << "\n";
qWarning() << LOGFUNCTION ;
}
void mainwindow::onGpSubmitJobAndGetResultComplete(const EsriRuntimeQt::GPJobResource &, const QList<EsriRuntimeQt::GPParameter *> &results)
{
qWarning() << "\n";
qWarning() << LOGFUNCTION ;
}
void mainwindow::onStatusUpdated(const EsriRuntimeQt::GPJobResource &jobResource, const QList<EsriRuntimeQt::GPMessage> &msgList)
{
qWarning() << "\n";
qWarning() << LOGFUNCTION << " isEmpty=" << jobResource.isEmpty();
qWarning() << LOGFUNCTION << " jobId='" << jobResource.jobId() << "'";
qWarning() << LOGFUNCTION << " jobStatus='" << (int)jobResource.jobStatus() << "'";
qWarning() << LOGFUNCTION << " inputParameters().size()='" << (int)jobResource.inputParameters().size() << "'";
qWarning() << LOGFUNCTION << " outputParameters().size()='" << (int)jobResource.outputParameters().size() << "'";
qWarning() << LOGFUNCTION << " messages().size()='" << (int)jobResource.messages().size() << "'";
qWarning() << LOGFUNCTION << " 2 msgList().size()='" << msgList.size() << "'";
m_geoprocessor->jobStatus();
}
void mainwindow::onGpTaskInfoComplete(const EsriRuntimeQt::GPTaskInfo &)
{
qWarning() << "\n";
qWarning() << LOGFUNCTION ;
}