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

Love2D渲染OSM地图出现垂直压缩变形,求修正方法

解决Love2D中OSM地图垂直压缩的正确纬度转换方法

你的核心问题是误用了反墨卡托投影函数处理原始纬度,导致转换逻辑完全颠倒,这才出现高纬度区域变形的问题。下面是正确的实现步骤和代码:

1. 正确的墨卡托投影公式

墨卡托投影的核心是将地理纬度转换为等角平面坐标,正确的正向转换(从纬度到投影Y坐标)公式为:
$$ Y = \ln\left(\tan\left(\frac{\pi}{4} + \frac{\text{lat}_\text{rad}}{2}\right)\right) $$
对应的Lua实现:

-- 输入:十进制纬度lat、十进制经度lon
-- 输出:墨卡托投影后的x, y坐标
local function mercatorProject(lat, lon)
    local radLat = math.rad(lat)
    -- 计算墨卡托Y坐标
    local y = math.log(math.tan(math.pi / 4 + radLat / 2))
    -- 经度直接作为X坐标(墨卡托X与经度线性对应)
    return lon, y
end

你之前写的mercatorY函数是反墨卡托转换(把投影Y坐标转回地理纬度),用来处理原始纬度自然会导致变形。

2. 调整OSM渲染流程

修改原处理步骤,适配正确的投影逻辑:

  • 步骤1:解析XML提取nodes和ways(保持不变)
  • 步骤2:对每个node的lat和lon,用上述mercatorProject函数转换为投影后的(x, y)坐标
  • 步骤3:基于投影后的坐标计算边界框(minX, maxX, minY, maxY),再计算统一缩放因子:
    -- screenW、screenH为Love2D窗口的宽高
    local xRange = maxX - minX
    local yRange = maxY - minY
    -- 取宽高方向的最小缩放比例,保证地图完整显示且比例正确
    local scale = math.min(screenW / xRange, screenH / yRange)
    
  • 步骤4:计算坐标偏移,将投影后的坐标平移到屏幕可视区域后绘制:
    -- 先平移到以minX、minY为原点,再缩放,最后居中显示
    local offsetX = (screenW - xRange * scale) / 2 - minX * scale
    local offsetY = (screenH - yRange * scale) / 2 - minY * scale
    
    -- 绘制时应用坐标转换
    love.graphics.push()
    love.graphics.translate(offsetX, offsetY)
    love.graphics.scale(scale, scale)
    -- 遍历ways绘制线条
    for _, way in ipairs(ways) do
        local points = {}
        for _, nodeId in ipairs(way.nodeIds) do
            local node = nodes[nodeId]
            table.insert(points, node.projX)
            table.insert(points, node.projY)
        end
        love.graphics.line(points)
    end
    love.graphics.pop()
    

3. 关键注意事项

  • 墨卡托投影在纬度接近±90°时,Y坐标会趋向无穷大,若OSM文件包含极地区域,需提前裁剪边界
  • 投影后的Y坐标在南半球为负、北半球为正,缩放和平移会自动处理该符号问题,无需额外调整
  • 墨卡托是等角投影,局部形状会保持正确,但高纬度区域的面积会被放大——这是该投影的固有特性,符合OpenStreetMap的原生标准

内容的提问来源于stack exchange,提问作者darkfrei

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 07:53:25