Since it was introduced in December 2018, Arcade FeatureSets have made it possible to include data from several layers and tables in one ArcGIS Online pop up. However, like some of our distant relatives, it’s difficult to see the connection between the layers and tables. Today we’ll look at how we can use Arcade FeatureSets to connect a separate layer and table through common attributes, and bring all relatives to our Arcade family pop up.
For this example we'll use Groundwater level measurements published by the CALIFORNIA natural resources AGENCY.
Groundwater well station locations (Feature Layer)
Groundwater levels - monthly mean (Related Data - Table)
Access 'Groundwater levels - monthly mean' table as a FeatureSet
Before we get started, I suggest you take a look at the following web map to familiarise yourself with the end result we're working towards.
If you want to follow along, save a copy of the web map to your account (you'll have the option to open and save the web map in Map Viewer Beta or Map Viewer Classic). Afterwards, add an Arcade attribute expression to the Groundwater well station locations
layer and use the following code snippet to bring in all features from the Groundwater levels - monthly mean (Related Data - Table).
Note:
if you'd prefer to copy and paste the code, the entire code snippet can be found at the end of this blog post.
Refer to this blog if you'd like to learn more about FeatureSetByPortalItem() and how to bring in features from another layer or table by using its itemId
and layerId
.
Filter related features by using a common attribute
Whether you like it or not, we all share common attributes with our relatives. This is also the case with related data. In our example the common attribute is the Station Id
, where the field names are called STATION
for both the feature layer and related table. Use the following code snippet to filter relatedData.
Refer to this blog if you'd like to learn more about the Filter() function and how to filter related records by using a common attribute.
Pro tip - Make sure to take advantage of the Test button to check related features for different Station Ids
.
Note:
if you're working with related tables in Survey123 the 2 common field names are likely to be globalid
for the feature layer, and parentglobalid
for the related table. Attached below is an example filterStatement.
var globalid = $feature.globalid
var filterStatement = 'parentglobalid = @globalid'
Sort related features by oldest to newest
Just like organising table arrangements for a family event, it is important that related data in popups are sorted in some order. Use the OrderBy() function to achieve this in Arcade FeatureSets.
Build the pop-up string by iterating through all related features
Use the following For loop to iterate through all features in the FeatureSet and build the popup string. Again, take advantage of the Test button to check popupString results for different Station Ids
.
Refer to this blog if you'd like to learn more about working with data inside FeatureSets.
Dealing with empty attributes
Finally, use the DefaultValue() function to replace any empty attributes with a default value or text.
Putting it all together
Here is the entire code to get your party started.
// Acess 'Groundwater Levels Monthly Mean' table as a FeatureSet
var portal = Portal("https://www.arcgis.com")
var waterLevels = FeatureSetByPortalItem(portal,
"426460a6ae7c47b5acb9a64294bd3dcb", 0, ['STATION', 'MSMT_DATE',
'RPE_WSE', 'GSE_WSE', 'WSE'])
// Filter related features by using a common attribute
var STATION = $feature.STATION
var filterStatement = 'STATION = @STATION'
// Related features as a variable
var relatedData = Filter(waterLevels, filterStatement)
// Sort related features by oldest to newest
var relatedDataSorted = OrderBy(relatedData, 'MSMT_DATE ASC')
// Build the pop-up string by iterating through all related features
var popupString = ''
for (var f in relatedDataSorted){
popupString += Text(f.MSMT_DATE, 'MMMM Y') + TextFormatting.NewLine +
"Depth to water surface (ft): " +
DefaultValue(f.RPE_WSE, 'no data') + TextFormatting.NewLine +
"Depth below ground surface (ft): " +
DefaultValue(f.GSE_WSE, 'no data') + TextFormatting.NewLine +
"Water Surface Elevation (ft): " +
DefaultValue(f.WSE, 'no data') + TextFormatting.NewLine +
TextFormatting.NewLine
}
DefaultValue(popupString, 'No measurements to show')
Who will you invite to your Arcade family pop up party?
Challenges
Please use the comments section below to post answers to the following questions.
How would you structure your expression to only show information from the last reading?
How would you convert the measurements from feet to metres?
Bonus round: How would you structure your code to show Quality Codes along with your Groundwater level readings?
Cheers! - Gee Fernando