Select to view content in your preferred language

Address Data Management; Site address numbering

1608
7
Jump to solution
05-12-2022 12:59 PM
ChrisMartinez
Regular Contributor

I'm testing the Address Data Management solution and plan to deploy it as soon as I have a solid grasp.  The issue I'm having currently is with the Full Address Number that is auto generated in one of several different ways.  No matter which method I use, the generated numbers are not in line with the actual numbers.  Which means this isn't much of a timesaver if I have to go back and edit each one after I create it.  

I've tried using the Offset on Left/Right Side of Road and the Address Line Method.  The first address I create is generally two to four digits above what I have as my first From Address on my center line.  Then gets progressively more out of sync as I go along.  Is there anything I can do to make the numbers match up better?

Respectfully,

Chris M. 

0 Kudos
2 Solutions

Accepted Solutions
ChrisFox
Esri Regular Contributor

Hi @ChrisMartinez,

Yes, that is exactly how I would approach it. I tried this out and was able to update the rule below to handle this exact scenario. I added a new field called startnum to the AddressLine feature class and exposed it in the editing template for the layer. Then using the updated code below it behaved exactly as you described, if you leave it blank it will use the original logic, otherwise it will use the number you specify for the 1st address point and then increment by the value you specify after that.

// This rule will create one or more site addresses at each vertex along a line
// The first vertex must intersect a road and is used to determine the initial address of the first site address point (2nd vertex). The 2nd vertex is also used to determine the side of the road the addresses fall on. Each additional vertex in the line will create a site address point and the address number will increment by the value passed in the feature template.
// A new address point will also be added for each new site address point located at the closest point to the site address along the road

// Define the Address Line fields
var incrementval_field = "incrementval";
var linecapturemeth_field = "capturemeth";
var linepointtype_field = "pointtype";
var startnum_field = "startnum";

// Define the Site Addresses fields
var addressptid_field = "addressptid";
var addrnum_field = "addrnum";
var roadfullname_field = "fullname";
var status_field = "status";
var defaultstatus = "Pending";
var addrcapturemeth_field = "capturemeth";

// Define the Road Centerline fields
var fromleft_field = "fromleft";
var fromright_field = "fromright";
var toleft_field = "toleft";
var toright_field = "toright";
var fullname_field = "fullname";

// Define the Address Points field names and defaults
var id_field = "addressptid";
var pointtype_field = "pointtype";
var capturemeth_field = "capturemeth";
var offdist_field = "offdist";
var offdir_field = "offdir";
var numpoints_field = "numpoints";

// This function will Get a new id for the address point
function getAddressPointID() {
    // Define the name of the database sequence and the format for the id
    // Text on either side of the ${ ... } will be added to the id
    var sequence_name = "AddressPointID";
    var id = NextSequenceValue(sequence_name);
    return `ADD-${id}`;
}

// This function will find the closest point on line_feature from point_feature
function closestPointInfo(point_feature, line_feature) {
    var vertices = line_feature["paths"]
    var x = point_feature["x"];
    var y = point_feature["y"];

    // Loop through each part of the geometry and each segment, tracking the shortest distance
    var shortest = [1e10];
    for (var i in vertices) {
        var part = vertices[i];
        var previous = part[0];
        for (var j = 1; j < Count(part); j++) {
            var current = part[j];
            var result = pDistance(x, y, previous["x"], previous["y"], current["x"], current["y"]);
            if (result[0] < shortest[0]) shortest = result
            previous = current;
        }

    }

    // Couldn't find anything
    if (Count(shortest) == 1) return null

    return {"distance": shortest[0],
            "coordinates": shortest[1],
            "isVertex": shortest[2],
            "lineSide": shortest[3]}
}

// This function will get distance between 2 points
function pDistance(x, y, x1, y1, x2, y2) {
  var A = x - x1;
  var B = y - y1;
  var C = x2 - x1;
  var D = y2 - y1;

  var dot = A * C + B * D;
  var len_sq = C * C + D * D;
  var param = -1;
  if (len_sq != 0) //in case of 0 length line
      param = dot / len_sq;

  var xx, yy;
  var is_vertex = true;
  if (param < 0) {
    xx = x1;
    yy = y1;
  }
  else if (param > 1) {
    xx = x2;
    yy = y2;
  }
  else {
    is_vertex = false;
    xx = x1 + param * C;
    yy = y1 + param * D;
  }

  var dx = x - xx;
  var dy = y - yy;
  return [Sqrt(dx * dx + dy * dy), [xx, yy], is_vertex, sideOfLine(x,y,x1,y1,x2,y2)];
}

// This function will get side of line segment that a point (x, y) is on based on the direction of segment [[x1, y1], [x2, y2]]
function sideOfLine(x, y, x1, y1, x2, y2) {

    var d = (x - x1) * (y2 - y1) - (y - y1) * (x2 - x1)
    if (d < 0) {
        return 'Left'
    } else if (d > 0) {
        return 'Right'
    } else {
        return null
    }
}

// This function will create point geometry from coordinates [x, y]
function createPoint(coordinates, spatial_ref) {    
    return Point({"x": coordinates[0], "y": coordinates[1], "z" : 0, "spatialReference": spatial_ref})
}

// This function will return the segment intersected and the distance along the line
function intersectDistanceAlong(sourceGeometry, interestedLine){
    var distanceAlongLine = 0;
    // Loop through the segments of the line. Handle multipart geometries
    for (var part in Geometry(interestedLine).paths) {
        var segment = Geometry(interestedLine).paths[part];

        // Loop through the points in the segment
        for (var i in segment) {
            if (i == 0) continue;

            // Construct a 2-point line segment from the current and previous point
            var firstPoint = segment[i-1];
            var secondPoint = segment[i]
            var twoPointLine = Polyline({ 'paths' : [[[firstPoint.x, firstPoint.y], [secondPoint.x, secondPoint.y]]], 'spatialReference' : firstPoint.spatialReference});

            // Test if the  point intersects the 2-point line segment
            if (Intersects(sourceGeometry, twoPointLine)) {
                // Construct a 2-point line segment using the previous point and the address point
                var lastSegment = Polyline({ 'paths' : [[[firstPoint.x, firstPoint.y], [sourceGeometry.x, sourceGeometry.y]]], 'spatialReference' : firstPoint.spatialReference});
                // Add to the total distance along the line and break the loop
                distanceAlongLine += Length(lastSegment);
                return [twoPointLine, distanceAlongLine]
            }
            // Add to the toal distance along the line
            distanceAlongLine += Length(twoPointLine);
        }
    }
    return null;
}

// This function will return the address number of the new site address point
// It determines this based on the from and to address range on the intersecting road and the direction of the offset
function getAddrNum(road, percentAlong, dir) {
    var addrNum = null;
    var from = road[fromleft_field];
    var to = road[toleft_field];    
    if (Lower(dir) == 'right') {
        var from = road[fromright_field];
        var to = road[toright_field];    
    }
    if (from == null || to == null) return null;
    var val = percentAlong * (to - from);
    var addrNum = 0;
    
    if ((Floor(val) % 2) == 0) addrNum = Floor(val);
    else if ((Ceil(val) % 2) == 0) addrNum = Ceil(val);
    else addrNum = Floor(val) - 1;
    
    return from + addrNum;
}

// Get the increment value from the construct site address points feature template
// Defaults to 2
var increment = 2;
If (!HasKey($feature, incrementval_field)) return;
if ($feature[incrementval_field] != null) increment = $feature[incrementval_field]

// Get the starting number
var addrnum = $feature[startnum_field];

// Get the global id and geometry of the line
var globalid = $feature.globalid;
var geom = Geometry($feature);
var capturemeth = $feature[linecapturemeth_field];
var pointtype = $feature[linepointtype_field];

// Get the vertices of the feature
var vertices = []
var firstPoint = null;
var vertices = []
for (var part in geom.paths) {
    var segment = geom.paths[part];

    // Loop through the points in the segment
    for (var i in segment) {
        if (IsEmpty(firstPoint)) {
            firstPoint = segment[i];
            continue;
        }
        Push(vertices, segment[i]);
    }
}

if (Count(vertices) < 1) return { "errorMessage" : "Line must have at least 2 vertices" }

// Find any intersecting roads with the first vertex
// If no roads intersect, buffer the point to handle cases where point isn't exactly snapped to line and try again
// If no roads intersect the the buffer return an error message and prevent the address point from being created
var intersectingRoads = Intersects(FeatureSetByName($datastore, "RoadCenterline", [fullname_field, fromleft_field, toleft_field, fromright_field, toright_field], true), firstPoint);
if (Count(intersectingRoads) == 0) {
 intersectingRoads = Intersects(FeatureSetByName($datastore, "RoadCenterline", [fullname_field, fromleft_field, toleft_field, fromright_field, toright_field], true), Buffer(firstPoint, 5));
 if (Count(intersectingRoads) == 0) return { "errorMessage": "First vertex must intersect at least one Road Centerline" }
}
var intersectingRoad = First(intersectingRoads);

// Get the offset direction based on the second vertex in the line
var data = closestPointInfo(vertices[0], Geometry(intersectingRoad));
var dir = data["lineSide"]

// Snap the first vertex to the closest place along the line and find the distance along the line it intersects
var data = closestPointInfo(firstPoint, Geometry(intersectingRoad));
var closest_point = createPoint(data["coordinates"], Geometry($feature)["spatialReference"])
var results = intersectDistanceAlong(closest_point, intersectingRoad)
var distanceAlongLine = results[1];

// Get the new address number of the site address point based on the distance along the road and direction of the offset
var percentAlong = distanceAlongLine / Length(intersectingRoad);

// If no starting address number was specified, find it based on the distance along the road
if (IsEmpty(addrnum)) {
    addrnum = getAddrNum(intersectingRoad, percentAlong, dir)
}

// Loop through each vertext and find the closest point along the road
// Store a new site address and related address point for each vertex in the line 
// Increment the address number by the value passed in the feature template
var addressPointAdds = []
var siteAddressAdds = []
for(var i in vertices) {
    if (i == 0) {
        data["lineSide"] = dir
        data["distance"] = Sqrt(Pow(closest_point["x"] - vertices[i]["x"], 2) +  Pow(closest_point["y"] - vertices[i]["y"], 2))
    }
    else {
        var data = closestPointInfo(vertices[i], Geometry(intersectingRoad))
        var closest_point = createPoint(data["coordinates"], Geometry($feature)["spatialReference"])
    }
     
    // Get a new id for the Address Point
    var addressptid = getAddressPointID();
    
    // Add a new Address Point
    Push(addressPointAdds, {
        'attributes': Dictionary(
                        id_field, addressptid,
                        numpoints_field, 0, 
                        capturemeth_field, capturemeth, 
                        pointtype_field, pointtype, 
                        offdir_field, data["lineSide"], 
                        offdist_field, data["distance"]
                    ), 
        'geometry': closest_point
    })
    
    // Add a new Site Address
    Push(siteAddressAdds, {
        'attributes': Dictionary(addressptid_field, addressptid, status_field, defaultstatus, 
                                 addrnum_field, addrnum, roadfullname_field, intersectingRoad[fullname_field],
                                 addrcapturemeth_field, capturemeth),
        'geometry': vertices[i]
    })
    
    data = null;
    addrNum += increment;
}

// Using the edit parameter create 1 or more new site addresses and related address points
// Delete the line used to sketch the site addresses
return {
    'edit': [{
        'className': 'SiteAddressPoint',
        'adds': siteAddressAdds
    },{
        'className': 'AddressPoint',
        'adds': addressPointAdds
    },{
        'className': 'AddressLine',
        'deletes': [{
            'globalID': globalid
        }]    
    }]
}

 

View solution in original post

bbaker_tngeo
Regular Contributor

@ChrisFox,

I am trying to retrofit this attribute rule into an existing geodatabase and am having an issue recreating the Address Line rule. Currently I get an error using the expression as-is: "Geometry cannot have Z values". This is on a feature class that does not have Z-enabled. I have tried removing the "z":0 code from line 122 but still get the same result. Does the SiteAddressPoint feature class have to be z-enabled for the rule to work?

View solution in original post

7 Replies
ChrisFox
Esri Regular Contributor

Hi @ChrisMartinez,

The methods for constructing new Site Addresses don't consider the address numbers of other Site Addresses when placing new addresses. The logic uses the address range of the road and the distance along the road where the address point is placed to determine the address number. So if the road has a range of 101 to 199 and the address is placed around half way it will get an address number of  149.

Additionally, with the Address Line Method, you have the ability to specify the value addresses should increment by, so if you specify 4, the first site address point will get an address number using the logic above and every site address point you place after that will increment by 4.

Based on what you describe It sounds like the address range of the road may not accurately reflect the correct address numbers along the road. Some communities calculate the address range of the road based on the length of the road and a defined distance between address numbers. We include a disabled rule on the Road Centerlines called Logical Block Addressing. In this rule you can define the interval or distance between unique addresses and when the rule is enabled when you define the left from and right from address number on a road it will automatically calculate the correct left to and right to values based on this interval and the length of the road. You just need to customize the addressIntervalDistance shown below to meet your community's requirements.

 

// This rule will calculate the left to and right to address number using the left from and right from address numbers, the length of the road and an interval or distance between unique addresses
// This rule is disabled by default. It can be configured by updating the addressIntervalDistance and unit variables below. Enable the rule when you are ready for it to run as the road left and right from values are updated.

// Specify the interval or distance between unique addresses
var addressIntervalDistance = 50;

// Specify the unity of measure. Valid options are feet, meters, yards, miles, kilometers
var unit = "feet";

 

 

 

0 Kudos
ChrisMartinez
Regular Contributor

@ChrisFox 

Thank you.  I understand that it's important to ship the solution so that it will cover as many use cases as possible.  Sadly because of numerous factors we are something of a petri dish for edge cases and as such I'm just looking to tighten up the numbering so I don't have to go back and edit 90% of the addresses I just created.

Using the Address Line method you mentioned, does get me closer.  It would be great if I could feed the tool a start value similar to the Sequential Numbering tool. That way when an inconsistency comes up, I can end my sketch and pick back up on a number of my choosing.  In order to accomplish this, it seems I could add a new field (myaddrnum) to the address line table so I can expose it for editing, then change the necessary code to test: If(myaddrnum != null) use that as the start value of the second vertex and increment, else grab the number from the road centerline and do as you normally do.

Does that seem doable, or is there a lot more to this that I've yet to see?

Respectfully,

 

Chris M.

0 Kudos
ChrisFox
Esri Regular Contributor

Hi @ChrisMartinez,

Yes, that is exactly how I would approach it. I tried this out and was able to update the rule below to handle this exact scenario. I added a new field called startnum to the AddressLine feature class and exposed it in the editing template for the layer. Then using the updated code below it behaved exactly as you described, if you leave it blank it will use the original logic, otherwise it will use the number you specify for the 1st address point and then increment by the value you specify after that.

// This rule will create one or more site addresses at each vertex along a line
// The first vertex must intersect a road and is used to determine the initial address of the first site address point (2nd vertex). The 2nd vertex is also used to determine the side of the road the addresses fall on. Each additional vertex in the line will create a site address point and the address number will increment by the value passed in the feature template.
// A new address point will also be added for each new site address point located at the closest point to the site address along the road

// Define the Address Line fields
var incrementval_field = "incrementval";
var linecapturemeth_field = "capturemeth";
var linepointtype_field = "pointtype";
var startnum_field = "startnum";

// Define the Site Addresses fields
var addressptid_field = "addressptid";
var addrnum_field = "addrnum";
var roadfullname_field = "fullname";
var status_field = "status";
var defaultstatus = "Pending";
var addrcapturemeth_field = "capturemeth";

// Define the Road Centerline fields
var fromleft_field = "fromleft";
var fromright_field = "fromright";
var toleft_field = "toleft";
var toright_field = "toright";
var fullname_field = "fullname";

// Define the Address Points field names and defaults
var id_field = "addressptid";
var pointtype_field = "pointtype";
var capturemeth_field = "capturemeth";
var offdist_field = "offdist";
var offdir_field = "offdir";
var numpoints_field = "numpoints";

// This function will Get a new id for the address point
function getAddressPointID() {
    // Define the name of the database sequence and the format for the id
    // Text on either side of the ${ ... } will be added to the id
    var sequence_name = "AddressPointID";
    var id = NextSequenceValue(sequence_name);
    return `ADD-${id}`;
}

// This function will find the closest point on line_feature from point_feature
function closestPointInfo(point_feature, line_feature) {
    var vertices = line_feature["paths"]
    var x = point_feature["x"];
    var y = point_feature["y"];

    // Loop through each part of the geometry and each segment, tracking the shortest distance
    var shortest = [1e10];
    for (var i in vertices) {
        var part = vertices[i];
        var previous = part[0];
        for (var j = 1; j < Count(part); j++) {
            var current = part[j];
            var result = pDistance(x, y, previous["x"], previous["y"], current["x"], current["y"]);
            if (result[0] < shortest[0]) shortest = result
            previous = current;
        }

    }

    // Couldn't find anything
    if (Count(shortest) == 1) return null

    return {"distance": shortest[0],
            "coordinates": shortest[1],
            "isVertex": shortest[2],
            "lineSide": shortest[3]}
}

// This function will get distance between 2 points
function pDistance(x, y, x1, y1, x2, y2) {
  var A = x - x1;
  var B = y - y1;
  var C = x2 - x1;
  var D = y2 - y1;

  var dot = A * C + B * D;
  var len_sq = C * C + D * D;
  var param = -1;
  if (len_sq != 0) //in case of 0 length line
      param = dot / len_sq;

  var xx, yy;
  var is_vertex = true;
  if (param < 0) {
    xx = x1;
    yy = y1;
  }
  else if (param > 1) {
    xx = x2;
    yy = y2;
  }
  else {
    is_vertex = false;
    xx = x1 + param * C;
    yy = y1 + param * D;
  }

  var dx = x - xx;
  var dy = y - yy;
  return [Sqrt(dx * dx + dy * dy), [xx, yy], is_vertex, sideOfLine(x,y,x1,y1,x2,y2)];
}

// This function will get side of line segment that a point (x, y) is on based on the direction of segment [[x1, y1], [x2, y2]]
function sideOfLine(x, y, x1, y1, x2, y2) {

    var d = (x - x1) * (y2 - y1) - (y - y1) * (x2 - x1)
    if (d < 0) {
        return 'Left'
    } else if (d > 0) {
        return 'Right'
    } else {
        return null
    }
}

// This function will create point geometry from coordinates [x, y]
function createPoint(coordinates, spatial_ref) {    
    return Point({"x": coordinates[0], "y": coordinates[1], "z" : 0, "spatialReference": spatial_ref})
}

// This function will return the segment intersected and the distance along the line
function intersectDistanceAlong(sourceGeometry, interestedLine){
    var distanceAlongLine = 0;
    // Loop through the segments of the line. Handle multipart geometries
    for (var part in Geometry(interestedLine).paths) {
        var segment = Geometry(interestedLine).paths[part];

        // Loop through the points in the segment
        for (var i in segment) {
            if (i == 0) continue;

            // Construct a 2-point line segment from the current and previous point
            var firstPoint = segment[i-1];
            var secondPoint = segment[i]
            var twoPointLine = Polyline({ 'paths' : [[[firstPoint.x, firstPoint.y], [secondPoint.x, secondPoint.y]]], 'spatialReference' : firstPoint.spatialReference});

            // Test if the  point intersects the 2-point line segment
            if (Intersects(sourceGeometry, twoPointLine)) {
                // Construct a 2-point line segment using the previous point and the address point
                var lastSegment = Polyline({ 'paths' : [[[firstPoint.x, firstPoint.y], [sourceGeometry.x, sourceGeometry.y]]], 'spatialReference' : firstPoint.spatialReference});
                // Add to the total distance along the line and break the loop
                distanceAlongLine += Length(lastSegment);
                return [twoPointLine, distanceAlongLine]
            }
            // Add to the toal distance along the line
            distanceAlongLine += Length(twoPointLine);
        }
    }
    return null;
}

// This function will return the address number of the new site address point
// It determines this based on the from and to address range on the intersecting road and the direction of the offset
function getAddrNum(road, percentAlong, dir) {
    var addrNum = null;
    var from = road[fromleft_field];
    var to = road[toleft_field];    
    if (Lower(dir) == 'right') {
        var from = road[fromright_field];
        var to = road[toright_field];    
    }
    if (from == null || to == null) return null;
    var val = percentAlong * (to - from);
    var addrNum = 0;
    
    if ((Floor(val) % 2) == 0) addrNum = Floor(val);
    else if ((Ceil(val) % 2) == 0) addrNum = Ceil(val);
    else addrNum = Floor(val) - 1;
    
    return from + addrNum;
}

// Get the increment value from the construct site address points feature template
// Defaults to 2
var increment = 2;
If (!HasKey($feature, incrementval_field)) return;
if ($feature[incrementval_field] != null) increment = $feature[incrementval_field]

// Get the starting number
var addrnum = $feature[startnum_field];

// Get the global id and geometry of the line
var globalid = $feature.globalid;
var geom = Geometry($feature);
var capturemeth = $feature[linecapturemeth_field];
var pointtype = $feature[linepointtype_field];

// Get the vertices of the feature
var vertices = []
var firstPoint = null;
var vertices = []
for (var part in geom.paths) {
    var segment = geom.paths[part];

    // Loop through the points in the segment
    for (var i in segment) {
        if (IsEmpty(firstPoint)) {
            firstPoint = segment[i];
            continue;
        }
        Push(vertices, segment[i]);
    }
}

if (Count(vertices) < 1) return { "errorMessage" : "Line must have at least 2 vertices" }

// Find any intersecting roads with the first vertex
// If no roads intersect, buffer the point to handle cases where point isn't exactly snapped to line and try again
// If no roads intersect the the buffer return an error message and prevent the address point from being created
var intersectingRoads = Intersects(FeatureSetByName($datastore, "RoadCenterline", [fullname_field, fromleft_field, toleft_field, fromright_field, toright_field], true), firstPoint);
if (Count(intersectingRoads) == 0) {
 intersectingRoads = Intersects(FeatureSetByName($datastore, "RoadCenterline", [fullname_field, fromleft_field, toleft_field, fromright_field, toright_field], true), Buffer(firstPoint, 5));
 if (Count(intersectingRoads) == 0) return { "errorMessage": "First vertex must intersect at least one Road Centerline" }
}
var intersectingRoad = First(intersectingRoads);

// Get the offset direction based on the second vertex in the line
var data = closestPointInfo(vertices[0], Geometry(intersectingRoad));
var dir = data["lineSide"]

// Snap the first vertex to the closest place along the line and find the distance along the line it intersects
var data = closestPointInfo(firstPoint, Geometry(intersectingRoad));
var closest_point = createPoint(data["coordinates"], Geometry($feature)["spatialReference"])
var results = intersectDistanceAlong(closest_point, intersectingRoad)
var distanceAlongLine = results[1];

// Get the new address number of the site address point based on the distance along the road and direction of the offset
var percentAlong = distanceAlongLine / Length(intersectingRoad);

// If no starting address number was specified, find it based on the distance along the road
if (IsEmpty(addrnum)) {
    addrnum = getAddrNum(intersectingRoad, percentAlong, dir)
}

// Loop through each vertext and find the closest point along the road
// Store a new site address and related address point for each vertex in the line 
// Increment the address number by the value passed in the feature template
var addressPointAdds = []
var siteAddressAdds = []
for(var i in vertices) {
    if (i == 0) {
        data["lineSide"] = dir
        data["distance"] = Sqrt(Pow(closest_point["x"] - vertices[i]["x"], 2) +  Pow(closest_point["y"] - vertices[i]["y"], 2))
    }
    else {
        var data = closestPointInfo(vertices[i], Geometry(intersectingRoad))
        var closest_point = createPoint(data["coordinates"], Geometry($feature)["spatialReference"])
    }
     
    // Get a new id for the Address Point
    var addressptid = getAddressPointID();
    
    // Add a new Address Point
    Push(addressPointAdds, {
        'attributes': Dictionary(
                        id_field, addressptid,
                        numpoints_field, 0, 
                        capturemeth_field, capturemeth, 
                        pointtype_field, pointtype, 
                        offdir_field, data["lineSide"], 
                        offdist_field, data["distance"]
                    ), 
        'geometry': closest_point
    })
    
    // Add a new Site Address
    Push(siteAddressAdds, {
        'attributes': Dictionary(addressptid_field, addressptid, status_field, defaultstatus, 
                                 addrnum_field, addrnum, roadfullname_field, intersectingRoad[fullname_field],
                                 addrcapturemeth_field, capturemeth),
        'geometry': vertices[i]
    })
    
    data = null;
    addrNum += increment;
}

// Using the edit parameter create 1 or more new site addresses and related address points
// Delete the line used to sketch the site addresses
return {
    'edit': [{
        'className': 'SiteAddressPoint',
        'adds': siteAddressAdds
    },{
        'className': 'AddressPoint',
        'adds': addressPointAdds
    },{
        'className': 'AddressLine',
        'deletes': [{
            'globalID': globalid
        }]    
    }]
}

 

ChrisMartinez
Regular Contributor

That worked perfectly. I may have grasped the logic, but tinkering with the code would have taken me a while.  Thank you so much for the assist!

Chris' helping Chris' 

Respectfully,

Chris M.

bbaker_tngeo
Regular Contributor

@ChrisFox,

I am trying to retrofit this attribute rule into an existing geodatabase and am having an issue recreating the Address Line rule. Currently I get an error using the expression as-is: "Geometry cannot have Z values". This is on a feature class that does not have Z-enabled. I have tried removing the "z":0 code from line 122 but still get the same result. Does the SiteAddressPoint feature class have to be z-enabled for the rule to work?

ChrisFox
Esri Regular Contributor

@bbaker_tngeo, my best guess is your Address Line feature class is z-enabled. The rule takes the geometry from the vertices of the line sketch to create the site address points and if the line feature class is z-enabled then the vertices geometry will have a z value. Since this feature class is just used for sketching and only has one rule, the easiest fix would probably be to delete it and recreate it without z values enabled.

bbaker_tngeo
Regular Contributor

@ChrisFox I wondered if the site address point was trying to inherit the elevation from the line feature class. You confirmed my suspicions. I'll give that a try but I'm guessing that will solve it. Thanks for the response!

0 Kudos