Bare with me on this...
The scenario I have is that I have users plot points on a map. These plotted points need a column populated with a unique value from other nearby points and lines ('id'). The issue I have is that these nearby points and lines are in different layers.
I am able to achieve when the nearby points are in one layer, however I am struggling to achieve this when there are multiple layers. Below is a snippet of the Arcade...
// FeatureClass2
var FeatureClass2 = FeatureSetById($map, /* Layer */ "***")
// Buffer FeatureClass1
var inspBuffer = Buffer($feature,1,'m')
// Undertake an intersection between FeatureClass2
// and FeatureClass1.
// These 2 should intersect when used correctly
var inspIntersection = Intersects(FeatureClass2, inspBuffer)
// 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 inspIntersection) {
Push(featuresWithDistances,
{
'distance': Distance($feature, f, 'm'),
'feature': f
}
)
}
function sortByDistance(a, b) {
return a['distance'] - b['distance']
}
var sorted = Sort(featuresWithDistances, sortByDistance)
var closestFeatureWithDistance = First(sorted)
// If there is no id, return null
if (IsEmpty(closestFeatureWithDistance)) {
return `${closestFeatureWithDistance['feature']['id']}`
}
else {
return null
}
TIA
Solved! Go to Solution.
OK for the "m", but the null check really should not work. Curious...
Anyway, here is one way to solve your problem:
// load the two (or more) feature classes
var featuresets = [
FeaturesetByName($datastore, "TestLines"),
FeaturesetByName($datastore, "TestPolygons"),
]
// get the id of the closest feature in a 1 meter radius
var f_buffer = Buffer($feature, 1, "meters")
var smallest_distance = 1000
var id = null
for(var i in featuresets) {
var i_fs = Intersects(featuresets[i], f_buffer)
for(var f in i_fs) {
var d = Distance(f, $feature, "meters")
if(d >= smallest_distance) { continue }
smallest_distance = d
id = f.id
}
}
return id
Basically, this adds another for loop around your lines 11-23 to take care of different featuresets.
Personally, I like to write out custom Sort()s in a for loop (that is what happens under the hood in your code anyway) because then I can see what's happening all in one place. Plus, because I set the output variable to default to null (line 9), I can eliminate the null check at the end.
How should the extraced value look? Do you want the id of the closest feature, no matter if it's a point or line? Or do you want something like "closestpoint.id, closestline.id"
Things I noticed at a first glance:
Hi Johannes,
I need the id of the closest feature, no matter whether it's a point or a line.
Regarding 'm', this is accepted as meters. Have been using for some time with no issues. The same is also true for the null check, all works as expected.
OK for the "m", but the null check really should not work. Curious...
Anyway, here is one way to solve your problem:
// load the two (or more) feature classes
var featuresets = [
FeaturesetByName($datastore, "TestLines"),
FeaturesetByName($datastore, "TestPolygons"),
]
// get the id of the closest feature in a 1 meter radius
var f_buffer = Buffer($feature, 1, "meters")
var smallest_distance = 1000
var id = null
for(var i in featuresets) {
var i_fs = Intersects(featuresets[i], f_buffer)
for(var f in i_fs) {
var d = Distance(f, $feature, "meters")
if(d >= smallest_distance) { continue }
smallest_distance = d
id = f.id
}
}
return id
Basically, this adds another for loop around your lines 11-23 to take care of different featuresets.
Personally, I like to write out custom Sort()s in a for loop (that is what happens under the hood in your code anyway) because then I can see what's happening all in one place. Plus, because I set the output variable to default to null (line 9), I can eliminate the null check at the end.
That's done the job. Thank you @JohannesLindner