Select to view content in your preferred language

Arcade Expression to count points intersecting multiple polygons

4380
6
Jump to solution
02-24-2021 09:34 AM
JasonGlidewell
Occasional Contributor

Hi,

I am trying to count the number of point features intersecting multiple polygons.  I have filtered the polygons by an attribute value.

I have included what I have below but I keep getting an error stating, "Spatial Relation cannot accept this parameter type"

My goal is to click on a polygon and count all the points intersecting all polygon with the same text attribute.

Any help would be greatly appreciated!

JasonGlidewell_2-1614188056373.png

 

 

 

 

0 Kudos
1 Solution

Accepted Solutions
jcarlson
MVP Esteemed Contributor

Gotcha!

Well, this is certainly still possible, but it could be a really laggy expression. Intersects wants either two geometries, or a geometry and a FeatureSet, but not two FeatureSets.

To deal with this, you've got to run your Intersection against a single district feature. Initially, I'd thought to use the Union function to merge the districts first, but my test said I used an "Illegal Argument", so I went with plan B: a for-loop.

I'll use a layer of house locations and Tax Districts for my example. Here in orange are all the tax districts (there are 4 of them) with a particular value in their "Park District" field.

jcarlson_0-1614193226290.png

// Get park dist ID
var p_id = $feature.park

// Filter layer for all matching park IDs
var dists = Filter($layer, "park = @p_id")
Console(Count(dists) + ' districts')

// Houses layer
var houses = FeatureSetByName($map,"CAMA ")

// Instantiate final count at 0
var final_count = 0

// Iterate over dists FeatureSet and get intersected houses for each
for(var d in dists){
    var h_count = Count(Intersects(houses, d))
    Console(h_count + ' houses')
    
    final_count += h_count
}

Console('Total: ' + final_count)
return final_count

Which returns:

CONSOLE:
4 districts
21 houses
48 houses
0 houses
9 houses

RESULT:
78

 Depending on how many points and districts we're talking about, your popup expression could be evaluating dozens of separate intersections, but this should work.

- Josh Carlson
Kendall County GIS

View solution in original post

6 Replies
jcarlson
MVP Esteemed Contributor

Just a general tip, don't forget about the Code Sample option on here, it can make your post a lot easier to read for other users.

jcarlson_0-1614188861002.png

It would help to know more about all of these layers. You mention points and "multiple" polygons; which layers are the points, and which are the polygons? Can you give an example situation and the output you'd expect to get from it?

I can see you're using the Console function; are you getting messages from those? Does the error message specifically point to the Intersects line?

I'm sure there's a way to address this, but I don't think I have enough information.

- Josh Carlson
Kendall County GIS
0 Kudos
JasonGlidewell
Occasional Contributor

Hi Josh,

I appreciate your willingness to help.  I apologize for the question error.  This is my first post on here.

My polygons represent operating areas.  However, a single person oversees multiple operating areas.  By clicking on one polygon I would like to get the count of all points (in this case customer locations) within all polygons overseen by the same person.  The name of the supervisor is an attribute in all polygons.

My featureset after the filter includes the required polygons, confirmed by the Console Count on line 13.  However, it seems the intersect function can not accept more than one polygon, at least that is my guess.

My points have the variable prem and are brought in via portal.  My polygons have the variable PWSID and are also brought in via portal.  From there, I am filtering by the polygons by "OperatingDistrict".  However, it seems this filtered featureset is unacceptable to the intersects function.

// Sources: Meter Pits Clean-up, wMeterPit, Meter Pit Collection, Meter Collection, wPremiseLocation
var mpcu = FeatureSetByPortalItem(Portal('https://maps.arcgis.com/'), '060fbd931a9d4736bfc495839c6279bf', '0')
var mpsde = FeatureSetByPortalItem(Portal('https://maps.arcgis.com/'), 'e56c278361ee4e758bff62bea1eb1a27', '0')
var mpcol = FeatureSetByPortalItem(Portal('https://maps.arcgis.com/'), '5abe4e6ee79341a4a3cb6264a0774409', '15')
var mcol = FeatureSetByPortalItem(Portal('https://maps.arcgis.com/'), '5abe4e6ee79341a4a3cb6264a0774409', '16')
var prem = FeatureSetByPortalItem(Portal('https://maps.arcgis.com/'), 'c64a2c678acf46b098f0c063797a2474', '0')

var PWSID = FeatureSetByPortalItem(Portal('https://inaw.maps.arcgis.com/'), '10e903ae8c11435c80667d764ec1b226', '0')
var opdist = $feature.OperatingDistrict
Console(opdist)
var premsql = "OperatingDistrict LIKE @opdist"
var opdistfilter = Filter(PWSID, premsql)

var intcount = Count(Intersects(opdistfilter,prem))

return intcount

 

0 Kudos
jcarlson
MVP Esteemed Contributor

Gotcha!

Well, this is certainly still possible, but it could be a really laggy expression. Intersects wants either two geometries, or a geometry and a FeatureSet, but not two FeatureSets.

To deal with this, you've got to run your Intersection against a single district feature. Initially, I'd thought to use the Union function to merge the districts first, but my test said I used an "Illegal Argument", so I went with plan B: a for-loop.

I'll use a layer of house locations and Tax Districts for my example. Here in orange are all the tax districts (there are 4 of them) with a particular value in their "Park District" field.

jcarlson_0-1614193226290.png

// Get park dist ID
var p_id = $feature.park

// Filter layer for all matching park IDs
var dists = Filter($layer, "park = @p_id")
Console(Count(dists) + ' districts')

// Houses layer
var houses = FeatureSetByName($map,"CAMA ")

// Instantiate final count at 0
var final_count = 0

// Iterate over dists FeatureSet and get intersected houses for each
for(var d in dists){
    var h_count = Count(Intersects(houses, d))
    Console(h_count + ' houses')
    
    final_count += h_count
}

Console('Total: ' + final_count)
return final_count

Which returns:

CONSOLE:
4 districts
21 houses
48 houses
0 houses
9 houses

RESULT:
78

 Depending on how many points and districts we're talking about, your popup expression could be evaluating dozens of separate intersections, but this should work.

- Josh Carlson
Kendall County GIS
JasonGlidewell
Occasional Contributor

Yes sir, that worked perfectly!  Thank you, I really appreciate the help!

Funny, I too tried the union.  My logic was to turn the featureset into a single polygon.  Seems this isn;t an option.

Clearly I need to do some researching on for loops in Arcade.  

Again, thank you very much!

0 Kudos
JerrySneary
Regular Contributor

Hi, @JasonGlidewell & @jcarlson 

I'm fairly new to writing code and can't seem to get this to work for me. I only have two hosted feature layers that I want to intersect. I can't write the Arcade Expression correctly for a Pop-Up but can't figure out how to get it to work in a Data Expression. Below is the Data Expression I wrote. I want to count how many NNO locations are in each of the Boundaries.

 

var boundaries = FeatureSetByPortalItem(Portal('https://arcgis.com/'),'a1795cc14f9744d68787f649a7865715', 0, ['*'], true);
var nno = FeatureSetByPortalItem(Portal('https://arcgis.com/'),'6d13be8f482e434ea129f751c00385b0', 0, ['*'], true);  
   
var intcount = Count(Intersects(boundaries,nno));

return intcount

 

This is the error that I got when I tested it.

JerrySneary_0-1660771481276.png

 I even tried using @jcarlson's code and swapping in my feature layers but that doesn't work either.

 

var dists = FeatureSetByPortalItem(Portal('https://arcgis.com/'),'a1795cc14f9744d68787f649a7865715', 0,['*'],true);

// Houses layer
var houses = FeatureSetByPortalItem(Portal('https://arcgis.com/'),'6d13be8f482e434ea129f751c00385b0',0,['*'],true);

// Instantiate final count at 0
var final_count = 0

// Iterate over dists FeatureSet and get intersected houses for each
for(var d in dists){
    var h_count = Count(Intersects(houses, d))
    Console(h_count + ' houses')
    
    final_count += h_count
}

Console('Total: ' + final_count)
return final_count

 

 This is the error I got when I tested it: Execution Error:Error

Can you guys help point me in the right direction.

Kind regards,

Jerry

JerrySneary
Regular Contributor

To anyone who is viewing this post. I was able to get the intersects to work with a count and sum but the problem I have now is that it is very slow to load.

var boundaries = FeatureSetByPortalItem(
    Portal('https://arcgis.com/'),
    'a1795cc14f9744d68787f649a7865715',
    1);
    
var nno = FeatureSetByPortalItem(
    Portal('https://arcgis.com/'),
    '6d13be8f482e434ea129f751c00385b0',
    0);
    
var outputDict = {'fields': [
    { 'name': 'MEMBER', 'type': 'esriFieldTypeString'},
    { 'name': 'Type', 'type': 'esriFieldTypeString'},
    { 'name': 'DISTRICT', 'type': 'esriFieldTypeString'},
    { 'name': 'District_Sort', 'type': 'esriFieldTypeString'},
    { 'name': 'NNO_Count', 'type': 'esriFieldTypeInteger'},
    { 'name': 'NNO_Attendance', 'type': 'esriFieldTypeInteger'}], 
    'geometryType': '', 'features': []};

var index = 0;

for (var boundary in boundaries) {
   var nnoint = Intersects(boundary,nno)
   var nnocount = Count(nnoint)
   var nnosum = Sum(nnoint, 'Expected_Attendance')
   outputDict.features[index++] = { 
            'attributes': {'MEMBER': boundary['MEMBER'],
            'Type': boundary['Type'],
            'DISTRICT': boundary['DISTRICT'],
            'District_Sort': boundary['District_Sort'],
            'NNO_Count': nnocount,
            'NNO_Attendance': nnosum}
            
}}

return FeatureSet(Text(outputDict));
0 Kudos