| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- export interface TileItem {
- key: string
- url: string
- x: number
- y: number
- leftPx: number
- topPx: number
- sizePx: number
- isCenter: boolean
- }
- const TILE_OVERLAP_PX = 2
- export interface TileGridOptions {
- urlTemplate: string
- zoom: number
- centerTileX: number
- centerTileY: number
- viewportWidth: number
- viewportHeight: number
- tileSize: number
- overdraw: number
- }
- export function buildTileUrl(template: string, z: number, x: number, y: number): string {
- return template
- .replace('{z}', String(z))
- .replace('{x}', String(x))
- .replace('{y}', String(y))
- }
- export function createTileGrid(options: TileGridOptions): TileItem[] {
- const tiles: TileItem[] = []
- const halfWidth = options.viewportWidth / 2
- const halfHeight = options.viewportHeight / 2
- const horizontalRange = Math.ceil(halfWidth / options.tileSize) + options.overdraw
- const verticalRange = Math.ceil(halfHeight / options.tileSize) + options.overdraw
- for (let dy = -verticalRange; dy <= verticalRange; dy += 1) {
- for (let dx = -horizontalRange; dx <= horizontalRange; dx += 1) {
- const x = options.centerTileX + dx
- const y = options.centerTileY + dy
- const rawLeft = halfWidth + (dx - 0.5) * options.tileSize
- const rawTop = halfHeight + (dy - 0.5) * options.tileSize
- tiles.push({
- key: `${options.zoom}-${x}-${y}`,
- url: buildTileUrl(options.urlTemplate, options.zoom, x, y),
- x,
- y,
- leftPx: Math.floor(rawLeft - TILE_OVERLAP_PX / 2),
- topPx: Math.floor(rawTop - TILE_OVERLAP_PX / 2),
- sizePx: Math.ceil(options.tileSize) + TILE_OVERLAP_PX,
- isCenter: dx === 0 && dy === 0,
- })
- }
- }
- return tiles
- }
|