When creating an ArcGIS Pro Calculation Attribute Rule that is triggered by an insert or update, if that includes a check of the geometry ($originalFeature) the rule does not trigger on insert.
The code below is intended to trigger on insert and update. Applied to the $feature, it updates a field value based on an intersecting feature class. It should, in theory, populate on insert or update.
if (Equals(Geometry($originalFeature),Geometry($feature))) {
return $feature.SBPI_ID_NO
}
var parcels = Filter(Intersects(FeatureSetByName($datastore, "Parcel", ["RETIREDBYRECORD", "SBPI_ID_NO"], false), Centroid($feature)),'RETIREDBYRECORD IS NULL')
if (Count(parcels) > 0) {
var select = first(parcels)
return select.SBPI_ID_NO;
}
return null
The assumption is that when you create a new feature the $originalFeature geometry there is NULL (nonexistent) and when compared to $feature, which is assumed to be the new features geometry, the rule will trigger. To clarify, if geometry null/nonexistent is not equal to the new shape geometry the rule should trigger on insert. Because of the design of feature creation in Esri geodatabase (fGDB or eGDB) attribute rules that utilize $originalFeature on insert do not see a geometry change during creation and do not populate attributes.
This may indicate that during feature creation there is a ‘temporary’ object in which the geodatabase utilizes to calculate the features geometry, then the feature is created permanently in the geodatabase. The assumption is that the rule sees that there is a geometry (temporary object) and that geometry has not changed when creating the permanent geodatabase feature which the user sees.
We had to create a separate attribute rule without $originalFeature geometry to trigger on insert only. Then utilize the attribute rule below with the $originalFeature to trigger on update if there is a change to the geometry.
var parcels = Filter(Intersects(FeatureSetByName($datastore, "Parcel", ["RETIREDBYRECORD", "SBPI_ID_NO"], false), Centroid($feature)),'RETIREDBYRECORD IS NULL')
if (Count(parcels) > 0) {
var select = first(parcels)
return select.SBPI_ID_NO;
}
return null
Is this a common issue? Are we utilizing the $originalFeature global incorrectly? Can we confirm that this is in fact how features are created in a Esri Geodatabase?
Solved! Go to Solution.
I did a quick test, your rule works for me, both in FGDB and SDE.
Possible workarounds:
// only compare with original geometry when you update, not on insert
if ($editcontext.editType == "UPDATE" && Equals(Geometry($originalFeature),Geometry($feature))) {
return $feature.SBPI_ID_NO
}
// set includeGeometry to true
var parcels = Filter(Intersects(FeatureSetByName($datastore, "Parcel", ["RETIREDBYRECORD", "SBPI_ID_NO"], true), Centroid($feature)),'RETIREDBYRECORD IS NULL')
if (Count(parcels) > 0) {
var select = first(parcels)
return select.SBPI_ID_NO;
}
return null
I did a quick test, your rule works for me, both in FGDB and SDE.
Possible workarounds:
// only compare with original geometry when you update, not on insert
if ($editcontext.editType == "UPDATE" && Equals(Geometry($originalFeature),Geometry($feature))) {
return $feature.SBPI_ID_NO
}
// set includeGeometry to true
var parcels = Filter(Intersects(FeatureSetByName($datastore, "Parcel", ["RETIREDBYRECORD", "SBPI_ID_NO"], true), Centroid($feature)),'RETIREDBYRECORD IS NULL')
if (Count(parcels) > 0) {
var select = first(parcels)
return select.SBPI_ID_NO;
}
return null
Johannes,
Thanks for taking a look. I'll explore your solution.
To my understanding includeGeometry flag should be set 'true' when you are modifying the features geometry. This concept is outlines in this video at about the 13 min mark.
Again thanks so much!
-Jake
That's a very helpful video, that I missed completely, thanks!
@JohannesLindner Was able to test this and works like a charm. Also tested with includeGeometry flag set to false and executed.