Compare commits

..

No commits in common. "d688bff8134973ccec875c8bd1f4a7c5442eb2a3" and "76a187bbb6d8b4e440dc7fe3d7a68332f187a6f3" have entirely different histories.

4 changed files with 28 additions and 156 deletions

View File

@ -1,4 +1,7 @@
require('regenerator-runtime/runtime'); require('regenerator-runtime/runtime');
const {createMap} = require('./map'); const {createMap} = require('./map');
require('../tam/simulation');
createMap(/* map = */ 'map'); createMap(/* map = */ 'map');

View File

@ -21,7 +21,6 @@ const color = require('color');
const mapboxToken = `pk.eyJ1IjoibWF0dGVvZGVsYWJyZSIsImEiOiJja2NxaTUyMmUwcmFhMn\ const mapboxToken = `pk.eyJ1IjoibWF0dGVvZGVsYWJyZSIsImEiOiJja2NxaTUyMmUwcmFhMn\
h0NmFsdzQ3emxqIn0.cyxF0h36emIMTk3cc4VqUw`; h0NmFsdzQ3emxqIn0.cyxF0h36emIMTk3cc4VqUw`;
const simulation = require('../tam/simulation');
const network = require('../tam/network.json'); const network = require('../tam/network.json');
const getRouteColors = routes => const getRouteColors = routes =>
@ -40,7 +39,7 @@ const getRouteColors = routes =>
return ['#FFFFFF']; return ['#FFFFFF'];
}; };
const makeDataSources = () => const makeDataSources = async () =>
{ {
const segmentsSource = new VectorSource(); const segmentsSource = new VectorSource();
const stopsSource = new VectorSource(); const stopsSource = new VectorSource();
@ -102,7 +101,7 @@ const stopsStyle = feature => new Style({
}), }),
}); });
const createMap = target => const createMap = async (target) =>
{ {
// Map background // Map background
const backgroundSource = new XYZSource({ const backgroundSource = new XYZSource({
@ -117,8 +116,8 @@ const createMap = target =>
source: backgroundSource, source: backgroundSource,
}); });
// Static data overlay // Data overlay
const {segmentsSource, stopsSource} = makeDataSources(); const {segmentsSource, stopsSource} = await makeDataSources();
const segmentsBorderLayer = new VectorLayer({ const segmentsBorderLayer = new VectorLayer({
source: segmentsSource, source: segmentsSource,
@ -145,63 +144,6 @@ const createMap = target =>
updateWhileAnimating: true, updateWhileAnimating: true,
}); });
// Dynamic data overlay
const coursesSource = new VectorSource();
const onFrame = courses =>
{
// Remove stale courses
for (let feature of coursesSource.getFeatures())
{
if (!(feature.getId() in courses))
{
coursesSource.removeFeature(feature);
}
}
// Add new courses or update existing courses
const newFeatures = [];
for (let [courseId, course] of Object.entries(courses))
{
if ('position' in course)
{
const feature = coursesSource.getFeatureById(courseId);
const coords = proj.fromLonLat([
course.position.lon,
course.position.lat
]);
if (feature === null)
{
const feature = new Feature({
colors: ['#FF0000'],
geometry: new Point(coords)
});
feature.setId(courseId);
newFeatures.push(feature);
}
else
{
feature.getGeometry().setCoordinates(coords);
}
}
}
coursesSource.addFeatures(newFeatures);
};
simulation.run(onFrame);
const coursesLayer = new VectorLayer({
source: coursesSource,
style: stopsStyle,
updateWhileInteracting: true,
updateWhileAnimating: true,
});
// Setup map // Setup map
const map = new Map({ const map = new Map({
target, target,
@ -210,7 +152,6 @@ const createMap = target =>
segmentsBorderLayer, segmentsBorderLayer,
segmentsInnerLayer, segmentsInnerLayer,
stopsLayer, stopsLayer,
coursesLayer,
], ],
view: new View({ view: new View({
center: proj.fromLonLat([3.88, 43.605]), center: proj.fromLonLat([3.88, 43.605]),

View File

@ -1,6 +1,5 @@
const tam = require('./sources/tam'); const tam = require('./sources/tam');
const util = require('../util'); const util = require('../util');
const network = require('./network.json');
/** /**
* Comparison function between two stop passings. * Comparison function between two stop passings.
@ -58,28 +57,6 @@ const getCourses = () => new Promise((res, rej) =>
if (!util.isObject(entry)) if (!util.isObject(entry))
{ {
// Filter courses to only keep those referring to known data
for (let courseId of Object.keys(courses))
{
const course = courses[courseId];
if (!(course.line in network.lines))
{
delete courses[courseId];
}
else
{
for (let passing of course.nextPassings)
{
if (!(passing.stopId in network.stops))
{
delete courses[courseId];
break;
}
}
}
}
// End of courses information stream. Sort next stops by increasing // End of courses information stream. Sort next stops by increasing
// arrival time in each course then save result in memory cache // arrival time in each course then save result in memory cache
for (let course of Object.values(courses)) for (let course of Object.values(courses))

View File

@ -71,6 +71,12 @@ const updateFromTam = async (courses) =>
for (let [id, course] of Object.entries(currentCourses)) for (let [id, course] of Object.entries(currentCourses))
{ {
// Only track selected lines
if (!['1', '2', '3', '4'].includes(course.line))
{
continue;
}
// Find out the next stop, ignoring the ones that are in the past // Find out the next stop, ignoring the ones that are in the past
let nextStop = null; let nextStop = null;
let arrivalTime = null; let arrivalTime = null;
@ -149,7 +155,6 @@ const updatePositions = (courses, time) =>
{ {
if (course.state === 'moving') if (course.state === 'moving')
{ {
// Increase the travelled distance respective to the current speed
const delta = course.speed * time; const delta = course.speed * time;
const segment = getCurrentSegment(course); const segment = getCurrentSegment(course);
@ -163,66 +168,20 @@ const updatePositions = (courses, time) =>
{ {
course.traveledDistance += delta; course.traveledDistance += delta;
} }
// Recompute updated position
const departureStop = network.stops[course.departureStop];
const arrivalStop = network.stops[course.arrivalStop];
const nextNodeIndex = segment.points.findIndex(
({distance}) => distance >= course.traveledDistance);
if (nextNodeIndex === 0)
{
course.position = {
lat: departureStop.lat,
lon: departureStop.lon
};
}
else if (nextNodeIndex === -1)
{
course.position = {
lat: arrivalStop.lat,
lon: arrivalStop.lon
};
}
else
{
const previousNode = segment.points[nextNodeIndex - 1];
const nextNode = segment.points[nextNodeIndex];
const curLength = course.traveledDistance
- previousNode.distance;
const totalLength = nextNode.distance
- previousNode.distance;
const progression = curLength / totalLength;
course.position = {
lat: progression * nextNode.lat
+ (1 - progression) * previousNode.lat,
lon: progression * nextNode.lon
+ (1 - progression) * previousNode.lon,
};
}
}
else
{
const currentStop = network.stops[course.currentStop];
course.position = {
lat: currentStop.lat,
lon: currentStop.lon,
};
} }
} }
}; };
const run = callback => const courses = {};
{ let lastFrame = null;
const courses = {}; let lastUpdate = null;
let lastFrame = null;
let lastUpdate = null;
const loop = () => const loop = now =>
{ {
const now = Date.now(); const time = lastFrame === null ? 0 : now - lastFrame;
lastFrame = now;
updatePositions(courses, time);
if (lastUpdate === null || lastUpdate + 5000 <= now) if (lastUpdate === null || lastUpdate + 5000 <= now)
{ {
@ -230,15 +189,7 @@ const run = callback =>
updateFromTam(courses); updateFromTam(courses);
} }
const time = lastFrame === null ? 0 : now - lastFrame; requestAnimationFrame(loop);
lastFrame = now;
updatePositions(courses, time);
callback(courses);
};
const interval = setInterval(loop, 24);
return () => clearInterval(interval);
}; };
exports.run = run; requestAnimationFrame(loop);