地理数据分析常用工具

在地理空间数据分析中,常用一些模块进行地理数据分析、特征提取及可视化,包括shapely、geopandas、folium、kepler.gl、geohash等工具。

1. shapely

shapely是基于笛卡尔坐标的几何对象操作和分析Python库,底层基于GEOS和JTS拓扑运算库。

1.1 Point对象
1
2
3
4
5
6
7
8
9
10
11
from shapely.geometry import Point

point1 = Point(1, 1)
point2 = Point(5, 5)
point3 = Point(10, 10)

#点的可视化
geo.GeometryCollection([point1,point2,point3])

#Point转为numpy数组
print(np.array(point))
1.2 LineString对象
1
2
3
# 创建LineString对象
line1 = geo.LineString([(0,0),(2,-2.2),(3,3.3),(4,-4.4),(5,-5.5),(6,6.6)])
line1
1
2
3
4
5
#点和线的可视化
geo.GeometryCollection([line1,Point(1,1)])

#计算点线或线线的最短距离
print ('点线距离:'+str(Point(1,1).distance(line1)))
1
2
3
#几何中心
center = line1.centroid
geo.GeometryCollection([line1,center])
1
2
3
#几何对象的最小外接矩形
b_rect = line1.envelope
geo.GeometryCollection([line1,b_rect])
1
2
3
 #简化线(Douglas-Pucker算法)
line1_simplify = line1.simplify(0.4, preserve_topology=False)
line1
1
2
3
#生成线的缓冲区
buffer_with_circle = line1.buffer(0.3)
geo.GeometryCollection([line1,buffer_with_circle])
1.3 LinearRings对象
1
2
3
4
from shapely.geometry.polygon import LinearRing

ring = geo.polygon.LinearRing([(0, 0), (1, -1), (1, 0)])
geo.GeometryCollection([ring])
1.4 Polygon对象
1
2
3
4
from shapely.geometry import Polygon

poly1 = Polygon([(0,0),(2,0),(1,-1),(-3,1),(0,0)]) #起点和终点相同
poly1
1
2
3
4
#通过numpy生成多边形
coords = np.array([(0,0),(1,0.1),(2,0),(1,2),(0,0)])
poly2 = Polygon(coords)
poly2
1
2
#多个polygon的集合
geo.GeometryCollection([poly1,poly2])
1
2
3
#几何中心
center = poly1.centroid #几何中心
geo.GeometryCollection([center,poly1])
1
2
3
#最小外接矩形
rect = poly1.minimum_rotated_rectangle #最小外接矩形
geo.GeometryCollection([rect,poly1])
1
poly1.boundary#边缘
1
poly2.simplify(0.5)#简化面
1
2
3
4
5
6
7
8
r1 = poly2.contains(point2) #面点关系
print(r1)

r2 = poly2.intersects(line1) #面线关系
print(r2)

r3 = poly1.intersects(poly2) #面面关系
print(r3)
1
2
3
poly1.intersection(poly2) #面面交集
poly1.union(poly2) #面面并集
poly2.difference(poly1) #面面补集

2. geopandas

geopandas是pandas在地理数据处理领域的扩展包,其核心数据结构是GeoSeries和GeoDataFrame。
geopandasd 主要功能为:

1.文件读写
2.空间查询
3.坐标转换
4.空间join
5.地理数据可视化

2.1 文件读写

geopandas可读geojson和shp等空间文件,也可读含有geometry字段的csv文件。

1
2
3
4
5
6
import numpy as np 
import pandas as pd
import shapely
import geopandas as gpd
from shapely import wkt
from shapely import geometry as geo
1
2
3
4
#读取geojson
countries = gpd.read_file("dfcountries.geojson",bbox = [-180,-80,180,80])
countries.plot()#显示图
countries #显示表格
1
2
3
4
#读取shp
cities = gpd.GeoDataFrame.from_file('./cities.shp', encoding='utf-8')
cities.plot()#显示图
cities #显示表格

f1

1
2
3
4
5
6
#保存成geojson
countries.to_file("dfcountries.geojson",driver = "GeoJSON")
#保存成csv
cities.to_csv("dfcountries.csv",index = False,sep = "\t")
#保存成shp
cities.to_file(".a/cities.shp")
1
2
3
4
5
#按值的大小填充颜色
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(9,6),dpi = 100)
cities.plot('area',ax = ax,legend = True)
plt.show()

f2

3.Folium

folium是一种交互式动态地图接口,可以用来画热力图、填充地图、路径图、散点标记等图。

1
2
3
4
5
import folium
import os
#指定坐标中心和缩放尺寸,生成交互式地图
m = folium.Map(location=[30.33,120.37],zoom_start=10)
m

f3

1
2
3
4
5
6
from folium.plugins import HeatMap
#生成随机数据,指定坐标中心和缩放尺寸,生成热力图
data=(np.random.normal(size=(100,3))*np.array([[1,1,1]])+np.array([[30.33,120.37,1]])).tolist()
m=folium.Map([30.33,120.37],tiles='Stamen Toner',zoom_start=6)
HeatMap(data).add_to(m)
m

f4

folium的MarkerCluster()聚类函数,可以用来反映一个区域的拥挤程度。

1
2
3
4
5
6
7
8
9
10
11
12
from folium.plugins import MarkerCluster

#创建对象
marker_cluster = MarkerCluster().add_to(m)

#将经纬度加入聚类
for element in data:
folium.Marker(location=[element[0], element[1]],icon=None).add_to(marker_cluster)

#添加至地图
m.add_child(marker_cluster)
m

4.Kepler.gl

Kepler.gl是Uber联合Mapbox推出的地理空间可视化工具,支持3种数据格式:CSV、JSON、GeoJSON。接下来将以杭州市OSM路网为例,制作路径流动动画。

1
2
3
from keplergl import KeplerGl
import json
import time
1
2
3
#读取geojson
with open('./hzroad.json',encoding='gb18030', errors='ignore') as g:
raw_roads = json.load(g)
1
2
3
4
5
6
7
8
9
10
11
12
#生成虚构时间戳信息和高度0
start_time = time.mktime(time.strptime('2020-05-29 20:00:00', "%Y-%m-%d %H:%M:%S"))

for i in range(raw_roads['features'].__len__()):
for j in range(raw_roads['features'][i]['geometry']['coordinates'].__len__()):
# 更新当前对应的时间戳
shift_time = int((j / raw_roads['features'][i]['geometry']['coordinates'].__len__())*3600)

# 高度设置为0
raw_roads['features'][i]['geometry']['coordinates'][j] \
.extend([0,
int(start_time) + shift_time])
1
2
3
4
5
6
from keplergl import KeplerGl
# 生成KeplerGl对象
m = KeplerGl(height=400,
data={'flow': raw_roads}) # data以图层名为键,对应的矢量数据为值
m
m.save_to_html(file_name='./hangzhou.html')

5.Geohash

GeoHash是一种地址编码方法,可以将地理经纬度坐标编码为由字母和数字所构成的字符串。其原理类似哈希表:由于遍历列表查找时间复杂度高,而创建散列函数能够更高效地定位数据。而GeoHash将二维的经纬度坐标编码到一维的字符串中,在做地理位置索引时只需匹配字符串,便于信息的缓存和压缩。

GeoHash采用二分法不断缩小经度和纬度的区间来进行二进制编码,最后将经纬度分别产生的编码奇偶位交叉合并,再用字母数字表示。

f6

p.s. 酷炫动图见公众号

欢迎关注我们的公众号
0%