Using Arcade to Find the Nearest Address Point

8856
17
Jump to solution
10-10-2019 02:44 PM
PeterDalrymple
Occasional Contributor

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

17 Replies
NaomiBegg2
Occasional Contributor III

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? 

0 Kudos
XanderBakker
Esri Esteemed Contributor

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..."
}


0 Kudos
NaomiBegg1
New Contributor II

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.

0 Kudos
XanderBakker
Esri Esteemed Contributor

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.

0 Kudos
ScottStepro1
New Contributor III

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;

 

0 Kudos
OliverSandoval_p
New Contributor III

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! console_results.pnginfinity_1.pnginfinity_2.pngnullval.pngI have attached some photos for reference 

0 Kudos
XanderBakker
Esri Esteemed Contributor

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: 

XanderBakker_0-1654278056439.png

 

0 Kudos
OliverSandoval_p
New Contributor III

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

 

0 Kudos