ArcGIS Pro

Simulate Session Attributes with Attribute Rules (LastValue)

When creating features, users may fill different attributes in the editing template. Features often share common attributes and populating these attributes on every feature can be time consuming.  Setting default values at both the field and subtype level helps with the workflow; however, attributes values can be different from default values in each user edit session.

A common example of this  is populating the workorder Id for all features in a work order. The editor may create hundreds of features that all need to have the same workorderId for the current project they are planning, but then have a different workorder id on a different project. Of course, they could select all features and do a field calculate, but it is more convenient to set the workorderId once and let subsequent edits pick up the workorderId to improve the editing experience. This is similar to the LastValue option found in Attribute Assistant.

In this blog I’ll show you how to set and read session attributes and then use them to populate attributes when creating features using attribute rules. I will use a point feature class with two fields ‘workorderId’ and ‘workordertype’, where I will set the attributes once so that any point features created will have the attributes populated.

Here is an example of what we are building:

 

You can download the sample geodatabase found in this blog here.

Creating the tables and classes

We first need a table to store our session attributes.  This table will act like as a template for the attribute rule to read fields from and populate them in the features that are created.

To do this, create a mobile geodatabase and then create a table named sessionattributes with three fields:

Example of the table schema used to store session attributes

Next we create a point feature class with two fields:

 

 

Example schema of the point feature class

 

With that completed, we are now ready to write the attribute rule.

 

Writing the attribute rule

We need to write an attribute rule on the point class that will read the fields from the sessionattributes table and populate them in the field on the point feature class on insert.

Of course the user has to populate the sessionattributes table for this to work. At the end of the blog I’ll show how we can write the attribute rule in a way that updates sessionattributes with the last values if no fields were detected.

Let’s now insert two session attributes in the table, one for workorderid and one for workordertype.

 

 

Example attributes entry in the table.

Now to write the attribute rule:

//read the session variables
var fs = FeatureSetByName($datastore, "sessionattributes");
//get all variables for the pointclass table
var f = filter(fs, "tablename = 'pointclass'");
//build the return dictionary
var res  = {
    "attributes": {}
}

for (var r in f) {
     res.attributes[r.fieldname] = r.fieldvalue
 }

return {
    "result": res
}

 

Modify the Rule to Overwrite variables

When supporting variables, you want an easier way for the user to edit these attributes without having to go to the session table for editing every time. I thought a good way to override the variables would be to let the user explicitly set them in the template while creating the feature. If the user specifies attributes,  we use them and update the session attributes table with them.  If the user didn’t provide an attribute we use the ones already in the table.

Here is how it works now:

And the updated rule:

//read the session variables
var fs = FeatureSetByName($datastore, "sessionattributes");
var attributes = [];
var attributeCount = 0;

//optional, if the user provided attributes, we override the session attributes 
var updates = []
var editCount = 0;
//if the field is set we update the session attribute table
if (!isempty($feature.workorderid)) {
    var wid = first(filter(fs, "tablename = 'pointclass' and fieldname = 'workorderid'"));
    //make sure to add each attribute at least once (TODO: code can be changed to auto add )
    if (wid != null)
        updates[editCount++] = {
            "globalId": wid.globalid,
            "attributes": {
                "fieldvalue": $feature.workorderid
            }
        }
} else //if it is not set we ask for it 
    attributes[attributeCount++] = "workorderid";


if (!isempty($feature.workordertype)) {
    var wid = first(filter(fs, "tablename = 'pointclass' and fieldname = 'workordertype'"));
    //make sure to add each attribute at least once (TODO: code can be changed to auto add )
    if (wid != null)
        updates[editCount++] = {
            "globalId": wid.globalid,
            "attributes": {
                "fieldvalue": $feature.workordertype
            }
        }
} else //if it is not set we ask for it 
    attributes[attributeCount++] = "workordertype";



//get all variables for the pointclass table
var f;

var returnPayload = {}

if (count(attributes) > 0) {

    f = filter(fs, "tablename = 'pointclass' and fieldname in @attributes");

    //build the return dictionary
    var res = {
        "attributes": {}
    }
    //whatever we get back is what we set on $feature
    for (var r in f) {
        res.attributes[r.fieldname] = r.fieldvalue
    }

    returnPayload["result"] = res;
}

if (count(updates) > 0)
    returnPayload["edit"] = [{
        "className": "main.sessionattributes",
        "updates": updates
    }]

return returnPayload;

 

You can download the mobile geodatabase containing this example and rule here.

 

In this blog we showed how to write an attribute rule that reads the last attribute values making editing more effective. The rule can be configured to work on multiple classes and work on local filegdb, mobile or services.

About the author

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

Connect:
0 Comments
Inline Feedbacks
View all comments

Next Article

Pop-ups: the essentials

Read this article