Points to Line modification v10

323
1
05-23-2012 01:33 PM
MathewCoyle
Frequent Contributor
I am attempting to add some functionality to the basic points to line tools script that will allow for a new optional parameter that will limit the maximum distance between points to draw a line.

I took the code and converted it to arcpy v10.0 just so everything is on the same page, and that worked fine. I am just having a bit of trouble figuring out the best way to go about the next step. Would it be best to check if each point is a certain euclidean distance from the previous point, or after the lines have all been drawn, to simply split the feature at line lengths above the threshold.

Any input would be appreciated, I've pasted the code below as well as attached it with the script tool parameters.

import arcpy
import os
#import types

def convertPoints():
    arcpy.env.overwriteOutput = True

    # Input point FC
    # Output FC
    # Feature Field
    # Sort Field
    # Close Line or Leave Open
    # Max line length to join
    inPts       = arcpy.GetParameterAsText(0)
    outFeatures = arcpy.GetParameterAsText(1)
    IDField     = arcpy.GetParameterAsText(2)
    sortField   = arcpy.GetParameterAsText(3)
    closeLine   = arcpy.GetParameterAsText(4)
    maxLine     = arcpy.GetParameterAsText(5)

    if IDField in ["", "#"]: IDField = None

    if sortField in ["", "#"]:
        cursorSort = IDField
    else:
        if IDField:
            cursorSort = IDField + ";" + sortField
        else:
            cursorSort = sortField

    #if types.TypeType(closeLine) != types.BooleanType:
    if type(closeLine) != bool:
        if closeLine.lower() == "false":
            close = False
        else:
            close = True

    if maxLine in ["", "#"]:
        maxLine = None
    else:
        if type(maxLine) == float:
            maxLine = float(maxLine)
        elif type(maxLine) == int:
            maxLine = int(maxLine)

    convertPointsToLine(arcpy, inPts, outFeatures, IDField, cursorSort, close, maxLine)

def enableParam(hasMZ):
    if hasMZ:
        return "ENABLED"
    else:
        return "DISABLED"

def convertPointsToLine(arcpy, inPts, outFeatures, IDField, cursorSort, close, maxLine):
    try:
        # Assign empty values to cursor and row objects
        iCur, sRow, sCur, feat = None, None, None, None

        desc = arcpy.Describe(inPts)
        shapeName = desc.ShapeFieldName

        # Create the output feature class
        #
        outPath, outFC = os.path.split(outFeatures)
        arcpy.CreateFeatureclass_management(outPath, outFC, "POLYLINE", "",
                                         enableParam(desc.hasM),
                                         enableParam(desc.hasZ),
                                         inPts)

        # If there is an IDField, add the equivalent to the output
        #
        if IDField:
            f = arcpy.ListFields(inPts, IDField)[0]
            tMap = {'Integer': 'LONG', 'String': 'TEXT', 'SmallInteger': 'SHORT'}
            fType = f.type
            if tMap.has_key(fType):
                fType = tMap[fType]
            fName = arcpy.ValidateFieldName(f.name, outPath)
            arcpy.AddField_management(outFeatures, fName, fType, f.precision, f.scale, f.length,
                                   f.aliasName, f.isNullable, f.required, f.domain)

        # Open an insert cursor for the new feature class
        #
        iCur = arcpy.InsertCursor(outFeatures)
        sCur = arcpy.SearchCursor(inPts, "", None, cursorSort, cursorSort)

        #sRow = sCur.Next()

        # Create an array and point object needed to create features
        #
        array = arcpy.CreateObject("Array")
        pt = arcpy.CreateObject("Point")

        # Initialize a variable for keeping track of a feature's ID.
        #
        ID = -1
        for sRow in sCur:
            pt = sRow.getValue(shapeName).getPart(0)
            if IDField:
                currentValue = sRow.getValue(IDField)
            else:
                currentValue = None

            if ID == -1:
                ID = currentValue

            if ID <> currentValue:
                if array.count >= 2:

                    # To close, add first point to the end
                    #
                    if close:
                        array.add(array.getObject(0))

                    feat = iCur.newRow()
                    if IDField:
                        if ID: #in case the value is None/Null
                            feat.setValue(IDField, ID)
                    feat.setValue(shapeName, array)
                    iCur.insertRow(feat)
                else:
                    arcpy.AddIDMessage("WARNING", 1059, str(ID))

                array.removeAll()

            array.add(pt)
            ID = currentValue

        # Add the last feature
        #
        if array.count > 1:
            # To close, add first point to the end
            #
            if close:
                array.add(array.getObject(0))

            feat = iCur.newRow()
            if IDField:
                if ID: #in case the value is None/Null
                    feat.setValue(IDField, currentValue)
            feat.setValue(shapeName, array)
            iCur.insertRow(feat)
        else:
            arcpy.AddIDMessage("WARNING", 1059, str(ID))
        array.removeAll()

    except Exception as err:
        arcpy.AddError(err.message)

    finally:
        if iCur:
            del iCur
        if sRow:
            del sRow
        if sCur:
            del sCur
        if feat:
            del feat

if __name__ == '__main__':
    convertPoints()
Tags (2)
0 Kudos
1 Reply
MathewCoyle
Frequent Contributor
I got what changes I wanted to work. A few little problems left. If both the maxline and close line or id field options are set, how to handle closing/ending each line segment.

This works fine for simple point to line construction using a maxline variable though, which is all I need for now. Hopefully someone else can get some use out of it too.
0 Kudos