I am trying to create an offset polyline using arcpy, identical to the function in ArcObjects (constructoffset). After trying to access ArcObjects in arcpy, which I found difficult for those not well-versed in COM languages, and after much searching for functionality in the regular geoprocessing toolboxes, I discovered that this functionality seems to only exist in ArcObjects. There may be ways to program this functionality in arcpy using trig, but that seems really hard. Essentially, the product I'd like is an offset polyline that preserves all original geometry and curvature. Simply using a SearchCursor on the input and building a new feature class based on its geometry requires some algorithm I don't know. This is because without an algorithm based on slope, etc., a one-size-fits-all addition or subtraction will not preserve an offset shape for all slopes. Any help?
We came up with this technique at work that uses geoprocessing tools to do the job:
First off, make sure your line segs have unique IDs.
- Buffer "FLAT" in each direction of the line, add a new field of the same name to each and give them a direction ("L","R").
- Merge the buffers together.
- Buffer the original line again, this time "FULL".
- Convert the FULL buffer to lines (PolygonToLine: "IGNORE_NEIGHBORS"), then convert its vertices to points (FeatureVerticesToPoints: "BOTH_ENDS").
- Buffer each point by a very small width (e.g. 0.1 m).
- Split the lines by vertex (SplitLine).
- Select by location to select all lines that intersect with the point buffers.
- Delete these lines.
- Dissolve ("SINGLE_PART") on the segment unique ID.
- Spatial Join ("SHARE_A_LINE_SEGMENT_WITH") the new lines to the merged "LEFT" and "RIGHT" buffers to attribute them with direction.
Voila! Offset lines without ArcObjects.
Here is the code to do the same in arcpy
import arcpy tmpwrkspace = "C:/tempgdb/temp.gdb/" fc_line = tmpwrkspace + "MultiLineLayer" # Set some variables tempFeatureClass = tmpwrkspace + "temp_pline" #set the offset to +n or -n for direction xOffset = 0.2 yOffset = 0.2 if arcpy.Exists(tempFeatureClass): arcpy.Delete_management(tempFeatureClass) arcpy.CopyFeatures_management(fc_line, tempFeatureClass) # Perform the move with arcpy.da.UpdateCursor(tempFeatureClass, ["SHAPE@XY"]) as cursor: for row in cursor: cursor.updateRow([[row + xOffset, row + yOffset]])