Files
test/ltg.html
2025-11-27 22:25:36 +00:00

482 lines
15 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<title>RLX Lightning Archive</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
crossorigin=""></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js" integrity="sha512-ozq8xQKq6urvuU6jNgkfqAmT7jKN2XumbrX1JiB3TnF7tI48DPI4Gy1GXKD/V3EExgAs1V+pRO7vwtS1LHg0Gw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw-src.css" integrity="sha512-vJfMKRRm4c4UupyPwGUZI8U651mSzbmmPgR3sdE3LcwBPsdGeARvUM5EcSTg34DK8YIRiIo+oJwNfZPMKEQyug==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw-src.js" integrity="sha512-czICF/Crp0B7QB13iQZG9bYUpd/P1Ona1NeZN52gYsoVFXIpakDmdOUepMCHCMBIBd9Ei5Mlg8Quy4e504IT5A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css" integrity="sha512-gc3xjCmIy673V6MyOAZhIW93xhM9ei1I+gLbmFjUHIjocENRsLX/QUE1htk5q1XV2D/iie/VQ8DXI6Vu8bexvQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>
<body>
<style type="text/css">
//#mapid { height: 800px; }
body {
padding: 0;
margin: 0;
}
html, body {
height: 100%;
width: 100%
}
#mapid {
height: 97%;
}
#bototmbar {
height: 3%;
}
#form {
position: absolute;
width: 250px;
left: 15px;
top: 350px;
z-index: 255555;
}
#inputForm {
background-color: #fff;
width: 250px;
z-index: 255553;
}
.datetimes {
width: 250px;
z-index: 2556557;
}
#current {
z-index: 10000000;
}
#legend {
position: absolute;
right: 30px;
bottom: 40px;
z-index: 55555;
}
</style>
<div id="mapid">
<div id="legend">
<img src="legend.png" alt="Legend">
</div>
<div id="form">
<form id="inputForm">
<label for="datetimes">Time Range (UTC)</label>
<input type="text" name="datetimes" class="datetimes" id="datetimes">
Use the box drawing thing in the top right so you don't have to manually enter these<br>
<label for="nwLon">NE Corner Latitude:</label><br>
<input type="text" id="neLat" name="neLat" required><br>
<label for="nwLon">NE Corner Longitude:</label><br>
<input type="text" id="neLon" name="neLon" required><br>
<label for="seLat">SW Corner Latitude:</label><br>
<input type="text" id="swLat" name="swLat" required><br>
<label for="seLon">SW Corner Longitude:</label><br>
<input type="text" id="swLon" name="swLon" required><br>
<label>Output Format:</label><br>
<input type="radio" id="leafletMap" name="outputFormat" value="Leaflet Map" checked>
<label for="leafletMap">Leaflet Map</label><br>
<input type="radio" id="geoJSON" name="outputFormat" value="geoJSON">
<label for="geoJSON">geoJSON</label><br>
<input type="radio" id="kml" name="outputFormat" value="KML">
<label for="kml">KML</label><br>
<label>Database:</label><br>
<label>Real-time ltg ingest has been disabled</label><br>
<input type="radio" id="main" name="database" value="main" checked>
<label for="main">Main (1986-Present)</label><br>
<input type="radio" id="current" name="database" value="current">
<label for="main">Current (Only new strikes)</label><br>
<!-- <input type="radio" id="csv" name="outputFormat" value="CSV">
<label for="csv">CSV</label><br>-->
<button type="button" onclick="generateOutput()">Generate Output</button>
<button type="button" onclick="clearstrikes()">Clear Strikes</button><br>
<label for="strikecount">Total / Pos / Neg Strikes Displayed:</label><br>
<input type="text" id="strikecount" name="strikecount" value=0 readonly><br>
</form>
</div>
</div>
<div id="bottombar">
<a href="cams.html" class="w3-button w3-black">Cam List</a>
<a href="admin.html" class="w3-button w3-black">Add Camera</a>
<a href="db.html" class="w3-button w3-black">WU obs</a>
<a href="5min.html" class="w3-button w3-black">5m ASOS obs</a>
<a href="outagemap.html" class="w3-button w3-black">Power Outages</a>
<a href="today.txt" class="w3-button w3-black">CoCoRaHS Remarks</a>
<a href="https://docs.google.com/forms/d/1-2rTBkNyyBVe08G1vN1hcSOEOvvLUcS1Vs2SmmaudlU" class="w3-button w3-black" target="_blank">Questions? Comments?</a>
<!-- <a href="http://stoat.org/work/db.html" class="w3-button w3-black">Wunderground Obs</a>-->
</div>
<script>
var mymap = L.map('mapid').setView([38.332372, -81.652480], 8);
var Esri_WorldStreetMap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri'
});
var Esri_WorldImagery = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
});
var Esri_WorldTopoMap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community'
});
var Stadia_StamenToner = L.tileLayer('https://tiles.stadiamaps.com/tiles/stamen_toner/{z}/{x}/{y}{r}.{ext}', {
minZoom: 0,
maxZoom: 20,
attribution: '&copy; <a href="https://www.stadiamaps.com/" target="_blank">Stadia Maps</a> &copy; <a href="https://www.stamen.com/" target="_blank">Stamen Design</a> &copy; <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a> &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
ext: 'png'
});
var USGS_USImageryTopo = L.tileLayer('https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryTopo/MapServer/tile/{z}/{y}/{x}', {
maxZoom: 20,
attribution: 'Tiles courtesy of the <a href="https://usgs.gov/">U.S. Geological Survey</a>'
});
var baselayers = {
"Esri Street Map": Esri_WorldStreetMap,
"Esri Satellite": Esri_WorldImagery,
"Esri Topo": Esri_WorldTopoMap,
"USGS Sat/Topo": USGS_USImageryTopo
}
L.control.layers(baselayers,null,{collapsed: false}).addTo(mymap);
Esri_WorldStreetMap.addTo(mymap);
var counties = 'counties.json'
var exteriorStyle = {
"color": "#000000",
"weight": 1,
"fillOpacity": 0
};
fetch(
counties
).then(
res => res.json()
).then(
data => L.geoJSON(data, {style: exteriorStyle}).addTo(mymap)
)
var LeafIcon = L.Icon.extend({
options: {
shadowUrl:
'http://leafletjs.com/docs/images/leaf-shadow.png',
iconSize: [38, 95],
shadowSize: [50, 64],
iconAnchor: [22, 94],
shadowAnchor: [4, 62],
popupAnchor: [-3, -76]
}
});
var greenIcon = new LeafIcon({
iconUrl: 'http://leafletjs.com/docs/images/leaf-green.png'
});
var drawnItems = new L.FeatureGroup();
mymap.addLayer(drawnItems);
var drawControl = new L.Control.Draw({
position: 'topright',
draw: {
rect: true,
polygon: false,
circle: false,
marker: false,
circlemarker: false,
polyline: false
},
edit: {
featureGroup: drawnItems
}
});
mymap.addControl(drawControl);
mymap.on('draw:created', function (e) {
var type = e.layerType,
layer = e.layer;
document.getElementById('neLat').value = layer._bounds._northEast.lat.toFixed(4);
document.getElementById('neLon').value = layer._bounds._northEast.lng.toFixed(4);
document.getElementById('swLat').value = layer._bounds._southWest.lat.toFixed(4);
document.getElementById('swLon').value = layer._bounds._southWest.lng.toFixed(4);
if (type === 'marker') {
layer.bindPopup('A popup!');
}
drawnItems.addLayer(layer);
});
$(function() {
var date = new Date();
$('input[name="datetimes"]').daterangepicker({
timePicker: true,
timePicker24Hour: true,
showDropdowns: true,
startDate: moment().utc().startOf('hour').add(-23, 'hour'),
endDate: moment().utc().startOf('hour').add(1,'hour'),
maxSpan: { "years": 100 },
linkedCalenders: false,
minDate: new Date(1986,0,1),
maxDate: new Date(date.getFullYear(), date.getMonth() + 1, 0),
opens: 'right',
drops: 'up',
locale: {
format: 'M/DD/YYYY HH:mm'
}
});
});
function generateOutput() {
// Retrieve user inputs
var neLat = (document.getElementById("neLat").value);
var neLon = document.getElementById("neLon").value;
var swLat = document.getElementById("swLat").value;
var swLon = document.getElementById("swLon").value;
var database = document.querySelector('input[name="database"]:checked').value;
var outputFormat = document.querySelector('input[name="outputFormat"]:checked').value;
var startDate = $('#datetimes').data('daterangepicker').startDate._d;
var endDate = $('#datetimes').data('daterangepicker').endDate._d;
if (neLat && neLon && swLat && swLon) {
let data = {swLat: swLat, neLat: neLat, swLon: swLon, neLon: neLon, type: outputFormat, startDate: startDate, endDate: endDate, database: database};
// Perform actions based on the selected output format
switch (outputFormat) {
case "geoJSON":
fetch_geoJSON(data)
// Generate GeoJSON output
// Implement your GeoJSON generation logic here
break;
case "KML":
generate_kml(data)
// Generate KML output
// Implement your KML generation logic here
break;
case "CSV":
// Generate CSV output
// Implement your CSV generation logic here
break;
case "Leaflet Map":
add_leaflet(data);
// Show a Leaflet map with the specified coordinates and date/time
// Implement your Leaflet map rendering logic here
break;
default:
// Handle unsupported format
break;
}
} else {
alert('Please ensure you have selected a bounding box for the data you want')
}
}
function fetch_geoJSON(data) {
fetch("https://wx.stoat.org/cgi-bin/ltg.py", {
method: "POST",
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
}).then((res) => res.blob())
.then((blob) => URL.createObjectURL(blob))
.then((href) => {
Object.assign(document.createElement('a'), {
href,
download: 'RLXltg.geojson',
}).click();
});
}
function add_leaflet(data) {
var geojsonMarkerOptions = {
radius: 8,
fillColor: "#ff7800",
color: "#000",
weight: 1,
opacity: 1,
fillOpacity: 0.8
};
fetch("https://wx.stoat.org/cgi-bin/ltg.py", {
method: "POST",
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
}).then((res) => res.text())
.then(text => (plot_geojson(text)));
}
function plot_geojson(data) {
data = jQuery.parseJSON(data);
if (data.features == null) {
alert("No strikes were returned from the database, try a different time range or bounding box!");
}
var geojsonMarkerOptions = {
radius: 2,
fillColor: "#ff7800",
color: "#000",
weight: 1,
opacity: 1,
fillOpacity: 0.8
};
L.geoJson(data, {
pointToLayer: function (feature, latlng) {
mypopup = L.popup().setContent("Time (UTC): " + (feature.properties.time) + "<br> Magnitude (kA) " + feature.properties.mag)
counter = counter + 1;
if (feature.properties.mag > 0) {
poscounter = poscounter + 1;
}
if (feature.properties.mag < 0) {
negcounter = negcounter + 1;
}
return L.circleMarker(latlng, {
radius: 3,
fillColor: styleMarker(feature),
color: styleMarker(feature),
weight: 1,
opacity: 1,
fillOpacity: 0.8
}
).bindPopup(mypopup);
}
}).addTo(layerGroup);
document.getElementById('strikecount').value = counter + " / " + poscounter + " / " + negcounter;
drawnItems.clearLayers();
//document.getElementById("current").innerHTML = 'Total Displayed Strikes: ' + counter;
}
counter = 0;
poscounter = 0;
negcounter = 0;
document.getElementById('strikecount').value = counter + " / " + poscounter + " / " + negcounter;
function generate_kml(data) {
fetch("https://wx.stoat.org/cgi-bin/ltg.py", {
method: "POST",
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
}).then((res) => res.blob())
.then((blob) => URL.createObjectURL(blob))
.then((href) => {
Object.assign(document.createElement('a'), {
href,
download: 'RLXltg.kml',
}).click();
});
}
function styleMarker(feature) {
if (feature.properties.mag > 0) {
return 'red';
}
if (feature.properties.mag < 0) {
return 'blue';
}
}
function clearstrikes() {
layerGroup.clearLayers();
counter = 0;
poscounter = 0;
negcounter = 0;
document.getElementById('strikecount').value = counter;
}
var layerGroup = L.layerGroup().addTo(mymap);
</script>
</body>
</html>