1

I try to calculate distance between points from gpx file using harvesine formula. I stuck in moment when I should use 'lats' and 'lons' for formula which I found in internet. I want to use that two list as pairs, so zip function would be ok. But how i should do that?

import xml.etree.ElementTree as ET
import math
f = ('St_Louis_Zoo_sample.gpx')
p = ET.parse(f)
root = p.getroot()
lats=[]
lons=[]

for mainElement in root.findall('{http://www.topografix.com/GPX/1/1}wpt'):    
        y = float(mainElement.attrib['lat'])
        x = float(mainElement.attrib['lon'])
        lats.append(y)
        lons.append(x)

def distance(origin, destination):
    lat1, lon1 = origin
    lat2, lon2 = destination
    radius = 6371 # km

    dlat = math.radians(lat2-lat1)
    dlon = math.radians(lon2-lon1)
    a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.radians(lat1)) \
        * math.cos(math.radians(lat2)) * math.sin(dlon/2) * math.sin(dlon/2)
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
    d = radius * c

    return d
PolyGeo
  • 65,136
  • 29
  • 109
  • 338

1 Answers1

4

Look at How to calculate distances in a point sequence?, you need to iterate by pair of points to compute the distances

  points =  zip(lats,lons)
  # or directly with a list comprehension
  points = [(float(mainElement.attrib['lat']), float(mainElement.attrib['lon'])) for mainElement in tree.findall('{http://www.topografix.com/GPX/1/1}wpt')]
  print points
  [(38.63473, -90.29408), (38.63368, -90.28679), (38.63408, -90.29323), (38.63533, -90.29019), (38.63677, -90.28976), (38.63496, -90.28948), (38.63421, -90.29458), (38.63633, -90.29083), (38.63395, -90.28715), (38.63347, -90.28769)]

  def pair(list):
      '''Iterate over pairs in a list -> pair of points '''
      for i in range(1, len(list)):
             yield list[i-1], list[i]
  for first, second in pair(points):
        print first, second, distance(first, second)
  (38.63473, -90.29408) (38.63368, -90.28679) 0.643881089995
  (38.63368, -90.28679) (38.63408, -90.29323) 0.561144390742
  (38.63408, -90.29323) (38.63533, -90.29019) 0.29839986488
  (38.63533, -90.29019) (38.63677, -90.28976) 0.164418862328
  (38.63677, -90.28976) (38.63496, -90.28948) 0.202726888151
  (38.63496, -90.28948) (38.63421, -90.29458) 0.450763798782
  (38.63421, -90.29458) (38.63633, -90.29083) 0.402073386107
  (38.63633, -90.29083) (38.63395, -90.28715) 0.414976855973
  (38.63395, -90.28715) (38.63347, -90.28769) 0.0710547282793

You can also use the itertools standard module

  import itertools
  for first, second in itertools.izip(points, points[1:]):
        print first, second, distance(first, second)
  (38.63473, -90.29408) (38.63368, -90.28679) 0.643881089995
  (38.63368, -90.28679) (38.63408, -90.29323) 0.561144390742
  (38.63408, -90.29323) (38.63533, -90.29019) 0.29839986488
  ....
gene
  • 54,868
  • 3
  • 110
  • 187