資料表連接 (PyQGIS)¶
警告
This tutorial is now obsolete. The preferred way to do table joins via pyqgis is to run the native:joinattributestable
algorithm via Python. See details at Running Processing Algorithms via Python (QGIS3).
本教學示範如何在 QGIS 中利用 Python 腳本 (PyQGIS) 操作資料表連接,並為輸出的圖層進行漸層樣式設定。我們要重複一次在 資料表連接 中進行的步驟,但這一次會只使用 python 腳本來操作。
內容說明¶
請參考 資料表連接 的教學說明。
你還會學到這些¶
利用 Python 載入壓縮的圖層到 QGIS 中
使用 QgsGraduatedSymbolRendererV2 為向量圖層設定漸層樣式
取得資料¶
請下載以下資料至電腦中:
資料來源 [TIGER] [USCENSUS]
操作流程¶
你可以在 Python 主控台 或是 QGIS 內建的 編輯器 中輸入以下指令。
第一步是載入 shapefile,我們要的檔案包含在檔名含有 tract.zip 的壓縮檔中。雖然我們可以解壓縮然後載入 shapefile,不過 OGR 提供元(provider,這裡就是 QGIS)也可以經由虛擬的檔案系統直接載入 shapefile。只要在路徑最前端加上
/vsizip/
之後,就能夠載入 zip 格式的 shapefile。
備註
zip_uri 在 Linux 和 Mac 系統上的前綴是 /vsizip//
(注意多出來的 /)
zip_uri = '/vsizip/C:/Users/Ujaval/Downloads/tl_2013_06_tract.zip'
shp = QgsVectorLayer(zip_uri, 'tl_2013_06_tract', 'ogr')
QgsMapLayerRegistry.instance().addMapLayer(shp)
接下來載入 CSV 檔。由於 CSV 檔不包含任何空間資訊,我們要使用
delimitedtext
做為資料提供元,載入成表格。
csv_uri = 'file:///C:/Users/Ujaval/Downloads/ca_tracts_pop.csv?delimiter=,'
csv = QgsVectorLayer(csv_uri, 'ca_tracts_pop', 'delimitedtext')
QgsMapLayerRegistry.instance().addMapLayer(csv)
開始進行資料表連接。在 QGIS 中此操作要使用
QgsVectorJoinInfo
物件,而且我們需要指定 CSV 圖層中的GEO.id2
作為 連結欄位,以及 shapefile 圖層中的GEOID
作為 目標欄位。執行下列程式碼後,shapefile 的圖層就會多出一個從 CSV 圖層連結過來的屬性。
備註
當使用 QgsVectorJoinInfo 時,務必要確認兩個圖層都已載入至 QgsMapLayerRegistry,否則是不會有任何東西被連結的。
shpField='GEOID'
csvField='GEO.id2'
joinObject = QgsVectorJoinInfo()
joinObject.joinLayerId = csv.id()
joinObject.joinFieldName = csvField
joinObject.targetFieldName = shpField
joinObject.memoryCache = True
shp.addJoin(joinObject)
另一個較簡單,而且也較為推薦的方法是使用「處理框架」。你可以呼叫
qgis:joinattributestable
演算法來創造連接完畢的圖層。
備註
我們這邊使用的是 processing.runandload()
方法,而不是較常見的 processing.runalg()
來執行演算法,這是因為我們想要把執行的結果圖層也加到 QGIS 中,使用 processing.runandload()
是較方便的選擇。
import processing
shpField='GEOID'
csvField='GEO.id2'
result = processing.runandload('qgis:joinattributestable', shp, csv, shpField, csvField, None)
在本教學剩餘的部分中,我們會繼續使用第一種利用
QgsVectorJoinInfo
的方法。接下來我們要來為連接後的圖層設定漸層樣式。在連接後的圖層中,人口的欄位是ca_tracts_pop_D001
,我們要使用QgsGraduatedSymbolRendererV2
,在分位數
模式下設定漸層樣式,相關的顏色和數值範圍設定請參考 資料表連接。
from PyQt4 import QtGui
myColumn = 'ca_tracts_pop_D001 '
myRangeList = []
myOpacity = 1
ranges = []
myMin1 = 0.0
myMax1 = 3157.2
myLabel1 = 'Group 1'
myColor1 = QtGui.QColor('#f7fbff')
ranges.append((myMin1, myMax1, myLabel1, myColor1))
myMin2 = 3157.2
myMax2 = 4019.0
myLabel2 = 'Group 2'
myColor2 = QtGui.QColor('#c7dcef')
ranges.append((myMin2, myMax2, myLabel2, myColor2))
myMin3 = 4019.0
myMax3 = 4865.8
myLabel3 = 'Group 3'
myColor3 = QtGui.QColor('#72b2d7')
ranges.append((myMin3, myMax3, myLabel3, myColor3))
myMin4 = 4865.8
myMax4 = 5996.4
myLabel4 = 'Group 4'
myColor4 = QtGui.QColor('#2878b8')
ranges.append((myMin4, myMax4, myLabel4, myColor4))
myMin5 = 5996.4
myMax5 = 37452.0
myLabel5 = 'Group 5'
myColor5 = QtGui.QColor('#08306b')
ranges.append((myMin5, myMax5, myLabel5, myColor5))
for myMin, myMax, myLabel, myColor in ranges:
mySymbol = QgsSymbolV2.defaultSymbol(shp.geometryType())
mySymbol.setColor(myColor)
mySymbol.setAlpha(myOpacity)
myRange = QgsRendererRangeV2(myMin, myMax, mySymbol, myLabel)
myRangeList.append(myRange)
myRenderer = QgsGraduatedSymbolRendererV2('', myRangeList)
myRenderer.setMode(QgsGraduatedSymbolRendererV2.Quantile)
myRenderer.setClassAttribute(myColumn)
shp.setRendererV2(myRenderer)
在 Python 主控台中直接輸入程式碼,對於執行小型的工作非常方便,不過對於以上的程式片段,使用內建的 編輯器 會容易得多。你可以複製整段程式碼然後貼上到 編輯器 中,然後按下 執行,當腳本執行完畢後,資料表連接和樣式設定就完成了,不需要多餘的手動操作。
以下放上完整的 join_attributes.py
檔做為參考。
from PyQt4 import QtGui
zip_uri = '/vsizip/C:/Users/Ujaval/Downloads/tl_2013_06_tract.zip/tl_2013_06_tract.shp'
shp = QgsVectorLayer(zip_uri, 'tl_2013_06_tract', 'ogr')
QgsMapLayerRegistry.instance().addMapLayer(shp)
csv_uri = "file:///C:/Users/Ujaval/Downloads/ca_tracts_pop.csv?delimiter=,"
csv = QgsVectorLayer(csv_uri, "ca_tracts_pop", "delimitedtext")
QgsMapLayerRegistry.instance().addMapLayer(csv)
shpField='GEOID'
csvField='GEO.id2'
joinObject = QgsVectorJoinInfo()
joinObject.joinLayerId = csv.id()
joinObject.joinFieldName = csvField
joinObject.targetFieldName = shpField
joinObject.memoryCache = True
shp.addJoin(joinObject)
myColumn = 'ca_tracts_pop_D001 '
myRangeList = []
myOpacity = 1
ranges = []
myMin1 = 0.0
myMax1 = 3157.2
myLabel1 = 'Group 1'
myColor1 = QtGui.QColor('#f7fbff')
ranges.append((myMin1, myMax1, myLabel1, myColor1))
myMin2 = 3157.2
myMax2 = 4019.0
myLabel2 = 'Group 2'
myColor2 = QtGui.QColor('#c7dcef')
ranges.append((myMin2, myMax2, myLabel2, myColor2))
myMin3 = 4019.0
myMax3 = 4865.8
myLabel3 = 'Group 3'
myColor3 = QtGui.QColor('#72b2d7')
ranges.append((myMin3, myMax3, myLabel3, myColor3))
myMin4 = 4865.8
myMax4 = 5996.4
myLabel4 = 'Group 4'
myColor4 = QtGui.QColor('#2878b8')
ranges.append((myMin4, myMax4, myLabel4, myColor4))
myMin5 = 5996.4
myMax5 = 37452.0
myLabel5 = 'Group 5'
myColor5 = QtGui.QColor('#08306b')
ranges.append((myMin5, myMax5, myLabel5, myColor5))
for myMin, myMax, myLabel, myColor in ranges:
mySymbol = QgsSymbolV2.defaultSymbol(shp.geometryType())
mySymbol.setColor(myColor)
mySymbol.setAlpha(myOpacity)
myRange = QgsRendererRangeV2(myMin, myMax, mySymbol, myLabel)
myRangeList.append(myRange)
myRenderer = QgsGraduatedSymbolRendererV2('', myRangeList)
myRenderer.setMode(QgsGraduatedSymbolRendererV2.Quantile)
myRenderer.setClassAttribute(myColumn)
shp.setRendererV2(myRenderer)
If you want to give feedback or share your experience with this tutorial, please comment below. (requires GitHub account)