Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?

share|improve this question
    
When you mean slope, do you mean that you have a PolyLineZ feature class with Z values at each vertex? And if so, how would offsetting the line affect the Z values? Wouldn't simply preserving them be what you want? – blah238 May 20 '12 at 22:58
    
Also are your features in projected coordinates? If so you could simply add/subtract your offset to each vertex coordinate. – blah238 May 20 '12 at 23:07
    
This doesn't work because if my offset is 5 meters, I would need to have that 5 meter offset extend from each line perpendicular from any point on the line, else a 5 meter x offset on a horizontal line just moves the whole line west 5 meters, as opposed to extending in the y-direction as well. Therefore, the offset calculation is more complex than that, and I think it's what the Buffer function does. – ndimhypervol May 22 '12 at 18:58
up vote 7 down vote accepted

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.

  1. 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").
  2. Merge the buffers together.
  3. Buffer the original line again, this time "FULL".
  4. Convert the FULL buffer to lines (PolygonToLine: "IGNORE_NEIGHBORS"), then convert its vertices to points (FeatureVerticesToPoints: "BOTH_ENDS").
  5. Buffer each point by a very small width (e.g. 0.1 m).
  6. Split the lines by vertex (SplitLine).
  7. Select by location to select all lines that intersect with the point buffers.
  8. Delete these lines.
  9. Dissolve ("SINGLE_PART") on the segment unique ID.
  10. 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.

share|improve this answer

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[0][0] + xOffset, row[0][1] + yOffset]])
share|improve this answer
    
this takes offset as a decimal degree. is there any to input offset distance in meters. lets say i want to take offset around 20 meters of Line ?? – Akhil Kumar Mar 10 at 8:57
    
It depend on liner unit in projection system. If liner unit is meter then it will take meter. – abdul8817 Mar 10 at 9:48
    
isn't there any way to forcefully give desired unit into offset ? – Akhil Kumar Mar 10 at 10:04
    
check this Linear unit and to change projection system define projection. – abdul8817 Mar 10 at 10:17
    
I can't get this to work, it offsets my entire feature class. Also I have a grid of lines (street centerlines) so I would assume the X and Y offset would vary based on the orientation of the line? also I have varied distances for each line, I have the values stored in an attribute field. I tried to pull those using a search cursor wiith the original layer with the updateCursor nested below. – kflaw Apr 18 at 21:24

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.