ProConcepts Editing Dimensions - kataya/arcgis-pro-sdk GitHub Wiki

This concepts document covers special considerations for authors of editing tools for dimensions. It augments the overall dimension concepts covered in ProConcepts Dimensions.

ArcGIS.Core.dll

ArcGIS.Desktop.Editing.dll

Language:      C#
Subject:       Dimensions
Contributor:   ArcGIS Pro SDK Team <[email protected]>
Organization:  Esri, http://www.esri.com
Date:          11/24/2020
ArcGIS Pro:    2.7
Visual Studio: 2017, 2019

In this topic

Overview

This concepts document augments the overall dimension concepts covered in ProConcepts Dimensions. Dimension features differ from other geodatabase features in a few small but fundamental ways. It is important to keep these in mind when developing custom dimension editing tools.

Similar to annotation feature classes, the dimension feature class stores polygon geometry. This polygon is the boundary of the dimension feature. It is automatically updated by the application each time the dimension attributes are modified. You should never need to access or modify a dimension feature's polygon shape.

A dimension feature requires that a specific number of points be entered into the edit sketch to describe it's geometry. The key coordinates for a dimension feature are the begin and end points, the dimension line point and the text point. These are stored as groups of x and y fields on the feature class itself. To modify the shape of a dimension feature, you must modify one or more of these x and y field pairs.

The begin and end dimension points define the dimension's measurement points. The dimension line point determines the height of the dimension line above the baseline. And the text point defines a custom text location. In many situations the text point x and y are null, meaning that the text is at it's default location - the midpoint of the baseline.

dimension

Dimension Style Classes

A dimension feature class has a collection of one or more styles associated with it. These styles are defined when the feature class is created. Every time you create a new dimension feature, you assign it one of these predefined styles. The style contains properties that describe how the dimension feature is displayed, such as the start point and end point symbols, the dimension line symbol and the text font, style and size.

You can retrieve the style classes for a dimension feature class by accessing its DimensionFeatureClassDefinition. This can be achieved using code similar to the following:

   // must be executed on the MCT - wrap in a QueuedTask.Run

   // get the dimension layer
   DimensionLayer dimLayer = CurrentTemplate.Layer as DimensionLayer;
   if (dimLayer == null)
     return false;

   // get the dimension feature class
   var fc = dimLayer.GetTable() as ArcGIS.Core.Data.Mapping.DimensionFeatureClass;
   if (fc == null)
     return false;

   // get the featureclass definition which contains the style collections
   var cimDefinition = fc.GetDefinition() as ArcGIS.Core.Data.Mapping.DimensionFeatureClassDefinition;
   var styles = cimDefinition.GetDimensionStyles();

Use a value in this collection to set the StyleID field when creating or modifying dimension features.

If you find over time, that the styles created do not contain the properties you need for additional dimension features, you must create a new style with the new properties, then assign the new style to the dimension features. You cannot overwrite individual properties on the style on a feature-by-feature basis like you can with annotation symbols.

Accessing Dimensions

By default, dimension feature classes are created with a predefined set of system fields. These fields are guaranteed to exist in the physical schema and cannot be deleted by the user. Because of this, it is possible to use the Inspector object to access or modify dimension features as you would with standard geodatabase features.

Creating Dimension Features

Writing a construction tool for dimension features is very similar to writing a construction tool for point, line or polygon data. Use the ArcGIS Pro Construction Tool template in Visual Studio to create a construction tool. Configure the categoryRefID tag in the config.daml file for your tool to be esri_editing_construction_dimension. Dimension features are required to be created using a multipoint geometry so set the SketchType property in the constructor code to be SketchGeometryType.Multipoint.

  <tool id="DimensionTools_MyDimConstructionTool" 
              categoryRefID="esri_editing_construction_dimension" 
              caption="MyDimConstructionTool" className="MyDimConstructionTool" 
              loadOnClick="true" 
              smallImage="Images\GenericButtonRed16.png" 
              largeImage="Images\GenericButtonRed32.png">
     <tooltip heading="Tooltip Heading">dimension<disabledText /></tooltip>
  </tool>
 public MyDimConstructionTool()
 {
   IsSketchTool = true;
   UseSnapping = true;
   // Select the type of construction tool you wish to implement.  
   SketchType = SketchGeometryType.Multipoint;
 }

The most important part of a dimension construction tool is determining when to finish the sketch. As previously mentioned, even though the shape of a dimension feature is a polygon, a multipoint is required to be passed to the EditOperation.Create method. Dimension features can be created with 2, 3 or 4 points within the multipoint. Two points specify the Begin and End dimension points with a null dimension Line point and a null Text point. Three points means defining the dimension Line point in addition to the Begin and End points. Finally with four points; you have the Begin and End dimension points, Line Point and Text Point defined.

As the construction tool author, you decide how many points your tool requires. This is accomplished by overriding the OnSketchModifiedAsync method and forcing the sketch to finish when it matches the required number of points. Here is an example of how to force the sketch to finish after the user clicks 2 times.

 protected override async Task<bool> OnSketchModifiedAsync()
 {
   // restrict the sketch to 2 points
   bool finish = await QueuedTask.Run(async () =>
   {
     // get the current sketch
     var geometry = await base.GetCurrentSketchAsync();
     // cast to a Multipoint
     var geom = geometry as ArcGIS.Core.Geometry.Multipoint;
     // check the point count
     return geom?.PointCount >= 2;
   });

   // call FinishSketchAsync if we have 2 points
   if (finish)
     finish = await base.FinishSketchAsync();
 
   return finish;
 }

The OnSketchCompleteAsync method as defined by the Visual Studio template wizard does not require any additional modifications in order for the construction tool to be completed. An edit operation is created, the Create method is called using the CurrentTemplate and sketch geometry (restricted to a 2 point multipoint as per the OnSketchModifiedAsync method) and then finally the ExecuteAsync method is called.

 /// <summary>
 /// Called when the sketch finishes. This is where we will create the sketch operation and then execute it.
 /// </summary>
 /// <param name="geometry">The geometry created by the sketch.</param>
 /// <returns>A Task returning a Boolean indicating if the sketch complete event was successfully handled.</returns>
 protected override Task<bool> OnSketchCompleteAsync(Geometry geometry)
 {
   if (CurrentTemplate == null || geometry == null)
     return false;

   // Create an edit operation
   var createOperation = new EditOperation();
   createOperation.Name = string.Format("Create {0}", CurrentTemplate.Layer.Name);
   createOperation.SelectNewFeatures = true;

   // Queue feature creation
   createOperation.Create(CurrentTemplate, geometry);

   // Execute the operation
   return createOperation.ExecuteAsync();
 }

Modifying Dimension Features

Modifying dimension features should follow similar patterns to modifying point, line or polygon features. That is; create an Inspector object, load the appropriate feature, modify the necessary attributes, then call EditOperation.Modify passing the updated Inspector object. Here is an example showing how to update the StyleID of a dimension feature

   // must be executed on the MCT - wrap in a QueuedTask.Run

   // get the dimension feature class
   var fc = dimLayer.GetTable() as ArcGIS.Core.Data.Mapping.DimensionFeatureClass;
   if (fc == null)
     return false;

   // get the featureclass definition which contains the style collections
   var cimDefinition = fc.GetDefinition() as ArcGIS.Core.Data.Mapping.DimensionFeatureClassDefinition;
   var styles = cimDefinition.GetDimensionStyles();

   // make sure there are styles
   if (styles.Count == 0)
     return;

   // load the inspector with a feature
   var insp = new Inspector(true);
   insp.Load(dimLayer, oids);
   string oldStyleID = insp["styleID"].ToString();

   int int_styleID = Convert.ToInt32(styleID);

   int newStyleID = -1; 
   foreach (var style in styles)
   {
     // if it's different
     if (style.ID != int_styleID)
       newStyleID = style.ID;
   }

   if (newStyleID == -1)
   {
      // the dimension feature class requires more than 1 style in 
      //    order to assign a new style
     return;
   }

   insp["styleID"] = newStyleID;

   var op = new EditOperation();
   op.Modify(insp);
   bool result = op.Execute();

If you are interested in displaying a custom length rather than the dimension length, modify the UseCustomLength and CustomLength fields. To change the dimension display, modify the DimDisplay (are dimension lines displayed?), MarkerDisplay (are dimension symbols displayed?) or ExtDisplay (are the extension lines displayed?) fields. All three fields have a range of 0-3 indicating Both (0), Begin (1), End (2), None (3). The coordinates of the dimension components are represented by the BeginX, BeginY, EndX, EndY, DimX, DimY and TextX and TextY fields. Finally modify the ExtAngle field to change the extension line angle (stored in radians). And the TextAngle field to change the dimension text angle (stored in radians).

Similar to editing of other geometry types, you can load multiple dimension features into the inspector, assign values via the Inspector class and have those values be applied to all features loaded in the inspector.

Creating Dimension Templates

The Inspector class is also the recommended pattern for creating dimension templates. Rather than dealing directly with the CIM as in previous releases, the CreateTemplate method facilitates template creation with a populated Inspector object. You can also easily assign the template name, description, tags, default tool and tool filter with the same call.

   // must be executed on the MCT - wrap in a QueuedTask.Run

   // load the schema
   insp = new Inspector();
   insp.LoadSchema(dimLayer);

   // set up the StyleID fields - required field
   // ok to access them this way - they are guaranteed to exist
   insp["StyleID"] = style.ID;

   // set default values for other dimension fields as necessary using Inspector

   // set up tags
   var tags = new[] { "Dimension", "tag1", "tag2" };

   // set up default tool - use daml-id rather than guid
   string defaultTool = "esri_editing_AlignedDimensionTool";

   // create a new CIM template  - new extension method
   var newTemplate = dimLayer.CreateTemplate("My new template", "sample description", 
                                  insp, defaultTool, tags);
⚠️ **GitHub.com Fallback** ⚠️