-2

I have been working on this code for awhile and I can't make it work the way I need it to. The code is suppose to move a feature according to a set distance from types in a designated field. As the code is now the point features move at the angle and distance for elif Type == 'Type2': distance = .707107

in the code below. The problem might be the updateCursor or in_features causing the if statement to be ignored. I am still new to python and arcpy but I would like to get this code to work.

import arcpy, os, sys
from math import radians, sin, cos

arcpy.env.workspace = "C:/data"
arcpy.env.overwriteOutput = True

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

    infc = "Point.shp"
    rows = arcpy.SearchCursor(infc)
    for row in rows:
        x = row.Easting
        y = row.Northing
        Type = row.feat_Type
        if Type == 'Type1':
            distance = .3535535 

        elif Type == 'Type2':
            distance = .707107

        else:
            print Type

    shift_features(infc, distance * sin(radians(45)), distance * cos(radians(45)))

#Variables for creating the XY event
infc = r'Database Connections\Test.odc\Units'
x_coords = "Easting"
y_coords = "Northing"
z_coords = ""

out_Layer = "points_layer"
Saved_Layer = "Point.shp"

# Add a spatial reference to the new shapefile
prjfile = "C:/data/LocalGrid.prj"
spRef = arcpy.SpatialReference(prjfile)

# Make the XY event layer...
arcpy.MakeXYEventLayer_management(infc, x_coords, y_coords, out_Layer, spRef, z_coords)
arcpy.CopyFeatures_management(out_Layer, Saved_Layer)
move()


# Print feature count and messages
print arcpy.GetMessages()

Also I am using ArcGIS 10.2.1


Here is the new code, it looks like it is actually skipping the shift_features function. Also, I have tried taking it out of the def move(): function but I get the same results.

import arcpy, os, sys
from math import radians, sin, cos

arcpy.env.workspace = "C:/data"
arcpy.env.overwriteOutput = True

def move():
    def shift_features(in_features):
        with arcpy.da.UpdateCursor(in_features, ('SHAPE@XY', 'feat_type')) as cursor:
            for row in cursor:
                if row[1] == 'Type1':
                    distance = .3535535 
                elif row[1] == 'Type2':
                    distance = .707107 
                else:
                    print row[1]
                    distance = 0 
                cursor.updateRow([[row[0][0] + distance * sin(radians(45)), row[0][1] + distance * cos(radians(45))]])
    return 0
    infc = "Point.shp"
    shift_features(infc)

#Variables for creating the XY event
infc = r'Database Connections\Test.odc\Units'
x_coords = "Easting"
y_coords = "Northing"
z_coords = ""

out_Layer = "points_layer"
Saved_Layer = "Point.shp"

# Add a spatial reference to the new shapefile
prjfile = "C:/data/LocalGrid.prj"
spRef = arcpy.SpatialReference(prjfile)

# Make the XY event layer...
arcpy.MakeXYEventLayer_management(infc, x_coords, y_coords, out_Layer, spRef, z_coords)
arcpy.CopyFeatures_management(out_Layer, Saved_Layer)
move()


# Print feature count and messages
print arcpy.GetMessages()

3 Answers 3

2

it seems that your shift_feature is applied after the loop of your search cursor, so only the last value is used and applied for all your features.

What I recommend is to avoid using 2 cursors when you can do it with one cursor.

    def shift_features(in_features):
        with arcpy.da.UpdateCursor(in_features, ('SHAPE@XY', 'feat_type')) as cursor:
            for row in cursor:
                if row[1] == 'Type1':
                    distance = .3535535 
                elif row[1] == 'Type2':
                    distance = .707107 
                else:
                    print row[1]
                    distance = 0 
                cursor.updateRow([[row[0][0] + distance * sin(radians(45)), row[0][1] + distance * cos(radians(45))]], row[1])
            del cursor
       return 0
2
  • I changed the code but the points are not shifting, and the else: statement does not print. I kept the original code the same but just changed the UpdateCursor (def shift_features) to one cursor.
    – marion
    Apr 7, 2014 at 17:30
  • please edit your question with your new code.
    – radouxju
    Apr 7, 2014 at 20:08
1

I am going to focus on the part of your code with the shift_features function, since I can reproduce what you are trying to do there. Firstly, I don't think you need to have a def within a def, and so you could keep it simpler by removing one of them. And, though you provide for a feature class to be passed to shift_features, you then set it within the move() module, which does not allow you to pass a different feature class because it is hard-coded in your module.

Here is some code that I was able to get to shift my points by the amount specified. This code worked in the python window in ArcMap on an arbitrary shapefile (that I called "Points.shp".)

def shift_features(in_features):
    with arcpy.da.UpdateCursor(in_features, ('SHAPE@XY', 'feat_type')) as cursor:
        for row in cursor:
            if row[1] == 'Type1':
                distance = .3535535
            elif row[1] == 'Type2':
                distance = .707107
            else:
                print row[1]
                distance = 0
            xshift = row[0][0] + distance * math.sin(math.radians(45))
            yshift = row[0][1] + distance * math.cos(math.radians(45))
            row[0] = [xshift, yshift]
            cursor.updateRow(row)

I separated out some things so I could debug better. I can't verify whether the rest of your code works, but here is how I would insert this into your other code:

import arcpy, os, sys, math

arcpy.env.workspace = "C:/data"
arcpy.env.overwriteOutput = True

def shift_features(in_features):
    with arcpy.da.UpdateCursor(in_features, ('SHAPE@XY', 'feat_type')) as cursor:
        for row in cursor:
            if row[1] == 'Type1':
                distance = .3535535
            elif row[1] == 'Type2':
                distance = .707107
            else:
                print row[1]
                distance = 0
            xshift = row[0][0] + distance * math.sin(math.radians(45))
            yshift = row[0][1] + distance * math.cos(math.radians(45))
            row[0] = [xshift, yshift]
            cursor.updateRow(row)

#Variables for creating the XY event
infc = r'Database Connections\Test.odc\Units'
x_coords = "Easting"
y_coords = "Northing"
z_coords = ""

out_Layer = "points_layer"
Saved_Layer = "Point.shp"

# Add a spatial reference to the new shapefile
prjfile = "C:/data/LocalGrid.prj"
spRef = arcpy.SpatialReference(prjfile)

# Make the XY event layer...
arcpy.MakeXYEventLayer_management(infc, x_coords, y_coords, out_Layer, spRef, z_coords)
arcpy.CopyFeatures_management(out_Layer, Saved_Layer)
shift_features(Saved_Layer)


# Print feature count and messages
print arcpy.GetMessages()
1
  • Also, I imported the math lib and then used math.sin, math.cos, and math.radians, but the way you do it works too (from math import sin, radians). I meant to change that back.
    – jencarta
    Apr 8, 2014 at 15:54
-1

As far as I am concerned wrapping the function in another function is not necessary, so 'def move():' and can be removed. Then you should pass an existing object to your function "shift_features", which accepts one parameter ("in_features"). For example:

shift_features(Saved_Layer)
3
  • I did that and now I get: TypeError: sequence size must match size of the row for cursor.updateRow([[row[0][0] + distance * sin(radians(45)), row[0][1] + distance * cos(radians(45))]])
    – marion
    Apr 8, 2014 at 14:27
  • I recommend you first calclate the x and y shift and then pass the values into the updateCursor. So something like: cursor.updateRow([[row[0][0] + (x_shift or 0), row[0][1] + (y_shift or 0)]])
    – G-wizard
    Apr 8, 2014 at 16:42
  • Please let us know what the problem was and how you solved it.
    – G-wizard
    Apr 10, 2014 at 17:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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