Geometry is a foundational concept used to help define the shape and location of real world objects being modeled in a geographic information system. In some instances, the geometry needs to be constructed new, while in other cases it requires an update to reflect changes over time. The ArcGIS Maps SDK for Swift provides you with key ways to handle these scenarios.
Geometry constructors
When you know your coordinates at the start when creating new geometry, the geometry constructors can be used to create the geometry all at once. For example, you might be converting geometries from a custom GIS data source, such as well-known text (also known as WKT) or a global positioning system exchange format (also known as GPX) into feature geometries. See Point
, Polyline
, or Polygon
classes for constructors you can use to create basic geometry types.
Geometry builders
When you are required to build up or edit geometry one change at a time and do not know the location of the next vertex as the geometry is being created or updated, the builders provide situational flexibility. For example, you might need to hold or update the current location from a custom streaming GIS data source. See PointBuilder
, PolylineBuilder
, or PolygonBuilder
classes for basic geometry types.
Geometry operations
You can use the geometry engine to perform actions, such as a buffer or clip on existing geometries, that results in output geometries. For example, cutting a geometry using a separate cutter line or buffering a geometry to produce required geometry for an editing scenario. See GeometryEngine
to explore various supported geometric operations.
Geometry editor
Geometry editor offers a way for you to allow an end user of your application to interactively add new or modify existing geometries. For example, you might need to allow your users to define a new polyline geometry for a new feature, or update an existing polygon to reflect a change in a building footprint. In these situations, you can use the GeometryEditor
API to capture user interactions on the MapView
to edit geometries.
The geometry editor captures a user's interaction with the map view in your application and returns the new or modified geometry. You can then assign the returned geometry to a new or existing Feature
or Graphic
on the map. To use the geometry editor, follow this workflow:
-
Construct a
GeometryEditor
and assign it to theMapView
.Use dark colors for code blocks Copy var body: some View { MapView(map: model.map) // It's best to store the geometry editor in a data model. // let geometryEditor = GeometryEditor() .geometryEditor(model.geometryEditor) }
-
Call the start method on the geometry editor. The start method signals to the geometry editor to start capturing the user interaction with the map through mouse or touch gestures. You can create a new geometry or update an existing geometry as follows:
- Option one: to create new geometry, call
GeometryEditor.start(geometryType)
.
Use dark colors for code blocks Copy // Starts the edit session and allows user to create new polygon geometry // while interacting with the map. geometryEditor.start(withType: Polygon.self)
- Option two: to modify existing geometry, call
GeometryEditor.start(initialGeomtry)
.
Use dark colors for code blocks Copy // Starts the edit session and exposes the vertices used to construct the existing geometry // and allows the user to make edits to that geometry. guard let geometry = identifiedFeature.geometry else { return } geometryEditor.start(withInitial: geometry)
- Option one: to create new geometry, call
-
The user can now edit the geometry using mouse or touch gestures directly on the map.
-
The final step in the workflow is to call the
GeometryEditor.stop()
method to return the new or modified geometry. When the stop method is called, the geometry editor stops processing any more user interactions on the map.Use dark colors for code blocks Copy // Stops the GeometryEditor from processing any more user interactions on the map. // Returns the final geometry created or modified by the user. let geometry = geometryEditor.stop()
The
GeometryEditor.stop()
method does not add or update the feature or graphic. You need to write logic to create a new or update an existing feature or graphic with the returned geometry.
For more details about this workflow, see Create new geometry, Modify existing geometry, and Retrieve edited geometry.
Create new geometry
In this scenario, your code will allow a user to create new geometry with one of the supported Geometry.Type
s. Depending on your application requirements, you will need to provide a user interface and experience that allows the user to indicate which geometry they intend to create that makes sense for the features or graphics that exist in your application. Once you have determined what the user intends to create, you will call the GeometryEditor.start(geometryType)
. You can use the Geometry.Type
to tell the geometry editor which type of geometry the user can create. In addition, verify that the geometry editor is not already capturing user interactions with the map before attempting to call the start method. By default, the geometry editor presents users with a VertexTool
to edit the geometry. You can change this to any GeometryEditorTool
, such as the FreehandTool
.
// Ensures an edit session has not already been started.
if !geometryEditor.isStarted {
// Optionally, set the GeometryEditorTool used by the user to create the new geometry.
geometryEditor.tool = VertexTool()
// Starts the editing session and allows the user to create point geometry.
geometryEditor.start(withType: Point.self)
}
Modify existing geometry
Alternatively, the user can identify an existing feature or graphic to update its geometry. For example, the user might wish to move an existing polygon to a new location in response to a change in a planned future residential neighborhood. The first part of this workflow requires you to code logic to identify the existing feature or graphic to be modified. Next, call GeometryEditor.start(initialGeomtry)
passing the selected feature or graphic's geometry.
// Starts the edit session and exposes the vertices used to construct the existing geometry
// and allows the user to make edits to that geometry.
guard let geometry = identifiedFeature.geometry else { return }
geometryEditor.start(withInitial: geometry)
Retrieve edited geometry
Regardless of the workflow followed, creating or modifying geometry, the final step is to retrieve the edited geometry. The geometry returned can be used to create a new or update an existing feature in a ServiceGeodatabase
, for example. A call to the GeometryEditor.stop()
method will stop the geometry editor from processing any more user interactions on the map view. At the same time, the final edited geometry is returned. While stopping the editor concludes the workflow for using the geometry editor, you still have to decide what to do with the edited geometry. One option is to add a new feature using the returned geometry to the source database. Another option might be to update the existing feature with the returned geometry. For graphics, an option may be to create a new or update an existing graphic in the map view's GraphicsOverlay.graphics
collection.
// Stops the GeometryEditor from processing any more user interactions on the map.
// Returns the final geometry created or modified by the user.
let geometry = geometryEditor.stop()
Edited geometry appearance
To help distinguish the geometry being edited from the other features or graphics that might be present in the map, the geometry has default symbology that is provided by the GeometryEditorStyle
. If necessary, you can customize the visual appearance of the geometry by adjusting the GeometryEditorTool.style
. After the geometry editor is stopped the edited graphic is removed from the map and its geometry is returned by the stop method.
Undo and redo edits
Undo and redo operations are key to help a user correct mistakes before finalizing one of the editing workflows. The geometry editor provides functionality to undo()
the last action performed by the user on the geometry. Going forward with redo()
is also available to reconstruct the last action undone on the geometry. The canUndo
and canRedo
properties are useful for enabling or disabling a user interface control to support the undo and redo operations, respectively.
geometryEditor.undo()
geometryEditor.redo()