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('../tam/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;