A major benefit of a Geographic Information System (GIS) is the ability to bring different data layers together spatially. A common 2-step GIS workflow is first creating buffers or drive-time polygons from a points layer of something like schools or hospitals. Then second, performing a spatial join using that new polygon layer with additional attributes of the community or natural environment within those polygons. Traditionally, this type of geoprocessing had to be pre-calculated before you could present your results. Furthermore, when a there was newer version of one of your input layers, you had to redo your geoprocessing and start all over again.
Today, we live in the world of live feeds and web layers that are constantly updated with new features and refreshed attribute values. The geometry functions in Arcade allow us to work with these web layers and perform such calculations on the fly when someone interacts with an app. Arcade FeatureSet functions allow us to reference other layers within your map in pop-ups. Simple geometry functions such as Intersects(), Buffer(), and Contains() allow us to perform spatial joins and geoprocessing with those layers on the fly, in real time. Combining the two allows us to present informative pop-ups in maps and in side panels within configurable apps.
Use Intersects() to combine existing point and polygon layers
For example, I have two layers for a project I did about the pipeline of transfer students from community colleges to universities. I have points of California community colleges, and polygons of 45-minute drive-times of California’s public universities, both as existing layers. I created my pop-ups to display what universities are close by for transfer students from each community college. This pop-up is then used in my final app’s side panel to display the number and the list of likely transfer destinations from each community college.
If the community college is within more than one university’s 45-minute drive-time area, which is the case for Cerritos College, we see a count and list of likely universities for transfer students:
If the community college is in a commutable area for only one university, which is the case for Victor Valley College, we see a slightly different sentence: “The most likely university for transfer students is the 1 university in a commutable distance:” and then the name of that university (in this case, Cal State San Bernardino).
If the community college is not in any drive-time polygons from the universities, we see different text entirely: “No public universities are in a commutable distance. Transfer students from this community college are likely to be residential students.” College of the Desert is a community college in this situation:
How was this done?
Both the count and the list of universities use the Intersects() function. The syntax for this function is very simple: Intersects(geometry that is tested for the intersects relationship, the geometry being intersected). This yields a Boolean (true/false) value, and returns a FeatureSet of features that do indeed intersect the second geometry. What makes this powerful is the ability to combine this with other Arcade functions to create informative pop-ups that provide your desired context.
How to display the count
Step 1. From the community college points layer, navigate to Configure Pop-up and add an expression. These points will be the geometry that is tested for the intersects relationship.
Step 2. Use FeatureSetbyID() to create a FeatureSet of the university drive-time polygons (polygon layer within this same map). These polygons will be the geometry being intersected.
Step 3. Return the new FeatureSet that you just created. (Tip: you can even click “Test” to see an example list of records.)
Step 4. Simply use the Count() function in conjunction with the Intersects() function to get the count of universities near each community college.
You can then use the when() logical function or other if/else logic to create an expression to display the three conditional sentences listed above. The type of logic is simply: If criterion A is met (in this case, if there are two or more public universities nearby), return sentence A. Else if criterion B is met (in this case, if there’s 1 and only 1 public university nearby), return sentence B. Else, (in this case, if there are zero), return sentence C.
How to display the list
Repeat steps 1 and 2 above. This gives you a FeatureSet of the multiple university drive time polygons that the community college intersects. In order to list these out, use a for loop. For each feature in our newly-created FeatureSet, list the field called Campus. I used an asterisk and a space to separate each campus. Here’s what this looks like in Arcade:
This community college app uses Intersects() to display both a count and a list in the pop-up to convey spatial context. Similarly, an app of farmers markets in Washington, DC uses other geometry functions to display additional information in the side panel.
Use Buffer() and Contains() to combine two point layers
Unlike the community colleges app, this app is powered by two point layers: farmer’s markets and retail locations that accept SNAP (Supplemental Nutritional Assistance Program). The first part of the side panel displays the count of retail stores that accept SNAP within a one-mile buffer of the farmer’s market:
How to display the count
Step 1. From the farmer’s markets points layer, navigate to Configure Pop-up and add an expression. These points will be the geometry used to form the 1-mile buffers.
Step 2. Use FeatureSetbyID() to create a FeatureSet of the retail locations that accept SNAP (points layer within this same map).
Step 3. Use Buffer() to create a 1-mile radius on the fly. Use the Buffer() function by specifying three parameters: the geometry to buffer, the distance to buffer from that geometry, and the unit of the distance as text. To do a one-mile ring, it’s simply Buffer($feature, 1, ‘miles’). There’s also a BufferGeodetic() if you need to account for the earth’s curvature.
Step 4. Use Contains(). The Contains() function is very similar to the Intersects() function described above. It returns a Boolean value for each feature, and a FeatureSet of those features that are in fact contained within a specified geometry.
Step 5. Once again combine with Count() and return the number of retail stores that accept SNAP within a 1-mile buffer of the farmer’s markets.
How to display the list
Repeat steps 1 through 4 above, and use a for loop similar to what we did in the community colleges example. Here the field we want is called Store_Name. This time, I forced a new line after every store name to separate each store.
When my map’s pop-up displays in the side panel of the app, it displays a list of the retail stores within 1 mile of the farmer’s market that the user selected:
These two apps use only a small fraction of all the geometry functions available when creating Arcade expressions.
Other geometry functions that allow you to combine layers spatially
Distance() and DistanceGeodetic()
These distance functions calculate the shortest distance between two points. Use these when you’re interested in “as-the-crow-flies” distances, rather than drive-time or walk-time distances over a street network.
Similar to Contains(), the Within() function indicates whether or not one geometry is within another. To decide which of these two functions to use, It’s helpful to think about which of your two layers is the inside geometry and the outside geometry. For example, points cannot contain polygons, but points can be within polygons. Polygons can only be within other polygons, not points.
So many more!
Union, Intersection, Clip, Overlaps, and more of your favorite spatial relationships are all available as Arcade geometry functions.
Combining layers together using Arcade makes working with ever-changing web-based layers easier. If a new community college or new farmer’s market is added to these layers, I don’t need to start over again. Arcade enables you to display the the spatial relationships across multiple data layers in pop-ups. This pop-up information travels through the ArcGIS Online system in configurable apps and dashboards, helping you to create polished web mapping applications. GIS analysts are well-positioned to take advantage of the location-based nature of so much of the data out there in the world. Arcade geometry functions are a great way to make those spatial relationships apparent.
Your Arcade Questions Answered is a blog post that has lots of great information for those looking to get started. Some of my favorite sections are:
- What is a FeatureSet?
- Can I do spatial calculations in Arcade?
- What is the difference between the Intersects() and Intersections() functions?
- Can I list the closest locations to a point on my map?
Pop-up taking a while to load?
- Consider optimizing performance by a more efficient use of Arcade. For example, reduce and subset features early on to avoid iterating through all features within a layer. The summary section of this blog gives a good overview of this. In general, take time to understand what’s slowing you down and what can be done to improve performance.
- In some cases, a join followed by a calculated field is more appropriate than using expressions, which is a faster query.