I'm currently trying to take the 'Shifting Features' script from ArcPy Cafe and this SE response and apply it to a similar script that will one by one, through all the features in a feature class, copy the first feature to another feature class, then create a copy of that feature X times with a set interval and angle.

So with this I should be able to take, say a feature class containing two lines, and create 5 lines, 3 feet apart at a 45 degree angle in a new feature class.

I figured this should be easy by nesting cursors, one for searching the original FC, one for inserting rows in the new FC, but I apparently don't know much about cursors in general, or SearchCursor or InsertCursor in general. The InsertCursor command runs the correct number of times, and creates the correct number of features, but the features have no geometry.

Can anyone help me figure out what I might be doing wrong? Thanks!

import arcpy, math

# all of these will eventually be made arguments

fc = r"c:/geometry/polylines.shp" # source feature class
fc2 = r"c:/geometry/polylines_shift.shp" # destination feature class
c_shift=3 # desired overall offset (hypotenuse)
no_features=5 # number of features to duplicate between offsets
angle=45 # angle of offsets

# given the angle and the hypotenuse, determine the x and y coordinate shift
x_shift=c_shift * math.cos(angle) 
y_shift=c_shift * math.sin(angle)

# I know this will copy the existing features from fc to fc2
#This will eventually be replaced with a command to create a blank feature class once I get the meat of the script fixed
if arcpy.Exists(fc2):

i_cursor = arcpy.da.InsertCursor(fc2,("SHAPE@XY"))
with arcpy.da.SearchCursor(fc, ["SHAPE@XY"]) as cursor:
    for row in cursor:
        for n_feat in xrange(1, no_features+1):
            i_cursor.insertRow([[row[0][0] + (x_shift*n_feat or 0),
                                 row[0][1] + (y_shift*n_feat or 0)]])
del row, cursor, i_cursor

There are two major differences with the SE post that you mention:

  1. you are working with lines (not points). Contrary to this example, shape@xy is thus not equivalent to your geometry.

  2. you are creating a new feature. When you update an existing geometry, arcpy will handle some shift operations on the centroid. In other words, shifting shape@XY will move the geometry. But if you write a point geometry to a polyline, you end up with a null geometry.

In your case, the solution whould thus be to create your cursors with SHAPE@ and add your XY shifts in a loop on all vertices of each new line.

EDIT : here is a hint (not checked, you have to insert it for your cursor and shift values)

for line in cursor:
    singleline = line[0].getPart(0) #get first part if multipart feature (I assume you only have single part features)
    for i in range(len(myline)):
        coordList.append([ myline[i].X + Xshift, myline[i].Y + Yshift]) #loop on vertices and add the shift value for X and Y
    polyline = arcpy.Polyline(arcpy.Array([arcpy.Point(*coords) for coords in coordList])) #create the actual line geometry based on vertices coordinates
  • That makes sense. Unfortunately, I'm not too familiar with working with arrays and geometry, either. I'll try to read up on those some more with the ESRI help files and revise the original post once I have something closer. Thanks! – RandomAdjectives Feb 21 '14 at 19:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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