You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 22:40:22