资料表连接 (PyQGIS)¶
本教学示范如何在 QGIS 中利用 Python 脚本 (PyQGIS) 操作资料表连接,并为输出的图层进行渐层样式设定。我们要重复一次在 资料表连接 中进行的步骤,但这一次会只使用 python 脚本来操作。
内容说明¶
请参考 资料表连接 的教学说明。
你还会学到这些¶
利用 Python 载入压缩的图层到 QGIS 中
使用 QgsGraduatedSymbolRendererV2 为向量图层设定渐层样式
操作流程¶
你可以在 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)