I am trying to create an attribute rule that when I update a field in one polygon, the intersecting polygon's field will also update. Is there an an arcade expression I should try?
Solved! Go to Solution.
Actually, scratch all of this, I thought too hard about it all.
Okay, first rule
// Get Parent shapes
var Parent = FeatureSetByName($datastore,"Parent",["Status"],false);
// Find intersecting parent
var intParent = intersects($feature, Parent)
// Find first parent
var fPar = First(intParent)
return iif(!isEmpty(fpar),fPar.Status,'')
Just make sure you call out the attribute in the rule and it become easier.
Second rule (apply this one to the parent layer) - this is one I actually put together for a different project and had forgotten about until now:
// Get Buildings shapes
var Buildings = FeatureSetByName($datastore,"Parent",["Status"],false);
// Find all intersecting buildings
var intBuilds = intersects($feature,Buildings)
var stat = ''
// Loop through all buildings. This will push the status from the Parent feature to all buiuldings features that touch it
var pUpdates = []
for (var s in intBuilds){
var update = {
objectID:s.OBJECTID,
attributes: {Status:$feature.Status}
}
Push (pUpdates,update)
}
return {
edit: [{
className: "Buildings",
updates: pUpdates
}]
}
I just duplicated this in my environment and the rules worked, so reply back with what you find!
Here's a rule I have in my production environment. It runs on a point feature class but that's not a requirement, can be a polygon also. This will essentially check if a newly places point intersects three different layers, and write an attribute from each of those layers to the newly created point if there is an intersect. So this runs on an insert, but you could set it to update instead.
// Make layers available
var cityParcels = FeatureSetByName($datastore, "epgdb.GIS.Parcels",['PID','Address'],false);
var parks = FeatureSetByName($datastore, "epgdb.PARKS.Parks",['PARKNAME'],false);
var owner = FeatureSetByName($datastore, "epgdb.parks.TreeOwnership_vw",['Ownership'],false);
// Find intersection feature
var fAdd = First(Intersects($Feature, cityParcels));
var fPrk = First(Intersects($Feature, parks));
var fOwn = First(Intersects($Feature, owner));
// Variables - check for nulls. If the feature does not intersect a feature on the polygon layer, return null
var addr = IIF(!IsEmpty(fAdd),proper(fAdd.Address),null)
var prk = IIF(!IsEmpty(fPrk),proper(fPrk.PARKNAME),null)
var own = IIF(!IsEmpty(fOwn),proper(fOwn.Ownership),null)
// Use a dictionary to write the values of the null-check variables
return{
'result':{
'attributes':{
'Address':addr,
'Park':prk,
'Location':own,
}
}
}
Okay so for example, I am placing a polygon with a specific field. I am then placing another polygon inside of it and currently it copies that field to the new feature. Will this allow me to add a rule that when I change that field in the first polygon, it will auto update that field in the second polygon?
Are the two different polygons on two layers, or are they in the same dataset?
They are currently two different layers.
Great, that does make it a bit easier. So this will basically pushes the changes from the feature where the edit occurs to the second feature class that you've identified as a variable and found a match. Pretty much just changing the structure of the dictionary:
return {
edit: [{
className: "Feature.Class.Name",
updates: [{
objectID: asset.OBJECTID,
attributes: {
<Field Name From Layer 2>: $feature.FieldName,
<Field Name From Layer 2>: $feature.FieldName
// add additional attributes as necessary
}
}]
}]
}
So for example, Parent is my source polygon. I am drawing Building inside of it and it is copying the status field of Parent. When I change the Parent status, it also changes Building. This is my current expression, but it throws an invalid Key message on line 15, <Field Name From Layer 2>: $feature.Status. Am I missing somthing? I removed the null section because the value in the field would never be null.
EDIT - don't pay attention to this, neither of these will work, scroll down to my second reply, which is much better.
For starters, it looks like your variable names didn't get updated when you reworked it into your own data, so that's important. Additionally, in your return, you'd need to replace <Field Name From Layer 2> with the actual name of the field you want to update.
Here are a couple of rules that I think get you what you want. The first one is on the buildings and will apply the parent status when the building is created. The second will push the parent status to all intersecting buildings when the parent is updated. I am a little unsure if I did the loop correctly, so if anyone else following along here sees an issue, please feel free to update it.
// RULE RUNS ON INSERT
// APPLY RULE TO BUILDING FEATURE CLASS
// Get Parent shapes
var Parent = FeatureSetByName($datastore,"Parent",["Status"],false);
// Find intersecting parent
var intParent = intersects($feature, Parent)
// Find first parent
var fPar = First(intParent)
//
return {
'result':{
'attributes':{
'Status':fPar.Status
}
// RULE RUNS ON UPDATE
// APPLY RULE TO PARENT FEATURE CLASS
// Get Buildings shapes
var Buildings = FeatureSetByName($datastore,"Parent",["Status"],false);
// Find all intersecting buildings
var intBuilds = intersects($feature,Buildings)
var bStatus = intBuilds.Status
// Loop through all buildings. This will push the status from the Parent feature to all buiuldings features that touch it
for (var s in intBuild){
bStatus = $feature.Status
}
return {
edit: [{
className: "Buildings",
updates: [{
objectID: Buildings.OBJECTID,
attributes: {
Status: bStatus,
}
}]
}]
}
Actually, scratch all of this, I thought too hard about it all.
Okay, first rule
// Get Parent shapes
var Parent = FeatureSetByName($datastore,"Parent",["Status"],false);
// Find intersecting parent
var intParent = intersects($feature, Parent)
// Find first parent
var fPar = First(intParent)
return iif(!isEmpty(fpar),fPar.Status,'')
Just make sure you call out the attribute in the rule and it become easier.
Second rule (apply this one to the parent layer) - this is one I actually put together for a different project and had forgotten about until now:
// Get Buildings shapes
var Buildings = FeatureSetByName($datastore,"Parent",["Status"],false);
// Find all intersecting buildings
var intBuilds = intersects($feature,Buildings)
var stat = ''
// Loop through all buildings. This will push the status from the Parent feature to all buiuldings features that touch it
var pUpdates = []
for (var s in intBuilds){
var update = {
objectID:s.OBJECTID,
attributes: {Status:$feature.Status}
}
Push (pUpdates,update)
}
return {
edit: [{
className: "Buildings",
updates: pUpdates
}]
}
I just duplicated this in my environment and the rules worked, so reply back with what you find!
Great! this helped. Had to make a minor adjustment on my end, but it worked and did what I needed it to do. Appreciate the assistance.