diff --git a/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/GeometryEditorButton.qml b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/GeometryEditorButton.qml
new file mode 100644
index 0000000000..d9c2f51428
--- /dev/null
+++ b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/GeometryEditorButton.qml
@@ -0,0 +1,64 @@
+// [WriteFile Name=CreateAndEditGeometries, Category=Geometry]
+// [Legal]
+// Copyright 2023 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 QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+
+// This component defines each of the buttons in the Geometry Editor control UI
+
+RoundButton {
+ id: geometryEditorButton
+
+ property string buttonName: ""
+ property string iconPath: ""
+
+ Layout.fillWidth: true
+
+ // Set the focus policy so that the buttons do not take focus from the MapView
+ focusPolicy: Qt.NoFocus
+
+ radius: 5
+
+ Rectangle {
+ anchors.fill: parent
+ radius: parent.radius
+ opacity: parent.enabled || parent.checked ? 1 : 0.3
+ color: geometryEditorButton.down ? "#d0d0d0" : "#e0e0e0"
+ }
+
+ Image {
+ id: imgComponent
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ verticalCenter: parent.verticalCenter
+ verticalCenterOffset: -textComponent.height/2
+ }
+ source: iconPath
+ width: 20
+ fillMode: Image.PreserveAspectFit
+ }
+
+ Text {
+ id: textComponent
+ anchors {
+ top: imgComponent.bottom
+ horizontalCenter: parent.horizontalCenter
+ }
+ text: buttonName
+ font.pixelSize: 8
+ }
+}
diff --git a/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/Info.plist b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/Info.plist
new file mode 100644
index 0000000000..59320340a3
--- /dev/null
+++ b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/Info.plist
@@ -0,0 +1,55 @@
+
+
+
+
+ CFBundleDisplayName
+ SnapGeometryEdits
+ CFBundleExecutable
+ SnapGeometryEdits
+ CFBundleGetInfoString
+ ArcGIS
+ CFBundleIcons~ipad
+
+ CFBundleIdentifier
+ com.esri.${PRODUCT_NAME:rfc1034identifier}
+ CFBundleName
+ ${PRODUCT_NAME}
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1.0
+ NOTE
+ This app is cool
+ UIFileSharingEnabled
+ FALSE
+ UIRequiresPersistentWiFi
+ NO
+ LSRequiresIPhoneOS
+
+ NSLocationAlwaysUsageDescription
+
+ NSLocationWhenInUseUsageDescription
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UILaunchStoryboardName
+ LaunchScreen
+
+
+
diff --git a/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/SnapGeometryEdits.cpp b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/SnapGeometryEdits.cpp
new file mode 100644
index 0000000000..3ccafab4b3
--- /dev/null
+++ b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/SnapGeometryEdits.cpp
@@ -0,0 +1,349 @@
+// [WriteFile Name=SnapGeometryEdits, Category=EditData]
+// [Legal]
+// Copyright 2024 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]
+
+#include "Geometry.h"
+#ifdef PCH_BUILD
+#include "pch.hpp"
+#endif // PCH_BUILD
+
+#include "SnapGeometryEdits.h"
+
+#include "Map.h"
+#include "MapQuickView.h"
+#include "MapTypes.h"
+#include "Portal.h"
+#include "PortalItem.h"
+#include "SnapGeometryEdits.h"
+#include "LoadSettings.h"
+#include "LayerListModel.h"
+#include "Layer.h"
+#include "GeometryEditor.h"
+#include "GraphicsOverlay.h"
+#include "GeometryEditor.h"
+#include "GeometryTypes.h"
+#include "GraphicsOverlayListModel.h"
+#include "SimpleFillSymbol.h"
+#include "SimpleLineSymbol.h"
+#include "SimpleMarkerSymbol.h"
+#include "SymbolTypes.h"
+#include "IdentifyGraphicsOverlayResult.h"
+#include "Graphic.h"
+#include "SnapSettings.h"
+#include "SnapSourceSettings.h"
+#include "GraphicListModel.h"
+#include "GeometryEditorElement.h"
+#include "FeatureLayer.h"
+#include "FeatureTable.h"
+
+#include
+
+using namespace Esri::ArcGISRuntime;
+
+SnapGeometryEdits::SnapGeometryEdits(QObject* parent /* = nullptr */) :
+ QObject(parent),
+ m_portal(new Portal(this)),
+ m_portalItem(new PortalItem(m_portal, "b95fe18073bc4f7788f0375af2bb445e", this))
+{
+ m_map = new Map(m_portalItem, this);
+ m_map->loadSettings()->setFeatureTilingMode(FeatureTilingMode::EnabledWhenSupported);
+ m_geometryEditor = new GeometryEditor(this);
+ m_graphicsOverlay = new GraphicsOverlay(this);
+ m_tempGraphicsParent = new QObject(this);
+ connect(m_map, &Map::doneLoading, this, [this]()
+ {
+ for (Layer* layer : *m_map->operationalLayers())
+ {
+ connect(layer, &Layer::doneLoading, this, [layer]()
+ {
+ qDebug() << "done" << layer->name();
+ });
+ }
+ });
+ }
+
+
+
+
+SnapGeometryEdits::~SnapGeometryEdits() = default;
+
+void SnapGeometryEdits::init()
+{
+ // Register the map view for QML
+ qmlRegisterType("Esri.Samples", 1, 0, "MapView");
+ qmlRegisterType("Esri.Samples", 1, 0, "SnapGeometryEditsSample");
+}
+
+MapQuickView* SnapGeometryEdits::mapView() const
+{
+ return m_mapView;
+}
+
+// Set the view (created in QML)
+void SnapGeometryEdits::setMapView(MapQuickView* mapView)
+{
+ if (!mapView || mapView == m_mapView)
+ return;
+
+ m_mapView = mapView;
+ m_mapView->setMap(m_map);
+
+ m_mapView->graphicsOverlays()->append(m_graphicsOverlay);
+
+ // Set the geometry editor on the map view
+ m_mapView->setGeometryEditor(m_geometryEditor);
+
+ m_mapView->setMagnifierEnabled(true);
+
+
+ emit mapViewChanged();
+ createInitialSymbols();
+ createConnections();
+
+ // showBottomSheet();
+}
+
+// Create symbols used by all graphics
+void SnapGeometryEdits::createInitialSymbols()
+{
+ m_pointSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Square, QColor(255, 45, 0), 20, this);
+ m_multiPointSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Square, QColor(255, 45, 0), 20, this);
+ m_lineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor(255, 45, 0), 2, this);
+ m_polygonSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle::Solid, QColor(255, 0, 0, 75),
+ new SimpleLineSymbol(SimpleLineSymbolStyle::Dash, QColor(0, 0, 0), 1.0, this), this);
+}
+
+void SnapGeometryEdits::createConnections()
+{
+ qDebug() << "1";
+
+ // Allow user to edit existing graphics by clicking on them
+ connect(m_mapView, &MapQuickView::mouseClicked, this, [this](const QMouseEvent& mouseEvent)
+ {qDebug() << "2";
+ if (!m_geometryEditor->isStarted())
+ {qDebug() << "3";
+ m_mapView->identifyGraphicsOverlayAsync(m_graphicsOverlay, mouseEvent.position(), 10 ,false).then(this,
+ [this](IdentifyGraphicsOverlayResult* rawResult){
+ // Handle editing selected graphics, if any
+
+ auto identifyResult = std::unique_ptr(rawResult);
+
+ // Return if no graphics were identified
+ if (identifyResult->graphics().isEmpty())
+ return;
+
+ m_editingGraphic = identifyResult->graphics().first();
+
+ // Hide the graphic currently being edited
+ m_editingGraphic->setVisible(false);
+
+ // Start the geometry editor with the graphic's geometry. This does not directly affect the graphic.
+ m_geometryEditor->start(m_editingGraphic->geometry());
+
+ emit geometryEditorStartedChanged();
+ });
+ }
+ emit canUndoChanged();
+ emit elementIsSelectedChanged();
+ });
+
+ // Enable or disable buttons when mouse is released (ie after a drag operation)
+ connect(m_mapView, &MapQuickView::mouseReleased, this, [this](const QMouseEvent&)
+ {
+ emit canUndoChanged();
+ emit elementIsSelectedChanged();
+ });
+}
+
+bool SnapGeometryEdits::geometryEditorStarted() const
+{
+ return (m_geometryEditor && m_geometryEditor->isStarted());
+}
+
+bool SnapGeometryEdits::canUndo()
+{
+ return (m_geometryEditor && m_geometryEditor->canUndo());
+}
+
+bool SnapGeometryEdits::elementIsSelected()
+{
+ return (m_geometryEditor && m_geometryEditor->selectedElement() && m_geometryEditor->selectedElement()->canDelete());
+}
+
+void SnapGeometryEdits::snappingEnabledStatus(bool snappingCheckedState)
+{
+ m_geometryEditor->snapSettings()->setEnabled(snappingCheckedState);
+}
+
+void SnapGeometryEdits::pointSourceEnabledStatus(bool snappingCheckedState, int index)
+{
+ m_pointSourceCheckedState[index] = snappingCheckedState;
+ m_geometryEditor->snapSettings()->sourceSettings()[index]->setEnabled(m_pointSourceCheckedState[index]);
+
+}
+
+void SnapGeometryEdits::polylineSourceEnabledStatus(bool snappingCheckedState, int index)
+{
+ m_polylineSourceCheckedState[index] = snappingCheckedState;
+ m_geometryEditor->snapSettings()->sourceSettings()[index]->setEnabled(m_polylineSourceCheckedState[index]);
+
+}
+
+void SnapGeometryEdits::onPointLayersEnabled()
+{
+ for (int index = 0; index < m_snapSourceList.size()-1; ++index)
+ {
+ FeatureLayer *featureLayer = static_cast(m_snapSourceList[index]->source());
+ if (featureLayer && featureLayer->featureTable() && featureLayer->featureTable()->geometryType() == GeometryType::Point)
+ {
+ pointSourceEnabledStatus(true, index);
+ }
+ }
+ emit pointSourceCheckedStateChanged();
+}
+
+void SnapGeometryEdits::onPolylineLayersEnabled()
+{
+ for (int index = 0; index < m_snapSourceList.size()-1; ++index)
+ {
+ FeatureLayer *featureLayer = static_cast(m_snapSourceList[index]->source());
+ if (featureLayer && featureLayer->featureTable() && featureLayer->featureTable()->geometryType() == GeometryType::Polyline)
+ {
+ polylineSourceEnabledStatus(true, index);
+ }
+ }
+ emit polylineSourceCheckedStateChanged();
+}
+
+void SnapGeometryEdits::startEditor(GeometryEditorMode geometryEditorMode)
+{
+ switch (geometryEditorMode)
+ {
+ case GeometryEditorMode::PointMode:
+ m_geometryEditor->start(Esri::ArcGISRuntime::GeometryType::Point);
+ break;
+
+ case GeometryEditorMode::MultipointMode:
+ m_geometryEditor->start(Esri::ArcGISRuntime::GeometryType::Multipoint);
+ break;
+
+ case GeometryEditorMode::PolylineMode:
+ m_geometryEditor->start(Esri::ArcGISRuntime::GeometryType::Polyline);
+ break;
+
+ case GeometryEditorMode::PolygonMode:
+ m_geometryEditor->start(Esri::ArcGISRuntime::GeometryType::Polygon);
+ break;
+
+ default:
+ break;
+ }
+
+ emit geometryEditorStartedChanged();
+}
+
+void SnapGeometryEdits::stopEditor()
+{
+ const Geometry geometry = m_geometryEditor->stop();
+ emit geometryEditorStartedChanged();
+
+ if (m_editingGraphic)
+ {
+ m_editingGraphic->setGeometry(geometry);
+
+ // Show the graphic and clear the selection
+ m_editingGraphic->setVisible(true);
+ m_editingGraphic = nullptr;
+
+ return;
+ }
+
+ Symbol* geometrySymbol = nullptr;
+ switch (geometry.geometryType())
+ {
+ case GeometryType::Point:
+ geometrySymbol = m_pointSymbol;
+ break;
+
+ case GeometryType::Multipoint:
+ geometrySymbol = m_multiPointSymbol;
+ break;
+
+ case GeometryType::Polyline:
+ geometrySymbol = m_lineSymbol;
+ break;
+
+ case GeometryType::Polygon:
+ geometrySymbol = m_polygonSymbol;
+ break;
+
+ default:
+ return;
+ }
+
+ // Append the new graphic to the graphics overlay
+ m_graphicsOverlay->graphics()->append(new Graphic(geometry, geometrySymbol, m_tempGraphicsParent));
+}
+
+void SnapGeometryEdits::deleteSelection()
+{
+ m_geometryEditor->deleteSelectedElement();
+ emit canUndoChanged();
+}
+
+void SnapGeometryEdits::editorUndo()
+{
+ // if (m_geometryEditor->canUndo())
+ m_geometryEditor->undo();
+ emit canUndoChanged();
+}
+
+void SnapGeometryEdits::configureSnapping()
+{
+
+ if (m_geometryEditor->snapSettings()->sourceSettings().empty())
+ {
+
+ m_geometryEditor->snapSettings()->syncSourceSettings();
+ m_geometryEditor->snapSettings()->setEnabled(true);
+
+ m_snapSourceList = m_geometryEditor->snapSettings()->sourceSettings();
+ qDebug() << m_snapSourceList.size();
+ qDebug() << static_cast(m_snapSourceList[0]->source())->name();
+ qDebug() << static_cast(m_snapSourceList[1]->source())->name();
+ qDebug() << static_cast(m_snapSourceList[2]->source())->name();
+ qDebug() << static_cast(m_snapSourceList[3]->source())->name();
+ }
+
+ m_pointLayers.clear();
+ m_polylineLayers.clear();
+ for (int index = 0; index < m_snapSourceList.size()-1; ++index)
+ {
+ FeatureLayer *featureLayer = static_cast(m_snapSourceList[index]->source());
+ if (featureLayer->featureTable()->geometryType() == GeometryType::Point)
+ {
+ m_pointLayers.append(featureLayer->name());
+ m_pointSourceCheckedState.append(m_snapSourceList[index]->isEnabled());
+ }
+ else if (featureLayer->featureTable()->geometryType() == GeometryType::Polyline)
+ {
+ m_polylineLayers.append(featureLayer->name());
+ m_polylineSourceCheckedState.append(m_snapSourceList[index]->isEnabled());
+ }
+ }
+
+ emit pointLayersChanged();
+ emit polylineLayersChanged();
+}
diff --git a/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/SnapGeometryEdits.h b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/SnapGeometryEdits.h
new file mode 100644
index 0000000000..fef337ce4a
--- /dev/null
+++ b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/SnapGeometryEdits.h
@@ -0,0 +1,117 @@
+// [WriteFile Name=SnapGeometryEdits, Category=EditData]
+// [Legal]
+// Copyright 2024 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 SNAPGEOMETRYEDITS_H
+#define SNAPGEOMETRYEDITS_H
+
+#include "GeometryEditor.h"
+namespace Esri::ArcGISRuntime {
+ class Map;
+ class MapQuickView;
+ class Portal;
+ class PortalItem;
+ class GeometryEditor;
+ class Graphic;
+ class GraphicsOverlay;
+ class SimpleMarkerSymbol;
+ class SimpleLineSymbol;
+ class SimpleFillSymbol;
+ class SnapSourceSettings;
+}
+
+#include
+
+Q_MOC_INCLUDE("MapQuickView.h");
+
+class SnapGeometryEdits : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(Esri::ArcGISRuntime::MapQuickView* mapView READ mapView WRITE setMapView NOTIFY mapViewChanged)
+ Q_PROPERTY(bool geometryEditorStarted READ geometryEditorStarted NOTIFY geometryEditorStartedChanged)
+ Q_PROPERTY(bool canUndo READ canUndo NOTIFY canUndoChanged)
+ Q_PROPERTY(bool elementIsSelected READ elementIsSelected NOTIFY elementIsSelectedChanged)
+ Q_PROPERTY(QList pointLayers MEMBER m_pointLayers NOTIFY pointLayersChanged)
+ Q_PROPERTY(QList polylineLayers MEMBER m_polylineLayers NOTIFY polylineLayersChanged)
+ Q_PROPERTY(QList pointSourceCheckedState MEMBER m_pointSourceCheckedState NOTIFY pointSourceCheckedStateChanged)
+ Q_PROPERTY(QList polylineSourceCheckedState MEMBER m_polylineSourceCheckedState NOTIFY polylineSourceCheckedStateChanged)
+
+public:
+ explicit SnapGeometryEdits(QObject* parent = nullptr);
+ ~SnapGeometryEdits() override;
+
+ enum class GeometryEditorMode {
+ PointMode,
+ MultipointMode,
+ PolylineMode,
+ PolygonMode
+ };
+
+ Q_ENUM(GeometryEditorMode)
+
+ static void init();
+ Q_INVOKABLE void startEditor(GeometryEditorMode geometryEditorMode);
+ Q_INVOKABLE void stopEditor();
+ Q_INVOKABLE void deleteSelection();
+ Q_INVOKABLE void editorUndo();
+ Q_INVOKABLE void snappingEnabledStatus(bool checkedValue);
+ Q_INVOKABLE void onPointLayersEnabled();
+ Q_INVOKABLE void onPolylineLayersEnabled();
+ Q_INVOKABLE void configureSnapping();
+ Q_INVOKABLE void pointSourceEnabledStatus(bool snappingCheckedState, int index);
+ Q_INVOKABLE void polylineSourceEnabledStatus(bool snappingCheckedState, int index);
+
+signals:
+ void mapViewChanged();
+ void geometryEditorStartedChanged();
+ void canUndoChanged();
+ void elementIsSelectedChanged();
+ void polylineLayersChanged();
+ void pointLayersChanged();
+ void pointSourceCheckedStateChanged();
+ void polylineSourceCheckedStateChanged();
+
+private:
+ Esri::ArcGISRuntime::MapQuickView* mapView() const;
+ void setMapView(Esri::ArcGISRuntime::MapQuickView* mapView);
+ bool geometryEditorStarted() const;
+ void createInitialSymbols();
+ void createConnections();
+ bool canUndo();
+ bool elementIsSelected();
+
+
+
+ Esri::ArcGISRuntime::Map* m_map = nullptr;
+ Esri::ArcGISRuntime::MapQuickView* m_mapView = nullptr;
+ Esri::ArcGISRuntime::Portal* m_portal = nullptr;
+ Esri::ArcGISRuntime::PortalItem* m_portalItem = nullptr;
+ Esri::ArcGISRuntime::GraphicsOverlay* m_graphicsOverlay = nullptr;
+ Esri::ArcGISRuntime::Graphic* m_editingGraphic = nullptr;
+ Esri::ArcGISRuntime::GeometryEditor* m_geometryEditor = nullptr;
+ Esri::ArcGISRuntime::SimpleMarkerSymbol* m_pointSymbol = nullptr;
+ Esri::ArcGISRuntime::SimpleMarkerSymbol* m_multiPointSymbol = nullptr;
+ Esri::ArcGISRuntime::SimpleLineSymbol* m_lineSymbol = nullptr;
+ Esri::ArcGISRuntime::SimpleFillSymbol* m_polygonSymbol = nullptr;
+ QList m_pointSourceCheckedState;
+ QList m_polylineSourceCheckedState;
+ QList m_snapSourceList;
+ QList m_pointLayers;
+ QList m_polylineLayers;
+ QObject* m_tempGraphicsParent = nullptr;
+};
+
+#endif // SNAPGEOMETRYEDITS_H
diff --git a/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/SnapGeometryEdits.pro b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/SnapGeometryEdits.pro
new file mode 100644
index 0000000000..8555b4c0b4
--- /dev/null
+++ b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/SnapGeometryEdits.pro
@@ -0,0 +1,65 @@
+#-------------------------------------------------
+# Copyright 2024 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.
+#-------------------------------------------------
+
+mac {
+ cache()
+}
+
+#-------------------------------------------------------------------------------
+
+CONFIG += c++17
+
+# additional modules are pulled in via arcgisruntime.pri
+QT += opengl qml quick
+
+TEMPLATE = app
+TARGET = SnapGeometryEdits
+
+ARCGIS_RUNTIME_VERSION = 200.5.0
+include($$PWD/arcgisruntime.pri)
+
+#-------------------------------------------------------------------------------
+
+HEADERS += \
+ SnapGeometryEdits.h
+
+SOURCES += \
+ main.cpp \
+ SnapGeometryEdits.cpp
+
+RESOURCES += SnapGeometryEdits.qrc
+
+#-------------------------------------------------------------------------------
+
+win32 {
+ LIBS += \
+ Ole32.lib
+}
+
+ios {
+ INCLUDEPATH += $$PWD
+ DEPENDPATH += $$PWD
+
+ OTHER_FILES += \
+ $$PWD/Info.plist
+
+ QMAKE_INFO_PLIST = $$PWD/Info.plist
+}
+
+android {
+ INCLUDEPATH += $$PWD
+ DEPENDPATH += $$PWD
+}
+android: include(/Users/har13205/Library/Android/sdk/android_openssl/openssl.pri)
diff --git a/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/SnapGeometryEdits.qml b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/SnapGeometryEdits.qml
new file mode 100644
index 0000000000..6c3e0307d3
--- /dev/null
+++ b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/SnapGeometryEdits.qml
@@ -0,0 +1,521 @@
+// [WriteFile Name=SnapGeometryEdits, Category=EditData]
+// [Legal]
+// Copyright 2024 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 QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import Esri.Samples
+
+Item {
+ // property var phases: ["System Value", "Service Connection", "Curb Stop Value"]
+ property var pointLayers: snapGeometryEditsSampleModel.pointLayers
+ property var polylineLayers: ["Lateral","Main"]
+ // add a mapView component
+ MapView {
+ id: view
+ anchors.fill: parent
+
+ Component.onCompleted: {
+ // Set and keep the focus on MapView to enable keyboard navigation
+ forceActiveFocus();
+ }
+ }
+
+ // Declare the C++ instance which creates the map etc. and supply the view
+ SnapGeometryEditsSample {
+ id: snapGeometryEditsSampleModel
+ mapView: view
+ }
+
+Rectangle {
+
+ anchors {
+ right: parent.right
+ margins: 10
+ }
+
+ Control {
+ id: control
+ anchors.right: parent.right
+ padding: 5
+ width: 140
+
+ background: Rectangle {
+ color: "black"
+ opacity: .5
+ }
+
+ contentItem: ColumnLayout {
+ id: columns
+ anchors {
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+
+ GridLayout {
+ id: geometryColumn
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+ columns: 2
+
+ Text {
+ id: geometryHeader
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+ Layout.columnSpan: 2
+ text: "Create"
+ color: "white"
+ font.pixelSize: 16
+ font.bold: true
+ }
+
+ GeometryEditorButton {
+ id: pointButton
+ buttonName: qsTr("Point")
+ iconPath: "qrc:/Samples/EditData/SnapGeometryEdits/iconAssets/point-32.png"
+ checkable: true
+ enabled: !snapGeometryEditsSampleModel.geometryEditorStarted
+ onClicked: {
+ snapGeometryEditsSampleModel.startEditor(SnapGeometryEditsSample.PointMode);
+ }
+ }
+
+ GeometryEditorButton {
+ id: multiPointButton
+ buttonName: qsTr("Multipoint")
+ iconPath: "qrc:/Samples/EditData/SnapGeometryEdits/iconAssets/multipoint-32.png"
+ checkable: true
+ enabled: !snapGeometryEditsSampleModel.geometryEditorStarted
+ onClicked: {
+ snapGeometryEditsSampleModel.startEditor(SnapGeometryEditsSample.MultipointMode);
+ }
+ }
+
+ GeometryEditorButton {
+ id: lineButton
+ buttonName: qsTr("Line")
+ iconPath: "qrc:/Samples/EditData/SnapGeometryEdits/iconAssets/line-32.png"
+ checkable: true
+ enabled: !snapGeometryEditsSampleModel.geometryEditorStarted
+ onClicked: {
+ snapGeometryEditsSampleModel.startEditor(SnapGeometryEditsSample.PolylineMode);
+ }
+ }
+
+ GeometryEditorButton {
+ id: polygonButton
+ buttonName: qsTr("Polygon")
+ iconPath: "qrc:/Samples/EditData/SnapGeometryEdits/iconAssets/polygon-32.png"
+ checkable: true
+ enabled: !snapGeometryEditsSampleModel.geometryEditorStarted
+ onClicked: {
+ snapGeometryEditsSampleModel.startEditor(SnapGeometryEditsSample.PolygonMode);
+ }
+ }
+ }
+
+ GridLayout {
+ id: editingColumn
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+ columns: 2
+
+ Text {
+ id: editingHeader
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+ Layout.columnSpan: 2
+ text: qsTr("Edit")
+ color: "white"
+ font.pixelSize: 16
+ font.bold: true
+ }
+
+ GeometryEditorButton {
+ id: undoButton
+ buttonName: qsTr("Undo")
+ iconPath: "qrc:/Samples/EditData/SnapGeometryEdits/iconAssets/undo-32.png"
+ enabled: snapGeometryEditsSampleModel.geometryEditorStarted && snapGeometryEditsSampleModel.canUndo
+ onClicked: snapGeometryEditsSampleModel.editorUndo();
+ }
+
+ GeometryEditorButton {
+ id: deleteVertexButton
+ buttonName: qsTr("Delete")
+ iconPath: "qrc:/Samples/EditData/SnapGeometryEdits/iconAssets/erase-32.png"
+ // Layout.columnSpan: 2
+ enabled: snapGeometryEditsSampleModel.geometryEditorStarted || snapGeometryEditsSampleModel.elementIsSelected
+ onClicked: snapGeometryEditsSampleModel.deleteSelection();
+ }
+
+ GeometryEditorButton {
+ id: saveEditsButton
+ buttonName: qsTr("Save")
+ iconPath: "qrc:/Samples/EditData/SnapGeometryEdits/iconAssets/save-32.png"
+ Layout.columnSpan: 2
+ enabled: snapGeometryEditsSampleModel.geometryEditorStarted
+ onClicked: {
+ snapGeometryEditsSampleModel.stopEditor();
+ }
+ }
+
+ GeometryEditorButton {
+ id: snapSettingsButton
+ buttonName: qsTr("Snap Settings")
+ iconPath: "qrc:/Samples/EditData/SnapGeometryEdits/iconAssets/settings.png"
+ Layout.columnSpan: 2
+ enabled: true
+ // MouseArea {
+ // anchors.fill: parent
+ // onClicked: optionPanel.visible = true;
+ // }
+ onClicked: {
+ optionPanel.visible = true;
+ snapGeometryEditsSampleModel.configureSnapping();
+ }
+ }
+ }
+ }
+ }
+}
+ Rectangle {
+ id: optionPanel
+ anchors {
+ right: parent.right
+ top: parent.top
+ // bottom: sceneView.attributionTop
+ bottom: parent.bottom
+ }
+ width: 360
+ visible: false
+ color: "white"
+ opacity: 1
+
+ Flickable {
+ anchors {
+ fill: parent
+ margins: 10
+ }
+ contentWidth: parent.width
+ contentHeight: parent.height
+ flickableDirection: Flickable.VerticalFlick
+ ColumnLayout
+ {
+ id: layout
+ spacing: 40
+ Column {
+ id: optionColumn
+ spacing: 10
+ width: optionPanel.width
+
+ Item {
+ width: parent.width
+ height: 25
+
+
+ Text {
+ text: "Snapping"
+ // anchors.horizontalCenter: parent.horizontalCenter
+ font.pixelSize: 15
+ color: "#8434C1"
+ font.bold: true
+
+ }
+
+ Rectangle {
+ anchors {
+ right: parent.right
+ margins: 10
+ }
+ width: 45
+ height: 20
+
+ Text {
+ text: "Done"
+ font.pixelSize: 15
+ color: "#8434C1"
+ font.bold: true
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: optionPanel.visible = false;
+ }
+ }
+ }
+
+ Item {
+ width: parent.width
+ height: 25
+
+ Rectangle {
+ // anchors.centerIn: parent
+ // width: childrenRect.width
+ // height: childrenRect.height
+ // anchors.margins: 40
+
+
+ anchors {
+ // right: parent.right
+ margins: 10
+ }
+
+ width: 340
+ height: 45
+ color: "#E9DFEA"
+ radius: 5
+ border {
+ color: "#4D4D4D"
+ width: 1
+ }
+
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ // width: parent.width * 0.75
+ text: qsTr("Enabled")
+ font.pixelSize: 15
+ anchors {
+ left: parent.left
+ margins: 10
+ verticalCenter: parent.verticalCenter
+ }
+ }
+
+ Switch {
+ anchors {
+ right: parent.right
+ margins: 10
+ verticalCenter: parent.verticalCenter
+ }
+ onCheckedChanged: snapGeometryEditsSampleModel.snappingEnabledStatus(checked)
+ }
+ }
+ }
+ }
+ Column {
+ id: optionColumn2
+ spacing: 10
+ width: optionPanel.width
+ Item {
+ width: parent.width
+ height: 25
+
+ Text {
+ text: "Point Layers"
+ // anchors.horizontalCenter: parent.horizontalCenter
+ font.pixelSize: 15
+ color: "#8434C1"
+ font.bold: true
+
+ }
+
+
+ Rectangle {
+ anchors {
+ right: parent.right
+ margins: 10
+ }
+ width: 140
+ height: 20
+
+ Text {
+ text: "Enable All Sources"
+ font.pixelSize: 15
+ color: "#8434C1"
+ font.bold: true
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ // checkAllPoint = true
+ snapGeometryEditsSampleModel.onPointLayersEnabled()
+ }
+ }
+ }
+ }
+
+ Item {
+ id: item
+
+ width: parent.width
+ height: 25
+
+ Rectangle {
+ anchors.margins: 20
+ width: 340
+ height: grid.height
+ color: "#E9DFEA"
+ radius: 5
+ border {
+ color: "#4D4D4D"
+ width: 1
+ }
+
+ ColumnLayout {
+ id: grid
+ Repeater {
+ id: repeater
+ model: snapGeometryEditsSampleModel.pointLayers // Adjust the number of items as needed
+ delegate: RowLayout {
+ Layout.margins: 10
+
+ Text {
+ id: textItem
+ text: pointLayers[index]
+ Layout.alignment: Qt.AlignLeft
+ Layout.fillWidth: true // Allow text to take all available space
+ Layout.rightMargin: 110
+ font.pixelSize: 15
+ }
+
+ Switch {
+ id: switchItem
+ Layout.alignment: Qt.AlignRight
+ // property bool localChecked: snapGeometryEditsSampleModel.snapSourceCheckedState[index]
+
+ onCheckedChanged: {
+ // if (localChecked !== checked) {
+ // snapGeometryEditsSampleModel.sourceEnabledStatus(checked, index)
+ // localChecked = checked
+ // }
+ snapGeometryEditsSampleModel.pointSourceEnabledStatus(checked, index)
+ }
+ // Bind the checked property to the localChecked property
+ checked: snapGeometryEditsSampleModel.pointSourceCheckedState[index]
+ }
+ }
+ }
+ }
+
+
+ }
+
+
+ }
+
+ }
+
+ Item {
+ // width: mainColumn.width
+ height: optionColumn2.height+10 // Adjust as needed
+ }
+
+ Column {
+ id: optionColumn3
+ spacing: 10
+ width: optionPanel.width
+
+ Item {
+ width: parent.width
+ height: 25
+
+ Text {
+ text: "Polyline Layers"
+ // anchors.horizontalCenter: parent.horizontalCenter
+ font.pixelSize: 15
+ color: "#8434C1"
+ font.bold: true
+
+ }
+
+
+ Rectangle {
+ anchors {
+ right: parent.right
+ margins: 10
+ }
+ width: 140
+ height: 20
+
+ Text {
+ text: "Enable All Sources"
+ font.pixelSize: 15
+ color: "#8434C1"
+ font.bold: true
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ // checkAllPoint = true
+ console.log("polyline")
+ snapGeometryEditsSampleModel.onPolylineLayersEnabled()
+ }
+ }
+ }
+ }
+
+ Item {
+
+ width: parent.width
+ height: 25
+
+ Rectangle {
+ anchors.margins: 20
+ width: 340
+ height: grid2.height
+ color: "#E9DFEA"
+ radius: 5
+ border {
+ color: "#4D4D4D"
+ width: 1
+ }
+
+ ColumnLayout {
+ id: grid2
+ // Layout.bottomMargin: 10
+ // Layout.topMargin: 10
+ Repeater {
+ id: repeater2
+ model: snapGeometryEditsSampleModel.polylineLayers // Adjust the number of items as needed
+ delegate: RowLayout {
+ // Layout.bottomMargin: 10
+ // Layout.topMargin: 10
+ Layout.margins: 10
+ // spacing: 10 // Adjust the default spacing between items
+
+ Text {
+ id: textItem2
+ text: polylineLayers[index]
+ Layout.alignment: Qt.AlignLeft
+ Layout.fillWidth: true // Allow text to take all available space
+ Layout.rightMargin: 200
+ // Layout.leftMargin: 10
+ font.pixelSize: 15
+ }
+
+ Switch {
+ id: switchItem2
+ Layout.alignment: Qt.AlignRight
+ }
+ }
+ }
+ }
+
+
+ }
+
+
+ }
+
+ }
+ }
+ }
+ }
+ }
+
+
+
+
+
diff --git a/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/SnapGeometryEdits.qrc b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/SnapGeometryEdits.qrc
new file mode 100644
index 0000000000..1643593a4a
--- /dev/null
+++ b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/SnapGeometryEdits.qrc
@@ -0,0 +1,21 @@
+
+
+ README.metadata.json
+ SnapGeometryEdits.qml
+ SnapGeometryEdits.h
+ SnapGeometryEdits.cpp
+ main.qml
+ screenshot.png
+ README.md
+ iconAssets/erase-32.png
+ iconAssets/line-32.png
+ iconAssets/multipoint-32.png
+ iconAssets/point-32.png
+ iconAssets/polygon-32.png
+ iconAssets/save-32.png
+ iconAssets/trash-32.png
+ iconAssets/undo-32.png
+ GeometryEditorButton.qml
+ iconAssets/settings.png
+
+
diff --git a/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/arcgisruntime.pri b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/arcgisruntime.pri
new file mode 100644
index 0000000000..23b71ebbe0
--- /dev/null
+++ b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/arcgisruntime.pri
@@ -0,0 +1,29 @@
+#-------------------------------------------------
+# Copyright 2024 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.
+#-------------------------------------------------
+
+contains(QMAKE_HOST.os, Windows):{
+ iniPath = $$(ALLUSERSPROFILE)\EsriRuntimeQt\ArcGIS Runtime SDK for Qt $${ARCGIS_RUNTIME_VERSION}.ini
+}
+else {
+ userHome = $$system(echo $HOME)
+ iniPath = $${userHome}/.config/EsriRuntimeQt/ArcGIS Runtime SDK for Qt $${ARCGIS_RUNTIME_VERSION}.ini
+}
+iniLine = $$cat($${iniPath}, "lines")
+dirPath = $$find(iniLine, "InstallDir")
+cleanDirPath = $$replace(dirPath, "InstallDir=", "")
+priLocation = $$replace(cleanDirPath, '"', "")
+!include($$priLocation/sdk/ideintegration/arcgis_runtime_qml_cpp.pri) {
+ message("Error. Cannot locate ArcGIS Runtime PRI file")
+}
diff --git a/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/erase-32.png b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/erase-32.png
new file mode 100644
index 0000000000..2a967045b0
Binary files /dev/null and b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/erase-32.png differ
diff --git a/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/line-32.png b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/line-32.png
new file mode 100644
index 0000000000..60bd40459b
Binary files /dev/null and b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/line-32.png differ
diff --git a/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/multipoint-32.png b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/multipoint-32.png
new file mode 100644
index 0000000000..6edabfb9fc
Binary files /dev/null and b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/multipoint-32.png differ
diff --git a/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/point-32.png b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/point-32.png
new file mode 100644
index 0000000000..10b0e3e55b
Binary files /dev/null and b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/point-32.png differ
diff --git a/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/polygon-32.png b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/polygon-32.png
new file mode 100644
index 0000000000..621ff9cb5d
Binary files /dev/null and b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/polygon-32.png differ
diff --git a/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/save-32.png b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/save-32.png
new file mode 100644
index 0000000000..6b71f0cfe7
Binary files /dev/null and b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/save-32.png differ
diff --git a/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/settings.png b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/settings.png
new file mode 100644
index 0000000000..74928c4e41
Binary files /dev/null and b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/settings.png differ
diff --git a/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/trash-32.png b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/trash-32.png
new file mode 100644
index 0000000000..d23b3d8516
Binary files /dev/null and b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/trash-32.png differ
diff --git a/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/undo-32.png b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/undo-32.png
new file mode 100644
index 0000000000..5512b01bc0
Binary files /dev/null and b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/iconAssets/undo-32.png differ
diff --git a/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/main.cpp b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/main.cpp
new file mode 100644
index 0000000000..88dfb7a50e
--- /dev/null
+++ b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/main.cpp
@@ -0,0 +1,85 @@
+// Copyright 2024 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.
+
+#include "ArcGISRuntimeEnvironment.h"
+#include "SnapGeometryEdits.h"
+
+#include
+#include
+#include
+#include
+
+#ifdef Q_OS_WIN
+#include
+#endif
+
+void setAPIKey(const QGuiApplication& app, QString apiKey);
+
+int main(int argc, char* argv[])
+{
+ QGuiApplication app(argc, argv);
+ app.setApplicationName(QString("SnapGeometryEdits - C++"));
+
+ // Access to Esri location services requires an API key. This can be copied below or used as a command line argument.
+ const QString apiKey = QString("");
+ setAPIKey(app, apiKey);
+
+ // Initialize the sample
+ SnapGeometryEdits::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/EditData/SnapGeometryEdits/main.qml"));
+
+ return app.exec();
+}
+
+// Use of Esri location services, including basemaps and geocoding,
+// requires authentication using either an ArcGIS identity or an API Key.
+// 1. ArcGIS identity: An ArcGIS named user account that is a member of an
+// organization in ArcGIS Online or ArcGIS Enterprise.
+// 2. API key: API key: a permanent key that grants access to
+// location services and premium content in your applications.
+// Visit your ArcGIS Developers Dashboard to create a new
+// API key or access an existing API key.
+
+void setAPIKey(const QGuiApplication& app, QString apiKey)
+{
+ if (apiKey.isEmpty())
+ {
+ // Try parsing API key from command line argument, which uses the following syntax "-k ".
+ QCommandLineParser cmdParser;
+ QCommandLineOption apiKeyArgument(QStringList{"k", "api"}, "The API Key property used to access Esri location services", "apiKeyInput");
+ cmdParser.addOption(apiKeyArgument);
+ cmdParser.process(app);
+
+ apiKey = cmdParser.value(apiKeyArgument);
+
+ if (apiKey.isEmpty())
+ {
+ qWarning() << "Use of Esri location services, including basemaps, requires"
+ << "you to authenticate with an ArcGIS identity or set the API Key property.";
+ return;
+ }
+ }
+
+ Esri::ArcGISRuntime::ArcGISRuntimeEnvironment::setApiKey(apiKey);
+}
diff --git a/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/main.qml b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/main.qml
new file mode 100644
index 0000000000..74ef4d96a7
--- /dev/null
+++ b/ArcGISRuntimeSDKQt_CppSamples/EditData/SnapGeometryEdits/main.qml
@@ -0,0 +1,25 @@
+// Copyright 2024 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.Controls
+import Esri.Samples
+
+ApplicationWindow {
+ visible: true
+ width: 800
+ height: 600
+
+ SnapGeometryEdits {
+ anchors.fill: parent
+ }
+}