Lua5.1(Redis环境)下Google Maps折线编码脚本报错求助
解决Redis中Lua5.1编写Google Maps折线编码时的bit库缺失问题
Redis内置的Lua5.1环境没有默认提供bit标准库,直接调用bit.lshift、bit.rshift这类函数会触发attempt to index global 'bit' (a nil value)错误。解决办法是用纯Lua代码模拟折线编码所需的位操作,完全不需要依赖外部库。
第一步:实现替代bit库的核心函数
折线编码仅用到左移、右移、按位与这几个位操作,纯Lua实现如下:
-- 模拟bit.lshift(左移) local function bit_lshift(x, n) return x * (2 ^ n) end -- 模拟无符号右移(对应bit.rshift) local function bit_rshift(x, n) return math.floor(x / (2 ^ n)) end -- 模拟bit.band(按位与) local function bit_band(x, y) local result = 0 local current_bit = 1 while x > 0 or y > 0 do if x % 2 == 1 and y % 2 == 1 then result = result + current_bit end x = math.floor(x / 2) y = math.floor(y / 2) current_bit = current_bit * 2 end return result end
第二步:编写完整的折线编码脚本
基于上述函数,实现符合Google Maps规则的折线编码核心逻辑(替换原代码中依赖bit库的部分):
-- 先定义替代bit库的函数 local function bit_lshift(x, n) return x * (2 ^ n) end local function bit_rshift(x, n) return math.floor(x / (2 ^ n)) end local function bit_band(x, y) local result = 0 local current_bit = 1 while x > 0 or y > 0 do if x % 2 == 1 and y % 2 == 1 then result = result + current_bit end x = math.floor(x / 2) y = math.floor(y / 2) current_bit = current_bit * 2 end return result end -- 折线编码核心函数 function encode_polyline(coords) local encoded = "" local prev_lat, prev_lng = 0, 0 for _, coord in ipairs(coords) do local lat = coord[1] local lng = coord[2] -- 计算坐标差并放大1e5倍(Google编码要求) local delta_lat = math.floor((lat - prev_lat) * 100000 + 0.5) local delta_lng = math.floor((lng - prev_lng) * 100000 + 0.5) -- 编码单个坐标差 local function encode_delta(delta) delta = delta < 0 and bit_band(bit_lshift(-delta, 1), 0xFFFFFFFF) or bit_lshift(delta, 1) while delta > 0 do local chunk = bit_band(delta, 0x1F) delta = bit_rshift(delta, 5) if delta > 0 then chunk = chunk + 0x20 end encoded = encoded .. string.char(chunk + 63) end end encode_delta(delta_lat) encode_delta(delta_lng) prev_lat = lat prev_lng = lng end return encoded end -- 示例调用(Redis中可通过redis.call返回结果) -- local test_coords = {{38.5, -120.2}, {40.7, -120.95}, {43.252, -126.453}} -- return encode_polyline(test_coords)
注意事项
- Lua的数值是双精度浮点数,处理极大坐标差时可能出现精度损失,但折线编码的坐标差通常不会超出双精度整数的精确范围(2^53以内),实际使用足够可靠。
- 代码中
encode_delta函数已通过位操作模拟了符号反转逻辑,完全符合Google的编码规则。
内容的提问来源于stack exchange,提问作者Sami Al-Subhi
相关产品推荐
相关产品推荐

