Select to view content in your preferred language

cycling through vertices of lines in python (arcgisscripting)

1284
4
09-08-2010 06:36 PM
TimBarnes
Frequent Contributor
Hi there- Im trying to write a script to convert polylines into XML text files for use in another program- Problem is, I can't get the script to iterate my vertex count. Other counts iterate OK (i.e. denseList), just not this one (altIndex)- It cycles through the correct number of vertices in the line, but the count doesn't increase.

Any ideas? (I've highlighted the relevant part of the script)

# ---------------------------------------------------------------------------
....Header....

# Local variables...
inFC = gp.GetParameterAsText(0)

# Variables to extract information from attribute table
colSuppress = gp.GetParameterAsText(1)
colWidth = gp.GetParameterAsText (2)
colExtrusion = gp.GetParameterAsText(3)
colMaterial = gp.GetParameterAsText (4)
colVertices = gp.GetParameterAsText (5)
out = gp.getParameterAsText(6)

# XML variables needed for formatting
tab = ' '
tabTab = ' ' + ' '
tabTabTab = ' ' + ' ' + ' '
tabTabTabTab = ' ' + ' ' + ' ' + ' '

# List array variables
# List containing values to cycle through for scenery density. Set to the first item initially.
denseList = ['VERY_SPARSE','SPARSE','NORMAL','DENSE','VERY_DENSE']
denseIndex = 0

# Identify the geometry field
desc = gp.Describe(inFC)
shapefieldname = desc.ShapeFieldName

# Create and open output file
outFile = open(out, "w")
# Write XML header
outFile.write('<?xml version="1.0" encoding="iso-8859-1"?>'+ '\n')
outFile.write('<!--Created for VectorLandClass -->'+ '\n')
outFile.write(str('<FSData')+ "\n")
outFile.write(str(tab) + 'version="9.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'+ '\n')
outFile.write(str(tab) + 'xsi:noNamespaceSchemaLocation="bglcomp.xsd">'+ '\n')

# Create search cursor to search through line features in the input feature class
rows = gp.SearchCursor(inFC)
row = rows.Next()

# Create a
# Enter while loop for each feature/row
while row :
    # Create the geometry object 'feat'
    feat = row.GetValue(shapefieldname)
    # Extract row attributes from precalculated columns in the attribte table accessed via a searchcursor
    numVertices = row.GetValue(colVertices)
    suppress = row.GetValue(colSuppress)
    width = row.GetValue(colWidth)
    extru = row.GetValue(colExtrusion)
    material = row.GetValue(colMaterial)

    line = row.shape
    density = denseList[denseIndex]
    
    # define variable firstPnt as the FirstPoint object of the line
    firstPnt = line.FirstPoint
    # define variable middlePnt as the Centroid object of the line
    middlePnt = line.Centroid
    # define variable lastPnt as the LastPoint object of the line
    lastPnt = line.LastPoint

    # Write the first part of the ExtrusionBridge XML tag
    outFile.write(str(tab)+ '<ExtrusionBridge' + '\n')
    outFile.write(str(tabTab) + 'instanceId="{00000000-0000-0000-0000-000000000000}"' + '\n')
    outFile.write(str(tabTab) + 'probability = "0.5"'+ '\n')
    outFile.write(str(tabTab) + 'suppressPlatform= "' + str(suppress)+ '"'+ '\n')
    outFile.write(str(tabTab) + 'imageComplexity= "'+ str(density) + '"' + '\n')
    outFile.write(str(tabTab) + 'roadWidth= "' + str(width) + '"' + '\n')
    outFile.write(str(tabTab) + 'extrusionProfile="'+ str(extru) + '"'+ '\n')
    outFile.write(str(tabTab) + 'materialSet="' + str(material) + '">'+ '\n')

    # Write to the Altitude sample location tag
    #gp.AddMessage('<AltitudeSampleLocationList>')
    outFile.write(str(tabTab) +'<AltitudeSampleLocationList>'+ '\n')
    # Add a message giving a string of the first points coordinates. This is the altitude reference point 1
    #gp.AddMessage('<AltitudeSampleLocation lat="' + str(firstPnt.x) + '" lon="' + str(firstPnt.y) +'"/>')
    outFile.write(str(tabTabTab) +'<AltitudeSampleLocation' + '\n') 
    outFile.write(str(tabTabTabTab) + 'lat="' + str(firstPnt.x) + '" \n')
    outFile.write(str(tabTabTabTab) + 'lon="' + str(firstPnt.y) +'" />'+ '\n')             
    # Add a message giving a string of the last points coordinates. This is the altitude reference point 2
    #gp.AddMessage('<AltitudeSampleLocation lat="' + str(lastPnt.x) + '" lon="' + str(lastPnt.y) +'"/>')
    outFile.write(str(tabTabTab) +'<AltitudeSampleLocation' + '\n') 
    outFile.write(str(tabTabTabTab) + 'lat="' + str(lastPnt.x) + '" \n')
    outFile.write(str(tabTabTabTab) + 'lon="' + str(lastPnt.y) +'" />'+ '\n')
    
    # Add closing tag
    #gp.AddMessage('</AltitudeSampleLocationList>')
    outFile.write(str(tabTab) + '</AltitudeSampleLocationList>'+ '\n')

    # Open the the Polyline point list tag
    gp.AddMessage("Feature " + str(row.getvalue(desc.OIDFieldName)) + ":")
    gp.AddMessage('This line has ' + str(numVertices) + ' vertices according to the attribute table')
    #gp.AddMessage('<PolylinePointList>')
    outFile.write(str(tabTab) +'<PolylinePointList>'+ '\n')

    # Set the part number to zero initially and set the variable partcount
    partnum = 0
    partcount = feat.PartCount
    while partnum < partcount:
        # Print the part number
        gp.AddMessage( "Line Part " + str(partnum) + ":")
        part = feat.GetPart(partnum)
        pnt = part.Next()
        pntcount = 0

        # Define the altitude list to be used for bridges with over 2 vertices
        altList = ['1','2','3','4','5','6','5','4','3','2','1']
        altIndex = 0
        altitude = altList[altIndex]
        
    # Enter while loop for each vertex depending on the number of vertices
    # If bridge only has 2 vertices, construct feature using first, last and centroid and standard alt list
        if numVertices == 2:
            # write first point set using the firstPnt variable and a standard altitude
            #gp.AddMessage('<PolylinePoint latitude="' + str(firstPnt.x) + '" lon="' + str(firstPnt.y) +'" altitude="-1.00"/>')
            outFile.write(str(tabTabTab) +'<PolylinePoint' +  '\n')
            outFile.write(str(tabTabTabTab) + 'latitude="' + str(firstPnt.x) + '"'+ '\n')
            outFile.write(str(tabTabTabTab) + 'longitude="' + str(firstPnt.x) + '"' + '\n')
            outFile.write(str(tabTabTabTab) + 'altitude="-2M" />' + '\n')
            # write mid point set using the middlePnt variable and a standard altitude
            #gp.AddMessage('<PolylinePoint latitude="' + str(middlePnt.x) + '" lon="' + str(middlePnt.y) +'" altitude="4.00"/>')
            outFile.write(str(tabTabTab) +'<PolylinePoint' + '\n')
            outFile.write(str(tabTabTabTab) + 'latitude="' + str(middlePnt.x) + '"' + '\n')
            outFile.write(str(tabTabTabTab) + 'longitude="' + str(middlePnt.x) + '"' + '\n')
            outFile.write(str(tabTabTabTab) + 'altitude="4M" />' + '\n')
            # write last point set using the lastPnt variable and a standard altitude
            #gp.AddMessage('<PolylinePoint latitude="' + str(lastPnt.x) + '" lon="' + str(lastPnt.y) +'" altitude="-1.00"/>')
            outFile.write(str(tabTabTab) +'<PolylinePoint' +  '\n')
            outFile.write(str(tabTabTabTab) + 'latitude="' + str(lastPnt.x) + '"' + '\n')
            outFile.write(str(tabTabTabTab) + 'longitude="' + str(lastPnt.x) + '"' + '\n')
            outFile.write(str(tabTabTabTab) + 'altitude="-2M" />' +  '\n')
        # If bridge has more than than 2 vertices do something else.    
        else:
            while pnt:
                # count number of vertices assign it to verts variable. Do this by checking if pnt exists. If not, counting has finished.
                pntcount += 1
                # Define the varibles coordX and coordY as the x and y of 'pnt'
                coordX = pnt.x
                coordY = pnt.y
                # Cycle through each vertice and write polyline point tag
                #gp.AddMessage('<PolylinePoint latitude="' + str(coordY) + '" lon="' + str(coordX) + ' altitude="' + str(altitude)+ '"/>')
                outFile.write(str(tabTabTab) +'<PolylinePoint' + '\n')
                outFile.write(str(tabTabTabTab) + 'latitude="' + str(coordX) + '"' + '\n')
                outFile.write(str(tabTabTabTab) + 'longitude="' + str(coordY) + '"' + '\n')
                outFile.write(str(tabTabTabTab) + 'altitude="' + str(altitude)+ 'M" />'+ '\n')
                # Iterate through altitude list
                altIndex =+1
                if altIndex == 6:
                    altIndex = 0
                pnt = part.Next()
        partnum += 1
        
    # Close polyline point list tag
    #gp.AddMessage('</PolylinePointList>')
    outFile.write(str(tabTab) +'</PolylinePointList>'+ '\n')
    # write polylineObjectPlacementList XML
    #gp.AddMessage('<PolylineObjectPlacementList>')
    outFile.write(str(tabTab) +'<PolylineObjectPlacementList>'+ '\n')
    # write placement id guid
    #gp.AddMessage('<PolylineObjectPlacement id="{70CE4D5C-D4A2-4AC8-B064-33FEFF87E748}"/>')
    outFile.write(str(tabTabTab) +'<PolylineObjectPlacement' + '\n')
    outFile.write(str(tabTabTabTab) + 'id="{70CE4D5C-D4A2-4AC8-B064-33FEFF87E748}" />'+ '\n')
    # close tag
    #gp.AddMessage('</PolylineObjectPlacementList>')
    outFile.write(str(tabTab) +'</PolylineObjectPlacementList>'+ '\n')
    # close extrusion bridge tag
    #gp.AddMessage('</ExtrusionBridge>')
    outFile.write(str(tab)+'</ExtrusionBridge>'+ '\n'+ '\n')

    # Move search cursor to next row/feature
    row = rows.Next()
    # iterate through lists
    denseIndex=denseIndex+1
    if denseIndex == 5:
        denseIndex = 0

# Delete the search cursor to avoid locks etc
del rows,row

# close XML
#gp.AddMessage('</FSData>')
outFile.write('</FSData>')
del gp



Thanks in advance.
0 Kudos
4 Replies
DanPatterson_Retired
MVP Emeritus
altIndex =+1
should be
altIndex += 1
0 Kudos
TimBarnes
Frequent Contributor
Thanks for the reply Don, unfortunately it still isn't out putting the correct values (all are 1, the first item in the list)

Any other ideas? I've tried changing the indentation, tried different forms (i.e. altIndex=altIndex+1) but just cannot seem to get it work!
0 Kudos
KimOllivier
Honored Contributor
Vertices in Parts are not properly pythonic iterable.

You have to use a next() operator or wrap the function in an iterator.

See my example on the resources for stepping through parts to find and delete donuts in polygons.
The same applies to polylines.

http://resources.arcgis.com/gallery/file/geoprocessing/details?entryID=C4E10FE5-1422-2418-A06D-33952...
0 Kudos
KimOllivier
Honored Contributor
             pnt = part.Next()
        partnum += 1


This doesn't look right either, setting a point object to the next part.
0 Kudos