One obvious requirement of this app is to get the closest bike station, or LUAS stop etc etc. This is the feature I’ve been working on lately.

Inititally I was a bit worried when I stumbled across the Great-Circle distance and the Haversine Formula as I’m not a big fan of calculations. Its one of the reasons I went into programming….so I could get computers to calculate hard stuff for me!!!

Luckily, I stumbled across a python library that has it all done for you!! Brilliant! Its called Geopy and can be installed with easy-install. My host doesnt allow for easy-install installs for some reason so I had to do it another way. I had to modify the django.fcgi file to point to a folder I named “modules” which contained the geopy tar.gz and django did the rest! Easy! I know I’m not giving much specifics here, but I’d imagine every host is different so you’ll need to figure out your own hosts methods for installing libraries yourself.

Anyway, with geopy all you need are 2 coordinates. You call a function called “distance.distance(coords1, coords2).miles” and it returns the distance in miles.

Here’s my code to find the nearest station based on the values in my XML file.

def nearestcoords(request, coords="53.345633+-6.267014"):
 user_coords = coords.replace("+", ", ")        ## convert from "lon+lat" to "lon,lat"
 from googlemaps import GoogleMaps
 from geopy import geocoders
 from geopy import distance
 g = geocoders.Google()

 # read xml file
 file = open('lockup.xml','r')
 data = file.read()
 dom = parseString(data)
 rows = dom.getElementsByTagName("root")[0].getElementsByTagName("subroot")[0].getElementsByTagName("stations")

 # setup vars
 shortestStation="None"        # Store temp nearest station
 shortestDistance=""
 for row in rows:
     # Get coords for current record
     curr_coords=row.getAttribute("lat")+','+row.getAttribute("lng")
     # Get distance
     tempDistance=distance.distance(user_coords,curr_coords).miles
     # check if distance is nearer/less
     if tempDistance<shortestDistance:
         shortestDistance=tempDistance
         shortestStation=json.dumps(
         {'number': row.getAttribute("number"),
         'address': row.getAttribute("address"),
         'lat': row.getAttribute("lat"),
         'lng': row.getAttribute("lng"),
         'open': row.getAttribute("open")},
         sort_keys=True,
         indent=4)

 result = ( "["+shortestStation[:-1]+"]" )
 return HttpResponse(result)

Seems straight forward enough! Basically what I’m doing here is opening the XML file, reading the values into an array called “rows”, then looping through that array and comparing coordinates. If the distance is less than the previous distance, that now becomes the new “shortestStation”. I then store the details of that station as a JSON string, which is outputted at the end, ready for consumption!!

Next on the agenda is getting the nearest 3 stations! I’ve no idea how I’m gonna manage this but we’ll see how I get on!

 

EDIT: After a few hours, and some helpful advice from the friendly folks at StackOverflow, I’ve manged to get this part working!

def nearestcoords(request, coords="53.345633+-6.267014"):
    user_coords = coords.replace("+", ", ")	 ## convert from "lon+lat" to "lon,lat"
    from googlemaps import GoogleMaps
    from geopy import geocoders
    from geopy import distance
    g = geocoders.Google()

    # read xml file
    file = open('lockup.xml','r')
    data = file.read()
    dom = parseString(data)
    rows = dom.getElementsByTagName("root")[0].getElementsByTagName("subroot")[0].getElementsByTagName("stations")

    # setup vars
    shortestStation=""		# Store temp nearest station
    shortestDistance=""
    mypoints = []
    for row in rows:
	 # Get coords for current record
	 curr_coords = row.getAttribute("lat") + ',' + row.getAttribute("lng")
	 # Get distance
	 tempDistance = distance.distance(user_coords, curr_coords).miles
	 mypoints.append((tempDistance, row))

    mypoints.sort()
    #the three closest points:
    mythree_shorter = mypoints[0:3]
    for distance, row in mythree_shorter:
	shortestStation = shortestStation+json.dumps(
        	{'number': row.getAttribute("number"),
		 'address': row.getAttribute("address"),
		 'lat': row.getAttribute("lat"),
		 'lng': row.getAttribute("lng"),
		 'open': row.getAttribute("open")},
		 sort_keys=True,
		 indent=4)+","
    result = ( "["+shortestStation[:-1]+"]" )
    return HttpResponse(result)

Wooh!! Now I’m happy! I can put this feature down as DONE!! 😀