tracktracker/src/front/map/index.js

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));
}
}