自然灾害数据是理解地球动态系统中风险分布的基础信息载体。不同的灾害类型、不同的时空尺度、不同的严重程度,构成了一个多维的信息网络。将这些分散的、异构的灾害事件数据汇聚为一个统一的可比较、可筛选、可追溯的整体,是人类在面对自然灾害时从被动响应走向主动认知的关键一步。
真正的价值不在于数据的简单罗列,而在于通过结构化的分类与可视化的表达,揭示灾害发生的时空规律、类型分布与严重程度格局。当数据从孤立的事件描述转化为可交互的知识图谱时,决策者才能在对的时间、对的地点、以前瞻性的视角做出判断——这正是灾害数据聚合分析所承载的深层使命。
灾害事件数据的聚合分析,遵循"获取—解析—筛选—统计—可视化—导出"的六步方法论。
步骤一:数据获取
从权威灾害监测机构的数据接口获取原始数据。请求需携带必要的筛选参数,包括灾害类型(地震、热带气旋、洪水、火山、干旱、野火)、警报级别(绿/橙/红)、时间范围以及分页信息。参数通过查询字符串编码,以标准 HTTP 协议发送请求并接收响应。
步骤二:数据解析与标准化
原始响应数据采用地理信息领域标准的空间数据交换格式(GeoJSON)。解析时需遍历特征集合中的每个要素,提取其属性字段(事件编号、标题、类型、国家、时间、警报级别、严重程度、受灾人口)和几何字段(经纬度坐标)。同时还需兼容数组格式的备选响应结构,确保对不同版本接口的适配能力。
除了 JSON 格式外,部分数据源也以 XML 格式的订阅源方式提供。对于 XML 数据,需要构建文档对象模型树并遍历其中的条目节点,通过命名空间区分自定义字段与标准字段,从中提取相同的事件属性。两种格式的数据经过解析后应统一映射为相同的内部数据结构,保证后续处理的一致性。
步骤三:多维筛选与分页
用户根据需求选择灾害类型、警报等级和时间区间进行过滤。时间区间校验是关键环节:起始日期不得晚于截止日期,区间跨度需控制在一年的合理范围内。筛选结果按页分割,每页固定数量,通过页码索引实现数据的分批浏览。
步骤四:统计分析与可视化
对筛选后的事件集合进行三类统计:
图表需支持动态主题适配,特别是色彩空间从感知均匀空间到显示设备空间的实时转换,确保在不同配色环境下图表的可读性。
步骤五:数据导出
将内存中的结构化事件数据序列化为 JSON 文本,打包为二进制大对象,生成临时下载链接并触发浏览器下载。导出前确保数据已通过筛选与解析流程,内容是最终面向用户的有效数据。
设计原则
本项目在 TypeScript 中使用了以下技术栈和算法实现。
使用浏览器内置的 fetch 函数发起 HTTP GET 请求,通过 URLSearchParams 构建查询字符串。
const params = new URLSearchParams()
params.set('fromdate', startDate!)
params.set('todate', endDate!)
params.set('pagenumber', formData.pageNumber.toString())
params.set('pagesize', formData.pageSize.toString())
const url = `https://www.gdacs.org/gdacsapi/api/events/geteventlist/SEARCH?${params.toString()}`
const response = await fetch(url)
GDACS 接口返回的数据为 GeoJSON FeatureCollection 结构,核心数据结构定义如下:
export interface GdacsFeature {
type: string
properties: {
eventid: string
eventtype: string
name: string
title: string
alertlevel: string
severity: string
fromdate: string
todate: string
country: string
population: number
url: string
geometry: { type: string; coordinates: number[] }
}
geometry: { type: string; coordinates: number[] }
}
export interface GdacsApiResponse {
type: string
features: GdacsFeature[]
}
解析时将 FeatureCollection 中的每个 feature 映射为内部使用的 GdacsEvent 结构,同时兼容数组格式的直接响应:
if (jsonData.type === 'FeatureCollection' && jsonData.features) {
events = jsonData.features.map((feature: any) => {
const props = feature.properties || {}
const coords = feature.geometry?.coordinates || []
return {
id: props.eventid || '',
title: props.title || '',
latitude: parseFloat(props.latitude) || parseFloat(coords[1]) || 0,
longitude: parseFloat(props.longitude) || parseFloat(coords[0]) || 0,
// ... 其他字段映射
}
})
}
对于 XML 格式的 RSS 订阅源数据,使用浏览器内置 DOMParser 解析,并通过命名空间提取自定义字段:
function parseGdacsXml(xmlText: string): GdacsEvent[] {
const parser = new DOMParser()
const xmlDoc = parser.parseFromString(xmlText, 'text/xml')
const items = xmlDoc.querySelectorAll('item')
const gdacsNamespace = 'http://www.gdacs.org'
items.forEach((item) => {
const gdacsAlertLevel = getGdacsElementContent(item, gdacsNamespace, 'alertlevel')
const gdacsLat = parseFloat(getGdacsElementContent(item, gdacsNamespace, 'lat') || '0')
// ...
})
}
function getGdacsElementContent(
parent: Element, namespace: string, tagName: string
): string | null {
const elements = parent.getElementsByTagNameNS(namespace, tagName)
return elements.length > 0 ? elements[0]!.textContent : null
}
用于绘制交互式图表,支持环形图、柱状图、散点图三种类型。
echarts图表的 ECharts Option 通过工厂函数生成,以警报级别柱状图为例:
import * as echarts from 'echarts'
export function generateAlertLevelChart(
data: GdacsEvent[], theme: ChartThemeColors
): EChartsOption {
return {
backgroundColor: 'transparent',
tooltip: { trigger: 'axis' },
xAxis: {
type: 'category',
data: Object.keys(levelCounts),
},
yAxis: { type: 'value', name: '数量' },
series: [{
type: 'bar',
data: Object.entries(levelCounts).map(([level, count]) => ({
value: count,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: getAlertLevelColor(level) },
{ offset: 1, color: getAlertLevelColor(level) + '80' },
]),
},
})),
}],
}
}
本项目的核心算法之一:将 DaisyUI 主题使用的 OKLCH 色彩空间转换为 ECharts 渲染所需的 sRGB 十六进制颜色值。
export function oklchToHex(color: string): string {
const match = color.match(/oklch\(([\d.]+)(%?)\s+([\d.]+)\s+([\d.]+)\)/)
if (!match) return null
let L = parseFloat(match[1]!)
if (match[2] === '%' || L > 1) L = L / 100
const { L, C, H } = parts
// OKLCH → OKLab
const hRad = (H * Math.PI) / 180
const a = C * Math.cos(hRad)
const b = C * Math.sin(hRad)
// OKLab → Linear sRGB
const l_ = L + 0.3963377774 * a + 0.2158037573 * b
const m_ = L - 0.1055613458 * a - 0.0638541728 * b
const s_ = L - 0.0894841775 * a - 1.291485548 * b
const l3 = l_ * l_ * l_
const m3 = m_ * m_ * m_
const s3 = s_ * s_ * s_
let r = +4.0767416621 * l3 - 3.3077115913 * m3 + 0.2309699292 * s3
let g = -1.2684380046 * l3 + 2.6097574011 * m3 - 0.3413193965 * s3
let bl = -0.0041960863 * l3 - 0.7034186147 * m3 + 1.707614701 * s3
// Gamma 校正 (sRGB transfer function)
const gamma = (c: number) =>
c <= 0.0031308 ? 12.92 * c : 1.055 * Math.pow(c, 1 / 2.4) - 0.055
r = gamma(r); g = gamma(g); bl = gamma(bl)
// 输出十六进制
const hex = (c: number) => {
const v = Math.round(Math.max(0, Math.min(1, c)) * 255)
return v.toString(16).padStart(2, '0')
}
return `#${hex(r)}${hex(g)}${hex(bl)}`
}
转换路径:OKLCH → OKLab → Linear sRGB → Gamma校正 → sRGB HEX。
date-fnszhCN locale),用于日期选择器的界面显示。使用浏览器原生 API 实现客户端文件下载,无需服务端参与:
export function downloadJson(data: GdacsEvent[], filename: string = 'gdacs_events.json'): void {
const jsonStr = JSON.stringify(data, null, 2)
const blob = new Blob([jsonStr], { type: 'application/json' })
const url = URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.download = filename
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
URL.revokeObjectURL(url)
}
用户输入参数 → URLSearchParams 编码 → fetch() 请求 GDACS API
↓
GeoJSON / Array 响应
↓
数据标准化 (GdacsEvent[])
↓
┌─────────────────┼─────────────────┐
↓ ↓ ↓
环形图(Pie) 柱状图(Bar) 散点图(Scatter)
事件类型分布 警报级别统计 时间分布
↑ ↑ ↑
└─────────────────┼──────────────────┘
↓
ECharts Instance 渲染
(OKLCH→sRGB 主题色注入)
↓
JSON.stringify → Blob → 下载
从 GDACS 获取全球灾害事件数据
本工具从全球灾害预警与协调系统(GDACS)获取实时的全球自然灾害事件数据,支持按事件类型、警报级别和时间范围进行筛选查询。查询结果以统计概览、可视化图表和事件列表三种形式呈现,并支持将数据导出为 JSON 文件。
| 筛选项 | 可选值 |
|---|---|
| 事件类型 | 全部类型 / 地震 / 热带气旋 / 洪水 / 火山 / 干旱 / 野火 |
| 警报级别 | 全部级别 / 绿色 / 橙色 / 红色 |
| 开始日期 | 1900-01-01 至 当日,默认 30 天前 |
| 结束日期 | 不早于开始日期,不晚于当日,默认当日 |
设置查询条件:在页面上方的查询参数区域,分别选择事件类型、警报级别、开始日期和结束日期。事件类型和警报级别选择"全部"可获取全量数据。日期通过日期选择器点选。
发起查询:点击"查询数据"按钮。系统将向 GDACS 服务器发送请求,按钮显示加载动画,请耐心等待。
查看结果:
翻页浏览:若事件数量超过每页 20 条,列表底部将出现分页控件。点击页码或"上一页/下一页"按钮切换页面。
导出数据:点击"下载 JSON"按钮,将当前查询的所有事件数据以 JSON 格式保存到本地文件。
清除结果:点击"清除结果"按钮可清空当前展示的所有数据,重新开始查询。
网络依赖:本工具直接请求 GDACS 官方网站的公开 API。如果 GDACS 服务器不可达或响应超时,查询将失败并显示错误提示。请确保网络畅通。GDACS 服务位于境外,国内用户可能出现访问延迟或失败,建议在网络状况良好时使用。
数据时效性:查询结果反映的是 GDACS 在当前时刻已收录的事件数据。不同时间段查询同一日期范围,结果可能会因 GDACS 数据更新而有所差异。事件列表和图表不会自动刷新,如需最新数据请重新点击"查询数据"。
时区说明:所有事件时间均为 UTC(协调世界时)。北京时间比 UTC 快 8 小时。例如列表中出现 10:00 的时间,对应的北京时间为当天 18:00。进行时间比对时请注意时区转换。
坐标精度:经纬度坐标保留四位小数。该精度足以标识灾害发生的大致区域,但不适用于需要精确定位的场景(如现场救援导航)。坐标来源于 GDACS 官方数据,本工具不做坐标变换或投影转换。
事件数据可能缺失部分字段:GDACS 对不同类型事件所提供的信息详细程度可能不一致。部分事件的描述、受灾人口或国别信息可能为空,这是数据源本身的限制,不属于工具异常。页面会对空值字段进行缺省显示处理。
图表与列表的数据一致性:图表和列表的数据来源于同一次查询结果,但图表会根据事件的特征字段(如类型、级别)进行聚合展示。在时间分布散点图中,由于同一时间可能重叠多个事件,图表展示的是趋势概览而非逐条明细。详细的事件级信息应以列表为准。
导出文件内容:下载的 JSON 文件包含当前查询返回的所有事件(不受分页限制),字段与页面展示的 GdacsEvent 结构一致。文件名默认为 gdacs_events.json,文件编码为 UTF-8。
鼠标悬停查看各省份的访问数据统计
所有评论均为匿名发布