Select to view content in your preferred language

Arcade Code Review: Set polyline M-values to cumulative length of line

03-11-2022 10:19 AM
Labels (1)
Honored Contributor

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;
    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.)


Tags (1)
0 Kudos
13 Replies
Honored Contributor

It looks like someone posted a similar script on GitHub:

Create SetMValues

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.

0 Kudos
MVP Frequent Contributor

No, it doesn't. I guess they copied the rule template and forgot to delete the comment.

Have a great day!
Honored Contributor

For future reference, when my organization moves from Pro 2.6.8 to Pro 3.2(?):

...copy your geoemtry(can do this by calling Dictionary(geo) on it, prior to 3.2, you need to call Dictionary(Text(geo))).

Arcade modify only Z geometry

0 Kudos