How to draw and add a polygon to the attributes table

770
4
Jump to solution
09-06-2021 10:28 AM
3RGv4
by
New Contributor II

Hello 🙂

 

I have a WPF window and I created a "Draw" button. This button minimize the wpf window and I would like to be able to draw some points on simple click, draw the polygon based on points on double click, then set the polygon to a row of the attributes table (in my feature layer) and maximize the wpf window.

 

I instantiate a "class Draw : MapTool" when I click on the "Draw" button, and try to draw some points on a graphic layer based on an example I found, but it doesn't work (and I don't want to let a graphic layer in my content). I know how to get/set the attributes table but the "draw" functions is the real problem. Is there an other way to do that please ?

 

Thank you ! 🙂

0 Kudos
2 Solutions

Accepted Solutions
Wolf
by Esri Regular Contributor
Esri Regular Contributor

The attached project performs your workflow using a dockpane (not a WPF window).   The project works on 2.7 or newer.

Wolf_0-1631028280268.png

 

View solution in original post

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

I coded your sample snippet in the code below and also found a bug in my attached solution. 

First be bug: The ICommand property in the viewmodel was not named properly it should have been named:

/// <summary>
/// hook existing ArcGIS Pro Tool Button
/// </summary>
public ICommand CmdCreatePolygon => FrameworkApplication.GetPlugInWrapper("CreatePolygon_PolygonTool") as ICommand; 

Second: here is my test snippet that shows the chained edit operation (on the same layer):

/// <summary>
/// Fires once the user completes the on-screen sketch. In the context of a construction tool the sketch geometry 
/// is used for the shape of the feature.
/// </summary>
/// <param name="geometry">The sketch geometry the user digitized on the screen.</param>
/// <returns></returns>
protected override Task<bool> OnSketchCompleteAsync(Geometry geometry)
{
  // find and use the first polygon layer
  var _polygonLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().Where(lyr => lyr.ShapeType == esriGeometryType.esriGeometryPolygon).FirstOrDefault();
  if (_polygonLayer == null)
  {
	MessageBox.Show("Cannot find a Polygon layer to save constructed geometries");
  }
  if (geometry == null || _polygonLayer == null)
	return Task.FromResult(false);
  var dockPane = Module1.ActiveDockPane;
  if (dockPane == null)
  {
	MessageBox.Show($@"Unable to find the Add Polygon dockpane");
  }

  return QueuedTask.Run(() =>
  {
	// create an edit operation
	var editOperation = new EditOperation
	{
	  Name = $@"Create polygon in '{_polygonLayer.Name}'",
	  ProgressMessage = "Working...",
	  CancelMessage = "Operation canceled",
	  ErrorMessage = "Error creating point"
	};
	long newObjectID = -1;
	// update attributes
	Dictionary<string, object> attributes = new Dictionary<string, object>
	{
	  { "TheString", "First edit operation" }
	};
	// queue the edit operation using the sketch geometry as the shape of the feature 
	editOperation.Create(_polygonLayer, geometry, object_id => newObjectID = object_id);
	dockPane.UpdateStatusText($@"Created a polygon in '{_polygonLayer.Name}'");
	//execute the operation
	if (!editOperation.Execute())
	{
	  return Task.FromResult(false);
	}
	// chain to create a new operation
	var opChain = editOperation.CreateChainedOperation();
	attributes["TheString"] = "Chained operation";
	opChain.Modify (_polygonLayer, newObjectID, attributes);
	return opChain.ExecuteAsync();

  });
}

and here is the result, which shows that the chained edit did update the attribute table (by updating the "TheString" field with the "Chained operation" status:

Wolf_0-1631212256314.png

 

View solution in original post

0 Kudos
4 Replies
Wolf
by Esri Regular Contributor
Esri Regular Contributor

The attached project performs your workflow using a dockpane (not a WPF window).   The project works on 2.7 or newer.

Wolf_0-1631028280268.png

 

0 Kudos
3RGv4
by
New Contributor II

Hello !

 

Thank you so much ! I work with the SDK 2.6 but it's not a problem. I adapted your code and it works ! I learnt so much things (EditOperation, SketchType, how to do a dock panel in ArcGis Pro).

 

Thanks again ! 🙂

 

I have one more question about the EditOperation (code below). I instantiated the EditOperation, then I use editOperation.create to create the new row and to fill it with attributes. If the attributes table panel is open, I see my new line. Nice ! After that, I create a chainedEditOperation to add the geometry with chainedEditOperation.Modify. The row is updated, but if the attributes table panel is open, the view is not updated. I have to close and open again the attributes table to see the geometry in the fields.

 

Is it possible to update the view like the "Create" method ?

 

Task t = QueuedTask.Run(() =>
{
   // create an edit operation
   var editOperation = new EditOperation
   {
      Name = $@"Create polygon in '{_polygonLayer.Name}'",
      ProgressMessage = "Working...",
      CancelMessage = "Operation canceled",
      ErrorMessage = "Error creating point"
   };

   long newOid = -1;
   Dictionary<string, object> attributes = new Dictionary<string, object>();
   attributes.Add("Name", EntityNamePreview);

   // queue the edit operation using the sketch geometry as the shape of the       feature and keep the object id
   editOperation.Create(_polygonLayer.GetTable(), attributes, oid => newOid =    oid);

   // if created, fill it with the new polygon
   if (editOperation.Execute())
   {
      var chainedOperation = editOperation.CreateChainedOperation();
      chainedOperation.Modify(_polygonLayer, newOid, PolygonCreated);
      chainedOperation.Execute();
   }
});

while (t.Status != TaskStatus.RanToCompletion) ;

 

Thank you !

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

I coded your sample snippet in the code below and also found a bug in my attached solution. 

First be bug: The ICommand property in the viewmodel was not named properly it should have been named:

/// <summary>
/// hook existing ArcGIS Pro Tool Button
/// </summary>
public ICommand CmdCreatePolygon => FrameworkApplication.GetPlugInWrapper("CreatePolygon_PolygonTool") as ICommand; 

Second: here is my test snippet that shows the chained edit operation (on the same layer):

/// <summary>
/// Fires once the user completes the on-screen sketch. In the context of a construction tool the sketch geometry 
/// is used for the shape of the feature.
/// </summary>
/// <param name="geometry">The sketch geometry the user digitized on the screen.</param>
/// <returns></returns>
protected override Task<bool> OnSketchCompleteAsync(Geometry geometry)
{
  // find and use the first polygon layer
  var _polygonLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().Where(lyr => lyr.ShapeType == esriGeometryType.esriGeometryPolygon).FirstOrDefault();
  if (_polygonLayer == null)
  {
	MessageBox.Show("Cannot find a Polygon layer to save constructed geometries");
  }
  if (geometry == null || _polygonLayer == null)
	return Task.FromResult(false);
  var dockPane = Module1.ActiveDockPane;
  if (dockPane == null)
  {
	MessageBox.Show($@"Unable to find the Add Polygon dockpane");
  }

  return QueuedTask.Run(() =>
  {
	// create an edit operation
	var editOperation = new EditOperation
	{
	  Name = $@"Create polygon in '{_polygonLayer.Name}'",
	  ProgressMessage = "Working...",
	  CancelMessage = "Operation canceled",
	  ErrorMessage = "Error creating point"
	};
	long newObjectID = -1;
	// update attributes
	Dictionary<string, object> attributes = new Dictionary<string, object>
	{
	  { "TheString", "First edit operation" }
	};
	// queue the edit operation using the sketch geometry as the shape of the feature 
	editOperation.Create(_polygonLayer, geometry, object_id => newObjectID = object_id);
	dockPane.UpdateStatusText($@"Created a polygon in '{_polygonLayer.Name}'");
	//execute the operation
	if (!editOperation.Execute())
	{
	  return Task.FromResult(false);
	}
	// chain to create a new operation
	var opChain = editOperation.CreateChainedOperation();
	attributes["TheString"] = "Chained operation";
	opChain.Modify (_polygonLayer, newObjectID, attributes);
	return opChain.ExecuteAsync();

  });
}

and here is the result, which shows that the chained edit did update the attribute table (by updating the "TheString" field with the "Chained operation" status:

Wolf_0-1631212256314.png

 

0 Kudos
3RGv4
by
New Contributor II

Hello ! 🙂

 

I see where is my mistake !

 

Thank you again !!!

0 Kudos