Select to view content in your preferred language

Text File to Lines using Python

838
2
06-22-2011 04:24 PM
by Anonymous User
Not applicable
I have a .csv file that I am reading in using python 2.5 in ArcGIS 9.3.1 and am having some issues with outputing the first line of the output shapefile.
It seems that the code runs OK but when I check it the first group of ids (#1) does not show up in the output but the last line of ids shows up twice.

Can't figure out why the first row is being omitted.

An extract of the python script I am using is as follows:

    for line in fileinput.input(infile): # Open the input file
        # Create a list of input values and set the point properties.
        values = string.split(line,",") #comma delimited
        #field values
        pnt.id = values[0]  #point ID (not FID or OID)
        pnt.x = values[1]   #x ak state plane 4 coord
        pnt.y = values[2]   #y ak state plane 4 coord
        pnt.z = values[3]   #z (TVD) true vertical depth
        #pnt.m = values[4]   #m (MD)  measured depth
        #print "values: " + str(pnt.id),str(pnt.x),str(pnt.y),str(pnt.z)

        if ID == -1:  # initial state
            ID = pnt.id
        # Add the point to the feature's array of points
        # If the ID has changed create a new feature
        if ID != pnt.id:
         # Create a new row or feature, in the feature class
            feat = cur.NewRow()
            # Set the geometry of the new feature to the array of points
            feat.shape = lineArray
            # Insert the feature
            feat.setvalue("ID",pnt.id)
            feat.setvalue("Z",pnt.z)
            cur.InsertRow(feat)
            lineArray.RemoveAll()

        #add point to point array
        if pnt.id != "0.100000E+31":
            lineArray.add(pnt)
            ID = pnt.id

    # Add the last feature
    feat = cur.NewRow()
    feat.shape = lineArray
    feat.setvalue("ID",pnt.id)
    feat.setvalue("Z",pnt.z)
    cur.InsertRow(feat)
Tags (2)
0 Kudos
2 Replies
by Anonymous User
Not applicable
I figured it out by using the tool script that I found in ArcGIS 10.0 toolbox albeit I was working in 9.3.1.

The code takes a point featureclass and converts it into lines and I modified it to work with reading a file.  My actual task was to read a Zmap file in and convert it into line contours.

Following is the ESRI code as found in the PointsToLines script tool:
#PointToLine.py script from ArcGIS 10.0 ArcCatalog Point to Line tool

import arcgisscripting
import os
import types

def convertPoints():
    gp = arcgisscripting.create(9.3)
    gp.OverWriteOutput = 1

    # Input point FC
    # Output FC
    # Feature Field
    # Sort Field
    # Close Line or Leave Open
    inPts       = gp.GetParameterAsText(0)
    outFeatures = gp.GetParameterAsText(1)
    IDField     = gp.GetParameterAsText(2)
    sortField   = gp.GetParameterAsText(3)
    closeLine   = gp.GetParameterAsText(4)

    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 closeLine.lower() == "false":
            close = False
        else:
            close = True

    convertPointsToLine(gp, inPts, outFeatures, IDField, cursorSort, close)

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

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

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

        # Create the output feature class
        #
        outPath, outFC = os.path.split(outFeatures)
        gp.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 = gp.ListFields(inPts, IDField)[0]
            tMap = {'Integer': 'LONG', 'String': 'TEXT', 'SmallInteger': 'SHORT'}
            fType = f.type
            if tMap.has_key(fType):
                fType = tMap[fType]
            fName = gp.ValidateFieldName(f.name, outPath)
            gp.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 = gp.InsertCursor(outFeatures)
        sCur = gp.SearchCursor(inPts, "", None, cursorSort, cursorSort)

        sRow = sCur.Next()

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

        # Initialize a variable for keeping track of a feature's ID.
        #
        ID = -1
        while sRow:
            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:
                    gp.AddIDMessage("WARNING", 1059, str(ID))
                                  
                array.RemoveAll()

            array.Add(pt)
            ID = currentValue
            sRow = sCur.Next()

        # 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:
            gp.AddIDMessage("WARNING", 1059, str(ID))
        array.RemoveAll()

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

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

if __name__ == '__main__':
    convertPoints()
    
0 Kudos
MatthewBarlow
Emerging Contributor
I thought I was experiencing the same problem, but upon investigation found that actually it wasn't skipping the first feature. As the feature ID is being set when the ID <> pnt.id, it has already stepped a bit too far and is assigning the next pnt.id to the previous feature.

To fix, simply assign a new variable to hold the values which are assigned when ID <> pnt.id (or currentValue, as I use). The key is where the values are being assigned to the variables (after the if "ID <> currentValue:" bit...):



        # Initialize a variable for keeping track of a feature's ID.
        #
        ID = -1
        while sRow:
            pt = sRow.GetValue(shapeName).GetPart(0)           
            currentValue = sRow.GetValue(IDField)
##            print currentValue

            if ID == -1:
                ID = currentValue

            if ID <> currentValue:
                if lineArray.count > 1:
                    feat = iCur.NewRow()
                    if ID: #in case the value is None/Null
                        feat.SetValue(IDField, seqIDV)
                        feat.SetValue("origID", oIDVal)
                        feat.SetValue("Color", ColorV)
                        feat.SetValue("GearType", GTypeV)
                    feat.SetValue(shapeName, lineArray)
                    iCur.InsertRow(feat)
                else:
                    gp.AddWarning("Not enough points to create a line for %s: %s" % (IDField, str(ID)))
                lineArray.RemoveAll()
            seqIDV = sRow.GetValue("seqID")
            oIDVal = sRow.GetValue("origID")
            ColorV = sRow.GetValue("Color")
            GTypeV =sRow.GetValue("GearType")

            lineArray.Add(pt)
            ID = currentValue
            sRow = sCur.Next()

        # Add the last feature... yada yada
0 Kudos