Shapefile屬性操作之查


版權聲明:本文爲博主原創文章,轉載請註明原文出處!

作者:阿振

寫作時間:2020-06-13 夜


開篇

在前面幾篇博文中,我們分別介紹了矢量空間數據的屬性數據的增(CREATE)刪(DELETE)改(UPDATE)操作,這篇博文我們來聊聊屬性數據的查詢(Retrieve)操作。

案例介紹

我們還是使用之前的分省Shapefile數據,主要包含每個省的一些統計信息。下面以兩個案例進行介紹:

  1. 從給定數據中查詢中學數量(HighSchool字段)大於1萬所的省份
  2. 從給定數據中查詢中學數量最多的省份

下面簡單說一下使用GDAL進行屬性數據查詢的兩種思路:

  1. 因爲矢量數據的屬性一般都是以關係表進行保存的,所以我們可以使用關係數據庫查詢語言SQL進行數據查詢。GDAL支持部分SQL查詢功能。
  2. 我們可以遍歷圖層Layer中包含的所有Feature要素,然後讀取要素的屬性數據進行篩選過濾得到我們想要的結果。

SQL查詢方式

代碼展示

Talk is cheap. Show me the code.

首先,我們來看看使用SQL進行查詢的代碼。

from osgeo import ogr
ogr.UseExceptions()

ds: ogr.DataSource = ogr.Open('../data/Provinces.shp')
# 注意Layer的名稱不能包含中文
layer: ogr.Layer = ds.GetLayer()
# 選擇出中學數量大於1萬所的省份
query: str = f'SELECT NAME, HighSchool FROM {layer.GetName()} WHERE HighSchool > 10000'
selected: ogr.Layer = ds.ExecuteSQL(query)
# 這裏的Feature中只包含兩個屬性NAME和HighSchool
for feature in selected:
    print(feature.GetField('NAME'))

# 選擇出中學數量最多的省份
# 我嘗試使用MAX函數和嵌套的SELECT語句進行實現,但是執行報錯,應該是OGR不支持嵌套的SQL查詢
query: str = f'SELECT NAME, HighSchool FROM {layer.GetName()} ORDER BY HighSchool DESC'
selected: ogr.Layer = ds.ExecuteSQL(query)
print(selected.GetFeature(0).GetField('NAME'))
print(selected.GetFeature(0).GetField('HighSchool'))

方法總結

  1. 首先我們使用ogr.Open()函數讀取數據,使用GetLayer()方法獲取圖層
  2. 然後構造SQL查詢語句,圖層名稱對應的是SQL語句中的表名。注意如果圖層名稱爲中文,查詢會失敗。
  3. 然後使用ExecuteSQL()方法執行查詢,得到的查詢結果仍然是一個ogr.Layer圖層類,但是圖層中的要素屬性只包含我們查詢語句中指定的字段
  4. 對於第二個案例,我們本來可以使用一個嵌套的SELECT查詢語句以及MAX聚合函數得到最大的中學數量,但是使用嵌套的SQL查詢執行會失敗。所以我在第二個案例中使用了ORDER BY子句進行排序,然後查詢結果的第一個要素就是我們尋找的最大值。

遍歷Feature要素方式

代碼展示

我們再來看使用遍歷Feature要素的方法。

from osgeo import ogr
ogr.UseExceptions()

ds: ogr.DataSource = ogr.Open('../data/Provinces.shp')
# 注意Layer的名稱不能包含中文
layer: ogr.Layer = ds.GetLayer()
# 使用filter函數對要素屬性進行過濾
selected = list(filter(lambda f: f.GetField('HighSchool') > 10000, layer))
for feature in selected:
    print(feature.GetField('NAME'))

# 使用sorted方法對要素進行自定義排序,這裏使用逆序
selected = sorted(layer, key=lambda f: f.GetField('HighSchool'), reverse=True)
print(selected[0].GetField('NAME'))
print(selected[0].GetField('HighSchool'))

方法總結

  1. 使用遍歷Feature要素的方法進行查詢是我們在獲取了圖層包含的所有Feature要素集合以後,使用Python內置的函數對該集合進行過濾,排序等操作得到我們想要的查詢結果。
  2. filter()函數的第一個參數是一個自定義函數,第二個參數是一個可迭代對象iterable。該函數會遍歷可迭代對象將滿足第一個自定義函數的值過濾出來。
  3. sorted()函數包含三個參數(後兩個可選),第一個參數是一個可迭代對象iterable,第二個參數是用於自定義排序的函數,第三個參數指定是否逆序。sorted()函數的返回值是一個list對象。
  4. 我更喜歡使用第二種遍歷的方式,因爲更方便調試一些。當然如果對SQL語言熟悉的同學,可能更喜歡SQL這種聲明式編程的方式。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章