muni 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +3 -0
- data/README.md +7 -0
- data/lib/muni/base.rb +15 -18
- data/lib/muni/direction.rb +3 -3
- data/lib/muni/prediction.rb +1 -1
- data/lib/muni/route.rb +12 -12
- data/lib/muni/stop.rb +3 -2
- data/lib/muni/version.rb +1 -1
- data/man/muni.1.html +1 -1
- data/man/muni.1.ronn +11 -12
- data/muni.gemspec +4 -3
- data/spec/cassettes/Muni_Route.yml +263 -0
- data/spec/cassettes/Muni_Stop.yml +439 -0
- data/spec/route_spec.rb +10 -7
- data/spec/spec_helper.rb +14 -0
- data/spec/stop_spec.rb +16 -11
- metadata +84 -18
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -4,6 +4,13 @@ About
|
|
4
4
|
`muni` is a simple NextBus API Client library and command line tool for retrieving
|
5
5
|
San Francisco Muni bus route and stop prediction information.
|
6
6
|
|
7
|
+
Install
|
8
|
+
=======
|
9
|
+
|
10
|
+
```bash
|
11
|
+
$ gem install muni
|
12
|
+
```
|
13
|
+
|
7
14
|
Client Library
|
8
15
|
===============
|
9
16
|
|
data/lib/muni/base.rb
CHANGED
@@ -4,24 +4,21 @@ module Muni
|
|
4
4
|
class Base < Mash
|
5
5
|
class << self
|
6
6
|
private
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
url
|
23
|
-
end
|
24
|
-
|
7
|
+
|
8
|
+
def fetch(command, options = {})
|
9
|
+
url = build_url(command, options)
|
10
|
+
xml = Net::HTTP.get(URI.parse(url))
|
11
|
+
doc = XmlSimple.xml_in(xml) || {}
|
12
|
+
fail NextBusError, doc['Error'].first['content'].gsub(/\n/,'') if doc['Error']
|
13
|
+
doc
|
14
|
+
end
|
15
|
+
|
16
|
+
def build_url(command, options = {})
|
17
|
+
url = "http://webservices.nextbus.com/service/publicXMLFeed?command=#{command}&a=sf-muni"
|
18
|
+
options.each { |key,value| url << "&#{key}=#{value}" }
|
19
|
+
url
|
20
|
+
end
|
21
|
+
|
25
22
|
end
|
26
23
|
end
|
27
24
|
end
|
data/lib/muni/direction.rb
CHANGED
@@ -3,11 +3,11 @@ require 'amatch'
|
|
3
3
|
module Muni
|
4
4
|
class Direction < Base
|
5
5
|
def stop_at(place)
|
6
|
-
return stops.select{|stop| stop.tag == place}.first if place =~ /[1-9][0-9]+/
|
7
|
-
pattern = Amatch::Sellers.new(place)
|
6
|
+
return stops.select{ |stop| stop.tag == place }.first if place =~ /[1-9][0-9]+/
|
7
|
+
pattern = Amatch::Sellers.new(place)
|
8
8
|
stops.sort_by{ |stop|
|
9
9
|
pattern.match(stop.title)
|
10
10
|
}.first
|
11
11
|
end
|
12
12
|
end
|
13
|
-
end
|
13
|
+
end
|
data/lib/muni/prediction.rb
CHANGED
data/lib/muni/route.rb
CHANGED
@@ -10,13 +10,13 @@ module Muni
|
|
10
10
|
return send(direction.downcase.to_sym) if direction =~ /(outbound|inbound)/i
|
11
11
|
directions.select{|dir| dir.id == direction}.first
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
def outbound
|
15
|
-
directions.select{|dir| dir.name =~ /outbound/i}.first
|
15
|
+
directions.select{ |dir| dir.name =~ /outbound/i }.first
|
16
16
|
end
|
17
17
|
|
18
18
|
def inbound
|
19
|
-
directions.select{|dir| dir.name =~ /inbound/i}.first
|
19
|
+
directions.select{ |dir| dir.name =~ /inbound/i }.first
|
20
20
|
end
|
21
21
|
|
22
22
|
class << self
|
@@ -24,10 +24,10 @@ module Muni
|
|
24
24
|
if tag == :all
|
25
25
|
find_all
|
26
26
|
else
|
27
|
-
find_by_tag(tag)
|
27
|
+
find_by_tag(tag)
|
28
28
|
end
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
private
|
32
32
|
def find_all
|
33
33
|
document = fetch(:routeList)
|
@@ -35,30 +35,30 @@ module Muni
|
|
35
35
|
Route.new(el)
|
36
36
|
end
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
def find_by_tag(tag)
|
40
40
|
document = fetch(:routeConfig, {:r => tag})
|
41
41
|
route = Route.new({:tag => document['route'].first['tag'], :title => document['route'].first['title']})
|
42
|
-
|
42
|
+
|
43
43
|
stops = {}
|
44
|
-
|
44
|
+
|
45
45
|
document['route'].first['stop'].each do |stop|
|
46
46
|
st = Stop.new({
|
47
47
|
:tag => stop['tag'],
|
48
48
|
:title => stop['title'],
|
49
49
|
:lat => stop['lat'],
|
50
50
|
:lon => stop['lat'],
|
51
|
-
:stopId => stop['lat'],
|
51
|
+
:stopId => stop['lat'],
|
52
52
|
})
|
53
53
|
stops[st[:tag]] = st
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
directions = []
|
57
57
|
route.directions = document['route'].first['direction'].collect do |direction|
|
58
58
|
direction_stops = direction['stop'].collect do |stop|
|
59
59
|
stops[stop['tag']]
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
direction_stops.each do |stop|
|
63
63
|
stop.route_tag = route.tag
|
64
64
|
stop.direction = direction['tag']
|
@@ -70,7 +70,7 @@ module Muni
|
|
70
70
|
:stops => direction_stops
|
71
71
|
})
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
route
|
75
75
|
end
|
76
76
|
end
|
data/lib/muni/stop.rb
CHANGED
@@ -4,8 +4,9 @@ require 'muni/prediction'
|
|
4
4
|
module Muni
|
5
5
|
class Stop < Base
|
6
6
|
def predictions
|
7
|
-
|
8
|
-
|
7
|
+
stop = Stop.send(:fetch, :predictions, r: route_tag, d: direction, s: tag)
|
8
|
+
return [] unless stop && stop['predictions']
|
9
|
+
stop['predictions'].first['direction'].first['prediction'].collect do |pred|
|
9
10
|
Prediction.new(pred)
|
10
11
|
end
|
11
12
|
end
|
data/lib/muni/version.rb
CHANGED
data/man/muni.1.html
CHANGED
@@ -157,7 +157,7 @@ Route 21-Hayes going Outbound to Fulton St & Shrader St at Hayes St & Sh
|
|
157
157
|
|
158
158
|
<p>With a fuzzy direction and stop name:</p>
|
159
159
|
|
160
|
-
<pre><code>$ muni predict 21 inbound hayes and shrader
|
160
|
+
<pre><code>$ muni predict 21 inbound hayes and shrader
|
161
161
|
Route 21-Hayes going Inbound to Steuart Terminal at Hayes St & Shrader St:
|
162
162
|
8102 less than a minute
|
163
163
|
2832 2 minutes
|
data/man/muni.1.ronn
CHANGED
@@ -7,8 +7,8 @@ muni(1) -- show san francisco muni routes and stop predictions
|
|
7
7
|
`muni` `list`<br/>
|
8
8
|
`muni` `predict` <route> <direction> <stop><br/>
|
9
9
|
`muni` `show` `-v`|`--verbose` <route> [<direction>]<br/>
|
10
|
-
|
11
|
-
## DESCRIPTION
|
10
|
+
|
11
|
+
## DESCRIPTION
|
12
12
|
|
13
13
|
**muni** retrieves San Francisco MUNI routes information and bus stop prediction
|
14
14
|
times. `muni` is mostly an exercise in implementing the core functions of the `muni`
|
@@ -25,7 +25,7 @@ List all available routes:
|
|
25
25
|
L L-Taraval
|
26
26
|
M M-Ocean View
|
27
27
|
....
|
28
|
-
|
28
|
+
|
29
29
|
Show basic route information:
|
30
30
|
|
31
31
|
$ muni show 21
|
@@ -45,7 +45,7 @@ Show a route and all stops using `-v` or `--verbose`:
|
|
45
45
|
6501 Steuart St & Market St
|
46
46
|
5669 Market St & Drumm St
|
47
47
|
...
|
48
|
-
|
48
|
+
|
49
49
|
Show a route and all stops for a particular direction:
|
50
50
|
|
51
51
|
$ muni show 21 outbound --verbose
|
@@ -59,7 +59,7 @@ Show a route and all stops for a particular direction:
|
|
59
59
|
Get predictions for a bus, going a certain direction, at a given stop.
|
60
60
|
`predict` can take the formal tag names for the direction and stop, or
|
61
61
|
it will perform it's best guess.
|
62
|
-
|
62
|
+
|
63
63
|
With formal direction and stop tags:
|
64
64
|
|
65
65
|
$ muni predict 21 21_OB4 5008
|
@@ -71,7 +71,7 @@ With formal direction and stop tags:
|
|
71
71
|
2823 about 1 hour
|
72
72
|
|
73
73
|
With a fuzzy stop name:
|
74
|
-
|
74
|
+
|
75
75
|
$ muni predict 21 21_OB4 hayes and shrader
|
76
76
|
Route 21-Hayes going Outbound to Fulton St & Shrader St at Hayes St & Shrader St:
|
77
77
|
2831 2 minutes
|
@@ -81,15 +81,14 @@ With a fuzzy stop name:
|
|
81
81
|
2823 about 1 hour
|
82
82
|
|
83
83
|
With a fuzzy direction and stop name:
|
84
|
-
|
85
|
-
$ muni predict 21 inbound hayes and shrader
|
84
|
+
|
85
|
+
$ muni predict 21 inbound hayes and shrader
|
86
86
|
Route 21-Hayes going Inbound to Steuart Terminal at Hayes St & Shrader St:
|
87
87
|
8102 less than a minute
|
88
88
|
2832 2 minutes
|
89
89
|
2831 22 minutes
|
90
90
|
8189 32 minutes
|
91
91
|
2842 about 1 hour
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
92
|
+
|
93
|
+
|
94
|
+
|
data/muni.gemspec
CHANGED
@@ -22,7 +22,8 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_dependency "xml-simple"
|
23
23
|
s.add_dependency "actionpack"
|
24
24
|
s.add_dependency "amatch"
|
25
|
-
# For the executable
|
26
|
-
s.
|
27
|
-
s.add_development_dependency "
|
25
|
+
s.add_dependency "thor" # For the executable
|
26
|
+
s.add_development_dependency "rspec", "~> 2"
|
27
|
+
s.add_development_dependency "webmock"
|
28
|
+
s.add_development_dependency "vcr"
|
28
29
|
end
|
@@ -0,0 +1,263 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://webservices.nextbus.com/service/publicXMLFeed?a=sf-muni&command=routeList
|
6
|
+
body: ''
|
7
|
+
headers:
|
8
|
+
Accept:
|
9
|
+
- ! '*/*'
|
10
|
+
User-Agent:
|
11
|
+
- Ruby
|
12
|
+
response:
|
13
|
+
status:
|
14
|
+
code: 200
|
15
|
+
message: OK
|
16
|
+
headers:
|
17
|
+
Date:
|
18
|
+
- Wed, 21 Nov 2012 17:58:13 GMT
|
19
|
+
Server:
|
20
|
+
- Apache/2.2.4 (Unix) mod_ssl/2.2.4 OpenSSL/0.9.7m DAV/2 mod_jk/1.2.30
|
21
|
+
Access-Control-Allow-Origin:
|
22
|
+
- ! '*'
|
23
|
+
Content-Length:
|
24
|
+
- '3473'
|
25
|
+
Vary:
|
26
|
+
- Accept-Encoding
|
27
|
+
Content-Type:
|
28
|
+
- text/xml
|
29
|
+
body: ! "<?xml version=\"1.0\" encoding=\"utf-8\" ?> \n<body copyright=\"All data
|
30
|
+
copyright San Francisco Muni 2012.\">\n<route tag=\"F\" title=\"F-Market &
|
31
|
+
Wharves\"/>\n<route tag=\"J\" title=\"J-Church\"/>\n<route tag=\"KT\" title=\"KT-Ingleside/Third
|
32
|
+
Street\"/>\n<route tag=\"L\" title=\"L-Taraval\"/>\n<route tag=\"M\" title=\"M-Ocean
|
33
|
+
View\"/>\n<route tag=\"N\" title=\"N-Judah\"/>\n<route tag=\"NX\" title=\"NX-N
|
34
|
+
Express\"/>\n<route tag=\"1\" title=\"1-California\"/>\n<route tag=\"1AX\" title=\"1AX-California
|
35
|
+
A Express\"/>\n<route tag=\"1BX\" title=\"1BX-California B Express\"/>\n<route
|
36
|
+
tag=\"2\" title=\"2-Clement\"/>\n<route tag=\"3\" title=\"3-Jackson\"/>\n<route
|
37
|
+
tag=\"5\" title=\"5-Fulton\"/>\n<route tag=\"6\" title=\"6-Parnassus\"/>\n<route
|
38
|
+
tag=\"8X\" title=\"8X-Bayshore Exp\"/>\n<route tag=\"8AX\" title=\"8AX-Bayshore
|
39
|
+
A Exp\"/>\n<route tag=\"8BX\" title=\"8BX-Bayshore B Exp\"/>\n<route tag=\"9\"
|
40
|
+
title=\"9-San Bruno\"/>\n<route tag=\"9L\" title=\"9L-San Bruno Limited\"/>\n<route
|
41
|
+
tag=\"10\" title=\"10-Townsend\"/>\n<route tag=\"12\" title=\"12-Folsom/Pacific\"/>\n<route
|
42
|
+
tag=\"14\" title=\"14-Mission\"/>\n<route tag=\"14L\" title=\"14L-Mission Limited\"/>\n<route
|
43
|
+
tag=\"14X\" title=\"14X-Mission Express\"/>\n<route tag=\"16X\" title=\"16X-Noriega
|
44
|
+
Express\"/>\n<route tag=\"17\" title=\"17-Park Merced\"/>\n<route tag=\"18\"
|
45
|
+
title=\"18-46th Avenue\"/>\n<route tag=\"19\" title=\"19-Polk\"/>\n<route tag=\"21\"
|
46
|
+
title=\"21-Hayes\"/>\n<route tag=\"22\" title=\"22-Fillmore\"/>\n<route tag=\"23\"
|
47
|
+
title=\"23-Monterey\"/>\n<route tag=\"24\" title=\"24-Divisadero\"/>\n<route
|
48
|
+
tag=\"27\" title=\"27-Bryant\"/>\n<route tag=\"28\" title=\"28-19th Avenue\"/>\n<route
|
49
|
+
tag=\"28L\" title=\"28L-19th Avenue Limited\"/>\n<route tag=\"29\" title=\"29-Sunset\"/>\n<route
|
50
|
+
tag=\"30\" title=\"30-Stockton\"/>\n<route tag=\"30X\" title=\"30X-Marina Express\"/>\n<route
|
51
|
+
tag=\"31\" title=\"31-Balboa\"/>\n<route tag=\"31AX\" title=\"31AX-Balboa A
|
52
|
+
Express\"/>\n<route tag=\"31BX\" title=\"31BX-Balboa B Express\"/>\n<route tag=\"33\"
|
53
|
+
title=\"33-Stanyan\"/>\n<route tag=\"35\" title=\"35-Eureka\"/>\n<route tag=\"36\"
|
54
|
+
title=\"36-Teresita\"/>\n<route tag=\"37\" title=\"37-Corbett\"/>\n<route tag=\"38\"
|
55
|
+
title=\"38-Geary\"/>\n<route tag=\"38AX\" title=\"38AX-Geary A Express\"/>\n<route
|
56
|
+
tag=\"38BX\" title=\"38BX-Geary B Express\"/>\n<route tag=\"38L\" title=\"38L-Geary
|
57
|
+
Limited\"/>\n<route tag=\"39\" title=\"39-Coit\"/>\n<route tag=\"41\" title=\"41-Union\"/>\n<route
|
58
|
+
tag=\"43\" title=\"43-Masonic\"/>\n<route tag=\"44\" title=\"44-O'Shaughnessy\"/>\n<route
|
59
|
+
tag=\"45\" title=\"45-Union/Stockton\"/>\n<route tag=\"47\" title=\"47-Van Ness\"/>\n<route
|
60
|
+
tag=\"48\" title=\"48-Quintara - 24th Street\"/>\n<route tag=\"49\" title=\"49-Mission-Van
|
61
|
+
Ness\"/>\n<route tag=\"52\" title=\"52-Excelsior\"/>\n<route tag=\"54\" title=\"54-Felton\"/>\n<route
|
62
|
+
tag=\"56\" title=\"56-Rutland\"/>\n<route tag=\"66\" title=\"66-Quintara\"/>\n<route
|
63
|
+
tag=\"67\" title=\"67-Bernal Heights\"/>\n<route tag=\"71\" title=\"71-Haight-Noriega\"/>\n<route
|
64
|
+
tag=\"71L\" title=\"71L-Haight-Noriega Limited\"/>\n<route tag=\"76\" title=\"76-Marin
|
65
|
+
Headlands\"/>\n<route tag=\"80X\" title=\"80X-Gateway Express\"/>\n<route tag=\"81X\"
|
66
|
+
title=\"81X-Caltrain Express\"/>\n<route tag=\"82X\" title=\"82X-Levi Plaza
|
67
|
+
Express\"/>\n<route tag=\"83X\" title=\"83X-Caltrain\"/>\n<route tag=\"88\"
|
68
|
+
title=\"88-B.A.R.T. Shuttle\"/>\n<route tag=\"90\" title=\"90-San Bruno Owl\"/>\n<route
|
69
|
+
tag=\"91\" title=\"91-Owl\"/>\n<route tag=\"108\" title=\"108-Treasure Island\"/>\n<route
|
70
|
+
tag=\"K OWL\" title=\"K-Owl\"/>\n<route tag=\"L OWL\" title=\"L-Owl\"/>\n<route
|
71
|
+
tag=\"M OWL\" title=\"M-Owl\"/>\n<route tag=\"N OWL\" title=\"N-Owl\"/>\n<route
|
72
|
+
tag=\"T OWL\" title=\"T-Owl\"/>\n<route tag=\"59\" title=\"Powell/Mason Cable
|
73
|
+
Car\"/>\n<route tag=\"60\" title=\"Powell/Hyde Cable Car\"/>\n<route tag=\"61\"
|
74
|
+
title=\"California Cable Car\"/>\n</body>\n"
|
75
|
+
http_version:
|
76
|
+
recorded_at: Wed, 21 Nov 2012 17:58:15 GMT
|
77
|
+
- request:
|
78
|
+
method: get
|
79
|
+
uri: http://webservices.nextbus.com/service/publicXMLFeed?a=sf-muni&command=routeConfig&r=21
|
80
|
+
body: ''
|
81
|
+
headers:
|
82
|
+
Accept:
|
83
|
+
- ! '*/*'
|
84
|
+
User-Agent:
|
85
|
+
- Ruby
|
86
|
+
response:
|
87
|
+
status:
|
88
|
+
code: 200
|
89
|
+
message: OK
|
90
|
+
headers:
|
91
|
+
Date:
|
92
|
+
- Wed, 21 Nov 2012 17:58:13 GMT
|
93
|
+
Server:
|
94
|
+
- Apache/2.2.4 (Unix) mod_ssl/2.2.4 OpenSSL/0.9.7m DAV/2 mod_jk/1.2.30
|
95
|
+
Access-Control-Allow-Origin:
|
96
|
+
- ! '*'
|
97
|
+
Vary:
|
98
|
+
- Accept-Encoding
|
99
|
+
Transfer-Encoding:
|
100
|
+
- chunked
|
101
|
+
Content-Type:
|
102
|
+
- text/xml
|
103
|
+
body: ! "<?xml version=\"1.0\" encoding=\"utf-8\" ?> \n<body copyright=\"All data
|
104
|
+
copyright San Francisco Muni 2012.\">\n<route tag=\"21\" title=\"21-Hayes\"
|
105
|
+
color=\"660000\" oppositeColor=\"ffffff\" latMin=\"37.7729599\" latMax=\"37.7944299\"
|
106
|
+
lonMin=\"-122.46384\" lonMax=\"-122.39323\">\n<stop tag=\"6497\" title=\"Steuart
|
107
|
+
St & Mission St\" lat=\"37.7933499\" lon=\"-122.39323\" stopId=\"16497\"/>\n<stop
|
108
|
+
tag=\"6501\" title=\"Steuart St & Market St\" lat=\"37.7944299\" lon=\"-122.3945499\"
|
109
|
+
stopId=\"16501\"/>\n<stop tag=\"5669\" title=\"Market St & Drumm St\" lat=\"37.79347\"
|
110
|
+
lon=\"-122.3961799\" stopId=\"15669\"/>\n<stop tag=\"5671\" title=\"Market St
|
111
|
+
& Front St\" lat=\"37.79192\" lon=\"-122.3981499\" stopId=\"15671\"/>\n<stop
|
112
|
+
tag=\"5689\" title=\"Market St & Sansome St\" lat=\"37.7901599\" lon=\"-122.40041\"
|
113
|
+
stopId=\"15689\"/>\n<stop tag=\"5684\" title=\"Market St & Montgomery St\"
|
114
|
+
lat=\"37.7884899\" lon=\"-122.40248\" stopId=\"15684\"/>\n<stop tag=\"5674\"
|
115
|
+
title=\"Market St & Grant Ave\" lat=\"37.78639\" lon=\"-122.4051599\" stopId=\"15674\"/>\n<stop
|
116
|
+
tag=\"5688\" title=\"Market St & Powell St\" lat=\"37.7846799\" lon=\"-122.40731\"
|
117
|
+
stopId=\"15688\"/>\n<stop tag=\"5683\" title=\"Market St & Mason St\" lat=\"37.7828499\"
|
118
|
+
lon=\"-122.40964\" stopId=\"15683\"/>\n<stop tag=\"5656\" title=\"Market St
|
119
|
+
& 7th St North\" lat=\"37.7805699\" lon=\"-122.41244\" stopId=\"15656\"/>\n<stop
|
120
|
+
tag=\"7423\" title=\"Market St & Hyde St\" lat=\"37.7787799\" lon=\"-122.41472\"
|
121
|
+
stopId=\"17423\"/>\n<stop tag=\"4997\" title=\"Hayes St & Larkin St\" lat=\"37.7777099\"
|
122
|
+
lon=\"-122.41685\" stopId=\"14997\"/>\n<stop tag=\"5013\" title=\"Hayes St &
|
123
|
+
Van Ness Ave\" lat=\"37.7772899\" lon=\"-122.42019\" stopId=\"15013\"/>\n<stop
|
124
|
+
tag=\"4996\" title=\"Hayes St & Gough St\" lat=\"37.77689\" lon=\"-122.4233299\"
|
125
|
+
stopId=\"14996\"/>\n<stop tag=\"4998\" title=\"Hayes St & Laguna St\" lat=\"37.7765299\"
|
126
|
+
lon=\"-122.42615\" stopId=\"14998\"/>\n<stop tag=\"4983\" title=\"Hayes St &
|
127
|
+
Buchanan St\" lat=\"37.7762599\" lon=\"-122.42827\" stopId=\"14983\"/>\n<stop
|
128
|
+
tag=\"5014\" title=\"Hayes St & Webster St\" lat=\"37.7760599\" lon=\"-122.42988\"
|
129
|
+
stopId=\"15014\"/>\n<stop tag=\"4993\" title=\"Hayes St & Fillmore St\"
|
130
|
+
lat=\"37.77584\" lon=\"-122.4315599\" stopId=\"14993\"/>\n<stop tag=\"5011\"
|
131
|
+
title=\"Hayes St & Steiner St\" lat=\"37.77563\" lon=\"-122.4331999\" stopId=\"15011\"/>\n<stop
|
132
|
+
tag=\"5003\" title=\"Hayes St & Pierce St\" lat=\"37.77547\" lon=\"-122.4344399\"
|
133
|
+
stopId=\"15003\"/>\n<stop tag=\"4991\" title=\"Hayes St & Divisadero St\"
|
134
|
+
lat=\"37.7749899\" lon=\"-122.43818\" stopId=\"14991\"/>\n<stop tag=\"4979\"
|
135
|
+
title=\"Hayes St & Baker St\" lat=\"37.7745699\" lon=\"-122.4415\" stopId=\"14979\"/>\n<stop
|
136
|
+
tag=\"4999\" title=\"Hayes St & Lyon St\" lat=\"37.77443\" lon=\"-122.4426299\"
|
137
|
+
stopId=\"14999\"/>\n<stop tag=\"4985\" title=\"Hayes St & Central Ave\"
|
138
|
+
lat=\"37.7742\" lon=\"-122.4442999\" stopId=\"14985\"/>\n<stop tag=\"5001\"
|
139
|
+
title=\"Hayes St & Masonic Ave\" lat=\"37.7739299\" lon=\"-122.44651\" stopId=\"15001\"/>\n<stop
|
140
|
+
tag=\"4987\" title=\"Hayes St & Clayton St\" lat=\"37.7736099\" lon=\"-122.44917\"
|
141
|
+
stopId=\"14987\"/>\n<stop tag=\"5007\" title=\"Hayes St & Shrader St\" lat=\"37.7731699\"
|
142
|
+
lon=\"-122.4525\" stopId=\"15007\"/>\n<stop tag=\"5009\" title=\"Hayes St &
|
143
|
+
Stanyan St\" lat=\"37.7729599\" lon=\"-122.45415\" stopId=\"15009\"/>\n<stop
|
144
|
+
tag=\"37499\" title=\"Fulton St & Shrader St\" lat=\"37.7748699\" lon=\"-122.45309\"
|
145
|
+
stopId=\"137499\"/>\n<stop tag=\"7499\" title=\"Fulton St & Shrader St\"
|
146
|
+
lat=\"37.7748699\" lon=\"-122.45309\" stopId=\"17499\"/>\n<stop tag=\"7561\"
|
147
|
+
title=\"Hayes St & Shrader St\" lat=\"37.77306\" lon=\"-122.4525099\" stopId=\"17561\"/>\n<stop
|
148
|
+
tag=\"4988\" title=\"Hayes St & Clayton St\" lat=\"37.7734199\" lon=\"-122.44946\"
|
149
|
+
stopId=\"14988\"/>\n<stop tag=\"5002\" title=\"Hayes St & Masonic Ave\"
|
150
|
+
lat=\"37.7739499\" lon=\"-122.44568\" stopId=\"15002\"/>\n<stop tag=\"4986\"
|
151
|
+
title=\"Hayes St & Central Ave\" lat=\"37.77409\" lon=\"-122.4445099\" stopId=\"14986\"/>\n<stop
|
152
|
+
tag=\"5000\" title=\"Hayes St & Lyon St\" lat=\"37.7742899\" lon=\"-122.44286\"
|
153
|
+
stopId=\"15000\"/>\n<stop tag=\"4980\" title=\"Hayes St & Baker St\" lat=\"37.7745099\"
|
154
|
+
lon=\"-122.44126\" stopId=\"14980\"/>\n<stop tag=\"4992\" title=\"Hayes St &
|
155
|
+
Divisadero St\" lat=\"37.7749999\" lon=\"-122.4374\" stopId=\"14992\"/>\n<stop
|
156
|
+
tag=\"5004\" title=\"Hayes St & Pierce St\" lat=\"37.7754099\" lon=\"-122.43418\"
|
157
|
+
stopId=\"15004\"/>\n<stop tag=\"5012\" title=\"Hayes St & Steiner St\" lat=\"37.77563\"
|
158
|
+
lon=\"-122.4324799\" stopId=\"15012\"/>\n<stop tag=\"4994\" title=\"Hayes St
|
159
|
+
& Fillmore St\" lat=\"37.7757999\" lon=\"-122.43083\" stopId=\"14994\"/>\n<stop
|
160
|
+
tag=\"5015\" title=\"Hayes St & Webster St\" lat=\"37.7760399\" lon=\"-122.42919\"
|
161
|
+
stopId=\"15015\"/>\n<stop tag=\"4984\" title=\"Hayes St & Buchanan St\"
|
162
|
+
lat=\"37.77624\" lon=\"-122.4275499\" stopId=\"14984\"/>\n<stop tag=\"5260\"
|
163
|
+
title=\"Laguna St & Hayes St\" lat=\"37.7767499\" lon=\"-122.42627\" stopId=\"15260\"/>\n<stop
|
164
|
+
tag=\"4921\" title=\"Grove St & Laguna St\" lat=\"37.77738\" lon=\"-122.4263199\"
|
165
|
+
stopId=\"14921\"/>\n<stop tag=\"4920\" title=\"Grove St & Gough St\" lat=\"37.77775\"
|
166
|
+
lon=\"-122.4233099\" stopId=\"14920\"/>\n<stop tag=\"4923\" title=\"Grove St
|
167
|
+
& Van Ness Ave\" lat=\"37.7781899\" lon=\"-122.41974\" stopId=\"14923\"/>\n<stop
|
168
|
+
tag=\"7463\" title=\"Grove St & Polk St\" lat=\"37.77838\" lon=\"-122.4183099\"
|
169
|
+
stopId=\"17463\"/>\n<stop tag=\"5652\" title=\"Market St & 9th St\" lat=\"37.77741\"
|
170
|
+
lon=\"-122.4163399\" stopId=\"15652\"/>\n<stop tag=\"5651\" title=\"Market St
|
171
|
+
& 8th St\" lat=\"37.77861\" lon=\"-122.4148299\" stopId=\"15651\"/>\n<stop
|
172
|
+
tag=\"5650\" title=\"Market St & 7th St\" lat=\"37.7803599\" lon=\"-122.41261\"
|
173
|
+
stopId=\"15650\"/>\n<stop tag=\"5647\" title=\"Market St & 6th St\" lat=\"37.7820999\"
|
174
|
+
lon=\"-122.4104\" stopId=\"15647\"/>\n<stop tag=\"5645\" title=\"Market St &
|
175
|
+
5th St\" lat=\"37.7838899\" lon=\"-122.40814\" stopId=\"15645\"/>\n<stop tag=\"5643\"
|
176
|
+
title=\"Market St & 4th St\" lat=\"37.7856499\" lon=\"-122.40589\" stopId=\"15643\"/>\n<stop
|
177
|
+
tag=\"5640\" title=\"Market St & 3rd St\" lat=\"37.7875299\" lon=\"-122.40352\"
|
178
|
+
stopId=\"15640\"/>\n<stop tag=\"5685\" title=\"Market St & New Montgomery
|
179
|
+
St\" lat=\"37.7886099\" lon=\"-122.40216\" stopId=\"15685\"/>\n<stop tag=\"7264\"
|
180
|
+
title=\"Market St & 1st St\" lat=\"37.79094\" lon=\"-122.3991899\" stopId=\"17264\"/>\n<stop
|
181
|
+
tag=\"5658\" title=\"Market St & Beale St\" lat=\"37.79257\" lon=\"-122.3970199\"
|
182
|
+
stopId=\"15658\"/>\n<stop tag=\"6475\" title=\"Spear St & Market St\" lat=\"37.7935899\"
|
183
|
+
lon=\"-122.3955499\" stopId=\"16475\"/>\n<stop tag=\"36497\" title=\"Steuart
|
184
|
+
St & Mission St\" lat=\"37.7933499\" lon=\"-122.39323\" stopId=\"136497\"/>\n<stop
|
185
|
+
tag=\"4733\" title=\"Fulton St & 6th Ave\" lat=\"37.7735299\" lon=\"-122.46384\"
|
186
|
+
stopId=\"14733\"/>\n<stop tag=\"3089\" title=\"Beale St & Mission St\" lat=\"37.7917499\"
|
187
|
+
lon=\"-122.3967\" stopId=\"13089\"/>\n<direction tag=\"21_IB1\" title=\"Inbound
|
188
|
+
to Downtown\" name=\"Inbound\" useForUI=\"true\">\n <stop tag=\"7499\" />\n
|
189
|
+
\ <stop tag=\"7561\" />\n <stop tag=\"4988\" />\n <stop tag=\"5002\" />\n
|
190
|
+
\ <stop tag=\"4986\" />\n <stop tag=\"5000\" />\n <stop tag=\"4980\" />\n
|
191
|
+
\ <stop tag=\"4992\" />\n <stop tag=\"5004\" />\n <stop tag=\"5012\" />\n
|
192
|
+
\ <stop tag=\"4994\" />\n <stop tag=\"5015\" />\n <stop tag=\"4984\" />\n
|
193
|
+
\ <stop tag=\"5260\" />\n <stop tag=\"4921\" />\n <stop tag=\"4920\" />\n
|
194
|
+
\ <stop tag=\"4923\" />\n <stop tag=\"7463\" />\n <stop tag=\"5652\" />\n
|
195
|
+
\ <stop tag=\"5651\" />\n <stop tag=\"5650\" />\n <stop tag=\"5647\" />\n
|
196
|
+
\ <stop tag=\"5645\" />\n <stop tag=\"5643\" />\n <stop tag=\"5640\" />\n
|
197
|
+
\ <stop tag=\"5685\" />\n <stop tag=\"7264\" />\n <stop tag=\"5658\" />\n
|
198
|
+
\ <stop tag=\"6475\" />\n <stop tag=\"36497\" />\n</direction>\n<direction
|
199
|
+
tag=\"21_OB4\" title=\"Outbound to Golden Gate Park\" name=\"Outbound\" useForUI=\"true\">\n
|
200
|
+
\ <stop tag=\"6497\" />\n <stop tag=\"6501\" />\n <stop tag=\"5669\" />\n
|
201
|
+
\ <stop tag=\"5671\" />\n <stop tag=\"5689\" />\n <stop tag=\"5684\" />\n
|
202
|
+
\ <stop tag=\"5674\" />\n <stop tag=\"5688\" />\n <stop tag=\"5683\" />\n
|
203
|
+
\ <stop tag=\"5656\" />\n <stop tag=\"7423\" />\n <stop tag=\"4997\" />\n
|
204
|
+
\ <stop tag=\"5013\" />\n <stop tag=\"4996\" />\n <stop tag=\"4998\" />\n
|
205
|
+
\ <stop tag=\"4983\" />\n <stop tag=\"5014\" />\n <stop tag=\"4993\" />\n
|
206
|
+
\ <stop tag=\"5011\" />\n <stop tag=\"5003\" />\n <stop tag=\"4991\" />\n
|
207
|
+
\ <stop tag=\"4979\" />\n <stop tag=\"4999\" />\n <stop tag=\"4985\" />\n
|
208
|
+
\ <stop tag=\"5001\" />\n <stop tag=\"4987\" />\n <stop tag=\"5007\" />\n
|
209
|
+
\ <stop tag=\"5009\" />\n <stop tag=\"37499\" />\n</direction>\n<path>\n<point
|
210
|
+
lat=\"37.775\" lon=\"-122.4374\"/>\n<point lat=\"37.77541\" lon=\"-122.43418\"/>\n<point
|
211
|
+
lat=\"37.77563\" lon=\"-122.43248\"/>\n<point lat=\"37.7757999\" lon=\"-122.43083\"/>\n<point
|
212
|
+
lat=\"37.77604\" lon=\"-122.42919\"/>\n<point lat=\"37.77624\" lon=\"-122.42755\"/>\n<point
|
213
|
+
lat=\"37.77646\" lon=\"-122.42627\"/>\n<point lat=\"37.77675\" lon=\"-122.42627\"/>\n<point
|
214
|
+
lat=\"37.7773899\" lon=\"-122.42646\"/>\n<point lat=\"37.77738\" lon=\"-122.42632\"/>\n<point
|
215
|
+
lat=\"37.77775\" lon=\"-122.42331\"/>\n<point lat=\"37.77819\" lon=\"-122.41974\"/>\n</path>\n<path>\n<point
|
216
|
+
lat=\"37.77487\" lon=\"-122.45309\"/>\n<point lat=\"37.77496\" lon=\"-122.45299\"/>\n<point
|
217
|
+
lat=\"37.7731\" lon=\"-122.45262\"/>\n<point lat=\"37.77306\" lon=\"-122.45251\"/>\n<point
|
218
|
+
lat=\"37.77342\" lon=\"-122.44946\"/>\n<point lat=\"37.77395\" lon=\"-122.44568\"/>\n</path>\n<path>\n<point
|
219
|
+
lat=\"37.77819\" lon=\"-122.41974\"/>\n<point lat=\"37.77848\" lon=\"-122.41823\"/>\n<point
|
220
|
+
lat=\"37.77838\" lon=\"-122.41831\"/>\n<point lat=\"37.7768\" lon=\"-122.4179\"/>\n<point
|
221
|
+
lat=\"37.77654\" lon=\"-122.41751\"/>\n<point lat=\"37.77741\" lon=\"-122.41634\"/>\n<point
|
222
|
+
lat=\"37.77861\" lon=\"-122.41483\"/>\n<point lat=\"37.78036\" lon=\"-122.41261\"/>\n</path>\n<path>\n<point
|
223
|
+
lat=\"37.77393\" lon=\"-122.44651\"/>\n<point lat=\"37.77361\" lon=\"-122.44917\"/>\n<point
|
224
|
+
lat=\"37.77317\" lon=\"-122.4525\"/>\n<point lat=\"37.77296\" lon=\"-122.45415\"/>\n<point
|
225
|
+
lat=\"37.7728899\" lon=\"-122.45428\"/>\n<point lat=\"37.77464\" lon=\"-122.45463\"/>\n<point
|
226
|
+
lat=\"37.7749\" lon=\"-122.45346\"/>\n<point lat=\"37.77487\" lon=\"-122.45309\"/>\n</path>\n<path>\n<point
|
227
|
+
lat=\"37.7856499\" lon=\"-122.40589\"/>\n<point lat=\"37.7875299\" lon=\"-122.40352\"/>\n<point
|
228
|
+
lat=\"37.78861\" lon=\"-122.40216\"/>\n</path>\n<path>\n<point lat=\"37.78036\"
|
229
|
+
lon=\"-122.41261\"/>\n<point lat=\"37.7821\" lon=\"-122.4104\"/>\n<point lat=\"37.78389\"
|
230
|
+
lon=\"-122.40814\"/>\n<point lat=\"37.7856499\" lon=\"-122.40589\"/>\n</path>\n<path>\n<point
|
231
|
+
lat=\"37.77487\" lon=\"-122.45309\"/>\n<point lat=\"37.7731\" lon=\"-122.45262\"/>\n<point
|
232
|
+
lat=\"37.77306\" lon=\"-122.45251\"/>\n<point lat=\"37.77342\" lon=\"-122.44946\"/>\n<point
|
233
|
+
lat=\"37.77395\" lon=\"-122.44568\"/>\n</path>\n<path>\n<point lat=\"37.77499\"
|
234
|
+
lon=\"-122.43818\"/>\n<point lat=\"37.77457\" lon=\"-122.4415\"/>\n<point lat=\"37.77443\"
|
235
|
+
lon=\"-122.44263\"/>\n<point lat=\"37.7742\" lon=\"-122.4443\"/>\n<point lat=\"37.77393\"
|
236
|
+
lon=\"-122.44651\"/>\n</path>\n<path>\n<point lat=\"37.77729\" lon=\"-122.42019\"/>\n<point
|
237
|
+
lat=\"37.77689\" lon=\"-122.42333\"/>\n<point lat=\"37.77653\" lon=\"-122.42615\"/>\n<point
|
238
|
+
lat=\"37.77626\" lon=\"-122.42827\"/>\n<point lat=\"37.77606\" lon=\"-122.42988\"/>\n<point
|
239
|
+
lat=\"37.77584\" lon=\"-122.43156\"/>\n<point lat=\"37.77563\" lon=\"-122.4332\"/>\n<point
|
240
|
+
lat=\"37.77547\" lon=\"-122.43444\"/>\n<point lat=\"37.77499\" lon=\"-122.43818\"/>\n</path>\n<path>\n<point
|
241
|
+
lat=\"37.78468\" lon=\"-122.40731\"/>\n<point lat=\"37.78285\" lon=\"-122.40964\"/>\n<point
|
242
|
+
lat=\"37.78057\" lon=\"-122.41244\"/>\n</path>\n<path>\n<point lat=\"37.78861\"
|
243
|
+
lon=\"-122.40216\"/>\n<point lat=\"37.79094\" lon=\"-122.39919\"/>\n<point lat=\"37.79257\"
|
244
|
+
lon=\"-122.39702\"/>\n<point lat=\"37.79378\" lon=\"-122.39563\"/>\n<point lat=\"37.79359\"
|
245
|
+
lon=\"-122.39555\"/>\n<point lat=\"37.79254\" lon=\"-122.39407\"/>\n<point lat=\"37.79322\"
|
246
|
+
lon=\"-122.39319\"/>\n<point lat=\"37.7933499\" lon=\"-122.39323\"/>\n</path>\n<path>\n<point
|
247
|
+
lat=\"37.7933499\" lon=\"-122.39323\"/>\n<point lat=\"37.79443\" lon=\"-122.39455\"/>\n<point
|
248
|
+
lat=\"37.7944699\" lon=\"-122.39476\"/>\n<point lat=\"37.79347\" lon=\"-122.39618\"/>\n<point
|
249
|
+
lat=\"37.79192\" lon=\"-122.39815\"/>\n<point lat=\"37.79016\" lon=\"-122.40041\"/>\n</path>\n<path>\n<point
|
250
|
+
lat=\"37.79016\" lon=\"-122.40041\"/>\n<point lat=\"37.78849\" lon=\"-122.40248\"/>\n<point
|
251
|
+
lat=\"37.78639\" lon=\"-122.40516\"/>\n<point lat=\"37.78468\" lon=\"-122.40731\"/>\n</path>\n<path>\n<point
|
252
|
+
lat=\"37.78861\" lon=\"-122.40216\"/>\n<point lat=\"37.7924\" lon=\"-122.39739\"/>\n<point
|
253
|
+
lat=\"37.79175\" lon=\"-122.3967\"/>\n</path>\n<path>\n<point lat=\"37.77353\"
|
254
|
+
lon=\"-122.46384\"/>\n<point lat=\"37.77487\" lon=\"-122.45309\"/>\n</path>\n<path>\n<point
|
255
|
+
lat=\"37.77395\" lon=\"-122.44568\"/>\n<point lat=\"37.77409\" lon=\"-122.44451\"/>\n<point
|
256
|
+
lat=\"37.77429\" lon=\"-122.44286\"/>\n<point lat=\"37.77451\" lon=\"-122.44126\"/>\n<point
|
257
|
+
lat=\"37.775\" lon=\"-122.4374\"/>\n</path>\n<path>\n<point lat=\"37.78057\"
|
258
|
+
lon=\"-122.41244\"/>\n<point lat=\"37.77878\" lon=\"-122.41472\"/>\n<point lat=\"37.77779\"
|
259
|
+
lon=\"-122.41593\"/>\n<point lat=\"37.77771\" lon=\"-122.41685\"/>\n<point lat=\"37.77729\"
|
260
|
+
lon=\"-122.42019\"/>\n</path>\n</route>\n</body>\n"
|
261
|
+
http_version:
|
262
|
+
recorded_at: Wed, 21 Nov 2012 17:58:15 GMT
|
263
|
+
recorded_with: VCR 2.0.0.rc1
|