Update ID field using another feature class

2057
16
Jump to solution
02-03-2021 11:36 AM
SarahHartholt
Occasional Contributor III

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?

 

0 Kudos
16 Replies
XanderBakker
Esri Esteemed Contributor

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?

0 Kudos
SarahHartholt
Occasional Contributor III

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. 

SarahHartholt_0-1612450099958.png

 

0 Kudos
XanderBakker
Esri Esteemed Contributor

Hi @SarahHartholt 

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.

SarahHartholt
Occasional Contributor III

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

0 Kudos
XanderBakker
Esri Esteemed Contributor

Hi @SarahHartholt ,

 

Just go to your featureclass in the catalog window, right click, choose Manage and you will see the option Add GlobalID's

XanderBakker_0-1612455560652.png

 

SarahHartholt
Occasional Contributor III

Thank you!

0 Kudos
XanderBakker
Esri Esteemed Contributor

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;
    }
}