76 lines
2.4 KiB
JavaScript
76 lines
2.4 KiB
JavaScript
|
import VectorLayer from 'ol/layer/Vector';
|
||
|
import {Vector as VectorSource} from 'ol/source.js';
|
||
|
import GeoJSON from 'ol/format/GeoJSON.js';
|
||
|
|
||
|
import Hls from 'hls.js';
|
||
|
|
||
|
import {Style} from 'ol/style.js';
|
||
|
import Icon from 'ol/style/Icon.js';
|
||
|
|
||
|
import states from './data/states.js';
|
||
|
|
||
|
import pin from './pin.svg?url'; // TODO: remove `?url`?
|
||
|
|
||
|
// https://en.wikipedia.org/wiki/Department_of_transportation#List_of_U.S._state_and_insular_area_departments_of_transportation
|
||
|
const dot_names = {
|
||
|
mn: "Minnesota: MNDOT/511MN",
|
||
|
ia: "Iowa: Iowa DOT/511IA",
|
||
|
wi: "Wisconsin: WisDOT/511WI",
|
||
|
co: "Colorado: CDOT/COtrip",
|
||
|
ks: "Kansas: KDOT/KanDrive",
|
||
|
ne: "Nebraska: NDOT/Nebraska 511",
|
||
|
ma: "Massachusetts: MassDOT/Mass511",
|
||
|
}
|
||
|
|
||
|
let vectorLayers = []
|
||
|
|
||
|
for (let [state, url] of Object.entries(states)) {
|
||
|
const vectorLayer = new VectorLayer({
|
||
|
source: new VectorSource({
|
||
|
url: url,
|
||
|
format: new GeoJSON,
|
||
|
}),
|
||
|
style: new Style({
|
||
|
image: new Icon({
|
||
|
anchor: [0.5, 1],
|
||
|
src: pin,
|
||
|
}),
|
||
|
}),
|
||
|
});
|
||
|
|
||
|
vectorLayer.customPopup = function(feature) {
|
||
|
const view = feature.values_.originalData.views[0];
|
||
|
if (view.category.toLowerCase() == "video") {
|
||
|
return `<video style="max-width: 80vw; max-height: 80vh;" id="popupVideo" autoplay controls></video>`;
|
||
|
} else if (view.category.toLowerCase() == "image") {
|
||
|
return `<img style="max-width: 80vw; max-height: 80vh;" src="${view.url}">`;
|
||
|
} else {
|
||
|
throw new Exception(`unknown category ${view.category}`);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
vectorLayer.customPopupCallback = function(feature) {
|
||
|
const view = feature.values_.originalData.views[0];
|
||
|
if (view.category.toLowerCase() == "video") {
|
||
|
const video = document.getElementById('popupVideo');
|
||
|
|
||
|
const videoSrc = view.sources[0].src;
|
||
|
if (Hls.isSupported()) {
|
||
|
var hls = new Hls();
|
||
|
hls.loadSource(videoSrc);
|
||
|
hls.attachMedia(video);
|
||
|
}
|
||
|
// iDevice support, untested (only works in Safari; required for iPhones)
|
||
|
else if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
||
|
video.src = videoSrc;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
vectorLayers.push({
|
||
|
name: dot_names[state] ?? state,
|
||
|
layer: vectorLayer,
|
||
|
});
|
||
|
}
|
||
|
|
||
|
export default vectorLayers;
|