Module: GoogleMapsApis::Polyline

Defined in:
lib/google_maps_apis/polyline.rb

Overview

Encoder/decoder for Google Encoded Polyline.

Class Method Summary collapse

Class Method Details

.decode(polyline) ⇒ Array

Decodes a Polyline string into a list of lat/lng hash.

See the developer docs for a detailed description of this encoding: https://developers.google.com/maps/documentation/utilities/polylinealgorithm

Examples:

encoded_path = '_p~iF~ps|U_ulLnnqC_mqNvxq`@'
path = GoogleMapsApis::Polyline.decode(encoded_path)
#=> [{:lat=>38.5, :lng=>-120.2}, {:lat=>40.7, :lng=>-120.95}, {:lat=>43.252, :lng=>-126.45300000000002}]

Parameters:

  • polyline (String)

    An encoded polyline

Returns:

  • (Array)

    Array of hash with lat/lng keys



22
23
24
25
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
52
53
# File 'lib/google_maps_apis/polyline.rb', line 22

def decode(polyline)
  points = []
  index = lat = lng = 0

  while index < polyline.length
    result = 1
    shift = 0
    while true
      b = polyline[index].ord - 63 - 1
      index += 1
      result += b << shift
      shift += 5
      break if b < 0x1f
    end
    lat += (result & 1) != 0 ? (~result >> 1) : (result >> 1)

    result = 1
    shift = 0
    while true
      b = polyline[index].ord - 63 - 1
      index += 1
      result += b << shift
      shift += 5
      break if b < 0x1f
    end
    lng += (result & 1) != 0 ? ~(result >> 1) : (result >> 1)

    points << {lat: lat * 1e-5, lng: lng * 1e-5}
  end

  points
end

.encode(points) ⇒ String

Encodes a list of points into a polyline string.

See the developer docs for a detailed description of this encoding: https://developers.google.com/maps/documentation/utilities/polylinealgorithm

Parameters:

  • points (Array<Hash>, Array<Array>)

    A list of lat/lng pairs.

Returns:

  • (String)


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/google_maps_apis/polyline.rb', line 63

def encode(points)
  last_lat = last_lng = 0
  result = ""

  points.each do |point|
    ll = GoogleMapsApis::Convert.normalize_latlng(point)
    lat = (ll[0] * 1e5).round.to_i
    lng = (ll[1] * 1e5).round.to_i
    d_lat = lat - last_lat
    d_lng = lng - last_lng

    [d_lat, d_lng].each do |v|
      v = (v < 0) ? ~(v << 1) : (v << 1)
      while v >= 0x20
        result += ((0x20 | (v & 0x1f)) + 63).chr
        v >>= 5
      end
      result += (v + 63).chr
    end

    last_lat = lat
    last_lng = lng
  end

  result
end