ArcGIS Pro

Limit Edits within a Boundary with Attribute Rules

How do I limit the editing extent? How can I restrict editing to certain boundaries? How can I limit users to edit only within the work order boundary assigned to them? Is it possible to limit users to edit in some boundaries and not in others? We get these questions a lot and in this blog we will illustrate how we can do this with Attribute Rules.

Limit Edits within a Boundary Area

In this example we want to create a boundary feature class which will represent the restrictive zones or areas. We will also create another feature class that represents the data; Finally we will add an attribute rule to the feature class that checks if the feature being created or updated is within the boundary.

Note: This example can be done in a File geodatabase with ArcGIS Pro 2.4 or later. However I’m using an enterprise geodatabase.

In an Enterprise geodatabase, create the following two feature classes with fields as illustrated.

 

 

 

Add a constraint Attribute Rule to the pointClass, make it execute on Insert, Update and Delete then click on save.  Use the following script

//allow edits only inside the boundary
var fsBoundary = FeatureSetByName($datastore, "boundaryClass", ["globalId"], false);
return Count(Intersects(fsBoundary, Geometry($feature))) > 0

Let us test this out, create a polygon in the boundaryClass and try creating point features outside and inside the boundary.

Limit Edits to User Assigned Boundaries

So the example above was pretty simple and straight forward. There is one or more boundaries and you want all your users to make sure to edit within the boundary. However, is it possible to use Attribute Rules to allow certain users to only edit in their assigned boundaries? Building on the example above, we will find out how to do that. Note that you can also apply the same idea to job and work orders.

This example can be done with ArcGIS Pro 2.5 and a client/server connection to an enterprise geodatabase. However I’m using ArcGIS Enterprise 10.8 through services.

First we will need an extra table that have the users assigned boundaries. Create a usersBoundary table, with a username text field and a boundaryGuid field foreign key to the globalId of the boundaryClass. We will also create a relationship class between the boundaryClass and the usersBoundary table. You don’t have to create the relationship, but it will allow us to assign multiple users to a boundary and will simplify editing the table in Pro.

 

 

 

Final thing we need on our pointClass is to enable editor tracking.  This is how we can tell what user is actually making the edit on attribute rule by looking at $feature.last_edited_user.

 

 

 

Ok we have all what we need, let us assign users to boundaries as follows:

 

 

 

Let us edit our attribute rule script on pointClass to the following script.

 

//get the current user
var user = $feature.last_edited_user;

//get the current Boundary the feature is created/updated on.
var fsBoundary = FeatureSetByName($datastore, "boundaryClass", ["globalId", "boundaryId"], false);
var fsIntersectedBoundaries = Intersects(fsBoundary, Geometry($feature))
//if no boundary error
if (Count(fsIntersectedBoundaries) == 0)
   return {"errorMessage": "Features must be created within a boundary"} 

//we are interested in the first boundary
//we can enhnace the script to look for all boundaries
var boundary = First(fsIntersectedBoundaries);
var boundaryGlobalId = boundary.globalId;

//query the usersBoundary class
var usersBoundary = FeatureSetByName($datastore, "usersBoundary"); 
//is the user allowed to edit this boundary?
var usercanEdit = Count(Filter(usersBoundary, "username = @user AND boundaryGuid = @boundaryGlobalId")) > 0

var bid = boundary.boundaryId
//return a good error message
if (usercanEdit == false) 
   return {"errorMessage": "User " + user + " is unauthroized to edit Boundary " + bid }

return usercanEdit;

Let us put our attribute rule to the test. If we log in as Jessica, we will only be able to create features on Boundary 1. Attempts to create features on Boundary 2 or 3 will fail.

Similarly, Thomas can only edit features in Boundary 2

Finally,  William can only edit features in Boundary  3.

This also applies for deleting features.

Updating features is the trickiest though. With the script we have now, Thomas can move features from any boundary to his Boundary, that is because we are only checking the Geometry($feature) which is the state of the feature AFTER it was updated. So if Tom moves the feature to Boundary 2 we will allow it which is wrong!

To achieve this we will need a new Arcade global that we have introduced in ArcGIS Pro 2.5/ 10.8 called the $originalFeature read more about this in this blog.

We  want to make sure that Tom is allowed to move the feature from its original geometry and that he is also allowed to move the feature to its new location. We will simplify the code by using Arcade functions, lets put all our code in canEdit that takes the user and the feature geometry and we will do the same code essentially.

The final script can be found here.

 

 

The benefit of doing this work with attribute rules is any client consuming the feature service will get this behavior, whether this is through Pro, Web Editor or Collector (connected).  You can alternatively write server side code like SOEs or SOIs to achieve similar scenario.

 

Note that the code above is provided for demonstration purposes only, assigning many users to boundaries individually my become difficult to manage. Therefore we are thinking of better ways for solving this problem for example by introducing the portal access controls in Arcade so we can work with groups instead of individual users.

Free ArcGIS Pro Trial

About the author

Product Engineer at Esri, Author of several GIS books and Software Engineering Content Creator on YouTube and a podcast host.

Connect:
3 Comments
Oldest
Newest
Inline Feedbacks
View all comments

Next Article

Basemap Releases Include Over 300 New and Updated Communities

Read this article