九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
python矢量數(shù)據(jù)篩選

lovewhoilove 小猿猴GISer 2022-07-23 09:33 發(fā)表于山東

溫馨提示:閱讀本文大約需要 18 分鐘。

屬性過(guò)濾

OGR 屬性過(guò)濾,是利用 layer.SetAttributeFilter(filter_string) 函數(shù)進(jìn)行要素篩選的。其參數(shù) filter_string 即過(guò)濾條件,而這里依據(jù)運(yùn)算符類型將過(guò)濾條件分為了 4 類:比較運(yùn)算符Comparison Operators)、邏輯運(yùn)算符Logical Operators)、成員運(yùn)算符Membership Operators)以及模糊匹配涉及通配符)。 

一、比較運(yùn)算符
filter_str = "Population < 50000"
filter_str = "class != 3"
# 字符串類型的值需要加引號(hào)
filter_str = "Name = 'China'"
為了將變量名添加至過(guò)濾字符串中,我們可以利用字符串對(duì)象的 format() 方法來(lái)格式化字符串:
name = 'China'
filter_str = "Name = '{}'".format(name)
二、邏輯運(yùn)算符
filter_str = '(Population > 25000) AND (Population < 50000)'
filter_str = "(Population > 25000) OR (Name = 'China')"
filter_str = 'Name NOT NULL'
filter_str = "(Population > 25000) OR NOT (Name = 'China')"
上述 AND 運(yùn)算符組成的過(guò)濾條件更推薦使用 BETWEEN AND 語(yǔ)句:
filter_str = 'Population BETWEEN 25000 AND 50000'
三、成員運(yùn)算符
filter_str = "Name IN ('China''America''Japan')"
同樣地,我們可以用 format() 方法來(lái)格式化過(guò)濾條件:如下所示,多個(gè)字符串組成一個(gè)列表,但由于需要傳入一個(gè)元組,因此需要進(jìn)行類型轉(zhuǎn)換:
countries = ['China''America''Japan']
# 多個(gè)值則需要傳入一個(gè)元組,因此需要做類型轉(zhuǎn)換
filter_str = "Name IN {}".format(tuple(countries))
四、模糊匹配
模糊匹配主要使用 LIKE 語(yǔ)句并配合通配符:首先模糊匹配不區(qū)分大小寫,另外,_(即下劃線)可以匹配任意單個(gè)字符,而 % 可以匹配任意數(shù)量的字符0 至無(wú)數(shù)個(gè)),[char_list] 匹配字符列表中的任何單一字符,[^char_list](或 [!char_list])匹配不在字符列表中的任何單一字符。
filter_str = "Name LIKE '_hin%'"


接下來(lái)我們利用屬性過(guò)濾來(lái)改寫曾在 矢量數(shù)據(jù)的寫入 一文的開篇的個(gè)案例,具體代碼實(shí)現(xiàn)如下:這里利用屬性過(guò)濾,并通過(guò) CopyLayer() 函數(shù)將過(guò)濾后的圖層復(fù)制到新的圖層文件中,這樣改寫是不是簡(jiǎn)單多了。 
import sys
from osgeo import ogr

# 打開數(shù)據(jù)源:參數(shù)為1時(shí)可寫,以便創(chuàng)建新的圖層及并將屬性信息寫入
ds = ogr.Open('osgeopy-data/global'1)
if ds is None:
    sys.exit('Could not open folder.')
# 獲取輸入圖層
in_lyr = ds.GetLayer('ne_50m_populated_places')
# 屬性過(guò)濾
in_lyr.SetAttributeFilter("FEATURECLA = 'Admin-0 capital'")
# 判斷輸出圖層是否存在,若存在則刪除
if ds.GetLayer('capital_cities'):
    ds.DeleteLayer('capital_cities')
# 將過(guò)濾后的圖層復(fù)制到新的數(shù)據(jù)文件中
out_lyr = ds.CopyLayer(in_lyr, 'capital_cities')
del ds  # 關(guān)閉文件,將編輯后的結(jié)果寫入至磁盤文件中
經(jīng)驗(yàn)總結(jié)
1. 上述案例中,我若將過(guò)濾條件寫為 'FEATURECLA = "Admin-0 capital"',即外層單引號(hào)內(nèi)層雙引號(hào),則會(huì)報(bào)錯(cuò),因此,像這種引號(hào)內(nèi)包含引號(hào)的語(yǔ)句,最好外層用雙引號(hào),內(nèi)層的字符串用單引號(hào)。
2. 我們?cè)趯?duì)某個(gè)圖層對(duì)象進(jìn)行屬性過(guò)濾操作后,后續(xù)若還需要用到該圖層,則需要清除屬性過(guò)濾條件,只需給屬性過(guò)濾方法傳遞一個(gè) None 值即可,如 lyr.SetAttributeFilter(None)。利用這一點(diǎn),我們將上述案例的屬性過(guò)濾封裝一下:
def get_attr_filter_lyr(ds, in_lyr, out_lyr, filter_cond, clear=True):
  """
  獲取過(guò)濾后的圖層

  :param ds: 數(shù)據(jù)源對(duì)象
  :param in_lyr: 輸入圖層
  :param out_lyr: 過(guò)濾后的圖層名稱
  :param filter_cond: 屬性過(guò)濾條件
  :param clear: 是否清除屬性過(guò)濾
  :return: 過(guò)濾后的圖層
  """

  if clear:
    in_lyr.SetAttributeFilter(None)
  in_lyr.SetAttributeFilter(filter_cond)
  filter_lyr = ds.CopyLayer(in_lyr, out_lyr)
  ds.SyncToDisk()
  if clear:
    in_lyr.SetAttributeFilter(None)
  return filter_lyr

空間過(guò)濾

空間過(guò)濾即利用空間范圍來(lái)篩選要素,可以用來(lái)選擇位于另一個(gè)要素內(nèi)部矩形邊界框內(nèi)部的要素。還有一個(gè)必要條件用于空間過(guò)濾的要素或坐標(biāo),必須與被篩選的圖層具有相同的空間參考系統(tǒng)。
一、位于另一個(gè)要素內(nèi)部
語(yǔ)法:被過(guò)濾圖層.SetSpatialFilter(過(guò)濾要素的幾何對(duì)象)
舉例:我們拿一個(gè)面圖層(代碼中的 filter_lyr)中的一個(gè)要素去過(guò)濾另外一個(gè)點(diǎn)圖層(即 be_filtered_lyr),顯然,這個(gè)面要素的范圍小于點(diǎn)圖層的范圍。
filter_feat = filter_lyr.GetNextFeature()
filter_geom = filter_feat.geometry().Clone()
be_filtered_lyr.SetSpatialFilter(filter_geom)
上述第二行代碼中,之所以利用 Clone() 函數(shù),是為了防止過(guò)濾要素被刪除后,與其相關(guān)的幾何對(duì)象不再可用,這時(shí),我們可以克隆一個(gè)幾何對(duì)象。
同樣地,和屬性過(guò)濾一樣,我們?cè)趯?duì)圖層對(duì)象進(jìn)行空間過(guò)濾后,若后續(xù)用到該圖層,則需要清除空間過(guò)濾條件,即給空間過(guò)濾方法傳入一個(gè) None 值即可。
二、位于邊界框內(nèi)部
首先,可以利用過(guò)濾圖層的 lyr.GetExtent() 方法來(lái)獲取它的四至范圍,它會(huì)返回一個(gè)形如 (min_x,max_x,min_y,max_y) 的元組,然后利用上述四至范圍對(duì)被過(guò)濾圖層進(jìn)行矩形框空間過(guò)濾,代碼如下:
ext = filter_lyr.GetExtent()
be_filtered_lyr.SetSpatialFilterRect(ext[0], ext[2], ext[1], ext[3])
注意
1. 這里要注意 SetSpatialFilterRect(min_x, min_y, max_x, max_y) 的參數(shù)的順序,不能將 GetExtent() 方法獲取的空間范圍直接帶入上述過(guò)濾方法。
2. 使用 SetSpatialFilterRect() 函數(shù)無(wú)法清除空間過(guò)濾

SQL 語(yǔ)句過(guò)濾

倘若我們要對(duì)圖層進(jìn)行更復(fù)雜的篩選,則可以借助 SQL(Structured Query Language,結(jié)構(gòu)查詢語(yǔ)言)語(yǔ)句來(lái)進(jìn)行過(guò)濾。
執(zhí)行 sql 查詢需借助 ds.ExecuteSQL(sql 語(yǔ)句, [spatialFilter], [dialect) 函數(shù)(帶 [] 為可選參數(shù)):

注意:對(duì)于出錯(cuò)的語(yǔ)句篩選后沒(méi)有結(jié)果集的語(yǔ)句,SQL 查詢的結(jié)果為空。

spatialFilter:是針對(duì)結(jié)果做空間過(guò)濾,可以為空。
dialect:參數(shù)類型為字符串,用于說(shuō)明 sql 語(yǔ)句用的是何種標(biāo)準(zhǔn),可以為空,若為空則默認(rèn)是 OGR 標(biāo)準(zhǔn)。

返回值:包含查詢結(jié)果的 OGRLayer。


我們借助 SQL 查詢語(yǔ)句繼續(xù)改寫第一小節(jié)屬性過(guò)濾中的例子,代碼實(shí)現(xiàn)如下:sql 語(yǔ)句要用 3 對(duì)引號(hào)包裹,若 WHERE 子句中存在字段串,則使用與外層不同類型的引號(hào),這里建議外層雙引號(hào),內(nèi)層單引號(hào)。
import sys
from osgeo import ogr

ds = ogr.Open('osgeopy-data/global'1)
if ds is None:
  sys.exit('Could not open folder.')
sql = """SELECT * FROM ne_50m_populated_places 
        WHERE FEATURECLA ='Admin-0 capital'"""

lyr = ds.ExecuteSQL(sql)
if ds.GetLayer('capital_cities'):
  ds.DeleteLayer('capital_cities')
out_lyr = ds.CopyLayer(lyr, 'capital_cities')

上述代碼中,使用 *星號(hào)來(lái)表示選取所有字段,這里也可以指定需要的字段,接下來(lái)我們將總結(jié)一下 SQL 語(yǔ)句的相關(guān)語(yǔ)法。

一、SELECT 語(yǔ)句

SELECT 語(yǔ)句用于從表中選取數(shù)據(jù),其后跟表中的字段名(列名稱),多個(gè)名稱之間用 ,逗號(hào)相連。

SELECT 字段名 FROM 表名
# 多個(gè)字段
SELECT 字段1,字段2 FROM 表名

1選擇所有字段

可以使用 *號(hào))來(lái)代表所有字段:當(dāng)然不包括下面的特定字段

SELECT * FROM 數(shù)據(jù)表名稱

2選擇內(nèi)置的特殊字段

OGR SQL 標(biāo)準(zhǔn)中的內(nèi)置的特殊字段見(jiàn)下表:
字段名稱返回結(jié)果
FID要素的 ID 值
OGR_GEOMETRYOGR 幾何類型常量(如 wkbPoint)
OGR_GEOM_WKT文本格式的要素幾何類型
OGR_GEOM_AREA要素的面積
OGR_STYLE要素的符號(hào)樣式的字符串

這里針對(duì)上表中的字段列舉幾個(gè)網(wǎng)上的例子:

# FID
SELECT FID, * FROM nation
# 幾何類型
SELECT OGR_GEOMETRY FROM nation
# 幾何類型篩選
SELECT * FROM nation WHERE OGR_GEOMETRY='POINT' OR OGR_GEOMETRY='POLYGON'
# WKT
SELECT OGR_GEOM_WKT, * FROM nation
# WKT-篩選
SELECT * FROM nation WHERE OGR_GEOM_WKT
    LIKE 'POINT%' OR OGR_GEOM_WKT LIKE 'POLYGON%'
# 面積
SELECT OGR_GEOM_AREA, * FROM nation
# 面積篩選
SELECT * FROM nation WHERE OGR_GEOM_AREA > 10000000
# 樣式
SELECT * FROM nation WHERE OGR_STYLE LIKE 'LABEL%'

3使用字段別名

若字段名比較長(zhǎng),我們可以使用 AS 關(guān)鍵字 來(lái)重命名一個(gè)簡(jiǎn)潔一點(diǎn)的名字:

 SELECT 字段名 AS 別名 FROM 表名

4更改字段類型

OGR SQL 支持使用 CAST 運(yùn)算符 更改字段的類型,這里給一個(gè)官方的例子:

SELECT *, CAST(OGR_STYLE AS character(255)) FROM rivers
支持轉(zhuǎn)換的類型如下:
boolean
character(field_length).默認(rèn)長(zhǎng)度為1
float(field_length)
numeric(field_length, field_precision)
smallint(field_length) : 16 位有符號(hào)整數(shù)
integer(field_length)
bigint(field_length), 64 位整數(shù)
date(field_length)
time(field_length)
timestamp(field_length)
geometry, geometry(geometry_type), geometry(geometry_type,epsg_code)

5DISTINCT 關(guān)鍵字

DISTINCT關(guān)鍵字 用于返回字段中唯一不同的屬性值,即去重。

SELECT DISTINCT 字段名 FROM 表名

6匯總運(yùn)算符(summarization operators

還可以借助函數(shù)來(lái)處理返回的字段的屬性值,如:COUNT(實(shí)例計(jì)數(shù))、AVG(數(shù)值平均)、SUM(數(shù)值和)、MIN(數(shù)值最小值)  MAX(數(shù)值最大值)。

MIN() 和 MAX() 函數(shù)也可用于文本類型,返回按字母順序排列的最高或最低值。

SELECT MIN(prop_val), MAX(prop_val), AVG(prop_val), SUM(prop_val), COUNT(prop_val) FROM 表名

DISTINCT 關(guān)鍵字也可以和 COUNT() 結(jié)合使用:

SELECT COUNT(DISTINCT 字段名) FROM 表名

7函數(shù)

這里舉倆例子:個(gè)人覺(jué)得應(yīng)該用不上

,最起碼用的不多。

# 拼接字符串
SELECT CONCAT(str1, st2, ...) FROM 表名
# 從字符串中提取子字符串
SELECT SUBSTR(string_expr, start_offset [, length]) FROM 表名
二、WHERE 子句

WHERE 子句:有條件地從表中選取數(shù)據(jù),語(yǔ)法如下:

SELECT 字段名 FROM 表名 WHERE 條件

我們?cè)O(shè)置條件會(huì)用到屬性查詢中的運(yùn)算符,具體可以參考第一小節(jié)的屬性過(guò)濾中的講解,這里列舉幾個(gè)官網(wǎng)上的例子:

SELECT * FROM  WHERE (prop_val >= 100000) AND (prop_val < 200000)
SELECT * FROM  WHERE NOT (area_code LIKE 'N0N%')
SELECT * FROM  WHERE (prop_val IS NOT NULL) AND (prop_val < 100000)
三、ORDER BY 語(yǔ)句

ORDER BY 語(yǔ)句:根據(jù)指定的字段(列)進(jìn)行排序,默認(rèn)為升序排列,若要降序則加上 DESC 關(guān)鍵字(升序?yàn)殛P(guān)鍵字為 ASC)。

SELECT 字段名 FROM  ORDER BY 字段名
# 降序
SELECT 字段名 FROM  ORDER BY 字段名 DESC
四、LIMIT 子句與 OFFSET 子句

LIMIT 子句:用于限制返回的記錄數(shù);而 OFFSET 子句:表示偏移值,用于跳過(guò)的記錄數(shù),例子如下:

SELECT * FROM 表名 LIMIT 5
SELECT * FROM  OFFSET 3
SELECT * FROM  LIMIT 5 OFFSET 3
五、表連接

OGR SQL 標(biāo)準(zhǔn)支持有限形式的一對(duì)一連接,原理:根據(jù)次表與查詢的主表之間的共享鍵,以查找次表中的記錄

這里舉個(gè)例子來(lái)說(shuō)明:我們拿“ne_50m_populated_places”(居住地,別名為 pp)的數(shù)據(jù)和“ne_50m_admin_0_countries”(國(guó)家,別名為c)數(shù)據(jù)通過(guò)基于(ON)“adm0_a3”相同的字段來(lái)連接(LEFT JOIN),然后輸出主表(居住地)的城市名稱city,為別名,后同)和城市人口city_pop),及次表中的國(guó)家名稱country)和國(guó)家人口country_pop),并限定(WHERE)僅選取首都城市(adm0cap = 1)。

注:LEFT JOIN: 從左表(主表)返回所有的行,即使在右表(次表)中沒(méi)有匹配的行。

ds = ogr.Open('osgeopy-data/global'1)
if ds is None:
    sys.exit('Could not open folder.')
sql = """SELECT pp.name AS city, pp.pop_min AS city_pop,
            c.name AS country, c.pop_est AS country_pop 
            FROM ne_50m_populated_places pp 
            LEFT JOIN ne_50m_admin_0_countries c 
            ON pp.adm0_a3 = c.adm0_a3 
            WHERE pp.adm0cap = 1"""

lyr = ds.ExecuteSQL(sql)
if ds.GetLayer('city_country'):
    ds.DeleteLayer('city_country')
out_lyr = ds.CopyLayer(lyr, 'city_country')

最后做一下總結(jié),SELECT 語(yǔ)句語(yǔ)法如下:

SELECT [fields] FROM layer_name [JOIN ...] [WHERE ...] [ORDER BY ...] [LIMIT ...] [OFFSET ...]

另外,更多關(guān)于 OGR SQL 的內(nèi)容請(qǐng)參考文末第 3 篇參考資料,若覺(jué)得中文翻譯得不夠準(zhǔn)確,可以結(jié)合文末第 2 篇英文原版參考資料,關(guān)于通用的 SQL 語(yǔ)法請(qǐng)參考文末最后一篇參考資料。


參考資料:

  • Mingxi Zhang. Python地理數(shù)據(jù)處理[M].  2017.

  • https://gdal.org/user/ogr_sql_dialect.html

  • https://www.osgeo.cn/gdal/user/ogr_sql_dialect.html

  • https://www.osgeo.cn/gdal/api/gdaldataset_cpp.html

  • https://www.w3school.com.cn/sql/index.asp



確定


  • 不看此公眾號(hào)

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
VFP命令、函數(shù)及程序語(yǔ)句大全
常用的SQL語(yǔ)句
SQL查詢語(yǔ)句 select 詳解
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服