Immediate rendering of courses

This commit is contained in:
Mattéo Delabre 2020-07-23 20:49:01 +02:00
parent f080bb808e
commit 1f8a78e399
Signed by: matteo
GPG Key ID: AE3FBD02DC583ABB
1 changed files with 61 additions and 69 deletions

View File

@ -8,6 +8,7 @@ const XYZSource = require('ol/source/XYZ').default;
const VectorLayer = require('ol/layer/Vector').default;
const VectorSource = require('ol/source/Vector').default;
const {getVectorContext} = require('ol/render');
const Feature = require('ol/Feature').default;
const Point = require('ol/geom/Point').default;
@ -75,21 +76,21 @@ const makeBorderColor = mainColor =>
return hsl.hex();
};
const segmentsBorderStyle = feature => new Style({
const segmentBorderStyle = feature => new Style({
stroke: new Stroke({
color: makeBorderColor(feature.get('colors')[0]),
width: 8,
}),
});
const segmentsInnerStyle = feature => new Style({
const segmentInnerStyle = feature => new Style({
stroke: new Stroke({
color: feature.get('colors')[0],
width: 6,
}),
});
const stopsStyle = feature => new Style({
const stopStyle = feature => new Style({
image: new Circle({
fill: new Fill({
color: feature.get('colors')[0],
@ -102,6 +103,19 @@ const stopsStyle = feature => new Style({
}),
});
const courseStyle = new Style({
image: new Circle({
fill: new Fill({
color: '#FF0000',
}),
stroke: new Stroke({
color: makeBorderColor('#FF0000'),
width: 1.5,
}),
radius: 6,
}),
});
const createMap = target =>
{
// Map background
@ -122,7 +136,7 @@ const createMap = target =>
const segmentsBorderLayer = new VectorLayer({
source: segmentsSource,
style: segmentsBorderStyle,
style: segmentBorderStyle,
updateWhileInteracting: true,
updateWhileAnimating: true,
@ -130,7 +144,7 @@ const createMap = target =>
const segmentsInnerLayer = new VectorLayer({
source: segmentsSource,
style: segmentsInnerStyle,
style: segmentInnerStyle,
updateWhileInteracting: true,
updateWhileAnimating: true,
@ -138,71 +152,21 @@ const createMap = target =>
const stopsLayer = new VectorLayer({
source: stopsSource,
style: stopsStyle,
style: stopStyle,
minZoom: 13,
updateWhileInteracting: 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
const view = new View({
center: proj.fromLonLat([3.88, 43.605]),
zoom: 13,
maxZoom: 22,
constrainResolution: true,
});
// Setup map
const map = new Map({
target,
layers: [
@ -210,16 +174,44 @@ const createMap = target =>
segmentsBorderLayer,
segmentsInnerLayer,
stopsLayer,
coursesLayer,
],
view: new View({
center: proj.fromLonLat([3.88, 43.605]),
zoom: 13,
maxZoom: 22,
constrainResolution: true,
}),
view,
});
// Run courses simulation and draw directly on the map
const simulInstance = simulation.start();
map.on('postcompose', ev =>
{
simulInstance.update();
// The normal way to access a layers vector context is through the
// `postrender` event of that layer. However, `postrender` is not
// triggered when no feature of the layer is inside the current
// bounding box, but we want to draw vehicles in between stops even
// if no stop is visible. This hack listens to the global `postcompose`
// event, which is always triggered at every frame, and reconstructs
// the stops layers vector context from internal variables
if (stopsLayer.renderer_)
{
ev.context = stopsLayer.renderer_.context;
ev.inversePixelTransform
= stopsLayer.renderer_.inversePixelTransform;
const ctx = getVectorContext(ev);
ctx.setStyle(courseStyle);
for (let course of Object.values(simulInstance.courses))
{
const point = new Point(course.position);
ctx.drawGeometry(point);
}
}
map.render();
});
map.render();
return map;
};