Python 程式设计入门 (QGIS3)

QGIS 具有强大的程式设计介面,支援目前流行的 Python 语言,可以让你扩展此软体的核心功能,或是撰写脚本让你想做的事情可以自动执行。不论你是否对 QGIS 或 Python 有深入了解,知道一点 QGIS 程式介面的使用方法一定会让你的工作事半功倍。阅读本教学不需任何程式设计的背景,我们会从头开始叙述 QGIS 的 Python 程式设计方法 (PyQGIS)。

内容说明

我们要以 Python 脚本处理世界上所有机场位置的点向量图层,此脚本会输出图层中机场名字、机场代码与经纬度资讯到一个文字档中。

取得资料

本教学使用 Natural Earth 提供的 机场 资料集。

下载 机场 shapefile

操作流程

  1. 在QGIS浏览器中找到 ne_10m_airports.zip 文件并将其展开。选择 ne_10m_airports.shp 文件并将其拖到画布上。

../../_images/150.png
  1. 接着 QGIS 中就可以看到 ne_10m_airports 图层。

../../_images/230.png
  1. 选择 Identify 工具,然后单击任意点以检查可用属性。您将看到机场名称及其3位数字代码分别包含在属性 nameiata_code 中。您可以关闭 Identify 窗口。

../../_images/324.png
  1. QGIS提供了一个内置控制台,您可以在其中键入python命令并获取结果。该控制台是学习脚本和进行快速数据处理的好方法。通过转到 Plugins ‣ Python Console 打开Python控制台。

../../_images/411.png
  1. 这时有个新面板会出现在 QGIS 画布下方,而且最底下左侧会有一个 >>> 的栏位,这里就是输入指令的地方。在此模式下方所有与 QGIS 环境的互动,都会透过一个叫做 iface 的变数来达成。例如要存取现在显示在 QGIS 中的图层的话,可输入如下指令后按下 Enter 键,layer 这个变数就会被设定成此图层。

layer = iface.activeLayer()
../../_images/512.png
  1. Python 中有个蛮实用的函数叫做 dir(),它会秀出某物件的所有可操作方法。当你不太了解这个物件该怎么操作时,这个函数相当管用。所以我们就输入如下指令,看看接下来我们可以对 layer 变数做什么事情。

dir(layer)
../../_images/612.png
  1. 您会看到一长串可用功能。现在,我们将使用一个名为 getFeatures() 的函数,该函数将为您提供对图层所有要素的引用。在我们的案例中,每个要素都是代表机场的点。您可以键入以下命令来迭代当前层中的每个要素。

注解

缩进(或每个语句前的空格数)在Python中非常重要。如果在此步骤中遇到错误,请确保在输入第二行之前添加了2个空格。

由于print(f)语句位于for循环内,因此您需要在该语句后按两次 Enter 一次退出循环,然后再次执行该命令。

for f in layer.getFeatures():
  print(f)
../../_images/7.gif
  1. 接着在输出画面中就可以看到每一行都是图层中的一个特定图征。图征的资讯会存在 f 变数当中,所以只要对 f 进行一些操作,就可以取得图征的属性,像是输入下面的指令,就可以印出每个机场的 nameiata_code 属性。

for f in layer.getFeatures():
  print(f['name'], f['iata_code'])
../../_images/8.gif
  1. 现在我们已经知道要怎么用指令取得图层中的图征属性了,接下来我们还得取得图征的座标。向量图征的座标可以使用一个叫做 geometry() 的函数来取得,此函数会输出一种几何物件,这里我们把它存在 geom 变数中,可以在几何对象上运行 asPoint() 函数以获取该点的x和y坐标。如果图征是线或是多边形的话,取得座标的函数会变成 asPolyline()asPolygon()。请输入以下指令后按下 Enter,就可以看到每个图征的座标。

for f in layer.getFeatures():
  geom = f.geometry()
  print(geom.asPoint())
../../_images/9.gif
  1. 如果我们只想要秀出 x 座标的话要怎么办? 只要在点几何物件上多套入一个 x() 函数就行了,如下所示。

for f in layer.getFeatures():
  geom = f.geometry()
  print(geom.asPoint().x())
../../_images/10.gif
  1. 现在,我们可以将所有零件拼接在一起以生成所需的输出。输入以下代码以打印每个机场要素的名称,iata_code,纬度和经度。 在这里,我们使用了 .format() 方法,该方法可以更好地控制打印多个变量。.2f 符号是将坐标限制为2位小数。

for f in layer.getFeatures():
  geom = f.geometry()
  print('{},{},{:.2f},{:.2f}'.format(f['name'], f['iata_code'], geom.asPoint().y(), geom.asPoint().x()))
../../_images/111.gif
  1. 您可以在控制台上看到输出。存储输出的更有用的方法是在文件中。您可以键入以下代码来创建文件并将输出写入那里。将文件路径替换为您自己系统上的路径。请注意,我们在行格式的末尾添加了 \ \ n。 这是在我们为每个功能添加数据之后添加换行符。

注解

下面有2级代码块。 请确保在代码起始行3中添加4个空格。

with open('/Users/ujaval/Desktop/airports.txt', 'w') as file:
  for f in layer.getFeatures():
    geom = f.geometry()
    line = '{},{},{:.2f},{:.2f}\n'.format(f['name'], f['iata_code'], geom.asPoint().y(), geom.asPoint().x())
    file.write(line)
../../_images/12.gif
  1. 最后就可以在输出的文字档中,查看我们刚刚利用 Python 指令从 shapefile 中转存出来的资料了。

../../_images/1312.png