bahn.rb 2.1.1 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +7 -7
- data/README.md +34 -34
- data/changelog.md +10 -0
- data/lib/bahn.rb +11 -11
- data/lib/bahn/bahn_agent.rb +271 -177
- data/lib/bahn/bahn_route.rb +208 -145
- data/lib/bahn/bahn_routepart.rb +55 -34
- data/lib/bahn/bahn_station.rb +50 -36
- data/lib/bahn/version.rb +3 -3
- metadata +49 -27
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8a42380d0b034d7aea7c91a276b6fbe34f342c5e
|
4
|
+
data.tar.gz: 097e4635b917d27595f865b883c9cfa45c418296
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0b90aa919d174c77041d5b60a754cddc9ac9a832e375412a02afe258d31c13768ef83350b1bc00289c32f456cf7cbe2e230421f46634ac8a63dd6b593e73ad8c
|
7
|
+
data.tar.gz: dfdc478a203847ba81dd56075ffc33f9ccab49ab3992de120d347613d6b6624e40140c0fed44582cd08dbb85450bc045d2f5957428efe68af3f60652d67ea9bf
|
data/LICENSE
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
Copyright (c) 2012 Simon Woker
|
2
|
-
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
-
|
5
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
-
|
7
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
1
|
+
Copyright (c) 2012 Simon Woker
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,35 +1,35 @@
|
|
1
|
-
Load connections for public transportation from the m.bahn.de website.
|
2
|
-
|
3
|
-
This is under heavy development. Don't expect a working solution!
|
4
|
-
|
5
|
-
Example
|
6
|
-
=
|
7
|
-
require 'bahn.rb'
|
8
|
-
|
9
|
-
agent = Bahn::Agent.new
|
10
|
-
routes = agent.get_routes(
|
11
|
-
"Düsseldorf reisholz s bahn", # start address or station
|
12
|
-
"Düsseldorf, Heerdter Sandberg 40 ", # target address or station
|
13
|
-
:include_coords => true, # include coordinates of stations
|
14
|
-
:limit => 1, # how many connections?
|
15
|
-
:start_type => :station, # :station or :address
|
16
|
-
:target_type => :address # :station or :address
|
17
|
-
)
|
18
|
-
# output the connection info
|
19
|
-
routes.each {|route| route.parts.each {|part| puts part } }
|
20
|
-
|
21
|
-
# or with Geocoder
|
22
|
-
routes = agent.get_routes(
|
23
|
-
Geocoder.search("Düsseldorf reisholz s bahn").first, # start address or station
|
24
|
-
Geocoder.search("Düsseldorf, Heerdter Sandberg 40").first, # target address or station
|
25
|
-
:include_coords => true, # include coordinates of stations
|
26
|
-
:limit => 1 # how many connections?
|
27
|
-
# you don't need start- and target-type with geocoder :)
|
28
|
-
)
|
29
|
-
# output the connection info
|
30
|
-
routes.each {|route| route.parts.each {|part| puts part } }
|
31
|
-
|
32
|
-
How to help
|
33
|
-
=
|
34
|
-
Feel free to implement some additions, refactor and create a pull request!
|
1
|
+
Load connections for public transportation from the m.bahn.de website.
|
2
|
+
|
3
|
+
This is under heavy development. Don't expect a working solution!
|
4
|
+
|
5
|
+
Example
|
6
|
+
=
|
7
|
+
require 'bahn.rb'
|
8
|
+
|
9
|
+
agent = Bahn::Agent.new
|
10
|
+
routes = agent.get_routes(
|
11
|
+
"Düsseldorf reisholz s bahn", # start address or station
|
12
|
+
"Düsseldorf, Heerdter Sandberg 40 ", # target address or station
|
13
|
+
:include_coords => true, # include coordinates of stations
|
14
|
+
:limit => 1, # how many connections?
|
15
|
+
:start_type => :station, # :station or :address
|
16
|
+
:target_type => :address # :station or :address
|
17
|
+
)
|
18
|
+
# output the connection info
|
19
|
+
routes.each {|route| route.parts.each {|part| puts part } }
|
20
|
+
|
21
|
+
# or with Geocoder
|
22
|
+
routes = agent.get_routes(
|
23
|
+
Geocoder.search("Düsseldorf reisholz s bahn").first, # start address or station
|
24
|
+
Geocoder.search("Düsseldorf, Heerdter Sandberg 40").first, # target address or station
|
25
|
+
:include_coords => true, # include coordinates of stations
|
26
|
+
:limit => 1 # how many connections?
|
27
|
+
# you don't need start- and target-type with geocoder :)
|
28
|
+
)
|
29
|
+
# output the connection info
|
30
|
+
routes.each {|route| route.parts.each {|part| puts part } }
|
31
|
+
|
32
|
+
How to help
|
33
|
+
=
|
34
|
+
Feel free to implement some additions, refactor and create a pull request!
|
35
35
|
... and create tests of course ;)
|
data/changelog.md
ADDED
data/lib/bahn.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'mechanize'
|
3
|
-
require 'active_support/all'
|
4
|
-
require 'json'
|
5
|
-
require 'geocoder'
|
6
|
-
|
7
|
-
require 'bahn/bahn_routepart'
|
8
|
-
require 'bahn/bahn_route'
|
9
|
-
require 'bahn/bahn_station'
|
10
|
-
require 'bahn/bahn_agent'
|
11
|
-
require 'bahn/version'
|
1
|
+
require 'rubygems'
|
2
|
+
require 'mechanize'
|
3
|
+
require 'active_support/all'
|
4
|
+
require 'json'
|
5
|
+
require 'geocoder'
|
6
|
+
|
7
|
+
require 'bahn/bahn_routepart'
|
8
|
+
require 'bahn/bahn_route'
|
9
|
+
require 'bahn/bahn_station'
|
10
|
+
require 'bahn/bahn_agent'
|
11
|
+
require 'bahn/version'
|
data/lib/bahn/bahn_agent.rb
CHANGED
@@ -1,177 +1,271 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Bahn
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Bahn
|
4
|
+
# Agent class that searches stations, street addresses and public transportation routes for germany
|
5
|
+
# Example:
|
6
|
+
# agent = Agent.new
|
7
|
+
# routes = agent.get_routes "Düsseldorf Heerdter Sandberg 25", "Düsseldorf Am Dreieck 1"
|
8
|
+
# routes.each {|route| route.parts.each {|part| puts part } }
|
9
|
+
#
|
10
|
+
# You can go even use far distances...
|
11
|
+
# routes = agent.get_routes "Heerdter Sandberg 35 Düsseldorf, Düsseldorf", "Berlin Hauptstraße 10"
|
12
|
+
# routes.each {|route| route.parts.each {|part| puts part } }
|
13
|
+
# => Am 2013-02-01 von 17:32 bis 17:33 : Düsseldorf - Oberkassel, Heerdter Sandberg 60 nach Heerdter Sandberg U, Düsseldorf via Fußweg
|
14
|
+
# => Am 2013-02-01 von 17:33 bis 17:47 : Heerdter Sandberg U, Düsseldorf nach Düsseldorf Hauptbahnhof via U 7
|
15
|
+
# => Am 2013-02-01 von 17:47 bis 17:53 : Düsseldorf Hauptbahnhof nach Düsseldorf Hbf via Fußweg
|
16
|
+
# => Am 2013-02-01 von 17:53 bis 22:22 : Düsseldorf Hbf nach Berlin Hbf via ICE 945
|
17
|
+
# => Am 2013-02-01 von 22:34 bis 22:40 : Berlin Hbf nach Berlin Alexanderplatz via RE 37386
|
18
|
+
# => Am 2013-02-01 von 22:40 bis 22:46 : Berlin Alexanderplatz nach Alexanderplatz (U), Berlin via Fußweg
|
19
|
+
# => Am 2013-02-01 von 22:46 bis 23:07 : Alexanderplatz (U), Berlin nach Oberseestr., Berlin via STR M5
|
20
|
+
# => Am 2013-02-01 von 23:07 bis 23:15 : Oberseestr., Berlin nach Berlin - Alt-Hohenschönhausen, Hauptstraße 10 via Fußweg
|
21
|
+
class Agent
|
22
|
+
@@options = {
|
23
|
+
:url_route => 'http://mobile.bahn.de/bin/mobil/query.exe/dox?country=DEU&rt=1&use_realtime_filter=1&searchMode=ADVANCED',
|
24
|
+
:uri_adresses => 'http://reiseauskunft.bahn.de/bin/ajax-getstop.exe/en?REQ0JourneyStopsS0A=2&REQ0JourneyStopsS0G=',
|
25
|
+
:uri_stations => 'http://reiseauskunft.bahn.de/bin/ajax-getstop.exe/en?REQ0JourneyStopsS0A=1&REQ0JourneyStopsS0G=',
|
26
|
+
:uri_stations_near => 'http://mobile.bahn.de/bin/mobil/query.exe/dox?ld=9627&n=1&rt=1&use_realtime_filter=1&performLocating=2&tpl=stopsnear&look_maxdist=1000&look_stopclass=1023&look_y=%i&look_x=%i'
|
27
|
+
}
|
28
|
+
|
29
|
+
# Set the used user agent
|
30
|
+
def self.user_agent=val
|
31
|
+
@@user_agent = val
|
32
|
+
end
|
33
|
+
|
34
|
+
TYPES =
|
35
|
+
{
|
36
|
+
:station => 1,
|
37
|
+
:address => 2
|
38
|
+
}.freeze
|
39
|
+
|
40
|
+
TIME_RELATION =
|
41
|
+
{
|
42
|
+
:arrival => 0,
|
43
|
+
:depature => 1
|
44
|
+
}.freeze
|
45
|
+
|
46
|
+
JOURNEY_PRODUCT_PRESETS = {
|
47
|
+
:alle => "1:1111111111000000",
|
48
|
+
:alle_ohne_ice => "2:0111111111000000",
|
49
|
+
:nur_nahverkehr => "4:0001111111000000",
|
50
|
+
}.freeze
|
51
|
+
|
52
|
+
# Initialize a new Agent
|
53
|
+
# options:
|
54
|
+
# :user_agent => Set the user agent. Default: "bahn.rb"
|
55
|
+
def initialize
|
56
|
+
@agent = Mechanize.new
|
57
|
+
@agent.set_defaults if @agent.respond_to?(:set_defaults)
|
58
|
+
@agent.user_agent = @@user_agent ||= "bahn.rb"
|
59
|
+
end
|
60
|
+
|
61
|
+
# Get the next few routes with public transportation from A to B.
|
62
|
+
#
|
63
|
+
# Options:
|
64
|
+
# * :time => start time for the connection
|
65
|
+
# * :include_coords => Include coordiantes for the station. This takes a while especially for longer routes! default: true
|
66
|
+
# Returns:
|
67
|
+
# Array of Bahn::Route(s)
|
68
|
+
# Raises:
|
69
|
+
# "no_route" if no route could be found
|
70
|
+
def get_routes from, to, options = {}
|
71
|
+
options[:start_type] = check_point_type(from) || options[:start_type]
|
72
|
+
options[:target_type] = check_point_type(to) || options[:target_type]
|
73
|
+
# default options
|
74
|
+
options = {
|
75
|
+
:time => Time.now,
|
76
|
+
:depth => 0,
|
77
|
+
:include_coords => true,
|
78
|
+
:limit => 2,
|
79
|
+
:time_relation => :depature }.merge(options)
|
80
|
+
|
81
|
+
options[:time] = options[:time].in_time_zone("Berlin") #+ 10.minutes # Ansonsten liegt die erste Verbindung in der Vergangenheit
|
82
|
+
page = @agent.get @@options[:url_route]
|
83
|
+
|
84
|
+
result = submit_form page.forms.first, from, to, options
|
85
|
+
|
86
|
+
routes = []
|
87
|
+
links = result.links_with(:href => /details=opened!/).select { |l| l.to_s.size > 0} # only select connection links, no warning links
|
88
|
+
links.each do |link|
|
89
|
+
page = link.click
|
90
|
+
routes << Route.new(page, options)
|
91
|
+
break if routes.count == options[:limit]
|
92
|
+
end
|
93
|
+
|
94
|
+
# Keine Station gefunden also suchen wir nach der nächstbesten Adresse/Station
|
95
|
+
if links.count == 0 && options[:depth] == 0
|
96
|
+
if options[:start_type] == :address
|
97
|
+
from = find_address(from, options)
|
98
|
+
options[:start_type] = from.station_type
|
99
|
+
from = from.name
|
100
|
+
elsif options[:start_type] == :station
|
101
|
+
from = find_station(from, options)
|
102
|
+
options[:start_type] = from.station_type
|
103
|
+
from = from.name
|
104
|
+
end
|
105
|
+
|
106
|
+
if options[:target_type] == :address
|
107
|
+
to = find_address(to, options)
|
108
|
+
options[:target_type] = to.station_type
|
109
|
+
to = to.name
|
110
|
+
elsif options[:target_type] == :station
|
111
|
+
to = find_station(to, options)
|
112
|
+
options[:target_type] = to.station_type
|
113
|
+
to = to.name
|
114
|
+
end
|
115
|
+
|
116
|
+
return get_routes from, to, options.merge(:depth => options[:depth]+1)
|
117
|
+
end
|
118
|
+
|
119
|
+
raise "no_route" if routes.count == 0 || links.count == 0
|
120
|
+
routes
|
121
|
+
end
|
122
|
+
|
123
|
+
# Find the first best station by name
|
124
|
+
# Example:
|
125
|
+
# Input: HH Allee Düsseldorf
|
126
|
+
# Output: Heinrich-Heine-Allee U, Düsseldorf
|
127
|
+
def find_station name, options={}
|
128
|
+
val = get_address_or_station(name, :station)
|
129
|
+
options[:coords] = name.respond_to?(:coordinates) ? name.coordinates : nil
|
130
|
+
result = @agent.get("#{@@options[:uri_stations]}#{val}").body.gsub("SLs.sls=", "").gsub(";SLs.showSuggestion();", "")
|
131
|
+
options[:current_station_type] = :station
|
132
|
+
options[:searched_name] = name
|
133
|
+
find_nearest_station result, options
|
134
|
+
end
|
135
|
+
|
136
|
+
# Finds the first usable address for the given parameter. The returned address can then be used for further processing in routes
|
137
|
+
# Example:
|
138
|
+
# Input: Roßstr. 41 40476 Düsseldorf
|
139
|
+
# Output: Düsseldorf - Golzheim, Rossstraße 41
|
140
|
+
def find_address address, options={}
|
141
|
+
val = get_address_or_station(address, :address)
|
142
|
+
options[:coords] = address.respond_to?(:coordinates) ? address.coordinates : nil
|
143
|
+
result = @agent.get("#{@@options[:uri_adresses]}#{val}").body.gsub("SLs.sls=", "").gsub(";SLs.showSuggestion();", "")
|
144
|
+
options[:current_station_type] = :address
|
145
|
+
find_nearest_station result, options
|
146
|
+
end
|
147
|
+
|
148
|
+
def find_station_at lat, lon, options={}
|
149
|
+
uri = @@options[:uri_stations_near] % [(lat * 1000000), (lon * 1000000)]
|
150
|
+
result = @agent.get(uri)
|
151
|
+
stations = result.links.select{|l| l.href.include?("HWAI=STATION!")}.map do |link|
|
152
|
+
s = Station.new({:do_load => false})
|
153
|
+
s.name = link.text
|
154
|
+
lat_match = link.href.match(/Y=(\d{7,})/)
|
155
|
+
s.lat = lat_match[1].insert(-7, ".") unless lat_match.nil?
|
156
|
+
lon_match = link.href.match(/X=(\d{7,})/)
|
157
|
+
s.lon = lon_match[1].insert(-7, ".") unless lon_match.nil?
|
158
|
+
# not needed but hey, since we got it ;)
|
159
|
+
dist_match = link.href.match(/dist=(\d+)!/)
|
160
|
+
s.distance = (dist_match[1].to_i / 1000) unless dist_match.nil? # meter to km
|
161
|
+
s.station_type = :station
|
162
|
+
s
|
163
|
+
end
|
164
|
+
|
165
|
+
# prefer HBF or Hauptbahnhof if there is one nearby
|
166
|
+
station = stations.select{|s| s.name.include?("Hauptbahnhof") || s.name.include?("HBF")}.first
|
167
|
+
return (station.nil? ? stations.first : station)
|
168
|
+
end
|
169
|
+
|
170
|
+
############################################################################################
|
171
|
+
private
|
172
|
+
############################################################################################
|
173
|
+
|
174
|
+
def find_nearest_station result, options={}
|
175
|
+
# a Mechanize::File instead of a Page is returned so we have to convert manually
|
176
|
+
result = encode result
|
177
|
+
result = JSON.parse(result)["suggestions"]
|
178
|
+
|
179
|
+
stations = result.map{|r| (Station.new(r) rescue StandardError) }.compact
|
180
|
+
stations = stations.delete_if{|s| s.instance_of?(StandardError)}
|
181
|
+
station = options[:searched_name].to_s.length > 0 ? stations.select{|s| s.name == options[:searched_name]}.first : nil
|
182
|
+
if options[:coords].nil?
|
183
|
+
station = stations.first if station.nil?
|
184
|
+
station.station_type = options[:current_station_type]
|
185
|
+
elsif station.nil? # 100% match not found, so look for the next best match
|
186
|
+
stations.each {|s| s.distance = Geocoder::Calculations.distance_between(options[:coords], s, :units => :km)}
|
187
|
+
stations.sort! {|a,b| a.distance <=> b.distance}
|
188
|
+
station = stations.first
|
189
|
+
station.station_type = options[:current_station_type]
|
190
|
+
|
191
|
+
# more than 1 km? This seems to be wrong...
|
192
|
+
if station.distance > 1
|
193
|
+
nearest_station = find_station_at options[:coords][0], options[:coords][1]
|
194
|
+
station = nearest_station if nearest_station
|
195
|
+
end
|
196
|
+
end
|
197
|
+
station
|
198
|
+
end
|
199
|
+
|
200
|
+
def encode str
|
201
|
+
if str.respond_to? :encode
|
202
|
+
str.force_encoding("iso-8859-1").encode("utf-8")
|
203
|
+
else
|
204
|
+
Iconv.conv("utf-8", "iso-8859-1", str)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def encode_to_iso str
|
209
|
+
if str.respond_to? :encode
|
210
|
+
str.encode("iso-8859-1")
|
211
|
+
else
|
212
|
+
Iconv.conv("iso-8859-1", "utf-8", str)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def check_point_type geocoder_result
|
217
|
+
return nil unless geocoder_result.respond_to?(:types)
|
218
|
+
return :station if geocoder_result.types.include?("transit_station") # subway, bus, ...
|
219
|
+
|
220
|
+
return :address if geocoder_result.types.include?("street_address") # full address
|
221
|
+
return :address if geocoder_result.types.include?("route") # street name only
|
222
|
+
return :address if geocoder_result.types.include?("postal_code") # plz only
|
223
|
+
|
224
|
+
# city without transit station => use address + HBF
|
225
|
+
if geocoder_result.types.include?("locality") && geocoder_result.transit_station.to_s.length == 0
|
226
|
+
geocoder_result.transit_station = geocoder_result.address.gsub(", Deutschland", "").gsub(", Germany", "")
|
227
|
+
geocoder_result.transit_station << " HBF"
|
228
|
+
return :station
|
229
|
+
end
|
230
|
+
|
231
|
+
# (sub-)locality or political or anything else => treat as station (most likely main station)
|
232
|
+
return :station
|
233
|
+
end
|
234
|
+
|
235
|
+
def get_address_or_station geocoder_result, type
|
236
|
+
return geocoder_result.to_s unless geocoder_result.respond_to?(:address)
|
237
|
+
addy = ""
|
238
|
+
|
239
|
+
if type == :station
|
240
|
+
addy = geocoder_result.transit_station if geocoder_result.respond_to?(:transit_station)
|
241
|
+
|
242
|
+
if geocoder_result.respond_to?(:address_components_of_type)
|
243
|
+
begin
|
244
|
+
addy = geocoder_result.address_components_of_type("transit_station").first["short_name"]
|
245
|
+
addy += " #{geocoder_result.city}" unless addy.include?(geocoder_result.city)
|
246
|
+
rescue StandardError
|
247
|
+
# use address instead
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
if addy.to_s.empty?
|
253
|
+
addy = geocoder_result.address
|
254
|
+
end
|
255
|
+
|
256
|
+
addy
|
257
|
+
end
|
258
|
+
|
259
|
+
def submit_form form, from, to, options
|
260
|
+
form["REQ0JourneyDate"] = options[:time].strftime "%d.%m.%y"
|
261
|
+
form["REQ0JourneyTime"] = options[:time].to_formatted_s :time
|
262
|
+
form["REQ0JourneyStopsS0A"] = TYPES[options[:start_type]]
|
263
|
+
form["REQ0JourneyStopsZ0A"] = TYPES[options[:target_type]]
|
264
|
+
form["REQ0JourneyStopsS0G"] = encode_to_iso(get_address_or_station(from, options[:start_type]))
|
265
|
+
form["REQ0JourneyStopsZ0G"] = encode_to_iso(get_address_or_station(to, options[:target_type]))
|
266
|
+
form["REQ0HafasSearchForw"] = TIME_RELATION[options[:time_relation]] # 0 -> Abfahrt, 1 -> Ankunft
|
267
|
+
form["REQ0JourneyProduct_prod_list"] = JOURNEY_PRODUCT_PRESETS[options[:journey_product]]
|
268
|
+
form.submit(form.button_with(:value => "Suchen"))
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|