import "maplibre-gl/dist/maplibre-gl.css"; import * as maplibre from "maplibre-gl"; import * as network from "./network"; import * as vehicles from "./vehicles"; import style from "./assets/style.json"; const mapId = "c1309cde-1b6e-4c9b-8b65-48512757d354"; const mapKey = "6T8Cb9oYBFeDjDhpmNmd"; style.sources.openmaptiles.url = style.sources.openmaptiles.url.replace("{key}", mapKey); style.glyphs = style.glyphs.replace("{key}", mapKey); const bounds = [ "3.660507202148437", "43.49552248630757", "4.092750549316406", "43.73736766145917", ]; export default class Map { /** * Instantiate a map. * @param {string|HTMLElement} target The container to add the map to. * @param {Object} simstate Course simulation state. * @param {Object.} handlers Handlers for the map events. */ constructor(target, simstate, handlers) { this.renderer = new maplibre.Map({ container: target, style, bounds, maplibreLogo: true, maxPitch: 70, }); this.renderer.addControl(new maplibre.NavigationControl()); this.renderer.on("load", () => { network.addLayers(this.renderer); vehicles.addLayers(this.renderer, handlers); // Move 3D buildings to the front of custom layers this.renderer.moveLayer("building-3d"); this.start(); }); // ID of the currently selected course this.selectedCourse = null; this.animation = null; this.simstate = simstate; this.handlers = handlers; } /** Start animating vehicles on the map. */ start() { this._animate(); } /** Stop the vehicle animation. */ stop() { cancelAnimationFrame(this.animation); this.animation = null; } /** * Select or unselect a vehicle. * @param {string?} id The ID of the vehicle to select, or null to unselect. */ select(courseId) { this.selectedCourse = courseId; const course = this.simstate.courses[courseId]; this.renderer.flyTo({ center: course.geometry.coordinates, bearing: course.properties.bearing, pitch: 60, zoom: 20, }); } _animate() { this.simstate.update(); vehicles.update(this.renderer, this.simstate.courses); if (this.selectedCourse !== null && !this.renderer.isMoving()) { const course = this.simstate.courses[this.selectedCourse]; this.renderer.jumpTo({ center: course.geometry.coordinates, bearing: course.properties.bearing, }); } this.animation = requestAnimationFrame(this._animate.bind(this)); } }