欢迎关注博主的微信公众号:“智能遥感”。
该公众号将为您奉上Python地学分析、爬虫、数据分析、Web开发、机器学习、深度学习等热门源代码。
本人的GitHub代码资料主页(持续更新中,多给Star,多Fork):
https://github.com/xbr2017
CSDN也在同步更新:
https://blog.csdn.net/XBR_2014
“ 本节通过鸟类GPS数据来分析鸟类行踪,有趣、好玩,赶紧来了解一下吧。”
每逢春运的时候,各大互联网公司通过GPS数据来分析全国各地人民的迁徙活动,其实这背后就涉及到地理信息系统的空间分析。本节以鸟类GPS数据来分析鸟类活动情况,如果你掌握了本节的方法,在获得人类活动GPS数据之后,也可以用此方法分析人类的活动,从中挖掘出有价值的信息。
本节数据来源于动物追踪数据库网站https://www.movebank.org/。先来看看鸟类活动的小视频吧!!!
编程环境
操作系统:windows
Python版本:2.7
IDE版本:PyCharm 2018.2.4专业版
数据格式转换
将下载的鸟类GPS数据保存为csv格式,然后转换为shapefile(简称shp)矢量数据。可以使用location-long和location-lat列中的x和y坐标来创建点和副本以及单个本地标识符和时间戳列作为属性。shp格式不支持真实的日期/时间字段,因此需要将时间戳信息保存为字符串。其代码如下所示:
# _*_ coding: utf-8 _*_
__author__ = 'xbr'
__date__ = '2018/11/12 11:51'
from osgeo import ogr, osr
# 动物的GPS数据
csv_fn = r"D:\osgeopy-data\Galapagos\Galapagos Albatrosses.csv"
# 先定义好即将输出的shp文件
shp_fn = r"D:\osgeopy-data\Galapagos\albatross_dd.shp"
# 定义为WGS84坐标系
sr = osr.SpatialReference(osr.SRS_WKT_WGS84)
# 获取驱动程序对象
shp_ds = ogr.GetDriverByName('ESRI Shapefile').CreateDataSource(shp_fn)
# 创建矢量点图层
shp_lyr = shp_ds.CreateLayer('albatross_dd', sr, ogr.wkbPoint)
# 添加属性字段:tag_id
shp_lyr.CreateField(ogr.FieldDefn('tag_id', ogr.OFTString))
# 添加属性字段:timestamp
shp_lyr.CreateField(ogr.FieldDefn('timestamp', ogr.OFTString))
# 创建空白特征,方便后面存储
shp_row = ogr.Feature(shp_lyr.GetLayerDefn())
csv_ds = ogr.Open(csv_fn)
csv_lyr = csv_ds.GetLayer()
# 主要实现将逐个CSV中的点存储到shp中
for csv_row in csv_lyr:
x = csv_row.GetFieldAsDouble('location-long')
y = csv_row.GetFieldAsDouble('location-lat')
# 创建几何点
shp_pt = ogr.Geometry(ogr.wkbPoint)
# 添加点
shp_pt.AddPoint(x, y)
tag_id = csv_row.GetField('individual-local-identifier')
timestamp = csv_row.GetField('timestamp')
# 添加点以及对应的属性tag_id和timestamp
shp_row.SetGeometry(shp_pt)
shp_row.SetField('tag_id', tag_id)
shp_row.SetField('timestamp', timestamp)
# 生成特征
shp_lyr.CreateFeature(shp_row)
del csv_ds, shp_ds
该代码将数据保存为shp文件,下面通过ArcGis软件来展示一下鸟类GPS活动点叠加在地图上的效果。
计算相邻点之间的距离
要计算距离,将要按顺序遍历每只鸟的点,然后计算每个位置与前一个位置之间的距离,因此你需要在循环时跟踪前一个点。这些点应该在原始.csv文件中的顺序正确,这意味着它们也在你创建的shapefile中按顺序排列,但是为了以防万一,你将添加要检查的代码。如果它确实发现了一些无序的点,它会抛出异常,以便纠正问题。代码如下:
# _*_ coding: utf-8 _*_
__author__ = 'xbr'
__date__ = '2018/11/13 22:07'
from osgeo import ogr, osr
# 从属性列获取唯一值的函数
def get_unique(datasource, layer_name, field_name):
sql = 'SELECT DISTINCT {0} FROM {1}'.format(field_name, layer_name)
lyr = datasource.ExecuteSQL (sql)
values = []
for row in lyr:
values.append(row.GetField(field_name))
datasource.ReleaseResultSet(lyr)
return values
# 计算相邻点之间的距离
ds = ogr.Open(r'D:\osgeopy-data\Galapagos', True)
lyr = ds.GetLayerByName('albatross_lambert')
lyr.CreateField(ogr.FieldDefn('distance', ogr.OFTReal))
tag_ids = get_unique(ds, 'albatross_lambert', 'tag_id')
for tag_id in tag_ids:
print('Processing ' + tag_id)
lyr.SetAttributeFilter("tag_id ='{}'".format(tag_id))
row = next(lyr)
previous_pt = row.geometry().Clone()
previous_time = row.GetField('timestamp')
for row in lyr:
current_time = row.GetField('timestamp')
if current_time < previous_time:
raise Exception('Timestamps out of order')
current_pt = row.geometry().Clone()
distance = current_pt.Distance(previous_pt)
row.SetField('distance', distance)
lyr.SetFeature(row)
previous_pt = current_pt
previous_time = current_time
del ds
获取最长距离
在能够计算相邻两点之间的距离之后,就可以计算每只鸟的总飞行距离,可以使用SQL查找哪些鸟具有按时间顺序下GPS之间的最长距离:
ds = ogr.Open(r'D:\osgeopy-data\Galapagos')
for tag_id in get_unique(ds, 'albatross_lambert', 'tag_id'):
sql = """SELECT MAX(distance) FROM albatross_lambert
WHERE tag_id = '{0}'""".format(tag_id)
lyr = ds.ExecuteSQL (sql)
for row in lyr:
print '{0}: {1}'.format(tag_id, row.GetField(0))
查找结果如下:
4264-84830852: 106053.530233
4266-84831108: 167097.198703
1103-1103: 69342.7642097