I have an Arcade calculation attribute rule that sets polyline M-values to the cumulative length of the line.
The script works as expected. But I'm still a novice, so I thought I'd ask: Can the script be improved?
Notes about the script:
- It works for both singlepart and multipart features.
- It densifies true curves (unavoidable, since Arcade pre-densifies true curves).
- The code below is out-of-date. I've posted an updated version in a reply...further down in this post.
//var paths = [[[0, 5, null], [10, 10, null], [30, 0, null], [50, 10, null], [60, 10, null]]]; //JS //Only do the calculation if the geometry was changed/edited. if (!Equals(Geometry($feature), Geometry($originalfeature))) { var geom = Dictionary(Text(Geometry($feature))); var paths = geom['paths']; //Alternatively, this could be done with the Arcade distance() function. I chose to do the math manually so that the script can be used elsewhere, such as VSCode (for debugging). function pythagoras(x1, y1, x2, y2) { return sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2)); } for (var path_idx in paths) { var oldX = paths[0][0][0], oldY = paths[0][0][1], length = 0; for (var point_idx in paths[path_idx]) { var newX = paths[path_idx][point_idx][0], newY = paths[path_idx][point_idx][1]; length += pythagoras(oldX, oldY, newX, newY); paths[path_idx][point_idx][2] = length; oldX = newX; oldY = newY; } } console(paths); return { "result": { "geometry": Polyline(geom) } }; //Output: [[[0,5,0],[10,10,11.180339887498949],[30,0,33.54101966249685],[50,10,55.90169943749475],[60,10,65.90169943749476]]] }
(The script was adapted from this GitHub sample: Set Ms to Index.)
Thanks!
It looks like someone posted a similar script on GitHub:
Create SetMValues
https://github.com/Esri/arcade-expressions/pull/72/commits/7a6c0c824dfc3ee24252a7a6dd57556875589399
I wonder what this comment refers to:
This Arcade expression will calculates field values from intersecting point layer
Does the attribute rule actually do that? I’m a bit rusty on Arcade.
No, it doesn't. I guess they copied the rule template and forgot to delete the comment.
For future reference, when my organization moves from Pro 2.6.8 to Pro 3.x:
...copy your geoemtry(can do this by calling Dictionary(geo) on it, prior to 3.2, you need to call Dictionary(Text(geo))).
A related Arcade solution: How to batch edit Z values and set them all to zero