Python的地图库如何打点?

打算给最短路径算法做个可视化,基本思路是这样: 得到一些经纬度的坐标,然后把这些坐标在地图上画出来,再交互式地用鼠标选点,选一对点后计算得到他们的最短…
关注者
5
被浏览
6,421

2 个回答

使用geopandas提取地理信息数据并绘制地图

「—Python提取目标区域geojson数据,转换为shp文件并绘制地图」

内容概要

geopandas是建立在GEOS、GDAL、PROJ等开源地理空间计算相关框架之上,类似pandas语法风格的空间数据分析Python库,其能简化地理空间数据处理,减少对Arcgis等工具的依赖,使得处理地理空间数据变得更加高效简洁,打造纯Python式的空间数据处理工作流程。本案例是近期我遇到的一个实际需求,需要从广东省的geojson地理信息数据中,提取出珠三角城市群的数据,然后保存为shp文件绘制地图。

广东省及各子城市的geojson地理信息数据可从DataV.GeoAtlas平台进行免费下载,网址如下:

url:http://datav.aliyun.com/portal/school/atlas/area_selector

具体操作过程如下图所示:

选中广东省区域地图,下载保存json文件到本地电脑即可。

珠江三角洲城市群包括广州市、佛山市、肇庆市、深圳市、东莞市、惠州市、珠海市、中山市和江门市等九个城市地区。下面将分两小节详细介绍如何从geojson数据中提取珠三角城市群数据保存为shp文件并绘制地图。


1.提取目标区域geojson数据

导入需要使用的库和原始geojson数据,打印输出原始数据组成:

import geopandas as gpd
import matplotlib.pyplot as plt
import pandas as pd
from shapely import geometry
import os
plt.rcParams['font.sans-serif'] = 'Microsoft YaHei' # 设置字体为微软雅黑
# 使打印输出显示更全
pd.set_option('display.max_columns',500)
pd.set_option('display.width',1000)
# 读取广东省geojson数据
data = gpd.read_file('guangdong.json') 
print(data)

输出:

原始数据包含了广东省所有21个城市的地理信息数据。

接下来提取属于珠三角城市群的数据:

prd_city = ['广州市','佛山市','肇庆市',
            '深圳市','东莞市','惠州市',
            '珠海市','中山市','江门市']
prd_city_english = ['guangzhou','foshan','zhaoqing',
                    'shenzhen','dongguan','huizhou',
                    'zhuhai','zhongshan','jiangmen']
prd = data[data['name'].isin(prd_city)]
# 将列重命名缩短,防止保存为shp文件时因列名过程导致的警告
prd = prd.rename(columns = {'childrenNum':'childnum','subFeatureIndex':'rawIndex'}) 
print(prd)

输出结果:

成功提取出珠三角9个城市的geojson数据。

接下来将其转换为shp文件、保存到本地电脑:

# 创建一个储存shp文件的文件夹
if not os.path.exists('PRD'):
    os.mkdir('PRD')
# 保存为shp文件
prd.to_file('PRD/PRD.shp',
             driver='ESRI Shapefile',
             encoding='utf-8')

查看本地电脑上保存的shp文件:

这里需要注意,一个完整的shp文件必须包含cpg、dbf、prj、shp和shx等五个文件,之后移动shp文件导入到Arcgis或Qgis时需要一起完整地移动这五个文件,确保其在同一个文件夹中,否则会读取失败。


2.绘制珠三角城市群地图

使用上述保存在prd变量中的珠三角城市群geojson数据进行绘制地图:

# 绘制地图
fig,ax = plt.subplots(figsize=(8,6))
colors =  ['C0','C1','C2','C3','C4','C5','C6','C7','C8','C9']
p = prd.plot(ax=ax,color=colors,scheme="quantiles",edgecolor='grey',alpha=0.8,label=prd_city)
# 设置经纬度范围
ax.set_ylim(21.5,24.5)
ax.set_xlim(111,115.5)
# 设置轴标签为经纬度
ax.set_xticks(range(111,116,1),[str(x)+'°E' for x in range(111,116,1)])
ax.set_yticks(range(22,25,1),[str(x)+'°N' for x in range(22,25,1)])
# 给每块地图区域添加城市名称
for x, y, label in zip(prd.representative_point().x, prd.representative_point().y, prd['name']):
    ax.text(x-0.1, y, label, fontsize=10)
# 根据研究站点的经纬度,将其添加到地图上
GZ = gpd.GeoSeries([geometry.Point([113.5, 23.5])],crs='EPSG:4326')
FS = gpd.GeoSeries([geometry.Point([113, 23])],crs='EPSG:4326')
GZ.plot(ax=ax,marker='*',color='r',markersize=200,label='GZ site')
FS.plot(ax=ax,marker='*',color='b',markersize=200,label='FS site')
#设置网格线图例和标题
ax.grid(ls='--',alpha=0.8)
ax.legend(frameon=False)
ax.set_title('珠三角城市群',color='grey',fontsize=20,fontweight='bold')
# 保存输出图形
plt.tight_layout()
plt.savefig('PRD/珠三角城市群.png',dpi=600)
plt.show()

绘图结果:


以上就是本文的全部内容,如有笔误望指出。关于geopandas下一篇文章,我将介绍如何根据污染物浓度水平对各城市地图进行不同颜色的映射插值,敬请期待。