屬性過濾 【Python學習交流群:772882553】
OGR 屬性過濾,是利用 layer.SetAttributeFilter(filter_string) 函數進行要素篩選的。其參數 filter_string 即過濾條件,而這裡依據運算符類型將過濾條件分為了 4 類:比較運算符(Comparison Operators)、邏輯運算符(Logical Operators)、成員運算符(Membership Operators)以及模糊匹配(涉及通配符)。
一、比較運算符
為了將變量名添加至過濾字符串中,我們可以利用字符串對象的 format() 方法來格式化字符串:
二、邏輯運算符
上述 AND 運算符組成的過濾條件更推薦使用 BETWEEN AND 語句:
三、成員運算符
同樣地,我們可以用 format() 方法來格式化過濾條件:如下所示,多個字符串組成一個列表,但由於需要傳入一個元組,因此需要進行類型轉換:
四、模糊匹配
模糊匹配主要使用 LIKE 語句並配合通配符:首先模糊匹配不區分大小寫,另外,_(即下劃線)可以匹配任意單個字符,而 % 可以匹配任意數量的字符(0 至無數個),[char_list] 匹配字符列表中的任何單一字符,[^char_list](或 [!char_list])匹配不在字符列表中的任何單一字符。
接下來我們利用屬性過濾來改寫曾在 矢量數據的寫入 一文的開篇的個案例,具體代碼實現如下:這裡利用屬性過濾,並通過 CopyLayer() 函數將過濾後的圖層復制到新的圖層文件中,這樣改寫是不是簡單多了。
經驗總結:
1. 上述案例中,我若將過濾條件寫為 'FEATURECLA = "Admin-0 capital"',即外層單引號內層雙引號,則會報錯,因此,像這種引號內包含引號的語句,最好外層用雙引號,內層的字符串用單引號。
2. 我們在對某個圖層對象進行屬性過濾操作後,後續若還需要用到該圖層,則需要清除屬性過濾條件,只需給屬性過濾方法傳遞一個 None 值即可,如 lyr.SetAttributeFilter(None)。利用這一點,我們將上述案例的屬性過濾封裝一下:
空間過濾
空間過濾即利用空間范圍來篩選要素,可以用來選擇位於另一個要素內部或矩形邊界框內部的要素。還有一個必要條件:用於空間過濾的要素或坐標,必須與被篩選的圖層具有相同的空間參考系統。
一、位於另一個要素內部
語法:被過濾圖層.SetSpatialFilter(過濾要素的幾何對象)。
舉例:我們拿一個面圖層(代碼中的 filter_lyr)中的一個要素去過濾另外一個點圖層(即 be_filtered_lyr),顯然,這個面要素的范圍小於點圖層的范圍。
上述第二行代碼中,之所以利用 Clone() 函數,是為了防止過濾要素被刪除後,與其相關的幾何對象不再可用,這時,我們可以克隆一個幾何對象。
同樣地,和屬性過濾一樣,我們在對圖層對象進行空間過濾後,若後續用到該圖層,則需要清除空間過濾條件,即給空間過濾方法傳入一個 None 值即可。
二、位於邊界框內部
首先,可以利用過濾圖層的 lyr.GetExtent() 方法來獲取它的四至范圍,它會返回一個形如 (min_x,max_x,min_y,max_y) 的元組,然後利用上述四至范圍對被過濾圖層進行矩形框空間過濾,代碼如下:
注意:
1. 這裡要注意 SetSpatialFilterRect(min_x, min_y, max_x, max_y) 的參數的順序,不能將 GetExtent() 方法獲取的空間范圍直接帶入上述過濾方法。
2. 使用 SetSpatialFilterRect() 函數無法清除空間過濾。
倘若我們要對圖層進行更復雜的篩選,則可以借助 SQL(Structured Query Language,結構查詢語言)語句來進行過濾。
執行 sql 查詢需借助 ds.ExecuteSQL(sql 語句, [spatialFilter], [dialect) 函數(帶 [] 為可選參數):
注意:對於出錯的語句或篩選後沒有結果集的語句,SQL 查詢的結果為空。
spatialFilter:是針對結果做空間過濾,可以為空。
dialect:參數類型為字符串,用於說明 sql 語句用的是何種標准,可以為空,若為空則默認是 OGR 標准。
返回值:包含查詢結果的 OGRLayer。
我們借助 SQL 查詢語句繼續改寫第一小節屬性過濾中的例子,代碼實現如下:sql 語句要用 3 對引號包裹,若 WHERE 子句中存在字段串,則使用與外層不同類型的引號,這裡建議外層雙引號,內層單引號。
上述代碼中,使用 *(星號)來表示選取所有字段,這裡也可以指定需要的字段,接下來我們將總結一下 SQL 語句的相關語法。
一、SELECT 語句
SELECT 語句用於從表中選取數據,其後跟表中的字段名(列名稱),多個名稱之間用 ,(逗號)相連。
1. 選擇所有字段
可以使用 *(星號)來代表所有字段:當然不包括下面的特定字段。
2. 選擇內置的特殊字段
OGR SQL 標准中的內置的特殊字段見下表:
這裡針對上表中的字段列舉幾個官網上的例子:
3. 使用字段別名
若字段名比較長,我們可以使用 AS 關鍵字 來重命名一個簡潔一點的名字:
4. 更改字段類型
OGR SQL 支持使用 CAST 運算符 更改字段的類型,這裡給一個官方的例子:
支持轉換的類型如下:
5. DISTINCT 關鍵字
DISTINCT關鍵字 用於返回字段中唯一不同的屬性值,即去重。
6. 匯總運算符(summarization operators)
還可以借助函數來處理返回的字段的屬性值,如:COUNT(實例計數)、AVG(數值平均)、SUM(數值和)、MIN(數值最小值) 和 MAX(數值最大值)。
DISTINCT 關鍵字也可以和 COUNT() 結合使用:
7. 函數
這裡舉倆例子:個人覺得應該用不上
,最起碼用的不多。
二、WHERE 子句
WHERE 子句:有條件地從表中選取數據,語法如下:
我們設置條件會用到屬性查詢中的運算符,具體可以參考第一小節的屬性過濾中的講解,這裡列舉幾個官網上的例子:
三、ORDER BY 語句
ORDER BY 語句:根據指定的字段(列)進行排序,默認為升序排列,若要降序則加上 DESC 關鍵字(升序為關鍵字為 ASC)。
四、LIMIT 子句與 OFFSET 子句
LIMIT 子句:用於限制返回的記錄數;而 OFFSET 子句:表示偏移值,用於跳過的記錄數,例子如下:
五、表連接
OGR SQL 標准支持有限形式的一對一連接,原理:根據次表與查詢的主表之間的共享鍵,以查找次表中的記錄。
這裡舉個例子來說明:我們拿“ne_50m_populated_places”(居住地,別名為 pp)的數據和“ne_50m_admin_0_countries”(國家,別名為c)數據通過基於(ON)“adm0_a3”相同的字段來連接(LEFT JOIN),然後輸出主表(居住地)的城市名稱(city,為別名,後同)和城市人口(city_pop),及次表中的國家名稱(country)和國家人口(country_pop),並限定(WHERE)僅選取首都城市(adm0cap = 1)。
注:LEFT JOIN: 從左表(主表)返回所有的行,即使在右表(次表)中沒有匹配的行。
最後做一下總結,SELECT 語句語法如下:
另外,更多關於 OGR SQL 的內容請參考文末第 3 篇參考資料,若覺得中文翻譯得不夠准確,可以結合文末第 2 篇英文原版參考資料,關於通用的 SQL 語法請參考文末最後一篇參考資料。
好了,以上就是本文的所有內容,希望對大家有所幫助!鑒於本人水平有限,若有錯誤還請評論提醒我哦。
【Python學習交流群:772882553】
【下方分享一些學習資料,大家感興趣的話可以看一下】:
python入門
Python的封裝
Python網絡編程
python高級用法
django項目案例精講
人工智能面試題解答
Python文件處理
雲計算 大數據和人工智能
快速學習爬蟲基礎
【下方分享一些python網盤資料包,大家感興趣的可以看一下】:
Python全網最熱資料包【華清遠見發放資料包】http://makerschool.mikecrm.com/6cvAGKm