1

I wanting to compare the distance between two sets of lat/long and I need help inputting my lat/long fields into the Haversine formula.

I am able to print my two sets of lat/longs (print floats1, floats2, floats3, and floats4). I am unsure how to take these variables and use them as my inputs for the Haversine definition.

I was able to find similar code on GIS Stack Exchange, but I am fairly new to python and having some trouble.

import csv
import math

def haversine(lon1, lat1, lon2, lat2):
    """
    Calculate the great circle distance between two points
    on the earth (specified in decimal degrees).
    Source: http://gis.stackexchange.com/a/56589/15183
    """
    # convert decimal degrees to radians
    lon1, lat1, lon2, lat2 = map(math.radians, [lon1, lat1, lon2, lat2])
    # haversine formula
    dlon = lon2 - lon1
    dlat = lat2 - lat1
    a = math.sin(dlat/2)**2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)**2
    c = 2 * math.asin(math.sqrt(a))
    km = 6367 * c
    return km

with open(r'PathtoFile.csv', 'rb') as f1:
    reader1 = csv.reader(f1, delimiter=',', quoting=csv.QUOTE_NONE)
    header1 = reader1.next()
    for row1 in reader1:
        floats1 = map(float, row1[16:]) #lon1
        floats2 = map(float, row1[17:]) #lat1
        floats3 = map(float, row1[18:]) #lon2
        floats4 = map(float, row1[19:]) #lat2
        print(floats1)
        print(floats2)
        print(floats3)
        print(floats4)
        print haversine(floats1[1],floats1[0],floats3[1],floats4[0])
1
  • Can you please past the first few lines from your CSV file? Then we can test your code and a fix.
    – Alex Leith
    Commented Mar 21, 2017 at 3:21

2 Answers 2

1

I don't have enough reputation to post this as a comment, but since nobody else has contributed yet, I'll just put this here. Are you sure you are passing your lat/longs as numbers and not strings?

Maybe try something like this just to make sure:

print haversine(float(floats1[1]),float(floats1[0]),float(floats3[1]),float(floats4[0]))

Also, is there a reason why you have an index on your values going to the function? Should it not just be:

print haversine(float(floats1),float(floats2),float(floats3),float(floats4))

I also noticed you reference floats1 twice in the call to the function.

1

There are a few questions I had about your code.

  1. Opening the files in 'rb' mode means to read it as a binary. Is this what you meant?
  2. I find your indexing a bit confusing. Your lines converting to float are mapping every item from an index on. That means that map(float, row1[16:]) converts every item from 16 to the end, map(float, row1[17:]) converts every item from 17 to the end, and so on. There's a lot of redundancy happening. To convert just one item, you can call the float function directly. In the example below, I've assumed that lon1 is item 16, lat1 is item 17, etc. This isn't exactly what you wrote, so modify as needed.

Here's a cleaned version that I believe does what you intended.

with open('test.csv', 'r') as f:
    reader = csv.reader(f, delimiter=',', quoting=csv.QUOTE_NONE)
    header = reader.next()
    for row in reader:
        floats1 = float(row[0])
        floats2 = float(row[1])
        floats3 = float(row[2])
        floats4 = float(row[3])
        print(floats1, floats2, floats3, floats4)
        print(haversine(floats1, floats1, floats3, floats4))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.