maplair
Version:
JavaScript library for mobile-friendly interactive maps
139 lines (138 loc) • 4.78 kB
JavaScript
import { falseFn, setOptions, template } from "../../core/Util.js";
import Browser_default from "../../core/Browser.js";
import { on } from "../../dom/DomEvent.js";
import { I18n } from "../../core/I18n.js";
import { GridLayer } from "./GridLayer.js";
//#region src/layer/tile/TileLayer.js
var TileLayer = class TileLayer extends GridLayer {
static {
this.setDefaultOptions({
minZoom: 0,
maxZoom: 18,
subdomains: "abc",
errorTileUrl: "",
zoomOffset: 0,
tms: false,
zoomReverse: false,
detectRetina: false,
crossOrigin: false,
referrerPolicy: "strict-origin-when-cross-origin"
});
}
constructor(url, options) {
super(options);
this._url = url;
options = setOptions(this, options);
const tileUrl = new URL(this._url, location.href);
const urlHostname = tileUrl.hostname;
if (["tile.openstreetmap.org", "tile.osm.org"].some((host) => urlHostname.endsWith(host))) {
if (options.attribution === null) options.attribution = `© <a href="https://www.openstreetmap.org/copyright">${I18n.translate("OpenStreetMap contributors")}</a>`;
if (tileUrl.protocol === "http:") {
tileUrl.protocol = "https:";
this._url = tileUrl.toString();
}
}
if (this.options.detectRetina && Browser_default.retina && this.options.maxZoom > 0) {
this.options.tileSize = Math.floor(this.options.tileSize / 2);
if (!this.options.zoomReverse) {
this.options.zoomOffset++;
this.options.maxZoom = Math.max(this.options.minZoom, this.options.maxZoom - 1);
} else {
this.options.zoomOffset--;
this.options.minZoom = Math.min(this.options.maxZoom, this.options.minZoom + 1);
}
this.options.minZoom = Math.max(0, this.options.minZoom);
} else if (!this.options.zoomReverse) this.options.maxZoom = Math.max(this.options.minZoom, this.options.maxZoom);
else this.options.minZoom = Math.min(this.options.maxZoom, this.options.minZoom);
if (typeof this.options.subdomains === "string") this.options.subdomains = this.options.subdomains.split("");
this.on("tileunload", this._onTileRemove);
this.callInitHooks(TileLayer);
}
setUrl(url, noRedraw) {
if (this._url === url && noRedraw === void 0) noRedraw = true;
this._url = url;
if (!noRedraw) this.redraw();
return this;
}
createTile(coords, done) {
const tile = document.createElement("img");
on(tile, "load", this._tileOnLoad.bind(this, done, tile));
on(tile, "error", this._tileOnError.bind(this, done, tile));
if (this.options.crossOrigin || this.options.crossOrigin === "") tile.crossOrigin = this.options.crossOrigin === true ? "" : this.options.crossOrigin;
if (typeof this.options.referrerPolicy === "string") tile.referrerPolicy = this.options.referrerPolicy;
tile.alt = "";
tile.src = this.getTileUrl(coords);
return tile;
}
getTileUrl(coords) {
const data = Object.create(this.options);
Object.assign(data, {
r: Browser_default.retina ? "@2x" : "",
s: this._getSubdomain(coords),
x: coords.x,
y: coords.y,
z: this._getZoomForUrl()
});
if (this._map && !this._map.options.crs.infinite) {
const invertedY = this._globalTileRange.max.y - coords.y;
if (this.options.tms) data["y"] = invertedY;
data["-y"] = invertedY;
}
return template(this._url, data);
}
_tileOnLoad(done, tile) {
done(null, tile);
}
_tileOnError(done, tile, e) {
const errorUrl = this.options.errorTileUrl;
if (errorUrl && tile.getAttribute("src") !== errorUrl) tile.src = errorUrl;
done(e, tile);
}
_onTileRemove(e) {
e.tile.onload = null;
}
_getZoomForUrl() {
let zoom = this._tileZoom;
const maxZoom = this.options.maxZoom, zoomReverse = this.options.zoomReverse, zoomOffset = this.options.zoomOffset;
if (zoomReverse) zoom = maxZoom - zoom;
return zoom + zoomOffset;
}
_getSubdomain(tilePoint) {
const index = Math.abs(tilePoint.x + tilePoint.y) % this.options.subdomains.length;
return this.options.subdomains[index];
}
_abortLoading() {
let i, tile;
for (i of Object.keys(this._tiles)) if (this._tiles[i].coords.z !== this._tileZoom) {
tile = this._tiles[i].el;
tile.onload = falseFn;
tile.onerror = falseFn;
if (!tile.complete) {
tile.setAttribute("src", "");
const coords = this._tiles[i].coords;
tile.remove();
delete this._tiles[i];
this.fire("tileabort", {
tile,
coords
});
}
}
}
_removeTile(key) {
const tile = this._tiles[key];
if (!tile) return;
tile.el.setAttribute("src", "");
return super._removeTile(key);
}
_tileReady(coords, err, tile) {
if (!this._map || tile && tile.getAttribute("src") === "") return;
return super._tileReady(coords, err, tile);
}
_clampZoom(zoom) {
return Math.round(super._clampZoom(zoom));
}
};
//#endregion
export { TileLayer };
//# sourceMappingURL=TileLayer.js.map