I have a calculation attribute rule that updates polyline geometries: Set polyline M-values to cumulative length of line. That attribute rule works as expected in ArcGIS Pro 2.9.2 / FGDB (test environment).
Now, I want to use it in our 10.7.1 EGDB and ArcGIS Pro 2.5.0 (production environment).
When I go to create the rule, I notice that the Field is mandatory, yet the SHAPE field is missing from the field list:
(That's different than 2.9.2 -- the field isn't mandatory in 2.9.2, and the SHAPE field shows up in the list.)
If the Field is mandatory in 2.5.0, and the SHAPE field is missing from the list, then how can I create an attribute rule that updates the geometry?
Thanks!
These were changes made in 2.6 (geometry updates) and 2.7 (update multiple fields). Arcade and Attribute Rules are under active development, so sadly, something like this is bound to happen now and then.
how can I create an attribute rule that updates the geometry?
In 2.5, you can't.*
You'll have to update your production environment. Pro 2.7 should be enough for your rule, but go take a look at the Arcade Release History, maybe there are some functions you want to use from later releases. Combined with the Arcade Version Matrix, this will tell you the versions of Pro and Enterprise.
*: Well, maybe (I didn't check versions or test this) you can update the geometries from another table:
// Calculation Attribute Rule on GeometryUpdateControlTable
// field: DoItNow (integer field, 1 means "update now")
// triggers: update
// requires another field: ObjectIDsToBeEdited (Text field with comma separated ObjectIDs of the polyline features. Null means all.)
var fs_polylines = FeatureSetByName($datastore, "PolylineFC", ["OBJECTID"], true)
if(!IsEmpty($feature.ObjectIDsToBeEdited)) {
var where = `ObjectID IN (${$feature.ObjectIDsToBeEdited})`
fs_polylines = Filter(fs_polylines, where)
}
var polyline_updates = []
for(var f in fs_polylines) {
var geom = Dictionary(Text(Geometry(f))) // f instead of $feature
var paths = geom['paths']
var oldX = paths[0][0][0];
var oldY = paths[0][0][1];
var line_length = 0;
for (var path_idx in paths) {
for (var point_idx in paths[path_idx]) {
var newX = paths[path_idx][point_idx][0];
var newY = paths[path_idx][point_idx][1];
//For multi-part features, we want the M-value for additional parts to start at the last M-value from the last part. We don't want to measure the distance *between* parts.
//So, for the first vertex in a given part, we will skip calculating the length between vertices.
if (point_idx != 0) {
line_length += pythagoras(oldX, oldY, newX, newY);
}
//We can use a negative slice: it will work when there is no Z.
paths[path_idx][point_idx][-1] = line_length;
oldX = newX;
oldY = newY;
}
}
Push(polyline_updates, {"objectID": f.OBJECTID, "geometry": Polyline(geom)})
}
return {
"result": 0,
"edit": [
{
"className": "Database.Dataowner.PolylineFC",
"updates": polyline_updates
}
]
}
This way, you could start the calculation manually by setting DoItNow to 1. Also, you could do it automatically:
// Calculation Attribute Rule on PolylineFC
// field: SomeField that is editable
// triggers: update
if (Text(Geometry($feature)) == Text(Geometry($originalfeature))) {
console("The geometry has not changed. We don't need to redefine the M-Values.")
return $feature.SomeField
}
console("The geometry has changed. So we *will* redefine the M-Values.")
return {
"result": $feature.SomeField,
"edit": [
{
"className": "Database.Dataowner.GeometryUpdateControlTable",
"updates": [{
"objectID": 1, "attributes": {
"ObjectIDsToBeEdited": Text($feature.ObjectID),
"DoItNow": 1
}}]
}
]
}
Thanks very much. That helps.
As you suggested, I'm looking into updating my version of Pro:
What versions of Pro are compatible with 10.7.1 EGDBs?