0

I'm trying to replicate a post I came across in the link below and had an error message come up I'm a bit unsure how to resolve: Link to Prior Post I'm trying to replicate

I'm getting an error on the following line:

coord = (row[5], row[6]) # lon, lat order

The error message reads IndexError: string index out of range. I'm calling the column numbers that have my lat and long, which is 5 & 6. Any idea what this error message is referring to?

Here's the script I have at this point:

import geopandas as gpd
import simplekml
kml = simplekml.Kml()


inputfile = gpd.read_file("C:/Users/CombineKMLs_AddLabels/Data/ScopePoles.shp") 
points = []
for row in inputfile:
    coord = (row[5], row[6]) # lon, lat order
    pnt = kml.newpoint(name=row[2], coords=[coord])
    points.append(coord)    
    pnt.style.iconstyle.icon.href = 'http://maps.google.com/mapfiles/kml/shapes/placemark_square.png'

ls = kml.newlinestring(name='A LineString')
ls.coords = np.array(points)
ls.altitudemode = simplekml.AltitudeMode.relativetoground
ls.extrude = 1

kml.save("C:/Users/CombineKMLs_AddLabels/Data/PolesandLines.shp")
Geno
  • 29
  • 7
  • 1
    Need to post example of the input. If row[6] is out of range then row length is less than 6 elements. Try `print(len(row), row)` before "coord =" line. – CodeMonkey Mar 25 '22 at 17:05
  • The script is dependent on the input format, what is the content of `row`? The string index error indicates that row is just a string which has less than 3 characters, so you trying to access the third character results in an error. – ewz93 Mar 25 '22 at 17:07
  • kml.save() saves a .kml file not a shapefile so ".shp" in name may be confusing. – CodeMonkey Mar 25 '22 at 17:08
  • @CodeMonkey I ran that line of code you suggested and the this is the results: 8 OBJECTID 10 STR_GEOTAG 9 LINE_NAME 7 VOLTAGE 7 STR_NUM 9 LONGITUDE 8 LATITUDE 6 HEIGHT – Geno Mar 25 '22 at 17:15
  • First line is the header not a line of data. – CodeMonkey Mar 25 '22 at 17:21
  • try something like: if not row or row[0] == 'OBJECTID': continue – CodeMonkey Mar 25 '22 at 17:22
  • @CodeMonkey, thanks for pointing out the .shp file naming issue I was going to eventually run into. Will change that to .kml! – Geno Mar 25 '22 at 17:22
  • @CodeMonkey sorry, not entirely sure where to insert that line of code – Geno Mar 25 '22 at 17:31
  • add test before `coord = (row[5], row[6]` line – CodeMonkey Mar 25 '22 at 17:55
  • Thanks @CodeMonkey, I inserted that before the coord line you mentioned and the error code reads IndexError: string index out of range – Geno Mar 25 '22 at 17:59
  • Need to debug it. `print(len(row), row)` if length value < 6 then that is the issue causing error. – CodeMonkey Mar 25 '22 at 18:25
  • @CodeMonkey Here's what I am getting: for row in inputfile: if not row or row[0] == 'OBJECTID': continue print(len(row), row) coord = (row[5], row[6]) # lon, lat order 8 OBJECTID 10 STR_GEOTAG 9 LINE_NAME 7 VOLTAGE 7 STR_NUM 9 LONGITUDE 8 LATITUDE 6 HEIGHT – Geno Mar 25 '22 at 18:52
  • try: if not row or row[0].startswith('OBJECTID'): continue – CodeMonkey Mar 25 '22 at 19:09
  • @CodeMonkey I used that after the for row in inputfile line but seems to be the same results – Geno Mar 25 '22 at 19:51

1 Answers1

0

Use df.iterrows() to iterate over the data frame and df.loc[index, 'geometry'] to access the point.

import geopandas as gpd
import simplekml

kml = simplekml.Kml()

df = gpd.read_file("C:/Users/CombineKMLs_AddLabels/Data/ScopePoles.shp")

points = []
for index, poi in df.iterrows():
  pt = df.loc[index, 'geometry']
  coord = (pt.x, pt.y)
  pnt = kml.newpoint(name=index, coords=[coord])
  points.append(coord)
  pnt.style.iconstyle.icon.href = 'http://maps.google.com/mapfiles/kml/shapes/placemark_square.png'

ls = kml.newlinestring(name='A LineString', coords=points)

kml.save('PolesandLines.kml')
CodeMonkey
  • 22,825
  • 4
  • 35
  • 75
  • thanks for the follow up for this question. It looks as if this will process through the code without an error. The results show all the points and a line connecting all the points. How would I need to edit this further to have the line and points break into individual clusters based on a unique name found in each of line and point shapefiles? The end result would be one line assigned to numerous points, then another line assigned to numerous points, for all lines in the original shapefile. – Geno Mar 28 '22 at 21:13
  • @Geno - Sounds like the answer above solves your original question and this should be a new question. For that you could add a check as first line in for loop to test with logic for name to create a new cluster then create a new line and reset `points = []` to start a new line, etc. – CodeMonkey Mar 28 '22 at 21:57