A utility network container allows a dense collection of features to be represented by a single feature, which can be used to reduce map clutter.

Use case
Offering a container view for features aids in the review for valid structural attachment and containment relationships and helps determine if a dataset has an association role set. Container views often model a cluster of electrical devices on a pole top or inside a cabinet or vault.
How to use the sample
Select a container feature to show all features inside the container. The container is shown as a polygon graphic with the content features contained within. The viewpoint and scale of the map are also changed to the container’s extent. Connectivity and attachment associations inside the container are shown as red and blue dotted lines respectively.
How it works
- Load a web map that includes ArcGIS Pro Subtype Group Layers with only container features visible (i.e. fuse bank, switch bank, transformer bank, hand hole and junction box).
- Get and load the first
UtilityNetworkfrom the web map. - Add a
GraphicsOverlayfor displaying a container view. - Create a connection to
MapQuickView::mouseClicked. - Identify a feature with
MapView::identifyLayersAsyncand create aUtilityElementfrom it. - Get the associations for this element using
UtilityNetwork::associationsAsync(UtilityElement *element, UtilityAssociationType::Containment). - Turn-off the visibility of all
OperationalLayers. - Get the features for the
UtilityElement(s) from the associations usingUtilityNetwork::featuresForElementsAsync(const QList<UtilityElement *> &elements) - Add a
Graphicwith the geometry and symbol of each feature to theGraphicsOverlay. - Get associations for the extent of the
GraphicsOverlayusingUtilityNetwork::associationsAsync(const Envelope &extent) - Add a
Graphicto represent the association geometry between container features using a symbol that distinguishes betweenAttachmentandConnectivityassociation type. - Add another
Graphicthat represents this extent and zoom to this extent with some buffer.
Relevant API
- SubtypeFeatureLayer
- UtilityAssociation
- UtilityAssociationType
- UtilityElement
- UtilityNetwork
About the data
The Naperville electric network feature service, hosted on ArcGIS Online (authentication required: this is handled within the sample code), contains a utility network used to find associations shown in this sample and a web map portal item, Naperville electric containers, that use the same feature service endpoint and displays only container features.
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.
Tags
associations, connectivity association, containment association, structural attachment associations, utility network
Sample Code
// [WriteFile Name=DisplayContentOfUtilityNetworkContainer, Category=UtilityNetwork]// [Legal]// Copyright 2021 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 "DisplayContentOfUtilityNetworkContainer.h"#include "SymbolImageProvider.h"
// ArcGIS Maps SDK headers#include "ArcGISFeature.h"#include "ArcGISFeatureLayerInfo.h"#include "ArcGISFeatureListModel.h"#include "ArcGISFeatureTable.h"#include "ArcGISRuntimeEnvironment.h"#include "Authentication/AuthenticationManager.h"#include "Authentication/ArcGISAuthenticationChallenge.h"#include "Authentication/TokenCredential.h"#include "DrawingInfo.h"#include "Envelope.h"#include "Error.h"#include "ErrorException.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 "Polygon.h"#include "Renderer.h"#include "SimpleLineSymbol.h"#include "SpatialReference.h"#include "SubtypeFeatureLayer.h"#include "Symbol.h"#include "SymbolTypes.h"#include "UtilityAssetType.h"#include "UtilityAssociation.h"#include "UtilityElement.h"#include "UtilityNetworkListModel.h"#include "UtilityNetwork.h"#include "UtilityNetworkTypes.h"
// Qt headers#include <QImage>#include <QQmlContext>#include <QUuid>
using namespace Esri::ArcGISRuntime;using namespace Esri::ArcGISRuntime::Authentication;
DisplayContentOfUtilityNetworkContainer::DisplayContentOfUtilityNetworkContainer(QObject* parent /* = nullptr */) : ArcGISAuthenticationChallengeHandler(parent){ ArcGISRuntimeEnvironment::authenticationManager()->setArcGISAuthenticationChallengeHandler(this);
// Load a web map that includes ArcGIS Pro Subtype Group Layers with only container features visible (i.e. fuse bank, switch bank, transformer bank, hand hole and junction box) m_map = new Map(QUrl("https://sampleserver7.arcgisonline.com/portal/home/item.html?id=0e38e82729f942a19e937b31bfac1b8d"), this);
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(); });}
DisplayContentOfUtilityNetworkContainer::~DisplayContentOfUtilityNetworkContainer() = default;
void DisplayContentOfUtilityNetworkContainer::init(){ // Register the map view for QML qmlRegisterType<MapQuickView>("Esri.Samples", 1, 0, "MapView"); qmlRegisterType<DisplayContentOfUtilityNetworkContainer>("Esri.Samples", 1, 0, "DisplayContentOfUtilityNetworkContainerSample");}
MapQuickView* DisplayContentOfUtilityNetworkContainer::mapView() const{ return m_mapView;}
// Set the view (created in QML)void DisplayContentOfUtilityNetworkContainer::setMapView(MapQuickView* mapView){ if (!mapView || mapView == m_mapView) { return; }
m_mapView = mapView; m_mapView->setMap(m_map);
// Add a GraphicsOverlay for displaying a container view. m_containerGraphicsOverlay = new GraphicsOverlay(this); m_mapView->graphicsOverlays()->append(m_containerGraphicsOverlay);
createConnections(); createLegend();
emit mapViewChanged();}
void DisplayContentOfUtilityNetworkContainer::createConnections(){ connect(m_mapView, &MapQuickView::mouseClicked, this, &DisplayContentOfUtilityNetworkContainer::identifyFeaturesAtMouseClick);
// Connect error signals to message box connect(m_map, &Map::errorOccurred, this, [this](const Error& e) { setMessageBoxText("Map error: " + e.message() + " " + e.additionalMessage()); });
connect(m_mapView, &MapQuickView::errorOccurred, this, [this](const Error& e) { setMessageBoxText("MapView error: " + e.message() + " " + e.additionalMessage()); });}
void DisplayContentOfUtilityNetworkContainer::onTaskFailed(const QString& errorMsg, const ErrorException& taskException){ setMessageBoxText(errorMsg + taskException.error().message() + " " + taskException.error().additionalMessage());}
void DisplayContentOfUtilityNetworkContainer::identifyFeaturesAtMouseClick(QMouseEvent& mouseEvent){ if (m_map->loadStatus() != LoadStatus::Loaded || m_utilityNetwork->loadStatus() != LoadStatus::Loaded || !m_featuresFuture.isFinished()) { return; }
constexpr double tolerance = 5; constexpr bool returnPopupsOnly = false;
m_mapView->identifyLayersAsync(mouseEvent.position(), tolerance, returnPopupsOnly) .then(this, [this](const QList<IdentifyLayerResult*>& identifyResults) { getUtilityAssociationsOfFeature(identifyResults); }) .onFailed(this, [this](const ErrorException& e) { onTaskFailed("MapView error: ", e); });}
void DisplayContentOfUtilityNetworkContainer::getUtilityAssociationsOfFeature(const QList<IdentifyLayerResult*>& identifyResults){ if (identifyResults.isEmpty()) { return; }
if (m_containerElement) { delete m_containerElement; m_containerElement = nullptr; }
// Identify a feature and create a UtilityElement from it. for (IdentifyLayerResult* layerResult : identifyResults) { if (!m_containerElement && dynamic_cast<SubtypeFeatureLayer*>(layerResult->layerContent())) { const auto results = layerResult->sublayerResults(); for (const IdentifyLayerResult* sublayerResult : results) { const auto elements = sublayerResult->geoElements(); for (GeoElement* geoElement : elements) { if (ArcGISFeature* feature = dynamic_cast<ArcGISFeature*>(geoElement)) { m_containerElement = m_utilityNetwork->createElementWithArcGISFeature(feature); if (!m_containerElement) { return; }
// Queries for a list of all UtilityAssociation objects of containment association types present in the geodatabase for the m_containerElement. m_utilityAssociationFuture = m_utilityNetwork->associationsAsync(m_containerElement, UtilityAssociationType::Containment); m_utilityAssociationFuture .then(this, [this](const QList<UtilityAssociation*>& containmentAssociations) { onAssociationsCompleted_(containmentAssociations); }) .onFailed(this, [this](const ErrorException& e) { onTaskFailed("Utility Network error occured: ", e); }); return; } } } } }}
void DisplayContentOfUtilityNetworkContainer::onAssociationsCompleted_(const QList<UtilityAssociation*>& containmentAssociations){ if (!m_showContainerView) { getFeaturesForElementsOfUtilityAssociations(containmentAssociations); } else { showAttachmentAndConnectivitySymbols(containmentAssociations); }}
void DisplayContentOfUtilityNetworkContainer::getFeaturesForElementsOfUtilityAssociations(const QList<UtilityAssociation*>& containmentAssociations){ // Create a list of elements representing the participants in the containment associations QList<UtilityElement*> contentElements; for (UtilityAssociation* association : containmentAssociations) { UtilityElement* otherElement = association->fromElement()->objectId() == m_containerElement->objectId() ? association->toElement() : association->fromElement(); contentElements.append(otherElement); }
if (!contentElements.isEmpty()) { // Set visibility of all `OperationalLayers` to `false` setShowContainerView(true);
// Get the features for the UtilityElements m_featuresFuture = m_utilityNetwork->featuresForElementsAsync(contentElements); m_featuresFuture .then(this, [this](QList<ArcGISFeature*>) { displayFeaturesAndGetAssociations(); }) .onFailed(this, [this](const ErrorException& e) { onTaskFailed("Utility Network error occured: ", e); }); }}
void DisplayContentOfUtilityNetworkContainer::displayFeaturesAndGetAssociations(){ // Display the features on the graphics overlay const QList<Feature*> contentFeatures = m_utilityNetwork->featuresForElementsResult()->features(); for (Feature* content : contentFeatures) { Symbol* symbol = dynamic_cast<ArcGISFeatureTable*>(content->featureTable())->layerInfo().drawingInfo().renderer(this)->symbol(content); m_containerGraphicsOverlay->graphics()->append(new Graphic(content->geometry(), symbol, this)); }
// Get the associations for each feature within the graphics overlay extent m_utilityAssociationFuture = m_utilityNetwork->associationsAsync(m_containerGraphicsOverlay->extent()); m_utilityAssociationFuture .then(this, [this](const QList<UtilityAssociation*>& containmentAssociations) { onAssociationsCompleted_(containmentAssociations); }) .onFailed(this, [this](const ErrorException& e) { onTaskFailed("Utility Network error occured: ", e); });}
void DisplayContentOfUtilityNetworkContainer::showAttachmentAndConnectivitySymbols(const QList<UtilityAssociation*>& containmentAssociations){ // Display the association lines on the graphics overlay for (UtilityAssociation* association : containmentAssociations) { Symbol* symbol = association->associationType() == UtilityAssociationType::Attachment ? m_attachmentSymbol : m_connectivitySymbol; m_containerGraphicsOverlay->graphics()->append(new Graphic(association->geometry(), symbol, this)); }
// If there are no associations, create a bounding box graphic using the viewpoint, otherwise use the extent of the graphics overlay if (m_containerGraphicsOverlay->graphics()->size() == 1 && m_containerGraphicsOverlay->graphics()->first()->geometry().geometryType() == GeometryType::Point) { m_mapView->setViewpointAndWait( Viewpoint(Point(m_containerGraphicsOverlay->graphics()->first()->geometry()), m_containerElement->assetType()->containerViewScale())); m_boundingBox = m_mapView->currentViewpoint(ViewpointType::BoundingGeometry).targetGeometry(); m_mapView->setViewpointAndWait(m_previousViewpoint);
setMessageBoxText("This feature contains no associations"); } else { m_boundingBox = GeometryEngine::buffer(m_containerGraphicsOverlay->extent(), 0.05); }
m_containerGraphicsOverlay->graphics()->append(new Graphic(m_boundingBox, m_boundingBoxSymbol, this)); m_mapView->setViewpointGeometryAsync(m_containerGraphicsOverlay->extent(), 100);}
bool DisplayContentOfUtilityNetworkContainer::showContainerView() const{ return m_showContainerView;}
void DisplayContentOfUtilityNetworkContainer::setShowContainerView(bool showContainerView){ m_showContainerView = showContainerView;
if (m_showContainerView) { m_previousViewpoint = m_mapView->currentViewpoint(ViewpointType::BoundingGeometry); for (Layer* layer : *m_mapView->map()->operationalLayers()) { layer->setVisible(false); } } else { m_mapView->setViewpointAsync(m_previousViewpoint, 0.5); m_containerGraphicsOverlay->graphics()->clear();
for (Layer* layer : *m_mapView->map()->operationalLayers()) { layer->setVisible(true); } }
emit showContainerViewChanged();}
QString DisplayContentOfUtilityNetworkContainer::messageBoxText() const{ return m_messageBoxText;}
void DisplayContentOfUtilityNetworkContainer::setMessageBoxText(const QString& message){ m_messageBoxText = message; emit messageBoxTextChanged();}
// Create attachment, connectivity, and bounding box legendvoid DisplayContentOfUtilityNetworkContainer::createLegend(){ QQmlEngine* engine = QQmlEngine::contextForObject(this)->engine(); m_symbolImageProvider = new SymbolImageProvider(); engine->addImageProvider(SymbolImageProvider::imageProviderId(), m_symbolImageProvider);
m_attachmentSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Dot, Qt::blue, 3, this); m_connectivitySymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Dot, Qt::red, 3, this); m_boundingBoxSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Dot, Qt::yellow, 3, this);
m_attachmentSymbol->createSwatchAsync().then(this, [this](const QImage& image) { if (!m_symbolImageProvider) { return; }
// convert the QUuid into a QString const QString imageId = QUuid().createUuid().toString(QUuid::WithoutBraces);
// add the image to the provider m_symbolImageProvider->addImage(imageId, image);
// update the URL with the unique id m_attachmentSymbolUrl = QString("image://%1/%2").arg(SymbolImageProvider::imageProviderId(), imageId);
// emit the signal to trigger the QML Image to update emit attachmentSymbolUrlChanged(); });
m_connectivitySymbol->createSwatchAsync().then(this, [this](const QImage& image) { if (!m_symbolImageProvider) { return; }
// convert the QUuid into a QString const QString imageId = QUuid().createUuid().toString(QUuid::WithoutBraces);
// add the image to the provider m_symbolImageProvider->addImage(imageId, image);
// update the URL with the unique id m_connectivitySymbolUrl = QString("image://%1/%2").arg(SymbolImageProvider::imageProviderId(), imageId);
// emit the signal to trigger the QML Image to update emit connectivitySymbolUrlChanged(); });
m_boundingBoxSymbol->createSwatchAsync().then(this, [this](const QImage& image) { if (!m_symbolImageProvider) { return; }
// convert the QUuid into a QString const QString imageId = QUuid().createUuid().toString(QUuid::WithoutBraces);
// add the image to the provider m_symbolImageProvider->addImage(imageId, image);
// update the URL with the unique id m_boundingBoxSymbolUrl = QString("image://%1/%2").arg(SymbolImageProvider::imageProviderId(), imageId);
// emit the signal to trigger the QML Image to update emit boundingBoxSymbolUrlChanged(); });}
QString DisplayContentOfUtilityNetworkContainer::attachmentSymbolUrl() const{ return m_attachmentSymbolUrl;}
QString DisplayContentOfUtilityNetworkContainer::connectivitySymbolUrl() const{ return m_connectivitySymbolUrl;}
QString DisplayContentOfUtilityNetworkContainer::boundingBoxSymbolUrl() const{ return m_boundingBoxSymbolUrl;}
void DisplayContentOfUtilityNetworkContainer::handleArcGISAuthenticationChallenge(ArcGISAuthenticationChallenge* challenge){ TokenCredential::createWithChallengeAsync(challenge, "viewer01", "I68VGU^nMurF", {}, this) .then(this, [challenge](TokenCredential* tokenCredential) { challenge->continueWithCredential(tokenCredential); }) .onFailed(this, [challenge](const ErrorException& e) { challenge->continueWithError(e.error()); });}// [WriteFile Name=DisplayContentOfUtilityNetworkContainer, Category=UtilityNetwork]// [Legal]// Copyright 2021 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 DISPLAYCONTENTOFUTILITYNETWORKCONTAINER_H#define DISPLAYCONTENTOFUTILITYNETWORKCONTAINER_H
// ArcGIS Maps SDK headers#include "Authentication/ArcGISAuthenticationChallengeHandler.h"#include "Geometry.h"#include "Viewpoint.h"
// Qt headers#include <QFuture>#include <QMouseEvent>
namespace Esri::ArcGISRuntime{ class ArcGISFeature; class ErrorException; class GraphicsOverlay; class IdentifyLayerResult; class Map; class MapQuickView; class SubtypeFeatureLayer; class Symbol; class UtilityAssociation; class UtilityElement; class UtilityNetwork;} // namespace Esri::ArcGISRuntime
namespace Esri::ArcGISRuntime::Authentication{ class ArcGISAuthenticationChallenge;}
class SymbolImageProvider;
Q_MOC_INCLUDE("MapQuickView.h")
class DisplayContentOfUtilityNetworkContainer : public Esri::ArcGISRuntime::Authentication::ArcGISAuthenticationChallengeHandler{ Q_OBJECT
Q_PROPERTY(Esri::ArcGISRuntime::MapQuickView* mapView READ mapView WRITE setMapView NOTIFY mapViewChanged) Q_PROPERTY(bool showContainerView READ showContainerView WRITE setShowContainerView NOTIFY showContainerViewChanged) Q_PROPERTY(QString attachmentSymbolUrl READ attachmentSymbolUrl NOTIFY attachmentSymbolUrlChanged) Q_PROPERTY(QString connectivitySymbolUrl READ connectivitySymbolUrl NOTIFY connectivitySymbolUrlChanged) Q_PROPERTY(QString boundingBoxSymbolUrl READ boundingBoxSymbolUrl NOTIFY boundingBoxSymbolUrlChanged) Q_PROPERTY(QString messageBoxText READ messageBoxText WRITE setMessageBoxText NOTIFY messageBoxTextChanged)
public: explicit DisplayContentOfUtilityNetworkContainer(QObject* parent = nullptr); ~DisplayContentOfUtilityNetworkContainer();
static void init();
signals: void mapViewChanged(); void showContainerViewChanged(); void attachmentSymbolUrlChanged(); void connectivitySymbolUrlChanged(); void boundingBoxSymbolUrlChanged(); void messageBoxTextChanged();
private: Esri::ArcGISRuntime::MapQuickView* mapView() const; void createConnections(); bool showContainerView() const; void identifyFeaturesAtMouseClick(QMouseEvent& mouseEvent); void getUtilityAssociationsOfFeature(const QList<Esri::ArcGISRuntime::IdentifyLayerResult*>& identifyResult); void displayFeaturesAndGetAssociations(); void getFeaturesForElementsOfUtilityAssociations(const QList<Esri::ArcGISRuntime::UtilityAssociation*>& containmentAssociations); void showAttachmentAndConnectivitySymbols(const QList<Esri::ArcGISRuntime::UtilityAssociation*>& containmentAssociations); void setMapView(Esri::ArcGISRuntime::MapQuickView* mapView); void setShowContainerView(bool showContainerView); void setMessageBoxText(const QString& message); QString messageBoxText() const; void createLegend(); QString attachmentSymbolUrl() const; QString connectivitySymbolUrl() const; QString boundingBoxSymbolUrl() const; void onAssociationsCompleted_(const QList<Esri::ArcGISRuntime::UtilityAssociation*>& containmentAssociations); void onTaskFailed(const QString& errorMsg, const Esri::ArcGISRuntime::ErrorException& taskException);
void handleArcGISAuthenticationChallenge(Esri::ArcGISRuntime::Authentication::ArcGISAuthenticationChallenge* challenge) override;
Esri::ArcGISRuntime::Geometry m_boundingBox; Esri::ArcGISRuntime::GraphicsOverlay* m_containerGraphicsOverlay = nullptr; Esri::ArcGISRuntime::Map* m_map = nullptr; Esri::ArcGISRuntime::MapQuickView* m_mapView = nullptr; QFuture<QList<Esri::ArcGISRuntime::ArcGISFeature*>> m_featuresFuture; QFuture<QList<Esri::ArcGISRuntime::UtilityAssociation*>> m_utilityAssociationFuture; Esri::ArcGISRuntime::UtilityElement* m_containerElement = nullptr; Esri::ArcGISRuntime::UtilityNetwork* m_utilityNetwork = nullptr; Esri::ArcGISRuntime::Viewpoint m_previousViewpoint; bool m_showContainerView = false; bool m_setBoundingBox = false; QString m_messageBoxText; QString m_attachmentSymbolUrl; QString m_connectivitySymbolUrl; QString m_boundingBoxSymbolUrl; Esri::ArcGISRuntime::Symbol* m_attachmentSymbol = nullptr; Esri::ArcGISRuntime::Symbol* m_connectivitySymbol = nullptr; Esri::ArcGISRuntime::Symbol* m_boundingBoxSymbol = nullptr; SymbolImageProvider* m_symbolImageProvider = nullptr;};
#endif // DISPLAYCONTENTOFUTILITYNETWORKCONTAINER_H// [WriteFile Name=DisplayContentOfUtilityNetworkContainer, Category=UtilityNetwork]// [Legal]// Copyright 2021 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 QtQuick.Layoutsimport Esri.Samples
Item { id: item1
// Declare the C++ instance which creates the map etc. and supply the view DisplayContentOfUtilityNetworkContainerSample { id: model mapView: view }
// add a mapView component MapView { id: view anchors.fill: parent focus: true
Component.onCompleted: { // Set and keep the focus on MapView to enable keyboard navigation forceActiveFocus(); } }
// Create outer rectangle for the legend Rectangle { id: containerViewOverlay anchors.fill: parent
// Prevent MapView interaction ScrollView { anchors.fill: parent }
color: "transparent" border.color: "transparent"
visible: model.showContainerView onVisibleChanged: { if (containerViewOverlay.visible) containerViewOverlay.focus = true; else view.focus = true; }
Control { id: legendBox anchors { top: parent.top left: parent.left margins: 20 } background: Rectangle { color: palette.mid border.color: "black" border.width: 1 } padding: 5
contentItem: GridLayout { id: grid anchors.horizontalCenter: parent.horizontalCenter columns: 2 Layout.fillWidth: true
Label { text: qsTr("Utility association types") Layout.alignment: Qt.AlignHCenter Layout.columnSpan: 2 }
Image { id: attachmentImage source: model.attachmentSymbolUrl fillMode: Image.PreserveAspectFit } Label { id: attachmentLabel text: qsTr("Attachment") }
Image { id: connectivityImage source: model.connectivitySymbolUrl fillMode: Image.PreserveAspectFit } Label { id: connectivityLabel text: qsTr("Connectivity") }
Image { id: boundingBoxSymbol source: model.boundingBoxSymbolUrl fillMode: Image.PreserveAspectFit } Label { id: boundingBoxLabel text: qsTr("Bounding box") } } }
Button { id: containerCloseButton anchors { bottom: parent.bottom bottomMargin: 30 horizontalCenter: parent.horizontalCenter } text: qsTr("Close container view") font.pointSize: 16 onClicked: model.showContainerView = false; } }
Control { id: messageBoxPopup anchors.centerIn: parent padding: 10 width: Math.max(messageBoxText.width, closeMessage.width) + (padding * 2) height: messageBoxText.height + closeMessage.height + (messageBoxPopup.padding * 3) background: Rectangle { color: palette.base border.color: "black" }
visible: model.messageBoxText !== ""
Label { id: messageBoxText anchors { top: parent.top topMargin: messageBoxPopup.padding horizontalCenter: parent.horizontalCenter } text: model.messageBoxText }
Button { id: closeMessage anchors { bottom: parent.bottom bottomMargin: messageBoxPopup.padding horizontalCenter: parent.horizontalCenter } text: qsTr("Close") onClicked: model.messageBoxText = ""; } }}// [Legal]// Copyright 2021 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 "SymbolImageProvider.h"
// Qt headers#include <QQuickImageProvider>
SymbolImageProvider::SymbolImageProvider() : QQuickImageProvider(QQuickImageProvider::Image){}
// reimplemented function for QML to request Images from the providerQImage SymbolImageProvider::requestImage(const QString& id, QSize* size, const QSize& requestedSize){ Q_UNUSED(size) Q_UNUSED(requestedSize) return m_images[id];}
// helper to add images to the the providervoid SymbolImageProvider::addImage(const QString& id, const QImage& img){ m_images[id] = img;}
// static function to return the image provider idQString SymbolImageProvider::imageProviderId(){ return QStringLiteral("symbolimageprovider");}// [Legal]// Copyright 2021 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]
// 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.
#ifndef SYMBOLIMAGEPROVIDER_H#define SYMBOLIMAGEPROVIDER_H
// Qt headers#include <QHash>#include <QImage>#include <QQuickImageProvider>
class SymbolImageProvider : public QQuickImageProvider{public: SymbolImageProvider(); ~SymbolImageProvider() override = default;
public: QImage requestImage(const QString& id, QSize* size, const QSize& requestedSize) override; void addImage(const QString& id, const QImage& img); static QString imageProviderId();
private: QHash<QString, QImage> m_images;};
#endif // SYMBOLIMAGEPROVIDER_H// [Legal]// Copyright 2021 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 "DisplayContentOfUtilityNetworkContainer.h"
// ArcGIS Maps SDK headers#include "ArcGISRuntimeEnvironment.h"
// Qt headers#include <QCommandLineParser>#include <QDir>#include <QGuiApplication>#include <QQmlApplicationEngine>
// Platform specific headers#ifdef Q_OS_WIN#include <Windows.h>#endif
int main(int argc, char* argv[]){ QGuiApplication app(argc, argv); app.setApplicationName(QString("DisplayContentOfUtilityNetworkContainer"));
// 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 DisplayContentOfUtilityNetworkContainer::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/DisplayContentOfUtilityNetworkContainer/main.qml"));
return app.exec();}// Copyright 2021 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
DisplayContentOfUtilityNetworkContainer { anchors.fill: parent }}