Select to view content in your preferred language

Move Features

5054
12
10-08-2013 11:16 AM
JamesSmith7
Emerging Contributor
I am attempting to select features within ArcMap, run the script, and move the selected features by a distance entered.  I am attempting to recreate the Editor Move Tool and the wheel.  I read through the documentation;  http://resources.arcgis.com/en/help/main/10.1/index.html#//01m80000000s000000.  But, the documetation dos not provide a script example.  I was thinking something along the lines of the following script.  An attribute error exists on the line reading, ext = lyr.extent.  I tried including a layer in the ListLayers function, but that did not solve the error. 

mxd = arcpy.mapping.MapDocument ("CURRENT")
df = arcpy.mapping.ListDataFrames (mxd)[0]
lyr = arcpy.mapping.ListLayers(mxd, df)

EW = arcpy.GetParameter(0)
NS = arcpy.GetParameter(1)

#orig extent
ext = lyr.extent
#mods
ext.XMin += EW
ext.XMax += EW
ext.YMin += NS
ext.YMax += NS
#new extent
lyr.extent = ext
Tags (2)
0 Kudos
12 Replies
MathewCoyle
Honored Contributor
extent is not a property of a layer object. Read through the doc here to find what you are looking for.
http://resources.arcgis.com/en/help/main/10.1/index.html#/Layer/00s300000008000000/

Also, you cannot modify the extent of a layer in that manner, you will need to modify the geometry. Finally, how you are calling a layer object is actually returning the list of layers. You will need to reference an index in the same manner you do with the dataframe object to reference an individual layer object.
0 Kudos
JamesSmith7
Emerging Contributor
Does Python provide a "short cut" approach other than using ListLayers?  Otherwise, I will be typing out 50+ Feature Classes.  Which is why I had hoped to be able to use use a generic, lyr = arcpy.mapping.ListLayers(mxd, df), and allow for any layer within the TOC to be selected and moved.
0 Kudos
JamesSmith7
Emerging Contributor
Matt,

Is this http://resources.arcgis.com/en/help/main/10.1/index.html#/Geometry/018z00000070000000/ the geometry information you suggested?  If so, ESRI's example illustrates how to calculate geometry length.  Where can I find information and script examples on how to move a selected feature?
0 Kudos
MathewCoyle
Honored Contributor
0 Kudos
JamesSmith7
Emerging Contributor
The script returns arcpy.AddMessage("Feature(s) not moved").   What am I doing incorrectly to move selected features?  Railroads is a Polyline Feature Class.

rai = arcpy.mapping.ListLayers(mxd, "Railroads", df)[0]

EW = arcpy.GetParameter(0)
NS = arcpy.GetParameter(1)

with arcpy.da.UpdateCursor(rai, ['OID@', 'SHAPE@X', 'SHAPE@Y']) as cursor:
 EWmove = 0
 NSmove = 0
 for row in cursor:
  if row[1] >= '0':
   cursor.updateRow(row)
  elif row[2] >= '0':
   cursor.updateRow(row)
  else:
   arcpy.AddMessage("Feature(s) not moved")
  
0 Kudos
MathewCoyle
Honored Contributor
You are using updateRow incorrectly. That takes a row object, not the row values. Also, if you are updating a line feature you need to change each vertex value, which means will will need to access the geometry object and step through each one, modify it, add it to an array, then pass it back to a polyline object to be updated in the geometry object.

Here's an example.
import arcpy

rai = arcpy.mapping.ListLayers(mxd, "Railroads", df)[0]
EWmove = float(arcpy.GetParameter(0))
NSmove = float(arcpy.GetParameter(1))
update_cursor = arcpy.da.UpdateCursor(rai, 'SHAPE@')
for row in update_cursor:
    array = arcpy.Array()
    for part in row[0]:
        for point in part:
            point.X += EWmove
            point.Y += NSmove
            array.add(point)

    new_line = arcpy.Polyline(array)
    row[0] = new_line
    update_cursor.updateRow(row)

del update_cursor
0 Kudos
JamesSmith7
Emerging Contributor
I skipped the geometry section once the word point was listed.  Since, I only intend to use Polylines, Polygons, and Annotations.  Your suggestion works well for one Polyline.  I am going to try and modify the script to work with multiple Polylines, Polygons, and Annotations(if possible).  Thanks.
0 Kudos
NeilAyres
MVP Alum
You don't actually have to update each vertex according to the Café Python page..
http://arcpy.wordpress.com/page/2/

just update the SHAPE@XY token instead, then the whole feature moves.

like :
with arcpy.da.UpdateCursor(in_features, ['SHAPE@XY']) as cursor:
    for row in cursor:
        cursor.updateRow([[row[0][0] + (x_shift or 0), row[0][1] + (y_shift or 0)]])


Cheers,
Neil
0 Kudos
MathewCoyle
Honored Contributor
You don't actually have to update each vertex according to the Café Python page..
http://arcpy.wordpress.com/page/2/

just update the SHAPE@XY token instead, then the whole feature moves.

like :
with arcpy.da.UpdateCursor(in_features, ['SHAPE@XY']) as cursor:
    for row in cursor:
        cursor.updateRow([[row[0][0] + (x_shift or 0), row[0][1] + (y_shift or 0)]])


Cheers,
Neil


That makes it much easier, good find.
0 Kudos