用USGS接口做乡镇级地震速报,我踩到的三个坑
去年给一个乡镇做应急值班工具,需求很简单:地震发生后,值班员能第一时间在手机上看到附近的地震信息,不用自己去官网刷。数据源选了 USGS 的 GeoJSON 接口。环境是 Python 3.10 + requests,部署在乡镇一台常年开机的旧笔记本上,网络是普通宽带。
接口调用本身不复杂:
import requests, datetime
def fetch_quakes(minmag=3.0, days=1):
end = datetime.datetime.utcnow()
start = end - datetime.timedelta(days=days)
url = "https://earthquake.usgs.gov/fdsnws/event/1/query"
params = {
"format": "geojson",
"starttime": start.strftime("%Y-%m-%dT%H:%M:%S"),
"endtime": end.strftime("%Y-%m-%dT%H:%M:%S"),
"minmagnitude": minmag,
"orderby": "time",
}
r = requests.get(url, params=params, timeout=20)
r.raise_for_status()
return r.json()["features"]
拿到 features 后按经纬度算距离,筛出半径 300 公里内的记录,再按震级和距离合成一个提醒等级。距离用 haversine,不引第三方库,二十行以内。
第一个坑是时区。接口的 time 是毫秒时间戳,我在展示层直接拿本地时间格式化,结果值班员看到的“发生时间”比实际早了 8 小时,差点被当成误报。后来统一走 UTC 存储、展示时再转。
第二个坑是“全球小震全量拉取”。一开始我把 minmagnitude 设成 0,想着一网打尽,结果单次返回几千条,旧笔记本解析要好几秒,偶尔还超时。改成 minmagnitude=2.5、按天分段拉,量降到几十到几百条,稳定多了。代价是极小的本地震可能漏掉——但对乡镇场景来说,震级太小的记录提醒价值也有限。
第三个坑最隐蔽:接口偶尔返回的 feature 里 properties.mag 是 null。我第一次上线没做判空,某天一条记录直接让脚本抛异常退出,而值班员并不知道脚本挂了。现在所有字段都先 get 再判断,异常时写日志并保留上一次结果,不覆盖。
边界要提前说清:这套东西只做信息聚合,不做预警。USGS 的记录是台网测定后发布的,本身就有延迟,几十秒到几分钟不等;跨洋远震和近场小震的延迟差别很大。它不能替代官方速报,也不能用来做疏散判断。另外旧笔记本断网、接口限流、夏令时切换,都是实际遇到过的失效场景,值班流程里得留人工核对的环节。
你们在乡镇或园区做这类信息聚合时,是按行政边界筛还是按固定半径筛?固定半径在山区很容易把隔壁县的相关记录也带进来,我还没找到特别干净的划法。
0 条评论
还没有评论,写下第一条。