Created
June 17, 2012 12:28
-
-
Save mapmeld/2944409 to your computer and use it in GitHub Desktop.
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 | |
# 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('May 30.csv', 'r') | |
bustrack = [ ] | |
for line in bustrackfile: | |
bustrack.append(line) | |
bustrackfile.close() | |
# limit to visits by these vehicles | |
routes = [ | |
{ | |
"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 ] | |
} | |
] | |
# 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: | |
# import a bus route and schedule | |
routenum = str(route["routenum"]) | |
# watch for known vehicles on this route | |
recordvehicle = route["recordVehicle"] | |
# 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: | |
bustrackindex = bustrackindex + 1 | |
if(bustrackindex == 1): | |
continue | |
line = rawline.replace('\x00','').replace('\r\n','') | |
vehicle = line.split(",")[4].strip() | |
if(vehicleInBubble.has_key(vehicle) == False): | |
vehicleInBubble[vehicle] = 0 | |
vehicleBubbleClosest[vehicle] = 10 | |
vehicleBubbleClosestTime[vehicle] = "" | |
if(vehicle in recordvehicle): | |
lat = line.split(",")[2] | |
lng = line.split(",")[3] | |
timestamp = line.split(",")[1] | |
year = int(timestamp.split('-')[0]) | |
month = int(timestamp.split('-')[1]) | |
day = int(timestamp.split('-')[2].split(' ')[0]) | |
hour = int(timestamp.split(':')[0].split(' ')[1]) | |
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 = "inbound" | |
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 | |
if(direction == "inbound"): | |
intimeprint = str(vehicleBubbleClosestTime[ vehicle ]).split(":")[0].split(' ')[1] + ":" + str(vehicleBubbleClosestTime[ vehicle ]).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: | |
outtimeprint = str(vehicleBubbleClosestTime[ vehicle ]).split(":")[0].split(' ')[1] + ":" + str(vehicleBubbleClosestTime[ vehicle ]).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] ) | |
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 + '),' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment