如何为平面 1:1 像素坐标系配置 Openlayers?
How to configure Openlayers for a flat 1:1 pixel coordinate system?
我正在尝试为激战 2 游戏构建地图,但无法让 openlayers 正确处理坐标系并完整渲染地图。
这是我所拥有的fiddle:https://jsfiddle.net/ndqb8rqx/
Guild Wars 世界是方形的,在两个轴上都是 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没有渲染完整的地图。该地图实际上比 fiddle 显示的更向南和向东延伸。 fiddle 中实际显示的右下角实际上是 [32768, 32768]
,但地图延伸到 [49152, 49152]
。当完全缩小时,openlayers 似乎只是将坐标系缩小到单个图块的区域。相反,我希望坐标与像素匹配 1:1。
另一个问题是目前y坐标在北方向增加。我想反转y轴,使y坐标向南方向增加。
完成这项工作的关键是自定义图块网格定义,即具有正确的范围和最大缩放:
var tilegrid = new ol.tilegrid.createXYZ({
extent: gw2Projection.getExtent(),
maxZoom: 7
});
然后使用该图块网格配置 XYZ 源:
source: new ol.source.XYZ({
url: 'https://tiles.guildwars2.com/1/1/{z}/{x}/{y}.jpg',
projection: gw2Projection,
tileGrid: tilegrid
})
还使用该图块网格的分辨率配置视图:
view: new ol.View({
center: ol.extent.getCenter(gw2Projection.getExtent()),
extent: gw2Projection.getExtent(),
zoom: 1,
resolutions: tilegrid.getResolutions()
}
我创建了一个更新的 fiddle,使您的地图可以正常工作:https://jsfiddle.net/kay99yor/。
@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轴仍然是负数。
这是一个 fiddle 的结果,我还包含了 TileDebug 层作为很好的衡量标准:https://jsfiddle.net/kay99yor/1/
我正在尝试为激战 2 游戏构建地图,但无法让 openlayers 正确处理坐标系并完整渲染地图。
这是我所拥有的fiddle:https://jsfiddle.net/ndqb8rqx/
Guild Wars 世界是方形的,在两个轴上都是 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没有渲染完整的地图。该地图实际上比 fiddle 显示的更向南和向东延伸。 fiddle 中实际显示的右下角实际上是 [32768, 32768]
,但地图延伸到 [49152, 49152]
。当完全缩小时,openlayers 似乎只是将坐标系缩小到单个图块的区域。相反,我希望坐标与像素匹配 1:1。
另一个问题是目前y坐标在北方向增加。我想反转y轴,使y坐标向南方向增加。
完成这项工作的关键是自定义图块网格定义,即具有正确的范围和最大缩放:
var tilegrid = new ol.tilegrid.createXYZ({
extent: gw2Projection.getExtent(),
maxZoom: 7
});
然后使用该图块网格配置 XYZ 源:
source: new ol.source.XYZ({
url: 'https://tiles.guildwars2.com/1/1/{z}/{x}/{y}.jpg',
projection: gw2Projection,
tileGrid: tilegrid
})
还使用该图块网格的分辨率配置视图:
view: new ol.View({
center: ol.extent.getCenter(gw2Projection.getExtent()),
extent: gw2Projection.getExtent(),
zoom: 1,
resolutions: tilegrid.getResolutions()
}
我创建了一个更新的 fiddle,使您的地图可以正常工作:https://jsfiddle.net/kay99yor/。
@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轴仍然是负数。
这是一个 fiddle 的结果,我还包含了 TileDebug 层作为很好的衡量标准:https://jsfiddle.net/kay99yor/1/