ptitlutins/app/services/mapService.ts
2026-06-15 23:34:49 +02:00

45 lines
1.4 KiB
TypeScript

import type { OsmMap } from "esquisse"
/** The project's shared vector base style (Positron over the France pmtiles). */
const BASE_STYLE_URL =
"https://static.ppsfleet.navy/osm-data/styles/positron.json"
export interface MapView {
center: [number, number]
zoom: number
}
/**
* Build the interactive base map inside `container`.
*
* This is the only place that knows about the map library and the tile
* transport (esquisse + MapLibre + pmtiles) — the rendering layer never touches
* them. The libraries are imported lazily so they stay out of the server bundle:
* MapLibre needs a WebGL/DOM context that only exists in the browser.
*
* Returns the map instance, or `null` if it could not be created, so the caller
* shows an error state rather than letting an exception crash the UI.
*/
export async function createBaseMap(
container: HTMLElement,
view: MapView,
): Promise<OsmMap | null> {
try {
const [maplibreModule, pmtiles, { createMap }] = await Promise.all([
import("maplibre-gl"),
import("pmtiles"),
import("esquisse"),
])
return createMap({
maplibre: maplibreModule.default,
pmtiles,
container,
baseStyle: BASE_STYLE_URL,
center: view.center,
zoom: view.zoom,
})
} catch (error) {
console.error("createBaseMap: could not initialise the map", error)
return null
}
}