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

204 lines
10 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NWS VTEC Browser</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.13.2/themes/smoothness/jquery-ui.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.8.0/dist/leaflet.css" integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9+580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.8.0/dist/leaflet.js" integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ==" crossorigin=""></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@^2.0.0/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@turf/turf@6.5.0/turf.min.js"></script>
<!-- CSS -->
<style type="text/css">
body, html {
height: 100%; width: 100%; margin: 0; padding: 0; font-family: sans-serif;
}
#container {
display: flex; height: 100%; width: 100%;
}
#map-container {
flex-grow: 1; height: 100%; display: flex; flex-direction: column;
}
#mapid {
flex-grow: 1; width: 100%; z-index: 1;
}
#summary-container {
height: 60%; /* Adjust map/summary ratio (higher % = smaller map) */
overflow-y: auto; padding: 15px; background: #f9f9f9;
border-top: 1px solid #ddd; line-height: 1.4; box-sizing: border-box;
}
#summary-container img {
max-width: calc(100% - 450px); height: auto; border: 1px solid #ccc; margin-top: 10px;
margin-bottom: 10px; display: block;
}
#summary-container h2 {
margin-top: 0; margin-bottom: 10px; padding-bottom: 5px; border-bottom: 2px solid #ccc;
}
#summary-container h3 {
margin-top: 18px; margin-bottom: 8px; padding-bottom: 3px; border-bottom: 1px solid #eee;
}
#summary-container h4 { margin-top: 10px; margin-bottom: 5px; }
#summary-container p { margin-top: 0.5em; margin-bottom: 0.5em; }
#summary-container ul { margin-top: 0.5em; padding-left: 25px; }
#summary-container li { margin-bottom: 0.4em; }
#summary-container .gauge-summary { margin-bottom: 20px; border-top: 1px solid #eee; padding-top: 10px; }
#summary-container .event-summary-item { border-left-width: 5px; border-left-style: solid; padding-left: 10px; margin-bottom: 15px; }
#copySummaryBtn {
float: right; margin-bottom: 10px; padding: 5px 10px; cursor: pointer; border: 1px solid #ccc;
background-color: #f0f0f0; border-radius: 3px; font-size: 0.9em;
}
#copySummaryBtn:hover { background-color: #e0e0e0; }
#controls {
width: 400px; /* Set the desired width */
flex-shrink: 0; /* Prevent the item from shrinking */
padding: 10px;
background: #f0f0f0;
overflow-y: auto;
border-right: 1px solid #ccc;
z-index: 1000;
display: flex;
flex-direction: column;
box-sizing: border-box;
}
#controls label, #controls select, #controls input[type=number], #controls input[type=text], #controls input[type=button] {
display: block;
margin-bottom: 8px;
width: 100%; /* Make controls fill width */
box-sizing: border-box;
}
#controls select[multiple] {
height: 250px;
width: 100%;
box-sizing: border-box;
}
/* Leaflet Layer Styling */
.my-label { /* County Labels */
font-size: 8px; font-weight: bold; color: #333; background-color: rgba(255, 255, 255, 0.7);
border: 0px; border-radius: 3px; padding: 1px 3px; white-space: nowrap; pointer-events: none;
}
.leaflet-tooltip { /* Optional overrides for base tooltip */ }
.lsr-label-tooltip {
font-size: 9px !important; font-weight: bold !important; color: black !important; white-space: nowrap;
background: transparent !important; border: none !important; box-shadow: none !important;
padding: 0 !important; margin: 0 !important; display: inline-block; text-align: center;
vertical-align: middle; pointer-events: none;
}
/* Hide the template canvas */
#hydrograph-canvas-template { display: none; }
#summary-container ul.analysis-list {
margin-top: 0; /* Remove extra space above list */
padding-left: 25px; /* Keep indentation */
list-style-type: disc; /* Or desired bullet style */
}
/* Style for the per-zone verification list */
#summary-container .zone-verification-list {
margin-top: 0; /* Remove extra space above list */
padding-left: 25px; /* Keep indentation */
list-style-type: disc; /* Or desired bullet style */
font-size: 0.9em; /* Match other sub-details */
}
#summary-container .zone-verification-list li {
margin-bottom: 0.2em; /* Smaller spacing between zones */
}
/* Style for export buttons */
#export-controls {
margin-top: 15px;
border-top: 1px solid #ccc;
padding-top: 10px;
}
#export-controls h3 {
margin-bottom: 5px;
}
#export-controls input[type=button] {
background-color: #e7e7e7;
border: 1px solid #ccc;
padding: 6px 12px;
cursor: pointer;
margin-top: 5px; /* Space between buttons */
}
#export-controls input[type=button]:hover {
background-color: #d7d7d7;
}
#export-controls input[type=button]:disabled {
background-color: #f5f5f5;
color: #aaa;
cursor: not-allowed;
}
</style>
</head>
<body>
<div id="container">
<div id="controls">
<h3>Select Products</h3>
<label for="yeartowork">Choose a year:</label>
<select name="yeartowork" id="yeartowork" onchange="getwwas()">
<option value="2025">2025</option>
<option value="2024">2024</option>
<option value="2023">2023</option>
<option value="2022">2022</option>
</select>
<!-- Event selector added by JS -->
<label for="eventFilterInput" style="margin-top: 15px;">Filter Events:</label>
<input type="text" id="eventFilterInput" placeholder="Type to filter list..." />
<h3>Options</h3>
<label for="lsrbuffer">Time Buffer for Reports (hrs):</label>
<input id="lsrbuffer" name="lsrbuffer" type="number" value="1">
<label for="powerthresh">Power Outage Threshold for Reporting:</label>
<input id="powerthresh" name="powerthresh" type="number" value="50">
<input id="generateSummaryBtn" type="button" value="Generate Summary" onclick="generateSummaryForSelectedEvents();" style="margin-top: 15px; font-weight: bold; background-color: #add8e6;" />
<!-- Export Controls Section -->
<div id="export-controls">
<h3>Export Options</h3>
<input type="button" id="exportLsrCsvBtn" value="Export All Reports (CSV)" onclick="generateLsrCsv();" disabled>
<input type="button" id="exportKmlBtn" value="Export Products/Reports (KML)" onclick="generateKml();" disabled>
Note: Reports not from LSRs (power outage, DOT, 911, etc) will be filtered if an LSR has already been issued within 1 mile of them.
</div>
</div>
<div id="map-container">
<div id="mapid"></div>
<div id="summary-container">
<!-- Copy button will be added here by JS in buildHtmlSummary -->
<p>Select one or more warnings and click "Generate Summary".</p>
<!-- Summary content will be generated here -->
</div>
</div>
</div>
<script>
let mymap;
let geoJSONwwas; // Layer for selected warning polygons
let geoJSONcounties; // Layer for county/zone outlines & zone lookup
let markersLayer; // Layer for LSR markers (Filtered by selected product polygons)
let gaugeMarkersLayer; // Layer for NWS Gauge markers
let currentSelectedEvents = []; // Raw event objects selected by the user
let currentSelectedEventDetails = []; // Detailed info { event, data, fullDetails } for selected events
let unfilteredLSRs = { type: "FeatureCollection", features: [] }; // Stores ALL LSRs fetched for the time range + buffer
let hydrographCharts = {}; // Keep track of Chart.js instances if needed (though now generating images directly)
let prePlotLayer; // Layer for pre-plotting selected warnings
let eventGeometryCache = {}; // Simple cache for event geometry { 'phen|sig|etn|year': geoJsonData }
</script>
<!-- Core helper functions (constants, lookups, LSR verification helpers, contrast colors, status calculations) -->
<script src="stormdata/core_helpers.js"></script>
<!-- Utility functions (date formatting, formatting helpers, utility functions) -->
<script src="stormdata/utility_functions.js"></script>
<!-- Data fetching functions (fetching from APIs, data retrieval helpers) -->
<script src="stormdata/data_fetching.js"></script>
<!-- Parsing functions (NWS product parsing, time string parsing, text parsing) -->
<script src="stormdata/parsing_functions.js"></script>
<!-- Analysis functions (hydrograph analysis, LSR processing, data analysis) -->
<script src="stormdata/analysis_functions.js"></script>
<!-- Hydro functions (gauge handling, hydrograph generation, water data functions) -->
<script src="stormdata/hydro_functions.js"></script>
<!-- Map functions (map setup, styling, Leaflet helpers, marker creation) -->
<script src="stormdata/map_functions.js"></script>
<!-- Event handling functions (VTEC event handling, selection, summary generation triggers) -->
<script src="stormdata/event_handling_functions.js"></script>
<!-- UI/Summary functions (HTML generation, summary building, export functions) -->
<script src="stormdata/ui_summary_functions.js"></script>
<canvas id="hydrograph-canvas-template" width="800" height="450" style="display: none;"></canvas>
</body>
</html>