bahn.rb 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -17,6 +17,17 @@ Example
17
17
  )
18
18
  # output the connection info
19
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 } }
20
31
 
21
32
  How to help
22
33
  =
data/lib/bahn.rb CHANGED
@@ -9,5 +9,5 @@ require 'bahn/bahn_station'
9
9
  require 'bahn/bahn_agent'
10
10
 
11
11
  module Bahn
12
- VERSION = "2.0.0"
12
+ VERSION = "2.1.0"
13
13
  end
@@ -44,30 +44,21 @@ module Bahn
44
44
 
45
45
  # Get the next few routes with public transportation from A to B.
46
46
  #
47
- # :start_type and :target_type should be the same, no other options is implemented yet
48
47
  # Options:
49
48
  # * :time => start time for the connection
50
- # * :start_type => :station or :address
51
- # * :target_type => :station or :address
52
49
  # * :include_coords => Include coordiantes for the station. This takes a while especially for longer routes! default: true
53
50
  # Returns:
54
51
  # Array of Bahn::Route(s)
55
52
  # Raises:
56
53
  # "no_route" if no route could be found
57
54
  def get_routes from, to, options = {}
58
- options = {:time => Time.now, :start_type => :address, :target_type => :address, :depth => 0, :include_coords => true, :limit => 2}.merge(options)
59
- options[:time] = options[:time] + 10.minutes # Ansonsten liegt die letzte Verbindung in der Vergangenheit
60
-
55
+ options[:start_type] = check_point_type(from) || options[:start_type]
56
+ options[:target_type] = check_point_type(to) || options[:target_type]
57
+ options = {:time => Time.now, :depth => 0, :include_coords => true, :limit => 2}.merge(options)
58
+ options[:time] = options[:time] + 10.minutes # Ansonsten liegt die letzte Verbindung in der Vergangenheit
61
59
  page = @agent.get @@options[:url_route]
62
- form = page.forms.first
63
- form["REQ0JourneyDate"] = options[:time].strftime "%d.%m.%y"
64
- form["REQ0JourneyTime"] = options[:time].to_formatted_s :time
65
- form["REQ0JourneyStopsS0A"] = TYPES[options[:start_type]]
66
- form["REQ0JourneyStopsZ0A"] = TYPES[options[:target_type]]
67
- form["REQ0JourneyStopsS0G"] = from
68
- form["REQ0JourneyStopsZ0G"] = to
69
- form["REQ0JourneyProduct_prod_list"] = "4:0001111111000000"
70
- result = form.submit(form.button_with(:value => "Suchen"))
60
+
61
+ result = submit_form page.forms.first, from, to, options
71
62
 
72
63
  routes = []
73
64
  links = result.links_with(:href => /details=opened!/)
@@ -78,20 +69,20 @@ module Bahn
78
69
  end
79
70
 
80
71
  # Keine Station gefunden und es werden keine Vorschläge angezeigt...
81
- # also suchen wir nachder nächstbesten Adresse und nutzen dies
72
+ # also suchen wir nach der nächstbesten Adresse/Station und nutzen diese
82
73
  if links.count == 0 && options[:depth] == 0
83
74
  if options[:start_type] == :address
84
- from = find_address(from).name
75
+ from = find_address(from, options).name
85
76
  elsif options[:start_type] == :station
86
- from = find_station(from).name
77
+ from = find_station(from, options).name
87
78
  end
88
79
 
89
80
  if options[:target_type] == :address
90
- to = find_address(to).name
81
+ to = find_address(to, options).name
91
82
  elsif options[:target_type] == :station
92
- to = find_station(to).name
83
+ to = find_station(to, options).name
93
84
  end
94
-
85
+
95
86
  return get_routes from, to, options.merge(:depth => options[:depth]+1)
96
87
  end
97
88
 
@@ -103,22 +94,82 @@ module Bahn
103
94
  # Example:
104
95
  # Input: HH Allee Düsseldorf
105
96
  # Output: Heinrich-Heine-Allee U, Düsseldorf
106
- def find_station name
107
- result = @agent.get("#{@@options[:uri_stations]}#{name}").body.gsub("SLs.sls=", "").gsub(";SLs.showSuggestion();", "")
108
- # a Mechanize::File instead of a Page is returned so we have to convert manually
109
- result = Iconv.conv("utf-8", "iso-8859-1", result)
110
- Station.new(JSON.parse(result)["suggestions"].first)
97
+ def find_station name, options={}
98
+ val = get_address_or_station(name, :station)
99
+ options[:coords] = name.coordinates if name.respond_to?(:coordinates)
100
+ result = @agent.get("#{@@options[:uri_stations]}#{val}").body.gsub("SLs.sls=", "").gsub(";SLs.showSuggestion();", "")
101
+ find_nearest_station result, options
111
102
  end
112
103
 
113
104
  # Finds the first usable address for the given parameter. The returned address can then be used for further processing in routes
114
105
  # Example:
115
106
  # Input: Roßstr. 41 40476 Düsseldorf
116
107
  # Output: Düsseldorf - Golzheim, Rossstraße 41
117
- def find_address address
118
- result = @agent.get("#{@@options[:uri_adresses]}#{address}").body.gsub("SLs.sls=", "").gsub(";SLs.showSuggestion();", "")
108
+ def find_address address, options={}
109
+ val = get_address_or_station(address, :address)
110
+ options[:coords] = address.coordinates if address.respond_to?(:coordinates)
111
+ result = @agent.get("#{@@options[:uri_adresses]}#{val}").body.gsub("SLs.sls=", "").gsub(";SLs.showSuggestion();", "")
112
+ find_nearest_station result, options
113
+ end
114
+
115
+ ############################################################################################
116
+ private
117
+ ############################################################################################
118
+
119
+ def find_nearest_station result, options={}
119
120
  # a Mechanize::File instead of a Page is returned so we have to convert manually
120
- result = Iconv.conv("utf-8", "iso-8859-1", result)
121
- Station.new(JSON.parse(result)["suggestions"].first)
121
+ result = encode result
122
+ result = JSON.parse(result)["suggestions"]
123
+
124
+ if options[:coords].nil?
125
+ s = Station.new(result.first)
126
+ else
127
+ result.map!{|r| Station.new(r)}
128
+ result.each {|s| s.distance = Geocoder::Calculations.distance_between(options[:coords], s)}
129
+ result.sort! {|a,b| a.distance <=> b.distance}
130
+ s = result.first
131
+ end
132
+
133
+ s
134
+ end
135
+
136
+ def encode str
137
+ if str.respond_to? :encode
138
+ str.force_encoding("iso-8859-1").encode("utf-8")
139
+ else
140
+ Iconv.conv("utf-8", "iso-8859-1", str)
141
+ end
142
+ end
143
+
144
+ def check_point_type geocoder_result
145
+ return nil unless geocoder_result.is_a? Geocoder::Result::Base
146
+ return :address unless geocoder_result.address_components.index{|a| a["types"].include?("route")}.nil?
147
+ return :station if geocoder_result.address_components.index{|a| a["types"].include?("train_station") || a["types"].include?("transit_station")}.nil?
148
+ return :station
149
+ end
150
+
151
+ def get_address_or_station geocoder_result, type
152
+ return geocoder_result.to_s unless geocoder_result.is_a? Geocoder::Result::Base
153
+ addy = geocoder_result.address
154
+ if type == :station
155
+ begin
156
+ addy = geocoder_result.address_components.find{|a| a["types"].include? "transit_station"}["short_name"]
157
+ addy += " #{geocoder_result.city}" unless addy.include?(geocoder_result.city)
158
+ rescue StandardError
159
+ end
160
+ end
161
+ addy
162
+ end
163
+
164
+ def submit_form form, from, to, options
165
+ form["REQ0JourneyDate"] = options[:time].strftime "%d.%m.%y"
166
+ form["REQ0JourneyTime"] = options[:time].to_formatted_s :time
167
+ form["REQ0JourneyStopsS0A"] = TYPES[options[:start_type]]
168
+ form["REQ0JourneyStopsZ0A"] = TYPES[options[:target_type]]
169
+ form["REQ0JourneyStopsS0G"] = get_address_or_station(from, options[:start_type])
170
+ form["REQ0JourneyStopsZ0G"] = get_address_or_station(to, options[:target_type])
171
+ form["REQ0JourneyProduct_prod_list"] = "4:0001111111000000"
172
+ form.submit(form.button_with(:value => "Suchen"))
122
173
  end
123
174
  end
124
175
  end
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Bahn
2
4
  # The whole Route from A to B.
3
5
  # This is created from the m.bahn.de detail view page and parses the given data.
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Bahn
2
4
  # Route Parts show a small step of the route from A to B with one specific type of transportation
3
5
  # Example: "Am 2013-02-01 von 17:33 bis 17:47 : Heerdter Sandberg U, Düsseldorf nach Düsseldorf Hauptbahnhof via U 7"
@@ -1,6 +1,7 @@
1
1
  module Bahn
2
2
  class Station
3
- attr_accessor :lat, :lon, :name
3
+ attr_accessor :lat, :lon, :distance, :name
4
+
4
5
  def initialize json={}
5
6
  self.name = json["value"] unless json["value"].nil?
6
7
 
@@ -22,6 +23,11 @@ module Bahn
22
23
  "#{self.name} (#{self.lat},#{self.lon})"
23
24
  end
24
25
 
26
+ def to_coordinates
27
+ [lat, lon]
28
+ end
29
+ alias_method :coordinates, :to_coordinates
30
+
25
31
  def == other
26
32
  return false if other.nil?
27
33
  other.name == self.name
metadata CHANGED
@@ -1,88 +1,66 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: bahn.rb
3
- version: !ruby/object:Gem::Version
4
- hash: 15
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.1.0
5
5
  prerelease:
6
- segments:
7
- - 2
8
- - 0
9
- - 0
10
- version: 2.0.0
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Simon Woker
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2013-02-20 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
21
- version_requirements: &id001 !ruby/object:Gem::Requirement
12
+ date: 2013-03-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: json
16
+ requirement: &12393320 !ruby/object:Gem::Requirement
22
17
  none: false
23
- requirements:
18
+ requirements:
24
19
  - - ~>
25
- - !ruby/object:Gem::Version
26
- hash: 3
27
- segments:
28
- - 1
29
- - 6
30
- version: "1.6"
31
- requirement: *id001
32
- prerelease: false
20
+ - !ruby/object:Gem::Version
21
+ version: '1.6'
33
22
  type: :runtime
34
- name: json
35
- - !ruby/object:Gem::Dependency
36
- version_requirements: &id002 !ruby/object:Gem::Requirement
37
- none: false
38
- requirements:
39
- - - ">="
40
- - !ruby/object:Gem::Version
41
- hash: 3
42
- segments:
43
- - 0
44
- version: "0"
45
- requirement: *id002
46
23
  prerelease: false
47
- type: :runtime
24
+ version_requirements: *12393320
25
+ - !ruby/object:Gem::Dependency
48
26
  name: mechanize
49
- - !ruby/object:Gem::Dependency
50
- version_requirements: &id003 !ruby/object:Gem::Requirement
27
+ requirement: &12392820 !ruby/object:Gem::Requirement
51
28
  none: false
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- hash: 3
56
- segments:
57
- - 0
58
- version: "0"
59
- requirement: *id003
60
- prerelease: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
61
33
  type: :runtime
34
+ prerelease: false
35
+ version_requirements: *12392820
36
+ - !ruby/object:Gem::Dependency
62
37
  name: activesupport
63
- - !ruby/object:Gem::Dependency
64
- version_requirements: &id004 !ruby/object:Gem::Requirement
38
+ requirement: &12392000 !ruby/object:Gem::Requirement
65
39
  none: false
66
- requirements:
67
- - - ">="
68
- - !ruby/object:Gem::Version
69
- hash: 3
70
- segments:
71
- - 0
72
- version: "0"
73
- requirement: *id004
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
74
45
  prerelease: false
75
- type: :development
46
+ version_requirements: *12392000
47
+ - !ruby/object:Gem::Dependency
76
48
  name: rake
49
+ requirement: &12390680 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *12390680
77
58
  description: Load connections for public transportation from the m.bahn.de website.
78
59
  email: github@simonwoker.de
79
60
  executables: []
80
-
81
61
  extensions: []
82
-
83
62
  extra_rdoc_files: []
84
-
85
- files:
63
+ files:
86
64
  - lib/bahn/bahn_agent.rb
87
65
  - lib/bahn/bahn_route.rb
88
66
  - lib/bahn/bahn_routepart.rb
@@ -92,38 +70,29 @@ files:
92
70
  - README.md
93
71
  homepage: https://github.com/swoker/bahn.rb
94
72
  licenses: []
95
-
96
73
  post_install_message:
97
74
  rdoc_options: []
98
-
99
- require_paths:
75
+ require_paths:
100
76
  - lib
101
- required_ruby_version: !ruby/object:Gem::Requirement
77
+ required_ruby_version: !ruby/object:Gem::Requirement
102
78
  none: false
103
- requirements:
104
- - - ">="
105
- - !ruby/object:Gem::Version
106
- hash: 3
107
- segments:
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ segments:
108
84
  - 0
109
- version: "0"
110
- required_rubygems_version: !ruby/object:Gem::Requirement
85
+ hash: 3470599687635693811
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
87
  none: false
112
- requirements:
113
- - - ">="
114
- - !ruby/object:Gem::Version
115
- hash: 23
116
- segments:
117
- - 1
118
- - 3
119
- - 6
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
120
91
  version: 1.3.6
121
92
  requirements: []
122
-
123
93
  rubyforge_project:
124
- rubygems_version: 1.8.25
94
+ rubygems_version: 1.8.11
125
95
  signing_key:
126
96
  specification_version: 3
127
- summary: "Bahn \xC3\x96PNV information"
97
+ summary: Bahn ÖPNV information
128
98
  test_files: []
129
-