我在一个旧的Silverlight应用程序中使用了Bing Maps的Quadkey系统,我想在一个新的Openlayers 3地图中使用它们。
我发现了几个函数的例子,这些函数将转换这些源为Leaflet.js,但语法对于OL3有些不同,通过阅读API文档表明有一个ol.Tile.coord类,但如果我理解正确,这是一个实验性的功能,可能需要从源代码中自定义构建。
在GitHub页面上有这样的功能参考,但我不知道我是否必须用这个源编译一个构建:https://github.com/openlayers/ol3/blob/5c5364bbb7e8df76f18242ad665c87ca08a76e76/src/ol/source/bingmapssource.js
谁能提供这种类型的转换的例子,或者确实有人知道是否最新的(3.8.2)版本的OL3支持quadkey方法?
这是传单的例子:
var BingLayer = L.TileLayer.extend({
getTileUrl: function (tilePoint) {
this._adjustTilePoint(tilePoint);
return L.Util.template(this._url, {
s: this._getSubdomain(tilePoint),
q: this._quadKey(tilePoint.x, tilePoint.y, this._getZoomForUrl())
});
},
_quadKey: function (x, y, z) {
var quadKey = [];
for (var i = z; i > 0; i--) {
var digit = '0';
var mask = 1 << (i - 1);
if ((x & mask) != 0) {
digit++;
}
if ((y & mask) != 0) {
digit++;
digit++;
}
quadKey.push(digit);
}
return quadKey.join('');
}
});
这是现有的Silverlight代码:
public override Uri GetUri(int x, int y, int zoomLevel, bool getPrintLink)
{
Uri uri = null;
if (this.Covers(x, y, zoomLevel))
{
QuadKey qk = new QuadKey(x, y, zoomLevel);
if (getPrintLink)
{
uri = new Uri(this.CurrentHostURL + "/tiles/NL/" + zoomLevel.ToString() + "/" + qk.Key + ".ipic", UriKind.RelativeOrAbsolute);
}
else
{
uri = new Uri("http://tileserver.satmap.com/NL/" + zoomLevel.ToString() + "/" + qk.Key + ".ipic", UriKind.RelativeOrAbsolute);
}
}
return uri;
}
任何见解将是感激的,因为我已经拖网了许多论坛和无数页面的搜索结果没有找到一个解决方案。
据我所知,您的_quadKey函数是正确的。可能出现的问题是理解提供给URL函数的ol.TileCoord
。
在OpenLayers 3.7及以后的版本中,所有的TileCoord
都是以左上角作为原点计算的。此外,X和Y坐标都自然增加,因此TileCoord的X和Y坐标对应于二维轴的正常概念。
给定缩放级别的左上角贴图将始终具有X=0和Y=-1。下面的贴图将有X=0和Y=-2;Y总是负的
一些地图应用程序,如Bing,也使用左上角作为贴图原点,但让Y坐标向下增加。左上角的贴图将是X=0和Y=0,而下面的贴图将是X=0和Y=1。
为了计算四键,Y坐标必须倒转并调整1。这应该可以工作:
// this is unchanged from the question
var quadkey = function (x, y, z) {
var quadKey = [];
for (var i = z; i > 0; i--) {
var digit = '0';
var mask = 1 << (i - 1);
if ((x & mask) != 0) {
digit++;
}
if ((y & mask) != 0) {
digit++;
digit++;
}
quadKey.push(digit);
}
return quadKey.join('');
};
var quadKeyLayer = new ol.layer.Tile({
source: new ol.source.XYZ({
maxZoom: 19,
tileUrlFunction: function (tileCoord, pixelRatio, projection) {
var z = tileCoord[0];
var x = tileCoord[1];
var y = -tileCoord[2] - 1;
return "//example.com/r" + quadkey(x, y, z);
}
})
});