import './style.css'; import {Map, View} from 'ol'; import Feature from 'ol/Feature'; import GeoJSON from 'ol/format/GeoJSON'; import Overlay from 'ol/Overlay'; import Point from 'ol/geom/Point'; import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer'; import {Circle as CircleStyle, Fill, Icon, Stroke, Style} from 'ol/style'; import {OSM, Vector as VectorSource} from 'ol/source'; import {useGeographic} from 'ol/proj'; import geojsonRoute from './geo/route.json' import geojsonPOI from './geo/poi.json' useGeographic(); const styles = { lineOrange: new Style({ stroke: new Stroke({ color: '#FF9900', // lineDash: [8], width: 5, }), }), lineGrey: new Style({ stroke: new Stroke({ color: '#555555', // lineDash: [8], width: 5, }), }), iconStop: new Style({ image: new Icon({ anchor: [0.5, 46], anchorXUnits: 'fraction', anchorYUnits: 'pixels', src: 'data/icon.png', }), }), iconVan: new Style({ image: new Icon({ anchor: [0.5, 16], anchorXUnits: 'fraction', anchorYUnits: 'pixels', src: 'data/van-100px.png', }), }), circleBlack: new Style({ image: new CircleStyle({ radius: 7, fill: new Fill({color: '#FF9900'}), stroke: new Stroke({ color: 'white', width: 2, }), }) }) } // // Route // const lastStageFinished = 4; const stagesCompleted = geojsonRoute.features.slice(0, lastStageFinished); const stagesAhead = geojsonRoute.features.slice(lastStageFinished); const vectorSourceStagesCompleted = new VectorSource(); const vectorSourceStagesAhead = new VectorSource(); for (const stage of stagesCompleted) { vectorSourceStagesCompleted.addFeature(new GeoJSON().readFeature(stage)); } for (const stage of stagesAhead) { vectorSourceStagesAhead.addFeature(new GeoJSON().readFeature(stage)); } const stagesCompletedLayer = new VectorLayer({ source: vectorSourceStagesCompleted, style: styles.lineOrange }); const stagesAheadLayer = new VectorLayer({ source: vectorSourceStagesAhead, style: styles.lineGrey }); // // Points of Interest // const vectorSourcePOI = new VectorSource({ features: new GeoJSON().readFeatures(geojsonPOI), }); const poiLayer = new VectorLayer({ source: vectorSourcePOI, style: styles.circleBlack, }); const vectorSourceVan = new VectorSource(); const vanFeature= new Feature({ geometry: new Point([ 12.498556, 45.780383 ]), name: 'Support Van' }); vectorSourceVan.addFeature(vanFeature); const vanLayer = new VectorLayer({ source: vectorSourceVan, style: styles.iconVan }); // // Map initialization // const view = new View({ center: [10.6, 46.9], zoom: 6.6 }) const map = new Map({ target: 'map', layers: [ new TileLayer({ source: new OSM() }), stagesCompletedLayer, stagesAheadLayer, poiLayer, vanLayer ], view: view }); // // Popups // const popupEl = document.getElementById('popup'); const popup = new Overlay({ element: popupEl, positioning: 'bottom-center', stopEvent: false, }); map.addOverlay(popup); let popover; function disposePopover() { if (popover) { popover.dispose(); popover = undefined; } } // display popup on click map.on('click', function (evt) { const feature = map.forEachFeatureAtPixel(evt.pixel, function (feature) { return feature; }); disposePopover(); if (!feature) { return; } popup.setPosition(evt.coordinate); popover = new bootstrap.Popover(popupEl, { placement: 'top', html: true, content: feature.get('name'), }); popover.show(); }); // change mouse cursor when over marker map.on('pointermove', function (evt) { map.getTargetElement().style.cursor = map.hasFeatureAtPixel(evt.pixel) ? 'pointer' : ''; }); // Close the popup when the map is moved map.on('movestart', disposePopover);