Skip to content

Commit

Permalink
CL-25818, Upgraded geocoder version and fixed calculate_route, lookup…
Browse files Browse the repository at this point in the history
… and autocomplete API (#5)

* CL-25743, Upgraded geocoder version and changed code accordingly

* Resolved comments and refactored code

* Adding Flexible polyline decoding logic to return route results with lat, lng
  • Loading branch information
harshaljaitpal authored Jun 30, 2022
1 parent 8f07ede commit f78ecb3
Show file tree
Hide file tree
Showing 13 changed files with 220 additions and 67 deletions.
8 changes: 4 additions & 4 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
PATH
remote: .
specs:
geocoder_here_maps (0.3.0)
geocoder (>= 1.5.1, < 1.7.0)
geocoder_here_maps (0.3.1)
geocoder (>= 1.8.0)

GEM
remote: https://rubygems.org/
specs:
diff-lcs (1.3)
geocoder (1.6.3)
geocoder (1.8.0)
rake (10.5.0)
rspec (3.8.0)
rspec-core (~> 3.8.0)
Expand All @@ -34,4 +34,4 @@ DEPENDENCIES
rspec (~> 3.0)

BUNDLED WITH
1.17.1
1.17.3
2 changes: 1 addition & 1 deletion geocoder_here_maps.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "rake", "~> 10.0"
spec.add_development_dependency "rspec", "~> 3.0"

spec.add_dependency "geocoder", ">= 1.5.1", "< 1.7.0"
spec.add_dependency "geocoder", ">= 1.8.0"
end
6 changes: 3 additions & 3 deletions lib/geocoder/lookups/concerns/here_lookup_default_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ def supported_protocols

def query_url_here_options(query)
options = {
apikey: configuration.api_key,
language: (query.language || configuration.language)
apiKey: configuration.api_key,
lang: (query.language || configuration.language)
}
end

def domain
'ls.hereapi.com'
'hereapi.com'
end
end
end
17 changes: 7 additions & 10 deletions lib/geocoder/lookups/here_calculate_route.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ def name
private

def base_query_url(query)
"#{protocol}://route.#{domain}/routing/7.2/calculateroute.json?"
"#{protocol}://router.#{domain}/v8/routes?"
end

def results(query)
return [] unless doc = fetch_data(query)
return [] unless doc["response"] && doc["response"]["route"]
return [] unless doc["routes"]

r = doc["response"]["route"]
r = doc["routes"]

if r.is_a?(Array)
return r
Expand All @@ -26,15 +26,12 @@ def results(query)
end

def query_url_params(query)
super.merge(query_url_here_options(query)).merge(
waypoints_hash(query.to_param)
)
super.merge(query_url_here_options(query))
end

def waypoints_hash(waypoints)
waypoints.each_with_object({}).with_index do |(point, hash), index|
hash["waypoint#{index}"] = point.join(',')
end
def hash_to_query(hash)
URI.encode_www_form(hash)
end

end
end
25 changes: 25 additions & 0 deletions lib/geocoder/lookups/here_lookup_id.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module Geocoder::Lookup
class HereLookupId < Base
include HereLookupDefaultMethods

def name
"HereLookupId"
end

private

def base_query_url(query)
"#{protocol}://lookup.search.#{domain}/v1/lookup?"
end

def results(query)
return [] unless item = fetch_data(query)
[item].compact.presence || []
end

def query_url_params(query)
params = {id: super[:location_id]}
params.merge(query_url_here_options(query))
end
end
end
20 changes: 10 additions & 10 deletions lib/geocoder/lookups/here_suggest.rb
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
require 'geocoder/lookups/here'

module Geocoder::Lookup
class HereSuggest < Base
include HereLookupDefaultMethods
class HereSuggest < Here

def name
"HereSuggest"
end

def handle
:here
end

private

def base_query_url(query)
"#{protocol}://autocomplete.geocoder.#{domain}/6.2/suggest.json?"
"#{protocol}://autocomplete.search.hereapi.com/v1/autocomplete?"
end

def results(query)
return [] unless doc = fetch_data(query)
return [] unless doc['suggestions']
return [] unless doc['items']

r = doc['suggestions']
r = doc['items']

if r.is_a?(Array)
return r
Expand All @@ -25,10 +30,5 @@ def results(query)
end
end

def query_url_params(query)
super.merge(query_url_here_options(query)).merge(
query: query.sanitized_text
)
end
end
end
97 changes: 97 additions & 0 deletions lib/geocoder/results/concerns/flexible_polyline_decoder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
module Geocoder::Result
class FlexiblePolylineDecoder

DECODING_TABLE = [
62, -1, -1, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, -1, -1, -1, -1, 63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
]
FORMAT_VERSION = 1

# Reserved values 4 and 5 should not be selectable
THIRD_DIM_MAP = {1=> 'level', 2=> 'altitude', 3=> 'elevation', 6=> 'custom1', 7=> 'custom2'}

def decode(encoded)
# Return an iterator over coordinates. The number of coordinates are 2 or 3 depending on the polyline content.
return unless encoded.present?
last_lat = last_lng = last_z = 0

decoder = decode_unsigned_values(encoded)
header = decode_header(decoder)

factor_degree = 10.0 ** header[:precision]
factor_z = 10.0 ** header[:third_dim_precision]
third_dim = header[:third_dim]
third_dim_key = THIRD_DIM_MAP[third_dim]

if third_dim.zero?
return decoder.each_slice(2).drop(1).map do |decoded_lat, decoded_lng|
last_lat += to_signed(decoded_lat)
last_lng += to_signed(decoded_lng)
[last_lat / factor_degree, last_lng / factor_degree]
end
else
return decoder.drop(2).each_slice(3).map do |decoded_lat, decoded_lng, decoded_z|
last_lat += to_signed(decoded_lat)
last_lng += to_signed(decoded_lng)
last_z += to_signed(decoded_z)

{ lat: (last_lat / factor_degree),
lng: (last_lng / factor_degree),
"#{third_dim_key}": (last_z / factor_z)
}
end
end
end

private

def decode_header(decoder)
# Decode the polyline header from an encoded_char. Returns a PolylineHeader object.
raise 'Invalid format version' if decoder.next != FORMAT_VERSION

value = decoder.next
precision = value & 15
value >>= 4
third_dim = value & 7
third_dim_precision = (value >> 3) & 15

{ precision: precision, third_dim: third_dim,
third_dim_precision: third_dim_precision
}
end

def decode_char(char)
# Decode a single char to the corresponding value
char_value = char.ord
DECODING_TABLE[char_value - 45]
end

def to_signed(value)
# Decode the sign from an unsigned value
value = ~value unless (value & 1).zero?
value >>= 1
end

def decode_unsigned_values(encoded)
# Return an iterator over encoded unsigned values part of an encoded polyline
result = shift = 0

Enumerator.new do |y|
encoded.each_char do |char|

value = decode_char(char)
result |= (value & 0x1F) << shift

if (value & 0x20).zero?
y << result
result = shift = 0
else
shift += 5
end
end
end
end
end
end
62 changes: 43 additions & 19 deletions lib/geocoder/results/here_calculate_route.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,46 +15,70 @@ def initialize(data)
@cache_hit = nil
end

def waypoint
@data['waypoint']
end

def leg
@data['leg']
def polyline
sections.collect { |section|
section['polyline']
}
end

def shape
@data['shape']
end

def maneuver
leg['maneuver']
sections.flat_map { |section|
FlexiblePolylineDecoder.new.decode(section['polyline'])
}
end

def mode
@data['mode']
def transport_mode
transport_data['mode']
end

def distance
summary_data['distance']
sections.sum { |section|
length(section)
}
end

def travel_time
summary_data['travelTime']
sections.sum { |section|
duration(section)
}
end

def traffic_time
summary_data['trafficTime']
sections.sum { |section|
duration(section)
}
end

def base_time
summary_data['baseTime']
sections.sum { |section|
base_duration(section)
}
end

def sections
@data['sections']
end

private # ----------------------------------------------------------------

def summary_data
@data['summary']
def duration(section)
summary_data(section)['duration']
end

def base_duration(section)
summary_data(section)['baseDuration']
end

def length(section)
summary_data(section)['length']
end

def summary_data(section)
section['summary']
end

def transport_data
@data['transport']
end
end
end
12 changes: 12 additions & 0 deletions lib/geocoder/results/here_lookup_id.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Geocoder::Result
class HereLookupId < Here

def label(format = :full)
@data['title']
end

def location_id
@data['id']
end
end
end
16 changes: 12 additions & 4 deletions lib/geocoder/results/here_suggest.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Geocoder::Result
class HereSuggest < Base
def address(format = :full)
@data['label']
def label(format = :full)
@data['title']
end

##
Expand All @@ -11,8 +11,16 @@ def coordinates
fail
end

def country_code
address_data['countryCode']
end

def country
address_data['country']
address_data['countryName']
end

def state_code
address_data['stateCode']
end

def state
Expand All @@ -32,7 +40,7 @@ def postal_code
end

def location_id
@data['locationId']
@data['id']
end

private # ----------------------------------------------------------------
Expand Down
Loading

0 comments on commit f78ecb3

Please sign in to comment.