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