bahn.rb 2.0.0 → 2.1.0

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/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
-