maps.chandlerswift.com/layers/dot-cams/index.js

86 lines
2.7 KiB
JavaScript
Raw Permalink Normal View History

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';
2024-01-29 19:28:41 -06:00
import {Style} from 'ol/style.js';
import Icon from 'ol/style/Icon.js';
import pin from './pin.svg?url'; // TODO: remove `?url`?
import pinVideo from './pin-video.svg?url'; // TODO: remove `?url`?
import castleRockStates from './castle-rock/data/states.js';
import travelIqStates from './travel-iq/data/states.js';
import al from './al/data.geojson?url';
2024-02-03 03:14:48 -06:00
import de from './de/data.geojson?url';
2024-02-03 03:30:10 -06:00
import md from './md/data.geojson?url';
import dot_names from './layer_names.js';
const allStates = {
...castleRockStates,
...travelIqStates,
'Alabama': al,
2024-02-03 03:14:48 -06:00
'Delaware': de,
2024-02-03 03:30:10 -06:00
'Maryland': md,
};
let dot_cams = {
2024-01-29 19:28:41 -06:00
name: "State DOT Cameras",
2024-01-29 23:31:17 -06:00
details: `<a href="#" onclick="this.closest('details').querySelectorAll('ul li input').forEach(e => e.checked || e.click()); return false;">Enable All</a>`,
layers: [],
2024-01-29 19:28:41 -06:00
};
for (let [state, url] of Object.entries(allStates)) {
const vectorLayer = new VectorLayer({
source: new VectorSource({
url: url,
format: new GeoJSON,
}),
style: function(feature, resolution){
return new Style({
image: new Icon({
anchor: [0.5, 1],
src: feature.getProperties().views[0].hasVideo ? pinVideo : pin,
}),
});
},
});
vectorLayer.customPopup = function(feature) {
const view = feature.getProperties().views[0];
if (view.hasVideo) {
return `<p>${feature.getProperties().name}</p><video style="max-width: 80vw; max-height: 80vh;" id="popupVideo" autoplay controls></video>`;
} else {
return `<img style="max-width: 80vw; max-height: 80vh;" src="${view.src}">`;
}
};
vectorLayer.customPopupCallback = function(feature) {
const view = feature.getProperties().views[0];
if (view.hasVideo) {
const video = document.getElementById('popupVideo');
if (Hls.isSupported()) {
var hls = new Hls();
hls.loadSource(view.src);
hls.attachMedia(video);
vectorLayer.destroyPopupCallback = () => hls.destroy();
}
// iDevice support, untested (only works in Safari; required for iPhones)
else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = view.src;
}
}
}
dot_cams.layers.push({
name: dot_names[state] ?? state,
layer: vectorLayer,
});
}
dot_cams.layers.sort((a, b) => a.name > b.name ? 1 : -1); // Names are always unique
2024-01-29 19:28:41 -06:00
export default dot_cams;