diff --git a/layers/dot-cams/index.js b/layers/dot-cams/index.js new file mode 100644 index 0000000..f4dd5a9 --- /dev/null +++ b/layers/dot-cams/index.js @@ -0,0 +1,18 @@ +import mn from './mn/layer.js'; +import wi from './wi/layer.js'; + +const dot_cams = { + name: "State DOT Cameras", + layers: [ + { + name: "MNDOT/511MN", + layer: mn, + }, + { + name: "WisDOT/511WI", + layer: wi, + }, + ], +}; + +export default dot_cams; diff --git a/layers/511mn/process_data.py b/layers/dot-cams/mn/get_data.py similarity index 100% rename from layers/511mn/process_data.py rename to layers/dot-cams/mn/get_data.py diff --git a/layers/511mn/layer.js b/layers/dot-cams/mn/layer.js similarity index 100% rename from layers/511mn/layer.js rename to layers/dot-cams/mn/layer.js diff --git a/layers/511mn/pin.svg b/layers/dot-cams/mn/pin.svg similarity index 100% rename from layers/511mn/pin.svg rename to layers/dot-cams/mn/pin.svg diff --git a/layers/511mn/query.graphql b/layers/dot-cams/mn/query.graphql similarity index 100% rename from layers/511mn/query.graphql rename to layers/dot-cams/mn/query.graphql diff --git a/layers/dot-cams/wi/get_data.py b/layers/dot-cams/wi/get_data.py new file mode 100644 index 0000000..c21fb45 --- /dev/null +++ b/layers/dot-cams/wi/get_data.py @@ -0,0 +1,74 @@ +#!/usr/bin/python3 + +import requests +import json + +query={ + "columns": [ # no clue what any of this is, so here it stays + { + "data": None, + "name": "", + }, + { + "name": "sortId", + "s": True, + }, + { + "name": "region", + "s": True, + }, + { + "name": "county", + "s": True, + }, + { + "name": "roadway", + "s": True, + }, + { + "name": "description1", + }, + { + "data": 6, + "name": "", + }, + ], + "start": 0, + "length": 100, +} + +cameras = [] +available_cameras = 999_999 # lots + +while len(cameras) < available_cameras: + res = requests.get("https://511wi.gov/List/GetData/Cameras", { + "query": json.dumps(query), + "lang": "en", + }) + res.raise_for_status() + res = res.json() + available_cameras = res['recordsTotal'] + for c in res['data']: + cameras.append({ + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [c['longitude'], c['latitude']], # yes, [lon, lat] since it's [x, y] + }, + "properties": { + 'address': c['displayName'], + 'website': c['videoUrl'], + 'originalData': c, + }, + }) + query['start'] += 100 + +geojson = { + "type": "FeatureCollection", + "features": cameras, +} + +with open("data.geojson", "w") as f: + f.write(json.dumps(geojson)) + +print(f"{len(cameras)} locations found") diff --git a/layers/dot-cams/wi/layer.js b/layers/dot-cams/wi/layer.js new file mode 100644 index 0000000..7a8a6e3 --- /dev/null +++ b/layers/dot-cams/wi/layer.js @@ -0,0 +1,46 @@ +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 url from './data.geojson?url'; // TODO: remove `?url`? +import pin from './pin.svg?url'; // TODO: remove `?url`? + +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) { + return ``; +}; + +vectorLayer.customPopupCallback = function(feature) { + + const video = document.getElementById('popupVideo'); + + const videoSrc = feature.values_.originalData.videoUrl; + 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; + } +} + +export default vectorLayer; diff --git a/layers/dot-cams/wi/pin.svg b/layers/dot-cams/wi/pin.svg new file mode 100644 index 0000000..fb93212 --- /dev/null +++ b/layers/dot-cams/wi/pin.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + diff --git a/layers/index.js b/layers/index.js index 95999b4..109133c 100644 --- a/layers/index.js +++ b/layers/index.js @@ -14,7 +14,7 @@ import cellular from './cellular.js'; import light_pollution from './light_pollution.js'; import state_land from './state-land/index.js'; import trips from './trips/index.js'; -import _511mncamerasLayer from './511mn/layer.js'; +import dot_cams from './dot-cams/index.js'; const layerCategories = [ { // Base maps @@ -76,12 +76,9 @@ const layerCategories = [ name: "Bikepacking.com Routes", layer: bikepackingLayer, }, - { - name: "511MN Cameras", - layer: _511mncamerasLayer, - } ] }, + dot_cams, trips, chains, census_bureau,