Select to view content in your preferred language

Apply count of intersecting features to another features attribue field

1322
4
Jump to solution
01-10-2022 02:55 PM
KeiranBray
Esri Contributor

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: 

https://www.esri.com/arcgis-blog/products/arcgis-pro/data-management/advanced-gdb-attribute-rules-ed...

and documentation here:

https://pro.arcgis.com/en/pro-app/2.8/help/data/geodatabases/overview/attribute-rule-script-expressi...

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

0 Kudos
1 Solution

Accepted Solutions
JohannesLindner
MVP Frequent Contributor

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}]
}

 

JohannesLindner_0-1655886453252.png

 

Creating points:

JohannesLindner_1-1655886491017.png

 

Moving points:

JohannesLindner_2-1655886531504.png

 

 

Deleting points:

JohannesLindner_3-1655886550980.png

 

Literal edge cases:

JohannesLindner_4-1655886605810.png

 


Have a great day!
Johannes

View solution in original post

0 Kudos
4 Replies
JohannesLindner
MVP Frequent Contributor

For code display:

JohannesLindner_0-1641884667644.pngJohannesLindner_1-1641884685610.png

Please move the "Insert code sample" button - Esri Community

 

The count in PolygonsA changes when

  • a feature is added in B
  • a feature is updated in B
  • a feature is deleted in B
  • a feature is added in A
  • a feature is updated in A

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 ?


Have a great day!
Johannes
DonovanC
Occasional Contributor

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

0 Kudos
JohannesLindner
MVP Frequent Contributor

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}]
}

 

JohannesLindner_0-1655886453252.png

 

Creating points:

JohannesLindner_1-1655886491017.png

 

Moving points:

JohannesLindner_2-1655886531504.png

 

 

Deleting points:

JohannesLindner_3-1655886550980.png

 

Literal edge cases:

JohannesLindner_4-1655886605810.png

 


Have a great day!
Johannes
0 Kudos
KeiranBray
Esri Contributor

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

0 Kudos