Skip to content

Instantly share code, notes, and snippets.

@mapmeld
Created June 17, 2012 12:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mapmeld/2944409 to your computer and use it in GitHub Desktop.
Save mapmeld/2944409 to your computer and use it in GitHub Desktop.
BusTimeTabler
# 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