/
weather.qmd
103 lines (95 loc) · 2.7 KB
/
weather.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
---
title: Click on map to obtain NWS weekly forecast
echo: false
format:
dashboard:
orientation: columns
---
```{ojs}
//| output: false
us = FileAttachment("states-10m.json").json()
nation = topojson.feature(us, us.objects.nation)
proj = d3.geoAlbersUsa().fitSize([cards.map.width, cards.map.height], nation);
statemesh = topojson.mesh(us, us.objects.states, (a, b) => a !== b)
mutable mutCent = [-108.4569010952928, 36.85687898029089];
forecast = {
const resp = await fetch(`https://api.weather.gov/points/${mutCent[1]},${mutCent[0]}`);
if (resp.status !== 200) {
return {
place: "Unknown",
periods: []
}
}
const json = await resp.json();
if (json.properties.forecast) {
const forecastResp = await fetch(json.properties.forecast);
const tbl = await forecastResp.json();
const place = json.properties.relativeLocation.properties;
if (tbl.properties === undefined) {
return {
place: `${place.city}, ${place.state}`,
periods: [],
response1: json,
response2: tbl,
response2Status: forecastResp.status
}
}
return {
place: `${place.city}, ${place.state}`,
periods: tbl.properties.periods,
response1: json,
response2: tbl,
response2Status: forecastResp.status
};
}
return {
place: "",
periods: [],
}
}
```
## Column {width=60%}
```{ojs}
//| label: map
plot = {
const result = Plot.plot({
projection: proj,
length: { range: [0, 200] },
marks: [
Plot.geo(nation, { fill: "#e0e0e0" }),
Plot.geo(statemesh, { stroke: "white" }),
Plot.geo({
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": mutCent
},
}, { stroke: "red", radius: 2 })
],
});
result.onclick = function(evt) {
const width = Number(result.getAttribute("width"));
const height = Number(result.getAttribute("height"));
const v = proj.invert([evt.offsetX, evt.offsetY]);
mutable mutCent = v;
}
return result;
}
```
## Column {width=40%}
:::{.card title="Location: ${forecast.place}"}
```{ojs}
{
if (forecast.response2Status !== 200) {
return html`<div>NWS did not provide forecast</div>`;
}
return Inputs.table(forecast.periods.map(period => {
return {
time: period.name,
temperature: period.temperature,
wind: `${period.windDirection} at ${period.windSpeed}`
};
}))
}
```
:::