1. 程式人生 > >Python地學分析 — 通過GPS資料分析鳥類行蹤 07

Python地學分析 — 通過GPS資料分析鳥類行蹤 07

歡迎關注博主的微信公眾號:“智慧遙感”。

該公眾號將為您奉上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