【问题标题】:How to configure Openlayers for a flat 1:1 pixel coordinate system?如何为平面 1:1 像素坐标系配置 Openlayers?
【发布时间】:2017-12-02 20:58:00
【问题描述】:

我正在尝试为游戏激战 2 构建地图,但无法让 openlayers 正确处理坐标系并完全渲染地图。

这是我所拥有的小提琴:https://jsfiddle.net/ndqb8rqx/

激战世界是正方形的,两个轴上的像素都是 49152 像素。坐标的原点 ([0, 0]) 应该是西北。东南应该是[49152, 49152]。游戏开发者将地图图块作为服务提供:https://wiki.guildwars2.com/wiki/API:Tile_service

我基于 Zoomify 创建了一个Projection 来尝试处理这个问题:

var gw2Projection = new ol.proj.Projection({
  code: 'ZOOMIFY',
  units: 'pixels',
  extent: [0, -49152, 49152, 0]
})

我还从 XYZ 源将游戏图块添加为 Tilelayer,如下所示:

new ol.layer.Tile({
  source: new ol.source.XYZ({
    url: 'https://tiles.guildwars2.com/1/1/{z}/{x}/{y}.jpg',
    projection: gw2Projection
  }),
}),

第一个问题是 openlayers 没有渲染完整的地图。地图实际上比小提琴显示的更南和更东。小提琴中实际显示的右下边缘实际上是[32768, 32768],但地图延伸到[49152, 49152]。当完全缩小时,openlayers 似乎只是将坐标系缩小到单个图块的区域。相反,我希望坐标与像素 1:1 匹配。

另外一个问题是目前y坐标向北增加。我想反转 y 轴,使 y 坐标向南增加。

【问题讨论】:

    标签: javascript openlayers


    【解决方案1】:

    @ahocevar 将我推向了正确的方向。创建自定义 tilegrid 的建议是必要的,但不是设置缩放级别,而是设置实际分辨率。

    所以通过添加这样的 tilegrid:

    var tilegrid = new ol.tilegrid.TileGrid({
      extent: extent,
      resolutions: [128, 64, 32, 16, 8, 4, 2, 1]
    });
    

    像这样在图层源中使用它:

    source: new ol.source.XYZ({
      tileGrid: tilegrid,
      url: 'https://tiles.guildwars2.com/1/1/{z}/{x}/{y}.jpg',
      projection: gw2Projection
    }),
    

    最后也将它添加到视图中:

    view: new ol.View({
      center: ol.extent.getCenter(extent),
      zoom: 1,
      projection: gw2Projection,
      extent:extent,
      resolutions: tilegrid.getResolutions()
    })
    

    现在显示了整个地图,并且坐标正确。 Y 轴仍然是负数。

    这是对结果的修改,我还包括了 TileDebug 层以更好地衡量:https://jsfiddle.net/kay99yor/1/

    【讨论】:

    • 我已经尝试解决这个问题将近一周了。谢谢你! :)
    【解决方案2】:

    完成这项工作的关键是自定义平铺网格定义,即具有正确的范围和最大缩放:

    var tilegrid = new ol.tilegrid.createXYZ({
      extent: gw2Projection.getExtent(),
      maxZoom: 7
    });
    

    然后使用该 tilegrid 配置 XYZ 源:

    source: new ol.source.XYZ({
      url: 'https://tiles.guildwars2.com/1/1/{z}/{x}/{y}.jpg',
      projection: gw2Projection,
      tileGrid: tilegrid
    })
    

    同时使用该 tilegrid 的分辨率配置视图:

    view: new ol.View({
      center: ol.extent.getCenter(gw2Projection.getExtent()),
      extent: gw2Projection.getExtent(),
      zoom: 1,
      resolutions: tilegrid.getResolutions()
    }
    

    我创建了一个更新的小提琴,使您的地图工作:https://jsfiddle.net/kay99yor/

    【讨论】:

    • 谢谢你的回答,但不幸的是我真的看不出有什么不同?坐标还是一样,y轴方向还是一样的,地图缺失的部分还是没有显示出来。我能看到的唯一区别是您将视图置于地图的中心。
    猜你喜欢
    • 1970-01-01
    • 2011-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-14
    相关资源
    最近更新 更多