Split map logic in front

This commit is contained in:
Mattéo Delabre 2020-07-17 19:17:06 +02:00
parent 2c3b16caef
commit a5aa58d2ee
Signed by: matteo
GPG Key ID: AE3FBD02DC583ABB
3 changed files with 180 additions and 130 deletions

32
front/data.js Normal file
View File

@ -0,0 +1,32 @@
const updateFromTam = async (courses) =>
{
const currentCourses = await getCurrentCourses();
for (let [id, course] of Object.entries(currentCourses))
{
if (!(id in courses))
{
course.arrivalTime = now() + course.eta;
console.log(`${displayNow(now())} - New course ${id} @ ${course.line} departing from stop ${course.stop} at ${displayNow(course.arrivalTime)}`);
courses[id] = course;
}
else
{
course.arrivalTime = now() + course.eta;
console.log(`${displayNow(now())} - Course ${id} @ ${course.line} will arrive to stop ${course.stop} at ${displayNow(course.arrivalTime)} (previously to stop ${courses[id].stop} at ${displayNow(courses[id].arrivalTime)})`);
courses[id] = course;
}
}
};
const sleep = time => new Promise(res => setTimeout(res, time));
const courses = {};
const loop = async (courses = {}) =>
{
await updateFromTam(courses);
await sleep(30000);
return loop(courses);
};
loop();

View File

@ -1,131 +1,4 @@
require('ol/ol.css');
require('regenerator-runtime/runtime');
const {Map, View} = require('ol');
const TileLayer = require('ol/layer/Tile').default;
const XYZSource = require('ol/source/XYZ').default;
const VectorLayer = require('ol/layer/Vector').default;
const VectorSource = require('ol/source/Vector').default;
const Feature = require('ol/Feature').default;
const Point = require('ol/geom/Point').default;
const LineString = require('ol/geom/LineString').default;
const proj = require('ol/proj');
const {Style, Fill, Stroke, Circle} = require('ol/style');
const color = require('color');
// Map background
const mapboxToken = 'pk.eyJ1IjoibWF0dGVvZGVsYWJyZSIsImEiOiJjazUxaWNsdXcwdWhjM2\
9tc2xndXJoNGtxIn0.xELwMerqJLFimIqU6RxnZw';
const backgroundSource = new XYZSource({
url: 'https://api.mapbox.com/' + [
'styles', 'v1', 'mapbox', 'streets-v11',
'tiles', '512', '{z}', '{x}', '{y}',
].join('/') + `?access_token=${mapboxToken}`,
tileSize: [512, 512],
});
const backgroundLayer = new TileLayer({
source: backgroundSource,
});
// Data overlay
const dataSource = new VectorSource();
const SERVER = window.origin;
fetch(SERVER + '/network').then(res => res.json()).then(network =>
{
const stopPoints = Object.entries(network.stops)
.map(([stopId, stop]) =>
new Feature({
type: 'stop',
color: network.lines[stop.lines[0]].color,
geometry: new Point(proj.fromLonLat([stop.lon, stop.lat])),
})
);
const segmentLines = Object.values(network.lines)
.flatMap(({color, routes}) =>
routes.map(({segments}) =>
new Feature({
type: 'segment',
color,
geometry: new LineString(segments.flat().map(
({lat, lon}) => proj.fromLonLat([lon, lat])
)),
})
)
);
dataSource.addFeatures(
stopPoints.concat(segmentLines)
);
});
const makeBorderColor = mainColor =>
{
const hsl = color(mainColor).hsl();
hsl.color = Math.max(0, hsl.color[2] -= 20);
return hsl.hex();
};
const dataLayer = new VectorLayer({
source: dataSource,
style: feature =>
{
if (feature.get('type') === 'stop')
{
return new Style({
image: new Circle({
fill: new Fill({
color: feature.get('color'),
}),
stroke: new Stroke({
color: makeBorderColor(feature.get('color')),
width: 2,
}),
radius: 6,
}),
});
}
else if (feature.get('type') === 'segment')
{
return [
new Style({
stroke: new Stroke({
color: makeBorderColor(feature.get('color')),
width: 8,
}),
}),
new Style({
stroke: new Stroke({
color: feature.get('color'),
width: 6,
}),
}),
];
}
},
});
// Setup map
const map = new Map({
target: 'map',
layers: [
backgroundLayer,
dataLayer,
],
view: new View({
center: proj.fromLonLat([3.88, 43.605]),
zoom: 13,
maxZoom: 22,
constrainResolution: true,
}),
});
module.exports = map;
const {createMap} = require('./map');
createMap(/* map = */ 'map');

145
front/map.js Normal file
View File

@ -0,0 +1,145 @@
require('ol/ol.css');
const {Map, View} = require('ol');
const TileLayer = require('ol/layer/Tile').default;
const XYZSource = require('ol/source/XYZ').default;
const VectorLayer = require('ol/layer/Vector').default;
const VectorSource = require('ol/source/Vector').default;
const Feature = require('ol/Feature').default;
const Point = require('ol/geom/Point').default;
const LineString = require('ol/geom/LineString').default;
const proj = require('ol/proj');
const {Style, Fill, Stroke, Circle} = require('ol/style');
const color = require('color');
const mapboxToken = 'pk.eyJ1IjoibWF0dGVvZGVsYWJyZSIsImEiOiJjazUxaWNsdXcwdWhjM2\
9tc2xndXJoNGtxIn0.xELwMerqJLFimIqU6RxnZw';
const server = window.origin;
const fetchDataSources = async () =>
{
const dataSource = new VectorSource();
const res = await fetch(`${server}/network`);
const network = await res.json();
const stopPoints = Object.entries(network.stops)
.map(([stopId, stop]) =>
new Feature({
type: 'stop',
color: network.lines[stop.lines[0]].color,
geometry: new Point(proj.fromLonLat([stop.lon, stop.lat])),
})
);
dataSource.addFeatures(stopPoints);
const segmentLines = Object.values(network.lines)
.flatMap(({color, routes}) =>
routes.map(({segments}) =>
new Feature({
type: 'segment',
color,
geometry: new LineString(segments.flat().map(
({lat, lon}) => proj.fromLonLat([lon, lat])
)),
})
)
);
dataSource.addFeatures(segmentLines);
return dataSource;
};
const createMap = async (target) =>
{
// Map background
const backgroundSource = new XYZSource({
url: 'https://api.mapbox.com/' + [
'styles', 'v1', 'mapbox', 'streets-v11',
'tiles', '512', '{z}', '{x}', '{y}',
].join('/') + `?access_token=${mapboxToken}`,
tileSize: [512, 512],
});
const backgroundLayer = new TileLayer({
source: backgroundSource,
});
// Data overlay
const dataSource = await fetchDataSources();
const makeBorderColor = mainColor =>
{
const hsl = color(mainColor).hsl();
hsl.color = Math.max(0, hsl.color[2] -= 20);
return hsl.hex();
};
const dataLayer = new VectorLayer({
source: dataSource,
updateWhileInteracting: true,
updateWhileAnimating: true,
style: feature =>
{
if (feature.get('type') === 'stop')
{
return new Style({
image: new Circle({
fill: new Fill({
color: feature.get('color'),
}),
stroke: new Stroke({
color: makeBorderColor(feature.get('color')),
width: 2,
}),
radius: 6,
}),
});
}
else if (feature.get('type') === 'segment')
{
return [
new Style({
stroke: new Stroke({
color: makeBorderColor(feature.get('color')),
width: 8,
}),
}),
new Style({
stroke: new Stroke({
color: feature.get('color'),
width: 6,
}),
}),
];
}
},
});
// Setup map
const map = new Map({
target,
layers: [
backgroundLayer,
dataLayer,
],
view: new View({
center: proj.fromLonLat([3.88, 43.605]),
zoom: 13,
maxZoom: 22,
constrainResolution: true,
}),
});
return map;
};
exports.createMap = createMap;