Hello,
I am attempting to auto calculate a field in the Field maps smart form for a hosted feature layer using the new arcade calculation capability. Using the solution provided here Solved: Using Arcade to Find the Nearest Address Point - Esri Community I kept getting wrong and inconsistent results for the nearest address. So I have now switched to making a dictionary and converting it into a feature so I can sort the buffer intersecting addresses by distance to get accurate results. Now I am just receiving null values
Our feature services are in nad 1983.
Here is my code
var search_distance = 150;
var addresses = FeatureSetById($map, /* AddressPoints_Export */ "AddressPoints_Export_5543")
var buf = Buffer($feature, search_distance, "feet")
var intersecting = Intersects(addresses, buf)
var cnt = Count(intersecting)
Console("Total Number of addresses within buffer: " + cnt)
var emptyDict = {
'fields': [{ 'name': 'address', 'type': 'esriFieldTypeString'},{ 'name': 'distance_a', 'type': 'esriFieldTypeInteger'}],
'geometryType': '',
'features': []
};
var index = 0;
if (cnt >0){
for (var f in intersecting){
var addressDist = number(Distance(f,$feature, "feet"));
var address_n = f.FULL_ADDRESS
for(var i = 0; i <1; i++){
emptyDict.features[index]= {
'attributes':{
'address': address_n,
'distance_a': addressDist
}
}
index++;
}
}
}
var fs_dict = FeatureSet(Text(emptyDict));
var nearest_address = First(Orderby(fs_dict, 'distance_a DESC'));
return nearest_address;
Solved! Go to Solution.
@OliverSandoval_p Try something like this:
// If feature doesn't have geometry return null
if (IsEmpty(Geometry($feature))) { return null }
// Get the parcels layer
var parcels = FeatureSetByName($map, 'Parcels')
// Buffer the current location and intersect with parcels
var bufferedLocation = Buffer($feature, 100, 'feet')
var candidateParcels = Intersects(parcels, bufferedLocation)
// Calculate the distance between the parcel and the current location
// Store the feature and distance as a dictionary and push it into an array
var featuresWithDistances = []
for (var f in candidateParcels) {
Push(featuresWithDistances,
{
'distance': Distance($feature, f, 'feet'),
'feature': f
}
)
}
// Sort the candidate parcels by distance using a custom function
function sortByDistance(a, b) {
return a['distance'] - b['distance']
}
var sorted = Sort(featuresWithDistances, sortByDistance)
// Get the closest feature
var closestFeatureWithDistance = First(sorted)
// If there was no feature, return null
if (IsEmpty(closestFeatureWithDistance)) { return null }
// Return the address
return `${closestFeatureWithDistance['feature']['ADDNUM']} ${closestFeatureWithDistance['feature']['ADDRESSNAM']}`
I think you were pretty close. You don't need to create a feature set, you can just create an array of objects and then use a custom sort function sort by distance, then access the attributes for that feature to generate the address.
@OliverSandoval_p Try something like this:
// If feature doesn't have geometry return null
if (IsEmpty(Geometry($feature))) { return null }
// Get the parcels layer
var parcels = FeatureSetByName($map, 'Parcels')
// Buffer the current location and intersect with parcels
var bufferedLocation = Buffer($feature, 100, 'feet')
var candidateParcels = Intersects(parcels, bufferedLocation)
// Calculate the distance between the parcel and the current location
// Store the feature and distance as a dictionary and push it into an array
var featuresWithDistances = []
for (var f in candidateParcels) {
Push(featuresWithDistances,
{
'distance': Distance($feature, f, 'feet'),
'feature': f
}
)
}
// Sort the candidate parcels by distance using a custom function
function sortByDistance(a, b) {
return a['distance'] - b['distance']
}
var sorted = Sort(featuresWithDistances, sortByDistance)
// Get the closest feature
var closestFeatureWithDistance = First(sorted)
// If there was no feature, return null
if (IsEmpty(closestFeatureWithDistance)) { return null }
// Return the address
return `${closestFeatureWithDistance['feature']['ADDNUM']} ${closestFeatureWithDistance['feature']['ADDRESSNAM']}`
I think you were pretty close. You don't need to create a feature set, you can just create an array of objects and then use a custom sort function sort by distance, then access the attributes for that feature to generate the address.
Hi Aaron,
Sorry for the late reply! I was able to figure out that the Web Map needed to have its projection changed by adding a service as a basemap with a different projection than web Mercator in order to match the layers' NAD 1983. I ended up using my original code based off the solution in the original post, but I had to reupload the hosted feature layers as Web Mercator.
Making sure everything in a workspace including the map is in the right projection is one of the most critical steps, but its something I wasn't familiar with in terms of ArcGIS Online jiminey crickets!!!
Thank you for your taking the time to make the solution!
Best,
Oliver