Calculate Distance Between Points - Arcade

939
7
Jump to solution
07-16-2020 05:43 AM
JoshHarris
Occasional Contributor

I was wondering if it was possible to calculate the distance from one point feature to the nearest point (a separate feature service),  and having this distance as a popup, using Arcade?

TIA

Tags (1)
0 Kudos
1 Solution

Accepted Solutions
XanderBakker
Esri Esteemed Contributor

Hi Josh Harris ,

Here is an example expression that you can use:

var fs = FeatureSetByName($map,"The Name of the other point feature service");
var buf = Buffer($feature, 500, "meter");
var fs_filtered = Intersects(fs, buf);
var cnt = Count(fs_filtered);

var min_dist = 999;
if (cnt > 0) {
    for (var f in fs_filtered) {
        var dist = Distance($feature, f);
        if (dist < min_dist) {
            min_dist = dist;
            // if you want to know which feature is nearest, 
            // you should extract that here
        }
    }
}

return min_dist;

View solution in original post

7 Replies
XanderBakker
Esri Esteemed Contributor

Hi Josh Harris ,

The short answer is yes you can. However, you will need to consider performance and be smart on determining the nearest point. Als the other service should be in the same map or in the same datastore to have access.

You can access the other service and start processing each feature one by one to determine the nearest point. If the service has a lot of points, this will come with a cost (performance wise). You can reduce the number of features to process if you have some idea about the maximum distance in which you are sure to find a point. This would allow you to create buffer around the input feature, and use the Intersects function to query the other layer and after that loop through the subset of feature to get to the nearest.

So to provide you with some more advise, it would be necessary to share how many feature you have in the other feature service and if there is a distance you can define to avoid processing a large quantity of features.

JoshHarris
Occasional Contributor

Hi Xander Bakker‌,

Thanks for the prompt response. That's great. So the scenario is that I have a webmap with two hosted feature services (Point 1, Point 2). Both feature services are being updated on a daily basis, and will hold at maximum ~30,000 records. I am only interested in distances <= 500m. Initially I thought the Distance or DistanceGeodetic would give me what I was after, but I kept getting "Illegal Argument" error. Am I on the right path with this?

0 Kudos
XanderBakker
Esri Esteemed Contributor

Hi Josh Harris ,

Here is an example expression that you can use:

var fs = FeatureSetByName($map,"The Name of the other point feature service");
var buf = Buffer($feature, 500, "meter");
var fs_filtered = Intersects(fs, buf);
var cnt = Count(fs_filtered);

var min_dist = 999;
if (cnt > 0) {
    for (var f in fs_filtered) {
        var dist = Distance($feature, f);
        if (dist < min_dist) {
            min_dist = dist;
            // if you want to know which feature is nearest, 
            // you should extract that here
        }
    }
}

return min_dist;

JoshHarris
Occasional Contributor

Hi @XanderBakker 

I'm digging this old post up. I'm looking to retrieve a specific attribute from the nearest feature (e.g I want to grab the asset ID from the nearest feature. I've tried tweaking the above expression, but it doesn't seem to be reliable in what it's retrieving. Any help would be greatly appreciated.

var fs = FeatureSetByPortalItem(Portal('https://www.arcgis.com/'), '[item_id]', 0);
var buf = Buffer($feature, 500, "meter");
var fs_filtered = Intersects(fs, buf);
var cnt = Count(fs_filtered);

var min_dist = 999;
if (cnt > 0) {
    for (var f in fs_filtered) {
        var dist = DistanceGeodetic($feature, f);
        if (dist < min_dist) {
            min_dist = dist;
        }
    }
}

return f.[field_name];
0 Kudos
XanderBakker
Esri Esteemed Contributor

Hi @JoshHarris ,

A couple of changes (you are close):

// Connect to featureset
var fs = FeatureSetByPortalItem(Portal('https://www.arcgis.com/'), '[item_id]', 0); 

// define the field name with the information you are looking for
var field_name = "Your Field Name goes here";

// buffer, filter and count (unchanged)
var buf = Buffer($feature, 500, "meter"); 
var fs_filtered = Intersects(fs, buf); 
var cnt = Count(fs_filtered); 

// some initial values
var min_dist = 999; 
var result = "No feature found";

// first check if you have feature in the search distance
if (cnt > 0) { 
    // loop through the features found
    for (var f in fs_filtered) { 
        // calculate distance
        var dist = DistanceGeodetic($feature, f); 
        // check if it is closer than previous results
        if (dist < min_dist) { 
            // got a hot, change the min dist and read the field
            min_dist = dist; 
            result = f[field_name];
        } 
    } 
}

// return the result
return result; 
JoshHarris
Occasional Contributor

Awesome as always @XanderBakker ,thanks for your help.

0 Kudos
JoshHarris
Occasional Contributor

Spot on Xander Bakker‌, that works perfectly thank you