-1

I have a list of locations with their names and coordinate points.

I'm trying to find the closest location pairs for each location and print the current location name, the distance to the closest location, and the closest location name.

  • location names stored in column 0
  • latitudes are stored in column 5
  • longitudes are stored in column 8

I have tried to work this out but I get this error after a few iterations.

---------------------------------------------------------------------------
     24         for j in range(len(data[i])):
     25             if(i != j):
---> 26                 distance = get_distance(float(data[i][5]),float(data[i][8]),float(data[j][5]),float(data[j][8]))
     27                 temp = str(data[i][0])
     28                 if (min > distance):

ValueError: could not convert string to float: 

I get results before this error, but I suspect that the results are wrong. Not sure what the issue is, any help would be greatly appreciated.

Edit: My issue now is that the algorithm is broken. The closest location it returns is always the same target location. The distance it returns varies from like 80 miles to thousands of miles which I know is not the case. All locations are within a few hundred miles of each other.

    import math
    import csv
    with open("Locations.csv") as f:
        def get_distance(lat_1, lng_1, lat_2, lng_2): 
            d_lat = lat_2 - lat_1
            d_lng = lng_2 - lng_1 

            temp = (  
            math.sin(d_lat / 2) ** 2 
            + math.cos(lat_1) 
            * math.cos(lat_2) 
            * math.sin(d_lng / 2) ** 2
            )
            return 3963.1676 * (2 * math.atan2(math.sqrt(temp), math.sqrt(1 
            - temp))) 

        min = float(9000)
        temp = ''
        closest = ''
        reader = csv.reader(f)
        next(reader) # skip header
        for i in range(len(data)):
            for j in range(len(data[i])):
                if(i != j):
                    distance = get_distance(float(data[i][5]),float(data[i][8]),float(data[j][5]), float(data[j][8]))
                    temp = str(data[i][0])
                    if (min > distance):
                        min = distance
                        closest = temp
            print(str(data[i][0]) +" " + str(min) + " " + closest)
            min = 90000
            closest = ''
Bartman
  • 1
  • 3
  • Does [this](https://stackoverflow.com/questions/41336756/find-the-closest-latitude-and-longitude) help you if your points are longitudes and latitudes? – Sheldore Sep 19 '18 at 17:53
  • Where is the "data" variable defined? – amacf Sep 19 '18 at 17:54
  • 2
    Have you checked your csv file to make sure there are no characters in it? – Nick Eu Sep 19 '18 at 18:00
  • @amacf I missed the data definition, data = [r for r in reader], should be right after nextline(reader)...somehow this doesn't make a difference – Bartman Sep 19 '18 at 18:01
  • @NickEu I have, the csv is clean – Bartman Sep 19 '18 at 18:05
  • Is more info printed on the value error? You can wrap the `distance = ...` line in something like a `try: ... except ValueError: print(f"FAILED: {data[i][5]},{data[i][8]},{data[j][5]},{data[j][8]}")` block and see which entry it is failing on? – amacf Sep 19 '18 at 18:12
  • @amacf I put in the try block and boom, no more error....I don't get it but thank you man. – Bartman Sep 19 '18 at 18:26
  • You essentially added a handler for the ValueError exception. You can read more about this topic here https://docs.python.org/3/tutorial/errors.html . That probably seems to have fixed the issue, but I suspect it just suppressed it. That may be sufficient for a best-effort algorithm, but I was more talking about using this to debug and not as a solution to the problem – amacf Sep 19 '18 at 18:32
  • @amacf I am only using this to generate a list to import somewhere else. As long as it generates all values it satisfies my needs. Which it seems to be able to do now. Just wondering though, how would I use this to debug if it doesn't throw the error? – Bartman Sep 19 '18 at 18:38
  • Well you know that 1 entry is throwing a value error. So you can catch when that happens, and do something about it in the `except` block. For instance, print the values of i and j to understand when the problem happens. Or print the values of `data` that are being read to determine if there is some formatting in the input file that is askew – amacf Sep 19 '18 at 18:43
  • BTW, if you want to get [WGS84](https://en.wikipedia.org/wiki/World_Geodetic_System) ellipsoid distances (the same as GPS), take a look at the excellent [geographiclib](https://geographiclib.sourceforge.io/). Not all of its functions are easily accessible from Python, but the geodesic stuff is. – PM 2Ring Sep 19 '18 at 19:10
  • Oh I see, upon scouring the results I found 2 rows that had blank coordinates, thanks again amacf. @Bazingaa I replaced my algorithm with that one and It works now. Thank you. I really appreciate all your guys help. If anyone wants the final code let me know – Bartman Sep 19 '18 at 19:10

1 Answers1

0

I assume you're trying to read the file object instead of the content. Have a look at docs and you can find the usage.

Here's a simple example from the same document:

import csv
with open('some.csv', newline='') as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

Looking at the code nothing is read and your reader is out of your CSV files scope. Note that you're using "with open" which defines its scope and closes the file afterward.

PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
Nina
  • 148
  • 2
  • 16