Python加载basemap绘制分省地图

发布时间:2021-10-25 付费文章:6.6元

Talk is cheap

 

 

Python加载basemap绘制分省地图(Zip打包链接,270M)

内含中国基础地图+湾湾+九段线+西藏地区shp

basemap for python 3.6 3.7 whl

繁体字转中文.py

操作范例.ipython

背景

Bokeh的Geo采用谷歌地图API,无法调用;国内的百度、腾讯、高德API在热点图渲染时可以用,至于Echarts的使用,也出现了一些鸡肋功能,于是想从根源上解决这个问题。

代码

 

(一)注意在渲染全国地图时,一定要加上湾湾,确保政治正确:

这里有一个非常大的BUG,需要道友们注意!

gadm.org/download_count

上面这个网址很坑爹,差点让本主犯错。主要体现在以下几个方面:

1.竟然把湾湾作为独立数据包,而非整合在我华一个范围内;

2.竟然没有九段线;

3.最要命藏南达旺地区不在该数据包中,这个很要紧。

 

m= Basemap(llcrnrlon=77, llcrnrlat=14, urcrnrlon=140, urcrnrlat=51, projection='lcc', lat_1=33, lat_2=45, lon_0=100)
# m= Basemap(llcrnrlon=73, llcrnrlat=18, urcrnrlon=135, urcrnrlat=53)

# m.drawcountries(linewidth=0.5)
# m.drawcoastlines(linewidth=0.5)

m.readshapefile('gadm36_CHN_shp/gadm36_CHN_0',  'china', drawbounds=True)  # 中国,竟然没有湾湾,NND
m.readshapefile('gadm36_CHN_shp/gadm36_TWN_0',  'taiwan', drawbounds=True) # 湾湾,是中国的一部分

咋一看没有啥问题,实际上坑爹坑大了,藏南不在图中,导致本主的几个视频在我乎不能审核通过,再次也感谢知乎小编,虽然没有告诉本主原因,但是内心不安的本主,最终还是找出了原因。

m.readshapefile('gadm36_CHN_shp/simplied_china_country',  'china', drawbounds=True)  # 中国,没有湾湾
m.readshapefile('gadm36_CHN_shp/gadm36_TWN_0',  'taiwan', drawbounds=True) # 湾湾,是中国的一部分

于是,从新找了一个中国轮廓数据包,这里需要吐槽一下,不仅仅上面下载网址,甚至CSDN上面很多包都是错的,R他大爷:

虽然不知道知乎小编是怎么发现这个问题的,腾讯视频号那边就没有发现,嘿嘿。于是,本主赶紧删掉视频号一个已发布在视频号的视频,内心庆幸,还好发现的早!

地图选择器【高德地图】

本主在想,国内这些地图厂商为毛不能免费提供shp基础包,避免地理小白犯错?

回看,高德地图这个API还算不错,经过简单的操作,就可以获取西藏地区的shp数据:

 

url='https://geo.datav.aliyun.com/areas_v2/bound/540000.json'
res = json.loads(requests.get(url).content)
for i in res[ 'features']:
    if '西藏' in i['properties']['name']:
        xizang = i['geometry']['coordinates'][0][0]

with open('gadm36_CHN_shp/xizang.json', 'w') as result_file:
    json.dump(xizang, result_file)

一顿操作猛如虎,上九段线,重新来!

m.readshapefile('gadm36_CHN_shp/simplied_china_country',  'china', drawbounds=True)  # 中国,没有湾湾
m.readshapefile('gadm36_CHN_shp/gadm36_TWN_0',  'taiwan', drawbounds=True) # 湾湾,是中国的一部分
m.readshapefile('gadm36_CHN_shp/china_nine_dotted_line',  'nine_dotted_line', drawbounds=True)  # 九段线走起

# 重构西藏边界
with open('gadm36_CHN_shp/xizang.json', 'r') as result_file:
    xizang_shp_oral = json.load(result_file)
xizang_shap_ax = []
for i in xizang_shp_oral:
    xizang_shap_ax.append(m(i[0], i[1]))

#   省界
for info, shp in zip(m.states_info, m.states):
    proid = Converter('zh-hans').convert(info['NL_NAME_1'] ) # 简体
#     print(proid)
    if '西藏' in proid:
        poly = Polygon(xizang_shap_ax,
                       facecolor='g',alpha=0.3,
                       lw=3)
        ax.add_patch(poly)

终于,搞定了一部分,然后用PIL再在该图右下角增加九段线的大样图,完美!!!

 

(二)Basemap在读取shp地名时,部分地名竟然还是繁体字,必须改过来:

from langconv import *

traditional_sentence = '憂郁的灣灣烏龜'
Converter('zh-hans').convert(traditional_sentence)

Out[2]: '忧郁的湾湾乌龟'

 

(三)在绘制省市边界时,需要事先知道绘制范围,左下、右上经纬度边界。以陕西省为例:

 

fig = plt.figure(figsize=(16, 9))

ax = plt.gca()   # 获取当前绘图区的坐标系
bmap = Basemap(llcrnrlon=105,llcrnrlat=31,urcrnrlon=112,urcrnrlat=40,
            projection='lcc',lat_1=33,lat_2=45,lon_0=120)

# bmap.etopo()
bmap.bluemarble()

# 画省
shp_info = bmap.readshapefile('gadm36_CHN_shp/gadm36_CHN_1','states',drawbounds=False)


for info, shp in zip(bmap.states_info, bmap.states):
    #     proid = info['NAME_1'] # NAME_1代表各省的拼音
    proid = Converter('zh-hans').convert(info['NL_NAME_1'] ) # 汉语
    if '陕西' in proid:
        poly = Polygon(shp,facecolor='w',edgecolor='b', lw=0.2)
        ax.add_patch(poly)
# 画市
bmap.readshapefile(shapefile='gadm36_CHN_shp/gadm36_CHN_2',
                name='citys',
                drawbounds=True) # 市

for info, shp in zip(bmap.citys_info, bmap.citys):
    
#     proid = info['NAME_2']  # NAME_2 代表各市的拼音
    proid = Converter('zh-hans').convert(info['NL_NAME_2'] ) # 简体
#     print(proid)
    if "西安" in proid:
        poly = Polygon(shp,
                       facecolor='r',alpha=0.3,
                       lw=3)
        ax.add_patch(poly)
        
        

bmap.drawcoastlines()
bmap.drawcountries()


plt.title('陕西省')
# plt.savefig('fig_province.png', dpi=100, bbox_inches='tight')
plt.show()

至于再细化到某一城市,以及GIS级别的效果,需要你自行摸索了。最后再次强调,西藏地区最好使用高德地图API自行重构。本主已经打包为xizang.json。

下载

本主将以下文件打包:2020年初微信付费文章还没有出来了的时候,本主撸了一个打赏系统,需要的可以自行打赏提取。共270M。