//PointToPointRouting_Example.h
#ifndef POINTTOPOINTROUTING_EXAMPLE_H
#define POINTTOPOINTROUTING_EXAMPLE_H
namespace EsriRuntimeQt
{
class MapGraphicsView;
class Map;
class ArcGISLocalTiledLayer;
class ArcGISTiledMapServiceLayer;
class ArcGISDynamicMapServiceLayer;
class ArcGISFeatureLayer;
class GraphicsLayer;
class FeatureLayer;
}
//Uncomment if needed
#include "LocalMapService.h"
#include "LocalFeatureService.h"
#include "GraphicsLayer.h"
#include <QPushButton>
#include <QMainWindow>
//for local geoprocessing service
#include "LocalGeoprocessingService.h"
#include "Geoprocessor.h"
class PointToPointRouting_Example : public QMainWindow
{
Q_OBJECT
public:
PointToPointRouting_Example (QWidget *parent = 0);
~PointToPointRouting_Example ();
public slots:
void onMapReady();
// void onFeatureServiceInfoComplete(const EsriRuntimeQt::FeatureServiceInfo& serviceInfo);
// void onLocalServiceCreationSuccess(const QString& url, const QString& name);
// void onLocalServiceCreationFailure(const QString& name);
// void onFeatureServiceCreationSuccess(const QString& url, const QString& name);
// void onFeatureServiceCreationFailure(const QString& name);
void onAddStartPoint();
void onAddEndPoint();
void onSolve();
void onServiceCreationSuccess(QString url, QString name);
void onServiceCreationFailure(QString name);
void onGpExecuteComplete(QList<EsriRuntimeQt::GPParameter*> &result);
void onGpError(EsriRuntimeQt::ServiceError error);
void onMousePress(QMouseEvent& event);
void onMouseRelease(QMouseEvent& event);
private:
void addStartPoint(EsriRuntimeQt::Point mapPoint);
void addEndPoint(EsriRuntimeQt::Point mapPoint);
EsriRuntimeQt::Map* m_map;
EsriRuntimeQt::MapGraphicsView* m_mapGraphicsView;
EsriRuntimeQt::ArcGISLocalTiledLayer* m_tiledLayer;
// UI elements
QPushButton* m_startPointBtn;
QPushButton* m_endPointBtn;
QPushButton* m_solveBtn;
// Bools to track user input
bool m_addingStartPoint;
bool m_addingEndPoint;
bool m_bRouteActive;
EsriRuntimeQt::GraphicsLayer* m_graphicsLayer;
EsriRuntimeQt::Graphic* m_grStartPoint;
EsriRuntimeQt::Graphic* m_grEndPoint;
EsriRuntimeQt::Graphic* m_grRouteLine;
EsriRuntimeQt::LocalGeoprocessingService* m_routingService;
EsriRuntimeQt::Geoprocessor* m_geoprocessor;
EsriRuntimeQt::SpatialReference m_srMap;
QPointF m_lastMouseCoord;
EsriRuntimeQt::ArcGISTiledMapServiceLayer* m_tiledServiceLayer;
// EsriRuntimeQt::ArcGISDynamicMapServiceLayer* m_dynamicServiceLayer;
// EsriRuntimeQt::LocalMapService m_localMapService;
// EsriRuntimeQt::ArcGISDynamicMapServiceLayer* m_dynamicLocalServiceLayer;
EsriRuntimeQt::LocalFeatureService m_localFeatureService;
// EsriRuntimeQt::ArcGISFeatureLayer* m_localFeatureLayer;
// EsriRuntimeQt::GraphicsLayer* m_graphicsLayer;
// EsriRuntimeQt::FeatureLayer* m_featureLayer;
int m_startID;
int m_endID;
int m_routeID;
};
#endif // POINTTOPOINTROUTING_EXAMPLE_H
//PointToPointRouting_Example.cpp
#include "PointToPointRouting_Example.h"
#include "MapGraphicsView.h"
#include "Map.h"
#include "ArcGISRuntime.h"
#include "Polyline.h"
#include <QMessageBox>
// Uncomment if needed
#include "ArcGISLocalTiledLayer.h"
#include "ArcGISTiledMapServiceLayer.h"
#include "ArcGISDynamicMapServiceLayer.h"
#include "ArcGISFeatureLayer.h"
#include "GraphicsLayer.h"
#include "Graphic.h"
#include "SimpleMarkerSymbol.h"
#include "Point.h"
#include "ServiceInfoTask.h"
#include "GeodatabaseFeatureServiceTable.h"
#include "FeatureLayer.h"
#include "GeometryEngine.h"
#include "SimpleLineSymbol.h"
#include "QVBoxLayout"
#include "QGraphicsProxyWidget"
PointToPointRouting_Example::PointToPointRouting_Example(QWidget *parent)
: QMainWindow(parent),
m_addingStartPoint(false),
m_addingEndPoint(false),
m_startID(-1),
m_endID(-1),
m_routeID(-1)
{
m_map = new EsriRuntimeQt::Map(this);
//// connect to signal that is emitted when the map is ready
//// the mapReady signal is emitted when the Map has obtained a
//// spatial reference from an added layer
connect(m_map, SIGNAL(mapReady()), this, SLOT(onMapReady()));
m_mapGraphicsView = EsriRuntimeQt::MapGraphicsView::create(m_map, this);
setCentralWidget(m_mapGraphicsView);
m_map->setWrapAroundEnabled(false);
QString path = EsriRuntimeQt::ArcGISRuntime::installDirectory();
path.append("/sdk/samples/data");
QDir dataDir(path); // using QDir to convert to correct file separator
QString pathSampleData = dataDir.path() + QDir::separator();
//geoprocessing package route
m_routingService = new EsriRuntimeQt::LocalGeoprocessingService(
pathSampleData + "gpks" + QDir::separator() +
"Routing" + QDir::separator() + "Route.gpk" );
m_routingService->setServiceType(EsriRuntimeQt::GPServiceType::Execute);
//// ArcGIS Online Tiled Basemap Layer
//m_tiledServiceLayer = new EsriRuntimeQt::ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer", this);
//m_map->addLayer(m_tiledServiceLayer);
//// Local Tiled Basemap Layer using: sdk/samples/data/tpks/SanFrancisco.tpk
QString tiledBaseMapLayer = pathSampleData + "tpks" + QDir::separator() + "SanFrancisco.tpk";
m_tiledLayer = new EsriRuntimeQt::ArcGISLocalTiledLayer(tiledBaseMapLayer, this);
m_map->addLayer(m_tiledLayer);
// create UI elements
QWidget* widget = new QWidget();
m_startPointBtn = new QPushButton("Start Point");
m_startPointBtn->setObjectName("m_startPointBtn");
m_startPointBtn->setStyleSheet("QPushButton#m_startPointBtn { background-color: white; color: #000; } QPushButton#m_startPointBtn:pressed {background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #dadbde, stop: 1 #f6f7fa);}");
connect(m_startPointBtn, SIGNAL(clicked()), this, SLOT(onAddStartPoint()));
m_endPointBtn = new QPushButton("End Point");
m_endPointBtn->setObjectName("m_endPointBtn");
m_endPointBtn->setStyleSheet("QPushButton#m_endPointBtn { background-color: white; color: #000; } QPushButton#m_endPointBtn:pressed {background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #dadbde, stop: 1 #f6f7fa);}");
connect(m_endPointBtn, SIGNAL(clicked()), this, SLOT(onAddEndPoint()));
m_solveBtn = new QPushButton("Solve");
m_solveBtn->setObjectName("m_solveBtn");
m_solveBtn->setStyleSheet("QPushButton#m_solveBtn { background-color: white; color: #000; }");
connect(m_solveBtn, SIGNAL(clicked()), this, SLOT(onSolve()));
m_startPointBtn->setEnabled(true);
m_endPointBtn->setEnabled(true);
m_solveBtn->setEnabled(false);
connect(m_routingService, SIGNAL(serviceCreationSuccess(QString,QString)), this, SLOT(onServiceCreationSuccess(QString,QString)));
connect(m_routingService, SIGNAL(serviceCreationFailure(QString)), this, SLOT(onServiceCreationFailure(QString)));
m_routingService->start();
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(m_startPointBtn);
layout->addWidget(m_endPointBtn);
layout->addWidget(m_solveBtn);
widget->setFixedSize(100,150);
widget->setLayout(layout);
widget->setPalette(QPalette(QPalette::Base));
QGraphicsProxyWidget *proxy = m_mapGraphicsView->scene()->addWidget(widget);
proxy->setPos(7, 7);
proxy->setAcceptedMouseButtons(Qt::LeftButton);
proxy->setFlag(QGraphicsItem::ItemIsSelectable, false);
proxy->setOpacity(0.75);
//// ArcGIS Online Dynamic Map Service Layer
//m_dynamicServiceLayer = new EsriRuntimeQt::ArcGISDynamicMapServiceLayer("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StateCityHighway_USA/MapSe...", this);
//m_map->addLayer(m_dynamicServiceLayer);
//Local Dynamic Layer using: sdk/samples/data/mpks/USCitiesStates.mpk
/*
QString dataPath = pathSampleData + "mpks" + QDir::separator() + "USCitiesStates.mpk";
m_localMapService = EsriRuntimeQt::LocalMapService(dataPath);
// connect to signal that is emitted when the service is created successfully
connect(&m_localMapService, SIGNAL(serviceCreationSuccess(const QString&, const QString&)), this, SLOT(onLocalServiceCreationSuccess(const QString&, const QString&)));
// connect to signal that is emitted when the service failed
connect(&m_localMapService, SIGNAL(serviceCreationFailure(const QString&)), this, SLOT(onLocalServiceCreationFailure(const QString&)));
// start the service and the Local Server
m_localMapService.start();
*/
// Feature service using: sdk/samples/data/mpks/USCitiesStates.mpk
/*
QString localFeatureService = pathSampleData + "mpks" + QDir::separator() + "USCitiesStates.mpk";
m_localFeatureService = EsriRuntimeQt::LocalFeatureService(localFeatureService);
m_localFeatureService.setMaximumRecords(3000);
// connect to signal that is emitted when the service is created successfully
connect(&m_localFeatureService, SIGNAL(serviceCreationSuccess(const QString&, const QString&)), this, SLOT(onFeatureServiceCreationSuccess(const QString&, const QString&)));
// connect to signal that is emitted when the service failed
connect(&m_localFeatureService, SIGNAL(serviceCreationFailure(const QString&)), this, SLOT(onFeatureServiceCreationFailure(const QString&)));
// start the service and the Local Server
m_localFeatureService.start();
*/
// Graphics Layer
//EsriRuntimeQt::Point point1(0, 0, m_map->spatialReference());
//EsriRuntimeQt::SimpleMarkerSymbol redCircle(Qt::red, 10, EsriRuntimeQt::SimpleMarkerSymbolStyle::Circle);
//EsriRuntimeQt::Graphic* graphic1 = new EsriRuntimeQt::Graphic(point1, redCircle);
m_graphicsLayer = new EsriRuntimeQt::GraphicsLayer(this);
//m_graphicsLayer->addGraphic(graphic1);
m_map->addLayer(m_graphicsLayer);
// connect mouse press signals
connect(m_map, SIGNAL(mousePress(QMouseEvent&)), this, SLOT(onMousePress(QMouseEvent&)));
connect(m_map, SIGNAL(mouseRelease(QMouseEvent&)), this, SLOT(onMouseRelease(QMouseEvent&)));
}
PointToPointRouting_Example::~PointToPointRouting_Example()
{
// stop the Local Map Service
/*
if(m_localMapService.status() == EsriRuntimeQt::LocalServiceStatus::Running)
m_localMapService.stopAndWait();
*/
// stop the Local Feature Service
/*
if(m_localFeatureService.status() == EsriRuntimeQt::LocalServiceStatus::Running)
m_localFeatureService.stopAndWait();
*/
// stop the Local Server Instance for local service
/*
if (EsriRuntimeQt::LocalServer::instance().isRunning())
EsriRuntimeQt::LocalServer::instance().shutdownAndWait();
*/
}
void PointToPointRouting_Example::onMapReady()
{
// set the map extent
m_map->setExtent(EsriRuntimeQt::Envelope(-122.520, 37.8365, -122.3023 , 37.6985, m_map->spatialReference()));
//// Feature Layer
//// Initialize the FeatureLayer with a GeodatabaseFeatureServiceTable after the Map has
//// obtained a spatial reference so its features can be projected correctly
//// specify the URL to create a Service Info Task to get a specific layer by name or id
//EsriRuntimeQt::ServiceInfoTask* serviceTaskInfo = new EsriRuntimeQt::ServiceInfoTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer", this);
//connect(serviceTaskInfo, SIGNAL(featureServiceInfoComplete(const EsriRuntimeQt::FeatureServiceInfo&)), this, SLOT(onFeatureServiceInfoComplete(const EsriRuntimeQt::FeatureServiceInfo&)));
//serviceTaskInfo->featureServiceInfo();
}
void PointToPointRouting_Example::onAddStartPoint()
{
m_addingStartPoint = true;
m_addingEndPoint = false;
}
void PointToPointRouting_Example::onAddEndPoint()
{
m_addingStartPoint = false;
m_addingEndPoint = true;
}
void PointToPointRouting_Example::onSolve()
{
// We will define this slot later...
if ((m_endID == -1)|| (m_startID == -1))
{
QMessageBox::warning(this, "Warning", "You need to add at least one start point and one end point to solve a route.", QMessageBox::Ok);
return;
}
// Reset the drawing bools
m_addingStartPoint = false;
m_addingEndPoint = false;
if (m_routeID != -1)
{
m_graphicsLayer->removeGraphic(m_routeID);
}
QList<EsriRuntimeQt::GPParameter*> parameters;
EsriRuntimeQt::GPFeatureRecordSetLayer* param = new EsriRuntimeQt::GPFeatureRecordSetLayer("Input_Locations", this);
param->setGeometryType(EsriRuntimeQt::GeometryType::Point);
param->setSpatialReference(m_srMap);
param->addGraphic(m_grStartPoint);
param->addGraphic(m_grEndPoint);
parameters.append(param);
m_geoprocessor->execute(parameters);
}
void PointToPointRouting_Example::onServiceCreationSuccess(QString url, QString name)
{
Q_UNUSED(url);
Q_UNUSED(name);
// create a Geoprocessor that points to the geoprocessing service URL
QString urlService(m_routingService->urlGeoprocessingService());
m_geoprocessor = new EsriRuntimeQt::Geoprocessor( urlService + "/Route");
m_geoprocessor->setProcessSR(m_srMap);
m_geoprocessor->setOutSR(m_srMap);
disconnect(m_geoprocessor, SIGNAL(gpExecuteComplete(const QList<EsriRuntimeQt::GPParameter*>&)), this, SLOT(onGpExecuteComplete(QList<EsriRuntimeQt::GPParameter*>&)));
disconnect(m_geoprocessor, SIGNAL(gpError(EsriRuntimeQt::ServiceError)), this, SLOT(onGpError(EsriRuntimeQt::ServiceError)));
connect(m_geoprocessor, SIGNAL(gpExecuteComplete(const QList<EsriRuntimeQt::GPParameter*>&)), this, SLOT(onGpExecuteComplete(QList<EsriRuntimeQt::GPParameter*>&)));
connect(m_geoprocessor, SIGNAL(gpError(EsriRuntimeQt::ServiceError)), this, SLOT(onGpError(EsriRuntimeQt::ServiceError)));
m_bRouteActive = true;
}
void PointToPointRouting_Example::onServiceCreationFailure(QString name)
{
m_bRouteActive = false;
qWarning() << name + " failed to start";
qWarning() << m_routingService->error().what();
}
void PointToPointRouting_Example::onGpExecuteComplete(QList<EsriRuntimeQt::GPParameter*> &result)
{
foreach (EsriRuntimeQt::GPParameter* outputParameter, result)
{
EsriRuntimeQt::GPFeatureRecordSetLayer* gpLayer = qobject_cast<EsriRuntimeQt::GPFeatureRecordSetLayer*>(outputParameter);
if (!gpLayer)
continue;
// get all the graphics and add them to the graphics layer.
foreach (EsriRuntimeQt::Graphic* resultGraphic, gpLayer->graphics())
{
EsriRuntimeQt::Graphic* grRouteLine = new EsriRuntimeQt::Graphic(resultGraphic->geometry(), EsriRuntimeQt::SimpleLineSymbol(QColor("black"), 2.0, EsriRuntimeQt::SimpleLineSymbolStyle::Dash));
// add to the graphics layer
m_routeID = m_graphicsLayer->addGraphic(grRouteLine);
m_graphicsLayer->sendToBack(m_routeID);
}
}
}
void PointToPointRouting_Example::onGpError(EsriRuntimeQt::ServiceError error)
{
qWarning() << QString("Service Error, code: %1, message: %2, details: %3").arg(QString::number(error.code()), error.message(), error.details());
}
void PointToPointRouting_Example::onMousePress(QMouseEvent& event)
{
// store the location of the mouse click
if (event.button() == Qt::LeftButton)
m_lastMouseCoord = QPointF(event.pos().x(), event.pos().y());
}
void PointToPointRouting_Example::onMouseRelease(QMouseEvent& event)
{
if (event.button() != Qt::LeftButton)
return;
QPointF scenePosition = event.pos();
// make sure the mouse didn't move - if so it was a pan so do nothing
if (m_lastMouseCoord.x() != scenePosition.x() || m_lastMouseCoord.y() != scenePosition.y())
return;
// Clicked in item box
if (m_mapGraphicsView->scene()->itemAt(scenePosition, QTransform()))
return;
EsriRuntimeQt::Point pt = m_map->toMapPoint(scenePosition.x(), scenePosition.y());
if (m_addingStartPoint)
{
addStartPoint(pt);
}
else if (m_addingEndPoint)
{
addEndPoint(pt);
}
if (m_startID != -1 && m_endID != -1)
m_solveBtn->setEnabled(true);
}
void PointToPointRouting_Example::addStartPoint(EsriRuntimeQt::Point mapPoint)
{
if (EsriRuntimeQt::GeometryEngine::within(mapPoint, m_map->extent()))
{
EsriRuntimeQt::SimpleMarkerSymbol purpleDiamond(QColor(102, 0, 187), 15, EsriRuntimeQt::SimpleMarkerSymbolStyle::Diamond);
purpleDiamond.setOutline(EsriRuntimeQt::SimpleLineSymbol(QColor("black"), 1.0, EsriRuntimeQt::SimpleLineSymbolStyle::Solid));
if (m_startID != -1)
{
m_graphicsLayer->removeGraphic(m_startID);
}
m_grStartPoint = new EsriRuntimeQt::Graphic(mapPoint, purpleDiamond);
m_startID = m_graphicsLayer->addGraphic(static_cast<EsriRuntimeQt::Graphic*>(m_grStartPoint->clone()));
}
}
void PointToPointRouting_Example::addEndPoint(EsriRuntimeQt::Point mapPoint)
{
if (EsriRuntimeQt::GeometryEngine::within(mapPoint, m_map->extent()))
{
EsriRuntimeQt::SimpleMarkerSymbol purpleDiamond(QColor(0, 102, 187), 15, EsriRuntimeQt::SimpleMarkerSymbolStyle::Diamond);
purpleDiamond.setOutline(EsriRuntimeQt::SimpleLineSymbol(QColor("black"), 1.0, EsriRuntimeQt::SimpleLineSymbolStyle::Solid));
if (m_endID != -1)
{
m_graphicsLayer->removeGraphic(m_endID);
}
m_grEndPoint = new EsriRuntimeQt::Graphic(mapPoint, purpleDiamond);
m_endID = m_graphicsLayer->addGraphic(static_cast<EsriRuntimeQt::Graphic*>(m_grEndPoint->clone()));
}
}
/*
void PointToPointRouting_Example::onFeatureServiceInfoComplete(const EsriRuntimeQt::FeatureServiceInfo& serviceInfo)
{
QList<EsriRuntimeQt::FeatureLayerInfo*> layerInfoList = serviceInfo.layers("states");
if(!layerInfoList.isEmpty() && !layerInfoList.at(0)->url().isEmpty())
{
// give the feature service table the URL to the feature service layer
EsriRuntimeQt::GeodatabaseFeatureServiceTable* featureServiceTable = new EsriRuntimeQt::GeodatabaseFeatureServiceTable(layerInfoList.at(0)->url(), this);
// initialize the feature layer with the feature service table as its feature source
m_featureLayer = new EsriRuntimeQt::FeatureLayer(featureServiceTable, this);
m_map->addLayer(m_featureLayer);
}
}
*/
/*
void PointToPointRouting_Example::onLocalServiceCreationSuccess(const QString& url, const QString& name)
{
Q_UNUSED(url);
Q_UNUSED(name);
// create the ArcGISDynamicMapServiceLayer using the LocalMapService's url
m_dynamicLocalServiceLayer = new EsriRuntimeQt::ArcGISDynamicMapServiceLayer(m_localMapService.urlMapService(), this);
m_map->addLayer(m_dynamicLocalServiceLayer);
}
*/
/*
void PointToPointRouting_Example::onLocalServiceCreationFailure(const QString& name)
{
qWarning() << name + " failed to start";
qWarning() << m_localMapService.error().what();
}
*/
/*
void PointToPointRouting_Example::onFeatureServiceCreationSuccess(const QString& url, const QString& name)
{
Q_UNUSED(url);
Q_UNUSED(name);
QString serviceUrl;
EsriRuntimeQt::FeatureServiceInfo featureServiceInfo = m_localFeatureService.featureServiceInfo();
QList<EsriRuntimeQt::FeatureLayerInfo*> layerInfoList= featureServiceInfo.layers("Cities");
if(!layerInfoList.isEmpty())
serviceUrl = layerInfoList.at(0)->url();
if (serviceUrl.isEmpty())
{
qWarning() << "The required layer does not exist";
return;
}
m_localFeatureLayer = new EsriRuntimeQt::ArcGISFeatureLayer(serviceUrl, this);
m_map->addLayer(m_localFeatureLayer);
}
*/
/*
void PointToPointRouting_Example::onFeatureServiceCreationFailure(const QString& name)
{
qWarning() << name + " failed to start";
qWarning() << m_localFeatureService.error().what();
}
*/
//Thank you !