3

I'm working on a python toolbox tool that creates offset points along a polyline via the arcpy.CreateRoutes_lr() tool and arcpy.MakeRouteEventLayer_lr(). The tool simplifies the process by constructing a GPTable for the Offset Table and allowing the user to insert their "Offset Left" and "Offset Right" values as input parameters. The table's row length is equal to the polyline length so that there is 1 row for every 1 meter of length along the polyline. The table also has the appropriate Field Name and Data Types.

If I run these steps in the python console in ArcMap everything works as expected and there is an offset point at every 1m step along the polyline.

When I run this script from my python toolbox the number of offset points is rounded down to the nearest 1000th place + the number of km. In other words: A shape length of 1458 yields 1001 points each (left and right offsets); 4777m polyline gets me 4004 offset points each.

I have no idea why this is happening.

ArcMap Version 10.3.1 Python 2.7

enter image description here

import os
import sys
import arcpy


class Toolbox(object):
def __init__(self):
    """Define the toolbox (the name of the toolbox is the name of the
    .pyt file)."""
    self.label = "Toolbox"
    self.alias = ""

    # List of tool classes associated with this toolbox
    self.tools = [CrossSection]

class CrossSection(object):
def __init__(self):
    """Define the tool (tool name is the name of the class)."""
    self.label = "2. Create Cross Sections from Routed Centerline"
    self.description = "Create cross section polylines along the routed 
    valley centerline."
    self.canRunInBackground = False

def getParameterInfo(self):
    inputFC = arcpy.Parameter(
        displayName = "Input Routed Centerline Feature Class",
        name = "RoutedCenterline",
        datatype = "DEFeatureClass",
        parameterType = "Required",
        direction = "Input")

    routeFIELD = arcpy.Parameter(
        displayName = "Select Route Field Name",
        name = "RouteField",
        datatype = "Field",
        parameterType = "Required",
        direction = "Input")
    routeFIELD.filter.list =["LONG"]
    routeFIELD.parameterDependencies = [inputFC.name]

    routeID = arcpy.Parameter(
        displayName = "Select Centerline Route ID",
        name = "RouteId",
        datatype = "GPLong",
        parameterType = "Required",
        direction = "Input")
    routeID.filter.type = "ValueList"
    routeID.filter.list = []

    offsetLEFT = arcpy.Parameter(
        displayName = "Input Offset Left Value",
        name = "OffsetLeft",
        datatype = "GPLong",
        parameterType = "Required",
        direction = "Input")

    offsetRIGHT = arcpy.Parameter(
        displayName = "Input Offset Right Value",
        name = "OffsetRight",
        datatype = "GPLong",
        parameterType = "Required",
        direction = "Input")

    drawDIRECTION= arcpy.Parameter(
        displayName = "Direction to Start Stationing From",
        name = "DrawDirection",
        datatype = "GPString",
        parameterType = "Required",
        direction = "Input")
    drawDIRECTION.filter.type = "ValueList"
    drawDIRECTION.filter.list = ["UPPER_LEFT", "UPPER_RIGHT", "LOWER_LEFT", "LOWER_RIGHT"]

    params = [inputFC, routeFIELD, routeID, offsetLEFT, offsetRIGHT, drawDIRECTION]
    return params

def isLicensed(self):
    """Set whether tool is licensed to execute."""
    return True

def updateParameters(self, parameters):
    if parameters[1].value:  
        with arcpy.da.SearchCursor(parameters[0].valueAsText, parameters[1].valueAsText) as rows:  
            parameters[2].filter.list = sorted(list(set([row[0] for row in rows])))  
    else:  
        parameters[2].filter.list = []
    return

def updateMessages(self, parameters):
    return

def execute(self, parameters, messages):
    arcpy.ResetEnvironments()


    #Add Products to Map
    arcpy.env.addOutputsToMap = True

    #SET LOCAL VARIABLES
    input_fc = parameters[0].valueAsText
    route_field = parameters[1].valueAsText
    route_id = parameters[2].valueAsText
    off_left = parameters[3].valueAsText
    off_right = parameters[4].valueAsText
    draw_direction = parameters[5].valueAsText
    fc_routed = input_fc + "_RT"
    offset_table = "Offset_Table"
    table_rename = input_fc + offset_table
    off_left_ly = input_fc + "_Left"
    off_right_ly = input_fc + "_Right"
    offset_merged = input_fc+"_Offsets_Merged"
    fc_xsec = input_fc + "_Xsec"

    #SET PATHS
    ws = arcpy.env.workspace
    sw = arcpy.env.scratchWorkspace

    #CREATE ROUTES ALONG THE CENTERLINE "FIXED VARIABLES"
    arcpy.CreateRoutes_lr(input_fc, route_field, fc_routed, "LENGTH", "", "", draw_direction, "", "", "IGNORE", "NO_INDEX")

    #Create Table
    arcpy.CreateTable_management(ws,offset_table)

    #Add Fields
    arcpy.AddField_management(offset_table, "LOCATION", "LONG")
    arcpy.AddField_management(offset_table, "OFFSET_LEFT", "LONG")
    arcpy.AddField_management(offset_table, "OFFSET_RIGHT", "LONG")
    arcpy.AddField_management(offset_table, "NAME", "LONG")

    #Extract values from Centerline Polyline and create variable with desired row length
    fields_shapelength = ['shape_length', 'shape_Length', 'shape_LENGTH', 'Shape_length', 'Shape_Length', 'Shape_LENGTH', 'SHAPE_length', 'SHAPE_Length', 'SHAPE_LENGTH',]
    cursor_shapelength = arcpy.da.SearchCursor(input_fc, fields_shapelength,).next()[0]
    length_fc = int(cursor_shapelength)

    fields_name = ['name', 'Name', 'NAME']
    cursor_name =  arcpy.da.SearchCursor(input_fc, fields_name,).next()[0]

    #Append Extracted Values to Offset_Table
    fields_table = ["LOCATION", "OFFSET_LEFT", "OFFSET_RIGHT", "NAME"]
    cursor = arcpy.da.InsertCursor(offset_table, fields_table)
    for x in xrange(1, length_fc):
        cursor.insertRow((x, off_left, off_right, route_id, ))

    #MAKE ROUTE EVENT LAYERS
    arcpy.MakeRouteEventLayer_lr(fc_routed, route_field, offset_table, "NAME POINT LOCATION", off_left_ly, "OFFSET_LEFT","NO_ERROR_FIELD","NO_ANGLE_FIELD","NORMAL","ANGLE","LEFT","POINT")
    arcpy.MakeRouteEventLayer_lr(fc_routed, route_field, offset_table, "NAME POINT LOCATION", off_right_ly, "OFFSET_RIGHT","NO_ERROR_FIELD","NO_ANGLE_FIELD","NORMAL","ANGLE","LEFT","POINT")

    #MERGE OFFSETS
    arcpy.Merge_management([off_left_ly,off_right_ly], offset_merged, "")

    #Convert Points to Lines
    arcpy.PointsToLine_management(offset_merged, fc_xsec, "LOCATION", "LOCATION")
    return
0

Turns out that I had an open cursor. A simple del(cursor) solved the problem.

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.