Python 程序设计的初步上手

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

内容说明

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

取得资料

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

下载 Airports shapefile.

资料来源 [NATURALEARTH]

操作流程

  1. 在 QGIS 中选择 Layers ‣ Add Vector Layer。找到刚下载的 ne_10m_airports.zip 档案,按下 Open. 选择``ne_10m_airports.shp`` 最后按 OK
../_images/160.png
  1. 接着 QGIS 中就可以看到 ne_10m_airports 图层。
../_images/227.png
  1. 使用:guilabel:Identify 按钮,选择任一个点看一下有哪些属性。你会发现机场的名字是记在 name 属性,而机场的 3 位英文代码则是记在 ``iata_code``属性。
../_images/318.png

4. QGIS 有内建终端机模式,可以让你输入 Python 指令和查阅输出,对于学习和快速的资料处理很有帮助。选择:guilabel:Python Console 输入 Plugins ‣ Python Console,就可以进入该模式。

../_images/413.png
  1. 这时有个新面板会出现在 QGIS 画布下方,而且最底下会有一个左侧有 >>> 的栏位,这里就是输入指令的地方。在此模式下方所有与 QGIS 环境的互动,都会透过一个叫做 iface 的变数来达成。例如要存取现在显示在 QGIS 中的图层的话,可输入如下指令后按下:kbd:Enter`键, ``layer` 这个变数就会被设定成此图层。
layer = iface.activeLayer()
../_images/513.png
  1. Python 中有个蛮实用的函数叫做 dir() 它会秀出某物件的所有可操作方法。当你不太了解这个物件该怎么操作时,这个函数相当管用。所以我们就输入如下指令,看看接下来我们可以对 layer 变数做什么事情。
dir(layer)
../_images/612.png
  1. 这下子你就会看到一长串的可用函数。在这里,我们试着用 getFeatures() 这是帮助取得某个在图层中的图征的函数,在我们的例子中,它可以帮我们取得图层中代表「机场」的点。使用下面的指令就可以逐一取得图层中的所有图征,不过记得一定要在第二行的最前面加上 2 个空格。
for f in layer.getFeatures():
  print f
../_images/712.png
  1. 接着在输出画面中就可以看到每一行都是图层中的一个特定图征。图征的资讯会存在``f``变数当中,所以只要对 f 进行一些操作,就可以取得图征的属性,像是输入下面的指令,就可以印出每个机场的 nameiata_code 属性。
for f in layer.getFeatures():
  print f['name'], f['iata_code']
../_images/812.png
  1. 现在我们已经知道要怎么用指令取得图层中的图征属性了,接下来我们还得取得图征的座标。向量图征的座标可以使用一个叫做``geometry()`` 的函数来取得,此函数会输出一种「几何物件」,这里我们把它存在 geom``变数中,而「点几何物件」可以透过``asPoint() 函数来取得这个物件的 x 与 y 座标。如果图征是线或是多边形的话,取得座标的函数会变成``asPolyline()`` 或 ``asPolygon()``请输入以下指令后按下:kbd:Enter,就可以看到每个图征的座标。
for f in layer.getFeatures():
  geom = f.geometry()
  print geom.asPoint()
../_images/911.png
  1. 如果我们只想要秀出 x 座标的话要怎么办? 只要在点几何物件上多套入一个``x()`` 函数就行了,如下所示。
for f in layer.getFeatures():
  geom = f.geometry()
  print geom.asPoint().x()
../_images/1011.png
  1. 以上所讲的各种操作,只要把它们拼凑起来,就可以产生我们想要的输出结果。像是底下的程序代码可以印出每个机场的名字、iata_code 以及经纬度,程序代码中的 %s 和``%f`` 是用来调整字串和数字的输出格式的记号。
for f in layer.getFeatures():
  geom = f.geometry()
  print '%s, %s, %f, %f' % (f['name'], f['iata_code'],
         geom.asPoint().y(), geom.asPoint().x())
../_images/1115.png
  1. 到目前为止,所有的输出都直接显示在萤幕上,但其实如果能够存成档案,应该会更好用。你可以输入如下的程序代码,第一行的档名和路径记得改成你想存在你电脑中的样子,刚才的结果就会另存成新档。注意我们在每行的结尾都加上了``n``,这是用来告诉电脑存完每个图征资料后应该要换到下一行继续存。另外, unicode_line = line.encode('utf-8') 这一行的用意在于,有些图征的属性使用了 Unicode 字元,我们要先把它们编码成 UTF-8 格式,才能正确地存到文字档当中。
output_file = open('c:/Users/Ujaval/Desktop/airports.txt', 'w')
for f in layer.getFeatures():
  geom = f.geometry()
  line = '%s, %s, %f, %f\n' % (f['name'], f['iata_code'],
          geom.asPoint().y(), geom.asPoint().x())
  unicode_line = line.encode('utf-8')
  output_file.write(unicode_line)
output_file.close()
../_images/1213.png
  1. 最后就可以在输出的文字档中,查看我们刚刚利用 Python 指令从 shapefile 中转存出来的资料了!
../_images/1312.png