LeafletJS: Как переворачивать плитки вертикально на лету?
Предыстория: я произвел 1-терапевтическую визуализацию набора Мандельброта и использую LeafletJS для масштабирования и перемещения по нему в интерактивном режиме. Работает отлично. Но так как набор Мандельброта симметричен вдоль действительной оси, в настоящее время я использую вдвое больше плиточных изображений, чем необходимо.
Вопрос: Как я могу подключиться к коду времени отображения LeafletJS (используя некоторый обратный вызов?), Чтобы всякий раз, когда плитка загружалась по HTTP, она либо проходила без изменений, либо переворачивалась вертикально? Это позволило бы мне уменьшить данные на многие десятки гигабайт при более высоком уровне масштабирования.
Пример: здесь четыре плитки с уровнем масштабирования 1 (показаны здесь через один пиксель). Я хотел бы выбросить два нижних изображения плитки и вместо этого загрузить их как вертикально перевернутые версии двух верхних плиток. Можно ли это сделать на лету с LeafletJS?
Конкретнее: если я знаю уровень масштабирования z и координаты элемента x, y, я бы хотел перевернуть элемент вертикально во время загрузки, если значение y меньше 2 ^ (z – 1). Например, при уровне масштабирования z = 10 я бы хотел перевернуть плитки по вертикали для всех y <512.
Я думаю, что ответ будет включать в себя что-то вроде установки transform
, -moz-transform
, -o-transform
, а также -webkit-transform
свойства <img>
тег к scaleY(-1)
и возможно filter
а также -ms-filter
в FlipV
, но я не знаю, где / как определить их в контексте LeafletJS.
1 ответ
Вам просто нужно изменить y
количество нижних плиток в L.TileLayer._loadTile
метод, прежде чем он будет применен к URL-адресу изображения.
Что касается переворачивания самого изображения, к сожалению, мы не можем использовать классы, потому что transform
Leaflet уже применяет свойство непосредственно к плиткам (изображениям), поэтому оно переопределяет любые transform
в классе. Затем мы должны добавить любой transform
, -moz-transform
и т.д. на tile.style
,
L.HalfTileLayer = L.TileLayer.extend({
_loadTile: function (tile, tilePoint) {
tile._layer = this;
tile.onload = this._tileOnLoad;
tile.onerror = this._tileOnError;
this._adjustTilePoint(tilePoint);
//////////////////
var limit = Math.pow(2, tilePoint.z - 1),
y = tilePoint.y;
if (y >= limit) { // modify for bottom tiles, i.e. higher y
tilePoint.y = 2 * limit - y - 1; // y starts at 0
tile.style.transform += " scaleY(-1)"; // append
// apply more transforms for cross-browser
}
/////////////////
tile.src = this.getTileUrl(tilePoint);
this.fire('tileloadstart', {
tile: tile,
url: tile.src
});
}
});
(new L.HalfTileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png')).addTo(map);
Демо: http://jsfiddle.net/ve2huzxw/73/
Обратите внимание, что в конфигурации по умолчанию y = 0 - это верх, y = 2^z - 1 - это низ.