0

I need to update the whole table with the new values in SI. However when I start a new cursor, the list of values seems to go away and I cannot update each row with its corresponding value.

How can I do this?

import arcpy
import math

path = 'C:\\ProgInGIS\\FinalExam\\Final\\Hydro.gdb'
sindex = 'SINDEX'
arcpy.env.workspace = path

input_fc = arcpy.GetParameterAsText(0)
input_test = 'streams_gcs'

fcs = arcpy.ListFeatureClasses()
spat_ref = arcpy.Describe(input_test).spatialReference
if spat_ref.type == 'Projected':
    arcpy.AddMessage("{0} has {1} features. Using Planar calculations which differ from Geodesic".format(input_test, spat_ref.type))
if spat_ref.type == 'Geographic':
    arcpy.AddMessage("{0} has {1} features. Using Geodesic calculations which differ from Planar".format(input_test, spat_ref.type))
field_names = arcpy.ListFields(input_test)
for field in field_names:
    if field.name == sindex:
        arcpy.DeleteField_management(input_test, sindex)
        print('Deleted {0} field from {1}'.format(sindex, input_test))
arcpy.AddField_management(input_test, sindex, 'FLOAT')

with arcpy.da.SearchCursor(input_test, ['OID@', 'SHAPE@']) as cursor:
    for row in cursor:
        oid = row[0]
        shape = row[1]
        if shape.isMultipart is True:
            arcpy.AddError('There are multipart features present and no calculations can be performed')
            exit()
        channel = shape.length
        deltaX = shape.firstPoint.X - shape.lastPoint.X
        deltaY = shape.firstPoint.Y - shape.lastPoint.Y
        valley = math.sqrt(pow(deltaX, 2) + pow(deltaY, 2))
        si = round(channel / valley, 3)
        s_index = {oid, si}
        cursor2 = arcpy.da.UpdateCursor(input_test, [sindex])
        for row2 in cursor2:
            if row2[0] == 'None Type':
                print('yes')
                row2[0] = s_index[0]
                cursor2.updateRow(row2)
1
  • Replace to {oid:si} but code is not efficient. Do dictionary first in one go. Proceed with update cursor in next loop. If you need to remember si collection at all. Single update cursor will do.
    – FelixIP
    Apr 29, 2022 at 19:02

1 Answer 1

2

It looks like you are trying to put si in the sindex field but are trying to index it from set s_index={oid, si}? Sets do not support indexing and even if that were the case, it'd update it with the first index, oid.

sindex should be Null/None at the start of your cursor. Although you shouldn't even need it, I think you want

     if row2[0] is None

instead of

    if row2[0] == 'None Type'
    

Nonetheless, I think it's bad practice to nest a cursor inside of a cursor. Instead just use your With clause as the update cursor. Assuming your calculations check out and that the value of variable si is what you want to update in field sindex:

with arcpy.da.UpdateCursor(input_test, ['OID@', 'SHAPE@', sindex]) as cursor:
    for row in cursor:
        oid = row[0]
        shape = row[1]
        if shape.isMultipart:  # isMultipart returns True/False, so you don't need to evaluate if True is True
            # do not calculate/update sindex;
            arcpy.AddError('There are multipart features present and no calculations can be performed')
        else:
            channel = shape.length
            deltaX = shape.firstPoint.X - shape.lastPoint.X
            deltaY = shape.firstPoint.Y - shape.lastPoint.Y
            valley = math.sqrt(pow(deltaX, 2) + pow(deltaY, 2))
            si = round(channel / valley, 3)
            row[2] = si
            cursor.updateRow(row)

I'm not sure if multipoint can be mixed with regular point in the same feature class. In which case, there are probably better ways to evaluate that, before the cursor.

3
  • You are genius!! This works. I had a feeling the search cursor was messing me up. Apr 29, 2022 at 19:14
  • Glad to hear you got it working!
    – Ebingsya
    Apr 29, 2022 at 19:27
  • If answer helped you solve you problem, it's customary on GIS SE site to mark it as accepted, to let others with similar problems know that problem was resolved.
    – TomazicM
    Apr 29, 2022 at 19:35

Your Answer

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

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