From: maxious Date: Sat, 06 Nov 2010 08:16:52 +0000 Subject: Add weekend Network 10 X-Git-Url: http://maxious.lambdacomplex.org/git/?p=bus.git&a=commitdiff&h=9d20f424881b8ba14ccfba84907c3b734b3e8df8 --- Add weekend Network 10 --- --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -maxious-canberra-transit-feed/output/ +origin-src --- a/betweenpoint.load.php +++ /dev/null @@ -1,76 +1,1 @@ - nodes of the first movie. - * Output the rating scale, too. */ -foreach ($xml->node as $node) { - $geoPo = geopoEncode((float)$node['lat'],(float)$node['lon']); - $node['lat'] = (int) ((float)$node['lat']*10000000); - $node['lon'] = (int) ((float)$node['lon']*10000000); - echo($node['lat'].",".$node['lon']."=$geoPo
"); - $sql = "INSERT INTO stops (geohash, lat, lng) VALUES('$geoPo','{$node['lat']}','{$node['lon']}')"; - $result = pg_query($conn, $sql); - if (!$result) { - echo("Error in SQL query: " . pg_last_error() ."
\n"); - } -flush(); - -} -?> --- a/betweenpoint.php +++ b/betweenpoint.php @@ -7,71 +7,66 @@ function init() { - // create the ol map object - var map = new OpenLayers.Map('map'); + // create the ol map object + var map = new OpenLayers.Map('map'); - var osmtiles = new OpenLayers.Layer.OSM("local", "http://127.0.0.1/Maps/OSM/${z}/${x}/${y}.png") + var osmtiles = new OpenLayers.Layer.OSM("local", "http://127.0.0.1/tiles/${z}/${x}/${y}.png") // use http://open.atlas.free.fr/GMapsTransparenciesImgOver.php and http://code.google.com/p/googletilecutter/ to make tiles - markers = new OpenLayers.Layer.Markers("Between Stop Markers"); + markers = new OpenLayers.Layer.Markers("Between Stop Markers"); var timeicon = new OpenLayers.Icon("http://maps.google.com/mapfiles/kml/pushpin/grn-pushpin.png",new OpenLayers.Size(32,32)); var timepoints = new OpenLayers.Layer.GeoRSS("Timing Points", "displaytimepoints.georss.php", { icon: timeicon }); map.addLayers([osmtiles, markers,timepoints]); map.addControl(new OpenLayers.Control.LayerSwitcher()); - map.zoomToExtent(markers.getDataExtent()); + map.zoomToExtent(markers.getDataExtent()); } + + + + + + @@ -82,3 +87,4 @@ } ?> + --- a/busui/list.php +++ /dev/null @@ -1,22 +1,1 @@ -
-
-

GET Example

- AJAX -
-
- This page was loaded via AJAX. -
- -
-
-
-

Events test

- AJAX - Home -
-
- This is a test of live events. -
-
+ --- a/busui/schedule_viewer.py +++ b/busui/schedule_viewer.py @@ -337,6 +337,14 @@ def handle_json_GET_stops(self, params): schedule = self.server.schedule return [StopToTuple(s) for s in schedule.GetStopList()] + + def handle_json_GET_timingpoints(self, params): + schedule = self.server.schedule + matches = [] + for s in schedule.GetStopList(): + if s.stop_code.find("Wj") == -1: + matches.append(StopToTuple(s)) + return matches def handle_json_GET_stopsearch(self, params): schedule = self.server.schedule @@ -361,6 +369,7 @@ schedule = self.server.schedule stop = schedule.GetStop(params.get('stop', None)) time = int(params.get('time', 0)) + service_period = params.get('service_period', None) time_trips = stop.GetStopTimeTrips(schedule) time_trips.sort() # OPT: use bisect.insort to make this O(N*ln(N)) -> O(N) # Keep the first 15 after param 'time'. @@ -389,8 +398,8 @@ trip_name += route.route_long_name if headsign: trip_name += " (Direction: %s)" % headsign - - result.append((time, (trip.trip_id, trip_name, trip.service_id), tp)) + if service_period == None or trip.service_id == service_period: + result.append((time, (trip.trip_id, trip_name, trip.service_id), tp)) return result def handle_GET_ttablegraph(self,params): --- a/busui/stop.php +++ b/busui/stop.php @@ -5,11 +5,12 @@ include_header("Trips passing ".$stop[1]); echo ' '; include_footer(); --- a/busui/stopList.php +++ b/busui/stopList.php @@ -2,7 +2,8 @@ include('common.inc.php'); include_header("Stops"); echo ' '; -/* +echo'
-
-*/ + '; include_footer(); ?> --- a/maxious-canberra-transit-feed/01-extracttimes.rb +++ b/maxious-canberra-transit-feed/01-extracttimes.rb @@ -14,7 +14,14 @@ timetable = {"between_stops" => [], "short_name" => short_name} time_points = table.xpath('tr[1]//th').map do |tp| if tp.content != "\302\240" && tp.content != "" && tp.content != "
" - timing_point = tp.content.squeeze(" ").gsub("\r\n Platform"," - Platform").gsub(" - "," - ").gsub("\n","").gsub("\r","").gsub("\\"," / ").strip + timing_point = tp.content.squeeze(" ").gsub("Bus Station"," Bus Station ").gsub(" Platform"," (Platform").gsub(" - "," - ").gsub("\n"," ").gsub("\r"," ").gsub("\t"," ").gsub("\\"," / ").gsub("/"," / ").gsub(","," ").gsub("\302\240","").squeeze(" ").strip + if (tp.content.match('Platform')) + timing_point.concat(")") + end; + if tp.to_s.match(/[0-9][0-9][0-9]/) or tp.to_s.include? "Wheelchair" + timing_point = nil + end + timing_point end end time_points.delete(nil) @@ -24,12 +31,17 @@ table.css('tr').each do |row| times = row.css('td').map do |cell| time = cell.content.squeeze(" ").strip - time = time.gsub(/ *A\S?M/,"a").gsub(/ ?P\S?M/,"p").gsub("12:08 AM","1208x").gsub(":","").gsub("1.","1").gsub("2.","2") - time = time.gsub("3.","3").gsub("4.","4") + time = time.gsub(/ *A\S?M/,"a").gsub(/ ?P\S?M/,"p").gsub(/ *a\S?m/,"a").gsub(/ ?p\S?m/,"p") + time = time.gsub("12:08 AM","1208x").gsub(":","").gsub("1.","1").gsub("2.","2").gsub("3.","3").gsub("4.","4") time = time.gsub("5.","5").gsub("6.","6").gsub("7.","7").gsub("8.","8").gsub("9.","9").gsub("10.","10") - time = time.gsub("11.","11").gsub("12.","12").gsub(/\.+/,"-") + time = time.gsub("11.","11").gsub("12.","12").gsub(/\.+/,"-").gsub("\302\240","") + if time == "" or time.include? "chool" or time.include? "On Race Days" or time.include? "Bus" + time = nil # This hacky way is faster than using position()>1 xpath on s! + end + time end - if not times.empty? + times.delete(nil) + if not times.empty? if not (route = times.shift) raise("TODO: account for shifting route numbers eg. intertown/redex 62/162") end @@ -42,7 +54,7 @@ timetable[period] = periodtimes.to_a # pp timetable filename = timetable["short_name"] + "-" + timetable["long_name"]+ "." + period + ".yml" - filename = filename.downcase.gsub(" ","-").gsub("/","-") + filename = filename.downcase.gsub(" ","-").gsub("/","-").gsub("(","").gsub(")","") puts "Saving " + filename File.open("#{File.dirname(__FILE__)}/output/"+filename, "w") do |f| f.write timetable.to_yaml @@ -50,15 +62,14 @@ timetable end -#TODO fix route 934 -Dir.glob("source-html/Route*.htm*") { |file| +Dir.glob("source-html/*oute*.htm*") { |file| puts "Opened " + file doc = Nokogiri::HTML(open(file)) # Search for nodes by css timetables = [] short_name = ""; doc.xpath('//title').each do |title| - short_name = title.content.gsub("Route_","").gsub("Route ","").gsub(", ","/").squeeze(" ").strip + short_name = title.content.gsub("Route_","").gsub("Route ","").gsub("route ","").gsub(", ","/").gsub("ACTION Buses Timetable for ","").squeeze(" ").strip end if short_name == "" raise "Route number(s) not found in tag" @@ -67,7 +78,15 @@ doc.xpath('//table[preceding::text()="Weekdays"]').each do |table| timetables << makeTimetable(table, "stop_times", short_name) end - + doc.xpath('//table[preceding::text()="This timetable is effective from Monday 15th November 2010."]').each do |table| + timetables << makeTimetable(table, "stop_times", short_name) + end + #all tables are weekdays on some really malformatted timetables + if short_name == "170" + doc.xpath('//table').each do |table| + timetables << makeTimetable(table, "stop_times", short_name) + end + end #weekends doc.xpath('//table[preceding::text()="Saturdays" and following::a]').each do |table| timetables << makeTimetable(table, "stop_times_saturday", short_name) --- a/maxious-canberra-transit-feed/02-tidytimepoints.rb +++ b/maxious-canberra-transit-feed/02-tidytimepoints.rb @@ -2,9 +2,9 @@ require 'pp' require 'yaml' class Array - def to_yaml_style - :inline - end + def to_yaml_style + :inline + end end Dir.chdir("output") @@ -19,78 +19,96 @@ end } end +def correctTimePoints() +time_point_corrections = {"North Lynehamham" => "North Lyneham", + "Woden Bus Station Platform 10)" => "Woden Bus Station (Platform 10)", + "Saint AndrewsVillage Hughes"=>"Saint Andrews Village Hughes", + "Flemmington Road / Sandford St"=>"Flemington Road / Sandford St", + "City Interchange"=>"City Bus Station", + "City Interchange (Platform 9)"=>"City Bus Station (Platform 9)", + "City Bus Station Platfrom 9"=>"City Bus Station (Platform 9)", + "Belconnen Community Bus StationPlatform 2)"=>"Belconnen Community Bus Station (Platform 2)", + "Bridbabella Gardens Nursing Home"=>"Brindabella Gardens Nursing Home", + "Bridbabella GardensNursing Home"=> "Brindabella Gardens Nursing Home", + "BrindabellaBusiness Park"=> "Brindabella Business Park", + "NarrabundahTerminus"=>"Narrabundah Terminus", + "Railway StationKingston"=>"Railway Station Kingston", + "Saint AndrewsVillage Hughes"=>"Saint Andrews Village Hughes", + "Dickson ShopsAntill Street"=>"Dickson Shops", + "Cohen St Bus Station (Platform 3)" => "Cohen Street Bus Station (Platform 3)", + "Cohen St Bus Station (Platform 6)" => "Cohen Street Bus Station (Platform 6)", + "Newcastle Streetafter Isa Street" => "Newcastle Street after Isa Street", + "Newcastle St after Isa St" => "Newcastle Street after Isa Street", + "Newcastle Street after Isa St" => "Newcastle Street after Isa Street", + "Northbourne Ave / Antill St" => "Northbourne Avenue / Antill St", + "Macarthur / Northbourne" => "Macarthur / Northbourne Ave", + "Macarthur Ave / Northbourne" => "Macarthur / Northbourne Ave", + "Kings Ave / National Cct"=> "Kings Ave / National Circuit", + "Kosciuszco Ave / Everard Street"=>"Kosciuszko / Everard", + "Lithgow St Terminus" => "Lithgow St Terminus Fyshwick", + "Hospice Menindee Dr" => "Hospice / Menindee Dr", + "Gungahlin Market Place"=> "Gungahlin Marketplace", + "Gwyder Square Kaleen"=> "Gwydir Square Kaleen", + "Flemington Road / Nullabor Ave"=>"Flemington Rd / Nullabor Ave", + "Flemington Road / Sandford St"=>"Flemington Rd / Sandford St", + "Heagney Cres Clift Cres Richardson"=> "Heagney / Clift Richardson", + "Charnwood Shops (Tillyard Drive)"=> "Charnwood Shops", + "charnwood Shops"=> "Charnwood Shops", + "Black Moutain- Telstra Tower"=>"Black Mountain Telstra Tower", + "Bonython Primary"=> "Bonython Primary School", + "Athllon Drive / Sulwood Dr Kambah"=>"Athllon / Sulwood Kambah", + "Alexander Machonochie Centre Hume"=>"Alexander Maconochie Centre", + "Alexander Maconochie Centre Hume"=>"Alexander Maconochie Centre", + "Anthony Rolfe Ave / Moonight Ave" =>"Anthony Rolfe Av / Moonlight Av", + "Australian National Botanic Gardens"=>"Botanic Gardens", + "Calwell shops"=> "Calwell Shops", + "Chuculba / William Slim Drive"=>"Chuculba / William Slim Dr", + "Fyshwick direct Factory Outlet"=>"Fyshwick Direct Factory Outlet", + "Kaleen Village / Maibrynong"=>"Kaleen Village / Marybrynong", + "Kaleen Village / Marybrynong Ave"=>"Kaleen Village / Marybrynong", + "National Aquarium"=>"National Zoo and Aquarium", + "chisholm Shops"=>"Chisholm Shops", + "O'connor Shops"=>"O'Connor Shops", + "Mckellar Shops"=>"McKellar Shops", + "Melba shops"=> "Melba Shops", + "William Web / Ginninderra Drive"=>"William Webb / Ginninderra Drive", + "Procor / Mead"=>"Proctor / Mead", + "Fyshwick DirectFactory Outlet"=>"Fyshwick Direct Factory Outlet", + "Yarrulumla Shops"=>"Yarralumla Shops", + "Tharwa Dr / Pocket Ave"=>"Tharwa Dr / Pockett Ave", + "Paul Coe / Mirrebei Dr"=>"Paul Coe / Mirrabei Dr", + "Mirrebei Drive / Dam Wall"=>"Mirrabei Drive / Dam Wall", + "Tharwa / Knoke" => "Tharwa Drive / Knoke Ave", + "Tharwa / Pocket" => "Tharwa Dr / Pockett Ave", + "Outrim / Duggan" => "Outtrim / Duggan", + "ANU Burton and Garran Hall Daley Rd" => "Burton and Garran Hall Daley Road", + "Farrer Primary"=>"Farrer Primary School", + "St Thomas More Campbell"=>"St Thomas More's Campbell", + "Lyneham Shops"=>"Lyneham Shops Wattle Street", + + +} + time_point_corrections.each do |wrong, right| + $time_points_sources[wrong].each do |wrongfile| + badtimetable = YAML::load_file(wrongfile) + badentrynumber = badtimetable["time_points"].index wrong + badtimetable["time_points"][badentrynumber] = right + puts "Corrected '" + wrong + "' to '" + right + "' in " + wrongfile + File.open(wrongfile, "w") do |f| + f.write badtimetable.to_yaml + end + end + end +end getTimePoints() #pp $time_points.sort! #pp $time_points_sources.sort -time_point_corrections = {"North Lynehamham" => "North Lyneham", - "Lathlain St Platform 2" => "Lathlain St Bus Station - Platform 2", - "Lathlain St Sation - Platform 5" => "Lathlain St Bus Station - Platform 5", - "Lathlain Steet Station" => "Lathlain St Bus Station", - "Lathlain St - Platform 3" => "Lathlain St Bus Station - Platform 3", - "Lathlain Steet Station - Platform 3" => "Lathlain St Bus Station - Platform 3", - "Lathlain St Station" => "Lathlain St Bus Station", - "Lathlain St Station - Platform 1" => "Lathlain St Bus Station - Platform 1", - "Lathlain St Station - Platform 2" => "Lathlain St Bus Station - Platform 2", - "Lathlain St Station - Platform 3" => "Lathlain St Bus Station - Platform 3", - "Lathlain St Station - Platform 4" => "Lathlain St Bus Station - Platform 4", - "Lathlain St Station - Platform 5" => "Lathlain St Bus Station - Platform 5", - "Lathlain St Station - Platform 6" => "Lathlain St Bus Station - Platform 6", - "Flemington Rd, Sandford St" => "Flemington Rd/Sandford St", - "Erindale Centre / - Sternberg Crescent" => "Erindale Drive/Sternberg", - "Canberra Hospita" => "Canberra Hospital", - "Cohen Str Station - Platform 1" => "Cohen St Bus Station - Platform 1", - "Cohen Street Station" => "Cohen St Bus Station", - "Cohen Street Station - Platform 2" => "Cohen St Bus Station - Platform 2", - "Cohn St Station - Platform 3" => "Cohen St Bus Station - Platform 3", - "Cohen St Station" => "Cohen St Bus Station", - "Cohen St Station - Platform 1" => "Cohen St Bus Station - Platform 1", - "Cohen St Station - Platform 2" => "Cohen St Bus Station - Platform 2", - "Cohen St Station - Platform 3" => "Cohen St Bus Station - Platform 3", - "Cohen St Station - Platform 4" => "Cohen St Bus Station - Platform 4", - "Cohen St Station - Platform 5" => "Cohen St Bus Station - Platform 5", - "Cohen St Station - Platform 6" => "Cohen St Bus Station - Platform 6", - "City - Platform 7" => "City Interchange - Platform 7", - "Cameron Avenue Station" => "Cameron Ave Bus Station", - "Cameron Avenue Station - Platform 1" => "Cameron Ave Bus Station - Platform 1", - "Cameron Avenue Station - Platform 2" => "Cameron Ave Bus Station - Platform 2", - "Cameron Avenue Station - Platform 3" => "Cameron Ave Bus Station - Platform 3", - "Cameron Avenue Station - Platform 4" => "Cameron Ave Bus Station - Platform 4", - "Cameron Avenue Station - Platform 5" => "Cameron Ave Bus Station - Platform 5", - "Cameron Ave Station" => "Cameron Ave Bus Station", - "Cameron Ave Station - Platform 1" => "Cameron Ave Bus Station - Platform 1", - "Cameron Ave Station - Platform 2" => "Cameron Ave Bus Station - Platform 2", - "Cameron Ave Station - Platform 3" => "Cameron Ave Bus Station - Platform 3", - "Cameron Ave Station - Platform 4" => "Cameron Ave Bus Station - Platform 4", - "Cameron Ave Station - Platform 5" => "Cameron Ave Bus Station - Platform 5", - "Burton & Garranan Hall, Daley Road ANU" => "Burton & Garran Hall/Daley Road ANU", - "Burton & Garranan Hall,Daley Road ANU" => "Burton & Garran Hall/Daley Road ANU", - "Garran/Daley Rd" => "Burton & Garran Hall/Daley Road ANU", - "Kingstons Ave/National Crt" => "Kings Ave/National Crt", - "Newcastle Street after Isa St" => "Newcastle / Isa Street Fyshwick", - "National Circ/Canberra Ave" => "National Circuit / Canberra Ave", - "St Clare of Conder" => "St Clare of Assisi Primary", - "McKillop College Isabella Campus" => "MacKillop College Isabella Campus", - "Outrim / Duggan" => "Outtrim / Duggan", - "Manuka Captain Cook" => "Manuka/Captain Cook", - "Manuka, Captain Cook" => "Manuka/Captain Cook", - "Hospice, Menindee Drive" => "Hospice", - "Tharwa/Pocket" => "Tharwa/Pockett", - "Paul-Co / Mirrabei" => "Paul Coe / Mirrabei" - } -time_point_corrections.each do |wrong, right| - $time_points_sources[wrong].each do |wrongfile| - badtimetable = YAML::load_file(wrongfile) - badentrynumber = badtimetable["time_points"].index wrong - badtimetable["time_points"][badentrynumber] = right - puts "Corrected '" + wrong + "' to '" + right + "' in " + wrongfile - File.open(wrongfile, "w") do |f| - f.write badtimetable.to_yaml - end - end -end +correctTimePoints() +getTimePoints() +correctTimePoints() getTimePoints() pp $time_points.sort! --- a/maxious-canberra-transit-feed/03-locatetimepoints.rb +++ b/maxious-canberra-transit-feed/03-locatetimepoints.rb @@ -1,10 +1,10 @@ #!/usr/bin/ruby -require 'postgres' require 'highline.rb' include HighLine require 'rubygems' +require 'postgres' require 'json' require 'net/http' def cbr_geocode(query) @@ -12,7 +12,7 @@ url = "#{base_url}#{URI.encode(query)}&bbox=-35.47,148.83,-35.16,149.25&return_location=true" resp = Net::HTTP.get_response(URI.parse(url)) data = resp.body - +pp url # we convert the returned JSON data to native Ruby # data structure - a hash result = JSON.parse(data) @@ -51,13 +51,11 @@ connbus = PGconn.connect("localhost", 5432, '', '', "bus", "postgres", "snmc") -connosm = PGconn.connect("localhost", 5432, '', '', "openstreetmap", -"postgres", "snmc") if ask_if("Insert Timing Point names to database?") $time_points.each do |time_point| begin - time_point = time_point.gsub(/\\/, '\&\&').gsub(/'/, "''").gsub("St", "%") + time_point = time_point.gsub(/\\/, '\&\&').gsub(/'/, "''") # DON'T PUT MORE GSUB HERE res = connbus.exec("INSERT INTO timing_point (name) VALUES ('#{time_point}')") puts "Put '#{time_point}' into DB" rescue PGError => e @@ -68,164 +66,6 @@ end -if ask_if("Fill null Timing Points from OSM bus_stop database?") -# TODO Where there's a "Cnr" or a \/ or a &, Look for 2 ways or nodes and average the closest two! - begin - null_points = connbus.exec('SELECT name FROM timing_point WHERE lat IS null OR lng IS null;') - rescue PGError => e - puts "Error selecting null points from DB #{e}" - #conn.close() if conn - end - - null_points.each do |null_point_name| - begin - name = null_point_name.to_s.gsub(/\\/, '\&\&').gsub(/'/, "''") - pp name - search_name = ask("Hmm, if we're still looking, the name is probably wrong. What's the right name?", :string, :default => name) - matching_nodes = connosm.exec("Select * FROM (SELECT * from current_node_tags, - (Select id as ctagid FROM current_node_tags WHERE v LIKE '%#{search_name}%') as a - where a.ctagid = current_node_tags.id) as ctags INNER JOIN current_nodes ON - ctags.id=current_nodes.id") - rescue PGError => e - puts "Error selecting matching bus stops from DB #{e}" - #conn.close() if conn - end - suggested_nodes = Hash.new() - - matching_nodes.each do |matching_node_row| - #pp matching_node_row - # 0 = id - # 1 = k - # 2 = v - # 3,4 = redundant ids - # 5 = lat*100000 - # 6 = lng*100000 - suggested_node = suggested_nodes.fetch(matching_node_row[0], {'lat' => Float(matching_node_row[5])/10000000, - 'lng' => Float(matching_node_row[6])/10000000}) - if matching_node_row[1] == "ref" - matching_node_row[1] = "loc_ref" - end - suggested_node[matching_node_row[1]] = matching_node_row[2] - suggested_nodes[matching_node_row[0]] = suggested_node - end - pp suggested_nodes - nodeID = ask("Enter selected node ID:", :string) - if suggested_nodes.has_key?(nodeID) - node = suggested_nodes.fetch(nodeID) - guess = ask_if("Is this a guess?") - puts "Location #{node["lat"]},#{node["lng"]} for #{null_point_name}" - begin - res = connbus.exec("UPDATE timing_point SET lat = #{node["lat"]*10000000}, lng = -#{node["lng"]*10000000},osm_node = #{nodeID}" + (node.has_key?("loc_ref") ? ",loc_ref = #{node["loc_ref"]}" : "") + ",guess = #{guess} WHERE name -= '#{name}'") - puts "Put '#{null_point_name}' into DB" - rescue PGError => e - puts "Error inserting '#{null_point_name}' to DB #{e}" - ask_if("Continue?") - #conn.close() if conn - end - else - puts "Uhh, there was no suggestion ID like that. Try again next time!" - end - - puts "Hmm, so maybe this isn't a point? Maybe it's a way.... like a street or something? Is it a 'street' or a 'corner' or nothing?" - whatisit = ask("So what is it:", :string, :default => "corner") - if whatisit == "street" - begin - name = null_point_name.to_s.gsub(/\\/, '\&\&').gsub(/'/, "''") - pp "#{name} (ways)" - search_name = ask("Streets tend to have pretty bad quality data, What's the real name of the street?", :string, :default => name) - matching_ways = connosm.exec("Select avg(latitude), avg(longitude), name FROM ( - SELECT * from current_way_nodes,(Select id as ctagid, v as name FROM current_way_tags WHERE k = 'name' AND v LIKE - '%#{search_name}%') as a where a.ctagid = current_way_nodes.id) as ctags INNER JOIN current_nodes ON ctags.node_id=current_nodes.id - GROUP BY name") - rescue PGError => e - puts "Error selecting matching ways from DB #{e}" - #conn.close() if conn - end - suggested_ways = Hash.new() - - matching_ways.each do |matching_way_row| - #pp matching_way_row - # 0 = lat*100000 - # 1 = lng*100000 - # 2 = name - suggested_way = suggested_ways.fetch(matching_way_row[2], {'lat' => Float(matching_way_row[0])/10000000, - 'lng' => Float(matching_way_row[1])/10000000}) - suggested_way['name'] = suggested_way['name'] - suggested_ways[matching_way_row[2]] = suggested_way - end - pp suggested_ways - wayID = ask("Enter selected way ID:", :string) - if suggested_ways.has_key?(wayID) - way = suggested_ways.fetch(wayID) - guess = ask_if("Is this a guess?") - puts "Location #{way["lat"]},#{way["lng"]} for #{null_point_name}" - begin - res = connbus.exec("UPDATE timing_point SET lat = #{way["lat"]*10000000}, lng = - #{way["lng"]*10000000},guess = #{guess} WHERE name = '#{name}'") - puts "Put '#{null_point_name}' into DB" - rescue PGError => e - puts "Error inserting '#{null_point_name}' to DB #{e}" - ask_if("Continue?") - #conn.close() if conn - end - else - puts "Uhh, there was no suggestion ID like that. Try again next time!" - end - end - if whatisit == "corner" - # Where there's a "Cnr" or a \/ or a &, look for 2 ways and find the intersections - - name = null_point_name.to_s.gsub(/\\/, '\&\&').gsub(/'/, "''") - search_name = ask("I need this to look like STREETNAME1/STREETNAME2, okay? Can you do that for me?", :string, :default => name) - search_pieces = search_name.split("/") - pp search_pieces - if search_pieces.length == 2 - begin - matching_ways = connosm.exec("SELECT w.way_id, latitude, longitude, w.node_id from (Select current_way_nodes.id as way_id, * from current_nodes inner join current_way_nodes on current_nodes.id=current_way_nodes.node_id inner join current_ways on current_way_nodes.id=current_ways.id) as w, (select node_id, count(node_id) from - (Select * FROM (SELECT * from current_way_nodes, (Select id as ctagid, v as name FROM current_way_tags WHERE k = 'name' AND v LIKE '%#{search_pieces[0]}%') as a where a.ctagid = current_way_nodes.id ) as ctags INNER JOIN current_nodes ON ctags.node_id=current_nodes.id where sequence_id = 1 union Select * FROM ( SELECT * from current_way_nodes, (Select id as ctagid, v as name FROM current_way_tags WHERE k = 'name' AND v LIKE '%#{search_pieces[0]}%') as a where a.ctagid = current_way_nodes.id ) as ctags INNER JOIN current_nodes ON ctags.node_id=current_nodes.id where sequence_id = (select max(sequence_id) from current_way_nodes cnodes where cnodes.id = ctags.id) union Select * FROM ( SELECT * from current_way_nodes, (Select id as ctagid, v as name FROM current_way_tags WHERE k = 'name' AND v LIKE '%#{search_pieces[1]}%') as a where a.ctagid = current_way_nodes.id ) as ctags INNER JOIN current_nodes ON ctags.node_id=current_nodes.id where sequence_id = 1 union Select * FROM ( SELECT * from current_way_nodes, (Select id as ctagid, v as name FROM current_way_tags WHERE k = 'name' AND v LIKE '%#{search_pieces[1]}%') as a where a.ctagid = current_way_nodes.id ) as ctags INNER JOIN current_nodes ON ctags.node_id=current_nodes.id where sequence_id = (select max(sequence_id) from current_way_nodes cnodes where cnodes.id = ctags.id) ) as t GROUP BY node_id HAVING ( COUNT(node_id) > 1 ) ) as s where s.node_id = w.node_id") - rescue PGError => e - puts "Error selecting matching bus stops from DB #{e}" - #conn.close() if conn - end - suggested_ways = Hash.new() - - matching_ways.each do |matching_way_row| - pp matching_way_row - # 0 = way_id - # 1 = lat*100000 - # 2 = lng*100000 - # 3 = node_id - suggested_way = suggested_ways.fetch(matching_way_row[3], {'lat' => Float(matching_way_row[1])/10000000, - 'lng' => Float(matching_way_row[2])/10000000}) - suggested_way['way_id'] = " " + matching_way_row[0] - suggested_way['node_id'] = matching_way_row[3] - suggested_ways[matching_way_row[3]] = suggested_way - end - pp suggested_ways - wayID = ask("Enter selected way ID:", :string) - if suggested_ways.has_key?(wayID) - way = suggested_ways.fetch(wayID) - guess = ask_if("Is this a guess?") - puts "Location #{way["lat"]},#{way["lng"]} for #{null_point_name}" - begin - res = connbus.exec("UPDATE timing_point SET lat = #{way["lat"]*10000000}, lng = - #{way["lng"]*10000000},osm_node = #{wayID} ,guess = #{guess} WHERE name - = '#{name}'") - puts "Put '#{null_point_name}' into DB" - rescue PGError => e - puts "Error inserting '#{null_point_name}' to DB #{e}" - ask_if("Continue?") - #conn.close() if conn - end - else - puts "Uhh, there was no suggestion ID like that. Try again next time!" - end - end - end - end -end if ask_if("Fill null Timing Points from geocoder?") begin null_points = connbus.exec('SELECT name FROM timing_point WHERE lat IS null OR lng IS null;') @@ -237,7 +77,7 @@ null_points.each do |null_point_name| pp null_point_name name = null_point_name.to_s.gsub(/\\/, '\&\&').gsub(/'/, "''") - results = cbr_geocode(null_point_name[0]) + results = cbr_geocode(null_point_name.to_s.gsub("Shops", "")) if !results.empty? results['features'].each_with_index { |feature,index| print "#{index}: #{feature['properties']['name']} (#{feature['location']}) => #{feature['centroid']['coordinates']}\n" --- a/maxious-canberra-transit-feed/04-generateymlinclude.rb +++ b/maxious-canberra-transit-feed/04-generateymlinclude.rb @@ -1,10 +1,10 @@ #!/usr/bin/ruby -require 'postgres' require 'highline.rb' include HighLine require 'rubygems' +require 'postgres' require 'json' require 'yaml' require 'pp' @@ -19,7 +19,7 @@ f2.puts header f2.puts "stops:\n"; begin - time_points = connbus.exec("SELECT * from timing_point") + time_points = connbus.exec("SELECT * from timing_point ORDER BY name") rescue PGError => e puts "Error reading from DB #{e}" #conn.close() if conn @@ -30,7 +30,23 @@ # 1 = lat*100000 # 2 = lng*100000 + #pp time_point[0] f2.puts " - { name: #{time_point[0]},stop_code: #{time_point[0]}, lat: #{Float(time_point[1])/10000000}, lng: #{Float(time_point[2])/10000000}}" + end + begin + stops = connbus.exec("SELECT * from stops") + rescue PGError => e + puts "Error reading from DB #{e}" + #conn.close() if conn + end + stops.each do |stop| + #pp stop + # 0 = geoPo + # 1 = lat*100000 + # 2 = lng*100000 + # 3 = name + #pp time_point[0] + f2.puts " - { name: #{stop[3]},stop_code: #{stop[0]}, lat: #{Float(stop[1])/10000000}, lng: #{Float(stop[2])/10000000}}" end f2.puts "routes:\n"; end --- /dev/null +++ b/maxious-canberra-transit-feed/04-locatebetweenpoints.reversegeocode.php @@ -1,1 +1,38 @@ +<?php +function getPage($url) +{ + $ch = curl_init($url); +curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 ); +curl_setopt( $ch, CURLOPT_HEADER, 0 ); +$page = curl_exec($ch); +curl_close($ch); +return $page; +} +// +// http://developers.cloudmade.com/wiki/geocoding-http-api/Documentation +$conn = pg_connect("dbname=bus user=postgres password=snmc"); +if (!$conn) { + echo "An error occured.\n"; + exit; +} +$sql = "Select * from stops where name is null"; + $result_stops = pg_query($conn, $sql); + if (!$result_stops) { + cho("Error in SQL query: " . pg_last_error() ."<br>\n"); + } + while ($stop = pg_fetch_assoc($result_stops)) { + echo "Processing ".$stop['geohash'] . " ... "; + $url = "http://geocoding.cloudmade.com/daa03470bb8740298d4b10e3f03d63e6/geocoding/v2/find.js?around=".($stop['lat']/10000000).",".($stop['lng']/10000000)."&distance=closest&object_type=road"; + $contents = json_decode(getPage($url)); + $name = $contents->features[0]->properties->name; + echo "Saving $name ! <br>" ; + $result_save = pg_query($conn, "UPDATE stops set name = '".pg_escape_string($name)."' where geohash = '{$stop['geohash']}' "); + if (!$result_save) { + echo("Error in SQL query: " . pg_last_error() ."<br>\n"); + } + flush(); + } +?> + + --- /dev/null +++ b/maxious-canberra-transit-feed/05-addbetweenpointstotimetables.rb @@ -1,1 +1,53 @@ +require 'rubygems' +require 'postgres' +require 'pp' +require 'yaml' +class String + def escape_single_quotes + self.gsub(/'/, "''") + end +end +class Array + def to_yaml_style + :inline + end +end +Dir.chdir("output") +connbus = PGconn.connect("localhost", 5432, '', '', "bus", "postgres", "snmc") + +Dir.glob("*.yml") { |file| + timetable = YAML::load_file(file) + if timetable + route_name = timetable["short_name"] + timetable["between_stops"] = {} + for i in 0..timetable["time_points"].length-2 + begin + searchFrom = timetable["time_points"][i].escape_single_quotes.split("(")[0].strip + searchTo = timetable["time_points"][i+1].escape_single_quotes.split("(")[0].strip + # print "SELECT * from between_stops + # WHERE fromlocation = '#{searchFrom}' + # AND tolocation = '#{searchTo}' AND routes LIKE '%#{route_name};%'" + between_points = connbus.exec("SELECT * from between_stops + WHERE fromlocation = '#{searchFrom}' + AND tolocation = '#{searchTo}' AND routes LIKE '%#{route_name};%'") + rescue PGError => e + puts "Error selecting matching between points from DB #{e}" + #conn.close() if conn + end + between_points.each do |between_point_row| + points = between_point_row['points'].split(";") + points.delete("") + timetable["between_stops"][timetable["time_points"][i] + '-' +timetable["time_points"][i+1]] = points; + end + end + #pp timetable["between_stops"] + File.open(file, "w") do |f| + f.write timetable.to_yaml + end + + else + print "error, #{file} empty\n" + end +} + --- a/maxious-canberra-transit-feed/05-cleanupyaml.sh +++ /dev/null @@ -1,3 +1,1 @@ -#!/bin/bash -sed -i "s/- ---/- /g" cbrtable.yml --- a/maxious-canberra-transit-feed/05-generateymlinclude.rb +++ /dev/null @@ -1,53 +1,1 @@ -#!/usr/bin/ruby -require 'postgres' -require 'highline.rb' -include HighLine - -require 'rubygems' -require 'json' -require 'yaml' -require 'pp' -# make - { name: Civic Interchange Platform 1,stop_code: civic_platform_1, lat: -35.2794347, lng: 149.130588} -connbus = PGconn.connect("localhost", 5432, '', '', "bus", "postgres", "snmc") - -f = File.open('cbrtable.yml.in.in') -header = f.readlines -f.close - -File.open('cbrtable.yml.in', 'w') do |f2| - f2.puts header - f2.puts "stops:\n"; - begin - time_points = connbus.exec("SELECT * from timing_point ORDER BY name") - rescue PGError => e - puts "Error reading from DB #{e}" - #conn.close() if conn - end - time_points.each do |time_point| - #pp time_point - # 0 = name - - # 1 = lat*100000 - # 2 = lng*100000 - #pp time_point[0] - f2.puts " - { name: #{time_point[0]},stop_code: #{time_point[0]}, lat: #{Float(time_point[1])/10000000}, lng: #{Float(time_point[2])/10000000}}" - end - begin - stops = connbus.exec("SELECT * from stops") - rescue PGError => e - puts "Error reading from DB #{e}" - #conn.close() if conn - end - stops.each do |stop| - #pp stop - # 0 = geoPo - # 1 = lat*100000 - # 2 = lng*100000 - #pp time_point[0] - f2.puts " - { name: #{stop[0]},stop_code: #{stop[0]}, lat: #{Float(stop[1])/10000000}, lng: #{Float(stop[2])/10000000}}" - end - f2.puts "routes:\n"; -end - - --- a/maxious-canberra-transit-feed/900-intertown.yml +++ b/maxious-canberra-transit-feed/900-intertown.yml @@ -1,7 +1,9 @@ short_name: 900 long_name: Intertown time_points: [ civic_platform_6, 3042, 4531, 4929, civic_platform_1, civic_platform_5 ] -between_stops: [ ] +between_stops: [ +civic_platform_6-3042: [ADFA] +] stop_times: [ [ 632a, 642a, 657a, 708a, 715a, 727a], [ 702a, 712a, 727a, 738a, 745a, 757a], --- a/maxious-canberra-transit-feed/Makefile +++ b/maxious-canberra-transit-feed/Makefile @@ -1,19 +1,21 @@ default: cbrfeed.zip cbrfeed.zip: cbrtable.yml createfeed.py + sh 06-cleanupyaml.sh ./createfeed.py --input=cbrtable.yml --output=cbrfeed.zip cbrtable.yml: cbrtable.yml.in indent-route.pl cp cbrtable.yml.in cbrtable.yml @$(foreach ROUTE_FILE, $(wildcard output/*), \ echo "Parsing $(ROUTE_FILE)"; \ - echo "TODO: replace friendly timing spot names with OSM node IDs or geohash in $(ROUTE_FILE)"; \ - echo "TODO: add inbetween stops in $(ROUTE_FILE)"; \ - ./indent-route.pl < $(ROUTE_FILE) >> cbrtable.yml;) + ./indent-route.pl < "$(ROUTE_FILE)" >> cbrtable.yml;) cbrtable.yml.in: cbrtable.yml.in.in - ruby 04-generateymlinclude.rb + ruby 01-extracttimes.rb + ruby 02-tidytimepoints.rb + ruby 04-generateymlinclude.rb + ruby 05-addbetweenpointstotimetables.rb clean: - rm -f cbrtable.yml cbrtable.yml.in cbrfeed.zip *~ + rm -f cbrtable.yml cbrtable.yml.in cbrfeed.zip *~ output/* --- a/maxious-canberra-transit-feed/README +++ b/maxious-canberra-transit-feed/README @@ -1,10 +1,9 @@ === Introduction === This distribution contains everything required to build a basic google transit -feed for Halifax Metro Transit, Nova Scotia, Canada. Note that it is woefully -incomplete at the moment. +feed for Canberra, Australia. Note that it is woefully incomplete at the moment. -Requirements: GNU Make, Perl, Python 2.5. +Requirements: GNU Make, Perl, Python 2.5, PHP, Ruby, libpq (postgres-devel package on Fedora), postgres,json gem for Ruby, libyaml and pyyaml for Python === Usage === @@ -21,7 +20,7 @@ Then just type "make" to build the feed. The output at the end is "feed.zip". For fun, you can view this feed using the snazzy transit feed view application: -$HOME/src/transitfeed-1.1.7/python/schedule_viewer.py --feed=hfxfeed.zip +$HOME/src/transitfeed-1.1.7/python/schedule_viewer.py --feed=cbrfeed.zip === Copyright === @@ -29,7 +28,7 @@ License, please consider all software tools in distribution to be in the public domain. Use them for what you will. -I believe the Metro Transit route data is considered factual information -which can not be copyrighted. Note, however, that Metro Transit and/or -the city of Halifax may have claim over its own name and other trademarks. +I believe the ACTION busses route data is considered factual information +which can not be copyrighted. Note, however, that ACTION busses and/or +the ACT Government may have claim over its own name and other trademarks. --- a/maxious-canberra-transit-feed/add-between-times.pl +++ /dev/null @@ -1,104 +1,1 @@ -#!/usr/bin/perl -use strict; - -sub parse_time { - my ($time) = @_; - - my ($hour, $minute); - - if ($time =~ /a\Z/) { - $time =~ m/([0-9]+)([0-9][0-9])a/; - ($hour, $minute) = ($1, $2); - } elsif ($time =~ /p\Z/) { - $time =~ m/([0-9]+)([0-9][0-9])p/; - ($hour, $minute) = ($1, $2); - if ($hour < 12) { - $hour += 12; - } - } elsif ($time =~ /x\Z/) { - $time =~ m/([0-9]+)([0-9][0-9])x/; - ($hour, $minute) = ($1, $2); - if ($hour == 12) { - $hour += 12; - } else { - $hour += 24; - } - } elsif ($time =~ /^\ *-\Z/) { - ($hour, $minute) = (0, 0); - # no stop at this time - } else { - print "Should not happen! Time ('$time') misformed.\n"; - exit; - } - - return ($hour, $minute); -} - -my $num_intervals = $ARGV[0] or die "No num intervals given!"; -my $interval = $ARGV[1] or die "No interval given!"; - -my @times; - -$_ = <STDIN>; -print $_; - -if ($_ !~ /^\#/) { - my @timestrs; - if ($_ =~ m/\[(.*)\]/) { - my $inner = $1; - @timestrs = split (/\,/, $inner); - - } else { - @timestrs = split /\ /; - } - - foreach (@timestrs) { - my ($hour, $minute) = parse_time($_); - push @times, [ $hour, $minute ]; - } -} - -for (my $i=1; $i<($num_intervals+1); $i++) { - my $first = 1; - foreach (@times) { - my $mytime = $_; - my ($hour, $minute) = (@$mytime[0], @$mytime[1]); - if ($hour > 0 || $minute > 0) { - $minute += $interval * $i; - if ($minute > 59) { - $hour += int($minute / 60); - $minute = $minute % 60; - if ($minute < 10) { - $minute = "0" . $minute; - } - } - } - - sub print_time { - my ($hour, $minute) = @_; - if ($hour == 0 && $minute == 0) { - print "-"; - } else { - if ($hour < 12) { - print "$hour$minute" . "a"; - } else { - if ($hour > 12) { - $hour -= 12; - } - print "$hour$minute" . "p"; - } - } - } - - if (!$first) { - print " "; - print_time($hour, $minute); - } else { - $first = 0; - print_time($hour, $minute); - } - } -print "\n"; -} - --- a/maxious-canberra-transit-feed/cbrtable.yml +++ b/maxious-canberra-transit-feed/cbrtable.yml @@ -8,185 +8,232 @@ stops: + - { name: ACTEW AGL House,stop_code: ACTEW AGL House, lat: -35.282374, lng: 149.132047} - { name: ADFA,stop_code: ADFA, lat: -35.2937972, lng: 149.1643403} - { name: Ainslie,stop_code: Ainslie, lat: -35.2620105, lng: 149.1443302} - - { name: Alexander Maconochie Centre Hume,stop_code: Alexander Maconochie Centre Hume, lat: -35.3720651, lng: 149.1696618} + - { name: Ainslie Shops,stop_code: Ainslie Shops, lat: -35.26198, lng: 149.14535} + - { name: Alexander Maconochie Centre,stop_code: Alexander Maconochie Centre, lat: -35.3720651, lng: 149.1696618} - { name: Alpen & Clifford St,stop_code: Alpen & Clifford St, lat: -35.20562, lng: 149.06259} - - { name: Anthony Rolfe/Moonlight,stop_code: Anthony Rolfe/Moonlight, lat: -35.1856021, lng: 149.1543639} + - { name: Anthony Rolfe Av / Moonlight Av,stop_code: Anthony Rolfe Av / Moonlight Av, lat: -35.1856021, lng: 149.1543639} - { name: Aranda,stop_code: Aranda, lat: -35.257534, lng: 149.0762963} - - { name: Athllon/Sulwood Kambah,stop_code: Athllon/Sulwood Kambah, lat: -35.38442, lng: 149.09328} - - { name: Australian Institute Sports Bruce,stop_code: Australian Institute Sports Bruce, lat: -35.246351, lng: 149.101478} + - { name: Aranda Shops,stop_code: Aranda Shops, lat: -35.25753, lng: 149.0763} + - { name: Athllon / Sulwood Kambah,stop_code: Athllon / Sulwood Kambah, lat: -35.38442, lng: 149.09328} + - { name: Australian Institute of Sport,stop_code: Australian Institute of Sport, lat: -35.246351, lng: 149.101478} + - { name: Belconnen Community Bus Station,stop_code: Belconnen Community Bus Station, lat: -35.23987, lng: 149.0619} + - { name: Belconnen Community Bus Station (Platform 1),stop_code: Belconnen Community Bus Station (Platform 1), lat: -35.23982, lng: 149.06978} + - { name: Belconnen Community Bus Station (Platform 2),stop_code: Belconnen Community Bus Station (Platform 2), lat: -35.23982, lng: 149.06926} + - { name: Belconnen Community Bus Station (Platform 3),stop_code: Belconnen Community Bus Station (Platform 3), lat: -35.23986, lng: 149.06847} + - { name: Belconnen Community Bus Station (Platform 4),stop_code: Belconnen Community Bus Station (Platform 4), lat: -35.23994, lng: 149.06887} + - { name: Belconnen Community Bus Station (Platform 5),stop_code: Belconnen Community Bus Station (Platform 5), lat: -35.23994, lng: 149.06928} + - { name: Belconnen Community Bus Station (Platform 6),stop_code: Belconnen Community Bus Station (Platform 6), lat: -35.23994, lng: 149.0698} - { name: Belconnen Way,stop_code: Belconnen Way, lat: -35.24809, lng: 149.06765} - { name: Bimberi Centre,stop_code: Bimberi Centre, lat: -35.2219941, lng: 149.1546928} - { name: Black Mountain Telstra Tower,stop_code: Black Mountain Telstra Tower, lat: -35.2748058, lng: 149.0972461} - { name: Bonython,stop_code: Bonython, lat: -35.4297416, lng: 149.0814517} - - { name: Bonython Primary,stop_code: Bonython Primary, lat: -35.431019, lng: 149.0831217} + - { name: Bonython Primary School,stop_code: Bonython Primary School, lat: -35.431019, lng: 149.0831217} - { name: Botanic Gardens,stop_code: Botanic Gardens, lat: -35.278643, lng: 149.1093237} - { name: Brindabella Business Park,stop_code: Brindabella Business Park, lat: -35.314496, lng: 149.189145} - { name: Brindabella Gardens Nursing Home,stop_code: Brindabella Gardens Nursing Home, lat: -35.3294459, lng: 149.0806116} - - { name: Bugden/Sternberg,stop_code: Bugden/Sternberg, lat: -35.4017223, lng: 149.0992172} - - { name: Burton & Garran Hall/Daley Road ANU,stop_code: Burton & Garran Hall/Daley Road ANU, lat: -35.2753671, lng: 149.1172822} + - { name: Bugden Sternberg,stop_code: Bugden Sternberg, lat: -35.4017223, lng: 149.0992172} + - { name: Burton and Garran Hall Daley Road,stop_code: Burton and Garran Hall Daley Road, lat: -35.2753671, lng: 149.1172822} - { name: Calvary Hospital,stop_code: Calvary Hospital, lat: -35.25212, lng: 149.09088} - { name: Calwell Shops,stop_code: Calwell Shops, lat: -35.43524, lng: 149.113942} - { name: Cameron Ave Bus Station,stop_code: Cameron Ave Bus Station, lat: -35.2410195, lng: 149.0722506} - - { name: Cameron Ave Bus Station - Platform 1,stop_code: Cameron Ave Bus Station - Platform 1, lat: -35.2410195, lng: 149.0722506} - - { name: Cameron Ave Bus Station - Platform 2,stop_code: Cameron Ave Bus Station - Platform 2, lat: -35.2410108, lng: 149.0717142} - - { name: Cameron Ave Bus Station - Platform 3,stop_code: Cameron Ave Bus Station - Platform 3, lat: -35.2410064, lng: 149.0710758} - - { name: Cameron Ave Bus Station - Platform 4,stop_code: Cameron Ave Bus Station - Platform 4, lat: -35.2411773, lng: 149.0709793} - - { name: Cameron Ave Bus Station - Platform 5,stop_code: Cameron Ave Bus Station - Platform 5, lat: -35.241186, lng: 149.0720789} + - { name: Cameron Ave Bus Station (Platform 1),stop_code: Cameron Ave Bus Station (Platform 1), lat: -35.2410195, lng: 149.0722506} + - { name: Cameron Ave Bus Station (Platform 2),stop_code: Cameron Ave Bus Station (Platform 2), lat: -35.2410108, lng: 149.0717142} + - { name: Cameron Ave Bus Station (Platform 3),stop_code: Cameron Ave Bus Station (Platform 3), lat: -35.2410064, lng: 149.0710758} + - { name: Cameron Ave Bus Station (Platform 4),stop_code: Cameron Ave Bus Station (Platform 4), lat: -35.2411773, lng: 149.0709793} + - { name: Cameron Ave Bus Station (Platform 5),stop_code: Cameron Ave Bus Station (Platform 5), lat: -35.241186, lng: 149.0720789} - { name: Campbell Park Offices,stop_code: Campbell Park Offices, lat: -35.28368, lng: 149.17045} - - { name: Canberra College Weston,stop_code: Canberra College Weston, lat: -35.3490278, lng: 149.0486277} + - { name: Canberra College Weston Campus,stop_code: Canberra College Weston Campus, lat: -35.3490278, lng: 149.0486277} - { name: Canberra Hospital,stop_code: Canberra Hospital, lat: -35.3459462, lng: 149.1012001} - { name: Canberra Times,stop_code: Canberra Times, lat: -35.3245431, lng: 149.1705533} - { name: Caswell Drive,stop_code: Caswell Drive, lat: -35.25922, lng: 149.08576} - { name: Causeway,stop_code: Causeway, lat: -35.31615, lng: 149.15058} - - { name: Centre Link Tuggeranong,stop_code: Centre Link Tuggeranong, lat: -35.4207496, lng: 149.0700973} + - { name: Centrelink Tuggeranong,stop_code: Centrelink Tuggeranong, lat: -35.4207496, lng: 149.0700973} - { name: Chapman,stop_code: Chapman, lat: -35.3557877, lng: 149.0408111} + - { name: Chapman Shops,stop_code: Chapman Shops, lat: -35.35579, lng: 149.04082} - { name: Charnwood,stop_code: Charnwood, lat: -35.2052138, lng: 149.0337266} + - { name: Charnwood Shops,stop_code: Charnwood Shops, lat: -35.20472, lng: 149.03336} + - { name: Charnwood Tillyard Dr,stop_code: Charnwood Tillyard Dr, lat: -35.20295, lng: 149.04027} - { name: Chifley,stop_code: Chifley, lat: -35.350985, lng: 149.077319} + - { name: Chifley Shops,stop_code: Chifley Shops, lat: -35.35099, lng: 149.07732} - { name: Chisholm Shops,stop_code: Chisholm Shops, lat: -35.41341, lng: 149.12833} - - { name: Chuculba/William Slim,stop_code: Chuculba/William Slim, lat: -35.2103241, lng: 149.0997736} - - { name: City Interchange,stop_code: City Interchange, lat: -35.2794346, lng: 149.1305879} - - { name: City Interchange - Platform 1,stop_code: City Interchange - Platform 1, lat: -35.2794346, lng: 149.1305879} - - { name: City Interchange - Platform 10,stop_code: City Interchange - Platform 10, lat: -35.2793571, lng: 149.1293659} - - { name: City Interchange - Platform 11,stop_code: City Interchange - Platform 11, lat: -35.2787905, lng: 149.1288627} - - { name: City Interchange - Platform 3,stop_code: City Interchange - Platform 3, lat: -35.2787886, lng: 149.1304779} - - { name: City Interchange - Platform 4,stop_code: City Interchange - Platform 4, lat: -35.2785658, lng: 149.1301727} - - { name: City Interchange - Platform 5,stop_code: City Interchange - Platform 5, lat: -35.2785242, lng: 149.1297348} - - { name: City Interchange - Platform 7,stop_code: City Interchange - Platform 7, lat: -35.27843, lng: 149.130345} - - { name: City Interchange - Platform 8,stop_code: City Interchange - Platform 8, lat: -35.2778798, lng: 149.1305995} - - { name: City Interchange - Platform 9,stop_code: City Interchange - Platform 9, lat: -35.2783224, lng: 149.130726} - - { name: Citywest,stop_code: Citywest, lat: -35.2788605, lng: 149.1257969} + - { name: Chuculba / William Slim Dr,stop_code: Chuculba / William Slim Dr, lat: -35.208931, lng: 149.088499} + - { name: CIT Weston,stop_code: CIT Weston, lat: -35.330234, lng: 149.058632} + - { name: City Bus Station,stop_code: City Bus Station, lat: -35.2794346, lng: 149.1305879} + - { name: City Bus Station (Platform 1),stop_code: City Bus Station (Platform 1), lat: -35.2794346, lng: 149.1305879} + - { name: City Bus Station (Platform 10),stop_code: City Bus Station (Platform 10), lat: -35.2793571, lng: 149.1293659} + - { name: City Bus Station (Platform 11),stop_code: City Bus Station (Platform 11), lat: -35.2787905, lng: 149.1288627} + - { name: City Bus Station (Platform 2),stop_code: City Bus Station (Platform 2), lat: -35.278907, lng: 149.130612} + - { name: City Bus Station (Platform 3),stop_code: City Bus Station (Platform 3), lat: -35.2787886, lng: 149.1304779} + - { name: City Bus Station (Pl