Select to view content in your preferred language

Error when trying to find closest feature using buffer

1483
4
Jump to solution
05-10-2023 08:15 AM
BrianHumphries1
Emerging Contributor

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!

 

0 Kudos
1 Solution

Accepted Solutions
JohannesLindner
MVP Alum

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;

 


Have a great day!
Johannes

View solution in original post

4 Replies
MikeMillerGIS
Esri Frequent Contributor
Try passing in True as the forth argument, this will insure geometry will be returned
https://developers.arcgis.com/arcade/function-reference/featureset_functions/#featuresetbyname

0 Kudos
MikeMillerGIS
Esri Frequent Contributor

 

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);

 

 

 

0 Kudos
JohannesLindner
MVP Alum

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;

 


Have a great day!
Johannes
BrianHumphries1
Emerging Contributor

Thank you Johannes 🙂 that did the trick!

Your a 🌠ROCK STAR🌠

0 Kudos