lualua-5.1

Google Algorithm to encode polyline in lua5.1


I need to create lua script to encode polyline coordinates using google maps polyline encoding algorithm. This has to be for lua5.1 as the it is intended to be run inside Redis which is equipped with lua5.1. The following code is based on google golang equivalent. https://github.com/googlemaps/google-maps-services-go/blob/master/polyline.go

-- Encode a polyline in Google Maps format
function Encode(path)
  local prevLat, prevLng = 0, 0
  local out = ""

  for _, point in ipairs(path) do
    local lat = math.floor(point.Lat * 1e5)
    local lng = math.floor(point.Lng * 1e5)

    out = out .. encodeInt(lat - prevLat)
    out = out .. encodeInt(lng - prevLng)

    prevLat, prevLng = lat, lng
  end

  return out
end

-- Encode an int64 value in Google Maps format
function encodeInt(v)
  print(v)
  if v < 0 then
    v = bit.bxor(bit.lshift(v, 1), 0xffffffff)
  else
    v = bit.lshift(v, 1)
  end

  local encoded_num = ""
  while v >= 0x20 do
    encoded_num = encoded_num .. string.char(0x20 + (bit.band(v, 0x1f)) + 63)
    v = bit.rshift(v, 5)
  end
  encoded_num = encoded_num .. string.char(v + 63)
  return encoded_num
end

local path = { { Lat = 38.5, Lng = -120.2 }, { Lat = 40.7, Lng = -120.95 }, { Lat = 43.252, Lng = -126.453 } }
local encoded_polyline = Encode(path)
print(encoded_polyline) 
-- should output: _p~iF~ps|U_ulLnnqC_mqNvxq`@

However it outputs this error: lua:2: attempt to index global 'bit' (a nil value) It seems that bit is not available for lua5.1!.


Solution

  •   if v < 0 then
        v = bit.bxor(bit.lshift(v, 1), 0xffffffff)
      else
        v = bit.lshift(v, 1)
      end
    

    is equivalent to

      v = v < 0 and -1 - 2*v or 2*v
    

    You can also replace bit.band(v, 0x1f) with v % 32
    and bit.rshift(v, 5) with (v - v%32)/32