In a given city a line is constructed, and for every building in that city it is required to know the distance to that line. Therefore the .distanceTo method from the ArcPy Geometry class is used. It is also required that this distance is multiplied by 1.2.

The following code is written using ArcPy (10.4):

from arcpy import *

# A new attribute is first created to populate the distances with
AddField_management('buildings', 'distanceField', 'LONG')

buildingCursor = UpdateCursor('buildings', '#', '#', ['SHAPE@'])
lineCursor = SearchCursor('line', '#', '#', ['SHAPE@'])

for building in buildingCursor:
    buildingGeometry = buildingCursor[0]
    lineGeometry = lineCursor[0]
    distance = buildingGeometry.distanceTo(lineGeometry) * 1.2
    building.setValue('distanceField', distance)

del buildingCursor, lineCursor, building

The code returns an error. The error message is:

AttributeError: Object: Error in parsing arguments for UpdateCursor

How can I make this code work as intended?

  • 1
    change your distanceField type from LONG to FLOAT.
    – Delonix R.
    Aug 8 '17 at 14:15

So first of all you're using the old arcpy.UpdateCursor / arcpy.SearchCursor. The new ones are a lot faster and less prone to cause errors. But be aware that the syntax changed (see ArcGIS online help for details).

I assume that your "line" feature class only contains one line and does not need to be iterated. If this is correct, the following code should work:

import arcpy

# A new attribute is first created to populate the distances with
arcpy.AddField_management('buildings', 'distanceField', 'FLOAT')

lCursor = arcpy.da.SearchCursor('line', ['SHAPE@'])
lineGeometry = lCursor[0]

with arcpy.da.UpdateCursor('buildings', ['SHAPE@', 'distanceField']) as bCursor:
    for building in bCursor:
        buildingGeometry = building[0]
        distance = buildingGeometry.distanceTo(lineGeometry) * 1.2
        building[1] = distance[0]

del lineCursor

Note the following:

  • the use of the with arcpy.da.UpdateCursor() statement makes the closing of the cursor unnecessary.
  • it is sufficient to use the line cursor to read the geometry once only, there is no need to put it inside the UpdateCursor.
  • as Delonix R. mentioned in his comment, you should use a FLOAT field instead of a LONG field, as LONG can only store integer numbers.
  • by adding the newly created 'distanceField' field to your cursor you can directly modify it, without the use of the .setValue() function.

  • in your original code there is no need for the '#', you may use empty ''.

  • Thank you for your answer. I implemented your solution. However, it returns the following error message: Traceback (most recent call last): File "C:\script.py", line 1654, in <module> lineGeometry = lCursor[0] SystemError: error return without exception set. As for the line geometry, it is indeed a single line (although multipart).
    – Rob G
    Aug 8 '17 at 19:41
  • 1
    building[1] = distance will fail because it's a tuple. bCursor.updateRow((buildingGeometry, distance)) will work.
    – Paul
    Aug 9 '17 at 0:10
  • building[1] = distance[0] should do the trick too. I updated my answer.
    – dru87
    Aug 9 '17 at 6:02

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.