ArcGIS Pro SDK - Updating the same attribute on multiple features

1352
5
06-14-2019 09:35 AM
KevinMahoney
New Contributor III

Hello all,

I am trying to update a single attribute on 100 different features of at most 4 different layers, with the same value.  In my case I have 100 features that need a "comments" field updated.  

I used the Inspector class to modify multiple features, since it seems to be the preferred method on the ProSnippets documentation.  However I noticed something odd when it took nearly 20 seconds to complete.  I ran Fiddler  to look at all the network calls to ArcGIS Server that were made during the process and saw that "applyEdits" was called once for each feature that I loaded into the inspector  (see below screenshot, under code snippet), this resulted in 100 applyEdits calls and 100 queryFeature calls, 200 in total.  I was expecting at most 1 call per layer.

I recorded some timings based on larger feature counts for my EditOperation to finish the "ExecuteAsync" method.

Is there a way for me to configure Inspector to only make at most 1 call per updated layer?  Or is there a better method through the SDK?

Feature CountDuration (in seconds)

104

20

210

54

306

70

500

109

650

113

1100

247

1200

276

public static async void ApplyUpdateUsingInspector(IDictionary<Layer, List<FeatureObject>> layerAttributes, object value, string fieldName)
{
	await QueuedTask.Run(async () =>
	{
		var editOperation = new EditOperation();
		editOperation.Name = "Changing attribute...";
		editOperation.ProgressMessage = "Working...";
		editOperation.ShowProgressor = true;
		editOperation.CancelMessage = "Operation canceled";
		editOperation.ErrorMessage = "Error updating attributes";
		foreach (var layer in layerAttributes.Keys)
		{
			var features = layerAttributes[layer];
			var objectIds = from feature in features
							from attribute in feature.Attributes
							where attribute.Key == "ObjectID"
							select (long)attribute.Value;
			var inspector = new Inspector();
			inspector.Load(layer, objectIds.ToArray());
			inspector[fieldName] = value;
			editOperation.Modify(inspector);
			 
		}
		if (editOperation.IsEmpty)
		{
			editOperation.Abort();
		}
		else
		{
			await editOperation.ExecuteAsync();
		}

	});
}

0 Kudos
5 Replies
SeanJones
Esri Regular Contributor

Kevin,

This is currently as expected and the cause is events even if your process isn't subscribing.

Each feature is being created and returned through the query to allow the whole edit to be cancelled at any time through a row event. Its something that has to be optimized...

0 Kudos
KevinMahoney
New Contributor III

Sean,

 

Looking at "applyEdits"  in the FeatureServer section of the REST API, this process can update a large amount of features in one call. 

 

From the API:  (REST API)

"The applyEdits operation applies edits to features associated with multiple layers or tables in a single call (POST only). This operation is performed on a feature service resource. The result of this operation is an array of edit results for each layer/table edited. Each edit result identifies a single feature on a layer or table and indicates whether the edits were successful or not. If an edit is not successful, the edit result also includes an error code and an error description."

 

Is there anyway to do this with the Pro SDK?  I ran the applyEdits service on my FeatureServer in one bulk call, using my clients sessionID and version guid that I retrieved from fiddler.  This time the same 1200 features were updated in 15-20 seconds, which is much faster than the 276 above.  I was also able to undo this bulk transaction from within Pro within my version (branch versioning)

 

 Due to the timing difference, I am considering using applyEdits using the REST API within the Pro client.  Is there anyway to retrieve the sessionID from the SDK?  I was unable to find it, and need it since I am using Branch Versioning, and need to be able to undo changes within that specific session

 

Thanks,

Kevin

0 Kudos
SeanJones
Esri Regular Contributor

Hi Kevin,

The sessionID isnt exposed in the public API.

A few things to try;

ApplyEdits is available for console applications. It wasn't designed to run in Pro, but it isn't blocked from doing so either. Be aware of the caveats mentioned in that topic.

As a curve ball you can also try the GP tool, "calculate field" called via Geoprocessing.ExecuteToolAsync. This tool doesn't fire row events but im unsure how well this will perform against a branch version.

0 Kudos
KevinMahoney
New Contributor III

Hi Sean,

ApplyEdits from the pro-sdk will not work since it does not support Undo/Redo functionality, and the user needs to be able to undo the changes that we are attempting to make with this bulk transaction.  Also this does not support updating the map, which we also require for this process.

I tried Calculate Field from within Pro, and for only 37 features this took 2 minutes and 16 seconds.  

Can you confirm if sessionId will be exposed in the public API at some point? 

0 Kudos
SeanJones
Esri Regular Contributor

Hi Kevin,

There's no plans to expose the sessionID. The focus will be on providing a mechanism to do the bulk creates/updates.

0 Kudos