使用自订的 Python 表达式函数

QGIS 表达式非常的强大,而且也使用在许多核心操作上,像是选取、计算影像值、样式设定、标记等等。QGIS 也支援使用者自定义的表达式,只要使用一点点的 Python 程序,就可以设计自己的函数,然后把它安插到 QGIS 表达式的引擎中。

内容说明

我们要定义一个函数,它可以找出地图的 UTM 分区。然后我们要使用这个函数设计表达式,让使用者滑鼠在图征上移动的时候,可以显示出此处的 UTM 分区。

你还会学到这些

  • 使用 Map Tips 工具,在滑鼠游移在某图征上时显示自订的文字。

取得资料

我们要使用 Natural Earth 的 Populated Places 资料库,请下载 simple (less columns) dataset

为了方便起见,你也可以直接用下面的连结下载:

ne_10m_populated_places_simple.zip

操作流程

  1. 打开 QGIS,选择 Layers ‣ Add Vector ‣ Add Vector Layer
../_images/128.png
  1. 选择刚下载的 ne_10m_populated_places_simple.zip 并按下:guilabel:Open
../_images/219.png
  1. 选择 View ‣ Select ‣ Select By Expressions...
../_images/312.png
  1. 切换至:guilabel:Function Editor 分页,这里你可以撰写用于在表示式引擎中执行的 PyQGIS 程序代码。
../_images/48.png
  1. 由于 QGIS 中的自订函数作用在图征层级,所以我们可以定义一个称为``GetUtmZone`` 的函数,用来计算每个图征的 UTM 分区号码。 我们使用每个图征的中心经纬度座标来计算 UTM 分区号码,并且会加上 ‘N’ 或 ‘S’ 来标明此区是位在北半球还是南半球。 在编辑器中输入以下程序代码,把档案取名为``utm_zones.py``然后按下 Save file

注解

UTM 是依照经度把全球投影成 1 到 60 区,每个 UTM 分区都是经度 6 度宽。这里我们使用的是简单的数学公式,依照经度的数值来寻找适当的 UTM 分区,所以请注意这个公式并不处理一些比较特殊的 UTM 分区。

import math
from qgis.core import *
from qgis.gui import *

@qgsfunction(args=0, group='Custom')
def GetUtmZone(value1, feature, parent):
    centroid = feature.geometry()
    longitude = centroid.asPoint().x()
    latitude = centroid.asPoint().y()
    zone_number = math.floor(((longitude + 180) / 6) % 60) + 1

    if latitude >= 0:
        zone_letter = 'N'
    else:
        zone_letter = 'S'

    return '%d%s' % (int(zone_number), zone_letter)
../_images/58.png
  1. 按下 :guilabel:`Run Script`后程序代码会被执行,``GetUtmZone``函数会被注册到表达式引擎中。 这个步骤只须执行一次,当函数注册完毕后,就会一直在表达式引擎中出现。
../_images/67.png
  1. 切换到:guilabel:Expression 分页, 在 Select by expression 视窗中, 可看到在 Functions`的区块中有个:guilabel:`Custom 群组。 其中会出现一个新的函数 $GetUtmZone 这代表我们现在可以像使用其他函数一样使用这个函数了。 在文字编辑器中输入以下表达式,就可以选择所有落在 ``40N``的 UTM 分区中的点。按下 Select。(译按:随着 QGIS 版本的不同,你可能会看到 $GetUtmZone 或 GetUtmZone(),但都是一样的操作方法。)
$GetUtmZone = '40N'
../_images/77.png
  1. 回到 QGIS 主视窗,现在有许多点都被选取并标为黄色,这些就是符合我们给定的 UTM 分区表达式的点。
../_images/87.png
  1. 现在你已经知道我们要怎么利用自订表达式选取图征,接下来我们要使用同一个函数做另一件事。在 QGIS 中有个隐藏的神器称为 Map Tip``工具, 它会在你把滑鼠移到图征上时显示使用者定义的文字。请在``ne_10m_populated_places_simple 图层上按右键然后选择:guilabel:Properties
../_images/97.png
  1. 切换至 Display 分页,然后选择 HTML. 在这里你可以输入任何你想在图征上出现的文字,不过更好的做法是我们可以利用图层属性值或是表达式来指定更有用的讯息。按下 Insert expression... 钮。
../_images/107.png
  1. 你会再次看到熟悉的表达式编辑器。我们要利用``concat``函数来连接 name 属性和 GetUtmZone 函数的输出字串,因此输入以下的表达式后,按下:guilabel:OK
concat("name", ' | UTM Zone: ', $GetUtmZone)
../_images/1111.png
  1. 在:guilabel:Display`分页中的文字讯息内就会看到我们刚刚输入的表达式。按下:guilabel:`OK
../_images/129.png
  1. 在测试之前,要先取消我们在前几个步骤选取的点。选择 View ‣ Select ‣ Deselect Features from All Layers
../_images/137.png
  1. 选择 :menuselection:`View –> Map Tips`工具 以启动 ``Map Tips``功能。
../_images/147.png
  1. 缩放至地图的任一处然后把滑鼠游标放在任何图征上,你就会看到城市的名字和对应的 UTM 分区显示在地图提示之中。
../_images/157.png