134 lines
4.5 KiB
JavaScript
134 lines
4.5 KiB
JavaScript
/**
|
|
* @module ol/source/TileDebug
|
|
*/
|
|
|
|
import {createCanvasContext2D} from '../dom.js';
|
|
import EventType from '../events/EventType.js';
|
|
import {get as getProjection} from '../proj.js';
|
|
import {toSize} from '../size.js';
|
|
import {renderXYZTemplate} from '../uri.js';
|
|
import DataTile from './DataTile.js';
|
|
import ImageTile from './ImageTile.js';
|
|
|
|
/**
|
|
* @typedef {Object} Options
|
|
* @property {import("../proj.js").ProjectionLike} [projection='EPSG:3857'] Optional projection.
|
|
* @property {import("../tilegrid/TileGrid.js").default} [tileGrid] Tile grid.
|
|
* @property {boolean} [wrapX=true] Whether to wrap the world horizontally.
|
|
* @property {number|import("../array.js").NearestDirectionFunction} [zDirection=0]
|
|
* Set to `1` when debugging `VectorTile` sources with a default configuration.
|
|
* Choose whether to use tiles with a higher or lower zoom level when between integer
|
|
* zoom levels. See {@link module:ol/tilegrid/TileGrid~TileGrid#getZForResolution}.
|
|
* @property {import("./Tile.js").default} [source] Tile source.
|
|
* This allows `projection`, `tileGrid`, `wrapX` and `zDirection` to be copied from another source.
|
|
* If both `source` and individual options are specified the individual options will have precedence.
|
|
* @property {string} [template='z:{z} x:{x} y:{y}'] Template for labeling the tiles.
|
|
* Should include `{x}`, `{y}` or `{-y}`, and `{z}` placeholders.
|
|
* @property {string} [color='grey'] CSS color to fill text and stroke grid lines of each tile.
|
|
*/
|
|
|
|
/**
|
|
* @classdesc
|
|
* A pseudo tile source, which does not fetch tiles from a server, but renders
|
|
* a grid outline for the tile grid/projection along with the coordinates for
|
|
* each tile. See examples/canvas-tiles for an example.
|
|
* @api
|
|
*/
|
|
class TileDebug extends ImageTile {
|
|
/**
|
|
* @param {Options} [options] Debug tile options.
|
|
*/
|
|
constructor(options) {
|
|
/**
|
|
* @type {Options}
|
|
*/
|
|
options = options || {};
|
|
const template = options.template || 'z:{z} x:{x} y:{y}';
|
|
const source = options.source;
|
|
const color = options.color || 'grey';
|
|
|
|
super({
|
|
transition: 0,
|
|
wrapX:
|
|
options.wrapX !== undefined
|
|
? options.wrapX
|
|
: source !== undefined
|
|
? source.getWrapX()
|
|
: undefined,
|
|
});
|
|
|
|
const setReady = () => {
|
|
this.projection =
|
|
options.projection !== undefined
|
|
? getProjection(options.projection)
|
|
: source !== undefined
|
|
? source.getProjection()
|
|
: this.projection;
|
|
this.tileGrid =
|
|
options.tileGrid !== undefined
|
|
? options.tileGrid
|
|
: source !== undefined
|
|
? source.getTileGrid()
|
|
: this.tileGrid;
|
|
this.zDirection =
|
|
options.zDirection !== undefined
|
|
? options.zDirection
|
|
: source !== undefined
|
|
? source.zDirection
|
|
: this.zDirection;
|
|
|
|
if (source instanceof DataTile) {
|
|
this.transformMatrix = source.transformMatrix?.slice() || null;
|
|
}
|
|
|
|
const tileGrid = this.tileGrid;
|
|
if (tileGrid) {
|
|
this.setTileSizes(
|
|
tileGrid
|
|
.getResolutions()
|
|
.map((r, i) =>
|
|
toSize(tileGrid.getTileSize(i)).map((s) =>
|
|
Math.max(Math.floor(s), 1),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
this.setLoader((z, x, y, loaderOptions) => {
|
|
const text = renderXYZTemplate(template, z, x, y, loaderOptions.maxY);
|
|
const [width, height] = this.getTileSize(z);
|
|
const context = createCanvasContext2D(width, height);
|
|
|
|
context.strokeStyle = color;
|
|
context.strokeRect(0.5, 0.5, width + 0.5, height + 0.5);
|
|
|
|
context.fillStyle = color;
|
|
context.strokeStyle = 'white';
|
|
context.textAlign = 'center';
|
|
context.textBaseline = 'middle';
|
|
context.font = '24px sans-serif';
|
|
context.lineWidth = 4;
|
|
context.strokeText(text, width / 2, height / 2, width);
|
|
context.fillText(text, width / 2, height / 2, width);
|
|
// make the loader aysnc, so it behaves like other sources that fetch data from a remote server
|
|
return Promise.resolve(context.canvas);
|
|
});
|
|
this.setState('ready');
|
|
};
|
|
|
|
if (source === undefined || source.getState() === 'ready') {
|
|
setReady();
|
|
} else {
|
|
const handler = () => {
|
|
if (source.getState() === 'ready') {
|
|
source.removeEventListener(EventType.CHANGE, handler);
|
|
setReady();
|
|
}
|
|
};
|
|
source.addEventListener(EventType.CHANGE, handler);
|
|
}
|
|
}
|
|
}
|
|
|
|
export default TileDebug;
|