Split map logic in front
This commit is contained in:
		
							parent
							
								
									2c3b16caef
								
							
						
					
					
						commit
						a5aa58d2ee
					
				|  | @ -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(); | ||||
							
								
								
									
										133
									
								
								front/index.js
								
								
								
								
							
							
						
						
									
										133
									
								
								front/index.js
								
								
								
								
							|  | @ -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'); | ||||
|  |  | |||
|  | @ -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; | ||||
		Loading…
	
		Reference in New Issue