Hello Esri Community, It seems like Arcade is a good option to use in this scenario below:
1. Currently, I have water lines that end at a valve point
2. I'm looking for a way in Arcade to insert a 2ft Service Lateral from those valve points on the downstream side. (opposite side of existing water line that terminate at valve / the clear side)
3. Once Arcade inserts the newly generated 2ft laterals after the valve points, then add a plug to the end point of the new lateral lines.
Is anyone familiar with how to accomplish the above using an Arcade Attribute Rule in ArcGIS Pro 2.9.5?
Thank you for any feedback!
I have no clue about utility services. Is this the structure you're trying to achieve?
Are the laterals in the same feature class as the water lines?
Do you have relationships between water lines / valves / laterals / plugs based on attributes? Or do you just care about geometry?
This looks correct. The 'Service' lines (laterals) are in the same feature class as the 'Water Main' lines, and each are a subtype from the feature class called 'WaterLine' in a fgdb.
Both subtypes have coded value domains but I can calculate the correct domains once I add the newly generated line segments to that will get a plug.
I just care about the geometry but the features will all eventually participate in a topology.
Thank you!
OK. You could do something like this:
// Calculation Attribute Rule on the WaterLine feature class
// field: leave empty
// triggers: Insert
// Exclude from Application Evaluation
// If the new feature is not a water main, abort
if($feature.SubtypeField != "Water Main") { return }
// load all laterals
var laterals = Filter($featureset, "SubtypeField = 'Service'")
// load the valves
var valves = FeaturesetByName($datastore, "NameOfTheValveFeatureclass")
// get the new feature's end point
var end_point = Geometry($feature).paths[-1][-1]
// if the new feature doesn't end at a valve, abort
var valves_at_end_point = Intersects(valves, end_point)
var valve = First(valves_at_end_point)
if(valve == null) { return }
// if there already exists a lateral at the valve, abort
var laterals_at_valve = Intersects(laterals, valve)
if(First(laterals_at_valve) != null) { return }
// get the angle of the new feature at the valve
var waterline_clip = Clip($feature, Extent(Buffer(valve, 0.1)))
var wcp = waterline_clip.paths
var waterline_angle = Angle(wcp[0][0], wcp[-1][-1]) * PI / 180
// calculate the geometry of the lateral line
var lateral_length = 2
var lateral_start = Geometry(valve)
var lateral_end = Point({
x: lateral_start.x + lateral_length * cos(waterline_angle),
y: lateral_start.y + lateral_length * sin(waterline_angle),
spatialReference: lateral_start.spatialReference
})
var lateral_geometry = Polyline({
paths: [[
[lateral_start.x, lateral_start.y],
[lateral_end.x, lateral_end.y],
]],
spatialReference: lateral_start.spatialReference
})
// save the lateral and the plug
return {
edit: [
{
className: "NameOfThePlugFeatureclass",
adds: [{geometry: lateral_end, attributes: {SubtypeField: "Plug"}}]
},
{
className: "WaterLine",
adds: [{geometry: lateral_geometry, attributes: {SubtypeField: "Service"}}]
}
]
}
You have to supply the correct names of the feature classes, field names and subtypes in lines 7, 10, 13, 52, 53, 56, 57.
Line 33: This creates a 2 meter lateral in my test feature class. Try it with your data, maybe it works correctly there. Else you have to replace that with the metric value (2 feet = 0,6096 meters)
Thank you, Johannes! I will test first thing in the morning and let you know how it works.
I appreciate your time and support. Have a great day ahead.