152 lines
3.8 KiB
JavaScript
152 lines
3.8 KiB
JavaScript
require('ol/ol.css');
|
|
|
|
const axios = require('axios');
|
|
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.eyJ1IjoibWF0dGVvZGVsYWJyZSIsImEiOiJja2NxaTUyMmUwcmFhMn\
|
|
h0NmFsdzQ3emxqIn0.cyxF0h36emIMTk3cc4VqUw`;
|
|
|
|
const network = require('../back/data/network.json');
|
|
|
|
const makeDataSources = async () =>
|
|
{
|
|
const segmentsSource = new VectorSource();
|
|
const stopsSource = new VectorSource();
|
|
|
|
segmentsSource.addFeatures(
|
|
Object.values(network.segments).map(({lines, points}) =>
|
|
new Feature({
|
|
colors: lines.map(line => network.lines[line].color),
|
|
geometry: new LineString(points.map(
|
|
({lat, lon}) => proj.fromLonLat([lon, lat])
|
|
)),
|
|
})
|
|
)
|
|
);
|
|
|
|
stopsSource.addFeatures(
|
|
Object.values(network.stops).map(({lines, lon, lat}) =>
|
|
new Feature({
|
|
colors: lines.map(line => network.lines[line].color),
|
|
geometry: new Point(proj.fromLonLat([lon, lat])),
|
|
})
|
|
)
|
|
);
|
|
|
|
return {segmentsSource, stopsSource};
|
|
};
|
|
|
|
const makeBorderColor = mainColor =>
|
|
{
|
|
const hsl = color(mainColor).hsl();
|
|
hsl.color = Math.max(0, hsl.color[2] -= 20);
|
|
return hsl.hex();
|
|
};
|
|
|
|
const segmentsBorderStyle = feature => new Style({
|
|
stroke: new Stroke({
|
|
color: makeBorderColor(feature.get('colors')[0]),
|
|
width: 8,
|
|
}),
|
|
});
|
|
|
|
const segmentsInnerStyle = feature => new Style({
|
|
stroke: new Stroke({
|
|
color: feature.get('colors')[0],
|
|
width: 6,
|
|
}),
|
|
});
|
|
|
|
const stopsStyle = feature => new Style({
|
|
image: new Circle({
|
|
fill: new Fill({
|
|
color: feature.get('colors')[0],
|
|
}),
|
|
stroke: new Stroke({
|
|
color: makeBorderColor(feature.get('colors')[0]),
|
|
width: 1.5,
|
|
}),
|
|
radius: 6,
|
|
}),
|
|
});
|
|
|
|
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 {segmentsSource, stopsSource} = await makeDataSources();
|
|
|
|
const segmentsBorderLayer = new VectorLayer({
|
|
source: segmentsSource,
|
|
style: segmentsBorderStyle,
|
|
|
|
updateWhileInteracting: true,
|
|
updateWhileAnimating: true,
|
|
});
|
|
|
|
const segmentsInnerLayer = new VectorLayer({
|
|
source: segmentsSource,
|
|
style: segmentsInnerStyle,
|
|
|
|
updateWhileInteracting: true,
|
|
updateWhileAnimating: true,
|
|
});
|
|
|
|
const stopsLayer = new VectorLayer({
|
|
source: stopsSource,
|
|
style: stopsStyle,
|
|
|
|
minZoom: 13,
|
|
updateWhileInteracting: true,
|
|
updateWhileAnimating: true,
|
|
});
|
|
|
|
// Setup map
|
|
const map = new Map({
|
|
target,
|
|
layers: [
|
|
backgroundLayer,
|
|
segmentsBorderLayer,
|
|
segmentsInnerLayer,
|
|
stopsLayer,
|
|
],
|
|
view: new View({
|
|
center: proj.fromLonLat([3.88, 43.605]),
|
|
zoom: 13,
|
|
maxZoom: 22,
|
|
constrainResolution: true,
|
|
}),
|
|
});
|
|
|
|
return map;
|
|
};
|
|
|
|
exports.createMap = createMap;
|