160
0
01-28-2021 07:31 AM Occasional Contributor III

I just wanted to share with the community if you are using the ArcGIS Pro based Address Data Management Solution there is a way to add new Address Points without creating new Site Address Points and limit which road types Address Points can be added to. This is a small modification to the attribute rule that Esri provided.

"Create Site Address Point" is the name of the attribute rule that I modified and is stored in the Address Point feature class.

Change the default number of site address points to zero

``96: var numpoints = 0;``

Add filters to the find intersecting roads process (see lines 107, 108, 111, 112)

``````105: var intersectGeometry = geom;
108: if (Count(intersectingRoadsFilter) == 0) {
109:    intersectGeometry = Buffer(geom, 5, 'feet');
112:    if (Count(intersectingRoadsFilter) == 0) return {
114:    };
115:}``````

Wrap the original code that creates the site address points in an If-Then statement to run only if numpoints is greater than zero

``````117: if (numpoints > 0){
......
160:}``````

Finally add an Else statement at the end of the If-Then to return only the addresspointid if zero site address points are requested

``````160:} else {
162:}``````

Here is the complete expression

``````// 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
if (Lower(dir) == 'right') {
}
if (from == null || to == null) return null;
var val = percentAlong * (to - from);

if ((Floor(val) % 2) == 0) addrNum = Floor(val);
else if ((Ceil(val) % 2) == 0) addrNum = Ceil(val);
else addrNum = Floor(val) - 1;

}

// 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[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(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 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 0 and 0 respectively
var numpoints = 0;
if (\$feature.numpoints != null) numpoints = \$feature.numpoints;
var increment = 0;
if (\$feature.incrementval != null) increment = \$feature.incrementval;
var captureMethod = \$feature.capturemeth;

// 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;
intersectGeometry = Buffer(geom, 5, 'feet');
if (Count(intersectingRoadsFilter) == 0) return {
};
}

if (numpoints > 0){
// 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 twoPtSegment = results;
var distanceAlongLine = results;

// Construct a new point geometry offset perpendicularly from the road
var xy = offsetPoint(twoPtSegment.paths, twoPtSegment.paths, geom, dist)
var newPoint = Point({ 'x' : xy, 'y' : xy, '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);

// 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

for(var i=0; i<numpoints; i++) {
'attributes': {
},
'geometry': newPoint
}
}

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