import L, { Bounds, LatLng, Point } from 'leaflet' export const TileSize = 100 export const HnHMaxZoom = 6 export const HnHMinZoom = 1 export const HnHDefaultZoom = 6 export interface ImageIconOptions extends L.IconOptions { /** When the main icon image fails to load, use this URL (e.g. data URL or default marker). */ fallbackIconUrl?: string } export const ImageIcon = L.Icon.extend({ options: { iconSize: [32, 32], iconAnchor: [16, 16], } as ImageIconOptions, createIcon(oldIcon?: HTMLElement): HTMLElement { const img = L.Icon.prototype.createIcon.call(this, oldIcon) as HTMLImageElement const fallback = (this.options as ImageIconOptions).fallbackIconUrl if (fallback && img && img.tagName === 'IMG') { img.onerror = () => { img.onerror = null img.src = fallback } } return img }, }) as unknown as new (options?: ImageIconOptions) => L.Icon const latNormalization = (90.0 * TileSize) / 2500000.0 const lngNormalization = (180.0 * TileSize) / 2500000.0 const HnHProjection = { project(latlng: LatLng) { return new Point(latlng.lat / latNormalization, latlng.lng / lngNormalization) }, unproject(point: Point) { return new LatLng(point.x * latNormalization, point.y * lngNormalization) }, bounds: (() => new Bounds([-latNormalization, -lngNormalization], [latNormalization, lngNormalization]))(), } export const HnHCRS = L.extend({}, L.CRS.Simple, { projection: HnHProjection, }) as L.CRS