Show course informations in side pane

This commit is contained in:
Mattéo Delabre 2020-07-27 21:01:36 +02:00
parent fe08c42920
commit d9869ce2f7
Signed by: matteo
GPG Key ID: AE3FBD02DC583ABB
3 changed files with 105 additions and 46 deletions

View File

@ -7,21 +7,31 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<style>
body, html
{
body, html {
padding: 0;
margin: 0;
height: 100%;
}
#map
{
body {
display: flex;
flex-direction: row;
}
#informations {
flex: 0 0 600px;
padding: 20px;
overflow-y: auto;
}
#map {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="informations"></div>
<div id="map"></div>
<script src="index.js"></script>
</body>

View File

@ -1,6 +1,89 @@
// eslint-disable-next-line node/no-extraneous-require
require("regenerator-runtime/runtime");
const network = require("../tam/network.json");
const simulation = require("../tam/simulation");
const map = require("./map/index.js");
map.create(/* map = */ "map");
// Run courses simulation
const coursesSimulation = simulation.start();
global.courses = coursesSimulation.courses;
const informations = document.querySelector("#informations");
let courseId = null;
const displayTime = date => [
date.getHours(),
date.getMinutes(),
date.getSeconds()
].map(number => number.toString().padStart(2, '0')).join(':');
setInterval(() => {
let html = `
<dl>
<dt>Heure actuelle</dt>
<dd>${displayTime(new Date())}</dd>
</dl>
`;
if (courseId !== null && courseId in coursesSimulation.courses) {
const course = coursesSimulation.courses[courseId];
const timeToHTML = time => Math.ceil((time - Date.now()) / 1000);
const stopToHTML = stopId => network.stops[stopId].properties.name;
const passingsToHTML = passings => passings.map(([stopId, time]) => `
<tr>
<td>${stopToHTML(stopId)}</td>
<td>${displayTime(new Date(time))}</td>
</tr>
`).join('\n');
html += `
<dl>
<dt>ID</dt>
<dd>${courseId}</dd>
<dt>Ligne</dt>
<dd>${course.line}</dd>
<dt>Destination</dt>
<dd>${stopToHTML(course.finalStop)}</dd>
<dt>État</dt>
<dd>${course.state === 'moving'
? `Entre ${stopToHTML(course.departureStop)}
et ${stopToHTML(course.arrivalStop)}`
: `À larrêt ${stopToHTML(course.currentStop)}`}</dd>
${course.state === 'moving' ? `
<dt>Arrivée dans</dt>
<dd>${timeToHTML(course.arrivalTime)} s</dd>
<dt>Distance parcourue</dt>
<dd>${Math.ceil(course.traveledDistance)} m</dd>
<dt>Vitesse</dt>
<dd>${Math.ceil(course.speed * 3600)} km/h</dd>
` : `
<dt>Départ dans</dt>
<dd>${timeToHTML(course.departureTime)} s</dd>
`}
</dl>
<h2>Arrêts précédents</h2>
<table>${passingsToHTML(course.prevPassings)}</table>
<h2>Arrêts suivants</h2>
<table>${passingsToHTML(course.nextPassings)}</table>
`;
}
informations.innerHTML = html;
}, 1000);
// Create the network and courses map
map.create(/* map = */ "map", coursesSimulation, course => {
courseId = course;
});

View File

@ -9,7 +9,6 @@ const tilesLayers = require("./tiles");
const networkLayers = require("./network");
const { sizes, makeBorderColor, makeCourseColor } = require("./common");
const network = require("../../tam/network.json");
const simulation = require("../../tam/simulation");
const courseStyles = {};
@ -59,7 +58,7 @@ const getCourseStyle = lineColor => {
return courseStyles[lineColor];
};
const create = target => {
const create = (target, coursesSimulation, onClick) => {
const view = new View({
center: proj.fromLonLat([3.88, 43.605]),
zoom: 14,
@ -78,32 +77,9 @@ const create = target => {
const stopsLayer = map.getLayers().item(3);
// Run courses simulation
const simulInstance = simulation.start();
// Course on which the view is currently focused
let focusedCourse = null;
const startFocus = courseId => {
if (courseId in simulInstance.courses) {
const course = simulInstance.courses[courseId];
view.animate({
center: course.position,
duration: 500
}, () => {
focusedCourse = courseId;
});
}
};
const stopFocus = () => {
focusedCourse = null;
};
// Draw courses directly on the map
map.on("postcompose", ev => {
simulInstance.update();
coursesSimulation.update();
// The normal way to access a layers vector context is through the
// `postrender` event of that layer. However, `postrender` is not
@ -121,7 +97,8 @@ const create = target => {
const ctx = getVectorContext(ev);
for (const course of Object.values(simulInstance.courses)) {
for (const course of Object.values(coursesSimulation.courses)) {
const point = new Point(course.position);
const color = network.lines[course.line].color;
const style = getCourseStyle(color);
@ -131,14 +108,7 @@ const create = target => {
);
ctx.setStyle(style);
const point = new Point(course.position);
ctx.drawGeometry(point);
if (course.id === focusedCourse) {
view.setCenter(course.position);
}
}
}
@ -149,22 +119,18 @@ const create = target => {
map.on("singleclick", ev => {
const mousePixel = map.getPixelFromCoordinate(ev.coordinate);
const maxDistance = sizes.courseSize + sizes.courseOuterBorder;
const maxDistance = sizes.courseSize + sizes.courseInnerBorder;
for (const course of Object.values(simulInstance.courses)) {
for (const course of Object.values(coursesSimulation.courses)) {
const coursePixel = map.getPixelFromCoordinate(course.position);
const dx = mousePixel[0] - coursePixel[0];
const dy = mousePixel[1] - coursePixel[1];
const distance = dx * dx + dy * dy;
if (distance <= maxDistance * maxDistance) {
startFocus(course.id);
return;
onClick(course.id);
}
}
// Clicking anywhere else resets focus
stopFocus();
});
return map;