Hey all, im looking to use attribute rules to populate a field of another featureclass with the count of intersecting features.
For example, Polygon B intersects Polygon A, in Polygons A table there is a field that has the count of all Polygons in Polygon B intersecting it, so if Polygon B has three polygons intersecting A, A's field shows the integer 3.
I was able to achieve this in a pop-up easy enough, but i cant quite get it to work in attribute rules.
"L16GridSystem15NM" would be "Polygon A" in the above exmaple, $feature would be B, This is what I have so far:
var geom2 = FeatureSetByName($datastore,"L16GridSystem15NM");
var Intersect = Intersects(geom2, $feature);
var AddList = []
var counter = 0
var total = Count(Intersect);
if (total > 0) {
for (var i in Intersect) {
AddList[total] + {
'globalid' : i.globalid,
'attributes': {
'RangeUsage': total
}
}
counter++
}
return {
"edit": [
{
'className' : "L16GridSystem15NM",
'updates' : [
{
'attributes' : {
'RangeUsage' : total
}
}
]
}
]
}
}
I have played around with different options from here:
and documentation here:
I either had a error stating that globalid was not defined in the edit function or if i changed it to the current one above, it says that the Index is out of bounds (script line 😎
any help with this would be great!
Cheers
Keiran
Solved! Go to Solution.
It sounds like you did not create the rule for the polygon.
If your polygons are static (you don't edit them), you can do all of the work from within the point fc:
// Calculation Attriute Rule in TestPoints
// field: empty
// triggers: insert, update, delete
var fs_polygons = FeatureSetByName($datastore, "TestPolygons", ["GlobalID"], true)
var updates = []
// update all polygons that intersect the feature
for(var poly in Intersects($feature, fs_polygons)) {
var point_count = Count(Intersects(poly, $featureset))
if($editcontext.editType == "DELETE") {
// $feature is still there hwen this rule is executed, so we have to substract 1
point_count -= 1
}
Push(updates, {globalID: poly.GlobalID, attributes: {IntegerField: point_count}})
}
// update all polygons that intersected the original feature (before update)
if($editcontext.editType == "UPDATE") {
for(var poly in Intersects($originalfeature, fs_polygons)) {
var point_count = Count(Intersects(poly, $featureset))
Push(updates, {globalID: poly.GlobalID, attributes: {IntegerField: point_count}})
}
}
return {
edit: [{className: "TestPolygons", updates: updates}]
}
Creating points:
Moving points:
Deleting points:
Literal edge cases:
For code display:
Please move the "Insert code sample" button - Esri Community
The count in PolygonsA changes when
For A, it's easy:
// Calculation Attribute Rule in PolygonA (L16GridSystem15NM)
// field: RangeUsage
// triggers: insert, update
// if you want to get fancy, you can return early if neither the geometry
// nor the count field changed:
if(Equals(Geometry($feature), Geometry($originalfeature)) && $feature.RangeUsage == $originalfeature.RangeUsage) {
return $feature.RangeUsage
}
// return the count of intersecting features of PolygonsB
var fs_polygons_b = FeatureSetByName($datastore, "PolygonsB", ["GlobalID"], true)
var intersecting_b = Intersects($feature, fs_polygons_b)
return Count(intersecting_b)
For PolygonsB it's a little more complicated. Basically, whenever a feature is added/updated/deleted in B, you want to trigger the calculation rule in the intersecting A features. In this example I do that by setting the count field to null.
// Calculation Attriute Rule in PolygonsB
// field: empty
// triggers: insert, update, delete
var fs_polygons_a = FeatureSetByName($datastore, "PolygonsA", ["GlobalID"], true)
var updates = []
// update all A features that intersect the new or updated B feature
if(Includes(["INSERT", "UPDATE"], $editcontext.editType)) {
for(var a in Intersects($feature, fs_polygons_a)) {
Push(updates, {globalID: a.GlobalID, attributes: {RangeUsage: null}})
}
}
// update all A features that intersected the original feature (before update or deletion)
if(Includes(["UPDATE", "DELETE"], $editcontext.editType)) {
for(var a in Intersects($originalfeature, fs_polygons_a)) {
Push(updates, {globalID: a.GlobalID, attributes: {RangeUsage: null}})
}
}
return {
edit: [{className: "L16GridSystem15NM", updates: updates}]
}
The rule for PolygonsB currently works for inserting and updating features. It does not work for deleting features, I have absolutely no idea why. Maybe someone else can shed light on that. Maybe @jcarlson ?
Hi Johannes,
I am trying to do something very similar but in my case I want to count the points inside a polygon when a new point is inserted.
I applied this code and when I add a new point the field that captures how many points are in the polygon changes to null, so the code works as expected. I was wondering within this code I could I get it to update the count field in the polygon layer with the correct number of points in the polygon.
Thanks,
Donovan
It sounds like you did not create the rule for the polygon.
If your polygons are static (you don't edit them), you can do all of the work from within the point fc:
// Calculation Attriute Rule in TestPoints
// field: empty
// triggers: insert, update, delete
var fs_polygons = FeatureSetByName($datastore, "TestPolygons", ["GlobalID"], true)
var updates = []
// update all polygons that intersect the feature
for(var poly in Intersects($feature, fs_polygons)) {
var point_count = Count(Intersects(poly, $featureset))
if($editcontext.editType == "DELETE") {
// $feature is still there hwen this rule is executed, so we have to substract 1
point_count -= 1
}
Push(updates, {globalID: poly.GlobalID, attributes: {IntegerField: point_count}})
}
// update all polygons that intersected the original feature (before update)
if($editcontext.editType == "UPDATE") {
for(var poly in Intersects($originalfeature, fs_polygons)) {
var point_count = Count(Intersects(poly, $featureset))
Push(updates, {globalID: poly.GlobalID, attributes: {IntegerField: point_count}})
}
}
return {
edit: [{className: "TestPolygons", updates: updates}]
}
Creating points:
Moving points:
Deleting points:
Literal edge cases:
Hey Johannes, thanks for getting back to me and spending the time to take a look,
What you have for A is what I had too with which is good to see!
For B, that works for me as well which is great, i also have the same issue with deletes though, but this is still pretty good and achieves just about what I need, I'll have another look today at the delete option and see if I can get it to work,
Thanks again!
Kind regards
Keiran