使用 Bing Maps Quadkeys 作为 Openlayers 3 Tile 源

Posted

技术标签:

【中文标题】使用 Bing Maps Quadkeys 作为 Openlayers 3 Tile 源【英文标题】:Using Bing Maps Quadkeys as Openlayers 3 Tile source 【发布时间】:2015-09-08 09:36:11 【问题描述】:

我有许多在旧 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 是否支持四键方法?

这是传单示例:

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;
    

任何见解都将不胜感激,因为我在许多论坛和无数页的搜索结果中都没有找到解决方案。

【问题讨论】:

所以您想使用四键从 Bing 以外的其他来源获取图块,对吧? 基本上是的。所有 url 都按照第二个示例进行编码,我一直在阅读有关创建 OL3 的自定义构建的内容,因为我不确定最新版本是否包含 ol.TileUrlFunction 和 ol.tilecoord 类。我没有t 识别第一个示例的 tilePoint 或 Util.template 部分,这完全让我感到震惊。 @AlvinLindstam,你能帮我理解 ol.TileUrlFunction 以及它如何在这里应用吗?据我了解,例如,要为荷兰使用一组图块,我应该将图块的范围定义为纬度、经度,然后创建一个函数,在其中指示图块层源将其 XYZ 公式转换为四键并将其作为 url 传递。我需要以某种方式将其转换回来还是足以正确加载图块? 在下面查看我的答案。这应该足够了。使用EPSG:3857(默认)和默认的磁贴大小应该是唯一的附加要求。 【参考方案1】:

据我所知,您的 _quadKey 函数是正确的。可能出现的问题是理解提供给 URL 函数的ol.TileCoord

在 OpenLayers 3.7 及更高版本中,所有TileCoords 都以左上角为原点进行计算。此外,X 和 Y 坐标都自然增加,因此 TileCoord 的 X 和 Y 坐标对应于二维轴的正常概念。

给定缩放级别的左上图块将始终具有 X=0 和 Y=-1。下面的瓷砖将有 X=0 和 Y=-2; Y 永远是负数。

一些地图应用程序,例如必应,也使用左上角作为图块原点,但让Y coordinate increase downwards。左上的图块是 X=0 和 Y=0,而下面的图块是 X=0 和 Y=1。

为了计算四键,Y 坐标必须反转并调整一。 This should work:

// 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);
        
    )
);

【讨论】:

非常感谢阿尔文。我还没有完全让它工作,但你已经朝着正确的方向迈出了一大步。一旦它启动并运行,我将为可能遇到此问题的其他任何人发布我的解决方案。再次感谢您抽出宝贵时间。

以上是关于使用 Bing Maps Quadkeys 作为 Openlayers 3 Tile 源的主要内容,如果未能解决你的问题,请参考以下文章

Bing Maps Geographic Coverage - Bing地图图像覆盖范围

使用 Bing 或 Google Maps API 获取用户的位置(纬度、经度)

Bing Maps API - SQL - 几何与地理类型

Win8.1应用开发之Bing Maps

Bing Maps必应地图

HTML Bing Maps AJAX控件7.0:可拖动的Pushpins