2024-01-31 01:17:04 -06:00
|
|
|
import VectorLayer from 'ol/layer/Vector';
|
|
|
|
import {Vector as VectorSource} from 'ol/source.js';
|
|
|
|
import GeoJSON from 'ol/format/GeoJSON.js';
|
2024-01-30 00:14:55 -06:00
|
|
|
|
2024-01-31 01:17:04 -06:00
|
|
|
import Hls from 'hls.js';
|
2024-01-29 19:28:41 -06:00
|
|
|
|
2024-01-31 01:17:04 -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';
|
2024-01-31 01:17:04 -06:00
|
|
|
|
|
|
|
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,
|
2024-02-02 03:26:19 -06:00
|
|
|
};
|
|
|
|
|
2024-01-31 01:17:04 -06:00
|
|
|
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>`,
|
2024-01-31 01:17:04 -06:00
|
|
|
layers: [],
|
2024-01-29 19:28:41 -06:00
|
|
|
};
|
|
|
|
|
2024-01-31 01:17:04 -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],
|
2024-02-02 03:25:22 -06:00
|
|
|
src: feature.getProperties().views[0].hasVideo ? pinVideo : pin,
|
2024-01-31 01:17:04 -06:00
|
|
|
}),
|
|
|
|
});
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
vectorLayer.customPopup = function(feature) {
|
2024-02-02 03:25:22 -06:00
|
|
|
const view = feature.getProperties().views[0];
|
2024-01-31 01:17:04 -06:00
|
|
|
if (view.hasVideo) {
|
2024-02-02 03:25:22 -06:00
|
|
|
return `<p>${feature.getProperties().name}</p><video style="max-width: 80vw; max-height: 80vh;" id="popupVideo" autoplay controls></video>`;
|
2024-01-31 01:17:04 -06:00
|
|
|
} else {
|
|
|
|
return `<img style="max-width: 80vw; max-height: 80vh;" src="${view.src}">`;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
vectorLayer.customPopupCallback = function(feature) {
|
2024-02-02 03:25:22 -06:00
|
|
|
const view = feature.getProperties().views[0];
|
2024-01-31 01:17:04 -06:00
|
|
|
if (view.hasVideo) {
|
|
|
|
const video = document.getElementById('popupVideo');
|
|
|
|
|
|
|
|
if (Hls.isSupported()) {
|
|
|
|
var hls = new Hls();
|
|
|
|
hls.loadSource(view.src);
|
|
|
|
hls.attachMedia(video);
|
2024-02-02 21:46:21 -06:00
|
|
|
vectorLayer.destroyPopupCallback = () => hls.destroy();
|
2024-01-31 01:17:04 -06:00
|
|
|
}
|
|
|
|
// 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;
|