Hello,
I'm having trouble with an attribute rule expression in ArcGIS Pro 2.9. I'm trying to find the nearest hydrant within 50 feet of a water sample site using a buffer, but I keep getting errors that say "field not found" or "expected convertible to geometry".
Here's the code I'm using:
var hydrantLayer = FeatureSetByName($datastore, 'SDEP.SDEADMIN.w_watr_hydrant');
var buffer = Buffer($feature.Shape, 50, 'feet');
var closestHydrant;
var closestDistance = 9999999;
var intersectedFeatures = Intersects(hydrantLayer, buffer);
for (var i in intersectedFeatures) {
var feature = intersectedFeatures[i];
var distance = Distance($feature.geometry, feature.geometry, 'feet');
if (distance < closestDistance) {
closestDistance = distance;
closestHydrant = feature;
}
}
if (closestHydrant) {
return closestHydrant['UID'];
} else {
return null;
}
I've tried changing "geometry" to "Shape" and using FeatureSetByName to reference the hydrant layer, but I keep getting errors. Can anyone help me figure out what I'm doing wrong?
Thank you in advance for your help!
Solved! Go to Solution.
Multiple problems here:
line 2: Buffer() takes a Feature or a Geometry, you're giving it a field value.
Buffer($feature, 50, 'feet');
line 6&7: If you loop through a Featureset, the loop variable is actually the Feature:
for(var f in fs) {
Console(f.Field)
}
line 8: Distance() takes tow Features or Geometries. You're supplying a non-existing field.
var d = Distance($feature, other_feature, "feet")
line 14: this looks like you're used to the truthy values of Python. This doesn't work with Arcade, you have to check actual booleans.
if (closestHydrant != null) {
throughout the expression: You're using function names as variable names (Buffer, Feature, Distance). This is a very bad practice, because you're overwriting these functions.
After line 2, you can't call Buffer() anymore, because that name is now bound to a polygon. This isn't a problem in your expression, but you have the same thing going on with Distance(), and you try to call that in a loop, which will fail.
var hydrantLayer = FeatureSetByName($datastore, 'SDEP.SDEADMIN.w_watr_hydrant');
var b = Buffer($feature, 50, 'feet');
var closestHydrant;
var closestDistance = 9999999;
var intersectedFeatures = Intersects(hydrantLayer, b);
for (var f in intersectedFeatures) {
var d = Distance($feature, f, 'feet');
if (d < closestDistance) {
closestDistance = d;
closestHydrant = f;
}
}
if (closestHydrant != null) {
return closestHydrant['UID'];
}
return null;
Couple other observations
i in this case, is the feature. Looping over the FeatureSet gets access to the feaure
for (var i in intersectedFeatures) {
Also, you need fields and geometry in the FeatureSetByName
var hydrantLayer = FeatureSetByName($datastore, 'SDEP.SDEADMIN.w_watr_hydrant',['UID'], true);
Multiple problems here:
line 2: Buffer() takes a Feature or a Geometry, you're giving it a field value.
Buffer($feature, 50, 'feet');
line 6&7: If you loop through a Featureset, the loop variable is actually the Feature:
for(var f in fs) {
Console(f.Field)
}
line 8: Distance() takes tow Features or Geometries. You're supplying a non-existing field.
var d = Distance($feature, other_feature, "feet")
line 14: this looks like you're used to the truthy values of Python. This doesn't work with Arcade, you have to check actual booleans.
if (closestHydrant != null) {
throughout the expression: You're using function names as variable names (Buffer, Feature, Distance). This is a very bad practice, because you're overwriting these functions.
After line 2, you can't call Buffer() anymore, because that name is now bound to a polygon. This isn't a problem in your expression, but you have the same thing going on with Distance(), and you try to call that in a loop, which will fail.
var hydrantLayer = FeatureSetByName($datastore, 'SDEP.SDEADMIN.w_watr_hydrant');
var b = Buffer($feature, 50, 'feet');
var closestHydrant;
var closestDistance = 9999999;
var intersectedFeatures = Intersects(hydrantLayer, b);
for (var f in intersectedFeatures) {
var d = Distance($feature, f, 'feet');
if (d < closestDistance) {
closestDistance = d;
closestHydrant = f;
}
}
if (closestHydrant != null) {
return closestHydrant['UID'];
}
return null;
Thank you Johannes 🙂 that did the trick!
Your a 🌠ROCK STAR🌠