ArcPy – How to Create Arrays and Polylines from Dictionary

arcpyline

I have created a dictionary out of a csv values from an excel spreadsheet. I'm trying to use the keys and values in the dictionary to create arrays (one per 'Rhino') that I can use to create polylines.
The code I've writen so far has got me stuck when creating the arrays, since when I print the coordinate pairs in the array it gives me the same value repeated many times.

I am still in the beginning of learning Python for ArcGIS.

#reads through a text file with coordinates of rhino tracks,
#extracts the locations and adds pairs of coordinates to a polyline as an array
#to be automated with a function

import csv
import arcpy

#define a function to be used to add rhinos and their tracks to a dictionary
def rhinoTrackFinder(rhino, coordX, coordY, dictionary):
    coordPair = [coordX, coordY]
    if rhino in dictionary:
        dictionary[rhino].append(coordPair)
    else:
        dictionary[rhino] = coordPair

#open text file with rhinos and coordinates
trackFile = open("C:/Rafa/Lesson4PracticeExercises/RhinoObservations.csv")

#read the header line and create indices, then create empty dictionary
#that will store values and keys for rhinos and the coordinates of their   tracks
csvReader = csv.reader(trackFile, delimiter=",")
header = csvReader.next()

surveyorIndex = header.index("Observer")
XCoordIndex = header.index("X")
YCoordIndex = header.index("Y")
RhinoIdIndex = header.index("Rhino")
CommentIndex = header.index("Comments")

rhinoTrackDictionary = {}

for row in csvReader:
    rhino = row [RhinoIdIndex]
    CoordX = row [XCoordIndex]
    CoordY = row [YCoordIndex]
    #new seg - boolean to define if it is a new polyline or rhino
    rhinoTrackFinder(rhino, CoordX, CoordY, rhinoTrackDictionary)

#print rhinoTrackDictionary

#SO FAR SO GOOD#

#create an array to store lat and lon values of the dictionary as points

vertexArray = arcpy.Array()

#iterate through dictionary to create and add vertices as array points

for rhino in rhinoTrackDictionary:
    vertexArray = arcpy.Array()
    for pair in rhino:
        lon = CoordX
        lat = CoordY
        vertex = arcpy.Point(lon, lat)
        print vertex
        vertexArray.add(vertex)

        #def createPolyline (vertexArray,)


for pair in rhinoTrackDictionary:
    for vertex in pair:
        vertex = arcpy.Point(lon,lat)
        vertexArray.add(vertex)

Best Answer

At first pass, I see two potential issues you might want to examine.

1) The rhino dictionary contains a list of what?

This line, coordPair = [coordX, coordY], says you want a list stored under each item in the rhino dictionary. I bet that works, but I tend to think of pairs as tuples. So try changing the line to:

coordPair = (coordX, coordY)

This says, here's a tuple of X and Y, but we really want the dictionary to store a list, so let's change this bit as well:

def rhinoTrackFinder(rhino, coordX, coordY, dictionary):
    if rhino not in dictionary:
        dictionary[rhino] = []
    dictionary[rhino].append((coordX, coordY))

Note, I removed the coordPair assignment and just append the tuple directly.

So now rhinoTrackFinder will create a dictionary, keyed by rhino, containing a list of tuples.

rhinoTrackDictionary['bob'] might contain: (1,1), (2,4), (-3,7). These tuples should make it easier to read later.

2) What are lon and lat being assigned to?

Further along, you have lon = CoordX and lat = CoordY. Python loves global variables, so from what I can tell, you are just setting lon and lat to the last row values from the csvReader, CoordX = row [XCoordIndex] and CoordY = row [YCoordIndex]. That's probably not right.

If we use that tuple stuff above, try:

for rhino in rhinoTrackDictionary:
    for coord in rhinoTrackDictionary[rhino]:
        lon = coord[0]
        lat = coord[1]
        print rhino, lon, lat
        ...

We're going from rhino to rhino, and looking at the list of coordinates for that rhino. Then we go coordinate to coordinate.

For each coordinate, looks like you're adding it to the VertexArray, which then you use to create your polyline. That should all work.

Related Question