1

Using the python SimpleKML library and having problems substituting in my point (coordinate) values.

Here's the code example from the website:

import simplekml
kml = simplekml.Kml()
pnt = kml.newpoint(name='A Point')
pnt.coords = [(1.0, 2.0)]
pnt.style.labelstyle.color = simplekml.Color.red  # Make the text red
pnt.style.labelstyle.scale = 2  # Make the text twice as big
pnt.style.iconstyle.icon.href = 'http://maps.google.com/mapfiles/kml/shapes/placemark_circle.png'
kml.save("Point Styling.kml")

I try the following and it fails every time.

import simplekml
kml = simplekml.Kml()

a = range(10)
b = a

test = zip(a, b)

for point in test:
    pnt = kml.newpoint(name='Bogusname')
    pnt.coords = point

It throws the following error:

Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
  File "/Library/Python/2.7/site-packages/simplekml/featgeom.py", line 1079, in coords
    self._kml['coordinates'].addcoordinates(coords)
  File "/Library/Python/2.7/site-packages/simplekml/coordinates.py", line 30, in addcoordinates
    if len(coord) == 2:
TypeError: object of type 'int' has no len()

I believe this boils down to some sort of substitution misunderstanding. If I string those two values into one to satisfy the 1 argument requirement it adds single quotes, causing the kml to not render properly. I can't seem to figure out how to pass in the longitude / latitude values without causing an error.

So I thought I could fix it by making point into a string:

for i in test:
    pnt = kml.newpoint(name='Bogusname')
    pnt.coords = str(i)

But receive the following error instead:

>>> kml.save("Point Shared Style.kml")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Python/2.7/site-packages/simplekml/kml.py", line 285, in save
    out = self._genkml(format)
  File "/Library/Python/2.7/site-packages/simplekml/kml.py", line 198, in _genkml
    kml_str = self._feature.__str__()
  File "/Library/Python/2.7/site-packages/simplekml/featgeom.py", line 418, in __str__
    buf.append(feat.__str__())
  File "/Library/Python/2.7/site-packages/simplekml/featgeom.py", line 414, in __str__
    buf.append(super(Feature, self).__str__())
  File "/Library/Python/2.7/site-packages/simplekml/base.py", line 46, in __str__
    buf.append(u"{0}".format(val))  # Use the variable's __str__ as is
  File "/Library/Python/2.7/site-packages/simplekml/featgeom.py", line 1250, in __str__
    return '<Point id="{0}">{1}</Point>'.format(self._id, super(Point, self).__str__())
  File "/Library/Python/2.7/site-packages/simplekml/base.py", line 54, in __str__
    buf.append(u("<{0}>{1}</{0}>").format(var, val))  # Enclose the variable's __str__ with its name
  File "/Library/Python/2.7/site-packages/simplekml/coordinates.py", line 40, in __str__
    buf.append("{0},{1},{2}".format(cd[0], cd[1], cd[2]))
IndexError: string index out of range
CodeMonkey
  • 22,825
  • 4
  • 35
  • 75
Kenny Powers
  • 1,254
  • 2
  • 15
  • 25
  • How about if you use `pnt.coords = [point]`? I'm not certain of what the outcome should be, but it seems like `coords` (plural) is expecting some kind of iterable or collection rather than a singular coordinate. – Paul Rooney May 04 '15 at 02:50
  • That was my original thought too, but it fails with the same error. The google code site for this states that it needs a list of tuples of floats. I'm fuzzy on how to ensure that happens though. [link]https://code.google.com/p/simplekml/issues/detail?id=34&can=1&q=string%20index%20out%20of%20range[/link] – Kenny Powers May 04 '15 at 03:03
  • `>>>type(test[0]) >>>` – Kenny Powers May 04 '15 at 03:05
  • `zip` takes care of creating the `tuples`. My answer shows how to adapt the statement `range(10)` in your questions code to obtain a list of floats. – Paul Rooney May 04 '15 at 04:06

1 Answers1

1

Make your coords parameter a list. To do this either use

pnt.coords = [point]

or just pass it in the newpoint constructor

kml.newpoint(name="Bogusname", coords=[point])

If it requires floats, you could create sample float data as follows

a = [float(x) for x in range(10)]

Full example

from simplekml import Kml

a = range(10)
test = zip(a, a)
kml = Kml(name='KmlUsage')

for coord in test:
    kml.newpoint(name='Bogusname', coords=[coord])  # A simple Point
print kml.kml()  # Printing out the kml to screen
Paul Rooney
  • 20,879
  • 9
  • 40
  • 61