Skip to content

Commit 8d69898

Browse files
authored
Merge pull request #246 from Esri/zach/geometryEditorSampleEnhancements
2 parents 452c08e + edbbfc7 commit 8d69898

File tree

9 files changed

+133
-68
lines changed

9 files changed

+133
-68
lines changed

Samples.xcodeproj/project.pbxproj

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,8 @@
134134
883C121729C914E100062FF9 /* DownloadPreplannedMapAreaView.MapPicker.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = 883C121429C9136600062FF9 /* DownloadPreplannedMapAreaView.MapPicker.swift */; };
135135
883C121829C914E100062FF9 /* DownloadPreplannedMapAreaView.Model.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = E0D04FF128A5390000747989 /* DownloadPreplannedMapAreaView.Model.swift */; };
136136
883C121929C914E100062FF9 /* DownloadPreplannedMapAreaView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = E070A0A2286F3B6000F2B606 /* DownloadPreplannedMapAreaView.swift */; };
137-
88F93CC129C3D59D0006B28E /* SketchOnMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88F93CC029C3D59C0006B28E /* SketchOnMapView.swift */; };
138-
88F93CC229C4D3480006B28E /* SketchOnMapView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = 88F93CC029C3D59C0006B28E /* SketchOnMapView.swift */; };
137+
88F93CC129C3D59D0006B28E /* CreateAndEditGeometriesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88F93CC029C3D59C0006B28E /* CreateAndEditGeometriesView.swift */; };
138+
88F93CC229C4D3480006B28E /* CreateAndEditGeometriesView.swift in Copy Source Code Files */ = {isa = PBXBuildFile; fileRef = 88F93CC029C3D59C0006B28E /* CreateAndEditGeometriesView.swift */; };
139139
D701D72C2A37C7F7006FF0C8 /* bradley_low_3ds in Resources */ = {isa = PBXBuildFile; fileRef = D701D72B2A37C7F7006FF0C8 /* bradley_low_3ds */; settings = {ASSET_TAGS = (ShowViewshedFromGeoelementInScene, ); }; };
140140
D70BE5792A5624A80022CA02 /* CategoriesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70BE5782A5624A80022CA02 /* CategoriesView.swift */; };
141141
D710996D2A27D9210065A1C1 /* DensifyAndGeneralizeGeometryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D710996C2A27D9210065A1C1 /* DensifyAndGeneralizeGeometryView.swift */; };
@@ -326,7 +326,7 @@
326326
1C0C1C3D29D34DDD005C8B24 /* ChangeViewpointView.swift in Copy Source Code Files */,
327327
1C42E04A29D239D2004FC4BE /* ShowPopupView.swift in Copy Source Code Files */,
328328
108EC04229D25B55000F35D0 /* QueryFeatureTableView.swift in Copy Source Code Files */,
329-
88F93CC229C4D3480006B28E /* SketchOnMapView.swift in Copy Source Code Files */,
329+
88F93CC229C4D3480006B28E /* CreateAndEditGeometriesView.swift in Copy Source Code Files */,
330330
0044289329C9234300160767 /* GetElevationAtPointOnSurfaceView.swift in Copy Source Code Files */,
331331
4D2ADC6A29C50D91003B367F /* AddDynamicEntityLayerView.Model.swift in Copy Source Code Files */,
332332
4D2ADC6B29C50D91003B367F /* AddDynamicEntityLayerView.SettingsView.swift in Copy Source Code Files */,
@@ -446,7 +446,7 @@
446446
79302F862A1ED71B0002336A /* CreateAndSaveKMLView.Views.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateAndSaveKMLView.Views.swift; sourceTree = "<group>"; };
447447
79B7B8092A1BF8EC00F57C27 /* CreateAndSaveKMLView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateAndSaveKMLView.swift; sourceTree = "<group>"; };
448448
883C121429C9136600062FF9 /* DownloadPreplannedMapAreaView.MapPicker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownloadPreplannedMapAreaView.MapPicker.swift; sourceTree = "<group>"; };
449-
88F93CC029C3D59C0006B28E /* SketchOnMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SketchOnMapView.swift; sourceTree = "<group>"; };
449+
88F93CC029C3D59C0006B28E /* CreateAndEditGeometriesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateAndEditGeometriesView.swift; sourceTree = "<group>"; };
450450
D701D72B2A37C7F7006FF0C8 /* bradley_low_3ds */ = {isa = PBXFileReference; lastKnownFileType = folder; path = bradley_low_3ds; sourceTree = "<group>"; };
451451
D70BE5782A5624A80022CA02 /* CategoriesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoriesView.swift; sourceTree = "<group>"; };
452452
D710996C2A27D9210065A1C1 /* DensifyAndGeneralizeGeometryView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DensifyAndGeneralizeGeometryView.swift; sourceTree = "<group>"; };
@@ -607,6 +607,7 @@
607607
4D2ADC5329C4F612003B367F /* Change map view background */,
608608
1C0C1C3229D34DAE005C8B24 /* Change viewpoint */,
609609
E000E75E2869E325005D87C5 /* Clip geometry */,
610+
88F93CBE29C3D4E30006B28E /* Create and edit geometries */,
610611
79B7B8082A1BF8B300F57C27 /* Create and save KML file */,
611612
D7E440D12A1ECBC2005D74DE /* Create buffers around points */,
612613
D7B3C5C02A43B71E001DA4D8 /* Create convex hull around geometries */,
@@ -659,7 +660,6 @@
659660
1CAF831A2A20305F000E1E60 /* Show utility associations */,
660661
D7ABA2FB2A3287C10021822B /* Show viewshed from geoelement in scene */,
661662
0086F3FC28E3770900974721 /* Show viewshed from point in scene */,
662-
88F93CBE29C3D4E30006B28E /* Sketch on map */,
663663
E066DD362860AB0B004D3D5B /* Style graphics with renderer */,
664664
E004A6E42846A609002A1FE6 /* Style graphics with symbols */,
665665
D754E31D2A1D661D0006C5F1 /* Style point with picture marker symbols */,
@@ -983,12 +983,12 @@
983983
path = "Create and save KML file";
984984
sourceTree = "<group>";
985985
};
986-
88F93CBE29C3D4E30006B28E /* Sketch on map */ = {
986+
88F93CBE29C3D4E30006B28E /* Create and edit geometries */ = {
987987
isa = PBXGroup;
988988
children = (
989-
88F93CC029C3D59C0006B28E /* SketchOnMapView.swift */,
989+
88F93CC029C3D59C0006B28E /* CreateAndEditGeometriesView.swift */,
990990
);
991-
path = "Sketch on map";
991+
path = "Create and edit geometries";
992992
sourceTree = "<group>";
993993
};
994994
D701D7242A37C7E4006FF0C8 /* 07d62a792ab6496d9b772a24efea45d0 */ = {
@@ -1644,7 +1644,7 @@
16441644
D7E440D72A1ECE7D005D74DE /* CreateBuffersAroundPointsView.swift in Sources */,
16451645
00D4EF802863842100B9CC30 /* AddFeatureLayersView.swift in Sources */,
16461646
D710996D2A27D9210065A1C1 /* DensifyAndGeneralizeGeometryView.swift in Sources */,
1647-
88F93CC129C3D59D0006B28E /* SketchOnMapView.swift in Sources */,
1647+
88F93CC129C3D59D0006B28E /* CreateAndEditGeometriesView.swift in Sources */,
16481648
1C0C1C3929D34DAE005C8B24 /* ChangeViewpointView.swift in Sources */,
16491649
D734FA0C2A183A5B00246D7E /* SetMaxExtentView.swift in Sources */,
16501650
E004A6DC28465C70002A1FE6 /* DisplaySceneView.swift in Sources */,

Shared/Samples/Sketch on map/SketchOnMapView.swift renamed to Shared/Samples/Create and edit geometries/CreateAndEditGeometriesView.swift

Lines changed: 80 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import ArcGIS
1616
import SwiftUI
1717

1818
/// A view that shows how to interact with the geometry editor.
19-
struct SketchOnMapView: View {
19+
struct CreateAndEditGeometriesView: View {
2020
/// The map to display in the view.
2121
@State private var map = Map(basemapStyle: .arcGISTopographic)
2222

@@ -64,53 +64,91 @@ extension GeometryEditorMenu {
6464
private var mainMenuContent: some View {
6565
VStack {
6666
Button {
67-
model.geometryEditor.tool = VertexTool()
68-
model.geometryEditor.start(withType: Point.self)
69-
model.isStarted = true
67+
model.startEditing(with: VertexTool(), geometryType: Point.self)
7068
} label: {
7169
Label("New Point", systemImage: "smallcircle.filled.circle")
7270
}
7371

7472
Button {
75-
model.geometryEditor.tool = VertexTool()
76-
model.geometryEditor.start(withType: Polyline.self)
77-
model.isStarted = true
73+
model.startEditing(with: VertexTool(), geometryType: Polyline.self)
7874
} label: {
7975
Label("New Line", systemImage: "line.diagonal")
8076
}
8177

8278
Button {
83-
model.geometryEditor.tool = VertexTool()
84-
model.geometryEditor.start(withType: Polygon.self)
85-
model.isStarted = true
79+
model.startEditing(with: VertexTool(), geometryType: Polygon.self)
8680
} label: {
8781
Label("New Area", systemImage: "skew")
8882
}
8983

9084
Button {
91-
model.geometryEditor.tool = VertexTool()
92-
model.geometryEditor.start(withType: Multipoint.self)
93-
model.isStarted = true
85+
model.startEditing(with: VertexTool(), geometryType: Multipoint.self)
9486
} label: {
9587
Label("New Multipoint", systemImage: "hand.point.up.braille")
9688
}
9789

9890
Button {
99-
model.geometryEditor.tool = FreehandTool()
100-
model.geometryEditor.start(withType: Polyline.self)
101-
model.isStarted = true
91+
model.startEditing(with: FreehandTool(), geometryType: Polyline.self)
10292
} label: {
10393
Label("New Freehand Line", systemImage: "scribble")
10494
}
10595

10696
Button {
107-
model.geometryEditor.tool = FreehandTool()
108-
model.geometryEditor.start(withType: Polygon.self)
109-
model.isStarted = true
97+
model.startEditing(with: FreehandTool(), geometryType: Polygon.self)
11098
} label: {
11199
Label("New Freehand Area", systemImage: "lasso")
112100
}
113101

102+
Menu("Shapes") {
103+
Button {
104+
model.startEditing(with: ShapeTool(kind: .arrow), geometryType: Polyline.self)
105+
} label: {
106+
Label("New Line Arrow", systemImage: "arrowshape.right")
107+
}
108+
109+
Button {
110+
model.startEditing(with: ShapeTool(kind: .arrow), geometryType: Polygon.self)
111+
} label: {
112+
Label("New Polygon Arrow", systemImage: "arrowshape.right.fill")
113+
}
114+
115+
Button {
116+
model.startEditing(with: ShapeTool(kind: .rectangle), geometryType: Polyline.self)
117+
} label: {
118+
Label("New Line Rectangle", systemImage: "rectangle")
119+
}
120+
121+
Button {
122+
model.startEditing(with: ShapeTool(kind: .rectangle), geometryType: Polygon.self)
123+
} label: {
124+
Label("New Polygon Rectangle", systemImage: "rectangle.fill")
125+
}
126+
127+
Button {
128+
model.startEditing(with: ShapeTool(kind: .ellipse), geometryType: Polyline.self)
129+
} label: {
130+
Label("New Line Ellipse", systemImage: "circle")
131+
}
132+
133+
Button {
134+
model.startEditing(with: ShapeTool(kind: .ellipse), geometryType: Polygon.self)
135+
} label: {
136+
Label("New Polygon Ellipse", systemImage: "circle.fill")
137+
}
138+
139+
Button {
140+
model.startEditing(with: ShapeTool(kind: .triangle), geometryType: Polyline.self)
141+
} label: {
142+
Label("New Line Triangle", systemImage: "triangle")
143+
}
144+
145+
Button {
146+
model.startEditing(with: ShapeTool(kind: .triangle), geometryType: Polygon.self)
147+
} label: {
148+
Label("New Polygon Triangle", systemImage: "triangle.fill")
149+
}
150+
}
151+
114152
Divider()
115153

116154
Button(role: .destructive) {
@@ -146,6 +184,8 @@ extension GeometryEditorMenu {
146184
}
147185
.disabled(deleteButtonIsDisabled)
148186

187+
Toggle("Uniform Scale", isOn: $model.shouldUniformScale)
188+
149189
Button(role: .destructive) {
150190
model.geometryEditor.clearGeometry()
151191
} label: {
@@ -222,6 +262,17 @@ class GeometryEditorMenuModel: ObservableObject {
222262
/// A Boolean value indicating if the geometry editor has started.
223263
@Published var isStarted = false
224264

265+
/// A Boolean value indicating if the scale mode is uniform.
266+
@Published var shouldUniformScale = false {
267+
didSet {
268+
let scaleMode: GeometryEditorScaleMode = shouldUniformScale ? .uniform : .stretch
269+
let tool = geometryEditor.tool
270+
(tool as? FreehandTool)?.configuration.scaleMode = scaleMode
271+
(tool as? ShapeTool)?.configuration.scaleMode = scaleMode
272+
(tool as? VertexTool)?.configuration.scaleMode = scaleMode
273+
}
274+
}
275+
225276
/// Creates the geometry menu with a geometry editor.
226277
/// - Parameter geometryEditor: The geometry editor that the menu should interact with.
227278
/// - Parameter graphicsOverlay: The graphics overlay that is used to save geometries to.
@@ -282,4 +333,14 @@ class GeometryEditorMenuModel: ObservableObject {
282333
fatalError("Unexpected geometry type")
283334
}
284335
}
336+
337+
/// Starts editing with the specified tool and geometry type.
338+
/// - Parameters:
339+
/// - tool: The tool to draw with.
340+
/// - geometryType: The type of geometry to draw.
341+
func startEditing(with tool: GeometryEditorTool, geometryType: Geometry.Type) {
342+
geometryEditor.tool = tool
343+
geometryEditor.start(withType: geometryType)
344+
isStarted = true
345+
}
285346
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Create and edit geometries
2+
3+
Use the Geometry Editor to create new point, multipoint, polyline, or polygon geometries or to edit existing geometries by interacting with a map view.
4+
5+
![Image of create and edit geometries 1](create-and-edit-geometries-1.png)
6+
![Image of create and edit geometries 2](create-and-edit-geometries-2.png)
7+
8+
## Use case
9+
10+
A field worker can mark features of interest on a map using an appropriate geometry. Features such as sample or observation locations, fences or pipelines, and building footprints can be digitized using point, multipoint, polyline, and polygon geometry types. Polyline and polygon geometries can be created and edited using a vertex-based creation and editing tool (i.e. vertex locations specified explicitly via tapping), or using a freehand tool.
11+
12+
## How to use the sample
13+
14+
Tap the pencil button to choose a geometry editor tool. Begin interactively sketching on the map view. Tap the pencil button again for editing options.
15+
16+
## How it works
17+
18+
1. Create a `GeometryEditor` and assign it to a map view with the `geometryEditor` view modifier.
19+
2. Set the tool of the geometry editor to the preferred tool.
20+
3. Use the `start(withType:)` method on the `GeometryEditor` to start interactively sketching on the map view.
21+
4. Use various methods and properties of the `GeometryEditor` to undo, redo, delete a selected element, clear the sketch, and cancel the sketch.
22+
5. Edit a tool's `InteractionConfiguration` to set the `GeometryEditorScaleMode` to allow either uniform or stretch scale mode.
23+
6. Save a sketch as a `Graphic` to a `GraphicsOverlay` displayed on the map view.
24+
25+
## Relevant API
26+
27+
* Geometry
28+
* GeometryBuilder
29+
* GeometryEditor
30+
* Graphic
31+
* GraphicsOverlay
32+
* MapView
33+
34+
## Tags
35+
36+
draw, edit, freehand, geometry editor, sketch, vertex

Shared/Samples/Sketch on map/README.metadata.json renamed to Shared/Samples/Create and edit geometries/README.metadata.json

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
{
22
"category": "Maps",
3-
"description": "Use the Geometry Editor to edit or sketch a new point, multipoint, line, or polygon geometry on a map.",
3+
"description": "Use the Geometry Editor to create new point, multipoint, polyline, or polygon geometries or to edit existing geometries by interacting with a map view.",
44
"ignore": false,
55
"images": [
6-
"sketch-on-map-1.png",
7-
"sketch-on-map-2.png"
6+
"create-and-edit-geometries-1.png",
7+
"create-and-edit-geometries-2.png"
88
],
99
"keywords": [
1010
"draw",
1111
"edit",
12+
"freehand",
13+
"geometry editor",
1214
"sketch",
15+
"vertex",
1316
"Geometry",
1417
"GeometryBuilder",
1518
"GeometryEditor",
@@ -27,7 +30,7 @@
2730
"MapView"
2831
],
2932
"snippets": [
30-
"SketchOnMapView.swift"
33+
"CreateAndEditGeometriesView.swift"
3134
],
32-
"title": "Sketch on map"
35+
"title": "Create and edit geometries"
3336
}
142 KB
Loading
146 KB
Loading

Shared/Samples/Sketch on map/README.md

Lines changed: 0 additions & 35 deletions
This file was deleted.
-38.1 KB
Binary file not shown.
-52 KB
Binary file not shown.

0 commit comments

Comments
 (0)