Created
July 25, 2012 22:45
-
-
Save mapmeld/3179172 to your computer and use it in GitHub Desktop.
GPS-BusTimeTabler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Bus TimeTabler from My Tracks GPS App | |
# Imports CSV of Bus GPS points and KML of Bus Stops along a route. | |
# Helps create a complete timetable by recording when selected vehicles on this route approach the stop | |
import datetime | |
# import a day's worth of bus tracks | |
bustrackfile = open('Bus13.csv', 'r') | |
bustrack = [ ] | |
for line in bustrackfile: | |
bustrack.append(line) | |
bustrackfile.close() | |
# limit to visits by these vehicles | |
routes = [ | |
{ | |
"routenum": 1, | |
"recordVehicle": [ "main" ], | |
"inboundPoint": [ 32.832829, -83.624866 ], | |
"outboundPoint": [ 32.878416, -83.761107 ] | |
}, | |
{ | |
"routenum": 2, | |
"recordVehicle": [ "708", "704" ], | |
"inboundPoint": [ 32.832829, -83.624866 ], | |
"outboundPoint": [ 32.855382, -83.687576 ] | |
}, | |
{ | |
"routenum": "2B", | |
"recordVehicle": [ "708", "704" ], | |
"inboundPoint": [ 32.832829, -83.624866 ], | |
"outboundPoint": [ 32.878596, -83.763016 ] | |
}, | |
{ | |
"routenum": 3, | |
"recordVehicle": [ "523", "709" ], | |
"inboundPoint": [ 32.832829, -83.624866 ], | |
"outboundPoint": [ 32.833442, -83.740308 ] | |
}, | |
{ | |
"routenum": 4, | |
"recordVehicle": [ "703", "711", "712" ], | |
"inboundPoint": [ 32.832829, -83.624866 ], | |
"outboundPoint": [ 32.880037, -83.60696 ] | |
}, | |
{ | |
"routenum": 5, | |
"recordVehicle": [ "705", "707" ], | |
"inboundPoint": [ 32.832829, -83.624866 ], | |
"outboundPoint": [ 32.898812, -83.688799 ] | |
}, | |
{ | |
"routenum": 6, | |
"recordVehicle": [ "706" ], | |
"inboundPoint": [ 32.832829, -83.624866 ], | |
"outboundPoint": [ 32.798133, -83.707414 ] | |
}, | |
{ | |
"routenum": 9, | |
"recordVehicle": [ "520", "521", "583", "586", "522" ], | |
"inboundPoint": [ 32.832829, -83.624866 ], | |
"outboundPoint": [ 32.803769, -83.736231 ] | |
}, | |
{ | |
"routenum": 11, | |
"recordVehicle": [ "700" ], | |
"inboundPoint": [ 32.832829, -83.624866 ], | |
"outboundPoint": [ 32.870648, -83.569554 ] | |
}, | |
{ | |
"routenum": 12, | |
"recordVehicle": [ "587", "588", "713" ], | |
"inboundPoint": [ 32.832829, -83.624866 ], | |
"outboundPoint": [ 32.786778, -83.658297 ] | |
}, | |
{ | |
"routenum": "12B", | |
"recordVehicle": [ "587", "588", "713" ], | |
"inboundPoint": [ 32.832829, -83.624866 ], | |
"outboundPoint": [ 32.786778, -83.658297 ] | |
}, | |
{ | |
"routenum": "12C", | |
"recordVehicle": [ "587", "588", "713" ], | |
"inboundPoint": [ 32.832829, -83.624866 ], | |
"outboundPoint": [ 32.786778, -83.658297 ] | |
}, | |
{ | |
"routenum": "13", | |
"recordVehicle": [ "main" ], | |
"inboundPoint": [ 32.898812, -83.688799 ], | |
"outboundPoint": [ 32.93211, -83.726474 ] | |
} | |
] | |
# May30: 524 does two routes | |
# 701 does two East Macon routes | |
# 702 is a Warner Robins bus | |
# 703 and 712 are WR + Rt 4 bus | |
# 712 is WR + Rt 4 bus | |
# 2866 is Rt 9 | |
for route in routes: | |
# limit to a specific route | |
if(str(route["routenum"]) != "13"): | |
continue | |
# import a bus route and schedule | |
routenum = str(route["routenum"]) | |
# load stops | |
busroute = open('Route' + routenum + 'stops.kml', 'r') | |
busstops = [ ] | |
activebusstop = { } | |
for line in busroute: | |
if(line.find('<SimpleData name="OBJECTID">') > -1): | |
activebusstop["id"] = line[ line.find('OBJECTID') + 10 : line.find('</SimpleData') ] | |
elif(line.find('<SimpleData name="Location">') > -1): | |
activebusstop["location"] = line[ line.find('Location') + 10 : line.find('</SimpleData') ] | |
elif(line.find('<Point><coordinates>') > -1): | |
activebusstop["lat"] = float( (line[ line.find('<Point><coordinates>') + 20 : line.find('</coordinates>') ]).split(",")[1] ) | |
activebusstop["lng"] = float( (line[ line.find('<Point><coordinates>') + 20 : line.find('</coordinates>') ]).split(",")[0] ) | |
busstops.append(activebusstop) | |
activebusstop = { } | |
busroute.close() | |
threshold = 0.01 # inside the bubble around the stop ( avoids hitting the stop multiple times in the same neighborhood ) | |
stopThreshold = 0.005 # within stopping distance | |
for stop in busstops: | |
vehicleInBubble = { } | |
closestTimes = [ ] | |
vehicleBubbleClosest = { } | |
vehicleBubbleClosestTime = { } | |
intimes = [ ] | |
outtimes = [ ] | |
bustrackindex = 0 | |
for rawline in bustrack: | |
line = rawline.replace('"','') | |
vehicle = "main" | |
if(vehicleInBubble.has_key(vehicle) == False): | |
vehicleInBubble[vehicle] = 0 | |
vehicleBubbleClosest[vehicle] = 10 | |
vehicleBubbleClosestTime[vehicle] = "" | |
if(vehicle == "main"): | |
lat = line.split(",")[2] | |
lng = line.split(",")[3] | |
timestamp = line.split(",")[8] | |
year = int(timestamp.split('-')[0]) | |
month = int(timestamp.split('-')[1]) | |
day = int(timestamp.split('-')[2].split('T')[0]) | |
hour = int(timestamp.split(':')[0].split('T')[1]) - 3 | |
minute = int(timestamp.split(':')[1]) | |
second = int(timestamp.split(":")[2].split('.')[0]) | |
time = datetime.datetime( year, month, day, hour, minute, second ) | |
distance = (stop["lat"] - float(lat))**2 + (stop["lng"] - float(lng))**2 | |
if(distance < (threshold**2)): | |
if(vehicleInBubble[ vehicle ] == 0): | |
vehicleInBubble[ vehicle ] = 1 | |
vehicleBubbleClosest[ vehicle ] = distance | |
vehicleBubbleClosestTime[ vehicle ] = time | |
# inform user | |
#print vehicle + " entered bubble of stop " + stop["location"] + " at " + str(time) + " going " + direction | |
else: | |
# still in bubble - see if the vehicle got closer | |
if(distance < vehicleBubbleClosest[ vehicle ]): | |
vehicleBubbleClosest[ vehicle ] = distance | |
vehicleBubbleClosestTime[ vehicle ] = time | |
else: | |
if(vehicleInBubble[ vehicle ] == 1): | |
vehicleInBubble[ vehicle ] = 0 | |
#print vehicle + " exits bubble of stop " + stop["location"] + " at " + str(time) | |
#print "was closest at " + str(vehicleBubbleClosestTime) + " with " + str(vehicleBubbleClosest**0.5) | |
if(vehicleBubbleClosest[ vehicle ] > stopThreshold**2): | |
# entered and exited the bubble, but not close enough to stop | |
continue | |
# follow vehicle to find direction | |
direction = "outbound" | |
stopOutboundDistance = (stop["lat"] - route["outboundPoint"][0])**2 + (stop["lng"] - route["outboundPoint"][1])**2 | |
stopInboundDistance = (stop["lat"] - route["inboundPoint"][0])**2 + (stop["lng"] - route["inboundPoint"][1])**2 | |
for rawbusline in range(bustrackindex, len(bustrack)): | |
busline = bustrack[rawbusline].replace('\x00','').replace('\r\n','') | |
matchvehicle = busline.split(",")[4].strip() | |
if(matchvehicle == vehicle): | |
lat = busline.split(",")[2] | |
lng = busline.split(",")[3] | |
outboundDistance = (route["outboundPoint"][0] - float(lat))**2 + (route["outboundPoint"][1] - float(lng))**2 | |
inboundDistance = (route["inboundPoint"][0] - float(lat))**2 + (route["inboundPoint"][1] - float(lng))**2 | |
if(outboundDistance < threshold**2): | |
if(outboundDistance < stopOutboundDistance): | |
direction = "outbound" | |
break | |
elif(inboundDistance < threshold**2): | |
if(inboundDistance > stopInboundDistance): | |
direction = "outbound" | |
break | |
offsets = [ -63, -75, -75, -75, -305, -70, -70, -66 ] | |
if(direction == "inbound"): | |
offsettotal = 0 | |
for offset in offsets: | |
offsettotal = offsettotal + offset | |
intimeprint = str(vehicleBubbleClosestTime[ vehicle ] + datetime.timedelta(minutes=offsettotal)).split(":")[0].split(' ')[1] + ":" + str(vehicleBubbleClosestTime[ vehicle ] + datetime.timedelta(minutes=offsettotal)).split(":")[1] | |
# avoid double printing of times (not sure why this happens) | |
if(len(intimes) == 0 or intimes[ len(intimes) - 1 ] != intimeprint): | |
intimes.append( intimeprint ) | |
else: | |
offsettotal = 0 | |
for offset in offsets: | |
offsettotal = offsettotal + offset | |
outtimeprint = str(vehicleBubbleClosestTime[ vehicle ] + datetime.timedelta(minutes=offsettotal)).split(":")[0].split(' ')[1] + ":" + str(vehicleBubbleClosestTime[ vehicle ] + datetime.timedelta(minutes=offsettotal)).split(":")[1] | |
# avoid double printing of times (not sure why this happens) | |
if(len(outtimes) == 0 or outtimes[ len(outtimes) - 1 ] != outtimeprint): | |
outtimes.append( outtimeprint ) | |
#closestTimes.append( str(vehicleBubbleClosestTime).split(' ')[1] ) | |
intimes.reverse() | |
outtimes.reverse() | |
intimesprint = '["' + '","'.join(intimes) + '"]' | |
outtimesprint = '["' + '","'.join(outtimes) + '"]' | |
if(len(intimes) == 0): | |
intimesprint = '[ ]' | |
if(len(outtimes) == 0): | |
outtimesprint = '[ ]' | |
print ' MaconStop.new("' + stop["id"] + '","' + stop["location"] + '",["' + routenum + '"],[' + str(stop["lng"]) + ',' + str(stop["lat"]) + '],' + intimesprint + ',' + outtimesprint + '),' | |
break |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment