Streamlining Edits in the Utility Network With Attribute Rules

April 10, 2020 — Caleb Melies

If you are an ArcGIS Pro user in the utility space, you are probably familiar with the new Utility Network.

ESRI’s Utility Network for ArcGIS Pro is awesome and it’s even more awesome when utilizing Attribute Rules.  Today we will take a look at saving time for editors of the Utility Network by strategically building attribute rules that automate some of the tedious edits.

In today’s example, we will not get into the differences of Calculation vs Constraint vs Validation, instead, focusing on Immediate Calculation rules and how to automatically update an Assembly when editing one of its Devices. For this example, we are going to update the assembly’s label field with the sum of its contained devices kVA’s.  This Calculation rule should be applied to the ElectricAssembly Class and will be triggered by Updates.

NOTE: Don’t forget to check the “Exclude from application evaluation” Checkbox under the Execution section before saving your rule.  You cannot change this later.

Step 1: Find the Device’s Associated Assembly (it’s container).

The 2.4 Way

  1. Get the associations table
  2. Filter for the devices globalid in the toglobalid field where associationtype is 2 (container)
  3. Assign the fromglobalid field to a variable to use later
var un_6_associations = FeatureSetByName($datastore,'UN_6_Associations');
var containerRows = Filter(un_6_associations, "toglobalid = '" + $feature.globalid + "' AND associationtype = 2");
if(Count(containerRows) == 0) return 'no associations found';
var container = First(containerRows);
var assemblyGlobalId = container.fromglobalid;

The 2.5 Way

  1. Use the new function FeatureSetByAssociationI() to get the features container
  2. Assign the assembly’s globalid to a variable
var containerRows  = FeatureSetByAssociation($feature, "container")
if (count(containerRows) == 0) return $feature.labeltext;
var assemblyAssociationRow = first(containerRows)
var assemblyGlobalId = assemblyAssociationRow.globalId;

Step 2: Find All Contained (Sister) Devices.

The 2.4 Way

  1. Filter the associations table for devices contained by the assembly found in step 1
  2. Generate a list of device globalids
var devices = Filter(un_6_associations, "fromglobalid = '" + assemblyGlobalId + "' AND associationtype = 2");
var globalIds = [];
var i = 0;
for (var unit in devices){
globalIds[i++] = unit.toglobalid;
}var deviceClass = FeatureSetByName($datastore, "ElectricDevice", ["kva"], false);

The 2.5 Way

  1. Get the Assembly Feature
  2. Make a list of the devices’ globalid’s
  3. Get the devices using the list of their globalid’s
var assemblies = FeatureSetByName($datastore, "ElectricAssembly", ["labeltext"], false)
var assembly = First(Filter(assemblies, "globalid = @assemblyGlobalId"));
var contentRows  = FeatureSetByAssociation(assembly, "content")
var globalIds = [];
var i = 0;
for (var v in contentRows) {
globalIds[i++] = v.globalId
}
var deviceGlobalId = $feature.globalId;
var deviceClass = FeatureSetByName($datastore, "ElectricDevice", ["kva"], false)
var devicesRows = Filter(deviceClass, "globalid <> @")
var devicesRows = Filter(devicesRows, "globalid in @globalIds")

Step 3: Sum the devices KVA

The 2.4 Way

  1. Loop through the list of device globalids
  2. Filter the device features and sum up their kva’s
var totalKVA = 0;
for (var i=0; i < Count(globalIds); i++){
var globalId = globalIds[i];
var deviceRow = Filter(deviceClass, "globalid = '" + globalId + "'");
var device = First(deviceRow)
totalKVA += device.kva;
}

The 2.5 Way

  1. Loop through the devices and sum up their kva’s
var totalKVA =  0;
for (var device in devicesRows){
totalKVA+= number(device.kva);
}
totalKVA += number($feature.kva);

Step 4: Return the result and edit the assembly

Both 2.4 & 2.5 Ways

  1. Making use of Arcades Edit return object, we define our Assembly’s class
  2. Point the updates object at our assembly’s globalid
  3. Tell it to update the assembly’s labeltext field with the totalKVA value
return {
    "result": $feature.kva,
    "edit": [
        {
            "className": "ElectricAssembly",
            "updates": [
                {
                    "globalID": assemblyGlobalId,
                    "attributes": {
                        "labeltext": totalKVA
                    }
                }
            ]
        }
    ]
}

Bonus Step 2.5:

With the release of ArcGIS Pro 2.5 came the addition of $originalfeature in Arcade. This new feature allows us to prevent unwanted firing of our rules by wrapping them in a simple if statement. By comparing the previous field value to the edited field value, we can ensure our rules only run when fields we are interested in change.

if($originalfeature.kva !== $feature.kva){
    // Place Arcade Expression Here
} else {
    return
}

Et Voila!

By applying an attribute rule to the ElectricDevice class, we’ve leveraged the power of Arcade to automatically keep our Assembly’s labeling inline with the totalKVA of it’s contained devices. In doing this, we’ve saved countless clicks, sticky notes for shorthand math, and potentially many many human entry/math errors. Thanks to the power of Arcade, there are endless possibilities of how you can save edits and increase proficiency across the board.

We Wrote the Book

The Indispensible Guide to ArcGIS Online

Download It for Free

Caleb Melies

What do you think?

Leave a comment, and share your thoughts

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>


This site uses Akismet to reduce spam. Learn how your comment data is processed.