osrm 0.0.0 → 0.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.
- checksums.yaml +4 -4
- data/README.md +16 -0
- data/lib/osrm.rb +22 -0
- data/lib/osrm/configuration.rb +65 -0
- data/lib/osrm/query.rb +133 -0
- data/lib/osrm/route.rb +30 -0
- data/lib/osrm/version.rb +1 -1
- metadata +34 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 99fe81d0e8e9ed18d963a3416b26b481e603a17e
|
|
4
|
+
data.tar.gz: 5cae22daace097f00fdb33e97de4000b0cb64700
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fa42df2a83ced80bb0fd164a8963e88637ab858eeb238fca61921e01a5c1b984efe44e1b1485cfb32cdf89caa16e72209e7cc9ef69a1b9cd8656806178ab093a
|
|
7
|
+
data.tar.gz: 40959aa1aed650b0dee8c7e6c65bf28889dcc9efdce0f8ed27034144265986b0a4d5ded79b19c554a4eb2277de3c11cb3e7e610398183ace7633c082f05cbe1b
|
data/README.md
CHANGED
|
@@ -9,6 +9,22 @@ You can [run your own server](https://github.com/Project-OSRM/osrm-backend/wiki)
|
|
|
9
9
|
|
|
10
10
|
gem install osrm
|
|
11
11
|
|
|
12
|
+
2. Configure
|
|
13
|
+
|
|
14
|
+
require 'osrm'
|
|
15
|
+
OSRM.configure(
|
|
16
|
+
server: 'example.com',
|
|
17
|
+
port: 8080, # Default: 80 or 443 if SSL
|
|
18
|
+
use_ssl: true, # Default: false
|
|
19
|
+
timeout: 10, # Default: 3
|
|
20
|
+
user_agent: 'MyScript/1.1' # Default: OSRMRubyGem/{version}
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
3. Request
|
|
24
|
+
|
|
25
|
+
OSRM.routes('50.202712,8.582738', '50.20232,8.574447')
|
|
26
|
+
OSRM.route('50.202712,8.582738', '50.20232,8.574447')
|
|
27
|
+
|
|
12
28
|
## License
|
|
13
29
|
|
|
14
30
|
OSRM Gem is released under [GNU GPLv3](https://www.gnu.org/licenses/gpl-3.0.html).
|
data/lib/osrm.rb
CHANGED
|
@@ -1 +1,23 @@
|
|
|
1
|
+
require 'osrm/configuration'
|
|
2
|
+
require 'osrm/query'
|
|
3
|
+
require 'osrm/route'
|
|
1
4
|
require 'osrm/version'
|
|
5
|
+
|
|
6
|
+
module OSRM
|
|
7
|
+
def self.configure(options)
|
|
8
|
+
Configuration.instance.merge!(options)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.configuration
|
|
12
|
+
Configuration.instance
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.routes(*locations)
|
|
16
|
+
OSRM::Query.new(*locations).execute
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.route(*locations)
|
|
20
|
+
# OPTIMIZE: Send a different request with alt=false
|
|
21
|
+
routes(*locations).first
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'singleton'
|
|
2
|
+
require 'osrm/version'
|
|
3
|
+
|
|
4
|
+
module OSRM
|
|
5
|
+
class Configuration
|
|
6
|
+
include Singleton
|
|
7
|
+
|
|
8
|
+
DEFAULTS = {
|
|
9
|
+
server: nil,
|
|
10
|
+
port: nil,
|
|
11
|
+
use_ssl: false,
|
|
12
|
+
timeout: 3,
|
|
13
|
+
user_agent: "OSRMRubyGem/#{OSRM::VERSION}"
|
|
14
|
+
}.freeze
|
|
15
|
+
|
|
16
|
+
DEMO_SERVER = 'router.project-osrm.org'.freeze
|
|
17
|
+
|
|
18
|
+
def initialize
|
|
19
|
+
@data = DEFAULTS.dup
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def merge!(options)
|
|
23
|
+
options.each do |option, value|
|
|
24
|
+
public_send(:"#{option}=", value) if DEFAULTS.key?(option.to_sym)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
self
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def server=(server)
|
|
31
|
+
@data[:server] =
|
|
32
|
+
server == :demo ? Configuration::DEMO_SERVER.dup : server
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def port=(port)
|
|
36
|
+
@data[:port] = port && port.to_i
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def use_ssl=(use_ssl)
|
|
40
|
+
@data[:use_ssl] = use_ssl ? true : false
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def timeout=(timeout)
|
|
44
|
+
@data[:timeout] = timeout && timeout.to_i
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def use_demo_server?
|
|
48
|
+
@data[:server] == DEMO_SERVER
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Dynamically add missing accessors
|
|
52
|
+
DEFAULTS.each do |option, default_value|
|
|
53
|
+
reader = case default_value
|
|
54
|
+
when TrueClass, FalseClass then :"#{option}?"
|
|
55
|
+
else option
|
|
56
|
+
end
|
|
57
|
+
writer = :"#{option}="
|
|
58
|
+
|
|
59
|
+
define_method(reader) { @data[option] }
|
|
60
|
+
unless method_defined?(writer)
|
|
61
|
+
define_method(writer) { |value| @data[option] = value }
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
data/lib/osrm/query.rb
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'net/http'
|
|
3
|
+
require 'timeout'
|
|
4
|
+
require 'uri'
|
|
5
|
+
|
|
6
|
+
module OSRM
|
|
7
|
+
class Query
|
|
8
|
+
attr_accessor :locations
|
|
9
|
+
|
|
10
|
+
def initialize(*locations)
|
|
11
|
+
@locations = locations.compact.reject(&:empty?)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# OPTIMIZE: Don't execute if 0 or 1 location(s)
|
|
15
|
+
def execute
|
|
16
|
+
json = fetch_json_data
|
|
17
|
+
routes = []
|
|
18
|
+
return routes if json.nil?
|
|
19
|
+
|
|
20
|
+
# Main route
|
|
21
|
+
routes << Route.new(
|
|
22
|
+
geometry: json['route_geometry'],
|
|
23
|
+
summary: json['route_summary']
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
# Alternative routes
|
|
27
|
+
if json['found_alternative']
|
|
28
|
+
json['alternative_geometries'].each_index do |index|
|
|
29
|
+
routes << Route.new(
|
|
30
|
+
geometry: json['alternative_geometries'][index],
|
|
31
|
+
summary: json['alternative_summaries'][index]
|
|
32
|
+
)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
routes
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def fetch_json_data
|
|
42
|
+
raw_data = fetch_raw_data
|
|
43
|
+
JSON.parse(raw_data) if raw_data
|
|
44
|
+
rescue JSON::ParserError
|
|
45
|
+
warn 'OSRM API error: Invalid JSON'
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def fetch_raw_data
|
|
49
|
+
response = api_request
|
|
50
|
+
response.body if valid_response?(response)
|
|
51
|
+
rescue SocketError
|
|
52
|
+
warn 'OSRM API error: Unable to establish connection'
|
|
53
|
+
rescue SystemCallError => err
|
|
54
|
+
# NOTE: Identify error class by string in case the class
|
|
55
|
+
# is not implemented on the current platform
|
|
56
|
+
case err.class.to_s
|
|
57
|
+
when 'Errno::EHOSTDOWN'
|
|
58
|
+
warn 'OSRM API error: Host is down'
|
|
59
|
+
when 'Errno::ECONNREFUSED'
|
|
60
|
+
warn 'OSRM API error: Connection refused'
|
|
61
|
+
else
|
|
62
|
+
raise
|
|
63
|
+
end
|
|
64
|
+
rescue TimeoutError
|
|
65
|
+
warn 'OSRM API error: Timeout expired'
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# TODO: Be sure that the HTTP query is ALWAYS closed
|
|
69
|
+
# properly, even if an error happen (timeout or whatever)
|
|
70
|
+
def api_request
|
|
71
|
+
build_uri
|
|
72
|
+
timeout(configuration.timeout) do
|
|
73
|
+
Net::HTTP.start(uri.host, uri.port,
|
|
74
|
+
use_ssl: configuration.use_ssl?) do |http|
|
|
75
|
+
response = http.get(
|
|
76
|
+
uri.request_uri,
|
|
77
|
+
'User-Agent' => configuration.user_agent
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
if response.class.body_permitted?
|
|
81
|
+
charset = response.type_params['charset']
|
|
82
|
+
response.body.force_encoding(charset) if charset
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
response
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def valid_response?(response)
|
|
91
|
+
return true if response.is_a?(Net::HTTPOK)
|
|
92
|
+
|
|
93
|
+
if configuration.use_demo_server? &&
|
|
94
|
+
response['location'] &&
|
|
95
|
+
response['location']['forbidden.html']
|
|
96
|
+
warn 'OSRM API error: API usage policy has been violated, see https://github.com/Project-OSRM/osrm-backend/wiki/Api-usage-policy'
|
|
97
|
+
else
|
|
98
|
+
warn 'OSRM API error: Invalid response' \
|
|
99
|
+
" #{response.code} #{response.message}"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
false
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def build_uri
|
|
106
|
+
fail "OSRM API error: Server isn't configured" unless configuration.server
|
|
107
|
+
|
|
108
|
+
service = 'viaroute'
|
|
109
|
+
params = [
|
|
110
|
+
*@locations.map { |l| ['loc', l] },
|
|
111
|
+
%w(output json),
|
|
112
|
+
%w(instructions false),
|
|
113
|
+
%w(alt true)
|
|
114
|
+
]
|
|
115
|
+
|
|
116
|
+
uri_class = configuration.use_ssl? ? URI::HTTPS : URI::HTTP
|
|
117
|
+
@uri = uri_class.build(
|
|
118
|
+
host: configuration.server,
|
|
119
|
+
port: configuration.port,
|
|
120
|
+
path: "/#{service}",
|
|
121
|
+
query: URI.encode_www_form(params)
|
|
122
|
+
)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def uri
|
|
126
|
+
@uri || build_uri
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def configuration
|
|
130
|
+
OSRM.configuration
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
data/lib/osrm/route.rb
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'encoded_polyline'
|
|
2
|
+
|
|
3
|
+
module OSRM
|
|
4
|
+
class Route
|
|
5
|
+
attr_accessor :geometry, :summary
|
|
6
|
+
|
|
7
|
+
def initialize(geometry: nil, summary: nil)
|
|
8
|
+
@geometry = decode_geometry(geometry)
|
|
9
|
+
@summary = summary
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def decode_geometry(geometry)
|
|
15
|
+
return [] if geometry.nil? || geometry.empty?
|
|
16
|
+
|
|
17
|
+
EncodedPolyline.decode_points(geometry, 6).map do |point|
|
|
18
|
+
point.map { |coordinate| fix_float_precision(coordinate) }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# HACK: Should fix encoded_polyline gem instead
|
|
23
|
+
def fix_float_precision(float)
|
|
24
|
+
decimals = float.to_f.to_s[/\d+\z/]
|
|
25
|
+
fixed_decimals = decimals.sub(/(\d)\1{5,}\d{,2}\z/, '')
|
|
26
|
+
|
|
27
|
+
decimals == fixed_decimals ? float : float.round(fixed_decimals.size)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/lib/osrm/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: osrm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Freayd
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2014-12-
|
|
11
|
+
date: 2014-12-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -16,14 +16,40 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '1
|
|
19
|
+
version: '1'
|
|
20
|
+
- - ">="
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: 1.7.0
|
|
20
23
|
type: :development
|
|
21
24
|
prerelease: false
|
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
26
|
requirements:
|
|
24
27
|
- - "~>"
|
|
25
28
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '1
|
|
29
|
+
version: '1'
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 1.7.0
|
|
33
|
+
- !ruby/object:Gem::Dependency
|
|
34
|
+
name: rake
|
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '10'
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: 10.4.0
|
|
43
|
+
type: :development
|
|
44
|
+
prerelease: false
|
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
46
|
+
requirements:
|
|
47
|
+
- - "~>"
|
|
48
|
+
- !ruby/object:Gem::Version
|
|
49
|
+
version: '10'
|
|
50
|
+
- - ">="
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: 10.4.0
|
|
27
53
|
- !ruby/object:Gem::Dependency
|
|
28
54
|
name: encoded_polyline
|
|
29
55
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -53,10 +79,13 @@ files:
|
|
|
53
79
|
- LICENSE
|
|
54
80
|
- README.md
|
|
55
81
|
- lib/osrm.rb
|
|
82
|
+
- lib/osrm/configuration.rb
|
|
83
|
+
- lib/osrm/query.rb
|
|
84
|
+
- lib/osrm/route.rb
|
|
56
85
|
- lib/osrm/version.rb
|
|
57
86
|
homepage: https://github.com/freayd/osrm
|
|
58
87
|
licenses:
|
|
59
|
-
- GPL-3
|
|
88
|
+
- GPL-3.0
|
|
60
89
|
metadata: {}
|
|
61
90
|
post_install_message:
|
|
62
91
|
rdoc_options: []
|