Nearest Address Calculation Expression in Field Maps Smart Form

986
2
Jump to solution
05-24-2022 12:32 PM
OliverSandoval_p
New Contributor III

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;

 

 

 

 

 

 

 

Any advice would be greatly appreciated!!
 
EDIT: I am able to view the dictionary successfully, but cant figure out how to sort and return it as a featureSetconsole_results_dictionary.png

 

0 Kudos
1 Solution

Accepted Solutions
by Anonymous User
Not applicable

@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.

View solution in original post

2 Replies
by Anonymous User
Not applicable

@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
New Contributor III

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

0 Kudos