Run a filtered trace to locate operable features that will isolate an area from the flow of network resources.

Use case
Determine the set of operable features required to stop a network’s resource, effectively isolating an area of the network. For example, you can choose to return only accessible and operable valves: ones that are not paved over or rusted shut.
How to use the sample
Select one or more features to use as filter barriers or create and set the configuration’s filter barriers by selecting a category. Check or uncheck ‘Include isolated features’. Press ‘Trace’ to run a subnetwork-based isolation trace. Press ‘Reset’ to clear filter barriers.
How it works
- Create a
MapViewand connect to itsmouseClickedsignal. - Create and load a
Mapwith a web map item URL that contains aUtilityNetwork. - Get and load the first
UtilityNetworkfrom the web map. - Add a
GraphicsOverlaywith aGraphicthat represents the starting location, and another graphics overlay for the filter barriers. - Populate the list of filter barrier categories from
UtilityNetworkDefinition::categories. - When the map view is clicked, identify which features are at that location and add a graphic that represents a filter barrier.
- Create a
UtilityElementfor the identified feature and add this utility element to a list of filter barriers.- If the element is a junction with more than one terminal, display a terminal picker. Then set the junction’s
terminalproperty with the selected terminal. - If an edge, set its
fractionAlongEdgeproperty usingGeometryEngine::fractionAlong.
- If the element is a junction with more than one terminal, display a terminal picker. Then set the junction’s
- When “Trace” is pressed:
- Create
UtilityTraceParameterswithUtilityTraceType::Isolationand a starting location from a given asset type and global ID. - Set the
UtilityTraceParameters::traceConfigurationproperty from a defaultUtilityTraceConfiguration. Set thefilterproperty with anUtilityTraceFilterobject.
- Create
- If ‘Trace’ is clicked without filter barriers:
- Create a new
UtilityCategoryComparisonwith the selected category andUtilityCategoryComparisonOperator::Exists. - Create a new
UtilityTraceFilterwith this condition asBarriersto setFilterand updateIncludeIsolatedFeaturesproperties of the default configuration from step 5. - Run
UtilityNetwork::trace.
- Create a new
- If
Traceis clicked with filter barriers:
- Update
IncludeIsolatedFeaturesproperty of the default configuration from step 5. - Run
UtilityNetwork::trace.
- For every
FeatureLayerin the map, select the features returned byfeaturesForElementsAsyncfrom the elements matching theirNetworkSource::namewith the layer’sFeatureTable::name.
Relevant API
- GeometryEngine::fractionAlong
- ServiceGeodatabase
- UtilityCategory
- UtilityCategoryComparison
- UtilityCategoryComparisonOperator
- UtilityDomainNetwork
- UtilityElement
- UtilityElementTraceResult
- UtilityNetwork
- UtilityNetworkDefinition
- UtilityTerminal
- UtilityTier
- UtilityTraceFilter
- UtilityTraceParameters
- UtilityTraceResult
- UtilityTraceType
About the data
The Naperville gas network feature service, hosted on ArcGIS Online (authentication required: this is handled within the sample code), contains a utility network used to run the isolation trace shown in this sample.
Additional information
Using utility network on ArcGIS Enterprise 10.8 requires an ArcGIS Enterprise member account licensed with the Utility Network user type extension. Please refer to the utility network services documentation.
Credentials:
- Username: viewer01
- Password: I68VGU^nMurF
Tags
category comparison, condition barriers, filter barriers, isolated features, network analysis, subnetwork trace, trace configuration, trace filter, utility network
Sample Code
// [WriteFile Name=PerformValveIsolationTrace, Category=UtilityNetwork]// [Legal]// Copyright 2020 Esri.//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.// [Legal]
#ifdef PCH_BUILD#include "pch.hpp"#endif // PCH_BUILD
// sample headers#include "PerformValveIsolationTrace.h"
// ArcGIS Maps SDK headers#include "ArcGISRuntimeEnvironment.h"#include "Authentication/AuthenticationManager.h"#include "Authentication/ArcGISAuthenticationChallenge.h"#include "Authentication/TokenCredential.h"#include "ArcGISFeature.h"#include "ArcGISFeatureListModel.h"#include "Error.h"#include "ErrorException.h"#include "FeatureLayer.h"#include "GeometryEngine.h"#include "Graphic.h"#include "GraphicListModel.h"#include "GraphicsOverlay.h"#include "GraphicsOverlayListModel.h"#include "IdentifyLayerResult.h"#include "LayerListModel.h"#include "Map.h"#include "MapQuickView.h"#include "MapTypes.h"#include "Point.h"#include "Polyline.h"#include "QueryParameters.h"#include "ServiceFeatureTable.h"#include "SimpleMarkerSymbol.h"#include "SimpleRenderer.h"#include "SymbolTypes.h"#include "UtilityAssetGroup.h"#include "UtilityAssetType.h"#include "UtilityCategory.h"#include "UtilityCategoryComparison.h"#include "UtilityDomainNetwork.h"#include "UtilityElement.h"#include "UtilityElementTraceResult.h"#include "UtilityNetwork.h"#include "UtilityNetworkDefinition.h"#include "UtilityNetworkListModel.h"#include "UtilityNetworkSource.h"#include "UtilityNetworkTypes.h"#include "UtilityTerminal.h"#include "UtilityTerminalConfiguration.h"#include "UtilityTier.h"#include "UtilityTraceConfiguration.h"#include "UtilityTraceFilter.h"#include "UtilityTraceParameters.h"#include "UtilityTraceResultListModel.h"
// Qt headers#include <QFuture>#include <QUuid>
// Other headers#include "TaskCanceler.h"
using namespace Esri::ArcGISRuntime;using namespace Esri::ArcGISRuntime::Authentication;
namespace{const QString domainNetworkName = QStringLiteral("Pipeline");const QString tierName = QStringLiteral("Pipe Distribution System");const QString networkSourceName = QStringLiteral("Gas Device");const QString assetGroupName = QStringLiteral("Meter");const QString assetTypeName = QStringLiteral("Customer");const QString globalId = QStringLiteral("{98A06E95-70BE-43E7-91B7-E34C9D3CB9FF}");const QString sampleServer7Username = QStringLiteral("viewer01");const QString sampleServer7Password = QStringLiteral("I68VGU^nMurF");}
namespace{// Convenient RAII template struct that deletes all pointers in a given container.template <typename T>struct ScopedCleanup{ ScopedCleanup(const QList<T*>& list) : results(list) { } ~ScopedCleanup() { qDeleteAll(results); } const QList<T*>& results;};}
PerformValveIsolationTrace::PerformValveIsolationTrace(QObject* parent /* = nullptr */): ArcGISAuthenticationChallengeHandler(parent), m_map(new Map(QUrl("https://sampleserver7.arcgisonline.com/portal/home/item.html?id=f439b4724bb54ac088a2c21eaf70da7b"), this)), m_startingLocationOverlay(new GraphicsOverlay(this)), m_filterBarriersOverlay(new GraphicsOverlay(this)), m_graphicParent(new QObject()), m_taskCanceler(std::make_unique<TaskCanceler>()){ ArcGISRuntimeEnvironment::authenticationManager()->setArcGISAuthenticationChallengeHandler(this);
// disable UI while loading utility network m_tasksRunning = true; emit tasksRunningChanged();
connect(m_map, &Map::doneLoading, this, [this](const Error& error) { if (!error.isEmpty() || m_map->utilityNetworks()->isEmpty()) { return; }
m_utilityNetwork = m_map->utilityNetworks()->first(); m_utilityNetwork->load(); connectSignals(); });}
PerformValveIsolationTrace::~PerformValveIsolationTrace() = default;
void PerformValveIsolationTrace::init(){ // Register the map view for QML qmlRegisterType<MapQuickView>("Esri.Samples", 1, 0, "MapView"); qmlRegisterType<PerformValveIsolationTrace>("Esri.Samples", 1, 0, "PerformValveIsolationTraceSample");}
MapQuickView* PerformValveIsolationTrace::mapView() const{ return m_mapView;}
// Set the view (created in QML)void PerformValveIsolationTrace::setMapView(MapQuickView* mapView){ if (!mapView || mapView == m_mapView) return;
m_mapView = mapView; m_mapView->setMap(m_map);
connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent& mouseEvent) { if (m_map->loadStatus() != LoadStatus::Loaded) return;
constexpr double tolerance = 10.0; constexpr bool returnPopups = false; m_clickPoint = m_mapView->screenToLocation(mouseEvent.position().x(), mouseEvent.position().y()); m_taskCanceler->addTask(m_mapView->identifyLayersAsync(mouseEvent.position(), tolerance, returnPopups).then(this, [this](const QList<IdentifyLayerResult*>& results) { // handle the identify results onIdentifyLayersCompleted_(results); })); });
// apply renderers SimpleMarkerSymbol* startingPointSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Cross, Qt::green, 25, this); m_startingLocationOverlay->setRenderer(new SimpleRenderer(startingPointSymbol, this));
SimpleMarkerSymbol* filterBarrierSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::X, Qt::red, 25, this); m_filterBarriersOverlay->setRenderer(new SimpleRenderer(filterBarrierSymbol, this));
m_mapView->graphicsOverlays()->append(m_startingLocationOverlay); m_mapView->graphicsOverlays()->append(m_filterBarriersOverlay);
emit mapViewChanged();}
QStringList PerformValveIsolationTrace::categoriesList() const{ if (!m_utilityNetwork) return { };
if (m_utilityNetwork->loadStatus() != LoadStatus::Loaded) return { };
const QList<UtilityCategory*> categories = m_utilityNetwork->definition()->categories(); QStringList strList; for (UtilityCategory* category : categories) { strList << category->name(); } return strList;}
void PerformValveIsolationTrace::performTrace(){ if (m_selectedIndex < 0) return;
// disable UI while trace is run m_tasksRunning = true; emit tasksRunningChanged();
for (Layer* layer : *m_map->operationalLayers()) { // clear previous selection from the feature layers FeatureLayer* featureLayer = dynamic_cast<FeatureLayer*>(layer); if (featureLayer) featureLayer->clearSelection(); }
const QList<UtilityCategory*> categories = m_utilityNetwork->definition()->categories();
// get the selected utility category if (categories[m_selectedIndex] != nullptr) { // set whether to include isolated features m_traceConfiguration->setIncludeIsolatedFeatures(m_isolateFeatures);
UtilityTraceParameters* traceParameters = new UtilityTraceParameters(UtilityTraceType::Isolation, QList<UtilityElement*> {m_startingLocation}, this); traceParameters->setTraceConfiguration(m_traceConfiguration);
// reset trace configuration filter barriers m_traceConfiguration->setFilter(new UtilityTraceFilter(this));
// set the user selected filter barriers otherwise // set the category comparison to the barriers of the configuration's trace filter if (!m_filterBarriers.empty()) traceParameters->setFilterBarriers(m_filterBarriers); else { UtilityCategory* selectedCategory = categories[m_selectedIndex]; UtilityCategoryComparison* categoryComparison = new UtilityCategoryComparison(selectedCategory, UtilityCategoryComparisonOperator::Exists, this); traceParameters->traceConfiguration()->filter()->setBarriers(categoryComparison); }
m_taskCanceler->addTask(m_utilityNetwork->traceAsync(traceParameters).then(this, [this](QList<UtilityTraceResult*>) { onTraceCompleted_(); })); }}
void PerformValveIsolationTrace::onTraceCompleted_(){ // local paret to clean up UtilityElementTraceResult when we leave scope. QObject localParent;
m_tasksRunning = false; emit tasksRunningChanged();
UtilityTraceResultListModel* utilityTraceResultList = m_utilityNetwork->traceResult();
if (utilityTraceResultList->isEmpty()) { m_noResults = true; emit noResultsChanged(); return; }
UtilityElementTraceResult* utilityElementTraceResult = dynamic_cast<UtilityElementTraceResult*>(utilityTraceResultList->at(0)); if (utilityElementTraceResult) { // given local parent to clean up once we leave scope utilityElementTraceResult->setParent(&localParent);
const QList<UtilityElement*> utilityElementList = utilityElementTraceResult->elements(this);
// A convenience wrapper that deletes the contents of utilityElementList when we leave scope. ScopedCleanup<UtilityElement> utilityElementListCleanUp(utilityElementList);
if (utilityElementList.empty()) { m_noResults = true; emit noResultsChanged(); return; }
// iterate through the map's features for (Layer* layer : *m_map->operationalLayers()) { FeatureLayer* featureLayer = dynamic_cast<FeatureLayer*>(layer); if (featureLayer) { // create query parameters to find features whose network source names match layer's feature table name QueryParameters queryParameters; QList<qint64> objectIds = {};
for (UtilityElement* utilityElement : utilityElementList) { const QString networkSourceName = utilityElement->networkSource()->name(); const QString featureTableName = featureLayer->featureTable()->tableName(); if (networkSourceName == featureTableName) objectIds.append(utilityElement->objectId()); } queryParameters.setObjectIds(objectIds); m_taskCanceler->addTask(featureLayer->selectFeaturesAsync(queryParameters, SelectionMode::New)); } } }}
void PerformValveIsolationTrace::performReset(){ m_filterBarriersOverlay->graphics()->clear(); m_filterBarriers.clear(); m_traceConfiguration->setFilter(new UtilityTraceFilter(this)); m_graphicParent.reset(new QObject());
for (Layer* layer : *m_map->operationalLayers()) { // clear previous selection from the feature layers FeatureLayer* featureLayer = dynamic_cast<FeatureLayer*>(layer); if (featureLayer) featureLayer->clearSelection(); }}
void PerformValveIsolationTrace::connectSignals(){ connect(m_utilityNetwork, &UtilityNetwork::doneLoading, this, [this](const Error& error) { m_tasksRunning = false; emit tasksRunningChanged();
if (!error.isEmpty()) { qDebug() << error.message() << error.additionalMessage(); return; }
if (m_utilityNetwork->loadStatus() != LoadStatus::Loaded) return;
// get a trace configuration from a tier UtilityNetworkDefinition* networkDefinition = m_utilityNetwork->definition(); UtilityDomainNetwork* domainNetwork = networkDefinition->domainNetwork(domainNetworkName); if (domainNetwork) { UtilityTier* tier = domainNetwork->tier(tierName); if (tier) m_traceConfiguration = tier->defaultTraceConfiguration(); }
if (!m_traceConfiguration) return;
// create a trace filter m_traceConfiguration->setFilter(new UtilityTraceFilter(this));
// get a default starting location UtilityNetworkSource* networkSource = networkDefinition->networkSource(networkSourceName); if (networkSource) { UtilityAssetGroup* assetGroup = networkSource->assetGroup(assetGroupName); if (assetGroup) { UtilityAssetType* assetType = assetGroup->assetType(assetTypeName); if (assetType) m_startingLocation = m_utilityNetwork->createElementWithAssetType(assetType, QUuid(globalId), nullptr, this); } }
if (!m_startingLocation) return;
// display starting location m_taskCanceler->addTask(m_utilityNetwork->featuresForElementsAsync(QList<UtilityElement*> {m_startingLocation}).then(this, [this](QList<ArcGISFeature*>) { // display starting location ArcGISFeatureListModel* elementFeaturesList = m_utilityNetwork->featuresForElementsResult(); const Point startingLocationGeometry = geometry_cast<Point>(elementFeaturesList->first()->geometry()); Graphic* graphic = new Graphic(startingLocationGeometry, m_graphicParent.get()); m_startingLocationOverlay->graphics()->append(graphic);
constexpr double scale = 3000.0; m_taskCanceler->addTask(m_mapView->setViewpointCenterAsync(startingLocationGeometry, scale)); m_tasksRunning = false; emit tasksRunningChanged(); }));
// populate the combo box choices m_categoriesList = categoriesList(); emit categoriesListChanged(); });}
bool PerformValveIsolationTrace::noResults() const{ return m_noResults;}
bool PerformValveIsolationTrace::tasksRunning() const{ return m_tasksRunning;}
void PerformValveIsolationTrace::onIdentifyLayersCompleted_(const QList<IdentifyLayerResult*>& results){ // A convenience wrapper that deletes the contents of results when we leave scope. ScopedCleanup<IdentifyLayerResult> resultsScopedCleanup(results);
// could not identify location if (results.isEmpty()) return;
const IdentifyLayerResult* result = results[0]; ArcGISFeature* feature = static_cast<ArcGISFeature*>(std::as_const(result)->geoElements()[0]); m_element = m_utilityNetwork->createElementWithArcGISFeature(feature);
const UtilityNetworkSourceType elementSourceType = m_element->networkSource()->sourceType();
if (elementSourceType == UtilityNetworkSourceType::Junction) { const QList<UtilityTerminal*> terminals = m_element->assetType()->terminalConfiguration()->terminals();
if (terminals.size() > 1) { m_terminals.clear(); for (UtilityTerminal* terminal : terminals) { m_terminals.append(terminal->name()); } emit terminalsChanged(); return; } } else if (elementSourceType == UtilityNetworkSourceType::Edge) { if (feature->geometry().geometryType() == GeometryType::Polyline) { const Polyline line = geometry_cast<Polyline>(GeometryEngine::removeZ(feature->geometry())); // Set how far the element is along the edge. const double fraction = GeometryEngine::fractionAlong(line, m_clickPoint, -1); m_element->setFractionAlongEdge(fraction); } }
m_filterBarriersOverlay->graphics()->append(new Graphic(m_clickPoint, m_graphicParent.get())); m_filterBarriers.append(m_element);}
void PerformValveIsolationTrace::selectedTerminal(int index){ UtilityTerminal* selectedTerminal = m_element->assetType()->terminalConfiguration()->terminals().at(index); m_element->setTerminal(selectedTerminal);
m_filterBarriersOverlay->graphics()->append(new Graphic(m_clickPoint, m_graphicParent.get())); m_filterBarriers.append(m_element);}
void PerformValveIsolationTrace::handleArcGISAuthenticationChallenge(ArcGISAuthenticationChallenge* challenge){ TokenCredential::createWithChallengeAsync(challenge, sampleServer7Username, sampleServer7Password, {}, this).then(this, [challenge](TokenCredential* tokenCredential) { challenge->continueWithCredential(tokenCredential); }).onFailed(this, [challenge](const ErrorException& e) { challenge->continueWithError(e.error()); });}// [WriteFile Name=PerformValveIsolationTrace, Category=UtilityNetwork]// [Legal]// Copyright 2020 Esri.//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.// [Legal]
#ifndef PERFORMVALVEISOLATIONTRACE_H#define PERFORMVALVEISOLATIONTRACE_H
// Qt headers#include <QUuid>
// ArcGIS Maps SDK headers#include "Authentication/ArcGISAuthenticationChallengeHandler.h"#include "Point.h"
namespace Esri::ArcGISRuntime{class ArcGISFeature;class FeatureLayer;class GraphicsOverlay;class Map;class MapQuickView;class UtilityCategory;class UtilityElement;class UtilityNetwork;class UtilityTraceConfiguration;class UtilityTraceParameters;class IdentifyLayerResult;}
namespace Esri::ArcGISRuntime::Authentication{ class ArcGISAuthenticationChallenge;}
Q_MOC_INCLUDE("MapQuickView.h")Q_MOC_INCLUDE("IdentifyLayerResult.h")
class TaskCanceler;
class PerformValveIsolationTrace : public Esri::ArcGISRuntime::Authentication::ArcGISAuthenticationChallengeHandler{ Q_OBJECT
Q_PROPERTY(Esri::ArcGISRuntime::MapQuickView* mapView READ mapView WRITE setMapView NOTIFY mapViewChanged) Q_PROPERTY(QStringList categoriesList READ categoriesList NOTIFY categoriesListChanged) Q_PROPERTY(int selectedIndex MEMBER m_selectedIndex NOTIFY selectedIndexChanged) Q_PROPERTY(bool isolateFeatures MEMBER m_isolateFeatures NOTIFY isolateFeaturesChanged) Q_PROPERTY(bool tasksRunning READ tasksRunning NOTIFY tasksRunningChanged) Q_PROPERTY(bool noResults READ noResults NOTIFY noResultsChanged) Q_PROPERTY(QStringList terminals MEMBER m_terminals NOTIFY terminalsChanged)
public: explicit PerformValveIsolationTrace(QObject* parent = nullptr); ~PerformValveIsolationTrace();
static void init(); Q_INVOKABLE void performTrace(); Q_INVOKABLE void performReset(); Q_INVOKABLE void selectedTerminal(int index);
signals: void mapViewChanged(); void categoriesListChanged(); void selectedIndexChanged(); void isolateFeaturesChanged(); void tasksRunningChanged(); void noResultsChanged(); void terminalsChanged();
private: Esri::ArcGISRuntime::MapQuickView* mapView() const; void setMapView(Esri::ArcGISRuntime::MapQuickView* mapView); QStringList categoriesList() const; bool tasksRunning() const; bool noResults() const; void connectSignals(); void onIdentifyLayersCompleted_(const QList<Esri::ArcGISRuntime::IdentifyLayerResult*>& results); void onTraceCompleted_();
void handleArcGISAuthenticationChallenge(Esri::ArcGISRuntime::Authentication::ArcGISAuthenticationChallenge* challenge) override;
Esri::ArcGISRuntime::Map* m_map = nullptr; Esri::ArcGISRuntime::MapQuickView* m_mapView = nullptr; Esri::ArcGISRuntime::GraphicsOverlay* m_startingLocationOverlay = nullptr; Esri::ArcGISRuntime::GraphicsOverlay* m_filterBarriersOverlay = nullptr; Esri::ArcGISRuntime::UtilityElement* m_startingLocation = nullptr; Esri::ArcGISRuntime::UtilityElement* m_element = nullptr; Esri::ArcGISRuntime::UtilityNetwork* m_utilityNetwork = nullptr; Esri::ArcGISRuntime::UtilityTraceConfiguration* m_traceConfiguration = nullptr; Esri::ArcGISRuntime::Point m_clickPoint; QList<Esri::ArcGISRuntime::UtilityElement*> m_filterBarriers; QStringList m_terminals; QScopedPointer<QObject> m_graphicParent; QStringList m_categoriesList; std::unique_ptr<TaskCanceler> m_taskCanceler; int m_selectedIndex = -1; bool m_isolateFeatures = false; bool m_tasksRunning = false; bool m_traceRunning = false; bool m_noResults = false;};
#endif // PERFORMVALVEISOLATIONTRACE_H// [WriteFile Name=PerformValveIsolationTrace, Category=UtilityNetwork]// [Legal]// Copyright 2020 Esri.//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.// [Legal]
import QtQuickimport QtQuick.Controlsimport Esri.Samplesimport QtQuick.Layouts
Item { // add a mapView component MapView { id: view anchors.fill: parent
Component.onCompleted: { // Set the focus on MapView to initially enable keyboard navigation forceActiveFocus(); } }
ColumnLayout { anchors { left: parent.left top: parent.top }
Rectangle { id: backgroundRect color: "#FBFBFB" height: childrenRect.height width: row.width * 1.25
RowLayout { id: titleRow anchors { left: row.left top: parent.top } Rectangle { color: backgroundRect.color width: childrenRect.width height: childrenRect.height Text { text: "Choose category for filter barrier:" font.pixelSize: 14 } } }
RowLayout { id: row anchors { horizontalCenter: parent.horizontalCenter top: titleRow.bottom } ComboBox { id: comboBox enabled: !sampleModel.tasksRunning Layout.minimumWidth: 200 model: sampleModel.categoriesList onCurrentIndexChanged: { sampleModel.selectedIndex = currentIndex; } } Button { text: "Trace" onClicked: { sampleModel.performTrace(); } enabled: !sampleModel.tasksRunning } Button { text: "Reset" onClicked: { sampleModel.performReset(); } enabled: !sampleModel.tasksRunning } }
RowLayout { id: checkBoxRow anchors { top: row.bottom left: row.left }
CheckBox { text: "Include isolated features" enabled: !sampleModel.tasksRunning leftPadding: 0 onCheckedChanged: { sampleModel.isolateFeatures = checked; } } } } }
TerminalPickerView { id: terminalPickerView visible: sampleModel.terminals.length > 0 }
BusyIndicator { id: busyIndicator anchors.centerIn: parent running: sampleModel.tasksRunning }
Dialog { id: messageDialog visible: sampleModel.noResults title: "Isolation trace returned no elements." standardButtons: Dialog.Ok anchors.centerIn: parent }
// Declare the C++ instance which creates the map etc. and supply the view PerformValveIsolationTraceSample { id: sampleModel mapView: view }}import QtQuickimport QtQuick.Layoutsimport QtQuick.Controls
Dialog { id: terminalPickerView modal: true standardButtons: Dialog.Ok | Dialog.Cancel x: (parent.width - width) / 2 y: (parent.height - height) / 2
ColumnLayout { Text { text: qsTr("Select the terminal for this junction.") Layout.alignment: Qt.AlignHCenter }
ComboBox { id: terminalSelection model: sampleModel.terminals Layout.alignment: Qt.AlignHCenter } }
onAccepted: sampleModel.selectedTerminal(terminalSelection.currentIndex);}// [Legal]// Copyright 2020 Esri.//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.// [Legal]
// sample headers#include "PerformValveIsolationTrace.h"
// ArcGIS Maps SDK headers#include "ArcGISRuntimeEnvironment.h"
// Qt headers#include <QDir>#include <QGuiApplication>#include <QQmlApplicationEngine>
// Platform specific headers#ifdef Q_OS_WIN#include <Windows.h>#endif
int main(int argc, char *argv[]){ Esri::ArcGISRuntime::ArcGISRuntimeEnvironment::setUseLegacyAuthentication(false); QGuiApplication app(argc, argv); app.setApplicationName(QString("PerformValveIsolationTrace"));
// Use of ArcGIS location services, such as basemap styles, geocoding, and routing services, // requires an access token. For more information see // https://links.esri.com/arcgis-runtime-security-auth.
// The following methods grant an access token:
// 1. User authentication: Grants a temporary access token associated with a user's ArcGIS account. // To generate a token, a user logs in to the app with an ArcGIS account that is part of an // organization in ArcGIS Online or ArcGIS Enterprise.
// 2. API key authentication: Get a long-lived access token that gives your application access to // ArcGIS location services. Go to the tutorial at https://links.esri.com/create-an-api-key. // Copy the API Key access token.
const QString accessToken = QString("");
if (accessToken.isEmpty()) { qWarning() << "Use of ArcGIS location services, such as the basemap styles service, requires" << "you to authenticate with an ArcGIS account or set the API Key property."; } else { Esri::ArcGISRuntime::ArcGISRuntimeEnvironment::setApiKey(accessToken); }
// Initialize the sample PerformValveIsolationTrace::init();
// Initialize application view QQmlApplicationEngine engine; // Add the import Path engine.addImportPath(QDir(QCoreApplication::applicationDirPath()).filePath("qml"));
#ifdef ARCGIS_RUNTIME_IMPORT_PATH_2 engine.addImportPath(ARCGIS_RUNTIME_IMPORT_PATH_2);#endif
// Set the source engine.load(QUrl("qrc:/Samples/UtilityNetwork/PerformValveIsolationTrace/main.qml"));
return app.exec();}// Copyright 2020 Esri.
// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.
import QtQuick.Controlsimport Esri.Samples
ApplicationWindow { visible: true width: 800 height: 600
PerformValveIsolationTrace { anchors.fill: parent }}