Использование Bing Maps Quadkeys в качестве источника плитки Openlayers 3

У меня есть несколько источников тайлов, которые используют систему Quadkey Bing Maps в старом приложении Silverlight, и я хотел бы использовать их в новой карте 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;
    }

Буду признателен за любое понимание, поскольку я просмотрел множество форумов и бесчисленное количество страниц результатов поиска, но не нашел решения.


person dvmac01    schedule 08.09.2015    source источник
comment
Итак, вы хотите использовать quadkeys для получения фрагментов из других источников, кроме Bing, верно?   -  person Alvin Lindstam    schedule 09.09.2015
comment
В основном да. Все URL-адреса закодированы в соответствии со вторым примером, и я читал о создании пользовательской сборки OL3, поскольку я не уверен, есть ли в последнем выпуске запеченные классы ol.TileUrlFunction и ol.tilecoord. Я не знаю Не могу распознать части tilePoint или Util.template в первом примере, что меня совершенно сбивает с толку.   -  person dvmac01    schedule 09.09.2015
comment
@AlvinLindstam, не могли бы вы помочь мне понять функцию ol.TileUrlFunction и то, как она может применяться здесь? Насколько я понимаю, чтобы использовать набор плиток, например, для Нидерландов, я должен определить протяженность плиток как широту, долготу, а затем создать функцию, в которой я даю указание источнику слоя плитки преобразовать его формулу XYZ в четырехъядерный ключ. и передайте это как URL-адрес. Нужно ли мне каким-то образом преобразовать это обратно или этого будет достаточно, чтобы правильно загрузить плитки?   -  person dvmac01    schedule 16.09.2015
comment
Смотрите мой ответ ниже. Этого должно быть достаточно. Использование EPSG:3857 (по умолчанию) и размер плитки по умолчанию, вероятно, должны быть единственными дополнительными требованиями.   -  person Alvin Lindstam    schedule 16.09.2015


Ответы (1)


Насколько я вижу, ваша функция _quadKey верна. Проблема, которая может возникнуть, связана с пониманием ol.TileCoord, предоставляемого URL-функция.

В OpenLayers 3.7 и более поздних версиях все TileCoord рассчитываются с левым верхним углом в качестве источника. Кроме того, координаты X и Y естественным образом увеличиваются, так что координаты X и Y TileCoord соответствуют обычным понятиям двумерной оси.

Верхняя левая плитка данного уровня масштабирования всегда будет иметь X=0 и Y=-1. Плитка ниже будет иметь X=0 и Y=-2; Y всегда будет отрицательным.

Некоторые картографические приложения, такие как Bing, также используют верхний левый угол в качестве исходной точки плитки, но позволяют Координата Y увеличивается вниз. Верхняя левая плитка будет X=0 и Y=0, а нижняя плитка будет X=0 и Y=1.

Чтобы рассчитать quadkeys, координата Y должна быть инвертирована и скорректирована на единицу. Это должно работать:

// 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);
        }
    })
});
person Alvin Lindstam    schedule 16.09.2015
comment
Большое спасибо Элвин. Мне еще не удалось заставить его работать, но вы сделали огромный шаг в правильном направлении. Как только он будет запущен, я опубликую свое решение для всех, кто может столкнуться с этой проблемой. Еще раз спасибо, что нашли время. - person dvmac01; 17.09.2015