Search code examples
pythoncsvkmlsimplekml

Creating a KML linestring from a CSV with Python and simplekml


I've got a bunch of CSV files containing, amongst other fields, lat and long. Each row is a point on a journey. I'm trying to create a KML that shows the journey as a linestring, but can't quite figure out how to get multiple coords into the linestring element. At the moment it's just putting in the last coords and that's all. It prints the whole set to screen, so I don't think it's my logic.

import csv
import simplekml

inputfile = csv.reader(open('foo.csv','r'))
kml=simplekml.Kml()
ls = kml.newlinestring(name="Journey path")

inputfile.next(); # skip CSV header
for row in inputfile:
        ls.coords=[(row[10],row[9])];
        print ls.coords
kml.save('fooline.kml');

Solution

  • Problem

    This line is your problem:

    ls.coords=[(row[10],row[9])];
    

    You overwrite all the coordinates in your LineString with a new list each time, only containing the current coordinates.

    Semicolon isn't needed, and you should append the current coordinates to the Linestring coordinates. I couldn't find any documentation anywhere, but it seems that coords isn't a list object, but a simplekml.coordinates.Coordinates, which accepts an addcoordinates method:

    ls.coords.addcoordinates([(row[10],row[9])])
    

    To find this non-documented method, I had to call :

    print([method for method in dir(ls.coords) if callable(getattr(ls.coords, method))])
    # ['__class__', '__delattr__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'addcoordinates']
    

    Here's an example with lists:

    >>> coords = [(1,1)]
    >>> coords = [(2,2)]
    >>> coords = [(3,3)]
    >>> coords
    [(3, 3)]
    
    >>> coords = []
    >>> coords.append((1,1))
    >>> coords.append((2,2))
    >>> coords.append((3,3))
    >>> coords
    [(1, 1), (2, 2), (3, 3)]
    

    and with simplekml objects:

    import simplekml
    
    kml=simplekml.Kml()
    ls = kml.newlinestring(name="Journey path")
    
    ls.coords.addcoordinates([(1,2)])
    ls.coords.addcoordinates([(3,4)])
    ls.coords.addcoordinates([(5,6)])
    print(ls.coords)
    # 1,2,0.0 3,4,0.0 5,6,0.0
    

    Solution

    import csv
    import simplekml
    
    inputfile = csv.reader(open('foo.csv','r'))
    kml=simplekml.Kml()
    ls = kml.newlinestring(name="Journey path")
    
    inputfile.next()
    for row in inputfile:
            ls.coords.addcoordinates([(row[10],row[9])]) #<-- IMPORTANT! Longitude first, Latitude second.
            print ls.coords
    kml.save('fooline.kml');