使用 Javascript 可视化🔥世界各地🌍的活跃火灾🔥
最初发布在我的博客上
我们将学到什么?
在本文中,我们将了解如何通过Javascript 中的Znote使用Plotlyjs 和 Streams的开放数据来探索世界各地的活跃火灾数据。
活跃火灾数据
感谢美国国家航空航天局 (NASA ) 利用其两颗卫星(Aqua 和 Terra)上搭载的MODIS系统(中分辨率成像光谱仪)提供火灾位置和热异常,因此可以直观地看到火灾在全球范围内的分布情况。
从哪里获取数据?
最新的火灾数据可在此处获取。
如果您想探索历史,也可以在这里询问档案。
数据集描述
我们开始预览数据集,通过使用Danfojs进行简单打印来发现可用的列
const df = await dfd.readCSV("https://firms.modaps.eosdis.nasa.gov/data/active_fire/modis-c6.1/csv/MODIS_C6_1_Global_7d.csv");
print(df); // or df.ctypes to list all columns
完整数据集描述在这里
世界活跃火灾地图
每天每点就意味着一次新的火灾。看到每天都有这么多新的火灾发生,真是令人震惊。
如何构建这个地图?
const summer2022 = "/Users/alagrede/Desktop/modis-active-fires-7d.csv";
const content = _fs.readFileSync(summer2022, 'utf8'); // read data file
function show(date) {
// get lat/long fields for date given
const latLong = content.split('\n')
.filter(r=>String(r.split(",")[5]).startsWith(date))
.map(r => [r.split(",")[0], r.split(",")[1]]) // lat/long
latLong.shift(); // remove header
var data = [{
type: 'scattergeo',
lon: latLong.map(r=>r[1]),
lat: latLong.map(r=>r[0]),
marker: {size: 2, color:'red'}, // draw fires
}];
var layout = {
geo: {
scope: 'world',
resolution: 50,
showland: true,
showocean: true,
},
title: date,
};
Plotly.newPlot(el, data, layout);
}
// list days between 2 dates (functions used are described at the end of the article)
var daylist = await getDaysArray(new Date("2022-08-18"), new Date("2022-08-24"));
// loop over days
for(const day of daylist) {
show(day);
await sleep(500);
}
刷新数据(最近 7 天)ℹ️
现在我们可以创建一个函数来刷新数据并将其存储在文件中。最后一个 7d 文件可以直接在线获取。
const r = await fetch('https://firms.modaps.eosdis.nasa.gov/data/active_fire/modis-c6.1/csv/MODIS_C6_1_Global_7d.csv')
const content = await r.text();
_fs.writeFileSync('/Users/alagrede/Desktop/modis-active-fires-7d.csv', content);
聚焦一个国家
现在,您可以通过选择中心点并更改地图范围来关注您选择的特定国家/地区。
要查找特定的地理位置,请打开 Google 地图,选择一个点,然后复制/粘贴纬度/经度。
您可以在此处找到 Plotlyjs API 描述
var layout = {
geo: {
center: {lat: -46.449031, lon: 2.521705}, // France
projection: {scale: 1.5}, // zoom
scope: 'europe', // "africa" | "asia" | "europe" | "north america" | "south america" | "usa" | "world"
resolution: 50,
showland: true,
showocean: true,
},
title: date,
};
Plotly.newPlot(el, data, layout);
法国
如上所述,您可以添加滑块来及时手动导航
Plotly.newPlot(el+"-myGraph", data, layout);
// add a slider control (min - max - onChange callback)
const slider = await createSlider(0, daylist.length - 1, async function() {
show(daylist[slider.value]);
await sleep(200);
});
htmlEl.innerHTML=""; // reset result div
htmlEl.appendChild(slider); // add html slider
var graph = createElement("div"); // add the map into a div
graph.id = el+"-myGraph"; // plotly html id
htmlEl.appendChild(graph); // append map
show(daylist[0]);
2000年以来法国火灾的演变
现在我们知道了火灾发生的位置,看看自 2000 年以来火灾数量是如何变化的,可能会很有趣。
该表揭示了媒体报道的2003 年因欧洲强烈热浪而发生的异常火灾活动。
2019年创下森林火灾新纪录
:在法国,夏季中旬,过火面积超过2019年全年
2022年也创下新纪录……
法国史无前例的夏季野火,地图和图表
// All France fires count (make a ticket to ask history of fires)
const allfires = "/Users/alagrede/Desktop/fire_archive_M-C61_290304.csv";
const content = _fs.readFileSync(allfires, 'utf8');
const activeFires = content.split('\n');
activeFires.shift();
const count = activeFires
// map to month
.map(r=>String(r.split(",")[5]).slice(0,7)) // date field like 2008-08
// map to year
//.map(r=>String(r.split(",")[5]).slice(0,4)) // date field like 2008
// group by
.reduce((total, value) => {
total[value] = (total[value] || 0) + 1;
return total;
}, {});
const data = [{
y: Object.values(count),
x: Object.keys(count),
type: 'scatter'
}];
const layout = {
title: "Evolution of active fires",
height: 400,
width: 500
}
Plotly.newPlot(el, data, layout);
温度异常
气温方面,自21世纪初以来,气温呈现明显上升趋势。
这在一定程度上解释了火灾数量的增加以及记录频繁被打破的原因。
const r = await fetch('https://www.ncei.noaa.gov/access/monitoring/climate-at-a-glance/global/time-series/globe/land_ocean/ytd/12/1880-2016.json')
const json = await r.json();
//printJSON(json);
const result = Object.entries(json.data).map(year => [year[0], year[1]]);
const data = [{
y: result.map(r=>r[1]),
x: result.map(r=>r[0]),
type: 'scatter'
}];
const layout = {
title: "World temperature anomalies",
height: 400,
width: 500
}
Plotly.newPlot(el, data, layout);
世界
毫不奇怪,世界也正呈现同样的上升趋势。
其他大洲
与欧洲相比,非洲和南美洲大陆上宣布的新火灾数量确实令人恐惧…… 😅
脚本中使用的函数
async function getDaysArray(start, end) {
for(var arr=[],dt=new Date(start); dt<=new Date(end); dt.setDate(dt.getDate()+1)){
arr.push(new Date(dt).toISOString().slice(0,10));
}
return arr;
}
async function sleep(time) {
await new Promise(r => setTimeout(r, time));
}
async function createSlider(min, max, callback) {
var slider = createElement('input');
slider.type = 'range';
slider.min = min;
slider.max = max;
slider.value = 0;
slider.step = 1;
slider.style.marginLeft = "0px"
slider.style.width = "100%"
slider.addEventListener('input', callback, false);
return slider;
}
更进一步
对于那些想要进一步了解这个例子的人,完整的 Javascript 笔记本可以在我的Github repo中找到。
为了方便使用这些数据,本示例是使用交互式Znote应用程序制作的。
文章来源:https://dev.to/alagrede/visualize-active-fires-around-the-world-with-javascript-3heh