Select to view content in your preferred language

Attribute Rules | Arcade | Edit Multiple Line Features Using a Loop

809
5
Jump to solution
03-16-2023 11:39 AM
Labels (3)
FredK
by
Emerging Contributor

Hi Everyone,

I'm trying to edit a line feature class when a To Node point is moved. The arcade attribute rule I wrote works, but it only moves 1 line that has a matching ID. It seems like it is the first OBJECTID the script encounters. For some reason, the rest of the lines aren't moving. Does anyone see anything in this code that could be preventing that?

 

 

 

 

var pointGeometryX = Text(Geometry($feature).x) //X Coordinate of Point to Be Moved
var pointGeometryY = Text(Geometry($feature).y) //Y Coordinate of Point to Be Moved
var pointID = $feature.assetID //Asset ID of Point to be Moved

var lineImport = FeatureSetbyName($datastore, "LineLayer",['*'],true) //Line Layer to be moved based on new location of Point
var lineFilter = filter(lineImport "assetNodeTo = @pointID") //Filter Line Layer to just the To Nodes that join to the moved point, Join is based on Asset ID (point.assetID=line.assetNodeTo)

var AddList = [] //Create empty list
var counter = 0 //Set counter
var numToNodes= Count(lineFilter) //Get Count of Filtered data

if (numToNodes > 0) { //If there are 1 or more To Nodes, execute loop

for (var i in lineFilter) { //Loop through all rows in filtered data 

var LineGeomPaths = Geometry(i).paths ;//Get Geometry of Line Layer
var fromNodeGeom = LineGeomPaths[0][0]; //Get From Nodes XY Coordinates
var fromNodeGeomX = Text(fromNodeGeom.x); //Get Text From Node X
var fromNodeGeomY = Text(fromNodeGeom.y); // Get Text From Node Y

var polylineJSON = { "paths": [[[fromNodeGeomX,fromNodeGeomY,0],[pointGeometryX,pointGeometryY,0]]],"spatialReference": {"wkid":2249}}; //Build Polyline layer with new To Node (New moved point geometry), keep same From Node
var polyFinal=Polyline(polylineJSON)// Build Polyline

AddList[counter] = {'OBJECTID': i.OBJECTID,'geometry': polyFinal}; //Add to List
}
}
counter++ 
}
return {'result': i.OBJECTID,'edit': [{'className': 'LineLayer','updates': AddList}]}//Return edit statement
else { return $feature.assetID} //If no To Nodes, overwrite the assetID with current value and exit loop

 

 

 

 

0 Kudos
1 Solution

Accepted Solutions
DavidSolari
Frequent Contributor

I've cleaned up the posted code and moved the counter increment to the right spot, let us know if this works.

 

var pointGeometryX = Text(Geometry($feature).x);
var pointGeometryY = Text(Geometry($feature).y);
var pointID = $feature.assetID;

var lineImport = FeatureSetbyName($datastore, "LineLayer", ["*"], true);
var lineFilter = filter(lineImport "assetNodeTo = @pointID"); //Filter Line Layer to just the To Nodes that join to the moved point, Join is based on Asset ID (point.assetID=line.assetNodeTo)

var AddList = [];
var counter = 0;
var numToNode = Count(lineFilter);

if (numToNodes > 0) {
    for (var i in lineFilter) {
        var LineGeomPaths = Geometry(i).paths;
        var fromNodeGeom = LineGeomPaths[0][0]; //Get From Nodes XY Coordinates
        var fromNodeGeomX = Text(fromNodeGeom.x);
        var fromNodeGeomY = Text(fromNodeGeom.y);

        var polylineJSON = {   //Build Polyline layer with new To Node (New moved point geometry), keep same From Node
            "paths": [[
                [fromNodeGeomX, fromNodeGeomY, 0],
                [pointGeometryX, pointGeometryY, 0]
            ]],
            "spatialReference": {
                "wkid":2249
            }
        };
        var polyFinal = Polyline(polylineJSON)
        AddList[counter++] = {
            "OBJECTID": i.OBJECTID,
            "geometry": polyFinal
        };
    }
    return {
        "result": i.OBJECTID,
        "edit": [{
            "className": "LineLayer",
            "updates": AddList
        }]
    }
} else {
    return $feature.assetID
} 

 

View solution in original post

0 Kudos
5 Replies
KenBuja
MVP Esteemed Contributor

Is this the actual code you're testing? There seems to be some syntax errors, like a missing comma in line 6, missing parentheses in line 12 and 14, incorrect syntax in line 12.

0 Kudos
FredK
by
Emerging Contributor

No it's not, I edited to make it more understandable to a wider audience. I already caught a couple things and I'm editing it now. Generally speaking, it does in fact work, it just doesn't edit more than 1 line. 

0 Kudos
KenBuja
MVP Esteemed Contributor

You not incrementing the counter properly. It needs to go into the for loop.

0 Kudos
DavidSolari
Frequent Contributor

I've cleaned up the posted code and moved the counter increment to the right spot, let us know if this works.

 

var pointGeometryX = Text(Geometry($feature).x);
var pointGeometryY = Text(Geometry($feature).y);
var pointID = $feature.assetID;

var lineImport = FeatureSetbyName($datastore, "LineLayer", ["*"], true);
var lineFilter = filter(lineImport "assetNodeTo = @pointID"); //Filter Line Layer to just the To Nodes that join to the moved point, Join is based on Asset ID (point.assetID=line.assetNodeTo)

var AddList = [];
var counter = 0;
var numToNode = Count(lineFilter);

if (numToNodes > 0) {
    for (var i in lineFilter) {
        var LineGeomPaths = Geometry(i).paths;
        var fromNodeGeom = LineGeomPaths[0][0]; //Get From Nodes XY Coordinates
        var fromNodeGeomX = Text(fromNodeGeom.x);
        var fromNodeGeomY = Text(fromNodeGeom.y);

        var polylineJSON = {   //Build Polyline layer with new To Node (New moved point geometry), keep same From Node
            "paths": [[
                [fromNodeGeomX, fromNodeGeomY, 0],
                [pointGeometryX, pointGeometryY, 0]
            ]],
            "spatialReference": {
                "wkid":2249
            }
        };
        var polyFinal = Polyline(polylineJSON)
        AddList[counter++] = {
            "OBJECTID": i.OBJECTID,
            "geometry": polyFinal
        };
    }
    return {
        "result": i.OBJECTID,
        "edit": [{
            "className": "LineLayer",
            "updates": AddList
        }]
    }
} else {
    return $feature.assetID
} 

 

0 Kudos
FredK
by
Emerging Contributor

Thanks David, that was it. 

I swear I tried every combination of moving the 'counter++' and 'return' statement around to try and make this work before posting on here. Never thought to put the 'counter++' in the list. I knew someone would take a look at it and see what's wrong, so I appreciate you taking the time. I'll mark your answer as correct.

For those looking at this in posterity, there were a few minor additional adjustments I had to make to get it 100%, so here's the final code (These were issues in my original post): 

Line 5 | Limited the number of fields to just 'OBJECTID' and 'assetNodeTo' instead of '*'

Line 6 | There was a missing comma in the filter statement.

Line 10 | Should be: numToNodes, not numToNode.

Line 35 | Should be: "result": $feature.assetID. This will return the existing Asset ID instead of the OBJECTID of one of the lines.

I should also note that this will only work for lines with 2 vertices. If you have more than two, the updated line will be reduced to 2, so it will return a straight line. This isn't ideal  in some circumstances and I'll update this when I work in some code for lines with >2 vertices. 

 

 

var pointGeometryX = Text(Geometry($feature).x);
var pointGeometryY = Text(Geometry($feature).y);
var pointID = $feature.assetID;

var lineImport = FeatureSetbyName($datastore, "LineLayer", ['OBJECTID','assetNodeTo'], true);
var lineFilter = filter(lineImport, "assetNodeTo = @pointID"); //Filter Line Layer to just the To Nodes that join to the moved point, Join is based on Asset ID (point.assetID=line.assetNodeTo)

var AddList = [];
var counter = 0;
var numToNodes = Count(lineFilter);

if (numToNodes > 0) {
    for (var i in lineFilter) {
        var LineGeomPaths = Geometry(i).paths;
        var fromNodeGeom = LineGeomPaths[0][0]; //Get From Nodes XY Coordinates
        var fromNodeGeomX = Text(fromNodeGeom.x);
        var fromNodeGeomY = Text(fromNodeGeom.y);

        var polylineJSON = {   //Build Polyline layer with new To Node (New moved point geometry), keep same From Node
            "paths": [[
                [fromNodeGeomX, fromNodeGeomY, 0],
                [pointGeometryX, pointGeometryY, 0]
            ]],
            "spatialReference": {
                "wkid":2249
            }
        };
        var polyFinal = Polyline(polylineJSON)
        AddList[counter++] = {
            "OBJECTID": i.OBJECTID,
            "geometry": polyFinal
        };
    }
    return {
        "result": $feature.assetID,
        "edit": [{
            "className": "LineLayer",
            "updates": AddList
        }]
    }
} else {
    return $feature.assetID
}