reittiopas 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemtest +0 -0
- data/.rspec +2 -0
- data/.yardoc/checksums +9 -0
- data/.yardoc/object_types +4 -0
- data/.yardoc/objects/root.dat +0 -0
- data/.yardoc/proxy_types +0 -0
- data/History.txt +10 -0
- data/Manifest.txt +11 -2
- data/README.md +103 -0
- data/Rakefile +33 -27
- data/lib/reittiopas.rb +3 -1
- data/lib/reittiopas/coordinates.rb +4 -0
- data/lib/reittiopas/reittiopas.rb +2 -1
- data/lib/reittiopas/routing.rb +310 -0
- data/spec/fixtures/kallion_kirjasto.xml +1 -0
- data/spec/fixtures/no_access +7 -7
- data/spec/fixtures/route_ulvilantie_19-kallion_kirjasto.xml +776 -0
- data/spec/fixtures/ulvilantie_19_helsinki.xml +1 -0
- data/spec/reittiopas_routing_spec.rb +373 -0
- data/spec/reittiopas_spec.rb +1 -1
- data/spec/spec_helper.rb +3 -3
- data/tasks/rdoc.rake +8 -8
- data/tasks/rspec.rake +9 -15
- metadata +94 -30
- data/README.rdoc +0 -75
- data/spec/spec.opts +0 -4
data/.gemtest
ADDED
File without changes
|
data/.rspec
ADDED
data/.yardoc/checksums
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
lib/reittiopas.rb cced8096a3f0992a8d81ae358594e52a6149fff2
|
2
|
+
lib/reittiopas/reittiopas.rb 5019a3c332476f0e31f7416adfef3944c74ac649
|
3
|
+
lib/reittiopas/location.rb ddaf1913f5f6cc3267c5b97295c8daa3dc5375ac
|
4
|
+
lib/reittiopas/utils.rb 67f54e983f78e319fb239d173359fedf7d5187f6
|
5
|
+
lib/reittiopas/routing.rb 5833a35b3953e8f1d88e4ef48e6df43a4c72be47
|
6
|
+
lib/reittiopas/http.rb e5fccc0834481a6b2a1d732e2f7fa9007a291247
|
7
|
+
lib/reittiopas/geocoding.rb 41aacb43af4a7b178571646e7c4c2413dab250eb
|
8
|
+
lib/reittiopas/exceptions.rb c3d2abd5037e5971a29bc760b14171f8bba8c0b0
|
9
|
+
lib/reittiopas/coordinates.rb e4114495a73f43c51d040f3147f963fe28fcd1b6
|
@@ -0,0 +1,4 @@
|
|
1
|
+
{
|
2
|
+
:module[
|
3
|
+
"
|
4
|
+
class["Reittiopas"Reittiopas::HTTP"Nokogiri::XML::Element" Hash"Reittiopas::Routing::Route"!Reittiopas::Routing::Section"Reittiopas::Routing::Point"%Reittiopas::Routing::MapLocation"Reittiopas::Routing::Stop"%Reittiopas::Routing::SectionTime"!Reittiopas::Routing::Arrival"#Reittiopas::Routing::Departure"Reittiopas::Routing::Part"Reittiopas::Routing::Walk"Reittiopas::Routing::Line"Reittiopas::Location"*Reittiopas::Location::PointOfInterest"Reittiopas::Location::Stop"!Reittiopas::Location::Street"Reittiopas::AccessError"+Reittiopas::Location::Coordinates::WGS"+Reittiopas::Location::Coordinates::KKJ: root[;:
|
Binary file
|
data/.yardoc/proxy_types
ADDED
Binary file
|
data/History.txt
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
=== 0.1.0 2012-08-12
|
2
|
+
|
3
|
+
* Routing support from Matti Paksula
|
4
|
+
* Updated the project to use Rspec 2
|
5
|
+
* Use YARD for docs instead of Rdoc
|
6
|
+
|
7
|
+
=== 0.0.2 2010-04-22
|
8
|
+
|
9
|
+
* Fixed incorrectly configured runtime dependencies.
|
10
|
+
|
1
11
|
=== 0.0.1 2010-04-05
|
2
12
|
|
3
13
|
* 1 major enhancement:
|
data/Manifest.txt
CHANGED
@@ -1,6 +1,11 @@
|
|
1
|
+
.rspec
|
2
|
+
.yardoc/checksums
|
3
|
+
.yardoc/object_types
|
4
|
+
.yardoc/objects/root.dat
|
5
|
+
.yardoc/proxy_types
|
1
6
|
History.txt
|
2
7
|
Manifest.txt
|
3
|
-
README.
|
8
|
+
README.md
|
4
9
|
Rakefile
|
5
10
|
lib/reittiopas.rb
|
6
11
|
lib/reittiopas/coordinates.rb
|
@@ -9,15 +14,19 @@ lib/reittiopas/geocoding.rb
|
|
9
14
|
lib/reittiopas/http.rb
|
10
15
|
lib/reittiopas/location.rb
|
11
16
|
lib/reittiopas/reittiopas.rb
|
17
|
+
lib/reittiopas/routing.rb
|
12
18
|
lib/reittiopas/utils.rb
|
13
19
|
script/console
|
14
20
|
script/destroy
|
15
21
|
script/generate
|
22
|
+
spec/fixtures/kallion_kirjasto.xml
|
16
23
|
spec/fixtures/key.xml
|
17
24
|
spec/fixtures/no_access
|
18
25
|
spec/fixtures/reverse_geocoding.xml
|
26
|
+
spec/fixtures/route_ulvilantie_19-kallion_kirjasto.xml
|
27
|
+
spec/fixtures/ulvilantie_19_helsinki.xml
|
28
|
+
spec/reittiopas_routing_spec.rb
|
19
29
|
spec/reittiopas_spec.rb
|
20
|
-
spec/spec.opts
|
21
30
|
spec/spec_helper.rb
|
22
31
|
tasks/rdoc.rake
|
23
32
|
tasks/rspec.rake
|
data/README.md
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
# Reittiopas
|
2
|
+
|
3
|
+
* [Documentation at Github](http://raneksi.github.com/reittiopas/)
|
4
|
+
* [Specifications](http://raneksi.github.com/reittiopas/specdoc)
|
5
|
+
|
6
|
+
## DESCRIPTION
|
7
|
+
|
8
|
+
Reittiopas is a Ruby library for accessing the [Reittiopas Developer API](http://developer.reittiopas.fi/pages/fi/reittiopas-api.php).
|
9
|
+
|
10
|
+
Requires an account to the service that can be requested through [the account request page](http://developer.reittiopas.fi/pages/fi/accountrequest.php).
|
11
|
+
|
12
|
+
## SYNOPSIS
|
13
|
+
|
14
|
+
require 'reittiopas'
|
15
|
+
reittiopas = Reittiopas.new(:username => 'myuser', :password => 'lolcats')
|
16
|
+
|
17
|
+
#### Geocoding
|
18
|
+
|
19
|
+
Search for location by keyword _tee_.
|
20
|
+
|
21
|
+
location = reittiopas.location('tee').first
|
22
|
+
puts "#{location}, #{location.city}"
|
23
|
+
puts "http://maps.google.com/maps?q=#{URI.escape location.coordinates[:wgs]}"
|
24
|
+
|
25
|
+
=> Teeripuisto, Helsinki
|
26
|
+
=> http://maps.google.com/maps?q=60.2528,%2025.02051
|
27
|
+
|
28
|
+
### Reverse geocoding
|
29
|
+
|
30
|
+
Search for a location by [KKJ coordinates](http://fi.wikipedia.org/wiki/Kartastokoordinaattij%C3%A4rjestelm%C3%A4).
|
31
|
+
|
32
|
+
location = reittiopas.location(:x => 2546445, :y => 6675512).first
|
33
|
+
puts "#{location}, #{location.city}"
|
34
|
+
|
35
|
+
=> Otakaari 9, Espoo
|
36
|
+
|
37
|
+
### Routing
|
38
|
+
|
39
|
+
Search for routes between two locations: show 3 routes and do not use metro.
|
40
|
+
|
41
|
+
from = reittiopas.locations('mannerheimintie 5').first
|
42
|
+
to = reittiopas.location('kallion kirjasto').first
|
43
|
+
|
44
|
+
routes = reittiopas.routing(from, to, {"show" => 3, "use_metro" => 0})
|
45
|
+
routes.each do |route|
|
46
|
+
puts "#{route.distance} #{route.time}"
|
47
|
+
puts "Lines: "
|
48
|
+
|
49
|
+
route.lines.each do |line|
|
50
|
+
puts "#{line.code} starts from: #{line.stops.first.code}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
Options for routing are passed to Reittiopas. See Reittiopas developer API for the possible options.
|
55
|
+
|
56
|
+
|
57
|
+
## INSTALLATION
|
58
|
+
|
59
|
+
gem install reittiopas
|
60
|
+
|
61
|
+
or to use latest upstream:
|
62
|
+
|
63
|
+
git clone git://github.com/raneksi/reittiopas.git
|
64
|
+
cd reittiopas
|
65
|
+
rake newb
|
66
|
+
rake install_gem
|
67
|
+
|
68
|
+
## REQUIREMENTS
|
69
|
+
|
70
|
+
* [Nokogiri](htttp://nokogiri.org)
|
71
|
+
* [Addressable](http://github.com/sporkmonger/addressable)
|
72
|
+
|
73
|
+
## TODO
|
74
|
+
|
75
|
+
* Support for determining the closest stop within radius
|
76
|
+
|
77
|
+
## LICENSE
|
78
|
+
|
79
|
+
(The MIT License)
|
80
|
+
|
81
|
+
Copyright (c) 2010 - 2011:
|
82
|
+
|
83
|
+
* [Raine Virta](https://github.com/raneksi)
|
84
|
+
* [Matti Paksula](https://github.com/matti)
|
85
|
+
|
86
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
87
|
+
a copy of this software and associated documentation files (the
|
88
|
+
'Software'), to deal in the Software without restriction, including
|
89
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
90
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
91
|
+
permit persons to whom the Software is furnished to do so, subject to
|
92
|
+
the following conditions:
|
93
|
+
|
94
|
+
The above copyright notice and this permission notice shall be
|
95
|
+
included in all copies or substantial portions of the Software.
|
96
|
+
|
97
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
98
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
99
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
100
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
101
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
102
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
103
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
CHANGED
@@ -1,27 +1,33 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
gem 'hoe', '>= 2.1.0'
|
3
|
-
require 'hoe'
|
4
|
-
require 'fileutils'
|
5
|
-
|
6
|
-
Hoe.plugin :newgem
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'hoe', '>= 2.1.0'
|
3
|
+
require 'hoe'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
Hoe.plugin :newgem
|
7
|
+
Hoe.plugin :yard
|
8
|
+
|
9
|
+
$hoe = Hoe.spec 'reittiopas' do
|
10
|
+
developer 'Raine Virta', 'raine.virta@gmail.com'
|
11
|
+
self.rubyforge_name = self.name
|
12
|
+
|
13
|
+
self.extra_deps = [
|
14
|
+
[ 'addressable', '= 2.2.8' ],
|
15
|
+
[ 'nokogiri', '>= 0']
|
16
|
+
]
|
17
|
+
|
18
|
+
self.readme_file = "README.md"
|
19
|
+
self.urls = ["http://github.com/raneksi/reittiopas"]
|
20
|
+
self.extra_dev_deps = [
|
21
|
+
['webmock', "= 1.8.8"],
|
22
|
+
['rspec', "= 2.11.0"],
|
23
|
+
['yard', ">= 0.8.2.1"],
|
24
|
+
['hoe-yard', ">= 0"]
|
25
|
+
]
|
26
|
+
|
27
|
+
self.yard_title = 'Reittiopas (0.1.0)'
|
28
|
+
self.yard_markup = "markdown"
|
29
|
+
self.yard_opts = ['--protected']
|
30
|
+
end
|
31
|
+
|
32
|
+
require 'newgem/tasks'
|
33
|
+
Dir['tasks/**/*.rake'].each { |t| load t }
|
data/lib/reittiopas.rb
CHANGED
@@ -3,6 +3,7 @@ require 'cgi'
|
|
3
3
|
require 'net/http'
|
4
4
|
require 'nokogiri'
|
5
5
|
require 'addressable/uri'
|
6
|
+
require 'date'
|
6
7
|
|
7
8
|
$:.unshift(File.dirname(__FILE__)) unless
|
8
9
|
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
@@ -12,12 +13,13 @@ require 'reittiopas/utils'
|
|
12
13
|
require 'reittiopas/coordinates'
|
13
14
|
require 'reittiopas/location'
|
14
15
|
require 'reittiopas/geocoding'
|
16
|
+
require 'reittiopas/routing'
|
15
17
|
require 'reittiopas/reittiopas'
|
16
18
|
require 'reittiopas/http'
|
17
19
|
|
18
20
|
class Reittiopas
|
19
21
|
# The version of Reittiopas you are using.
|
20
|
-
VERSION = "0.0
|
22
|
+
VERSION = "0.1.0"
|
21
23
|
end
|
22
24
|
|
23
25
|
# Shorter way for Reittiopas instance creation.
|
@@ -0,0 +1,310 @@
|
|
1
|
+
class Reittiopas
|
2
|
+
|
3
|
+
module Routing
|
4
|
+
|
5
|
+
# Route between two Locations. Returns an array of Routes that contain all sub elements
|
6
|
+
|
7
|
+
def routing(from, to, opts)
|
8
|
+
@from = from
|
9
|
+
@to = to
|
10
|
+
@options = opts
|
11
|
+
|
12
|
+
params = { :a => @from.coordinates[:kkj].to_routing_string,
|
13
|
+
:b => @to.coordinates[:kkj].to_routing_string}.merge(@options)
|
14
|
+
|
15
|
+
xml = @http.get(params)
|
16
|
+
doc = Nokogiri::XML(xml)
|
17
|
+
|
18
|
+
routes = []
|
19
|
+
|
20
|
+
doc.search("ROUTE").each do |route|
|
21
|
+
routes << Route.parse(route)
|
22
|
+
end
|
23
|
+
|
24
|
+
return routes
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
class Route
|
29
|
+
|
30
|
+
attr_reader :time, :distance, :parts, :walks, :lines
|
31
|
+
|
32
|
+
def initialize(opts)
|
33
|
+
@time = opts[:time].to_f if opts[:time]
|
34
|
+
@distance = opts[:distance].to_f if opts[:distance]
|
35
|
+
|
36
|
+
@parts, @walks, @lines = opts[:parts], opts[:walks], opts[:lines]
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
# Parse the route and sub elements
|
41
|
+
def self.parse(xml)
|
42
|
+
length_element = xml.search("LENGTH").first
|
43
|
+
|
44
|
+
time = length_element.get_attr_value "time"
|
45
|
+
dist = length_element.get_attr_value "dist"
|
46
|
+
|
47
|
+
parts, walks, lines = [], [], []
|
48
|
+
|
49
|
+
xml.elements.each do |e|
|
50
|
+
next if e.name == "LENGTH"
|
51
|
+
case e.name
|
52
|
+
when "POINT"
|
53
|
+
parts << Point.parse(e)
|
54
|
+
when "WALK"
|
55
|
+
walk = Walk.parse(e)
|
56
|
+
parts << walk
|
57
|
+
walks << walk
|
58
|
+
when "LINE"
|
59
|
+
line = Line.parse(e)
|
60
|
+
parts << line
|
61
|
+
lines << line
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
new(:time => time,
|
67
|
+
:distance => dist,
|
68
|
+
:parts => parts,
|
69
|
+
:walks => walks,
|
70
|
+
:lines => lines)
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
# Points, MapLocations and Stops are Sections
|
78
|
+
class Section
|
79
|
+
attr_reader :x, :y, :arrival, :departure
|
80
|
+
|
81
|
+
def initialize(opts)
|
82
|
+
@x = opts[:x].to_f if opts[:x]
|
83
|
+
@y = opts[:y].to_f if opts[:y]
|
84
|
+
@arrival = opts[:arrival]
|
85
|
+
@departure = opts[:departure]
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.parse(xml)
|
89
|
+
x = xml.get_attr_value "x"
|
90
|
+
y = xml.get_attr_value "y"
|
91
|
+
|
92
|
+
arrival_element = xml.search("ARRIVAL").first
|
93
|
+
departure_element = xml.search("DEPARTURE").first
|
94
|
+
|
95
|
+
arrival = Arrival.parse arrival_element
|
96
|
+
departure = Departure.parse departure_element
|
97
|
+
|
98
|
+
{ :x => x,
|
99
|
+
:y => y,
|
100
|
+
:arrival => arrival,
|
101
|
+
:departure => departure }
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
class Point < Section
|
107
|
+
|
108
|
+
attr_reader :uid
|
109
|
+
|
110
|
+
def initialize(opts)
|
111
|
+
super
|
112
|
+
@uid = opts[:uid]
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.parse(xml)
|
116
|
+
opts = super
|
117
|
+
|
118
|
+
uid = xml.get_attr_value "uid"
|
119
|
+
|
120
|
+
opts.merge!( :uid => uid )
|
121
|
+
new(opts)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
class MapLocation < Section
|
126
|
+
|
127
|
+
attr_reader :location_type, :name
|
128
|
+
|
129
|
+
def initialize(opts)
|
130
|
+
super
|
131
|
+
@location_type = opts[:location_type].to_i if opts[:location_type]
|
132
|
+
@name = opts[:name]
|
133
|
+
end
|
134
|
+
|
135
|
+
def self.parse(xml)
|
136
|
+
opts = super
|
137
|
+
location_type = xml.get_attr_value "type"
|
138
|
+
|
139
|
+
name_elements = xml.search("NAME")
|
140
|
+
name = name_elements.first.get_attr_value "val" if name_elements.first
|
141
|
+
|
142
|
+
opts.merge!(:location_type => location_type,
|
143
|
+
:name => name)
|
144
|
+
|
145
|
+
new(opts)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
class Stop < Section
|
150
|
+
|
151
|
+
attr_reader :code, :stop_id,
|
152
|
+
:names
|
153
|
+
|
154
|
+
def initialize(opts)
|
155
|
+
super
|
156
|
+
@code = opts[:code]
|
157
|
+
@stop_id = opts[:stop_id]
|
158
|
+
@names = opts[:names]
|
159
|
+
end
|
160
|
+
|
161
|
+
def self.parse(xml)
|
162
|
+
opts = super
|
163
|
+
|
164
|
+
code = xml.get_attr_value "code"
|
165
|
+
stop_id = xml.get_attr_value "id"
|
166
|
+
|
167
|
+
name_elements = xml.search("NAME")
|
168
|
+
|
169
|
+
names = {}
|
170
|
+
name_elements.each do |e|
|
171
|
+
lang = e.get_attr_value "lang"
|
172
|
+
val = e.get_attr_value "val"
|
173
|
+
|
174
|
+
names[lang] = val
|
175
|
+
end
|
176
|
+
|
177
|
+
opts.merge!(:code => code,
|
178
|
+
:stop_id => stop_id,
|
179
|
+
:names => names)
|
180
|
+
new(opts)
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
|
185
|
+
# Each Section has Arrival and Departure times (and seems that those are always the same)
|
186
|
+
|
187
|
+
class SectionTime
|
188
|
+
|
189
|
+
attr_reader :date_time
|
190
|
+
|
191
|
+
def initialize(opts)
|
192
|
+
@date_time = DateTime.parse("#{opts[:date]} #{opts[:time]}")
|
193
|
+
end
|
194
|
+
|
195
|
+
def self.parse(xml)
|
196
|
+
date = xml.get_attr_value "date"
|
197
|
+
time = xml.get_attr_value "time"
|
198
|
+
|
199
|
+
new(:date => date,
|
200
|
+
:time => time)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
class Arrival < SectionTime ; end
|
205
|
+
|
206
|
+
class Departure < SectionTime ; end
|
207
|
+
|
208
|
+
|
209
|
+
# Part represents Walks and Lines.
|
210
|
+
class Part
|
211
|
+
|
212
|
+
attr_reader :time, :distance,
|
213
|
+
:sections, :map_locations, :points, :stops
|
214
|
+
|
215
|
+
def initialize(opts)
|
216
|
+
@time = opts[:time].to_f if opts[:time]
|
217
|
+
@distance = opts[:distance].to_f if opts[:time]
|
218
|
+
@sections, @map_locations, @points, @stops = opts[:sections], opts[:map_locations], opts[:points], opts[:stops]
|
219
|
+
end
|
220
|
+
|
221
|
+
def self.parse(xml)
|
222
|
+
length_element = xml.search("LENGTH").first
|
223
|
+
|
224
|
+
time = length_element.get_attr_value "time"
|
225
|
+
distance = length_element.get_attr_value "dist"
|
226
|
+
|
227
|
+
sections, map_locations, points, stops = [], [], [], []
|
228
|
+
|
229
|
+
xml.elements.each do |e|
|
230
|
+
next if e.name == "LENGTH"
|
231
|
+
|
232
|
+
case e.name
|
233
|
+
when "POINT"
|
234
|
+
point = Point.parse(e)
|
235
|
+
sections << point
|
236
|
+
points << point
|
237
|
+
when "MAPLOC"
|
238
|
+
map_location = MapLocation.parse(e)
|
239
|
+
sections << map_location
|
240
|
+
map_locations << map_location
|
241
|
+
when "STOP"
|
242
|
+
stop = Stop.parse(e)
|
243
|
+
sections << stop
|
244
|
+
stops << stop
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
{ :time => time,
|
249
|
+
:distance => distance,
|
250
|
+
:sections => sections,
|
251
|
+
:map_locations => map_locations,
|
252
|
+
:points => points,
|
253
|
+
:stops => stops }
|
254
|
+
end
|
255
|
+
|
256
|
+
end
|
257
|
+
|
258
|
+
class Walk < Part
|
259
|
+
|
260
|
+
def self.parse(xml)
|
261
|
+
opts = super
|
262
|
+
|
263
|
+
new opts
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
class Line < Part
|
268
|
+
attr_reader :line_id, :code, :line_type, :mobility
|
269
|
+
|
270
|
+
def initialize(opts)
|
271
|
+
super
|
272
|
+
|
273
|
+
@line_id = opts[:line_id]
|
274
|
+
@code = opts[:code]
|
275
|
+
@line_type = opts[:line_type].to_i if opts[:line_type]
|
276
|
+
@mobility = opts[:mobility].to_i if opts[:mobility]
|
277
|
+
|
278
|
+
@stops = opts[:stops] || []
|
279
|
+
end
|
280
|
+
|
281
|
+
def self.parse(xml)
|
282
|
+
opts = super
|
283
|
+
|
284
|
+
line_id = xml.get_attr_value "id"
|
285
|
+
code = xml.get_attr_value "code"
|
286
|
+
line_type = xml.get_attr_value "type"
|
287
|
+
mobility = xml.get_attr_value "mobility"
|
288
|
+
|
289
|
+
stops = []
|
290
|
+
|
291
|
+
opts[:sections].each do |section|
|
292
|
+
stops << section if section.is_a? Stop
|
293
|
+
end
|
294
|
+
|
295
|
+
opts.merge!(:line_id => line_id,
|
296
|
+
:code => code,
|
297
|
+
:line_type => line_type,
|
298
|
+
:mobility => mobility,
|
299
|
+
:stops => stops)
|
300
|
+
|
301
|
+
new(opts)
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
|
306
|
+
end
|
307
|
+
|
308
|
+
|
309
|
+
|
310
|
+
end
|