r2b22-map/main.js
2022-09-02 16:21:13 +02:00

147 lines
3.2 KiB
JavaScript

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 {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',
}),
}),
circleBlack: new Style({
image: new CircleStyle({
radius: 7,
fill: new Fill({color: '#FF9900'}),
stroke: new Stroke({
color: 'white',
width: 2,
}),
})
})
}
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
});
const vectorSourcePOI = new VectorSource({
features: new GeoJSON().readFeatures(geojsonPOI),
});
const poiLayer = new VectorLayer({
source: vectorSourcePOI,
style: styles.circleBlack,
});
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
],
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);