97 lines
2.7 KiB
JavaScript
97 lines
2.7 KiB
JavaScript
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.<callable>} 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));
|
|
}
|
|
}
|