Arcade Data Expression - Intersects for Dashboard List

1155
3
03-08-2023 06:24 AM
Labels (1)
RyanElvrum5
New Contributor II

@XanderBakker 

I am attempting to create a Data Expression to be used in a Dashboard List widget. My arcade expression is attempting to perform an intersect for each point feature in my FeatureSet to check if it intersects with a line in a different FeatureSet.

My understanding is that the Intersect needs to be performed on 1 input feature at a time, so I feel like some type of loop needs to occur. I then want to return all the point features that intersect a line as a FeatureSet to be used in the List widget. I believe this should be possible, but I think I am stuck at creating a For-in loop to perform an intersect for each point feature and store the results to be returned as a FeatureSet. Below is what my code looks like so far. Everything down to line 24 works, so I do not believe I have any issues up until that point. Everything after line 24 is where I am getting lost.

//Portal
var port = "Https://www.arcgis.com"
//ArcGIS Online item ID
var itemID = "4c82c3b6b8d64c6ca0ecd20d813531f2"
//Rest layer ID - Storm Gravity Mains
var GMlayerID = 60
//Rest layer ID - Storm Manholes
var MHlayerID = 57
//Fields returned - All (Default)
var fields = ['*']
//Geometry returned
var geo = True
//Set up Gravity Main feature set
var fsGM = FeatureSetByPortalItem(Portal(port), itemId, GMlayerID, fields,geo)
//Set up Manhole feature set
var fsMH = FeatureSetByPortalItem(Portal(port), itemId, MHlayerID, fields,geo)
//Filter statement used to filter feature set down to Gravity Mains with an upsteam invert value that is less than downstream invert value
var FilterStatementGM = "UpstreamInvert < DownstreamInvert AND TrunkMain = 'Y'"
//Returns filtered Gravity Mains
var filteredfsGM = Filter(fsGM, FilterStatementGM)
//Filter statement used to filter feature set down to Gravity Mains with an upsteam invert value that is less than downstream invert value
var FilterStatementMH = "TrunkMain = 'Y' AND NeedsGPS = 1 AND MajorDBDistrict = 'J'"
//Returns filtered Manholes
var filteredfsMH = Filter(fsMH, FilterStatementMH)
var MHlist = ''
for (var f in filteredfsMH){
  Intersects(f, filteredfsGM)
    MHlist += f.FacilityID
}
return MHlist

 

0 Kudos
3 Replies
jcarlson
MVP Esteemed Contributor

There is an example expression that performs a "spatial join" between two layers, which you can access right here: https://github.com/Esri/arcade-expressions/blob/master/dashboard_data/SpatialAggregation.md

 

- Josh Carlson
Kendall County GIS
0 Kudos
RyanElvrum5
New Contributor II

Thanks Josh, I am slowly trying to digest the information in your link! Do you know if the Contains function is applicable to points intersecting lines? I am struggling to find any alternatives for a "spatial join" type function.

0 Kudos
RyanElvrum5
New Contributor II

Josh, thanks again for providing the link. I pretty much have it working now. I am able to return a list of features, and I was able to use the Intersects() function to do so. 

The only thing I want to look into more deeply is, if instead of "creating" a new feature (list?/array?/object?) for the output, I'd rather return a FeatureSet of the actual features so that I may use the List widget Action: Zoom to Feature. I want the users to be able to select an item in the list and zoom directly to it. I will come back and update this thread if I can figure that out.

 

//Portal
var port = "Https://www.arcgis.com"
//ArcGIS Online item ID
var itemID = "4c82c3b6b8d64c6ca0ecd20d813531f2"
//Rest layer ID - Storm Gravity Mains
var GMlayerID = 60
//Rest layer ID - Storm Manholes
var MHlayerID = 57
//Fields returned - All (Default)
var fields = ['*']
//Geometry returned
var geo = True
//Set up Gravity Main feature set
var fsGM = FeatureSetByPortalItem(Portal(port), itemId, GMlayerID, fields,geo)
//Set up Manhole feature set
var fsMH = FeatureSetByPortalItem(Portal(port), itemId, MHlayerID, fields,geo)
//Filter statement used to filter feature set down to Gravity Mains with an upsteam invert value that is less than downstream invert value
var FilterStatementGM = "UpstreamInvert < DownstreamInvert AND TrunkMain = 'Y'"
//Returns filtered Gravity Mains
var filteredfsGM = Filter(fsGM, FilterStatementGM)
//Filter statement used to filter feature set down to Gravity Mains with an upsteam invert value that is less than downstream invert value
var FilterStatementMH = "TrunkMain = 'Y' AND NeedsGPS = 1 AND MajorDBDistrict = 'J'"
//Returns filtered Manholes
var filteredfsMH = Filter(fsMH, FilterStatementMH)
var MHlist = [];
var MH;
for (var f in filteredfsMH){
  var m = Intersects(f, filteredfsGM);

  MH = {
    'attributes':{
      'facilityID': f['FacilityID'],
      'cnt': Count(m)
    }
  }
  Push(MHlist, MH);
};

var out_dict = {
  'fields':[
    {'name': 'facilityID', 'alias': 'FacilityID', 'type': 'esriFieldTypeString'},
    {'name': 'cnt', 'alias': 'Count', 'type': 'esriFieldTypeInteger'}
  ],
  'geometryType': '',
  'features': MHlist
};
return FeatureSet(Text(out_dict))
0 Kudos