I'd like to use an Arcade Function to populate the Road Name for a Work Zone Layer based off an underlying Road layer. The issue that I'm running into is that the expression is pulling the name from an intersecting road and not from the main line that I'm digitizing along.
// Create a feature set using the 'All Roads' layer in the map
var roads = FeatureSetByName($map, 'All Roadways', ['MAP_LBL'])
// Intersect the current location with the road and
// get the first road
var road = First(Intersects($feature, roads))
// If the current location does intersect a feature,
// return the name of the road. Otherwise, return null
if (!IsEmpty(road)) {
return road['MAP_LBL']
} else {
return null
}
Solved! Go to Solution.
By using the assistance of Microsoft Copilot I was able to come up with a solution. I took your solutions and applied a Buffer function to find the largest overlap. Thanks!
// 1. Access the Roads layer (with geometry)
var roadsFS = FeatureSetByName($map, 'All Roadways', ['MAP_LBL'], true);
// If no roads found in the layer, exit
if (Count(roadsFS) == 0) {
return "No roads found in 'Roads' layer.";
}
// Define the geometry of the current feature
var featureGeometry = Geometry($feature);
// 2. Create a buffer around the current feature
var featureBuffer = Buffer(featureGeometry, 10); // Adjust buffer distance as needed
// 3. Identify all roads that intersect with the buffer
var intersectingRoads = Intersects(roadsFS, featureBuffer);
// If no roads intersect, return message
if (Count(intersectingRoads) == 0) {
return "No intersecting roads.";
}
// 4. Find the road with the largest overlap
var maxOverlapLength = 0;
var bestRoadName = "";
// Loop through each intersecting road
for (var road in intersectingRoads) {
// Define the geometry of the road
var roadGeometry = Geometry(road);
// Create a buffer around the road
var roadBuffer = Buffer(roadGeometry, 10); // Adjust buffer distance as needed
// Intersection returns the shared geometry
var sharedGeom = Intersection(featureBuffer, roadBuffer);
// Length of that shared geometry
var overlapLength = Length(sharedGeom);
// Update the maximum overlap road
if (overlapLength > maxOverlapLength) {
maxOverlapLength = overlapLength;
bestRoadName = road['MAP_LBL'];
}
}
// 5. Return the best matching road name
if (maxOverlapLength > 0) {
return bestRoadName;
} else {
// If all overlaps are basically points (e.g. T-junction),
// then the overlap length is 0
return "Road overlaps only at a point (T-junction).";
}
So I'm not 100% sure if this is true, but from my testing on my own datasets, First() will grab the lowest (ie first created) object ID of the intersecting features. It's possible that's what you're running into. Are there any other fields that might match, like a roadway ID that is unique to a particular road? Then you could use the filter function instead of intersects?
@SNyquist - Zach is right. First() grabs the lowest OID and isn't the best approach.
The following arcade finds whichever road has the largest overlapping length with the current "Works" feature, thereby ignoring T-junction roads that only share a point intersection.
// 1. Access the Roads layer (with geometry)
var roadsFS = FeatureSetByName($map, "Roads", ["roadname"], true);
// If no roads found in the layer, exit
if (Count(roadsFS) == 0) {
return "No roads found in 'Roads' layer.";
}
// 2. Identify all roads that intersect this Works feature
var intersectingRoads = Intersects(roadsFS, $feature);
// If no roads intersect, return message
if (Count(intersectingRoads) == 0) {
return "No intersecting roads.";
}
// 3. Find the road with the largest overlap
var maxOverlapLength = 0;
var bestRoadName = "";
// Loop through each intersecting road
for (var road in intersectingRoads) {
// Intersection returns the shared geometry
var sharedGeom = Intersection($feature, road);
// Length of that shared geometry
var overlapLength = Length(sharedGeom);
// Update the maximum overlap road
if (overlapLength > maxOverlapLength) {
maxOverlapLength = overlapLength;
bestRoadName = road["roadname"];
}
}
// 4. Return the best matching road name
if (maxOverlapLength > 0) {
return bestRoadName;
} else {
// If all intersections are basically points (e.g. T-junction),
// then the overlap length is 0
return "Road intersects only at a point (T-junction).";
}
In action -
This code allows for the "Works" layer to be drawn across two distinct road segments and it will pick the road where the overlap is higher.
Example -
Now that's a clever solution!
Thanks, this is a great solution. But, I'm still having some issues. I'm wondering if it actually has to do with the accuracy of the snapping with the Experience Builder Editor Tool. Also, the fact that I'm trying to pull information from a large Feature Service, so there is some lagging. I'm going to try and clip out a smaller section of the road Feature Service and see if that helps with performance. Thanks for your help!
By using the assistance of Microsoft Copilot I was able to come up with a solution. I took your solutions and applied a Buffer function to find the largest overlap. Thanks!
// 1. Access the Roads layer (with geometry)
var roadsFS = FeatureSetByName($map, 'All Roadways', ['MAP_LBL'], true);
// If no roads found in the layer, exit
if (Count(roadsFS) == 0) {
return "No roads found in 'Roads' layer.";
}
// Define the geometry of the current feature
var featureGeometry = Geometry($feature);
// 2. Create a buffer around the current feature
var featureBuffer = Buffer(featureGeometry, 10); // Adjust buffer distance as needed
// 3. Identify all roads that intersect with the buffer
var intersectingRoads = Intersects(roadsFS, featureBuffer);
// If no roads intersect, return message
if (Count(intersectingRoads) == 0) {
return "No intersecting roads.";
}
// 4. Find the road with the largest overlap
var maxOverlapLength = 0;
var bestRoadName = "";
// Loop through each intersecting road
for (var road in intersectingRoads) {
// Define the geometry of the road
var roadGeometry = Geometry(road);
// Create a buffer around the road
var roadBuffer = Buffer(roadGeometry, 10); // Adjust buffer distance as needed
// Intersection returns the shared geometry
var sharedGeom = Intersection(featureBuffer, roadBuffer);
// Length of that shared geometry
var overlapLength = Length(sharedGeom);
// Update the maximum overlap road
if (overlapLength > maxOverlapLength) {
maxOverlapLength = overlapLength;
bestRoadName = road['MAP_LBL'];
}
}
// 5. Return the best matching road name
if (maxOverlapLength > 0) {
return bestRoadName;
} else {
// If all overlaps are basically points (e.g. T-junction),
// then the overlap length is 0
return "Road overlaps only at a point (T-junction).";
}