From: maxious Date: Mon, 19 Apr 2010 12:45:16 +0000 Subject: Initial Commit X-Git-Url: https://maxious.lambdacomplex.org/git/?p=bus.git&a=commitdiff&h=10df80f8fd69cd08e79e437fdcfc426696701be7 --- Initial Commit --- --- /dev/null +++ b/display.kml.php @@ -1,1 +1,65 @@ + +'; +echo ' + '; +$conn = pg_connect("dbname=openstreetmap user=postgres password=snmc"); +if (!$conn) { + echo "An error occured.\n"; + exit; +} + +$result_route = pg_query($conn, "SELECT * from current_relation_tags, (Select id FROM current_relation_tags WHERE k = 'route' AND v = 'bus') as a +where a.id = current_relation_tags.id and k = 'ref';"); +if (!$result_route) { + echo "An route retirieve error occured.\n"; + exit; +} + +while ($route = pg_fetch_assoc($result_route)) { + echo "\n\n"; + echo "".$route['v']." position at ".$route['id'].""; + echo "".$route['v']." position at ".$route['id'].""; +echo "#yellowLineGreenPoly"; +echo " + 1 + "; +$result_way = pg_query($conn, 'SELECT member_id, sequence_id FROM "current_relation_members" WHERE "id" = '.$route['id'].' order by "sequence_id" +ASC'); +if (!$result_way) { + echo "An way retirieve error occured.\n"; + exit; +} + $count = 0; + +while ($way = pg_fetch_assoc($result_way)) { + $result_node = pg_query($conn, 'SELECT * FROM current_nodes INNER JOIN current_way_nodes ON current_way_nodes.node_id=current_nodes.id WHERE +current_way_nodes.id = '.$way['member_id'].' order by "sequence_id" ASC'); + if (!$result_node) { + echo "An node retirieve error occured.\n"; + exit; + } + + while ($node = pg_fetch_assoc($result_node)) { + $count++; + echo ($node['longitude']/10000000).",".($node['latitude']/10000000).",600 \n"; + } +} + if ($count == 0) echo (0).",".(0).",600 \n"; +echo " + "; +echo ''; +} + +echo "\n\n"; +?> --- /dev/null +++ b/display.php @@ -1,1 +1,58 @@ + + + + + + + + +
+ + + + --- /dev/null +++ b/index.php @@ -1,1 +1,3 @@ +$query = "SELECT * from current_relation_tags, (Select "id" FROM "public"."current_relation_tags" WHERE "k" = 'route' AND "v" = 'bus') as a where +a.id = current_relation_tags.id;" --- /dev/null +++ b/maxious-canberra-transit-feed/.gitignore @@ -1,1 +1,3 @@ - +hfxfeed.zip +hfxtable.yml +*~ --- /dev/null +++ b/maxious-canberra-transit-feed/900-intertown.yml @@ -1,1 +1,80 @@ +short_name: 900 +long_name: Intertown +time_points: [ civic_platform_6, 3042, 4531, 4929, civic_platform_1, civic_platform_5 ] +between_stops: [ ] +stop_times: [ + [ 632a, 642a, 657a, 708a, 715a, 727a], + [ 702a, 712a, 727a, 738a, 745a, 757a], + [ -, -, 755a, 806a, 813a, 825a], + [ 732a, 742a, 757a, 808a, 815a, 827a], + [ 802a, 812a, 827a, 838a, 845a, 857a], + [ 832a, 842a, 857a, 908a, 915a, 927a], + [ 902a, 912a, 927a, 938a, 945a, 957a], + [ 932a, 942a, 957a, 1008a, 1015a, 1027a], + [ 1002a, 1012a, 1027a, 1038a, 1045a, 1057a], + [ 1032a, 1042a, 1057a, 1108a, 1115a, 1127a], + [ 1102a, 1112a, 1127a, 1138a, 1145a, 1157a], + [ 1132a, 1142a, 1157a, 1208p, 1215p, 1227p], + [ 1202p, 1212p, 1227p, 1238p, 1245p, 1257p], + [ 1232p, 1242p, 1257p, 108p, 115p, 127p], + [ 102p, 112p, 127p, 138p, 145p, 157p], + [ 132p, 142p, 157p, 208p, 215p, 227p], + [ 202p, 212p, 227p, 238p, 245p, 257p], + [ 232p, 242p, 257p, 308p, 315p, 327p], + [ 302p, 312p, 327p, 338p, 345p, 357p], + [ -, -, 340p, 351p, 358p, 410p], + [ -, -, -, -, 407p, 419p], + [ 332p, 342p, 357p, 408p, 415p, 427p], + [ -, -, -, -, 428p, 440p], + [ 359p, 409p, 424p, 435p, 442p, 454p], + [ 432p, 442p, 457p, 508p, 515p, 527p], + [ 502p, 512p, 527p, 538p, 545p, 557p], + [ 532p, 542p, 557p, 608p, 615p, 627p], + [ 602p, 612p, 627p, 638p, 645p, 657p], + [ 632p, 642p, 657p, 708p, 715p, 727p], + [ 702p, 712p, 727p, 738p, 745p, 757p], + [ 732p, 742p, 757p, 808p, 815p, 827p], + [ 832p, 842p, 857p, 908p, 915p, 927p], + [ 932p, 942p, 957p, 1008p, 1015p, 1027p], + [ 1032p, 1042p, 1057p, -, -, -], + [ 1132p, 1142p, 1157p, -, -, -], + [ 1235x, 1245x, 100x, -, -, -] +] +stop_times_saturday: [ + [ 646a, 655a, 710a, 721a, 728a, 740a], + [ 746a, 755a, 810a, 821a, 828a, 840a], + [ 846a, 855a, 910a, 921a, 928a, 940a], + [ 946a, 955a, 1010a, 1021a, 1028a, 1040a], + [ 1046a, 1055a, 1110a, 1121a, 1128a, 1140a], + [ 1146a, 1155a, 1210p, 1221p, 1228p, 1240p], + [ 1246p, 1255p, 110p, 121p, 128p, 140p], + [ 146p, 155p, 210p, 221p, 228p, 240p], + [ 246p, 255p, 310p, 321p, 328p, 340p], + [ 346p, 355p, 410p, 421p, 428p, 440p], + [ 446p, 455p, 510p, 521p, 528p, 540p], + [ 546p, 555p, 610p, 621p, 628p, 640p], + [ 646p, 655p, 710p, 721p, 728p, 740p], + [ 746p, 755p, 810p, 821p, 828p, 840p], + [ 846p, 855p, 910p, 921p, 928p, 940p], + [ 946p, 955p, 1010p, 1021p, 1028p, 1040p], + [ 1046p, 1055p, 1107p, -, -, -] +] +stop_times_sunday: [ + [ 728a, 736a, 750a, 801a, 808a, 817a], + [ 828a, 836a, 850a, 901a, 908a, 917a], + [ 928a, 936a, 950a, 1001a, 1008a, 1017a], + [ 1028a, 1036a, 1050a, 1101a, 1108a, 1117a], + [ 1128a, 1136a, 1150a, 1201p, 1208p, 1217p], + [ 1228p, 1236p, 1250p, 101p, 108p, 117p], + [ 128p, 136p, 150p, 201p, 208p, 217p], + [ 228p, 236p, 250p, 301p, 308p, 317p], + [ 328p, 336p, 350p, 401p, 408p, 417p], + [ 428p, 436p, 450p, 501p, 508p, 517p], + [ 528p, 536p, 550p, 601p, 608p, 617p], + [ 628p, 636p, 650p, 701p, 708p, 717p], + [ 728p, 736p, 750p, 801p, 808p, 817p], + [ 828p, 836p, 850p, 901p, 908p, 917p], + [ 928p, 936p, 950p, 1001p, 1008p, 1017p], + [ 1028p, 1036p, 1050p, 1101p, 1108p, 1117p] +] --- /dev/null +++ b/maxious-canberra-transit-feed/Makefile @@ -1,1 +1,23 @@ +default: cbrfeed.zip +cbrfeed.zip: cbrtable.yml createfeed.py + ./createfeed.py --input=cbrtable.yml --output=cbrfeed.zip + +ROUTE_FILES=900-intertown.yml + +cbrtable.yml: cbrtable.yml.in $(ROUTE_FILES) indent-route.pl + cp cbrtable.yml.in cbrtable.yml + @$(foreach ROUTE_FILE, $(ROUTE_FILES), \ + echo "Parsing $(ROUTE_FILE)"; \ + echo "TODO: replace friendly timing spot names with OSM node IDs in $(ROUTE_FILE)"; \ + echo "TODO: add inbetween stops in $(ROUTE_FILE)"; \ + ./indent-route.pl < $(ROUTE_FILE) >> cbrtable.yml;) + +cbrtable.yml.in: cbrtable.yml.in.in + @echo "TODO: autogenerate stops via OSM" + cp cbrtable.yml.in.in cbrtable.yml.in + + +clean: + rm -f cbrtable.yml cbrtable.yml.in cbrfeed.zip *~ + --- /dev/null +++ b/maxious-canberra-transit-feed/README @@ -1,1 +1,35 @@ +=== 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. + +Requirements: GNU Make, Perl, Python 2.5. + +=== Usage === + +First, grab a copy of google transit feed tools: + +cd $HOME/src +wget http://googletransitdatafeed.googlecode.com/files/transitfeed-1.1.7.tar.gz +tar zxvf transitfeed-1.1.7.tar.gz + +Set PYTHONPATH to the python directory in the above checkout: + +export PYTHONPATH=$HOME/src/transitfeed-1.1.7/python + +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 + +=== Copyright === + +With the exception of createfeed.py, which is licensed under the Apache Public +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. + --- /dev/null +++ b/maxious-canberra-transit-feed/add-between-times.pl @@ -1,1 +1,104 @@ +#!/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; + +$_ = ; +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"; +} + --- /dev/null +++ b/maxious-canberra-transit-feed/cbrtable.yml @@ -1,1 +1,99 @@ +options: + start_date: 20090525 + end_date: 20100601 + remove_date: 2010601 + agency_name: ACT Internal Omnibus Network (ACTION) + agency_url: http://www.action.act.gov.au/ + agency_timezone: Australia/Canberra +stops: + - { name: Civic Interchange Platform 1,stop_code: civic_platform_1, lat: -35.2794347, lng: 149.130588} + - { name: Civic Interchange Platform 5,stop_code: civic_platform_5, lat: -35.2786, lng: 149.13033} + - { name: Civic Interchange Platform 6,stop_code: civic_platform_6, lat: -35.27851, lng: 149.12979 } + - { name: Canberra House Northbound, stop_code: 3042, lat: -35.27833, +lng: 149.12712 } + - { name: Canberra House Southbound, stop_code: 4531, +lat: -35.2786, lng: 149.13033 } + - { name: Marcus Clarke Street - Unilodge ANU, stop_code: 4929, lat: -35.2764151, lng: 149.1267199 } + +routes: + - short_name: 900 + long_name: Intertown + time_points: [ civic_platform_6, 3042, 4531, 4929, civic_platform_1, civic_platform_5 ] + between_stops: [ ] + stop_times: [ + [ 632a, 642a, 657a, 708a, 715a, 727a], + [ 702a, 712a, 727a, 738a, 745a, 757a], + [ -, -, 755a, 806a, 813a, 825a], + [ 732a, 742a, 757a, 808a, 815a, 827a], + [ 802a, 812a, 827a, 838a, 845a, 857a], + [ 832a, 842a, 857a, 908a, 915a, 927a], + [ 902a, 912a, 927a, 938a, 945a, 957a], + [ 932a, 942a, 957a, 1008a, 1015a, 1027a], + [ 1002a, 1012a, 1027a, 1038a, 1045a, 1057a], + [ 1032a, 1042a, 1057a, 1108a, 1115a, 1127a], + [ 1102a, 1112a, 1127a, 1138a, 1145a, 1157a], + [ 1132a, 1142a, 1157a, 1208p, 1215p, 1227p], + [ 1202p, 1212p, 1227p, 1238p, 1245p, 1257p], + [ 1232p, 1242p, 1257p, 108p, 115p, 127p], + [ 102p, 112p, 127p, 138p, 145p, 157p], + [ 132p, 142p, 157p, 208p, 215p, 227p], + [ 202p, 212p, 227p, 238p, 245p, 257p], + [ 232p, 242p, 257p, 308p, 315p, 327p], + [ 302p, 312p, 327p, 338p, 345p, 357p], + [ -, -, 340p, 351p, 358p, 410p], + [ -, -, -, -, 407p, 419p], + [ 332p, 342p, 357p, 408p, 415p, 427p], + [ -, -, -, -, 428p, 440p], + [ 359p, 409p, 424p, 435p, 442p, 454p], + [ 432p, 442p, 457p, 508p, 515p, 527p], + [ 502p, 512p, 527p, 538p, 545p, 557p], + [ 532p, 542p, 557p, 608p, 615p, 627p], + [ 602p, 612p, 627p, 638p, 645p, 657p], + [ 632p, 642p, 657p, 708p, 715p, 727p], + [ 702p, 712p, 727p, 738p, 745p, 757p], + [ 732p, 742p, 757p, 808p, 815p, 827p], + [ 832p, 842p, 857p, 908p, 915p, 927p], + [ 932p, 942p, 957p, 1008p, 1015p, 1027p], + [ 1032p, 1042p, 1057p, -, -, -], + [ 1132p, 1142p, 1157p, -, -, -], + [ 1235x, 1245x, 100x, -, -, -] + ] + stop_times_saturday: [ + [ 646a, 655a, 710a, 721a, 728a, 740a], + [ 746a, 755a, 810a, 821a, 828a, 840a], + [ 846a, 855a, 910a, 921a, 928a, 940a], + [ 946a, 955a, 1010a, 1021a, 1028a, 1040a], + [ 1046a, 1055a, 1110a, 1121a, 1128a, 1140a], + [ 1146a, 1155a, 1210p, 1221p, 1228p, 1240p], + [ 1246p, 1255p, 110p, 121p, 128p, 140p], + [ 146p, 155p, 210p, 221p, 228p, 240p], + [ 246p, 255p, 310p, 321p, 328p, 340p], + [ 346p, 355p, 410p, 421p, 428p, 440p], + [ 446p, 455p, 510p, 521p, 528p, 540p], + [ 546p, 555p, 610p, 621p, 628p, 640p], + [ 646p, 655p, 710p, 721p, 728p, 740p], + [ 746p, 755p, 810p, 821p, 828p, 840p], + [ 846p, 855p, 910p, 921p, 928p, 940p], + [ 946p, 955p, 1010p, 1021p, 1028p, 1040p], + [ 1046p, 1055p, 1107p, -, -, -] + ] + stop_times_sunday: [ + [ 728a, 736a, 750a, 801a, 808a, 817a], + [ 828a, 836a, 850a, 901a, 908a, 917a], + [ 928a, 936a, 950a, 1001a, 1008a, 1017a], + [ 1028a, 1036a, 1050a, 1101a, 1108a, 1117a], + [ 1128a, 1136a, 1150a, 1201p, 1208p, 1217p], + [ 1228p, 1236p, 1250p, 101p, 108p, 117p], + [ 128p, 136p, 150p, 201p, 208p, 217p], + [ 228p, 236p, 250p, 301p, 308p, 317p], + [ 328p, 336p, 350p, 401p, 408p, 417p], + [ 428p, 436p, 450p, 501p, 508p, 517p], + [ 528p, 536p, 550p, 601p, 608p, 617p], + [ 628p, 636p, 650p, 701p, 708p, 717p], + [ 728p, 736p, 750p, 801p, 808p, 817p], + [ 828p, 836p, 850p, 901p, 908p, 917p], + [ 928p, 936p, 950p, 1001p, 1008p, 1017p], + [ 1028p, 1036p, 1050p, 1101p, 1108p, 1117p] + ] + --- /dev/null +++ b/maxious-canberra-transit-feed/cbrtable.yml.in @@ -1,1 +1,20 @@ +options: + start_date: 20090525 + end_date: 20100601 + remove_date: 2010601 + agency_name: ACT Internal Omnibus Network (ACTION) + agency_url: http://www.action.act.gov.au/ + agency_timezone: Australia/Canberra +stops: + - { name: Civic Interchange Platform 1,stop_code: civic_platform_1, lat: -35.2794347, lng: 149.130588} + - { name: Civic Interchange Platform 5,stop_code: civic_platform_5, lat: -35.2786, lng: 149.13033} + - { name: Civic Interchange Platform 6,stop_code: civic_platform_6, lat: -35.27851, lng: 149.12979 } + - { name: Canberra House Northbound, stop_code: 3042, lat: -35.27833, +lng: 149.12712 } + - { name: Canberra House Southbound, stop_code: 4531, +lat: -35.2786, lng: 149.13033 } + - { name: Marcus Clarke Street - Unilodge ANU, stop_code: 4929, lat: -35.2764151, lng: 149.1267199 } + +routes: + --- /dev/null +++ b/maxious-canberra-transit-feed/cbrtable.yml.in.in @@ -1,1 +1,20 @@ +options: + start_date: 20090525 + end_date: 20100601 + remove_date: 2010601 + agency_name: ACT Internal Omnibus Network (ACTION) + agency_url: http://www.action.act.gov.au/ + agency_timezone: Australia/Canberra +stops: + - { name: Civic Interchange Platform 1,stop_code: civic_platform_1, lat: -35.2794347, lng: 149.130588} + - { name: Civic Interchange Platform 5,stop_code: civic_platform_5, lat: -35.2786, lng: 149.13033} + - { name: Civic Interchange Platform 6,stop_code: civic_platform_6, lat: -35.27851, lng: 149.12979 } + - { name: Canberra House Northbound, stop_code: 3042, lat: -35.27833, +lng: 149.12712 } + - { name: Canberra House Southbound, stop_code: 4531, +lat: -35.2786, lng: 149.13033 } + - { name: Marcus Clarke Street - Unilodge ANU, stop_code: 4929, lat: -35.2764151, lng: 149.1267199 } + +routes: + --- /dev/null +++ b/maxious-canberra-transit-feed/createfeed.py @@ -1,1 +1,194 @@ +#!/usr/bin/python +# Copyright (C) 2007 Google Inc. +# Copyright (C) 2008-2009 William Lachance +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import transitfeed +from transitfeed import ServicePeriod +from optparse import OptionParser +import yaml, sys, os.path +import re + +stops = {} + +def ProcessOptions(schedule, options): + + # the follow features are REQUIRED + agency_name = options.get('agency_name') + agency_url = options.get('agency_url') + agency_timezone = options.get('agency_timezone') + + service_periods = [] + + service_periods.append(ServicePeriod(id="weekday")) + service_periods[0].SetWeekdayService() + service_periods.append(ServicePeriod(id="saturday")) + service_periods[1].SetDayOfWeekHasService(5) + service_periods.append(ServicePeriod(id="sunday")) + service_periods[2].SetDayOfWeekHasService(6) + + # the service period options are, well, optional + for service_period in service_periods: + if options.get('start_date'): + service_period.SetStartDate(options['start_date']) + if options.get('end_date'): + service_period.SetEndDate(options['end_date']) + if options.get('add_date'): + service_period.SetDateHasService(options['add_date']) + if options.get('remove_date'): + service_period.SetDateHasService(options['remove_date'], + has_service=False) + + # Add all service period objects to the schedule + schedule.SetDefaultServicePeriod(service_periods[0], validate=False) + schedule.AddServicePeriodObject(service_periods[1], validate=False) + schedule.AddServicePeriodObject(service_periods[2], validate=False) + + if not (agency_name and agency_url and agency_timezone): + print "You must provide agency information" + + schedule.NewDefaultAgency(agency_name=agency_name, agency_url=agency_url, + agency_timezone=agency_timezone) + + +# Remove any stops from stopsdata that aren't serviced by any routes in +# routedata. +def PruneStops(stopsdata, routedata): + stopset = set() + for route in routedata: + stopset.update(route['time_points']) + for between_list in route['between_stops']: + stopset.update(route['between_stops'][between_list]) + + toprune = list() + for i, stop in enumerate(stopsdata): + if stop['stop_code'] not in stopset: + print "Pruning unused stop %s " % stop['stop_code'] + toprune.append(i) + + # Prune the list in reverse order, as the indices will change otherwise. + toprune.sort() + toprune.reverse() + for prunee in toprune: + del stopsdata[prunee] + +def AddStops(schedule, stopsdata): + for stopdata in stopsdata: + stop_code = stopdata['stop_code'] + # we have to manually add the stop instead of using AddStop, cause + # we want the stop_code + stop_id = unicode(len(schedule.stops)) + stop = transitfeed.Stop(stop_id=stop_id, lat=stopdata['lat'], + lng=stopdata['lng'], name=stopdata['name'], + stop_code=stop_code) + schedule.AddStopObject(stop) + stops[stop_code] = stop + + +def AddTripsToSchedule(schedule, route, routedata, service_id, stop_times): + + service_period = schedule.GetServicePeriod(service_id) + timerex = re.compile('^(\d+)(\d\d)([a-z])$') + + for trip in stop_times: + t = route.AddTrip(schedule, headsign=routedata['long_name'], service_period=service_period) + + if len(trip) > len(routedata['time_points']): + print "Length of trip (%s) exceeds number of time points (%s)!" % (len(trip), len(routedata['time_points'])) + class StopTimesError(Exception): pass + raise StopTimesError() + else: + trip_stops = [] # Build a list of (time, stop_code) tuples + i = 0 + for stop_time in trip: + matches = timerex.match(str(stop_time)) + if matches and len(matches.groups()) == 3: + hour, minute, shift = (int(matches.group(1)), + str(matches.group(2)), + matches.group(3)) + if shift == 'p' and hour < 12: + hour += 12 + elif shift == 'x': + if hour == 12: + hour += 12 + else: + hour += 24 + + # munge hours and minutes if they're < 10 + if hour < 10: + hour = "0" + str(hour) + + clock_time = str(hour) + ":" + minute + ":00" + seconds = transitfeed.TimeToSecondsSinceMidnight(clock_time) + trip_stops.append((seconds, routedata['time_points'][i]) ) + elif re.search(r'^\-$', str(stop_time)): + pass + else: + class InvalidStopTimeError(Exception): pass + raise InvalidStopTimeError, 'Bad stoptime "%s"' % stop_time + i = i + 1 + + trip_stops.sort() # Sort by time + prev_stop_code = None + between_stops = routedata.get('between_stops') + + for (time, stop_code) in trip_stops: + if prev_stop_code and between_stops: + between_stop_list = between_stops.get('%s-%s' % (prev_stop_code, stop_code)) + if between_stop_list: + for between_stop_code in between_stop_list: + t.AddStopTime(stop=stops[between_stop_code]) + + t.AddStopTime(stop=stops[stop_code], arrival_secs=time, + departure_secs=time) + prev_stop_code = stop_code + + + +def AddRouteToSchedule(schedule, routedata): + r = schedule.AddRoute(short_name=str(routedata['short_name']), + long_name=routedata['long_name'], + route_type='Bus') + AddTripsToSchedule(schedule, r, routedata, "weekday", routedata['stop_times']) + if routedata.get('stop_times_saturday'): + AddTripsToSchedule(schedule, r, routedata, "saturday", routedata['stop_times_saturday']) + if routedata.get('stop_times_sunday'): + AddTripsToSchedule(schedule, r, routedata, "sunday", routedata['stop_times_sunday']) + +def main(): + parser = OptionParser() + parser.add_option('--input', dest='input', + help='Path of input file') + parser.add_option('--output', dest='output', + help='Path of output file, should end in .zip') + parser.set_defaults(output='feed.zip') + (options, args) = parser.parse_args() + + schedule = transitfeed.Schedule() + stream = open(options.input, 'r') + data = yaml.load(stream) + ProcessOptions(schedule, data['options']) + PruneStops(data['stops'], data['routes']) + AddStops(schedule, data['stops']) + + for route in data['routes']: + AddRouteToSchedule(schedule, route) + + schedule.WriteGoogleTransitFeed(options.output) + + +if __name__ == '__main__': + main() + --- /dev/null +++ b/maxious-canberra-transit-feed/extracttimes.rb @@ -1,1 +1,95 @@ +require 'rubygems' +require 'nokogiri' +require 'open-uri' +require 'pp' +def makeTimetable(table, period, short_name) + timetable = {"stop_times" => [], "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").strip + end + end + time_points.delete(nil) + timetable["time_points"] = time_points + timetable["long_name"] = "To " + time_points.last + periodtimes = [] + table.css('tr').each do |row| + times = row.css('td').map do |cell| + #TODO convert to GTFS time + time = cell.content.squeeze(" ").strip + end + if not times.empty? + if not (route = times.shift) + raise("TODO: account for shifting route numbers eg. intertown/redex 62/162") + end + periodtimes << times + end + end + if periodtimes.size < 1 + raise "No times for route " + short_name + " in period " + period + end + timetable["stop_times"] = { period => periodtimes } + # pp timetable + filename = timetable["short_name"] + "-" + timetable["long_name"].downcase.gsub(" ","-").gsub("/","") + "." + period + ".yml" + puts "Saving " + filename + File.open("#{File.dirname(__FILE__)}/output/"+filename, "w") do |f| + f.write timetable.to_yaml + end + timetable +end + +#TODO fix route 934 +Dir.glob("source-html/Route*.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 ","").squeeze(" ").strip + end + if short_name == "" + raise "Route number(s) not found in tag" + end + + doc.xpath('//table[preceding::text()="Weekdays"]').each do |table| + timetables << makeTimetable(table, "weekday", short_name) + end + + #weekends + doc.xpath('//table[preceding::text()="Saturdays" and following::a]').each do |table| + timetables << makeTimetable(table, "saturday", short_name) + end + doc.xpath('//table[preceding::text()="Sundays"]').each do |table| + timetables << makeTimetable(table, "sunday", short_name) + end + #930/934 special cases + doc.xpath('//table[preceding::text()="Saturday" and following::h2]').each do |table| + timetables << makeTimetable(table, "saturday", short_name) + end + doc.xpath('//table[preceding::text()="Sunday"]').each do |table| + timetables << makeTimetable(table, "sunday", short_name) + end + #route 81 = Weekdays - School Holidays Only + doc.xpath('//table[preceding::text()="Weekdays - School Holidays Only "]').each do |table| + timetable = makeTimetable(table, "weekday", short_name) + #TODO set active date range to only be holidays + timetables << timetable; + end + + + if timetables.size > 2 + puts "WARNING: " + file + " more than 2 timetables (weekend split?):" + timetables.size.to_s + end + if timetables.size < 2 + puts "WARNING: " + file + " less than 2 timetables (weekday loop service?):" + timetables.size.to_s + elsif not (timetables[0]["time_points"] - timetables[1]["time_points"].reverse).empty? + puts "WARNING: first pair of timetable timing points are not complementary for "+ file + pp(timetables[0]["time_points"] - timetables[1]["time_points"].reverse) + end + if timetables.size < 1 + raise "No timetables extracted from " + file + end +} + --- /dev/null +++ b/maxious-canberra-transit-feed/indent-route.pl @@ -1,1 +1,14 @@ +#!/usr/bin/perl +use strict; + +my $first = 1; +while (<STDIN>) { + if ($first) { + $first = 0; + print " - $_"; + } else { + print " $_"; + } +} + --- /dev/null +++ b/maxious-canberra-transit-feed/parse-times.pl @@ -1,1 +1,35 @@ +#!/usr/bin/perl +use strict; + +my $first = 1; +my $prev_comment = 0; +while (<STDIN>) { + if ($_ !~ /^\#/) { + if (!$first && !$prev_comment) { + print ",\n"; + } else { + $first = 0; + $prev_comment = 0; + } + chomp; + my @times = split /\ +/; + print " [ "; + my $first = 1; + foreach (@times) { + if (!$first) { + print ", "; + } else { + $first = 0; + } + print $_; + } + print "]"; + } else { + # yes, this conditional is loaded with assumptions... + print ",\n" . $_; + $prev_comment = 1; + } +} + + --- /dev/null +++ b/maxious-canberra-transit-feed/source-html/Intertown_300.html @@ -1,1 +1,3473 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"><!-- InstanceBegin template="/Templates/timetable08.dwt" codeOutsideHTMLIsLocked="false" --> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> +<link rel="stylesheet" type="text/css" href="/New_ACTION/CSS/print_timetable.css" media="print" /> +<link rel="stylesheet" type="text/css" href="/New_ACTION/CSS/timetable.css" media="screen" /> + +<!-- InstanceBeginEditable name="doctitle" --> +<title>Intertown 300 + + + + + + +
+

Chosen services: 300, 312, 313, 314, 315, 318, 319

+ +

View timetable and map

+

This timetable is effective from Monday 25 May 2009.

+ + +

Weekdays

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Tuggeranong Interchange
+ Platform 8
Woden Interchange
+ Platform 9
City Interchange
+ Platform 5
Cameron Ave Bus StationLathlain St Bus Station Cohen St Bus Station
300 wheelchair access5:30 AM5:48 AM6:04 AM6:21 AM6:23 AM6:27 AM
318 wheelchair access6:08 AM6:26 AM6:42 AM6:59 AM7:01 AM7:05 AM
319 wheelchair access6:25 AM6:43 AM6:59 AM7:16 AM7:18 AM7:22 AM
3186:38 AM6:56 AM7:12 AM7:29 AM7:31 AM7:35 AM
300 wheelchair access6:42 AM7:00 AM7:16 AM7:33 AM7:35 AM7:39 AM
111.....7:13 AM7:29 AM...............
319 wheelchair access6:55 AM7:13 AM7:29 AM7:47 AM7:49 AM7:53 AM
318 wheelchair access6:58 AM7:16 AM7:32 AM7:50 AM7:52 AM7:56 AM
314 wheelchair access7:06 AM7:24 AM7:41 AM7:59 AM8:01 AM8:05 AM
313 wheelchair access7:11 AM7:29 AM7:47 AM8:05 AM8:07 AM8:11 AM
111.....7:33 AM7:51 AM...............
319 wheelchair access7:15 AM7:33 AM7:51 AM8:09 AM8:11 AM8:15 AM
160.....7:34 AM7:49 AM...............
318 wheelchair access7:20 AM7:38 AM7:56 AM8:14 AM8:16 AM8:20 AM
162.....7:40 AM7:55 AM...............
312 wheelchair access7:26 AM7:45 AM8:03 AM8:21 AM8:23 AM8:27 AM
170.....7:49 AM8:04 AM...............
315 wheelchair access7:31 AM7:50 AM8:08 AM8:26 AM8:28 AM8:32 AM
111.....7:54 AM8:12 AM...............
319 wheelchair access7:35 AM7:54 AM8:12 AM8:30 AM8:32 AM8:36 AM
318 wheelchair access7:40 AM7:59 AM8:17 AM8:35 AM8:37 AM8:41 AM
161.....8:05 AM8:19 AM...............
314 wheelchair access7:46 AM8:05 AM8:23 AM8:41 AM8:43 AM8:47 AM
162.....8:07 AM8:22 AM...............
170.....8:07 AM8:22 AM...............
300 wheelchair access.....8:07 AM8:25 AM8:43 AM8:45 AM8:49 AM
313 wheelchair access7:51 AM8:10 AM8:28 AM8:46 AM8:48 AM8:52 AM
160.....8:11 AM8:26 AM...............
319 wheelchair access7:55 AM8:14 AM8:32 AM8:50 AM8:52 AM8:56 AM
111.....8:15 AM8:33 AM...............
318 wheelchair access8:00 AM8:19 AM8:37 AM8:55 AM8:57 AM9:01 AM
314 wheelchair access8:06 AM8:25 AM8:43 AM9:01 AM9:03 AM9:07 AM
300.....8:27 AM8:45 AM9:03 AM9:05 AM9:09 AM
313 wheelchair access8:11 AM8:30 AM8:48 AM9:06 AM9:08 AM9:12 AM
319 wheelchair access8:15 AM8:34 AM8:52 AM9:10 AM9:12 AM9:16 AM
111.....8:36 AM8:54 AM...............
318 wheelchair access8:20 AM8:39 AM8:57 AM9:15 AM9:17 AM9:21 AM
162.....8:40 AM8:55 AM...............
160.....8:41 AM8:56 AM...............
3128:26 AM8:45 AM9:03 AM9:21 AM9:23 AM9:27 AM
315 wheelchair access8:31 AM8:50 AM9:08 AM9:26 AM9:28 AM9:32 AM
319 wheelchair access8:34 AM8:53 AM9:11 AM9:29 AM9:31 AM9:35 AM
111.....8:56 AM9:14 AM...............
318 wheelchair access8:40 AM8:59 AM9:17 AM9:35 AM9:37 AM9:41 AM
314 wheelchair access8:43 AM9:02 AM9:20 AM9:38 AM9:40 AM9:44 AM
313 wheelchair access8:51 AM9:10 AM9:28 AM9:45 AM9:47 AM9:51 AM
319 wheelchair access8:55 AM9:14 AM9:32 AM9:49 AM9:51 AM9:55 AM
312 wheelchair access9:01 AM9:20 AM9:37 AM9:54 AM9:56 AM10:00 AM
318 wheelchair access9:05 AM9:24 AM9:41 AM9:58 AM10:00 AM10:04 AM
3159:11 AM9:30 AM9:46 AM10:03 AM10:05 AM10:09 AM
314 wheelchair access9:16 AM9:35 AM9:51 AM10:08 AM10:10 AM10:14 AM
3139:21 AM9:40 AM9:56 AM10:13 AM10:15 AM10:19 AM
319 wheelchair access9:25 AM9:43 AM9:59 AM10:16 AM10:18 AM10:22 AM
3129:31 AM9:49 AM10:05 AM10:22 AM10:24 AM10:28 AM
318 wheelchair access9:35 AM9:53 AM10:09 AM10:26 AM10:28 AM10:32 AM
315 wheelchair access9:41 AM9:59 AM10:15 AM10:32 AM10:34 AM10:38 AM
314 wheelchair access9:46 AM10:04 AM10:20 AM10:37 AM10:39 AM10:43 AM
3139:51 AM10:09 AM10:25 AM10:42 AM10:44 AM10:48 AM
319 wheelchair access9:55 AM10:13 AM10:29 AM10:46 AM10:48 AM10:52 AM
31210:01 AM10:19 AM10:35 AM10:52 AM10:54 AM10:58 AM
318 wheelchair access10:05 AM10:23 AM10:39 AM10:56 AM10:58 AM11:02 AM
31510:11 AM10:29 AM10:45 AM11:02 AM11:04 AM11:08 AM
314 wheelchair access10:16 AM10:34 AM10:50 AM11:07 AM11:09 AM11:13 AM
31310:21 AM10:39 AM10:55 AM11:12 AM11:14 AM11:18 AM
319 wheelchair access10:25 AM10:43 AM10:59 AM11:16 AM11:18 AM11:22 AM
312 wheelchair access10:31 AM10:49 AM11:05 AM11:22 AM11:24 AM11:28 AM
318 wheelchair access10:35 AM10:53 AM11:09 AM11:26 AM11:28 AM11:32 AM
315 wheelchair access10:41 AM10:59 AM11:15 AM11:32 AM11:34 AM11:38 AM
314 wheelchair access10:46 AM11:04 AM11:20 AM11:37 AM11:39 AM11:43 AM
313 wheelchair access10:51 AM11:09 AM11:25 AM11:42 AM11:44 AM11:48 AM
319 wheelchair access10:55 AM11:13 AM11:29 AM11:46 AM11:48 AM11:52 AM
31211:01 AM11:19 AM11:35 AM11:52 AM11:54 AM11:58 AM
318 wheelchair access11:05 AM11:23 AM11:39 AM11:56 AM11:58 AM12:02 PM
315 wheelchair access11:11 AM11:29 AM11:45 AM12:02 PM12:04 PM12:08 PM
31411:16 AM11:34 AM11:50 AM12:07 PM12:09 PM12:13 PM
313 wheelchair access11:21 AM11:39 AM11:55 AM12:12 PM12:14 PM12:18 PM
319 wheelchair access11:25 AM11:43 AM11:59 AM12:16 PM12:18 PM12:22 PM
31211:31 AM11:49 AM12:05 PM12:22 PM12:24 PM12:28 PM
318 wheelchair access11:35 AM11:53 AM12:09 PM12:26 PM12:28 PM12:32 PM
31511:41 AM11:59 AM12:15 PM12:32 PM12:34 PM12:38 PM
314 wheelchair access11:46 AM12:04 PM12:20 PM12:37 PM12:39 PM12:43 PM
313 wheelchair access11:51 AM12:09 PM12:25 PM12:42 PM12:44 PM12:48 PM
319 wheelchair access11:55 AM12:13 PM12:29 PM12:46 PM12:48 PM12:52 PM
312 wheelchair access12:01 PM12:19 PM12:35 PM12:52 PM12:54 PM12:58 PM
318 wheelchair access12:05 PM12:23 PM12:39 PM12:56 PM12:58 PM1:02 PM
315 wheelchair access12:11 PM12:29 PM12:45 PM1:02 PM1:04 PM1:08 PM
314 wheelchair access12:16 PM12:34 PM12:50 PM1:07 PM1:09 PM1:13 PM
31312:21 PM12:39 PM12:55 PM1:12 PM1:14 PM1:18 PM
319 wheelchair access12:25 PM12:43 PM12:59 PM1:16 PM1:18 PM1:22 PM
31212:31 PM12:49 PM1:05 PM1:22 PM1:24 PM1:28 PM
318 wheelchair access12:35 PM12:53 PM1:09 PM1:26 PM1:28 PM1:32 PM
31512:41 PM12:59 PM1:15 PM1:32 PM1:34 PM1:38 PM
314 wheelchair access12:46 PM1:04 PM1:20 PM1:37 PM1:39 PM1:43 PM
313 wheelchair access12:51 PM1:09 PM1:25 PM1:42 PM1:44 PM1:48 PM
319 wheelchair access12:55 PM1:13 PM1:29 PM1:46 PM1:48 PM1:52 PM
312 wheelchair access1:01 PM1:19 PM1:35 PM1:52 PM1:54 PM1:58 PM
318 wheelchair access1:05 PM1:23 PM1:39 PM1:56 PM1:58 PM2:02 PM
315 wheelchair access1:11 PM1:29 PM1:45 PM2:02 PM2:04 PM2:08 PM
314 wheelchair access1:16 PM1:34 PM1:50 PM2:07 PM2:09 PM2:13 PM
313 wheelchair access1:21 PM1:39 PM1:55 PM2:12 PM2:14 PM2:18 PM
319 wheelchair access1:25 PM1:43 PM1:59 PM2:16 PM2:18 PM2:22 PM
3121:31 PM1:49 PM2:05 PM2:22 PM2:24 PM2:28 PM
318 wheelchair access1:35 PM1:53 PM2:09 PM2:26 PM2:28 PM2:32 PM
3151:41 PM1:59 PM2:15 PM2:32 PM2:34 PM2:38 PM
314 wheelchair access1:46 PM2:04 PM2:20 PM2:37 PM2:39 PM2:43 PM
3131:51 PM2:09 PM2:25 PM2:42 PM2:44 PM2:48 PM
319 wheelchair access1:55 PM2:13 PM