routing 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6f2365563b9f8bbdedbfc071a7617b1d0d5865d1
4
+ data.tar.gz: f39f04367027d8d773ff8e9e98246fc29649f701
5
+ SHA512:
6
+ metadata.gz: 3bc6220170518feca7a9ba21ae7a0c4af6ba7a3cbe51b8ee5996f53f2a9552747acee5d74a02bf79ca19cc471ae45ea30073ca8a40b0b0784495dffc43757ef1
7
+ data.tar.gz: fe3dde7390ad12fbed60fa4647877f16a82adef21ad1dad3dcd68e60ed4fecbf14f9e850c2c4d5c757e4be8897eaf1afe1c25206cdeafc8ee567942479d2b22b
data/.gitignore CHANGED
@@ -21,3 +21,6 @@ test/version_tmp
21
21
  tmp
22
22
  **/.DS_Store
23
23
  .DS_Store
24
+
25
+ /.ruby-gemset
26
+ /.ruby-version
data/Gemfile CHANGED
@@ -1,8 +1,8 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
5
  gem "awesome_print"
6
6
  gem "yard"
7
7
  gem "redcarpet"
8
- gem "guard-rspec"
8
+ gem "guard-rspec"
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012 flinc AG
1
+ Copyright (c) 2014 flinc AG
2
2
 
3
3
  MIT License
4
4
 
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
19
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
20
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
21
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -15,8 +15,9 @@ class Routing
15
15
  # as only parameters and will return an Array of {Routing::GeoPoint}s when the calculation is done.
16
16
  module Adapter
17
17
 
18
+ autoload :Here, "routing/adapter/here"
18
19
  autoload :Navteq, "routing/adapter/navteq"
19
20
  autoload :Test, "routing/adapter/test"
20
21
 
21
22
  end
22
- end
23
+ end
@@ -0,0 +1,62 @@
1
+ require 'time'
2
+ require 'faraday'
3
+
4
+ class Routing
5
+ module Adapter
6
+
7
+ # Adapter for a Nokia Here Routing Service v7 server.
8
+ # It passes the {GeoPoint}s to the routing service and will return another
9
+ # Array of {GeoPoint}s, representing the calculated route.
10
+ class Here
11
+
12
+ def initialize(options = {})
13
+ @options = {
14
+ :host => 'http://route.api.here.com',
15
+ :service_path => '/routing/7.2/calculateroute.json',
16
+ :parser => ::Routing::Parser::HereSimple
17
+ }.merge(options)
18
+ end
19
+
20
+ def calculate(geo_points)
21
+ response = connection.get do |request|
22
+ request.url(options[:service_path])
23
+ request.params = default_params.merge(geo_points_to_params(geo_points)).merge(options[:credentials])
24
+ end
25
+
26
+ parse(response.body)
27
+ end
28
+
29
+ private
30
+
31
+ def parse(response)
32
+ options[:parser].new(response).to_geo_points
33
+ end
34
+
35
+ def default_params
36
+ options[:default_params] || {
37
+ departure: Time.now.utc.iso8601,
38
+ mode: "fastest;car",
39
+ language: "de_DE",
40
+ legattributes: "all,-links",
41
+ maneuverattributes: "position,travelTime,length,time"
42
+ }
43
+ end
44
+
45
+ def geo_points_to_params(geo_points)
46
+ Hash[geo_points.each_with_index.map { |point, i| [ "waypoint#{i}", "geo!#{point.lat},#{point.lng}" ] }]
47
+ end
48
+
49
+ def connection
50
+ @connection ||= Faraday.new(:url => options[:host]) do |builder|
51
+ builder.request :url_encoded
52
+ builder.adapter :net_http
53
+ end
54
+ end
55
+
56
+ def options
57
+ @options || {}
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -7,6 +7,7 @@ class Routing
7
7
  module Parser
8
8
 
9
9
  autoload :NavteqSimple, "routing/parser/navteq_simple"
10
+ autoload :HereSimple, "routing/parser/here_simple"
10
11
 
11
12
  # This error is thrown by the parsers if a calculated waypoint can't be matched
12
13
  # to one of the initial passed geo points that were routed.
@@ -23,4 +24,4 @@ class Routing
23
24
  end
24
25
 
25
26
  end
26
- end
27
+ end
@@ -0,0 +1,110 @@
1
+ class Routing
2
+ module Parser
3
+
4
+ # A very simple parser implementation for a Nokia Here Routing Service v7.
5
+ # It converts the json response of the routing service to an Array of {GeoPoint}s.
6
+ class HereSimple
7
+
8
+ # Creates a new instance of the parser.
9
+ #
10
+ # @param [String] response
11
+ # A json response string of a Nokia Here routing server.
12
+ def initialize(response)
13
+ response = JSON.parse(response)
14
+ check_for_error(response)
15
+
16
+ @route = response["response"]["route"].first
17
+ @overall_covered_distance = 0
18
+ @overall_relative_time = 0
19
+ end
20
+
21
+ # Converts the server response in an Array of {GeoPoint}s
22
+ #
23
+ # @return [Array<GeoPoint>]
24
+ # List of {GeoPoint}s that represent the calculated route.
25
+ def to_geo_points
26
+ legs = @route["leg"]
27
+ geo_points = legs.map { |leg| parse_leg(leg) }.flatten
28
+
29
+ # At last we add the destination point
30
+ geo_points << parse_maneuver(legs.last["maneuver"].last, waypoint: true)
31
+ geo_points
32
+ end
33
+
34
+ private
35
+
36
+ # Parses is single leg of the route including all its maneuvers.
37
+ #
38
+ # @param [Hash] leg
39
+ # The route leg to parse.
40
+ #
41
+ # @return [Array<GeoPoint>]
42
+ # List of {GeoPoint}s that represent the passed Leg.
43
+ def parse_leg(leg)
44
+ # Skip the last maneuver as it is the same as the first one
45
+ # of the next maneuver.
46
+ # For the last leg we parse the last maneuver right at the end
47
+ maneuvers = leg["maneuver"][0...-1]
48
+ maneuvers.map do |maneuver|
49
+ parse_maneuver(maneuver, :waypoint => (maneuver == maneuvers.first))
50
+ end
51
+ end
52
+
53
+ # Parses is single maneuver of a route leg.
54
+ #
55
+ # @param [Hash] maneuver
56
+ # The maneuver to parse.
57
+ #
58
+ # @param [Hash] attributes
59
+ # Additional attributes that should be set on the returned {GeoPoint}.
60
+ #
61
+ # @return [GeoPoint]
62
+ # A {GeoPoint} that represents the passed maneuver.
63
+ def parse_maneuver(maneuver, attributes = {})
64
+ geo_point = ::Routing::GeoPoint.new attributes.merge({
65
+ lat: maneuver["position"]["latitude"],
66
+ lng: maneuver["position"]["longitude"],
67
+ relative_time: @overall_relative_time,
68
+ distance: @overall_covered_distance
69
+ })
70
+
71
+ @overall_relative_time += maneuver["travelTime"].to_i
72
+ @overall_covered_distance += maneuver["length"].to_i
73
+
74
+ search_original_position(geo_point) if geo_point.waypoint?
75
+
76
+ geo_point
77
+ end
78
+
79
+ # Matches a parsed {GeoPoint} of the route response
80
+ # with the (unmapped) position of the
81
+ # corresponding {GeoPoint} of the request.
82
+ #
83
+ # @param [GeoPoint] geo_point
84
+ # Point of the response to find the initial position for.
85
+ #
86
+ # @return [GeoPoint]
87
+ # The passed in {GeoPoint}, enriched with the information about the original position in the request.
88
+ #
89
+ # @raise [NoMatchingMappedPositionFound] If no matching original position is found.
90
+ def search_original_position(geo_point)
91
+ matching_waypoint = @route["waypoint"].detect do |waypoint|
92
+ waypoint["mappedPosition"]["latitude"] == geo_point.lat &&
93
+ waypoint["mappedPosition"]["longitude"] == geo_point.lng
94
+ end or raise NoMatchingMappedPositionFound
95
+
96
+ geo_point.original_lat = matching_waypoint["originalPosition"]["latitude"]
97
+ geo_point.original_lng = matching_waypoint["originalPosition"]["longitude"]
98
+
99
+ geo_point
100
+ end
101
+
102
+ def check_for_error(response)
103
+ if error = response['type'] && response['type'][/error/i]
104
+ raise Routing::Parser::RoutingFailed.new("#{response['type']}(#{response['subtype']}) - #{response['details']}")
105
+ end
106
+ end
107
+
108
+ end
109
+ end
110
+ end
@@ -1,3 +1,3 @@
1
1
  class Routing
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -0,0 +1,17 @@
1
+ {
2
+ "type": "ApplicationError",
3
+ "subtype": "NoRouteFound",
4
+ "details": "Error is NGEO_ERROR_ROUTE_NO_END_POINT",
5
+ "additionalData": [
6
+ {
7
+ "key": "error_code",
8
+ "value": "NGEO_ERROR_ROUTE_NO_END_POINT"
9
+ }
10
+ ],
11
+ "metaInfo": {
12
+ "timestamp": "2014-02-20T08:49:26.399Z",
13
+ "mapVersion": "8.30.53.153",
14
+ "moduleVersion": "7.2.42.0_CD-902_1",
15
+ "interfaceVersion": "2.4.37"
16
+ }
17
+ }
@@ -0,0 +1,245 @@
1
+ {
2
+ "response": {
3
+ "metaInfo": {
4
+ "timestamp": "2014-02-20T08:48:17.028Z",
5
+ "mapVersion": "8.30.53.153",
6
+ "moduleVersion": "7.2.42.0_CD-902_1",
7
+ "interfaceVersion": "2.4.37"
8
+ },
9
+ "route": [
10
+ {
11
+ "waypoint": [
12
+ {
13
+ "linkId": "+1600996215040705549",
14
+ "mappedPosition": {
15
+ "latitude": 49.9019153,
16
+ "longitude": 8.8588599
17
+ },
18
+ "originalPosition": {
19
+ "latitude": 49.90261,
20
+ "longitude": 8.85866
21
+ },
22
+ "type": "stopOver",
23
+ "spot": 0.4035088,
24
+ "sideOfStreet": "left",
25
+ "mappedRoadName": "Hohe Straße",
26
+ "label": "Hohe Straße",
27
+ "shapeIndex": 0
28
+ },
29
+ {
30
+ "linkId": "-1601136969708929748",
31
+ "mappedPosition": {
32
+ "latitude": 49.9533103,
33
+ "longitude": 8.9529667
34
+ },
35
+ "originalPosition": {
36
+ "latitude": 49.9532,
37
+ "longitude": 8.95293
38
+ },
39
+ "type": "stopOver",
40
+ "spot": 0.3484848,
41
+ "sideOfStreet": "right",
42
+ "mappedRoadName": "Südring",
43
+ "label": "Südring",
44
+ "shapeIndex": 55
45
+ }
46
+ ],
47
+ "mode": {
48
+ "type": "fastest",
49
+ "transportModes": [
50
+ "car"
51
+ ],
52
+ "trafficMode": "default",
53
+ "feature": []
54
+ },
55
+ "leg": [
56
+ {
57
+ "start": {
58
+ "linkId": "+1600996215040705549",
59
+ "mappedPosition": {
60
+ "latitude": 49.9019153,
61
+ "longitude": 8.8588599
62
+ },
63
+ "originalPosition": {
64
+ "latitude": 49.90261,
65
+ "longitude": 8.85866
66
+ },
67
+ "type": "stopOver",
68
+ "spot": 0.4035088,
69
+ "sideOfStreet": "left",
70
+ "mappedRoadName": "Hohe Straße",
71
+ "label": "Hohe Straße",
72
+ "shapeIndex": 0
73
+ },
74
+ "end": {
75
+ "linkId": "-1601136969708929748",
76
+ "mappedPosition": {
77
+ "latitude": 49.9533103,
78
+ "longitude": 8.9529667
79
+ },
80
+ "originalPosition": {
81
+ "latitude": 49.9532,
82
+ "longitude": 8.95293
83
+ },
84
+ "type": "stopOver",
85
+ "spot": 0.3484848,
86
+ "sideOfStreet": "right",
87
+ "mappedRoadName": "Südring",
88
+ "label": "Südring",
89
+ "shapeIndex": 55
90
+ },
91
+ "length": 9117,
92
+ "travelTime": 592,
93
+ "maneuver": [
94
+ {
95
+ "position": {
96
+ "latitude": 49.9019153,
97
+ "longitude": 8.8588599
98
+ },
99
+ "instruction": "Fahren Sie auf <span class=\"street\">Hohe Straße</span> nach <span class=\"heading\">Osten</span>. <span class=\"distance-description\">Fahren Sie <span class=\"length\">159 m</span></span>.",
100
+ "travelTime": 35,
101
+ "length": 159,
102
+ "time": "2014-02-20T08:48:19Z",
103
+ "id": "M1",
104
+ "_type": "PrivateTransportManeuverType"
105
+ },
106
+ {
107
+ "position": {
108
+ "latitude": 49.9020696,
109
+ "longitude": 8.8610744
110
+ },
111
+ "instruction": "Biegen Sie <span class=\"direction\">links</span> ab auf die <span class=\"number\">K128</span>. <span class=\"distance-description\">Fahren Sie <span class=\"length\">1.1 km</span></span>.",
112
+ "travelTime": 88,
113
+ "length": 1103,
114
+ "time": "2014-02-20T08:48:54Z",
115
+ "id": "M2",
116
+ "_type": "PrivateTransportManeuverType"
117
+ },
118
+ {
119
+ "position": {
120
+ "latitude": 49.9085712,
121
+ "longitude": 8.8707948
122
+ },
123
+ "instruction": "Biegen Sie <span class=\"direction\">links</span> ab auf die <span class=\"number\">B26</span>. <span class=\"distance-description\">Fahren Sie <span class=\"length\">7.8 km</span></span>.",
124
+ "travelTime": 455,
125
+ "length": 7763,
126
+ "time": "2014-02-20T08:50:22Z",
127
+ "id": "M3",
128
+ "_type": "PrivateTransportManeuverType"
129
+ },
130
+ {
131
+ "position": {
132
+ "latitude": 49.9537396,
133
+ "longitude": 8.9518619
134
+ },
135
+ "instruction": "Biegen Sie <span class=\"direction\">rechts</span> ab auf <span class=\"next-street\">Südring</span>. <span class=\"distance-description\">Fahren Sie <span class=\"length\">92 m</span></span>.",
136
+ "travelTime": 14,
137
+ "length": 92,
138
+ "time": "2014-02-20T08:57:57Z",
139
+ "id": "M4",
140
+ "_type": "PrivateTransportManeuverType"
141
+ },
142
+ {
143
+ "position": {
144
+ "latitude": 49.9533103,
145
+ "longitude": 8.9529667
146
+ },
147
+ "instruction": "Sie erreichen <span class=\"street\">Südring</span>. Ihr Ziel liegt auf der rechten Seite.",
148
+ "travelTime": 0,
149
+ "length": 0,
150
+ "time": "2014-02-20T08:58:11Z",
151
+ "id": "M5",
152
+ "_type": "PrivateTransportManeuverType"
153
+ }
154
+ ],
155
+ "boundingBox": {
156
+ "topLeft": {
157
+ "latitude": 49.9537396,
158
+ "longitude": 8.8588599
159
+ },
160
+ "bottomRight": {
161
+ "latitude": 49.9019153,
162
+ "longitude": 8.9529667
163
+ }
164
+ },
165
+ "shape": [
166
+ "49.9019153,8.8588599",
167
+ "49.901973,8.8593256",
168
+ "49.9020696,8.8610744",
169
+ "49.9025095,8.8611817",
170
+ "49.9029493,8.861289",
171
+ "49.9037647,8.8615787",
172
+ "49.9040115,8.8616967",
173
+ "49.904741,8.8621795",
174
+ "49.90502,8.862437",
175
+ "49.9054062,8.8628447",
176
+ "49.9057817,8.8632846",
177
+ "49.9061894,8.8638747",
178
+ "49.9069083,8.8651192",
179
+ "49.9071443,8.8655806",
180
+ "49.9073482,8.8660741",
181
+ "49.9074447,8.8663852",
182
+ "49.9075949,8.8672328",
183
+ "49.9076915,8.8675761",
184
+ "49.907949,8.868295",
185
+ "49.9086678,8.8700974",
186
+ "49.9087322,8.8702905",
187
+ "49.9087429,8.870548",
188
+ "49.9087214,8.8706338",
189
+ "49.9086571,8.8707197",
190
+ "49.9085712,8.8707948",
191
+ "49.9086678,8.8709557",
192
+ "49.9101484,8.8739598",
193
+ "49.9104702,8.8746464",
194
+ "49.9114037,8.8769531",
195
+ "49.9127448,8.8803542",
196
+ "49.913528,8.8822746",
197
+ "49.9138498,8.882972",
198
+ "49.9140751,8.883369",
199
+ "49.9143648,8.8838089",
200
+ "49.914633,8.8841629",
201
+ "49.9154699,8.8850641",
202
+ "49.9202979,8.8900208",
203
+ "49.9205768,8.8903213",
204
+ "49.9208665,8.8907182",
205
+ "49.9210382,8.8910079",
206
+ "49.9212849,8.8915551",
207
+ "49.9214458,8.8921237",
208
+ "49.9215531,8.8925743",
209
+ "49.9216604,8.8934648",
210
+ "49.9217892,8.8952565",
211
+ "49.9218857,8.8959432",
212
+ "49.921993,8.8962972",
213
+ "49.9222076,8.8968337",
214
+ "49.942764,8.9327645",
215
+ "49.9496412,8.9447272",
216
+ "49.9522698,8.9493299",
217
+ "49.9536109,8.9516366",
218
+ "49.9537396,8.9518619",
219
+ "49.9534822,8.9524198",
220
+ "49.9533641,8.9527309",
221
+ "49.9533103,8.9529667"
222
+ ],
223
+ "firstPoint": 0,
224
+ "lastPoint": 55,
225
+ "trafficTime": 667,
226
+ "baseTime": 592,
227
+ "summary": {
228
+ "distance": 9117,
229
+ "trafficTime": 667,
230
+ "baseTime": 592,
231
+ "travelTime": 592
232
+ }
233
+ }
234
+ ],
235
+ "summary": {
236
+ "distance": 9117,
237
+ "trafficTime": 667,
238
+ "baseTime": 592,
239
+ "travelTime": 592
240
+ }
241
+ }
242
+ ],
243
+ "language": "de-de"
244
+ }
245
+ }
@@ -0,0 +1,88 @@
1
+ require 'spec_helper'
2
+
3
+ describe Routing::Adapter::Here do
4
+
5
+ let(:response) { mock(:response).as_null_object }
6
+ let(:request) { mock(:request).as_null_object }
7
+ let(:connection) { mock(:connection).as_null_object }
8
+ let(:parser_class) { mock(:parser_class, :new => parser) }
9
+ let(:parser) { mock(:parser).as_null_object }
10
+
11
+ let(:options) do
12
+ { :parser => parser_class, :credentials => { :app_id => "123", :app_code => "456" } }
13
+ end
14
+
15
+ let(:geo_points) { [stub(:lat => 1, :lng => 2), stub(:lat => 3, :lng => 4), stub(:lat => 5, :lng => 6)] }
16
+
17
+ subject { described_class.new(options) }
18
+
19
+ before do
20
+ connection.stub(:get).and_yield(request).and_return(response)
21
+ Faraday.stub(:new).and_return(connection)
22
+ end
23
+
24
+ context 'creating a new instance' do
25
+ it 'can be instantiated without arguments' do
26
+ expect { described_class.new }.to_not raise_error
27
+ end
28
+
29
+ it 'allows setting the host' do
30
+ Faraday.should_receive(:new).with(:url => 'http://other.com')
31
+ options.merge!(:host => 'http://other.com')
32
+ end
33
+
34
+ it 'allows setting the default params' do
35
+ params = { :hello => "world" }
36
+ options.merge!(:default_params => params)
37
+ request.should_receive(:params=).with(hash_including(params))
38
+ end
39
+
40
+ it 'sets the api credentials' do
41
+ request.should_receive(:params=).with(hash_including({ :app_id => "123", :app_code => "456" }))
42
+ end
43
+
44
+ it 'should allow setting the service path' do
45
+ options.merge!(:service_path => '/some/path.json')
46
+ request.should_receive(:url).with('/some/path.json')
47
+ end
48
+
49
+ it 'should use a default service path when none is given' do
50
+ request.should_receive(:url).with('/routing/7.2/calculateroute.json')
51
+ end
52
+
53
+ it 'should allow setting the parser' do
54
+ options.merge!(:parser => parser_class)
55
+ parser_class.should_receive(:new)
56
+ end
57
+
58
+ it 'should use a default parser when none is given' do
59
+ options.delete(:parser)
60
+ Routing::Parser::HereSimple.should_receive(:new).and_return(parser)
61
+ end
62
+
63
+ it 'ignores unknown options' do
64
+ expect { described_class.new(:hello => "world") }.to_not raise_error
65
+ end
66
+ end
67
+
68
+ describe '#calculate' do
69
+ it 'passes the response to the parser' do
70
+ response.stub(:body => '...')
71
+ parser_class.should_receive(:new).with('...')
72
+ end
73
+
74
+ it 'should return the parser\'s result' do
75
+ result = [double, double, double]
76
+ parser.stub(:to_geo_points => result)
77
+ subject.calculate(geo_points).should be(result)
78
+ end
79
+
80
+ it 'should convert the geo points into a compatible format' do
81
+ request.should_receive(:params=).with hash_including({
82
+ 'waypoint0' => 'geo!1,2',
83
+ 'waypoint1' => 'geo!3,4',
84
+ 'waypoint2' => 'geo!5,6'
85
+ })
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+ require 'json'
3
+
4
+ describe Routing::Parser::HereSimple do
5
+
6
+ context 'with a error response' do
7
+ let(:error_response) { fixture('here/error_response.json') }
8
+
9
+ it 'should throw an RoutingFailed error' do
10
+ lambda{ described_class.new(error_response) }.should raise_error(Routing::Parser::RoutingFailed)
11
+ end
12
+ end
13
+
14
+ context 'with a successful routing response' do
15
+ let(:response) { fixture('here/response.json') }
16
+ let(:json_response) { JSON.parse(response) }
17
+ let(:original_geo_points) do
18
+ json_response['response']['route'].first['waypoint'].collect do |waypoint|
19
+ mock({
20
+ lat: waypoint['originalPosition']['latitude'],
21
+ lng: waypoint['originalPosition']['longitude']
22
+ })
23
+ end
24
+ end
25
+
26
+ describe '#to_geo_points' do
27
+ subject { described_class.new(response).to_geo_points }
28
+
29
+ it 'returns geopoints' do
30
+ subject.each { |point| point.should be_a(::Routing::GeoPoint) }
31
+ end
32
+
33
+ describe 'number of geo points' do
34
+ let(:leg_size) { json_response["response"]["route"].first["leg"].size }
35
+ let(:leg_touching_point_size) { leg_size - 1 }
36
+ let(:maneuver_size) { json_response["response"]["route"].first["leg"].inject(0) { |sum, leg| sum + leg["maneuver"].size } }
37
+
38
+ it 'has the length of all maneuvers minus the duplicate ones at the touching points' do
39
+ should have(maneuver_size - leg_touching_point_size).geo_points
40
+ end
41
+ end
42
+
43
+ describe 'coordinates' do
44
+ it 'sets the calculated latitude and longitude for each geo point' do
45
+ subject.each do |geo_point|
46
+ geo_point.lat.should be
47
+ geo_point.lng.should be
48
+ end
49
+ end
50
+ end
51
+
52
+ describe 'original waypoints' do
53
+ subject { described_class.new(response).to_geo_points.select(&:waypoint?) }
54
+
55
+ it 'includes the same number of waypoints as passed in' do
56
+ should have(original_geo_points.size).geo_points
57
+ end
58
+
59
+ it 'sets original_lat and original_lng on the waypoints' do
60
+ subject.each_with_index do |geo_point, index|
61
+ geo_point.original_lat.should eq(original_geo_points[index].lat)
62
+ geo_point.original_lng.should eq(original_geo_points[index].lng)
63
+ end
64
+ end
65
+
66
+ context 'when response does not contain the original waypoints' do
67
+ let(:response) do
68
+ corrupted_response = JSON.parse(fixture('here/response.json'))
69
+ corrupted_response['response']['route'].first['waypoint'].first['mappedPosition']['latitude'] += 0.1
70
+ corrupted_response['response']['route'].first['waypoint'].first['mappedPosition']['longitude'] += 0.1
71
+ JSON.dump(corrupted_response)
72
+ end
73
+
74
+ it 'raises an exception if no matching original position was found' do
75
+ expect { subject }.to raise_error(Routing::Parser::NoMatchingMappedPositionFound)
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: routing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
5
- prerelease:
4
+ version: 0.0.4
6
5
  platform: ruby
7
6
  authors:
8
7
  - Christian Bäuerlein
@@ -10,42 +9,51 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2012-07-25 00:00:00.000000000 Z
12
+ date: 2014-02-20 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: faraday
17
- requirement: &70283743036520 !ruby/object:Gem::Requirement
18
- none: false
16
+ requirement: !ruby/object:Gem::Requirement
19
17
  requirements:
20
- - - ! '>='
18
+ - - ">="
21
19
  - !ruby/object:Gem::Version
22
20
  version: 0.7.0
23
21
  type: :runtime
24
22
  prerelease: false
25
- version_requirements: *70283743036520
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: 0.7.0
26
28
  - !ruby/object:Gem::Dependency
27
29
  name: json
28
- requirement: &70283743036060 !ruby/object:Gem::Requirement
29
- none: false
30
+ requirement: !ruby/object:Gem::Requirement
30
31
  requirements:
31
- - - ! '>='
32
+ - - ">="
32
33
  - !ruby/object:Gem::Version
33
34
  version: '0'
34
35
  type: :runtime
35
36
  prerelease: false
36
- version_requirements: *70283743036060
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
37
42
  - !ruby/object:Gem::Dependency
38
43
  name: rspec
39
- requirement: &70283743035460 !ruby/object:Gem::Requirement
40
- none: false
44
+ requirement: !ruby/object:Gem::Requirement
41
45
  requirements:
42
- - - ! '>='
46
+ - - ">="
43
47
  - !ruby/object:Gem::Version
44
48
  version: 2.9.0
45
49
  type: :development
46
50
  prerelease: false
47
- version_requirements: *70283743035460
48
- description: ! "\n Provides a generic interface for routing services that can by
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: 2.9.0
56
+ description: "\n Provides a generic interface for routing services that can by
49
57
  used to calculate directions between geolocations.\n Makes parsing and use-case
50
58
  specific data handling easy trough an extendable middleware stack.\n "
51
59
  email:
@@ -55,7 +63,7 @@ executables: []
55
63
  extensions: []
56
64
  extra_rdoc_files: []
57
65
  files:
58
- - .gitignore
66
+ - ".gitignore"
59
67
  - Gemfile
60
68
  - Guardfile
61
69
  - LICENSE
@@ -63,52 +71,61 @@ files:
63
71
  - Rakefile
64
72
  - lib/routing.rb
65
73
  - lib/routing/adapter.rb
74
+ - lib/routing/adapter/here.rb
66
75
  - lib/routing/adapter/navteq.rb
67
76
  - lib/routing/adapter/test.rb
68
77
  - lib/routing/geo_point.rb
69
78
  - lib/routing/middleware.rb
70
79
  - lib/routing/parser.rb
80
+ - lib/routing/parser/here_simple.rb
71
81
  - lib/routing/parser/navteq_simple.rb
72
82
  - lib/routing/version.rb
73
83
  - routing.gemspec
84
+ - spec/fixtures/here/error_response.json
85
+ - spec/fixtures/here/response.json
74
86
  - spec/fixtures/navteq/error_response.json
75
87
  - spec/fixtures/navteq/response.json
88
+ - spec/routing/adapter/here_spec.rb
76
89
  - spec/routing/adapter/navteq_spec.rb
77
90
  - spec/routing/adapter/test_spec.rb
78
91
  - spec/routing/geo_point_spec.rb
92
+ - spec/routing/parser/here_simple_spec.rb
79
93
  - spec/routing/parser/navteq_simple_spec.rb
80
94
  - spec/routing_spec.rb
81
95
  - spec/spec_helper.rb
82
96
  homepage: https://github.com/flinc/routing
83
97
  licenses: []
98
+ metadata: {}
84
99
  post_install_message:
85
100
  rdoc_options: []
86
101
  require_paths:
87
102
  - lib
88
103
  required_ruby_version: !ruby/object:Gem::Requirement
89
- none: false
90
104
  requirements:
91
- - - ! '>='
105
+ - - ">="
92
106
  - !ruby/object:Gem::Version
93
107
  version: '0'
94
108
  required_rubygems_version: !ruby/object:Gem::Requirement
95
- none: false
96
109
  requirements:
97
- - - ! '>='
110
+ - - ">="
98
111
  - !ruby/object:Gem::Version
99
112
  version: '0'
100
113
  requirements: []
101
114
  rubyforge_project:
102
- rubygems_version: 1.8.17
115
+ rubygems_version: 2.2.0
103
116
  signing_key:
104
- specification_version: 3
117
+ specification_version: 4
105
118
  summary: A ruby interface for route calculation services
106
119
  test_files:
120
+ - spec/fixtures/here/error_response.json
121
+ - spec/fixtures/here/response.json
107
122
  - spec/fixtures/navteq/error_response.json
108
123
  - spec/fixtures/navteq/response.json
124
+ - spec/routing/adapter/here_spec.rb
109
125
  - spec/routing/adapter/navteq_spec.rb
110
126
  - spec/routing/adapter/test_spec.rb
111
127
  - spec/routing/geo_point_spec.rb
128
+ - spec/routing/parser/here_simple_spec.rb
112
129
  - spec/routing/parser/navteq_simple_spec.rb
113
130
  - spec/routing_spec.rb
114
131
  - spec/spec_helper.rb