Hello!
I have a web map with a point layer representing manholes and a point layer representing addresses. I am attempting to create an Arcade expression that will display the nearest address point in the popup of a selected manhole. I'm trying to do this by creating a buffer around the selected manhole, calculating the distance of each address point intersecting the buffer, and returning the address of the nearest address point. No matter how I format the code below (I won't get into everything that I've tried), I do get one address point, but it is neither the nearest or the farthest manhole. I have tried sorting, ordering, and using compare functions for the intersecting address points, but I don't seem to have access to the distance value in order to grab the closest one. Can anyone tell me if I'm going about this the right way or if this is even possible? Thanks in advance!!!
var searchDist = 200; var addresses = Intersects(FeatureSetById($map, "Primary_Address_3482"), Buffer( $feature, searchDist, "feet")); var cnt = Count(addresses) Console("Total Number of addresses within buffer: " + cnt); var nearestaddress; for (var f in addresses){ var addressDist = Round(Distance(f, $feature, "feet"),2); Console(f.FULL_ADDR + ": " + " " + addressDist) } f.FULL_ADDR
Solved! Go to Solution.
var searchDist = 150;
var IntersectClose = Intersects(Buffer($feature, 150, 'kilometers'), FeatureSetByName($map,"Girls Brigade groups - Stats"));
var cnt = Count(IntersectClose)
Console("Total Number of addresses within buffer: " + cnt);
var nearestGroup;
var min_dist = 200;
for (var f in IntersectClose){
var groupDist = Round(Distance(f, $feature, "kilometers"),2)
if (groupDist < min_dist) {
nearestGroup = f.USER_Group_Name;
min_dist = groupDist;
}
Console(f.USER_Group_Name + ": " + " " + groupDist)
}return "Closest group is " + nearestGroup + ", " + groupDist + "km away."
I'm thinking that I need to out a second if statement similar to below.
if (groupDist < min_dist) && a.USER_Group_Name =! f.USER_Group_Name {
However how do I distinguished between the first group name and the second that appears within the for loop? Do I need to declare it as another var at the start?
Hi Naomi Begg ,
I think you could do something like this (see below). In this case you read out the object ID and only allow a result in case it is a different object ID. You could also filter the feature set by excluding this object id.
var currentOID = $feature.OBJECTID; // assumig you have an object ID field
var searchDist = 150;
var IntersectClose = Intersects(Buffer($feature, 150, 'kilometers'), FeatureSetByName($map,"Girls Brigade groups - Stats"));
var cnt = Count(IntersectClose)
Console("Total Number of addresses within buffer: " + cnt);
if (cnt > 0) {
var nearestGroup;
var min_dist = searchDist + 1;
for (var f in IntersectClose) {
if (f.OBJECTID != currentOID) {
var groupDist = Round(Distance(f, $feature, "kilometers"),2)
if (groupDist < min_dist) {
nearestGroup = f.USER_Group_Name;
min_dist = groupDist;
}
Console(f.USER_Group_Name + ": " + " " + groupDist)
}
}
return "Closest group is " + nearestGroup + ", " + groupDist + "km away."
} else {
// no features found in buffer
return "No closest group found..."
}
Thanks, Xander Bakker, I've got the query pulling out the correct group now. However, the distance it is returning is not reliable. I am getting two different results for groups that are right next to each other whereas they should return the same distance, and I am getting distances in the 100s when really they are 1km away.
Hi Naomi Begg , there is a note about the accuracy of the geometries and subsequent analysis on them, related to the scale in which you retrieve the geometry. However, this does not explain the differences that you are seeing. You could try using "DistanceGeodetic", but I doubt that it will solve this issue.
found this code today Xander... very few changes needed to make it work for me too. **bleep** yes and thank you...
Here is mine, you can easily see how few changes were needed.
var searchDist = 200;
var addresses = Intersects(FeatureSetById($map, /* Jefferson County KY Address Points */ "OpenDataAddresses_7579"), Buffer($feature, searchDist, "feet"));
var cnt = Count(addresses)
Console("Total addresses within Buffer" + cnt);
var nearestaddress;
var min_dist = 250;
for (var f in addresses){
var addressDist = Round(Distance(f, $feature, "feet"),2);
if (addressDist < min_dist) {
nearestaddress = f.FULL_ADDRESS;
min_dist = addressDist;
}
Console(f.FULL_ADDRESS + ": " + " " + addressDist);
}
return nearestaddress;
Hi @XanderBakker ,
Thank you for your help. I have tried using your code and ran into several weird issues. When I set min_dist to a value the result I get is null. This has lead me to set it to infinity as shown in this esri resource Find nearest features using Arcade expressions in a popup | ArcGIS API for JavaScript 3.40 | ArcGIS ... .
When I set to infinity I get a result but it is often not the nearest address distance wise. And it changes if I use a higher search distance which doesn't make sense. I also get large numbers for the address distances.
The $feature is being hosted in arcgisonline while the address points layer is a registered feature layer.
Do you have an idea as to what may be going wrong with my version? Thank you for your help again! I have attached some photos for reference
Hi @OliverSandoval_p ,
Sorry for the delay, but when I look at the distances that you get I wonder how big your feature is... Distances of 65M feet are about halfway around the globe.
If I use Infinity or the searchDist as the initial minimum distance it will return the same result:
hi @XanderBakker ,
The issue ended up being the web map's web Mercator projection while the hosted feature layers were in NAD 1983. I had to reprojection the data needed because end users needed to have more than one basemap and I didn't have time to create a custom basemap.
Thank you for your reply!
Best,
Oliver