Select to view content in your preferred language

Address Data Management Solution; Address Point added but no Site Address Point

968
3
Jump to solution
05-05-2020 01:28 PM
JoeBorgione
MVP Emeritus

ArcGisPro 2.5

I'm to a stage in my testing where I've added my own data to  the Address Data Management gdb and I'm modifying the address rules for the various feature classes. I can add an Address Point, but I don't get a resulting Site Address Point. 

I made only minor modifications to the Create Site Address Point Rule in the Address Points design:

  1. Changed the left/right from and left/right to field references to the proper field names of my Road Centerlines
  2. Changed the reference to the road centerlines feature class to the name of my Road centerlines
  3. See lines 29 through 33  and Lines 105 & 108 respectively  in script below  

Is the site address point spawned through the relationship class 'AddressPointHasSiteAddresses'?  It does not appear to be.  I'm not sure what is missing to cause the Site Address Point not to be created. 

// This rule will create a new site address point when an address point is created along a road
// The site address point will be offset from the road by the distance and direction defined in the address point feature template

// This function will return the new point offset perpendicularly from a 2-point line segment at a specified distance
// Positive distance is to the left of the line. Negative distance is to the right of the line 

function offsetPoint(firstPoint, secondPoint, fromPoint, dist) {
    var x1 = firstPoint.x;
    var y1 = firstPoint.y;
    var x2 = secondPoint.x;
    var y2 = secondPoint.y;
    var x3 = fromPoint.x;
    var y3 = fromPoint.y;

    var a = y1 - y2;
    var b = x2 - x1;

    var norm = Sqrt(a*a + b*b);
    a = a / norm;
    b = b / norm;

    return [x3 + a * dist, y3 + b * dist]
}

// 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.FROMADDR_L;
    var to = road.TOADDR_L;    
    if (Lower(dir) == 'right') {
        var from = road.FROMADDR_R;
        var to = road.TOADDR_R;    
    }
    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;
}

// This function will return the intersected features geometry, the segment intersected and the distance along the line
function IntersectingLineSegmentDistance(sourceGeometry, intersectGeometry, interestedLines){
    // Loop through the intersecting lines and find the segment of the line
    for (var line in interestedLines) {
  var distanceAlongLine = 0;
        // Loop through the segments of the line. Handle multipart geometries
        for (var part in Geometry(line).paths) {
            var segment = Geometry(line).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
                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(intersectGeometry, 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 [line, twoPointLine, distanceAlongLine]
                }
                // Add to the toal distance along the line
                distanceAlongLine += Length(twoPointLine);
            }
        }
    }
    return null;
}

// Get the object id and geometry of the feature
var oid = $feature.OBJECTID;
var id = $feature.addressptid
var geom = Geometry($feature);

// Get the distance and direction defined in the address point feature template/
// If none specified defaults to 0 and Left
var dist = 0;
if ($feature.offdist != null) dist = $feature.offdist;
var dir = 'Left';
if ($feature.offdir != null) dir = $feature.offdir; 
if (Lower(dir) == 'right') dist *= -1

// Get the number of site address points and increment value from the address point feature template
// Defaults to 1 and 0 respectively
var numpoints = 1;
if ($feature.numpoints != null) numpoints = $feature.numpoints;
var increment = 0;
if ($feature.incrementval != null) increment = $feature.incrementval;
var captureMethod = $feature.capturemeth;
    
// Find any intersecting roads with the address point
// If no roads intersect buffer the source point to handle cases where road 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 intersectGeometry = geom;
var intersectingRoads = Intersects(FeatureSetByName($datastore, "MSD_Centerlines"), intersectGeometry);
if (Count(intersectingRoads) == 0) {
 intersectGeometry = Buffer(geom, 5, 'feet');
 intersectingRoads = Intersects(FeatureSetByName($datastore, "MSD_Centerlines"), intersectGeometry);
 if (Count(intersectingRoads) == 0) return {
  "errorMessage": "Address Point must intersect at least one Road Centerline"
 };
}

// If the results are empty return an error message. This will occur if a point is created along a true curve.
// Prevent the address point from being created.
var results = IntersectingLineSegmentDistance(geom, intersectGeometry, intersectingRoads)
if (IsEmpty(results)) return {
    "errorMessage": "Failed to create the Address Point. This can occur when attempting to create an Address Point along a true curve segment. The Densify or Generalize tools can be used to convert the curve segment to a straight line segment."
}
var intersectingRoad = results[0];
var twoPtSegment = results[1];
var distanceAlongLine = results[2];

// Construct a new point geometry offset perpendicularly from the road
var xy = offsetPoint(twoPtSegment.paths[0][0], twoPtSegment.paths[0][1], geom, dist)
var newPoint = Point({ 'x' : xy[0], 'y' : xy[1], 'z' : 0, 'spatialReference' : geom.spatialReference });

// 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);
var addrnum = getAddrNum(intersectingRoad, percentAlong, dir)

// Create an array of 1 or more new site address point as specified
// Store the related address point id, the calculated address number, the intersecting road name and set the status to Pending
var adds = []
for(var i=0; i<numpoints; i++) {
 adds[Count(adds)] = {
    'attributes': {
     'addressptid' : id, 'status': 'Pending', addrnum : addrnum, fullname : intersectingRoad.fullname, capturemeth : captureMethod
    },
    'geometry': newPoint
   }
 addrNum += increment;
}

// Return the original address point id
// Using the edit parameter create 1 or more new site address points
return {
    'result' : id,
    'edit': [{
        'className': 'SiteAddressPoint',
        'adds': adds
    }]
}

Chris Fox

Hayley Miller

That should just about do it....
0 Kudos
1 Solution

Accepted Solutions
JoeBorgione
MVP Emeritus

Working through this with Chris Fox‌, we discovered a couple of issues.  The relationship class between the the two point feature classes was broken due to a mismatched field type in the key field; if you are using your own schema for the site address points, be aware of that.

We also made some edits to the block between lines 132 and 143.  One thing I've discovered is that the attributes provided in the solution are not simple and if you are in the trough of learning curve of Arcade as I am, it can be a challenge.

That should just about do it....

View solution in original post

0 Kudos
3 Replies
ChrisFox
Esri Regular Contributor

Joe Borgione‌ lines 147-153 is where it is sending the request to add the new site address points. Did you happen to change the name of the Site Address Point feature class. What are you setting for the offset and # of points for the Address Point?

JoeBorgione
MVP Emeritus

Chris Fox- I did change the original name of Site Address Points, and I was hoping that would do it for me.  Unfortunately, after I changed the feature class name in the rule, an new problem has come up:  I don't get even get a new address point now....

Sigh...

That should just about do it....
0 Kudos
JoeBorgione
MVP Emeritus

Working through this with Chris Fox‌, we discovered a couple of issues.  The relationship class between the the two point feature classes was broken due to a mismatched field type in the key field; if you are using your own schema for the site address points, be aware of that.

We also made some edits to the block between lines 132 and 143.  One thing I've discovered is that the attributes provided in the solution are not simple and if you are in the trough of learning curve of Arcade as I am, it can be a challenge.

That should just about do it....
0 Kudos