Create, update, and delete features to manage a feature layer.

Use case
An end-user performing a survey may want to manage features on the map in various ways during the course of their work.
How to use the sample
Pick an operation, then tap on the map to perform the operation at that location. Available feature management operations include: “Create feature”, “Delete feature”, “Update attribute”, and “Update geometry”.
How it works
- Create a
ServiceGeodatabasefrom a URL. - Get a
ServiceFeatureTablefrom theServiceGeodatabase. - Create a
FeatureLayerderived from theServiceFeatureTableinstance. - Update the
operationModeproperty when a feature management operation is selected. - Apply the feature management operation upon tapping the map.
- Create features: create a
Featurewith attributes and a location using theServiceFeatureTable. - Delete features: delete the selected
Featurefrom theFeatureTable. - Update attribute: update the attribute of the selected
Feature. - Update geometry: update the geometry of the selected
Feature.
- Create features: create a
- Update the
FeatureTablelocally. - Update the
ServiceGeodatabaseof theServiceFeatureTableby callingApplyEditsAsync().- This pushes the changes to the server.
Relevant API
- Feature
- FeatureEditResult
- FeatureLayer
- ServiceFeatureTable
- ServiceGeodatabase
Additional information
When editing feature tables that are subject to database behavior (operations on one table affecting another table), it’s now recommended to call these methods (apply or undo edits) on the ServiceGeodatabase object rather than on the ServiceFeatureTable object. Using the ServiceGeodatabase object to call these operations will prevent possible data inconsistencies and ensure transactional integrity so that all changes can be committed or rolled back.
Tags
amend, attribute, create, delete, deletion, details, edit, editing, feature, feature layer, feature table, geodatabase, information, moving, online service, service, update, updating, value
Sample Code
// [WriteFile Name=ManageFeaturesFeatureService, Category=EditData]// [Legal]// Copyright 2025 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 "ManageFeaturesFeatureService.h"
// ArcGIS Maps SDK headers#include "ArcGISFeature.h"#include "AttributeListModel.h"#include "Basemap.h"#include "CalloutData.h"#include "Envelope.h"#include "Error.h"#include "Feature.h"#include "FeatureEditResult.h"#include "FeatureIterator.h"#include "FeatureLayer.h"#include "FeatureQueryResult.h"#include "FeatureTableEditResult.h"#include "IdentifyLayerResult.h"#include "LayerListModel.h"#include "Map.h"#include "MapQuickView.h"#include "MapTypes.h"#include "MapViewTypes.h"#include "Point.h"#include "QueryParameters.h"#include "ServiceFeatureTable.h"#include "ServiceGeodatabase.h"#include "SpatialReference.h"#include "Viewpoint.h"
// Qt headers#include <QFuture>#include <QMap>#include <QMouseEvent>#include <QScopeGuard>#include <QString>#include <QUrl>#include <QUuid>#include <QVariant>
// STL headers#include <memory>
using namespace Esri::ArcGISRuntime;
ManageFeaturesFeatureService::ManageFeaturesFeatureService(QQuickItem* parent) : QQuickItem(parent){}
ManageFeaturesFeatureService::~ManageFeaturesFeatureService() = default;
void ManageFeaturesFeatureService::init(){ qmlRegisterType<MapQuickView>("Esri.Samples", 1, 0, "MapView"); qmlRegisterType<ManageFeaturesFeatureService>("Esri.Samples", 1, 0, "ManageFeaturesFeatureServiceSample"); qmlRegisterUncreatableType<CalloutData>("Esri.Samples", 1, 0, "CalloutData", "CalloutData is an uncreatable type");}
void ManageFeaturesFeatureService::componentComplete(){ QQuickItem::componentComplete();
// Find QML MapView component m_mapView = findChild<MapQuickView*>("mapView"); m_mapView->setWrapAroundMode(WrapAroundMode::Disabled);
// Create a Map by passing in the Basemap m_map = new Map(BasemapStyle::ArcGISStreets, this); m_map->setInitialViewpoint(Viewpoint(Point(-10800000, 4500000, SpatialReference(102100)), 3e7));
// Set map on the map view m_mapView->setMap(m_map);
// Create a ServiceGeodatabase m_serviceGeodatabase = new ServiceGeodatabase(QUrl("https://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer/"), this);
connect(m_serviceGeodatabase, &ServiceGeodatabase::loadStatusChanged, this, [this](LoadStatus loadStatus) { if (loadStatus != LoadStatus::Loaded) { return; } // Get the first table(id 0) from the ServiceGeodatabase if (ServiceFeatureTable* table = m_serviceGeodatabase->table(0); table) { ServiceFeatureTable* featureTable = table; m_featureLayer = new FeatureLayer(featureTable, this); m_map->operationalLayers()->append(m_featureLayer);
connectSignals_(); } });
// Load the ServiceGeodatabase m_serviceGeodatabase->load();}
void ManageFeaturesFeatureService::connectSignals_(){ // Connect to the mouse clicked signal on the MapQuickView connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent& mouseEvent) { if (m_operationMode == OperationMode::AddFeatures) { handleAddFeatureClick_(mouseEvent); } else if (m_operationMode == OperationMode::UpdateGeometry) { handleUpdateGeometryClick_(mouseEvent); } else { handleIdentifyFeatureClick_(mouseEvent); } });
// Connect to the viewpoint changed signal on the MapQuickView connect(m_mapView, &MapQuickView::viewpointChanged, this, [this]() { if (m_operationMode == OperationMode::AddFeatures) { return; } m_featureLayer->clearSelection(); emit hideWindow(); if (m_operationMode == OperationMode::UpdateGeometry) { m_featureSelected = false; } });}
ManageFeaturesFeatureService::OperationMode ManageFeaturesFeatureService::operationMode() const{ return m_operationMode;}
void ManageFeaturesFeatureService::setOperationMode(OperationMode mode){ if (m_operationMode == mode) { return; }
m_operationMode = mode;
// Clear any existing selection when switching modes if (m_featureLayer) { m_featureLayer->clearSelection(); m_featureSelected = false; } emit hideWindow(); emit operationModeChanged();}
QString ManageFeaturesFeatureService::featureType() const{ return m_featureType;}
void ManageFeaturesFeatureService::deleteSelectedFeature(){ m_serviceGeodatabase->table(0) ->deleteFeatureAsync(m_selectedFeature) .then(this, [this]() { // Handle the completion of applyEditsAsync from the ServiceGeodatabase m_serviceGeodatabase->applyEditsAsync().then(this, [](const QList<FeatureTableEditResult*>& tableEditResults) { const QScopeGuard deleteAllOnExit{[&tableEditResults]() { qDeleteAll(tableEditResults); }};
if (tableEditResults.isEmpty()) { return; }
// Get the first table result const FeatureTableEditResult* tableResult = tableEditResults.first(); if (!tableResult->editResults().isEmpty()) { // Get the first feature edit result from the table const FeatureEditResult* featureEditResult = tableResult->editResults().first(); // Check if there were errors, and if not, log the object ID if (featureEditResult && !featureEditResult->isCompletedWithErrors()) { qDebug() << "Successfully deleted Object ID:" << featureEditResult->objectId(); } else { qDebug() << "Apply edits error."; } } }); });}
void ManageFeaturesFeatureService::updateSelectedFeature(const QString& fieldVal){ if (!m_selectedFeature) { return; }
// Cancel any previously pending connection so at most one connection in queue disconnect(m_featureLoadStatusChangedConnection);
m_featureLoadStatusChangedConnection = connect(m_selectedFeature, &ArcGISFeature::doneLoading, this, [this, fieldVal](const Error& error) { if (!error.isEmpty()) { return; } if (!m_selectedFeature || !m_serviceGeodatabase) { return; } m_selectedFeature->attributes()->replaceAttribute("typdamage", fieldVal); if (ServiceFeatureTable* table = m_serviceGeodatabase->table(0); table) { table->updateFeatureAsync(m_selectedFeature) .then(this, [this]() { m_serviceGeodatabase->applyEditsAsync().then(this, [this](const QList<FeatureTableEditResult*>& tableEditResults) { onApplyEditsCompleted_(tableEditResults); }); }); } }, Qt::SingleShotConnection);
m_selectedFeature->load();}
void ManageFeaturesFeatureService::onIdentifyLayerCompleted_(const IdentifyLayerResult* identifyResult){ if (!identifyResult) { return; }
if (identifyResult->geoElements().empty()) { return; }
// Select the first item in the result Feature* feature = static_cast<Feature*>(identifyResult->geoElements().at(0)); m_featureLayer->selectFeature(feature); // Ensure layer isn't deleted with identify result m_featureLayer->setParent(this);
// Query full feature with attributes (could also cast if already ArcGISFeature with attributes loaded) QueryParameters queryParams; const QString whereClause = QStringLiteral("objectid=") + feature->attributes()->attributeValue(QStringLiteral("objectid")).toString(); queryParams.setWhereClause(whereClause); m_serviceGeodatabase->table(0) ->queryFeaturesAsync(queryParams) .then(this, [this](FeatureQueryResult* featureQueryResult) { if (!featureQueryResult || !featureQueryResult->iterator().hasNext()) { return; }
m_selectedFeature = static_cast<ArcGISFeature*>(featureQueryResult->iterator().next(this)); m_selectedFeature->setParent(this); m_featureType = m_selectedFeature->attributes()->attributeValue(QStringLiteral("typdamage")).toString(); m_mapView->calloutData()->setTitle(QString("<br><font size=\"+2\"><b>%1</b></font>").arg(m_featureType)); m_mapView->calloutData()->setLocation(m_selectedFeature->geometry().extent().center()); emit featureTypeChanged(); emit featureSelected(); });}
void ManageFeaturesFeatureService::onApplyEditsCompleted_(const QList<FeatureTableEditResult*>& tableEditResults){ const QScopeGuard deleteAllOnExit{[&tableEditResults]() { qDeleteAll(tableEditResults); }};
if (tableEditResults.isEmpty()) { qDebug() << "No table edit results"; return; }
// Get the first table result const FeatureTableEditResult* tableResult = tableEditResults.first(); if (!tableResult->editResults().isEmpty()) { // Get the first feature edit result from the table const FeatureEditResult* featureEditResult = tableResult->editResults().first(); // Check if there were errors, and if not, log the object ID if (featureEditResult && !featureEditResult->isCompletedWithErrors()) { qDebug() << "Successfully updated Object ID:" << featureEditResult->objectId(); } else { qDebug() << "Apply edits error."; } }}
void ManageFeaturesFeatureService::handleAddFeatureClick_(const QMouseEvent& mouseEvent){ // Add features mode // Obtain the map point const double screenX = mouseEvent.position().x(); const double screenY = mouseEvent.position().y(); Point newPoint = m_mapView->screenToLocation(screenX, screenY);
// Create the feature attributes QMap<QString, QVariant> featureAttributes; featureAttributes.insert("typdamage", "Minor"); featureAttributes.insert("primcause", "Earthquake");
// Get the first table from ServiceGeodatabase ServiceFeatureTable* featureTable = m_serviceGeodatabase->table(0);
// Create a new feature and add it to the feature table Feature* feature = featureTable->createFeature(featureAttributes, newPoint, this); featureTable->addFeatureAsync(feature).then(this, [this]() { // If add feature was successful, call apply edits on ServiceGeodatabase m_serviceGeodatabase->applyEditsAsync().then(this, [](const QList<FeatureTableEditResult*>& tableEditResults) { const QScopeGuard deleteAllOnExit{[&tableEditResults]() { qDeleteAll(tableEditResults); }};
if (tableEditResults.isEmpty()) { return; }
// Get the first table result const FeatureTableEditResult* tableResult = tableEditResults.first(); if (!tableResult->editResults().isEmpty()) { // Get the first feature edit result from the table const FeatureEditResult* featureEditResult = tableResult->editResults().first(); // Check if there were errors, and if not, log the new object ID if (!featureEditResult->isCompletedWithErrors()) { qDebug() << "New Object ID is:" << featureEditResult->objectId(); } else { qDebug() << "Apply edits error."; } } }); });}
void ManageFeaturesFeatureService::handleUpdateGeometryClick_(const QMouseEvent& mouseEvent){ // Update geometry mode // Get the point from the mouse point Point mapPoint = m_mapView->screenToLocation(mouseEvent.position().x(), mouseEvent.position().y());
// If a feature is already selected, move the selected feature to the new geometry if (m_featureSelected) { updateSelectedFeatureGeometry_(mapPoint); } else { selectFeatureForGeometryUpdate_(mouseEvent); }}
void ManageFeaturesFeatureService::handleIdentifyFeatureClick_(const QMouseEvent& mouseEvent){ // Identify and select feature mode (for delete and update attributes) // First clear the selection m_featureLayer->clearSelection();
// Set the properties for qml emit hideWindow();
// Call identify on the map view constexpr double tolerance = 5.0; constexpr int maxResults = 1; constexpr bool returnPopupsOnly = false; m_mapView->identifyLayerAsync(m_featureLayer, mouseEvent.position(), tolerance, returnPopupsOnly, maxResults) .then(this, [this](IdentifyLayerResult* rawIdentifyResult) { std::unique_ptr<IdentifyLayerResult> identifyResult(rawIdentifyResult); onIdentifyLayerCompleted_(identifyResult.get()); });}
void ManageFeaturesFeatureService::updateSelectedFeatureGeometry_(const Point& mapPoint){ // Set the selected feature's geometry to the tapped map point m_selectedFeature->setGeometry(mapPoint);
// Get the feature table that contains this feature ServiceFeatureTable* featureTable = static_cast<ServiceFeatureTable*>(m_selectedFeature->featureTable());
// Update the feature table with the new feature featureTable->updateFeatureAsync(m_selectedFeature) .then(this, [this]() { // Once updateFeatureAsync is done, call applyEditsAsync on ServiceGeodatabase m_serviceGeodatabase->applyEditsAsync().then(this, [](const QList<FeatureTableEditResult*>& tableEditResults) { const QScopeGuard deleteAllOnExit{[&tableEditResults]() { qDeleteAll(tableEditResults); }};
if (tableEditResults.isEmpty()) { return; }
// Get the first table result const FeatureTableEditResult* tableResult = tableEditResults.first(); if (!tableResult->editResults().isEmpty()) { // Get the first feature edit result from the table const FeatureEditResult* featureEditResult = tableResult->editResults().first(); // Check if there were errors, and if not, log the object ID if (featureEditResult && !featureEditResult->isCompletedWithErrors()) { qDebug() << "Successfully updated geometry for Object ID:" << featureEditResult->objectId(); } else { qDebug() << "Apply edits error."; } } }); });
// Reset the feature layer m_featureLayer->clearSelection(); m_featureSelected = false;}
void ManageFeaturesFeatureService::selectFeatureForGeometryUpdate_(const QMouseEvent& mouseEvent){ // First clear the selection m_featureLayer->clearSelection();
// Call identify on the map view constexpr double tolerance = 5.0; constexpr int maxResults = 1; constexpr bool returnPopupsOnly = false; m_mapView->identifyLayerAsync(m_featureLayer, mouseEvent.position(), tolerance, returnPopupsOnly, maxResults) .then(this, [this](IdentifyLayerResult* rawIdentifyResult) { std::unique_ptr<IdentifyLayerResult> identifyResult(rawIdentifyResult); if (!identifyResult) { return; }
if (identifyResult->geoElements().isEmpty()) { return; }
Feature* feature = static_cast<Feature*>(identifyResult->geoElements().at(0)); QueryParameters query; query.setObjectIds(QList<qint64>{feature->attributes()->attributeValue(QStringLiteral("objectid")).toLongLong()}); m_featureLayer->selectFeaturesAsync(query, SelectionMode::New) .then(this, [](FeatureQueryResult* rawResult) { std::unique_ptr<FeatureQueryResult>{rawResult}; });
m_selectedFeature = static_cast<ArcGISFeature*>(feature); m_selectedFeature->setParent(this); m_featureSelected = true; });}// [WriteFile Name=ManageFeaturesFeatureService, Category=EditData]// [Legal]// Copyright 2025 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 MANAGEFEATURESFEATURESERVICE_H#define MANAGEFEATURESFEATURESERVICE_H
// Qt headers#include <QQuickItem>
namespace Esri::ArcGISRuntime{ class ArcGISFeature; class Feature; class FeatureLayer; class FeatureQueryResult; class FeatureTableEditResult; class IdentifyLayerResult; class Map; class MapQuickView; class Point; class ServiceGeodatabase;} // namespace Esri::ArcGISRuntime
class QString;
class ManageFeaturesFeatureService : public QQuickItem{ Q_OBJECT
Q_PROPERTY(QString featureType READ featureType NOTIFY featureTypeChanged) Q_PROPERTY(OperationMode operationMode READ operationMode WRITE setOperationMode NOTIFY operationModeChanged)
public: enum class OperationMode { AddFeatures, DeleteFeatures, UpdateAttributes, UpdateGeometry }; Q_ENUM(OperationMode)
explicit ManageFeaturesFeatureService(QQuickItem* parent = nullptr); ~ManageFeaturesFeatureService() override;
void componentComplete() override; static void init();
Q_INVOKABLE void deleteSelectedFeature(); Q_INVOKABLE void updateSelectedFeature(const QString& fieldVal);
OperationMode operationMode() const; void setOperationMode(OperationMode mode); QString featureType() const;
signals: void featureSelected(); void featureTypeChanged(); void hideWindow(); void operationModeChanged();
private: void connectSignals_(); void onIdentifyLayerCompleted_(const Esri::ArcGISRuntime::IdentifyLayerResult* identifyResult); void onApplyEditsCompleted_(const QList<Esri::ArcGISRuntime::FeatureTableEditResult*>& tableEditResults);
void handleAddFeatureClick_(const QMouseEvent& mouseEvent); void handleUpdateGeometryClick_(const QMouseEvent& mouseEvent); void handleIdentifyFeatureClick_(const QMouseEvent& mouseEvent); void updateSelectedFeatureGeometry_(const Esri::ArcGISRuntime::Point& mapPoint); void selectFeatureForGeometryUpdate_(const QMouseEvent& mouseEvent);
Esri::ArcGISRuntime::Map* m_map = nullptr; Esri::ArcGISRuntime::MapQuickView* m_mapView = nullptr; Esri::ArcGISRuntime::FeatureLayer* m_featureLayer = nullptr; Esri::ArcGISRuntime::ServiceGeodatabase* m_serviceGeodatabase = nullptr; QPointer<Esri::ArcGISRuntime::ArcGISFeature> m_selectedFeature; QString m_featureType; OperationMode m_operationMode = OperationMode::AddFeatures; bool m_featureSelected = false; QMetaObject::Connection m_featureLoadStatusChangedConnection;};
#endif // MANAGEFEATURESFEATURESERVICE_H// [WriteFile Name=ManageFeaturesFeatureService, Category=EditData]// [Legal]// Copyright 2025 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.Samplesimport Esri.ArcGISRuntime.Toolkit
ManageFeaturesFeatureServiceSample { id: addFeaturesSample width: 800 height: 600
readonly property var featAttributes: ["Destroyed", "Major", "Minor", "Affected", "Inaccessible"] readonly property var operationModes: ["Add Features", "Delete Features", "Update Attributes", "Update Geometry"]
// MapView component MapView { id: view anchors.fill: parent objectName: "mapView"
Component.onCompleted: { // Set the focus on MapView to initially enable keyboard navigation forceActiveFocus(); }
// Callout for Delete and Update Attributes modes Callout { id: callout calloutData: view.calloutData leaderPosition: Callout.LeaderPosition.Automatic
// Delete mode - show trash button, Update mode - show accessory button accessoryButtonType: addFeaturesSample.operationMode === ManageFeaturesFeatureService.OperationMode.DeleteFeatures ? "Custom" : (addFeaturesSample.operationMode === ManageFeaturesFeatureService.OperationMode.UpdateAttributes ? "Info" : "None")
customImageUrl: addFeaturesSample.operationMode === ManageFeaturesFeatureService.OperationMode.DeleteFeatures ? "qrc:/Samples/EditData/ManageFeaturesFeatureService/trash-24.svg" : ""
onAccessoryButtonClicked: { if (addFeaturesSample.operationMode === ManageFeaturesFeatureService.OperationMode.DeleteFeatures) { if (callout.visible) callout.dismiss(); addFeaturesSample.deleteSelectedFeature(); } else if (addFeaturesSample.operationMode === ManageFeaturesFeatureService.OperationMode.UpdateAttributes) { updateWindow.visible = true; } } } }
// Text metrics to measure longest option TextMetrics { id: textMetrics font.pixelSize: 12 text: qsTr("Update Attributes") }
// Simple right panel - only takes space it needs Rectangle { id: rightPanel anchors { top: parent.top right: parent.right margins: 10 } width: Math.max(textMetrics.width + 60, 200) + 20 height: instructionText.visible ? 100 : 55 border.width: 1 radius: 5 color: palette.base
// Mouse/Touch area to prevent mouse events from propogating through the UI MouseArea { anchors.fill: parent acceptedButtons: Qt.AllButtons propagateComposedEvents: false
onWheel: { } }
MultiPointTouchArea { anchors.fill: parent }
Column { anchors { top: parent.top left: parent.left right: parent.right margins: 10 } spacing: 5
ComboBox { id: modeComboBox width: parent.width height: 35 model: operationModes currentIndex: addFeaturesSample.operationMode
onCurrentIndexChanged: { addFeaturesSample.operationMode = currentIndex } }
Label { id: instructionText width: parent.width font.pixelSize: 11 wrapMode: Text.WordWrap text: { switch(addFeaturesSample.operationMode) { case ManageFeaturesFeatureService.OperationMode.AddFeatures: return qsTr("Click anywhere on the map to add new features") case ManageFeaturesFeatureService.OperationMode.DeleteFeatures: return qsTr("Click on an existing feature to select and delete it") case ManageFeaturesFeatureService.OperationMode.UpdateAttributes: return qsTr("Click on an existing feature to select and update its attributes") case ManageFeaturesFeatureService.OperationMode.UpdateGeometry: return qsTr("Click to select a feature, then click again to move it to a new location") default: return qsTr("") } } } } }
// Handle feature selection for callout modes onFeatureSelected: { if (addFeaturesSample.operationMode === ManageFeaturesFeatureService.OperationMode.DeleteFeatures || addFeaturesSample.operationMode === ManageFeaturesFeatureService.OperationMode.UpdateAttributes) { // Show the callout callout.showCallout();
if (addFeaturesSample.operationMode === ManageFeaturesFeatureService.OperationMode.UpdateAttributes) { // Set the combo box's default value for update attributes mode damageComboBox.currentIndex = featAttributes.indexOf(addFeaturesSample.featureType); } } }
onHideWindow: { // Hide the callout if (callout.visible) callout.dismiss(); // Hide the update window updateWindow.visible = false; }
// Simple Update Attributes Window Rectangle { id: updateWindow width: 360 height: 180 anchors.centerIn: parent radius: 8 visible: false border.width: 1 z: 200 color: palette.base
MouseArea { anchors.fill: parent acceptedButtons: Qt.LeftButton | Qt.RightButton onClicked: mouse => mouse.accepted = true onDoubleClicked: mouse => mouse.accepted = true onWheel: wheel => wheel.accepted = true }
Column { anchors.fill: parent anchors.margins: 20 spacing: 15
Label { text: qsTr("Update Feature Attribute") font.pixelSize: 16 font.bold: true anchors.horizontalCenter: parent.horizontalCenter }
Column { width: parent.width spacing: 8
Label { text: qsTr("Damage Type:") font.pixelSize: 12 font.bold: true }
ComboBox { id: damageComboBox width: parent.width height: 35 model: featAttributes } }
Row { anchors.horizontalCenter: parent.horizontalCenter spacing: 10
Button { text: qsTr("Update") width: 100 height: 35
onClicked: { if (callout.visible) callout.dismiss(); updateWindow.visible = false; addFeaturesSample.updateSelectedFeature(damageComboBox.currentText) } }
Button { text: qsTr("Cancel") width: 100 height: 35
onClicked: updateWindow.visible = false; } } } }}// [Legal]// Copyright 2025 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 "ManageFeaturesFeatureService.h"
// ArcGIS Maps SDK headers#include "ArcGISRuntimeEnvironment.h"
// Qt headers#include <QCommandLineParser>#include <QDir>#include <QGuiApplication>#include <QQmlApplicationEngine>
// Other headers#include "Esri/ArcGISRuntime/Toolkit/register.h"
// Platform specific headers#ifdef Q_OS_WIN#include <Windows.h>#endif
int main(int argc, char* argv[]){ QGuiApplication app(argc, argv); app.setApplicationName(QString("ManageFeaturesFeatureService"));
// 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 ManageFeaturesFeatureService::init();
// Initialize application view QQmlApplicationEngine engine; // Add the import Path engine.addImportPath(QDir(QCoreApplication::applicationDirPath()).filePath("qml"));
// Register the application view with the toolkit Esri::ArcGISRuntime::Toolkit::registerComponents(engine);
#ifdef ARCGIS_RUNTIME_IMPORT_PATH_2 engine.addImportPath(ARCGIS_RUNTIME_IMPORT_PATH_2);#endif
// Set the source engine.load(QUrl("qrc:/Samples/EditData/ManageFeaturesFeatureService/main.qml"));
return app.exec();}// Copyright 2025 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
ManageFeaturesFeatureService { anchors.fill: parent }}