cloudmade 0.1.2
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/.gitignore +5 -0
- data/Gemfile +4 -0
- data/LICENSE +165 -0
- data/README.md +64 -0
- data/Rakefile +13 -0
- data/cloudmade.gemspec +27 -0
- data/lib/cloudmade.rb +26 -0
- data/lib/cloudmade/client.rb +82 -0
- data/lib/cloudmade/connection.rb +70 -0
- data/lib/cloudmade/examples.rb +23 -0
- data/lib/cloudmade/exceptions.rb +35 -0
- data/lib/cloudmade/geocoding.rb +144 -0
- data/lib/cloudmade/geometry.rb +139 -0
- data/lib/cloudmade/locations.rb +20 -0
- data/lib/cloudmade/routing.rb +145 -0
- data/lib/cloudmade/service.rb +54 -0
- data/lib/cloudmade/tiles.rb +105 -0
- data/lib/cloudmade/version.rb +3 -0
- data/test/mock_connection.rb +15 -0
- data/test/test_geocoding.rb +71 -0
- data/test/test_geometry.rb +100 -0
- data/test/test_routing.rb +78 -0
- data/test/test_tiles.rb +33 -0
- metadata +104 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'cloudmade'
|
|
2
|
+
include CloudMade
|
|
3
|
+
|
|
4
|
+
cm = CloudMade::Client.from_parameters('BC9A493B41014CAABB98F0471D759707')
|
|
5
|
+
|
|
6
|
+
puts 'Testing CloudMade Client'
|
|
7
|
+
puts "Geocoding"
|
|
8
|
+
puts "---------"
|
|
9
|
+
puts "Find"
|
|
10
|
+
puts cm.geocoding.find('Potsdamer Platz, Berlin, Germany')
|
|
11
|
+
puts "Find closest"
|
|
12
|
+
puts cm.geocoding.find_closest('pub', 50.9425, 6.9575)
|
|
13
|
+
|
|
14
|
+
puts "Routing\n-------\n"
|
|
15
|
+
puts cm.routing.route(
|
|
16
|
+
CloudMade::Point.new(47.25976, 9.58423),
|
|
17
|
+
CloudMade::Point.new(47.66117, 9.99882))
|
|
18
|
+
|
|
19
|
+
puts "Tiles\n-----\n"
|
|
20
|
+
tile = cm.tiles.get_tile(50.39947, 30.6479, 15)
|
|
21
|
+
file = File.new('my_tile.png', 'w')
|
|
22
|
+
file.write(tile)
|
|
23
|
+
file.close
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2009 CloudMade.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the GNU Lesser General Public License, Version 3.0;
|
|
5
|
+
# You may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.gnu.org/licenses/lgpl-3.0.txt
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
#Raised when API key is not specified in Connection constructor
|
|
18
|
+
class APIKeyMissingError < Exception
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
#Raised when object was not found by geocoding service
|
|
22
|
+
class ObjectNotFound < Exception
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
#Raised when HTTP code other than 200 returned
|
|
26
|
+
class HTTPError < Exception
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#Raised when specified route couldn't be found
|
|
30
|
+
class RouteNotFound < Exception
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
#Raised when geometry is malformed
|
|
34
|
+
class GeometryParseError < Exception
|
|
35
|
+
end
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2009 CloudMade.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the GNU Lesser General Public License, Version 3.0;
|
|
5
|
+
# You may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.gnu.org/licenses/lgpl-3.0.txt
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
module CloudMade
|
|
18
|
+
require 'cgi'
|
|
19
|
+
|
|
20
|
+
# Class that is responsible for geocoding services of Cloudmade
|
|
21
|
+
class GeocodingService < Service
|
|
22
|
+
|
|
23
|
+
# Find objects that match given query. Returns GeoResults object.
|
|
24
|
+
#
|
|
25
|
+
# * +query+ Query by which objects should be searched
|
|
26
|
+
# * +options+ Additional options, contains
|
|
27
|
+
# results: How many results should be returned.
|
|
28
|
+
# skip: Number of results to skip from beginning.
|
|
29
|
+
# bbox: Bounding box in which objects should be searched.
|
|
30
|
+
# bbox_only: If set to False, results will be searched in the whole world if there are no results for a given bbox.
|
|
31
|
+
# return_geometry: If specified, adds geometry in returned results. Defaults to true.
|
|
32
|
+
#
|
|
33
|
+
def find(query, options = {})
|
|
34
|
+
options['results'] = 10 unless options.has_key? 'results'
|
|
35
|
+
options['skip'] = 0 unless options.has_key? 'skip'
|
|
36
|
+
options['bbox_only'] = true unless options.has_key? 'bbox_only'
|
|
37
|
+
options['return_geometry'] = true unless options.has_key? 'return_geometry'
|
|
38
|
+
request = "/find/#{CGI.escape(query)}.js?#{Service.to_url_params(options)}"
|
|
39
|
+
|
|
40
|
+
GeoResults.new(JSON.parse(connect request))
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Find closest object to a given point.
|
|
44
|
+
# For a list of available object types, see:
|
|
45
|
+
# http://www.cloudmade.com/developers/docs/geocoding-http-api/object_types
|
|
46
|
+
# Returns GeoResult object, that contain found objects.
|
|
47
|
+
# Raise ObjectNotFound: Raised when no object could be found in radius of 50 km from point.
|
|
48
|
+
#
|
|
49
|
+
# * +object_type+ Type of object, that should be searched.
|
|
50
|
+
# * +point+ Closest object to this point will be searched.
|
|
51
|
+
# * +options+ are
|
|
52
|
+
# * +return_geometry+ If specified, adds geometry in returned results. Defaults to true
|
|
53
|
+
|
|
54
|
+
# TODO: Modify lat, lon parameters to point
|
|
55
|
+
def find_closest(object_type, lat, lon, options = {})
|
|
56
|
+
lat_lon = "#{CGI.escape(lat.to_s + '+' + lon.to_s)}"
|
|
57
|
+
request = "/closest/#{object_type}/#{lat_lon}.js?#{Service.to_url_params(options)}"
|
|
58
|
+
geo_results = GeoResults.new(JSON.parse(connect request))
|
|
59
|
+
raise ObjectNotFound.new if (geo_results.results == nil or geo_results.results.size == 0)
|
|
60
|
+
return geo_results.results[0]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# :nodoc:
|
|
64
|
+
def url_template
|
|
65
|
+
return "http://#{@subdomain}.#{@connection.url}/#{@connection.api_key}/geocoding"
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Location of the object in geographical terms
|
|
70
|
+
class Location
|
|
71
|
+
# road: Road on which object is situated
|
|
72
|
+
attr_accessor :road
|
|
73
|
+
# city: City, where the object is situated
|
|
74
|
+
attr_accessor :city
|
|
75
|
+
# county: County, where the object is situated
|
|
76
|
+
attr_accessor :county
|
|
77
|
+
# country: Country in which the object is situated
|
|
78
|
+
attr_accessor :country
|
|
79
|
+
# postcode: Postcode, which corresponds to location of the object
|
|
80
|
+
attr_accessor :postcode
|
|
81
|
+
|
|
82
|
+
def initialize(data)
|
|
83
|
+
self.road = data['road']
|
|
84
|
+
self.city = data['city']
|
|
85
|
+
self.county = data['county']
|
|
86
|
+
self.country = data['country']
|
|
87
|
+
self.postcode = data['postcode']
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Parsed results of geocoding request
|
|
92
|
+
class GeoResults
|
|
93
|
+
# Founded results
|
|
94
|
+
attr_accessor :found
|
|
95
|
+
# List of found GeoResult objects
|
|
96
|
+
attr_accessor :results
|
|
97
|
+
# Bounds of result set
|
|
98
|
+
attr_accessor :bounds
|
|
99
|
+
|
|
100
|
+
def initialize(data)
|
|
101
|
+
self.found = Integer(data['found']) if data.has_key? 'found'
|
|
102
|
+
if (data['features'] != nil) then
|
|
103
|
+
self.results = data['features'].map { |feature_data| CloudMade::GeoResult.new(feature_data) }
|
|
104
|
+
end
|
|
105
|
+
self.bounds = CloudMade::BBox.from_coordinates(data['bounds']) if data.has_key? 'bounds'
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def to_s
|
|
109
|
+
results.join(',') if results != nil
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
class GeoResult
|
|
114
|
+
# Id of the object
|
|
115
|
+
attr_accessor :id
|
|
116
|
+
# Geometry of the object
|
|
117
|
+
attr_accessor :geometry
|
|
118
|
+
# Centroid of the object
|
|
119
|
+
attr_accessor :centroid
|
|
120
|
+
# Bounds of result set
|
|
121
|
+
attr_accessor :bounds
|
|
122
|
+
# Properties of the object
|
|
123
|
+
attr_accessor :properties
|
|
124
|
+
# Location of the object
|
|
125
|
+
attr_accessor :location
|
|
126
|
+
|
|
127
|
+
def initialize(data)
|
|
128
|
+
self.id = data['id']
|
|
129
|
+
self.geometry = CloudMade::Geometry.parse(data['geometry'])
|
|
130
|
+
self.centroid = CloudMade::Geometry.parse(data['centroid'])
|
|
131
|
+
self.bounds = CloudMade::BBox.from_coordinates(data['bounds']) if data.has_key? 'bounds'
|
|
132
|
+
self.properties = data['properties']
|
|
133
|
+
if data.has_key? 'location'
|
|
134
|
+
self.location = Location.new(data['location'])
|
|
135
|
+
else
|
|
136
|
+
self.location = nil
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def to_s
|
|
141
|
+
self.geometry.to_s
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2009 CloudMade.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the GNU Lesser General Public License, Version 3.0;
|
|
5
|
+
# You may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.gnu.org/licenses/lgpl-3.0.txt
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
module CloudMade
|
|
18
|
+
class Geometry
|
|
19
|
+
|
|
20
|
+
class << self
|
|
21
|
+
def parse(data)
|
|
22
|
+
return nil if data == nil
|
|
23
|
+
case data['type'].downcase
|
|
24
|
+
when 'point' then return Point.new(data['coordinates'])
|
|
25
|
+
when 'line' then return Line.new(data['coordinates'])
|
|
26
|
+
when 'multilinestring' then return MultiLine.new(data['coordinates'])
|
|
27
|
+
when 'polygon' then return Polygon.new(data['coordinates'])
|
|
28
|
+
when 'multipolygon' then return MultiPolygon.new(data['coordinates'])
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class Point < Geometry
|
|
35
|
+
attr_accessor :lat
|
|
36
|
+
attr_accessor :lon
|
|
37
|
+
|
|
38
|
+
# Posible initializers are
|
|
39
|
+
# Point.new(1, -1)
|
|
40
|
+
# Point.new([1, -1])
|
|
41
|
+
def initialize(*args)
|
|
42
|
+
if args.size == 1
|
|
43
|
+
@lat = args[0][0]
|
|
44
|
+
@lon = args[0][1]
|
|
45
|
+
elsif args.size == 2
|
|
46
|
+
@lat = args[0]
|
|
47
|
+
@lon = args[1]
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def ==(point)
|
|
52
|
+
return (point.lat == @lat and point.lon == @lon)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def to_s
|
|
56
|
+
"Point(#{@lat},#{@lon})"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def to_latlon
|
|
60
|
+
"#{@lat},#{@lon}"
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
class Line < Geometry
|
|
65
|
+
attr_accessor :points
|
|
66
|
+
|
|
67
|
+
def initialize(coords)
|
|
68
|
+
@points = coords.map { |latlng| Point.new(latlng) }
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def to_s
|
|
72
|
+
"Line(#{@points.join(',')})"
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class MultiLine < Geometry
|
|
78
|
+
attr_accessor :lines
|
|
79
|
+
|
|
80
|
+
def initialize(coords)
|
|
81
|
+
@lines = coords.map { |line_coords| Line.new(line_coords) }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def to_s
|
|
85
|
+
"MultiLine(#{@lines.join(',')})"
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
class Polygon < Geometry
|
|
90
|
+
attr_accessor :border_line
|
|
91
|
+
attr_accessor :holes
|
|
92
|
+
|
|
93
|
+
def initialize(coords)
|
|
94
|
+
@border_line = Line.new(coords[0])
|
|
95
|
+
@holes = coords.slice(1, coords.length).map { |line_coords| Line.new(line_coords) }
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def to_s
|
|
99
|
+
"Polygon(#{@border_line} - (#{@holes.join(',')}))"
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
class MultiPolygon < Geometry
|
|
104
|
+
attr_accessor :polygons
|
|
105
|
+
|
|
106
|
+
def initialize(coords)
|
|
107
|
+
@polygons = coords.map { |poly_coords| Polygon.new(poly_coords) }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def to_s
|
|
111
|
+
"MultiPolygon(#{@polygons.join(',')})"
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
class BBox < Geometry
|
|
116
|
+
attr_accessor :points
|
|
117
|
+
|
|
118
|
+
def initialize(points)
|
|
119
|
+
self.points = points
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
class << self
|
|
123
|
+
def from_points(points)
|
|
124
|
+
return BBox.new(points)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def from_coordinates(coords)
|
|
128
|
+
point1 = Point.new(coords[0][0], coords[0][1])
|
|
129
|
+
point2 = Point.new(coords[1][0], coords[1][1])
|
|
130
|
+
return BBox.new([point1, point2])
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def ==(bbox)
|
|
135
|
+
return (bbox.points[0] == self.points[0] and bbox.points[1] = self.points[1] or
|
|
136
|
+
bbox.points[0] == self.points[1] and bbox.points[1] = self.points[0])
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2009 CloudMade.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the GNU Lesser General Public License, Version 3.0;
|
|
5
|
+
# You may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.gnu.org/licenses/lgpl-3.0.txt
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
module CloudMade
|
|
18
|
+
class LocationsService < Service
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2009 CloudMade.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the GNU Lesser General Public License, Version 3.0;
|
|
5
|
+
# You may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.gnu.org/licenses/lgpl-3.0.txt
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
require 'cgi'
|
|
18
|
+
require 'json'
|
|
19
|
+
|
|
20
|
+
module CloudMade
|
|
21
|
+
|
|
22
|
+
#Class corresponding for CloudMade's routing service
|
|
23
|
+
class RoutingService < Service
|
|
24
|
+
|
|
25
|
+
ROUTE_TYPES = ['car', 'foot', 'bicycle']
|
|
26
|
+
OUTPUT_FORMATS = ['js', 'json', 'gpx']
|
|
27
|
+
STATUS_OK = 0
|
|
28
|
+
STATUS_ERROR = 1
|
|
29
|
+
EARTHS_DIRECTIONS = ["N", "NE", "E", "SE", "S", "SW", "W", "NW"]
|
|
30
|
+
TURN_TYPE = ["C", "TL", "TSLL", "TSHL", "TR", "TSLR", "TSHR", "U"]
|
|
31
|
+
|
|
32
|
+
# Build route. Returns route that was found, instance of CloudMade::Route
|
|
33
|
+
# * +start_point+ Starting point
|
|
34
|
+
# * +end_point+ Ending point
|
|
35
|
+
# * +route_type+ Type of route, e.g. 'car', 'foot', etc.
|
|
36
|
+
# * +transit_points+ List of points route must visit before
|
|
37
|
+
# reaching end. Points are visited in the same order they are
|
|
38
|
+
# specified in the sequence.
|
|
39
|
+
# * +route_type_modifier+ Modifier of the route type
|
|
40
|
+
# * +lang+ Language code in conformance to `ISO 3166-1 alpha-2` standard
|
|
41
|
+
# * +units+ Measure units for distance calculation
|
|
42
|
+
def route(start_point, end_point, transit_points = nil, route_type = 'car', lang = 'en', route_type_modifier = nil)
|
|
43
|
+
transit_points = ",[#{transit_points.map {|point| point.to_latlon}.join(',')}]" if not transit_points == nil
|
|
44
|
+
route_type_modifier = "/#{route_type_modifier}" if not route_type_modifier == nil
|
|
45
|
+
url = "/#{start_point.to_latlon}#{transit_points},#{end_point.to_latlon}/#{route_type}#{route_type_modifier}.js?lang=#{lang}&units=km"
|
|
46
|
+
return Route.new(JSON.parse(connect url))
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
#:nodoc:
|
|
50
|
+
def url_template
|
|
51
|
+
return "http://#{@subdomain}.#{@connection.url}/#{@connection.api_key}/api/0.3"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# Statistics of the route
|
|
57
|
+
class RouteSummary
|
|
58
|
+
attr_accessor :total_distance
|
|
59
|
+
attr_accessor :total_time
|
|
60
|
+
attr_accessor :start_point
|
|
61
|
+
attr_accessor :end_point
|
|
62
|
+
attr_accessor :transit_points
|
|
63
|
+
|
|
64
|
+
def initialize(summary)
|
|
65
|
+
self.total_distance = Float(summary['total_distance'])
|
|
66
|
+
self.total_time = Float(summary['total_time'])
|
|
67
|
+
self.start_point = summary['start_point']
|
|
68
|
+
self.end_point = summary['end_point']
|
|
69
|
+
self.transit_points = summary['transit_points']
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Wrapper around raw data being returned by routing service
|
|
74
|
+
class Route
|
|
75
|
+
|
|
76
|
+
# List of route instructions
|
|
77
|
+
attr_accessor :instructions
|
|
78
|
+
# Statistical info about the route
|
|
79
|
+
attr_accessor :summary
|
|
80
|
+
# Geometry of route
|
|
81
|
+
attr_accessor :geometry
|
|
82
|
+
#Version of routing HTTP API
|
|
83
|
+
attr_accessor :version
|
|
84
|
+
# Status of response
|
|
85
|
+
attr_accessor :status
|
|
86
|
+
attr_accessor :status_message
|
|
87
|
+
|
|
88
|
+
STATUS_OK = 0
|
|
89
|
+
STATUS_ERROR = 1
|
|
90
|
+
|
|
91
|
+
def initialize(data)
|
|
92
|
+
begin
|
|
93
|
+
self.status = data['status'].to_i
|
|
94
|
+
self.instructions = data['route_instructions'].map { |instruction_data| RouteInstruction.new(instruction_data) }
|
|
95
|
+
self.summary = RouteSummary.new(data['route_summary'])
|
|
96
|
+
self.geometry = Line.new(data['route_geometry'])
|
|
97
|
+
self.version = data['version']
|
|
98
|
+
self.status_message = data['status_message']
|
|
99
|
+
rescue
|
|
100
|
+
raise RouteNotFound
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def to_s
|
|
105
|
+
self.instructions.to_s
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Instructions on route passing
|
|
110
|
+
class RouteInstruction
|
|
111
|
+
|
|
112
|
+
# Text instruction
|
|
113
|
+
attr_reader :instruction
|
|
114
|
+
# Length of the segment in meters
|
|
115
|
+
attr_reader :length
|
|
116
|
+
# Index of the first point of the segment
|
|
117
|
+
attr_reader :position
|
|
118
|
+
# Estimated time required to travel the segment in seconds
|
|
119
|
+
attr_reader :time
|
|
120
|
+
# Length of the segments in specified units
|
|
121
|
+
attr_reader :length_caption
|
|
122
|
+
# Earth direction
|
|
123
|
+
attr_reader :earth_direction
|
|
124
|
+
# North-based azimuth
|
|
125
|
+
attr_reader :azimuth
|
|
126
|
+
# Code of the turn type
|
|
127
|
+
attr_reader :turn_type
|
|
128
|
+
# Angle in degress of the turn between two segments
|
|
129
|
+
attr_reader :turn_angle
|
|
130
|
+
|
|
131
|
+
def initialize(data)
|
|
132
|
+
@instruction = data[0]
|
|
133
|
+
@length = Float(data[1])
|
|
134
|
+
@position = Integer(data[2])
|
|
135
|
+
@time = Integer(data[3])
|
|
136
|
+
@length_caption = data[4]
|
|
137
|
+
@earth_direction = data[5]
|
|
138
|
+
@azimuth = Float(data[6])
|
|
139
|
+
if data.length == 9
|
|
140
|
+
@turn_type = data[7]
|
|
141
|
+
@turn_angle = data[8]
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|