16.7. 了解Python控制台#
与QGIS交互的最直接方式API(简称:应用程序编程接口)是通过 Python控制台, 可以通过转到 图 16.15 。
。 在下面的截图中可以看到“Python控制台”显示在地图下方的新面板中,如
图 16.15 Python的控制台#
我们与应用程序、项目和数据交互的访问点是iface公司反对。获取所有可用功能的列表 (iface) ,类型帮助(iface)。 或者,可以在API文档在 http://qgis.org/api/classQgisInterface.html.
16.7.1. 加载和浏览数据集#
我们要做的第一件事就是加载一些数据。例如,要加载向量层,我们使用 “addVectorLayer()” 函数:
v_layer = iface.addVectorLayer(
'C:/Users/anita/Documents/Geodata/qgis_sample_data/shapefiles/airports.shp',
'airports','ogr')
当我们执行这个命令时, "airports.shp" 将使用 ogr
驱动程序并添加到图层名为”机场“。
此外,此函数还返回“图层”反对。使用这个“图层”我们存储在v_layer-我们可以访问向量层函数,
例如,名称(),它返回层名称并显示在“层”名单:
v_layer.name()
这是输出: u“机场”
这个 u 在 机场 层名称显示该名称作为Unicode字符串返回。
当然,下一个合乎逻辑的步骤是查看层的特性。可以使用 功能计数() :
v_layer.featureCount()
输出如下:
76L
这表明机场层包含76个特性。这个L最后说明它是一个长型的数值。在下一步中,我们将访问这些功能。 这可以使用 “getFeatures()” 函数,它返回"QgsFeatureIterator"反对。用一个简单的"for"循环, 然后我们可以打印“属性()”在我们这一层的所有功能中:
my_features = v_layer.getFeatures()
for feature in my_features:
print feature.attributes()
这是输出:
[1, u'US00157', 78.0, u'Airport/Airfield', u'PA', u'NOATAK' ...
[2, u'US00229', 264.0, u'Airport/Airfield', u'PA', u'AMBLER'...
[3, u'US00186', 585.0, u'Airport/Airfield', u'PABT', u'BETTL...
...
在使用前面的代码片段时,值得注意的是,Python语法需要适当的缩进。这意味着,例如,"for"循环必须缩进, 如前面的代码所示。如果Python遇到这样的错误,它将引发缩进误差 。
你可能已经注意到了“属性()”显示属性值,但我们还不知道字段名。要获取字段名,我们使用以下代码:
for field in v_layer.fields():
print field.name()
输出如下:
ID fk_region
ELEV
NAME
USE
一旦我们知道了字段名,我们就可以访问特定的特性属性,例如, NAME :
for feature in v_layer.getFeatures():
print feature.attribute('NAME')
这是输出:
NOATAK
AMBLER
贝蒂斯。。。
例如,总结高程值的快速解决方案如下:
[sum([feature.attribute('ELEV') for feature in v_layer.getFeatures()])]
输出如下:
22758.0
在前面的例子中,我们利用了Python允许我们通过编写"for"方格内环括号。这叫做列表理解, 您可以在 https://docs.python.org/2/tutorial/datastructures.html#list-comprehensions 。 加载栅格数据与加载矢量数据非常相似,使用 “addRasterLayer()” :
r_layer = iface.addRasterLayer(
'C:/Users/anita/Documents/Geodata/qgis_sample_data/raster/SR_50M_alaska_nad.tif',
'hillshade')
r_layer.name()
以下是输出:
u'hillshade'
要获取栅格层的像素大小,可以使用“宽度()”和“高度()”功能如下:
r_layer.width(), r_layer.height()
输出如下:
(17541394年)
如果我们想了解更多关于栅格值的信息,可以使用图层的数据提供程序对象,该对象提供对栅格波段统计信息的访问。 值得注意的是我们必须使用“带宽统计(1)”而不是“带宽统计(0)”访问单波段栅格的统计信息, 例如,“山体阴影”层(例如,对于最大值):
r_layer.dataProvider().bandStatistics(1).maximumValue
输出如下:
251.0
其他可以像这样访问的值是“最小值”范围,stdDev公司和sum。对于完整列表,请使用以下行:
help(r_layer.dataProvider().bandStatistics(1))
16.7.2. 设置图层样式#
因为我们现在知道如何加载数据,所以可以继续设置图层的样式。最简单的方法是加载一个预先制作好的样式(a .qml 文件):
v_layer.loadNamedStyle('C:/temp/planes.qml')
v_layer.triggerRepaint()
一定要打电话"triggerRepaint()"以确保重新绘制地图以反映您的更改。
你可以创建"planes.qml"通过保存在中创建的机场样式第二章,查看空间数据(通过,层属性-风格-保存样式-QGIS图层样式文件), 或使用任何您喜欢的其他样式。
当然,我们也可以在代码中创建样式。让我们看看一个基本的单符号渲染器。我们创建一个带有一层的简单符号,例如黄色菱形:
from PyQt4.QtGui import QColor symbol = QgsMarkerSymbolV2()
symbol.symbolLayer(0).setName('diamond')
symbol.symbolLayer(0).setSize(10)
symbol.symbolLayer(0).setColor(QColor('#ffff00'))
v_layer.rendererV2().setSymbol(symbol) v_layer.triggerRepaint()
更先进的方法是创建"rule-based renderer"。 我们在第五章,创建伟大的地图,以下示例创建了两个规则:
一个用于民用机场,另一个用于所有其他机场。由于这个脚本的长度,我建议您使用Python控制台编辑器,
单击 显示编辑器
按钮,如 图 16.16 。

图 16.16 显示编辑器#
本例中的每个规则都有一个名称、一个筛选器表达式和一个符号颜色。请注意规则是如何附加到渲染器的根规则的: 从PyQt4.QtGui导入QColor
[rules = [['Civil','USE LIKE \'%Civil%'','green'], ['Other','USE]
NOT LIKE \'%Civil%'','red']]
[symbol = QgsSymbolV2.defaultSymbol(v_layer.geometryType()) renderer =
QgsRuleBasedRendererV2(symbol) root_rule = renderer.rootRule() for label,
expression, color_name in rules: rule = root_rule.children()[0].clone()
rule.setLabel(label) rule.setFilterExpression(expression)
rule.symbol().setColor(QColor(color_name)) root_rule.appendChild(rule)
root_rule.removeChildAt(0) v_layer.setRendererV2(renderer)
v_layer.triggerRepaint()]
要运行脚本,请单击 运行脚本编辑器
工具栏底部的按钮。
如果你有兴趣阅读更多关于向量层样式的文章,我推荐Joshua Arnott在 http://snorf.net/blog/2014/03/04/symbology-of-vector-layers-inqgis-python-plugins/ 。
16.7.3. 过滤数据#
要以编程方式过滤矢量层特征,可以指定一个子集字符串。这与定义特征子集在中查询层属性一般章节。例如,只有机场的名称以A:
v_layer.setSubsetString("NAME LIKE 'A%'")
要删除筛选器,只需设置一个空的子集字符串:
v_layer.setSubsetString("")
16.7.4. 创建内存层#
创建临时向量层的一个好方法是使用所谓的内存层。内存层是临时分析输出或可视化的好选项。 它们是临时scratch层的脚本等价物,我们在第三章,数据创建和编辑,与临时暂存层一样, 内存层存在于QGIS会话中,并在QGIS关闭时被销毁。在下面的例子中,我们创建了一个内存层, 并向其中添加了一个多边形特征。
基本上,内存层是"QgsVectorLayer"像其他人一样。但是,提供程序(第三个参数)不是'奥格' 与前面加载文件的示例一样,但是'内存'。第一个参数不是文件路径,而是一个定义字符串, 指定几何体类型、CRS和属性表字段(在本例中,一个名为 MYNUM 一个字符串字段名为 MYTXT ):
mem_layer =
QgsVectorLayer("Polygon?crs=epsg:4326&field=MYNUM:integer&field=MYTXT:
string", "temp_layer", "memory")
if not mem_layer.isValid():
raise Exception("Failed to create memory layer")
一旦我们创造了 “QgsVectorLayer” 对象,我们可以开始向其数据提供程序添加功能:
mem_layer_provider = mem_layer.dataProvider() my_polygon =
QgsFeature() my_polygon.setGeometry(
[QgsGeometry.fromRect(QgsRectangle(16,48,17,49)))
my_polygon.setAttributes([10,"hello world"])
mem_layer_provider.addFeatures([my_polygon])
QgsMapLayerRegistry.instance().addMapLayer(mem_layer)]
注意我们如何首先创建一个空白"QgsFeature",然后使用"设置几何()"和"设置属性()",分别是。 当我们把图层添加到"QgsMapLayerRegistry",图层在地图上呈现。
16.7.5. 导出地图图像#
保存当前映射的最简单方法是使用另存为图像下项目。这会将当前地图导出到图像文件中, 其分辨率与QGIS应用程序窗口中的地图区域相同:iface.mapCanvas().saveAsImage('C:/temp/simple_export.png')
如果我们想要更多地控制导出图像的大小和分辨率,我们需要更多的代码行。 下面的示例演示如何创建自己的 “QgsMapRendererCustomPainterJob” 使用自定义 “QgsMapSettings” 大小(”宽度“和”高度“),分辨率( dpi ),地图程度和映射层 :
from PyQt4.QtGui import QImage, QPainter from PyQt4.QtCore import
QSize # configure the output image width = 800 height = 600 dpi = 92
img = QImage(QSize(width, height), QImage.Format_RGB32)
img.setDotsPerMeterX(dpi / 25.4 * 1000) img.setDotsPerMeterY(dpi /
25.4 * 1000)
[# get the map layers and extent layers = [ layer.id() for layer in
iface.legendInterface().layers() ] extent = iface.mapCanvas().extent() # configure
map settings for export mapSettings = QgsMapSettings()
mapSettings.setMapUnits(0) mapSettings.setExtent(extent)
mapSettings.setOutputDpi(dpi)]
mapSettings.setOutputSize(QSize(width,height))mapSettings.setLayers(layers)
mapSettings.setFlags(QgsMapSettings.Antialiasing |
QgsMapSettings.UseAdvancedEffects |
QgsMapSettings.ForceVectorOutput | QgsMapSettings.DrawLabeling)
# configure and run painter p = QPainter()
p、 开始(img)
mapRenderer = QgsMapRendererCustomPainterJob(mapSettings, p)
mapRenderer.start() mapRenderer.waitForFinished()
p、 结束()
# save the result
img.save("C:/temp/custom_export.png","png")