Select to view content in your preferred language

Finding closest point, returning closest point's ID in newly created feature's attribute table.

477
1
01-13-2022 08:18 AM
AdminAccount2
Frequent Contributor

I'm trying to develop an immediate calculation attribute rule that finds the closest asset (point) and returns the unique ID to the newly created feature's attribute table (also a point). For starters, I have been using a solved question thread originally posted by @James_Norquest, which can be found here.

Here's the code that I've been using:

 

//importing two fields, including geometry of the feature to be analyzed
var closestAsset = FeatureSetByName($datastore, "ClosestAssetFC",["label","type"], true);

//In OP, this is the "meat & potatoes"
var feature_buffer = Buffer($feature, 500, 'feet');
var nearest = First(Intersects(closestAsset, feature_buffer));

return nearest["label"];

 

 


When I create a new feature, the field to be populated by the rule returns the same asset ID from the ClosestAssetFC, no matter where I put it. Through some troubleshooting, I found that it was because the entire ClosestAssetFC was being returned by the script, and was only returning the first record, which was the same every time. 

I'd also like to subset the ClosestAssetFC to only include a specific asset type. Here's the code that I tried:

 

var closestAsset = FeatureSetByName($datastore, "ClosestAssetFC", ["label","type"], true);

var feature_buffer = Buffer($feature, 500, 'feet');
var nearest = Intersects(closestAsset, feature_buffer);
var nearestFilter = Filter(nearest, 'type = "Asset Type 1"');

return First(nearestFilter["label"]);

 


This gives me an error, saying that a dictionary type was expected at line 8.

Any advice here would be much appreciated! 

Best,

 

Mike

0 Kudos
1 Reply
JohannesLindner
MVP Frequent Contributor

First() only finds the first feature intersecting the buffer, not the closest one.

You get the error because you try to get "label" from the feature set, not from the first feature.

 

return First(nearestFilter)["label"];

 

 

This is how I do it in my Attribute Rules:

 

function closest_feature(test_feature, compare_feature_set) {
  var min_distance = 9999999
  var closest_feature = null
  for(var f in compare_feature_set) {
    var d = Distance(test_feature, f)
    if(d < min_distance) {
      min_distance = d
      closest_feature = f
    }
  }
  return closest_feature
}

var fs_assets = FeatureSetByName($datastore, "AssetFC", ["label", "type"], true)
var fs_filtered_assets = Filter(fs_assets, "type = 'Asset Type 1'")
var fs_close_assets = Intersects(fs_filtered_assets, Buffer($feature, 500, "feet"))
var closest_asset = closest_feature($feature, fs_close_assets)

if(closest_asset == null) {
  return null
}
return closest_asset.label

 

 


Have a great day!
Johannes
0 Kudos