{{ weatherStore.cityState }}
+Alerts
++ +
{{ feature.properties.headline }}
+{{ feature.properties.description }}
+diff --git a/src/router/index.js b/src/router/index.js
index 464d998..7430367 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -1,6 +1,7 @@
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import WeatherView from '../views/WeatherView.vue'
+import AlertsView from '../views/AlertsView.vue'
import HourlyView from '../views/HourlyView.vue'
import EditListView from '../views/EditListView.vue'
@@ -17,6 +18,11 @@ const router = createRouter({
name: 'weather',
component: WeatherView,
},
+ {
+ path: '/alerts',
+ name: 'alerts',
+ component: AlertsView,
+ },
{
path: '/hourly',
name: 'hourly',
diff --git a/src/stores/weather.js b/src/stores/weather.js
index c8c91ab..cf79fcf 100644
--- a/src/stores/weather.js
+++ b/src/stores/weather.js
@@ -10,6 +10,7 @@ const getDefaults = () => {
coordinates,
cityState,
weather: null,
+ alerts: null,
forecast: null,
radarLatestURL: null,
radarLoopURL: null,
@@ -32,14 +33,17 @@ export const useWeatherStore = defineStore('weather', {
this.setForecast(null)
this.radarLatestURL = null
this.radarLoopURL = null
+ this.alerts = null
},
async getWeather() {
if (!this.weather) {
+ let url
+ let response
- const url = `https://api.weather.gov/points/${this.coordinates}`
- const response = await fetch(url)
+ url = `https://api.weather.gov/points/${this.coordinates}`
+ response = await fetch(url)
const weather = await response.json()
if (weather.status == 404) {
throw new Error(`Data not found for ${this.coordinates}`)
@@ -57,6 +61,65 @@ export const useWeatherStore = defineStore('weather', {
this.radarLoopURL = `https://radar.weather.gov/ridge/standard/${station}_loop.gif`
this.setWeather(weather)
+
+ // fetch zone to get its official id
+ url = weather.properties.forecastZone
+ response = await fetch(url)
+ const zone = await response.json()
+
+ // fetch alerts for zone
+ url = `https://api.weather.gov/alerts/active/zone/${zone.properties.id}`
+ response = await fetch(url)
+ const zoneAlerts = await response.json()
+
+ // fetch county to get its official id
+ url = weather.properties.county
+ response = await fetch(url)
+ const county = await response.json()
+
+ // fetch alerts for county
+ url = `https://api.weather.gov/alerts/active/zone/${county.properties.id}`
+ response = await fetch(url)
+ const countyAlerts = await response.json()
+
+ const newAlerts = {}
+
+ // use latest timestamp from either zone or county
+ newAlerts.updated = zoneAlerts.updated
+ if (countyAlerts.updated > zoneAlerts.updated) {
+ newAlerts.updated = countyAlerts.updated
+ }
+
+ // collect all alert "features" but de-duplicate them
+ newAlerts.features = {}
+ for (let feature of zoneAlerts.features) {
+ newAlerts.features[feature.properties.id] = feature
+ }
+ for (let feature of countyAlerts.features) {
+ newAlerts.features[feature.properties.id] = feature
+ }
+ newAlerts.features = Object.values(newAlerts.features)
+
+ // put "likely" before "possible" alerts
+ newAlerts.features.sort((a, b) => {
+
+ if (a.properties.certainty == 'Likely' && b.properties.certainty == 'Possible') {
+ return -1
+ }
+ if (a.properties.certainty == 'Possible' && b.properties.certainty == 'Likely') {
+ return 1
+ }
+
+ // if (a.properties.certainty == b.properties.certainty) {
+ // return 0
+ // }
+
+ // TODO: what else should this do?
+ return 0
+ })
+
+ // we have our final alerts
+ this.alerts = newAlerts
}
return this.weather
diff --git a/src/views/AlertsView.vue b/src/views/AlertsView.vue
new file mode 100644
index 0000000..a397565
--- /dev/null
+++ b/src/views/AlertsView.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
+ {{ feature.properties.description }}{{ weatherStore.cityState }}
+ Alerts
+
+
+ {{ feature.properties.headline }}
+
Watches In Effect
+Updated {{ new Date(alerts.updated).toLocaleTimeString('en-US', {timeStyle: 'short'}) }}
+