Developing sketch tools

Using the components, classes and methods contained within the Sketch namespace, you can quickly and easily build shape editing into your client application. Shape editing is centered on geometry objects and the concept of a sketch. A sketch is like a temporary drawing that has tools used to create or edit geometries and can be displayed in the map with a sketchgraphiclayer. You can use the sketch to perform vertex edits on existing feature geometries by loading the shape into a specific sketch tool.

The following is a list of key features of the Sketch namespace:

The editing sketch tools are core Mobile SDK MapAction components like zoomin and pan. These tools provide the most common tasks when editing data. Any of these tools can be associated to the Map by using the Map.CurrentMapAction.

The Map provides an instantiated SnappingEnvironment object, which it is share with the sketch tool. The SnappingEnvironment has a list of SnappingAgents, each SnappingAgent requires a MapLayer to be constructed, and it provides two types of snapping: Vertex and Edge.

To render the user's feeback on the screen it is required to have one SketchGraphicLayer in the Map.MapGraphicLayers collection. More SketchGraphicLayer can be added to the Map, but only the first element of the list will be used by the sketching tools.

Architecture of the sketch namespace

Architecture of the sketch namespace

Workflow for editing with sketch

The following steps outline the basic workflow when using the sketching tools. Specific usage and examples with code are detailed in following sections.

Steps:
  1. To begin working with the sketching tools you will need to add the following components into the Map.MapActions() collection at run-time or design-time as follows:

    MapAction Collection Editor

  2. Add a SketchMapGraphicsLayer to the Map.MapGraphicLayers collection. In addition, this is possible at design-time, using the Map properties.

    private void map1_IsValidChanged(object sender, EventArgs e) 
    {
      if (!map1.IsValid) 
        return; 
      // Creates an instance of a SketchGraphicLayer 
      SketchGraphicLayer sketchGraphicLayer = new SketchGraphicLayer();
      // Sets the MapGraphic layer name
      sketchGraphicLayer.LayerName = "myeditsSketchGraphicLayer";
      // Adds the SketchGraphicLayer to the collection of MapGraphicLayers 
      map1.MapGraphicLayers.Add(sketchGraphicLayer);
    }
    

  3. Setup the snap environment if required.

    private void
    menuItem1_Click(object sender, EventArgs e) 
    {
      // Creates a new instance of a parcels SnapAgent 
      SnappingAgent snapAgent = new SnappingAgent(map1.MapLayers["Parcels"]); 
      // Activates the SnapAgent 
      snapAgent.Active = true; 
      // Speficies the SnappingType
      snapAgent.SnappingType = SnappingType.Vertex | SnappingType.Edge;
      // Adds the SnapAgent to the collection
      map1.SnappingEnvironment.SnappingAgents.Add(snapAgent); 
    }
    

  4. If you are creating new features, you are required to create an empty geometry of the type (polygon, line, point or multipoint) you wish to capture and set it to the SketchGraphicLayer.Geometry property. This should be the same geometry type as the layer in which you wish to create features. If you are modifying an existing feature's geometry, you need to obtain that geometry, via the selection map action or code, and then assign the geometry to the sketchMapAction.Geometry property. The geometry will then appear as a sketch that can be modified (DeleteVertexSketchTool, InsertVertexSketchTool, MoveVertexSketchTool) in the map display.
  5. Set one of the sketching tools to be the CurrentMapAction on the map.
  6. Use the mouse, stylus or rocker to work with the sketch. For example, create a new sketch via AddVertexSketchTool or delete a few vertices of an existing geometry via DeleteVertexSketchTool.
  7. One you have finished sketching or altering an existing geometry, you have to get the geometry from the SketchMapGraphicLayer and either create a new FeatureDataRow to add the new geometry, or to modify the geometry column value of an existing FeatureDataRow.

Create a sketch geometry

To create a new geometry you need to create an empty geometry of the type that matches the feature layer you are creating the geometry for and set it to the SketchGraphicLayer.Geometry property.

To enable the AddVertexSketchtool simply set it to the Map.CurrentMapAction property.

private void menuItem1_Click(object sender, EventArgs e)
{ 
  //Selects a specific cache layer 
  FeatureLayer featureLayer = mobileCache1.Layers["parcels"] as FeatureLayer; 
  // Sets map action to be add vertex sketch 
  map1.CurrentMapAction = addVertexSketchTool1; 
  // Get the feature geometry type GeometryType
  geometryType = featureLayer.GeometryType; 
  // Get the appropiate SketchGraphicLayer 
  SketchGraphicLayer sketchGraphicLayer = (map1.MapGraphicLayers["myeditsSketchGraphicLayer"]) as SketchGraphicLayer; 
  // Creates a new EMPTY instance of a geometry based on 
  // the selected layer geometry type and pass it to the sketch 
  if (geometryType == GeometryType.Point)
    sketchGraphicLayer.Geometry = new ESRI.ArcGIS.Mobile.Geometries.Point();
  else if (geometryType == GeometryType.Polygon) 
    sketchGraphicLayer.Geometry = new Polygon();
  else if (geometryType == GeometryType.Polyline)
    sketchGraphicLayer.Geometry = new Polyline(); 
  else if (geometryType == GeometryType.Multipoint)
    sketchGraphicLayer.Geometry = new Multipoint(); 
}

Start digitizing

Using the input device (mouse, stylus, rocker), click or tap the location for the vertices to add. As you add new vertices, sketch segments will be drawn for polygons and polylines. For points, a one click/tap will create a new geometry. For multipoints, each vertex will create a new point part in the sketch's geometry.

The following diagrams illustrate creating a new sketch:

Polygons

Digitizing a new polygon sketch

Polylines

Digitizing a new polyline sketch

Points

Digitizing a new point sketch

Multipoints

Digitizing a new multipoint sketch

Finish the sketch

Finishing sketching is a task that is part of every client application using the sketching tools. The following sample code shows how to finish a simple geometry.

private void menuItem1_Click(object sender, EventArgs e) 
{ 
  //Selects a specific cache layer 
  FeatureLayer featureLayer = mobileCache1.Layers["parcels"] as FeatureLayer; 
  // Get the appropiate SketchGraphicLayer
  SketchGraphicLayer sketchGraphicLayer = (map1.MapGraphicLayers["myeditsSketchGraphicLayer"]) as SketchGraphicLayer; 
  // Gets the feature layer data table schema
  FeatureDataTable featureDataTable = featureLayer.GetDataTable();
  // Creates a new row 
  FeatureDataRow featureDataRow = featureDataTable.NewRow();
  // Sets the new geomtry to the geometry field 
  featureDataRow[featureLayer.GeometryColumnIndex] = sketchGraphicLayer.Geometry; 
  // Adds the new row to the feature layer data table 
  featureDataTable.Rows.Add(featureDataRow); 
  // Updates the feature layer data table
  featureDataTable.SaveInFeatureLayer(); 
  // Clear the sketch's geometry 
  sketchGraphicLayer.Geometry = null;
}

How to create multipart sketch geometry

A multipart geometry is composed of more than one part. To create a multipart, start digitizing a new sketch. When the part is done, you increment the Geometry.CurrentPartIndex. When the user continues to digitize on the screen this will create the next part's coordinate collection.

The following diagrams illustrate creating multipart sketches.

Digitizing multiple shells

Digitizing multiple shells

Digitizing a shell and hole

Digitizing a shell and hole, digitize the shell
Digitizing a shell and hole, digitize the hole
Digitizing a shell and hole

The following example shows how to finish a part through code:

private void menuItem1_Click(object sender, EventArgs e) 
{
  // Get the appropiate SketchGraphicLayer 
  SketchGraphicLayer sketchGraphicLayer = (map1.MapGraphicLayers["myeditsSketchGraphicLayer"]) as SketchGraphicLayer; 
  // Gets the sketch geometry 
  Geometry geometry = sketchGraphicLayer.Geometry; 
  if (geometry == null || geometry.GeometryType == GeometryType.Point) 
    return; 
  // Gets current part in the sketch's geometry 
  int partIndex = geometry.CurrentPartIndex; 
  // Creates an instance of coordinate collection 
  CoordinateCollection newPartCoordinateCollection = new CoordinateCollection();  
  // Adds the empty coordiante collection to the geometry
  geometry.Parts.Add(newPartCoordinateCollection); 
  //Increments the part index 
  partIndex++; 
  // Sets the new coordinate collection index 
  geometry.CurrentPartIndex = partIndex;
 }

How to modify an existing geometry

The Mobile SDK includes sketch tools that let you modify existing geometries as well as create new ones. To use these tools, it is required that you set the SketchGraphicLayer.Geometry to an existing feature's geometry.

Using the editing namespace you can perform the following edits:

Deleting vertices

The following code passes a geometry to the SketchGraphicLayer and sets the DeleteVertexSketchTool as the Map.CurrentMapAction.

// Contains a geometry 
private Geometry m_geometry; 
private void menuItem1_Click(object sender, EventArgs e)
  {
  // Selects a specific cache layer 
  FeatureLayer featureLayer = mobileCache1.Layers["parcels"] as FeatureLayer; 
  // Sets map action to be add vertex sketch 
  map1.CurrentMapAction = deleteVertexSketchTool1; 
  // Get the appropiate SketchGraphicLayer
  SketchGraphicLayer sketchGraphicLayer = (map1.MapGraphicLayers["myeditsSketchGraphicLayer"]) as SketchGraphicLayer; 
  // // Query filter to find a specific feature by its ID 
  QueryFilter queryFilter = new QueryFilter(new int[] { 5473 });
  m_geometry = null;
  // Using a feature datareader to update features 
  using (FeatureDataReader featureDataReader = featureLayer.GetDataReader(queryFilter, null)) 
  {
    while (featureDataReader.Read()) 
    // Gets the feature's geometry
    m_geometry = featureDataReader.GetGeometry();
  } 
  if (m_geometry == null)
    return; 
  // Sets the feature geometry to the
  SketchGraphicLayer sketchGraphicLayer.Geometry = m_geometry; 
}

To use the DeleteVertexSketchTool move your mouse or tap near the vertex you wish to delete.

Using DeleteVertexSketchTool

Inserting vertices

The following code passes a geometry to the SketchGraphicLayer and sets the InsertVertexSketchTool as the Map.CurrentMapAction.

private void menuItem1_Click(object sender, EventArgs e) 
  { 
  // Sets map action to be add vertex sketch 
  map1.CurrentMapAction = insertVertexSketchTool1;
  if (m_geometry == null)
    return;
  // Get the appropiate SketchGraphicLayer 
  SketchGraphicLayer sketchGraphicLayer = (map1.MapGraphicLayers["myeditsSketchGraphicLayer"]) as SketchGraphicLayer; 
  // Sets the feature geometry to the
  SketchGraphicLayer sketchGraphicLayer.Geometry = m_geometry; 
}

To use the InsertVertexSketchTool move your mouse or tap near the geometry edge where you wish to insert a vertex. Once a new vertex has been introduced, this will remain active in order to move it to a specific location.

Using InsertVertexSketchTool

Moving vertices

The following code passes a geometry to the SketchGraphicLayer and sets the MoveVertexSketchTool as the Map.CurrentMapAction.

private void menuItem1_Click(object sender, EventArgs e) 
{
  // Sets map action to be add vertex sketch 
  map1.CurrentMapAction = moveVertexSketchTool1;
  if (m_geometry == null)
    return;
  // Get the appropiate SketchGraphicLayer 
  SketchGraphicLayer sketchGraphicLayer = (map1.MapGraphicLayers["myeditsSketchGraphicLayer"]) as SketchGraphicLayer; 
  // Sets the feature geometry to the SetchGraphicLayer 
  sketchGraphicLayer.Geometry = m_geometry; 
}

To use the MoveVertexSketchTool move your mouse or tap near the vertex you wish to move, this will remain active in order to move it to a specific location.

Using MoveVertexSketchTool


9/20/2011