Using Attribute Rules to update the line geometry and 'Auto Snap' to a point if it falls within a specified tolerance

2221
5
10-01-2021 07:21 AM
Labels (1)
AmirBar-Maor
Esri Regular Contributor
4 5 2,221

Problem:

When you enter COGO measurements to create a feature it will not snap to any other feature.

This can happen when you enter lot lines in a subdivision when you 'connect the dots' .

 

The Solution:

Disclaimer: this is R&D at this stage. If you are using true curves Arcade will densify them. So please don’t use on real data, this is not production-ready.”

Use attribute rule calculation to update the end vertex of a line if it falls within a specified tolerance to a point feature class.

AutoSnap using Attribute Rules.gif

You can see that:

1. The entered COGO dimensions are preserved

2. While the line fell short it updated the end vertex to the point.

 

How this is implemented?

When creating a new line (Insert trigger event), the end vertex of the line is extracted and buffered with the specified tolerance.

That buffer is then intersected with the points.

The number of intersected points are counted - if there is exactly one point that intersects the buffer the geometry of the line ($feature) is updated.

This attribute rule returns a geometry ('Polyline' method) that is calculated directly into the shape field.

Here is the expression:

 

 

 

//The attribute rule searchs for a point within the given search tolerance
// If one point is found the line end point 'snaps' to that point
//SETTINGS
var tolerance = 1; //Set your desired tolerance
var toleranceUnit = 'meter'; //Set to 'feet' or 'meter' or other 
var PointsFS = FeatureSetbyName($datastore,'Points',['*'], true); //Set 'Points' to the fully qualified table name

//Variables
var LineFirstVertexGeometry = Geometry($feature).Paths[0][0]; //geometry of first vertex
var LineEndVertexGeometry = Geometry($feature).Paths[0][1]; //geometry of end vertex
var EndVertexPolygonBuffer = Buffer(LineEndVertexGeometry,tolerance,toleranceUnit); //buffer last vertex
var IntersectedPointsFS = Intersects(PointsFS,EndVertexPolygonBuffer); //FS of intersected points
var CountPointsInTolerance = Count(IntersectedPointsFS); //how many points are intersected with buffer?

//if there is one point in the buffer AND the line is a 2 point line (not a curve or polyline)
if ((CountPointsInTolerance ==1) && (Count(Geometry($feature).paths[0]) == 2)){ 
    var TargetPointGeometry = Geometry(First(IntersectedPointsFS)); //find the geometry of target point    
    var x1 = TEXT(LineFirstVertexGeometry.x); //start X coordinate
    var y1 = TEXT(LineFirstVertexGeometry.y); //start Y coordinate
    var x2 = TEXT(TargetPointGeometry.x); //target X coordinate
    var y2 = TEXT(TargetPointGeometry.y); //target Y coordinate
    var SR = Geometry($feature).spatialReference; //spatial reference of the line
    var polylineJSON =  { //create a JSON representation of the updated line
        "hasZ":true,
        "paths":[[[x1,y1],[x2,y2]]],
        "spatialReference":SR
        };
        
    return Polyline(polylineJSON); //return the Polyline to update the SHP field       
}

 

 

 

 

Attribute rule setting:

AmirBarMaor_0-1633097787371.png

 

Please share thoughts and comments:

1. Do you find this useful?

2. Should it auto-snap to start/end vertices of other lines instead of the points?

3. Should we ship it with the parcel fabric

4. If you are using it, do you see undesired behavior?

 

You can download the project package and give it a try.

If you deploy it with real data,  make sure to reduce the tolerance. It was set to one for testing/development purposes.

 

 

5 Comments
AmirBar-Maor
Esri Regular Contributor

@SimonHawker1 @HusseinNasser2 - FYI

@XanderBakker - please continue to share knowledge and samples. They are fantastic.

FrankConkling
New Contributor III

Amir,

This is very interesting and could solve some issues that we have experienced when building subdivisions. I will download the sample and test the code with some data.

Great idea.

Frank Conkling - Panda Consulting.

JianT
by
New Contributor II

the results is a Geometry return to Shape field, is it possible to contain attribute fields value in result? 

AmirBar-Maor
Esri Regular Contributor

@JianT 

The 'polylineJSON' is the basis for updating the features' geometry, but a single calculation rule can update multiple fields (shp, name, ...). Check out this video to learn more.

JasonBessert
New Contributor III

Hi Amir,

I do like the idea of implementing an attribute rule to facilitate improved snapping within a specified tolerance.  I would just like to see if it can be configured further to auto snap line endpoints to other line endpoints to reduce the introduction of dangles, for users who are creating many lines for a new sub where points are not established in a fabric yet.  

 

1. Do you find this useful?  Not sure how useful this would be in contrast to our daily usage of the parcel fabric, seeing as how points are typically created AFTER a subdivision is fully COGO'd and and the user begins to build the parcel fabric with the records-based workflows.

2. Should it auto-snap to start/end vertices of other lines instead of the points?   YES - I feel this be most useful/valuable to auto-snap to start/endpoints of lines in cases where users are entering COGO for new subdivisions using the Traverse tool.  I say this, because we can't always rely that there are points representing the target location for the endpoint of a line that gets added.

3. Should we ship it with the parcel fabric:  Not opposed to this, provided users and DB administrators have the ability to toggle it off if they find no use for AutoSnapping to points.

4. If you are using it, do you see undesired behavior?  I implemented the code, tested it out, and it works successfully as intended.

About the Author
Product Engineer @ Esri. working on Parcel Fabric and ArcGIS Pro Tasks. Education: M.Sc. Geodetic Engineering, Licensed Land Surveyor, Licensed Real Estate Appraiser, System Designer, Project Manager... Free time: family, sailing, wing foiling, windsurfing, kitesurfing, diving, hiking.