0

The objective for this code is to take a csv that contains rhino observations and create a polyline shapefile for the data. The shapefile needs to have the paths the rhinos take based on observations (which is an x and y field in the csv) and the rhinos name must be stored in another field.

I have no idea what is going on, can't figure out the source of this error. I am not sure if the problem is in logic I used to create the dictionary, or if it with the code that follows the creation of the insert cursor.

It seems that the logic for the dictionary is working fine, I added print statements to make sure the rhino data is added properly, it follows the csv file as it should. Once you print the completed dictionary however, the rhino arrays are messed up. You can tell because some rhinos have more points than they should and some have less.

here is the code:

import arcpy
import csv
from arcpy import env
env.overwriteOutput = True

rhino_obsv = open(r"C:\Users\cvric\Desktop\GEOG485\project_4\RhinoObservations.csv")    # open csv containing the rhino observations for reading
sr = arcpy.SpatialReference(4326) # create a spatial reference object that is WGS1984
rhino_obsv_sf = arcpy.CreateFeatureclass_management(r"C:\Users\cvric\Desktop\GEOG485\project_4", "rhino_obsv.shp", "POLYLINE", spatial_reference = sr) # create empty polyline shapefile to store rhino data
arcpy.AddField_management(rhino_obsv_sf,"Name",field_type = "TEXT")

csv_reader = csv.reader(rhino_obsv) # create csv reader, delimiter is comma
header = csv_reader.next() # move reader to the header
name_index = header.index("Rhino") # find index pos. for rhino names
lat_index = header.index("X")   # find index pos. for latitude coordinate
lon_index = header.index("Y")   # index pos. for longitude coordinate

rhino_dict = {}
for row in csv_reader:
    lat = row[lat_index]
    lon = row[lon_index]
    name = row[name_index]
    if name in rhino_dict:
        sighting = arcpy.Point(lon,lat)
        rhino_track.add(sighting)
        #print("sighting added to " + name)

    else:
        #print("array created for " + name)
        rhino_track = arcpy.Array()
        sighting = arcpy.Point(lon,lat)
        rhino_track.add(sighting)
        rhino_dict[name] = [rhino_track]


with arcpy.da.InsertCursor(rhino_obsv_sf, ("SHAPEP@","Name")) as cursor: # use insert cursor to add rhink data to blank shapefile
    for key in rhino_dict:  # iterate through keys in dicitionary
        polyline = arcpy.Polyline(rhino_dict[key],sr) # use the array(value) that corresponds to each rhino(key) to create a polyline
        name = key # name of rhino is the key in the dictionary
        cursor.insertRow((polyline,name)) # use insertRow method to add polyline and name to the SHAPE and Name fields
del cursor

  • Probably side issue, but is x = latitude, etc? That's not usual in ArcGIS software. – mkennedy Jul 18 at 18:25
  • Check to see how many points are in each array (if it's only 1 this may be an issue), and if each point has viable XY coordinates. – Emil Brundage Jul 18 at 18:37
  • @EmilBrundage If you read the post you'll see that I have already addressed this and what is going on is odd. The logic is fine, rhinos are added when they should be, the arrays are updated accurately. Problem is once you print the finished dictionary the key:values are all messed up; some rhinos have more points in their arrayy then they should and some have less. – Karl Johnson Jul 18 at 19:25
  • The RuntimeError is probably happening because the rhino_dict contains lists of arcpy arrays, so you're trying to create a polygon object from a python list. Remove the list brackets where you're initially adding the track to the dict. Also "SHAPEP@" is probably not the field token you want – mikewatt Jul 18 at 19:55
  • @mikewatt thanks for some reason I thought I needed those brackets when I was adding a new key:value; changing that and spelling SHAPE correctly fixed one issue. The tracks for the rhinos are incorrect so now I know for sure the way I created the dictionary is wrong, I still don't get why. If I add print statements and have it print everytime a new track is added and everytime a sighting is added it lines up perfectly with the structure of the csv - the final output is all wrong though. – Karl Johnson Jul 18 at 20:16
2

When the rhino track is already in the dictionary you need to pull out its array before trying to update. Also don't add the array to the dictionary as a list.

if name in rhino_dict:
    sighting = arcpy.Point(lon,lat)
    rhino_track = rhino_dict [name] #### get correct track
    rhino_track.add(sighting)
    #rhino_dict[name] = [rhino_track] ###adding as a list - incorrect
    rhino_dict[name] = rhino_track ### adding as array

else:
    rhino_track = arcpy.Array()
    sighting = arcpy.Point(lon,lat)
    rhino_track.add(sighting)
    rhino_dict[name] = rhino_track #not as list
  • Ah you beat me to it. I managed to figure this out on my own by using the debugger instead of print statements. Thank you though! And also thanks to everyone else who gave me suggestions. – Karl Johnson Jul 18 at 20:53

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.