A few days ago, I decided to bike home from work (from Brussels to Leuven). Inspired by the "gefietst" blog en based upon the route here I made my adapted route to get to my home. The bike trip went well. Of course, I was wandering how long the bike trip was. Since I have a basic bike with no equipement to measure this I had to resort to the Google Maps info. I was almost sure that a webservice would exist that calculated the length of linesegments of Google Maps or from a KML file but after some searching I found no easy way to do this via the web. (If somebody would be aware of such a service, please drop me a line in the comments) Therefore, I decided to write a small Python script to calculate the lenght of all lines drawn on a Google Map. Just go to your map, click on "Link to this page", copy the URL and fill the URL in the Python script. Run the Python script and, bingo, you have the length in kilometers for every continuous linesegment. Here's the code:

The output of the above script is:

distance of fietsweg is 36.35 kilometer

Of course, this calculation is only an approximation since the trajectory is only an approximation (albeit a pretty good one) of the real route I followed and no heigth information is taken into account. Still I guess that its accurate upto a few kilometers. If somebody has a spare Bluetooth GPS receiver, you can always send me one ;-).

The calculation of the distance in kilometer between two points is based on the code in Ruby and the examples from the zips project a sourceforge. The coordinates of the linesegments are obtained from the KML file that Google Maps generates when appending &output=kml to the URL from 'link to this page'. The KML file is parsed using the Python minidom module. I hope that in the future Google will provide a "&output=jsonp&callback=calcfunc" so that a simple webpage with some Javascript can calculate the length. But that's for another programming project.

## 9 comments:

How do I run such a script myself?

@dikkie download to a file with extention .py and feed the file to the python interpreter. On osx Python is installed by default, on windoze it's a bit more difficult. But as I explained, I'm working on a more user friendly version that boils down to pasting an URL and pushing a button. In the mean while, you can calculate distances here So stay tuned.

Thanks a lot. Btw, I also found this one.

That's also a nice one, but I would like to create the routes with Google Maps and then be able to calculate the distance. A such I can keep the map stored. The drawback of this mapplet is that you can not store the map after chalking the route on the map.

cast42,

This tool to save routes on a map seems to do what you are looking for.

There's now a recipe for this:

Recipe 576782: Calculate distance from .kmz files

Hi!

I found your app is exactly what I need, however, kml format has probably changed since 2007 or at least I couldn't use it.

I changed your code a little to make it work with the new format

here it is:

#!/usr/bin/python

from xml.dom import minidom

import urllib,sys

import math

# This is the link to the google map

filename=sys.argv[1];

# Calculate distance based on http://highearthorbit.com/projects/geolocation/gpx.rb

# See also : http://zips.sourceforge.net/

def distance_in_km(lat1, lon1, lat2, lon2):

rtheta = math.radians(lon1 - lon2)

rlat1 = math.radians(lat1)

rlat2 = math.radians(lat2)

dist = math.sin(rlat1) * math.sin(rlat2) + math.cos(rlat1) * math.cos(rlat2) * math.cos(rtheta)

dist = math.degrees(math.acos(dist))

return (dist * 60.0 * 1.1515 * 1.609344) # distance in km

def getText(nodelist):

rc = ""

for node in nodelist:

if node.nodeType == node.TEXT_NODE:

rc = rc + node.data

return rc

# Retrieve the KML file

#sock =urllib.urlopen(url+"&output=kml")

#htmlSource = sock.read()

#sock.close()

f=open(filename);

strkml=f.read();

xmldoc = minidom.parseString(strkml);

placemarks = xmldoc.getElementsByTagName('kml')[0].getElementsByTagName('Document')[0].getElementsByTagName('Placemark')

first=True;

distance=0;

for placemark in placemarks:

name = getText(placemark.getElementsByTagName('name')[0].childNodes)

linestrings = placemark.getElementsByTagName('Point')

for linestring in linestrings:

coordinates = linestring.getElementsByTagName('coordinates')[0].childNodes

listofpoints = getText(coordinates)

points = listofpoints.split(',')

#distance = 0.0

point=points;

values = point;#.split(',')

if len(values) == 3:

(x,y,z) = float(values[0]), float(values[1]), float(values[2])

if first:

first = False

(x0,y0,z0) = (x,y,z)

else:

dist = distance_in_km(x0,y0,x,y)

# print 'dist='+str(dist);

distance += dist

x0 = x

y0 = y

else:

print 'len points='+str(len(points));

print "Total distance is %.2f kilometer" % distance;

hope the indentation works fine

mehageg at nana10 dot co dot ilI put the updated code into an pastebin:

http://pastebin.ca/1886961

Post a Comment