I am fairly new to Arcade and am trying to update the CoordinatedID field in my WaterMain layer using an attribute rule with the help of some code found here: Attribute rule script expression examples—ArcGIS Pro | Documentation
What I would like to do it grab the CoordinatedID field from my Roads (Centreline_Assets) layer and use it to populate the CoordinatedID field in my WaterMains (WaterMains_Assets) layer. They layers don't line up exactly so I am trying to buffer the road by 10m and populate the Coordinated field based on an intersection between the buffer and the WaterMains layer. Here's what I have so far:
//On Insert or Update populate Coordinate ID
var fcRoad=FeatureSetByName($datastore, "Centreline_Assets",["Coordinated_ID"])
var fcWaterMain=FeatureSetByName($datastore,"WaterMain_Assets_SplitLine",["Coordinated_ID"])
Var RoadIntersect = Intersects(Buffer(fcRoad,10,'meter'),fcWaterMain)
var AddList = []
var counter = 0
var noCID = Count(RoadIntersect)
if (noCID>0){
for (var Road in RoadIntersect){
AddList[counter]={
'Coordinated_ID':Centreline_Assets.CoordinatedID,
'attributes':{
'add_CoordinateID':$feature.Coordinated_ID
}
}
counter++
}
return {
'result': noCID + ' Coordinated ID found',
'edit': [{
'className':'Centreline_Assets',
'updates': AddList
}]
}
}else{
return 'No Coordinated ID'
}
I keep getting the following error:
Invalid expression. Error on line 4. Geometry type null expected.
Any suggestions?
Solved! Go to Solution.
Hi @SarahHartholt ,
Good catch, it should indeed be "roads". I wonder why the general function failure is happening. The general function failure closed your ArcGIS Pro session? What version are you using? Where are the centerlines and water mains stored (they should be in the same $datastore)?
Would it be possible to share a small piece of data to do some testing?
ArcPro stays open. I get the error when verifying the code in the Expression Builder within the Attribute Rule window. I'm using ArcPro 2.6.2
Both feature classes are stored in the default geodatabase that is automatically created with the ArcPro project.
I would recommend you to create an expression in the pop-up of the waterline layer and test the expression divided into parts. First until determining the count and return that count and then the other parts.
I closed the document, re opened it and now the expression that you wrote up seems to work. I think all I need to do now is figure out how to assign global id's to my water main features for the expression to be valid
Hi @SarahHartholt ,
Just go to your featureclass in the catalog window, right click, choose Manage and you will see the option Add GlobalID's
Thank you!
Hi @SarahHartholt ,
You are welcome.
To take it a step further and include the validation to see if the main is contained by a buffer of the roads, have a look at this example:
Function IsContainedByRoads(watermain, roads) {
var bufs = [];
// create list of selected roads buffer
for (var road in roads) {
var buf = Buffer(road, 10, 'meter');
bufs[Count(bufs)] = buf;
}
// union the road buffers
var buftot = Union(bufs);
// validate if watermain is contained by total buffer
return Contains(buftot, watermain);
}
//On Insert or Update populate Coordinate ID
var fsRoads = FeatureSetByName($datastore, "Centreline_Assets", ["Coordinated_ID"], True);
var watermain = $feature;
var watermainbuf = Buffer(watermain, 10, 'meter');
var roads = Intersects(fsRoads, watermainbuf);
var cnt = Count(roads);
// check different situations
if (cnt == 0) {
// there are no roads found
return null;
} else if (cnt == 1) {
// there is a one road, validate if the main is contained by the roads buffer
if (IsContainedByRoads(watermain, roads)) {
return First(roads)["Coordinated_ID"]; // create the ID using NextSequenceValue
} else {
// what to return when the main is not contained?
return null;
}
} else {
// there are multiple roads found, validate if the main is contained by the roads
if (IsContainedByRoads(watermain, roads)) {
//find the longest segment
var maxsegmentlength = 0;
var CoordID = null;
for (var road in roads) {
var segment = Intersection(road, watermainbuf);
var segmentlength = Length(segment, 'meter');
if (segmentlength > maxsegmentlength) {
CoordID = road["Coordinated_ID"];
maxsegmentlength = segmentlength;
}
}
return CoordID; // create the ID using NextSequenceValue
} else {
// what to return when the main is not contained?
return null;
}
}