Overlapping Features in Pop-Ups Quick Introduction to Using FeatureSets with Arcade

61981
163
12-10-2018 11:08 AM
KellyGerrow
Esri Frequent Contributor
35 163 62K

With the December update of ArcGIS Online, the ability to reference other layers using Arcade Expressions in Pop-Ups was introduced. This blog is going to outline a quick example about how to create a simple intersect expression and display the results in a Pop-Up.

In this example I have used 4 layers marked as authoritative in ArcGIS Online by  Miami-Dade County, Florida. I want to display the Elementary, Middle and High School names which intersect with building footprints in a single pop-up. I have three layers of School Attendance Boundaries which identifies a specific school boundary which overlaps with many building footprints. The building footprint layer contains geometry information but no information about the infrastructure or zones that intersect with the building.

This Web Map shows examples of the information available in these layers in 4 separate layers.

Unedited Pop-ups

Using the new Arcade FeatureSet functionality, I was able to include the Elementary, Middle and High School names in the building footprint pop up in this web map

feature set

Here are the steps to set up this simple intersecting Arcade Expressions to include in a pop-up.

  1. Add all the desired layers with information that you would like to see to a web map.

  2. Select the layer that should display the pop-up information (Building Footprint)

  3. Inspect the School Attendance Boundary layers to identify the fields that you would like to display in the Building Footprint layer Name)

  4. Select Configure Pop up and navigate to the Add Attribute Expressions

  5. Create the expression for each layer.

    1. Create a variable that returns the FeatureSet of intersecting feature attributes.

      var intersectLayer =Intersects(FeatureSetByName($map,"Elementary School Attendance Boundary"), $feature)

      Expression Values Explained:

      var intersectLayer – specifies the intersecting features variable name

      Intersects – specifies the geometry function one feature intersects the geometry of the other specified layer.

      FeatureSetByName  Creates a FeatureSet from a Feature Layer based on its name within a map or feature service

      $map,"Elementary School Attendance Boundary"– identifies that the feature set is a layer named Elementary School Attendance Boundary, within the web map.

      $featureis the feature that is being selected in the Building Footprint layer that provides the initial spatial information.

         b.   Loop through the feature set created and return a specific field from the feature set:

           

for (var f in intersectLayer){

    return f.NAME

}

6. Once all expressions are created, add them to the pop up configuration.

7. Disable the pop ups and potentially the visibility from the School Attendance Boundary Layers (Not required, but I think it cleans up the display,

8.Check out your pop up with information from intersecting layers.

There will be more documentation, blogs and examples coming out in the next week, but try out this quick sample with simple intersecting layers and let us know if you have questions.

Entire expression for a single high school name:

var intersectLayer =Intersects(FeatureSetByName($map,"Elementary School Attendance Boundary"), $feature)

for (var f in intersectLayer){
return f.NAME
}

163 Comments
TimothyKing3
Occasional Contributor

Xander,

I want to get general information from layers in my webmap i.e. Parcel ID, Section, Township, Range, Soil Type, Topo Quad name, etc by using the FeatureSets and then pass those variables to 123 via the Custom URL.  I haven't tried with the url yet as when I saw that they weren't visible in new Collector I didn't think they would get passed over.

XanderBakker
Esri Esteemed Contributor

So, in the web map you can create for instance create an expression in the pop-up of the parcel that includes all that information. If these are in multiple layers, you will have to use multiple requests to the server (making the expression more "expensive"), but the result could be a URL that links to a Survey and pre-fills all that data. It is possible to do this from the web map. I just don't know if this pop-up will work in Collector. It will work in the web map or an Web App configured based on this web map. 

TimothyKing3
Occasional Contributor

I am trying this with a point feature service and would like to pass the ParcelID that the point intersects to 123.  I have added the following code to my Attribute Expression

//Get the Parcel ID that the point intersects
var ParcelID = FeatureSetById($map, /* Parcels */ "DoubleE_Parcels_20190107_3156")
var IntersectsParcelID = Intersects(ParcelID,$feature)
return IntersectsParcelID

This returns the entire record and I want to only select one value from a field.  Is that possible?


Thanks,

XanderBakker
Esri Esteemed Contributor

It is possible, but in your case you are returning just an entire record, you are in fact returning a list of records (which possibly contains just a single record. Have a look at the code below:

//Get the Parcel ID that the point intersects
var parcels = FeatureSetById($map, "DoubleE_Parcels_20190107_3156");
var parcel = First(Intersects(parcels, $feature));
return parcel.ParcelID;‍‍‍‍

I create a variable parcels that is a reference to the parcels layer in the map. With intersect on line 3 you can see that I only want to obtain the relevant parcel(s) that intersect with the feature. I also include the function First that will return the first row in the list of intersected features. The result is stored in variable "parcel" that contains the row for the first parcel that intersected. To retrieve the ParcelID you will have to access the ParcelID property of the parcel. In my case I assume that the field is called "ParcelID". In case it is different, please change the name accordingly.

TimothyKing3
Occasional Contributor

Thanks again for your help Xander! 

I was also wondering what would go into the URL schema the Field Alias name of the Attribute expression or the Expression/expr0 value.  

XanderBakker
Esri Esteemed Contributor

If you go to this link:

https://community.esri.com/docs/DOC-12348-usar-expresiones-arcade-para-cumplir-con-la-resoluci%C3%B3... 

You will get to a certain section in a (Spanish, sorry) document where I have some code that creates a URL that links to a Survey123 survey and pre-populates part of the survey.

In short you will have to use something like this:

url = url + "field:nuevo_cliente=" + nuevo;

In this case I already have the first part of the URL and I'm adding URL parameters to pre-populate the fields. 

In this example my field is called "nuevo_cliente" and the value I want to assign is the content of the variable "nuevo".

MichaelVolz
Esteemed Contributor

The ability to extract information from intersecting layers in the web map to display in a pop-up is a great tool.  I was wondering if there is a best practice limit to how many layers you can hook up into the pop-up using intersect before it takes a toll on the responsiveness of the pop-up.  So if I am extracting data from more than 6 layers in the web map would I experience sluggishness in the presentation of the pop-up?

KyleWikstrom
Occasional Contributor II

Mike,

I've configured a statewide representative web map that contains 5 layers and 1 table, where a single layer's configured popup is returning attributes from intersecting features in the other 4 layers plus attributes from a related table for each of those 4 layers. The data is in ArcGIS Online Hosted Layers, and the return time is approximately 7 seconds.

I haven't come into any best practices, but perhaps this will offer an idea of responsiveness with a moderate sized set of data.

MichaelVolz
Esteemed Contributor

Kyle:

Thanks for the response.

Have you created a web application from that web map that makes use of the popup that you have created?  If so, do you still have a 7 second response time or has that time increased now since you have the web app on top of the web map?

Further, even if you don't have an increase in time, is 7 seconds to get a popup too long for most of your endusers as that does seem like a pretty long time for a popup to populate.  I would think a reasonable popup should return results in no more than 3 or 4 seconds.

KyleWikstrom
Occasional Contributor II

Yes, the response has been similar with the internet connection available.

Regarding end user expectations, the data is setup to model real-world for data management, where spatial and attribute relationships are important. Automated processes to join tables for view-only purposes would, I expect, improve response time.

Your consideration is valid.

TimothyKing3
Occasional Contributor

Thanks so much Xander!  I was able to get this to work but in the custom url I had to put in the Expression value i.e. {expression/expr1} instead of the Alias. I was hoping that the Name in the Add Attribute expressions would work.  That would be a really nice addition as I feel the {expression/expr1} will get confusing.  

TimothyKing3
Occasional Contributor

Xander,

Is there a way to calculate the LAT and LONG as an Attribute expression?  I don't think that when a point is manually dropped in Collector that that information is accessible.  For testing purposes I would like to be able to just drop a point and send its location to 123 with that information.  I know that those values are generated since they show up in the pop-ups within Collector but I don't know how to access them.

TimothyKing3
Occasional Contributor

I spoke too soon.  I was unable to get this to work in the new version of Collector.  I tried the expression and the name of the expression and neither one sent the info in the url.

XanderBakker
Esri Esteemed Contributor

In the link that I shared before I have an example of sending the coordinates to the Survey123 form: https://community.esri.com/docs/DOC-12348-usar-expresiones-arcade-para-cumplir-con-la-resoluci%C3%B3... 

The function that translates Web Mercator Auxiliary Sphere into WGS 1984 coordinates is this one:

function MetersToLatLon(x, y) {
    // Converts XY point from Spherical Mercator EPSG:900913 to lat/lon in WGS84 Datum
    // Fuente: http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/
    var originShift = 2.0 * PI * 6378137.0 / 2.0;

    var lon = (x / originShift) * 180.0;
    var lat = (y / originShift) * 180.0;

    lat = 180.0 / PI * (2.0 * Atan( Exp( lat * PI / 180.0)) - PI / 2.0);
    return [lat, lon];
}

You can access the coordinates like this:

var latlon = MetersToLatLon(Geometry($feature).X, Geometry($feature).Y);

To construct the URL you can use "center":

url = url + "&center=" + lat + "," + lon;

This will preset the location of the piont of the Survey123 and center at the provided location

TimothyKing3
Occasional Contributor

Can this be used to send data to Operations Dashboard?  I tried it and it does not seem to work at this time.  Would be a great addition.  

XanderBakker
Esri Esteemed Contributor

Arcade expressions configured in the pop-up window of a web map do not appear in Dashboard. You can however use the Arcade expressions to calculate a new field and that static data will be available in Dashboard.

Since you mention "send data to Dashboard" perhaps you are  interested in the URL parameters that are supported by Dashboard. This allows you to create a URL to the Dashboard and specify parameters that will set filters and other aspects of the Dashboard.

MonicaZhang
New Contributor II

Hi Xander, thank you for the code examples! They were really helpful to me in figuring out how to get the information for all the intersecting features to show. But now I'm wondering if it's possible to pick out one based on geometry.

I have a polygon layer, where one feature can overlap several congressional districts, so would it be possible to get congressional district information for just the one that intersects with the portion of the feature I clicked on? I tried using Intersects() with Intersection(), but I get "Execution Error:JSON.parse: unexpected character at line 1 column 2 of the JSON data," and I'm not sure if it's an issue with the data or I coded it wrong. This is what I tried to do:

var distIntersect = 
Intersects(
    Intersection(
            $feature,
            Geometry(FeatureSetById($map, 'USA_116th_Congressional_Districts_9662',[]))
            ), 
    FeatureSetbyID($map,'USA_116th_Congressional_Districts_9662', ['NAME','PARTY','STATE_ABBR','CDFIPS']));‍‍‍‍‍‍‍

The error seems to be coming from the Intersection() part. I'm using the Living Atlas 116th Congressional Districts layer.

Thanks!

XanderBakker
Esri Esteemed Contributor

Hi Monica Zhang ,

...would it be possible to get congressional district information for just the one that intersects with the portion of the feature I clicked on?

The essence of Arcade is that you start with a feature (the feature you clicked on) and not with the location of the click event. In the Arcade expression you will not have access to the part where the user clicked. You can evaluate the intersect areas and return the largest area of the intersect results, but this will not have anything to do with the location the user clicked. Since the identify function in the web map has a drill-down function, you will get the results of the underlying polygons where the user clicked. 

One of the errors in your expression is caused by trying to convert to a geometry the result of the FeatureSetById on line 5. The FeatureSetById will return a list of features (although the list might only contain a single feature it is still a list).

For testing I would recommend you not to nest the statements to be able to test (use the Console statement) each single line and function. After it works you can nest the statements again for better performance.

MonicaZhang
New Contributor II

Ok, I see, thank you for the quick reply Xander. That makes sense. I can live without identifying the individual intersection areas through Arcade.

I know the FeatureSetBy functions are grouped in the Data Functions in the Arcade documentation, but I saw that they had an includeGeometry argument, with the description saying, "Indicates whether to include the geometry in the features. By default, this is true. For performance reasons, you should only request the geometry if necessary, such as for use in geometry functions." Does that mean the list of features returned by FeatureSetById includes geometry of each feature, but I'd need to reference a specific feature to do something with its geometry?

XanderBakker
Esri Esteemed Contributor

Hi Monica Zhang ,

When you use the FeatureSetBy functions you will have access to the individual geometries. This also allows to use the Intersects function to filter the features to relevant ones. So by deafult you probably want use the default and nclude the geometries. In case you only want to calculate some statistics based on attributes, you can optimize the performance by only retrieving a list of features without the geometries. 

If you look at this article: https://community.esri.com/docs/DOC-12773-using-featuresetby-functions-in-arcade-to-drill-down-to-ot... you will see in the third code sample, that I'm using the FeatureSetBy function to obtain access to my hydrants and the second line will filter this list of hydrant by the polygon feature I clicked on. In this case you will need the geometries to be able to use the Intersects function.

NedCake1
Occasional Contributor

Hi Kyle,

It looks like the Near Me widget in the AGOL hosted WAB now supports output from Arcade expressions. Hopefully the next release of WAB Developer Edition will resolve the problem for self hosted WABs.

Ned

KyleWikstrom
Occasional Contributor II

Hey Ned!

Yes, I see this! This is great!

This was almost perfect, but now the recent update has begun not allowing my very cool table formatting to go through.  Something I'm working with other teams on. The updates to the Near Me widget have almost completely satisfied me now after this last update.

deleted-user-1_r2dgYuILKY
Occasional Contributor III

I have a district lookup widget for school attendance zones. These show up as menus that display custom popups based on conditional Arcade expressions from the district layer. Is it possible to have information from a related but separate layer show up below these district boundary menus on the widget? This would be utility information for the address. I could add the utility zones to the district layer, but I don't want redundant popup information on each tab, K-5, Middle and High School. Is this something I could accomplish with an Arcade expression?

 

For example:

 

KyleWikstrom
Occasional Contributor II

Levi, not in the location in the widget in which you have placed the additional text. If a location intersects multiple features at the location, the widget returns a listing of the layers touching, and then if you drill forward it will return a list of the features touching in that layer. This is if I'm understanding your scenario correctly.

deleted-user-1_r2dgYuILKY
Occasional Contributor III

Would I be able to customize the widget in JS to display text in that area?

TraceyLeet
New Contributor II

I want to create pop ups for parcels that drills down and shows fields from several other feature classes. such as Zoning, Flood Zones and so on. Is this possible with Arcade in ArcGIS Pro?

AndyWells
Occasional Contributor II

I'm attempting to follow the directions to do this, but the intersect results that the map is presenting are not what I am expecting. In my example, I am returning the zone name that a land parcel lies in (residential, commercial, etc). For the most part, zone borders will follow parcel lines, without crossing them. 

var intersectlayer = Intersects(FeatureSetByName($map,"Zoning"),$feature)
for (var f in intersectlayer){
   return f.ZoneName
}

The problem is, that where the parcel lies on the edge of the zone, the result returned is always the zone that is adjacent and never the zone that the parcel actually lies inside of. Here is an example of that happening, it returns Industrial for the selected parcel, when it should be Residential:

But if I click a parcel that is wholly inside of the Residential zone, it returns the correct zone name:

I realize that the parcels on the edge are intersecting two zones, even if one of the zones is a shared boundary. Is there a way to make Arcade return the most appropriate zone? I've tried fooling around with Within and Contains functions, but I haven't been able to get anything better with them. 

NedCake1
Occasional Contributor

Hi Andy

Would recommend a -10 foot buffer on the parcel boundary. that should be more than enough to account for any slivers.

For Example

var intersectZoning = Intersects(Buffer($feature, -10, 'feet'), FeatureSetByName($map, "Zoning"));
var zoning = "";
for (var f in intersectZoning) {
if (zoning == "") {
zoning = f.ZONING+ " - " + f.ZONED;
} else {
zoning += TextFormatting.NewLine + TextFormatting.NewLine + "AND" + TextFormatting.NewLine + TextFormatting.NewLine + f.ZONING + " - " + f.ZONED;
}
}
return zoning;

Hope that helps

Ned

Tallahassee/Leon County Land Information Map

AndyWells
Occasional Contributor II

YES! That worked perfectly. Thank you for that information!

NedCake1
Occasional Contributor

Glad to help! Incidentally, that script will also allow for parcels that have more than one zoning district. Thanks to folks like Xander and Kyle.... my Arcade Kung Fu is getting stronger.

NaomiBegg2
Occasional Contributor III

I've tried to use the intersect arcade expression to pick up info from one point that is on top of another (for example one point is a tree, the other point is an assessment done for that tree).  I am not getting an error, but then I'm also not getting any results!  It appears that the intersect doesn't work for Point-to-Point intersects??!?

https://community.esri.com/thread/232370-point-to-point-intersection-arcade

NedCake1
Occasional Contributor

Hi Naomi,

For this type of expression to work, the X/Y coordinates for both point features would have to be identical. If they are not identical, from a geometry perspective they don't really intersect (even if their map symbols appear to be stacked ). You'll need to determine your margin of error distance between the overlay point and the intersect points and use a buffer of that distance on the overlay feature to make the intersect work. There are some samples above using buffers.

Hope that helps

Ned

RezaTehranifar2
New Contributor III

I am trying to use these steps but for a multipart point. I tried to convert it to singlepart for MultiPartToSinglePart() before using the intersects() function in arcade, but I dont get the desired outcome. Is this possible or  am I missing a step?

Thanks
Reza

XanderBakker
Esri Esteemed Contributor

Hi Reza Tehranifar , 

Can you explain what you are trying to do and share the code you have so far? MultiPartToSinglePart() will return an array of points. Are you evaluating each point individually?

For instance:

var mp = Multipoint({ 'points' : [ [-97.06138,32.837], [-97.06133,32.836], [-97.06124,32.834], [-97.06127,32.832] ], 'spatialReference':{'wkid':102100} });
var allParts = MultiPartToSinglePart(mp);
for (var i in allParts) {
    var part = allParts[i];
    Console(i + ": " + TypeOf(part) + " -> " + part.x + ", " +  part.y);
}
return Count(allParts);

...will write to the Console:

0: Point -> -97.06138, 32.837
1: Point -> -97.06133, 32.836
2: Point -> -97.06124, 32.834
3: Point -> -97.06127, 32.832
RezaTehranifar2
New Contributor III

Thanks for reply Xander.

Similar to this article, my client would like to populate the popup with the intersecting boundary name. However, the dataset is multipoint. I would like to get the boundary name for that particular point I clicked on. 

To give an example, there is one feature (record) that has five locations. These five locations are in different districts.I would like it where when i click on one of the points, I get the district name where that point intersects.

Does this clarify my question?

XanderBakker
Esri Esteemed Contributor

Hi Reza Tehranifar , 

Yes that clarifies your question, but Arcade will never be able to know on what individual point of the multipoint the user clicked. You will have to publish the layer as single point to be able to do that.

RezaTehranifar2
New Contributor III

Thanks. I assumed it was wishful thinking. Two follow-up Q's:

1. Could I have it where somehow where the XY of where I click is recorded and I can use that to get the intersecting district? (I think someone asked something similar above, and it was no)

2. If I do publish this data as single point, is there a way I can use Arcade to visually show the relationship between points that would be evident if it was multipoint? For example, the client really likes how with multipoint structure you can see other points within that feature (record) highlighted when clicking on one point. Symbology is not an option as there are too many points (1500+) 

Thanks

Reza

XanderBakker
Esri Esteemed Contributor

What if you publish the single part layer and visualize it beneath the multipoint layer. The user will be abvle to see the selection (multipart points) and in the second pop-up you could configure the Arcade expression to show in which polygon that point is located. Arcade has no knowlegde of the XY location where the user clicked.

RezaTehranifar2
New Contributor III

That's a real clever idea. Will try that!

Thanks!

JamesCrandall
MVP Frequent Contributor

I'm not following here...  We already have created web layers from our entire library of map services published to our AGS site(s).  That is, we have a matching AGOL layer item for each map service we manage on our AGS sites and all of our web mapviewer products contain these AGOL layers or users search to add them into their own web mapviewer products.

Are you suggesting that we would have to add each individual map service layer and create a feature service out of it in order to reference it in an Arcade expression?

NedCake1
Occasional Contributor

Hi James,

Unfortunately, that is the case. In my AGOL org I register both map services (aka map image layers) and feature layers from our AGS sites. There are advantages and disadvantages to both. Map services are fast and look great with anti-aliasing and labeling etc but they lack the web side functionality you can take advantage of with a feature layer.  With feature layers you have access to queries, filters, symbology changes, and geometry functions like the arcade functions introduced in this blog. 

On the bright side, if you are using WAB, you can use the Layer List widget to actually hide the layers that are being referenced by your overlay/intersect calls in arcade. Heck they don't even have to be turned on/displayed in the map for arcade to use them.

Sorry for the disappointing news.

Ned

JamesCrandall
MVP Frequent Contributor

Got it.  Thanks for the feedback!

We've thrown around the idea of maintaining a replica set of feature services from the enterprise map services but it's a lot.  I think the biggest concern was unknowns of any performance issues on the enterprise in total should those FS's become popular and/or used in too many products across the user base.  Perhaps I could see creating sets of themed FS's for specific application use (say like EOC operations), but would of been nice to just use what's already published!

Thanks again.

ANILBaral
New Contributor

I have different layers in my map along with a point layer. When i click on point i was able to display attributes from other layers in pop up following the steps in the blog. I also want the address( not latitude and longitude) to be automatically displayed for those points in my pop up along with other attributes. Is it possible with arcade expression? I have option to add and edit those points in my application. So when the user add a point i want the address to be automatically displayed in popup!

XanderBakker
Esri Esteemed Contributor

Hi anilbaral , 

As far as I know Arcade will not do any reverse geocoding. You will need to enrich the layer in a different way. 

ANILBaral
New Contributor

Thanks is there any other way i can do it ?? I want some features like getting the attribute of overlapping features too in my pop up for which arcade was helpful. Can both arcade and java script do it?

James_Armstrong
Occasional Contributor

Hi Kelly,   I am trying to do this process in Portal with out much success.  I recently updated Portal Server and Data Store to 10.7.  When in Arcade interface, I am able to access the FeatureSetByName function.  I set everything up as you have indicated in this post, but keep getting an error on the $map component. 

The error is :Runtime Error: Identifier Not Found. $map

Would you have any suggestions?

James

XanderBakker
Esri Esteemed Contributor

Are you writing the expression manually or are you using the options to the right in the Arcade expression editor?

James_Armstrong
Occasional Contributor

Thanks for the reply, but I think I am beginning to understand the issue. IN a few other threads, I learned that using Map layer as published to my portal will not work. The lyers need to be hosted feature services. I tested it out on a layer from the living atlas (hosted) and could access the $map element. Now I just need to step back to get the larger pictures.

Thanks Again

MichaelMiller2
Occasional Contributor III

Is there a way to access and attribute using Arcade of a polyline  that is coincident to another polyline.  It seems the 'intersects' function selects using a polygon boundary.  I'm looking for something that is going to select the polyline directly under the clicked on point of the selected polyline.

XanderBakker
Esri Esteemed Contributor

You have no access to the point a user clicked in Arcade. Arcade will work with the geometry a user clicked on. In this case it will be a polyline. If that polyline intersects multiple other geometries, it will not be able to identify which one the user clicked on from the first geometry. 

About the Author
I love interactive maps and apps on the internet! The maps and apps that customers create and share on the web, make my job awesome. I'm a Product Manager with the ArcGIS Online team in Redlands, California. I am a proud graduate from Carleton University and the COGS in Canada, with research focus' in Health Geography. Originally from Bedford, NS, Canada but have spent a lot of time in Haliburton and Ottawa, Ontario. I have a passion for the outdoors and dogs.