使用python绘制地震地图

前些天在办公时微信的一条公众号消息突然映入我眼帘

乐山地震

身处四川的我马上就想到要不绘制一个地震地图,看下自己周边的地震情况。

说干就干,在我脑海中马上就浮现了这么几个步骤:

1. 查询地震数据

于是我立马访问了中国地震台网,得到了近一年地震接口的API

返回的是一个jsonp的数据结构

当我们的请求地址为/ajax/speedsearch?num=6&page=9&callback=call时,返回的数据结构如下

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
call({
"shuju":[
{
"id": "45773",
"CATA_ID": "CD20231224195141.00",
"SAVE_TIME": "2023-12-24 20:00:50",
"O_TIME": "2023-12-24 19:51:41",
"EPI_LAT": "38.43",
"EPI_LON": "75.39",
"EPI_DEPTH": 142,
"AUTO_FLAG": "M",
"EQ_TYPE": "M",
"O_TIME_FRA": "0",
"M": "3.3",
"M_MS": "0",
"M_MS7": "0",
"M_ML": "0",
"M_MB": "0",
"M_MB2": "0",
"SUM_STN": "0",
"LOC_STN": "0",
"LOCATION_C": "新疆克孜勒苏州阿克陶县",
"LOCATION_S": "",
"CATA_TYPE": "",
"SYNC_TIME": "2023-12-24 20:00:56",
"IS_DEL": "",
"EQ_CATA_TYPE": "",
"NEW_DID": "CD20231224195141"
},
....
],
"jieguo":"最近一年地震信息",
"page": "<div class=\"paging\" style=\"margin-top: 0px;\">\n <div class=\"pagination\">\n <ul>\n \n\n <li class=\"page\"><a href=\"javascript:void (0)\" page=\"1\" alt=\"首页\" title=\"首页\">首页<\/a><\/li>\n <li class=\"page\"><a href=\"javascript:void(0)\" page=\"8\" alt=\"上一页\" title=\"上一页\">«<\/a><\/li>\n\n\n \n\n \n \n \n <li class=\"page\"><a href=\"javascript:void (0)\" page=\"5\">5<\/a><\/li>\n \n \n <li class=\"page\"><a href=\"javascript:void (0)\" page=\"6\">6<\/a><\/li>\n \n \n <li class=\"page\"><a href=\"javascript:void (0)\" page=\"7\">7<\/a><\/li>\n \n \n <li class=\"page\"><a href=\"javascript:void (0)\" page=\"8\">8<\/a><\/li>\n \n \n <li class=\"active\"><a href=\"javascript:void (0)\" page=\"9\" >9<\/a><\/li>\n\n \n <li class=\"page\"><a href=\"javascript:void (0)\" page=\"10\">10<\/a><\/li>\n \n \n <li class=\"page\"><a href=\"javascript:void (0)\" page=\"11\">11<\/a><\/li>\n \n \n <li class=\"page\"><a href=\"javascript:void (0)\" page=\"12\">12<\/a><\/li>\n \n \n <li class=\"page\"><a href=\"javascript:void (0)\" page=\"13\">13<\/a><\/li>\n \n \n <li class=\"page\"><a href=\"javascript:void(0)\" page=\"10\" title=\"下一页\" alt=\"下一页\">»<\/a><\/li>\n <li class=\"page\"><a href=\"javascript:void(0)\" page=\"55\" title=\"尾页\" alt=\"尾页\">尾页<\/a><\/li>\n \n <\/ul>\n <\/div>\n<\/div>\n",
"num": 55
})

当我们不传callback参数时,返回的数据如下

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
({
"shuju":[
{
"id": "45773",
"CATA_ID": "CD20231224195141.00",
"SAVE_TIME": "2023-12-24 20:00:50",
"O_TIME": "2023-12-24 19:51:41",
"EPI_LAT": "38.43",
"EPI_LON": "75.39",
"EPI_DEPTH": 142,
"AUTO_FLAG": "M",
"EQ_TYPE": "M",
"O_TIME_FRA": "0",
"M": "3.3",
"M_MS": "0",
"M_MS7": "0",
"M_ML": "0",
"M_MB": "0",
"M_MB2": "0",
"SUM_STN": "0",
"LOC_STN": "0",
"LOCATION_C": "新疆克孜勒苏州阿克陶县",
"LOCATION_S": "",
"CATA_TYPE": "",
"SYNC_TIME": "2023-12-24 20:00:56",
"IS_DEL": "",
"EQ_CATA_TYPE": "",
"NEW_DID": "CD20231224195141"
},
....
],
"jieguo":"最近一年地震信息",
"page": "<div class=\"paging\" style=\"margin-top: 0px;\">\n <div class=\"pagination\">\n <ul>\n \n\n <li class=\"page\"><a href=\"javascript:void (0)\" page=\"1\" alt=\"首页\" title=\"首页\">首页<\/a><\/li>\n <li class=\"page\"><a href=\"javascript:void(0)\" page=\"8\" alt=\"上一页\" title=\"上一页\">«<\/a><\/li>\n\n\n \n\n \n \n \n <li class=\"page\"><a href=\"javascript:void (0)\" page=\"5\">5<\/a><\/li>\n \n \n <li class=\"page\"><a href=\"javascript:void (0)\" page=\"6\">6<\/a><\/li>\n \n \n <li class=\"page\"><a href=\"javascript:void (0)\" page=\"7\">7<\/a><\/li>\n \n \n <li class=\"page\"><a href=\"javascript:void (0)\" page=\"8\">8<\/a><\/li>\n \n \n <li class=\"active\"><a href=\"javascript:void (0)\" page=\"9\" >9<\/a><\/li>\n\n \n <li class=\"page\"><a href=\"javascript:void (0)\" page=\"10\">10<\/a><\/li>\n \n \n <li class=\"page\"><a href=\"javascript:void (0)\" page=\"11\">11<\/a><\/li>\n \n \n <li class=\"page\"><a href=\"javascript:void (0)\" page=\"12\">12<\/a><\/li>\n \n \n <li class=\"page\"><a href=\"javascript:void (0)\" page=\"13\">13<\/a><\/li>\n \n \n <li class=\"page\"><a href=\"javascript:void(0)\" page=\"10\" title=\"下一页\" alt=\"下一页\">»<\/a><\/li>\n <li class=\"page\"><a href=\"javascript:void(0)\" page=\"55\" title=\"尾页\" alt=\"尾页\">尾页<\/a><\/li>\n \n <\/ul>\n <\/div>\n<\/div>\n",
"num": 55
})

我们需要的是jsonp数据结构中的json参数数据,我们只需要通过字符串截取第一个到倒数第一个之间的数据即可;

1
2
3
4
5
6
7
8
9
10
11
12
import requests
import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

def dataSource(pageNo):
response = requests.get(url='https://www.ceic.ac.cn/ajax/speedsearch?num=6&page=%d' % pageNo, verify=False)
text = response.text
text = text[1:len(text) - 1]
json_data = json.loads(text)
last_page = int(json_data['num'])
return last_page, json_data['shuju']

2. 绘制地图

绘制地图采用的是folium库,通过如下简单的代码,便绘制出了一个地图,并保存到了html文件中

1
2
3
4
import folium

world_map = folium.Map()
world_map.save('map.html')

更多关于folium库的使用,请参考Python地图可视化之Folium – 标点符,我使用的folium的版本是0.15.1

3. 将地震坐标绘制到地图中

通过前面的两步,已经拿到了地震数据和地图,剩下的工作就是将地震坐标渲染到地图上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import folium

world_map = folium.Map()
incidents = folium.map.FeatureGroup()

page = 1
while True:
    last, data = dataSource(page)
    for item in data:
        incidents.add_child(folium.CircleMarker(
        [float(item['EPI_LAT']), float(item['EPI_LON'])],
            radius=7,
            color='yellow',
            fill=True,
            fill_color='red',
            fill_opacity=0.4
        ))
    page += 1
    if page >= last:
        break

world_map.add_child(incidents)
world_map.save('map.html')

最后看一下渲染后的结果

地震地图

4. 注意的地方

在实际项目过程中可能还会碰到如下问题,提供一些思路

4.1 过滤区域,例如只展示中国的地震数据

  • 调用地图厂商API,例如高德、百度等,传入经纬度,根据返回的国家、省份信息进行数据过滤

  • 使用GeoJSON数据,具体的实现请参考文章如何使用经纬度反查地理位置?

4.2 坐标系转换

目前我们常说的有三种坐标系

  • WGS-84:是国际标准,GPS坐标(Google Earth使用、或者GPS模块)

    地球坐标系,国际上通用的坐标系。 设备一般包含GPS芯片或者北斗芯片获取的经纬度为WGS84地理坐标系。谷歌地图采用的是WGS84地理坐标系(中国范围除外,谷歌中国地图采用的是GCJ02地理坐标系。)

  • GCJ-02:中国坐标偏移标准,Google Map、高德、腾讯使用

    火星坐标系,WGS84坐标系经加密后的坐标系。 出于国家安全考虑,国内所有导航电子地图必须使用国家测绘局制定的加密坐标系统,即将一个真实的经纬度坐标加密成一个不正确的经纬度坐标。

  • BD-09:百度坐标偏移标准,Baidu Map使用

    百度坐标系,在GCJ02坐标系基础上再次加密。其中bd09ll表示百度经纬度坐标,bd09mc表示百度墨卡托米制坐标。

具体的转换方式请根据自己使用的开发语言,使用对应的依赖库或者转换算法实现,本文不过多描述


使用python绘制地震地图
https://blog.jervain.site/2025/0399e01d79.html
作者
Jervain
发布于
2025年3月25日
许可协议