Initial Commit
--- /dev/null
+++ b/display.kml.php
@@ -1,1 +1,65 @@
+<?php
+header('Content-Type: application/vnd.google-earth.kml+xml');
+echo '<?xml version="1.0" encoding="UTF-8"?>
+<kml xmlns="http://www.opengis.net/kml/2.2"><Document>';
+echo '
+ <Style id="yellowLineGreenPoly">
+ <LineStyle>
+ <color>7f00ff00</color>
+ <width>4</width>
+ </LineStyle>
+ <PolyStyle>
+ <color>7f00ffff</color>
+ </PolyStyle>
+ </Style>';
+$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<Placemark>\n";
+ echo "<name>".$route['v']." position at ".$route['id']."</name>";
+ echo "<description>".$route['v']." position at ".$route['id']."</description>";
+echo "<styleUrl>#yellowLineGreenPoly</styleUrl>";
+echo " <LineString>
+ <extrude>1</extrude>
+ <coordinates> ";
+$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 " </coordinates>
+ </LineString>";
+echo '</Placemark>';
+}
+
+echo "\n</Document></kml>\n";
+?>
--- /dev/null
+++ b/display.php
@@ -1,1 +1,58 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+<script type="text/javascript" src="http://loki.com/plugin/files/loki.js"></script>
+ <script src="openlayers/OpenLayers.js"></script>
+ <script type="text/javascript">
+ var map, layer;
+ function aaa(a) {
+var lonLat = new OpenLayers.LonLat(a.coords.longitude, a.coords.latitude).transform(new OpenLayers.Projection("EPSG:4326"),map.getProjectionObject());
+ map.setCenter (lonLat, 13);
+ }
+ function handleError(a) {
+alert("error in geoloc");
+ }
+ function init(){
+ var extent = new OpenLayers.Bounds(148.98,-35.48, 149.25,-35.15);
+ map = new OpenLayers.Map( 'map');
+ layer = new OpenLayers.Layer.OSM("local", "http://10.0.1.153/tiles/${z}/${x}/${y}.png");
+ map.addLayer(layer);
+ var lonLat = new OpenLayers.LonLat(149.11, -35.28).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
+ map.setCenter (lonLat, 13);
+ map.addControl(new OpenLayers.Control.MousePosition({ displayProjection: new OpenLayers.Projection("EPSG:4326"),
+ suffix: "__________________________________" }));
+ map.addControl(new OpenLayers.Control.MousePosition({ displayProjection: new OpenLayers.Projection("EPSG:900913")}));
+ if (navigator.geolocation) {
+ navigator.geolocation.getCurrentPosition(this.aaa, this.handleError);
+ } else {
+ var loki = LokiAPI();
+ loki.onSuccess = function(location) {
+var lonLat = new OpenLayers.LonLat(location.longitude, location.latitude).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
+ map.setCenter (lonLat, 13);
+}
+ loki.onFailure = function(error) {
+ loki.requestIPLocation(true,loki.NO_STREET_ADDRESS_LOOKUP)
+ }
+ loki.setKey('maxious.lambdacomplex.org');
+ loki.requestLocation(true,loki.NO_STREET_ADDRESS_LOOKUP);
+ }
+map.addLayer(new OpenLayers.Layer.GML("KML", "display.kml.php",
+ {
+ format: OpenLayers.Format.KML,
+ formatOptions: {
+ extractStyles: true,
+ extractAttributes: true,
+ maxDepth: 2
+ }
+ }));
+
+ }
+ </script>
+
+ </head>
+ <body onload="init()">
+ <div id="map" width="100%" height="100%" class="smallmap"></div>
+ </body>
+</html>
+
+
--- /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;
+
+$_ = <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";
+}
+
Binary files /dev/null and b/maxious-canberra-transit-feed/cbrfeed.zip differ
--- /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 != "<br/>"
+ 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
+