Hello ESRI Forum,
I hope this message finds you well. I am currently working on an UN project where we need to calculate the actual 3D length of line assets when adding point assets to the map. The aim is to automatically connect the point assets to the line assets by adding a vertex to the intersecting line features at a right angle.
I have encountered an issue with the attribute rule that I'm seeking assistance with. While the rule works fine for insert processes, I am facing challenges when updating existing junction features.
The problem arises when the intersecting line features are at the same height. In such cases, only the last and first vertex of the line features are moved along, resulting in incorrect calculations of line lengths. I have tried various approaches but have been unable to resolve this behavior.
To illustrate the issue, let's consider the following scenarios:
1. When the lines are at different heights:
2. When the lines are at the same height:
I would greatly appreciate any help or insights you can provide to address this issue. Here is an overview of the attribute rule that I have placed on the point feature:
// get line features in a small radius
var lines = FeaturesetByName($datastore, "PipelineLine", ["GlobalID"], true);
var i_lines = Intersects(lines, $feature);
if (i_lines == null) {
return;
}
// create update variable
var updates = [];
// get distances from start and end point
for (var line in i_lines) {
var line_geo = Geometry(line);
var point_geo = Geometry($feature);
var d_start = Distance(point_geo, line_geo.paths[0][0]);
var d_end = Distance(point_geo, line_geo.paths[-1][-1]);
// get the new point coordinates: x/y from the closest line end point, z from the point
var i = IIf(d_start < d_end, 0, -1);
var v = [line_geo.paths[i][i].x, line_geo.paths[i][i].y, point_geo.z, null];
for (var k = 0; k < Count(line_geo.paths[i]); k++) {
if (line_geo.paths[i][k].x == v[0] && line_geo.paths[i][k].y == v[1] && line_geo.paths[i][k].z == v[2]) {
return;
}
}
// add vertex at start or end of line
var new_line_geo = Dictionary(Text(line_geo));
var j = IIf(i == 0, 0, Count(new_line_geo.paths[0]));
Insert(new_line_geo.paths[0], j, v);
var update = {
"globalID": line.GlobalID,
"geometry": Polyline(new_line_geo)
};
Push(updates, update);
}
return {
edit: [{
"className": "PipelineLine",
"updates": updates
}]
};
And i also have a code that lies on the line feature, so that the vertexes also get added when a enduser inserts a new line:
var junctions = FeaturesetByName($datastore, "PipelineJunction", ["GlobalID"], true);
var assemblies = FeaturesetByName($datastore, "PipelineAssembly", ["GlobalID"], true);
var devices = FeaturesetByName($datastore, "PipelineDevice", ["GlobalID"], true);
var intersectingJunctions = Intersects(junctions, $feature);
var intersectingAssemblies = Intersects(assemblies, $feature);
var intersectingDevices = Intersects(devices, $feature);
var pointGeos = [];
// Add the geometries of all intersecting features to an array
if (!isEmpty(intersectingJunctions)) {
for (var junction in intersectingJunctions) {
var fagt = [junction.assetgroup, junction.assettype]
if(arrayIsInArray(fagt, junctionTargets)){
Push(pointGeos, Geometry(junction));
}
}
}
if (!isEmpty(intersectingAssemblies)) {
for (var assembly in intersectingAssemblies) {
var fagt = [assembly.assetgroup, assembly.assettype]
if(arrayIsInArray(fagt, assemblyTargets)){
Push(pointGeos, Geometry(assembly));
}
}
}
if (!isEmpty(intersectingDevices)) {
for (var device in intersectingDevices) {
var fagt = [device.assetgroup, device.assettype]
if(arrayIsInArray(fagt, deviceTargets)){
Push(pointGeos, Geometry(device));
}
}
}
if(isEmpty(pointGeos)){
return;
}
var lineGeo = Geometry($feature);
// Iterate through all intersecting point geometries
for (var i = 0; i < Count(pointGeos); i++) {
var pointGeo = pointGeos[i];
// Calculate distances from the start and end points of the pipeline to the intersection
var d_start = Distance(pointGeo, lineGeo.paths[0][0]);
var d_end = Distance(pointGeo, lineGeo.paths[-1][-1]);
// Determine whether to add the vertex at the start or end of the line
var index = IIf(d_start < d_end, 0, -1);
// Create the vertex coordinates using the intersection and the current Z-coordinate
var v = [lineGeo.paths[index][index].x, lineGeo.paths[index][index].y, pointGeo.z];
// Check if the vertex already exists in the line geometry
var vertexExists = false;
for (var k = 0; k < Count(lineGeo.paths[index]); k++) {
if (lineGeo.paths[index][k].x == v[0] && lineGeo.paths[index][k].y == v[1] && lineGeo.paths[index][k].z == v[2]) {
vertexExists = true;
break;
}
}
// If the vertex does not exist, add it to the line geometry
if (!vertexExists) {
var newLineGeo = Dictionary(Text(lineGeo));
var j = IIf(index == 0, 0, Count(newLineGeo.paths[0]));
Insert(newLineGeo.paths[0], j, v);
lineGeo = Polyline(newLineGeo);
}
}
// Return the modified polyline geometry with the added vertices
return lineGeo;
Thanks in advance and kind regards,
Stefan
PS: I also needed some assistance when creating those rules. Thats the link to the post i made there:
https://community.esri.com/t5/attribute-rules-questions/need-help-with-calculating-3d-length-of-line...
I don't truly understand what is going on, but I ran into an issue with split and wonder if you are encounter something similar. Could pro be sending an apply edits that is overwriting your AR edits? If you watch fiddler, in the apply edits payload, is there a point and line edit?
Hi @MikeMillerGIS,
is my explenation not clear enough, or are you just having a problem understanding why its not working correctly? and what kind of issue with split do you have? I just tried splitting one of the two lines and it works fine. Saddly my free version of fiddler expiered some months ago but I will check for a different software. I tried to check the workload with the diagnostic monitor and no it doesnt look like there are any apply edits that overwrite my AR edits, they run through correctly, but I dont know if one can see this in the diagnostic monitor.