Select to view content in your preferred language

How to: Read value from "Shape_Length" field, create table that increments from 0 to "Shape_Length" value.

2589
12
06-04-2020 07:58 AM
ConnorMcivor
Occasional Contributor

Hello,

I am writing a script and a portion of said script requires that I build a table that starts at 0 and increments by 1 until reaching the value of "Shape_Length" from a feature class. I have line work that I wish to read the "Shape_Length" from and I am having troubles getting the syntax correct.

Route = arcpy.CreateRoutes_lr(Input_Linework, Linework_Field, Output_Name)

# Store value in SHAPE_LENGTH from Route
with arcpy.da.SearchCursor(Route, ['Shape_Length']) as cursor:
    for row in Cursor:
        Max_Value   = row.getValue('Shape_Length')
del row
del cursor
    
# Create table with two fields, RouteID and Chainage
Route_Table     = arcpy.CreateTable_management(str(Output_WS), Output_Name))

# Append additional rows to table in increments of 1 and end at the exact value of
# the Max_Value
fields          = ['RouteID', 'Chainage']
Pop_Table       = arcpy.da.InsertCursor(Route_Table, fields)
for x in range(0, Max_Value):
    Pop_Table.insertRow(str(Linework_Field), x)
del x‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I get an error on line 6:

AttributeError: 'tuple' object has no attribute 'getValue'

I have tried reading through the page:

Accessing data using cursors—Help | ArcGIS Desktop 

I messed around with the code a bit but this is where I am at now and can't determine how to move forward.

0 Kudos
12 Replies
ConnorMcivor
Occasional Contributor

Sorry Joe for the late response. To clarify, I was stuck on one portion of the presented code snippet then got stuck on the next. I have both issues mentioned earlier. I am not sure if I should start a new thread or not for a new error I have though. I figured out how to populate the table with the values i needed. The next step was to "Make Route Events" out of them. The results are interesting: The table population works like I said, containing all values required. However when I attempt to make them into route events, the result shows only 1001 records if between 0 - 2002, and will show 2002 of the records if between 2002 and 4008 records. Simply, I have a table that includes the RouteID field and measure/chainage values from 0 - 2768, when the script runs, it will only show up to the 2002nd measure/chainages. When I run the "Make Route Events" tool outside of the script, everything runs fine, and shows all 2768 records. I have attempted a "Table to table" conversion prior to running the "Make Route Events" however that did not solve my problem. If this requires a new thread please correct me.

0 Kudos
ConnorMcivor
Occasional Contributor

***I have corrected both issues mentioned earlier***

0 Kudos
MarkBryant
Regular Contributor

Conor,
You need to nest your cursors,  rather than having two separate cursors. Otherwise you just get the Max_Value from the last row for the route table.

def frange(start, stop, step):
    """Range function that works with floats"""
    r = start
    while r < stop:
        yield r
        if step > 0:
            r += step
        else:
            r -= step

def main_snippet():
    """ main processing snip"""
    in_routes = arcpy.lr.CreateRoutes(Input_Linework, Linework_Field, Output_Name)
    # Create table with two fields, RouteID and Chainage
    route_table = arcpy.management.CreateTable(str(Output_WS), Output_Name)
    # add the fields. Missing in your script
    arcpy.management.AddField(route_table, 'RouteID', 'TEXT', field_length=15)
    arcpy.management.AddField(route_table, 'Chainage', 'DOUBLE')

    # Populate event table using cursors
    search_fields = [Linework_Field, "SHAPE@"]
    update_fields = ['RouteID', 'Chainage']
    # increments of 1
    measure_interval = 1

    with arcpy.da.InsertCursor(route_table, update_fields) as icursor:
        with arcpy.da.SearchCursor(in_routes, search_fields) as cursor:
            for row in cursor:
                # read the geometry
                line = row[1]
                # use the measures
                first_measure = float(line.firstPoint.M)
                last_measure = float(line.lastPoint.M)
                # step thru the meaures, by measure_interval
                for measure in frange(first_measure, last_measure, measure_interval):
                    # insert value into route_table
                    icursor.insertRow((row[0], measure))
    print('Done.')
Mark.
0 Kudos