13.1. 表达式

基于层数据和预建或用户定义的函数, Expressions 提供了一种强大的方法来操作属性值、几何和变量,以便动态更改几何样式、标签的内容或位置、示意图的值、布局项的高度、选择某些要素、创建虚拟字段、...

备注

有关编写表达式的默认函数和变量的列表,请参阅 功能列表 ,有详细的信息和例子。

13.1.1. 表达式字符串构建器

用于生成表达式的主对话框中的 Expression string builder 可从QGIS中的许多部分访问,尤其在以下情况下可以访问:

通过表达式生成器对话框可以访问:

13.1.1.1. 《界面》

这个 Expression 页签提供了使用函数、层字段和值编写表达式的主界面。它包含以下小部件:

../../../_images/function_list.png

图 13.1 [表达式]选项卡

  • 用于键入或粘贴表达式的表达式编辑器区域。自动完成功能可用于加快表达式编写速度:

    • 与输入文本对应的变量、函数名和字段名如下所示:使用 UpDown 箭头以浏览项目,然后按 Tab 插入到表达式中,或只需单击所需项目。

    • 功能参数在填充时显示。

    QGIS还使用以下命令检查表达式的正确性并突出显示所有错误:

    • Underline :对于未知函数,参数错误或无效;

    • Marker :对于单个位置的所有其他错误(例如,缺少括号、意外字符)。

    小技巧

    Document your expression with comments

    使用复杂表达式时,最好将文本添加为多行注释或内联注释,以帮助您记忆。

    /*
    Labels each region with its highest (in altitude) airport(s)
    and altitude, eg 'AMBLER : 264m' for the 'Northwest Artic' region
    */
    with_variable(
      'airport_alti', -- stores the highest altitude of the region
      aggregate(
        'airports',
        'max',
        "ELEV", -- the field containing the altitude
        -- and limit the airports to the region they are within
        filter := within( $geometry, geometry( @parent ) )
      ),
        aggregate( -- finds airports at the same altitude in the region
          'airports',
          'concatenate',
          "NAME",
          filter := within( $geometry, geometry( @parent ) )
            and "ELEV" = @airport_alti
        )
        || ' : ' || @airport_alti || 'm'
        -- using || allows regions without airports to be skipped
    )
    
  • 在表达式编辑器之上,有一组工具可以帮助您:

  • 在表达式编辑器下,您可以找到:

    • 帮助您构建表达式的一组基本运算符

    • 数据定义要素属性时输出的预期格式的指示

    • 一场现场直播 Output preview (最多60个字符),默认情况下根据层的第一个要素进行求值。要查看超过60个字符的输出预览文本,可以将光标悬停在文本上以显示包含整个输出预览的工具提示弹出窗口。要将输出预览文本复制到剪贴板上,请右键单击输出预览文本并选择 文案编辑 Copy Expression Value

      您可以使用浏览和评估该图层的其他要素 Feature 组合框(这些值取自 display name 层的属性)。

      如果出现错误,它会提示您,您可以通过提供的超链接访问详细信息。

  • 函数选择器显示函数、变量、字段的列表...以小组形式组织的。可以使用搜索框来筛选列表并快速找到特定的函数或字段。双击某个项目会将其添加到表达式编辑器中。

  • 帮助面板显示功能选择器中每个选定项目的帮助。

    小技巧

    新闻发布会 Ctrl+Click 将函数名悬停在表达式中时,可在对话框中自动显示其帮助。

    在函数选择器中选择某个字段时显示的字段值小部件可帮助获取要素属性:

    • 查找特定的字段值

    • 显示的列表 All Unique10 Samples 价值观。也可以通过单击鼠标右键访问。

      当该字段与另一个层或一组值映射时,即如果 field widget 是的 RelationReferenceValueRelationValueMap 类型,则可以列出映射字段的所有值(来自引用的层、表或列表)。此外,您还可以筛选此列表以 复选框 Only show values in use 在当前的领域中。

    双击小部件中的字段值将其添加到表达式编辑器中。

    小技巧

    显示函数帮助或字段值的右侧面板可以在对话框中折叠(不可见)。按下按钮 Show ValuesShow Help 按下按钮把它拿回来。

13.1.1.2. 编写一个表达式

QGIS表达式用于选择要素或设置值。在QGIS中编写表达式遵循一些规则:

  1. The dialog defines the context :如果您习惯于使用SQL,则可能知道以下类型的查询 select features from layer where conditionupdate layer set field = new_value where condition 。QGIS表达式也需要所有这些信息,但用于打开表达式构建器对话框的工具提供了这些信息的一部分。例如,给出一个层 (buildings )和一个字段 (height ):

    • 按下按钮 表达式选择 :sup:按表达式选择`工具表示您要从建筑物中选择要素。这个 **condition** 是您需要在表达式文本小部件中提供的唯一信息,例如类型 `"height" > 20`` 以选择高于20的建筑。

    • 进行此选择后,按下 计算字段 Field calculator 按钮并选择“Height”作为 Update existing field ,您已经提供了命令“UPDATE BUBILIES SET HEIGH=?WHERE HEIGH>20”。在这种情况下,您必须提供的唯一剩余位是 new value ,例如,只需输入 50 在表达式编辑器文本框中设置以前选定建筑物的高度。

  2. Pay attention to quotes :单引号返回文字,因此文本放在单引号之间 ('145' )被解释为字符串。双引号将为您提供该文本的值,因此在字段中使用双引号 ("myfield" )。也可以使用不带引号的字段 (myfield )。数字不带引号 (3.16 )。

    备注

    函数通常以字段名的字符串作为参数。DO::

    attribute( @atlas_feature, 'height' ) -- returns the value stored in the "height" attribute of the current atlas feature
    

    而不是:

    attribute( @atlas_feature, "height" ) -- fetches the value of the attribute named "height" (e.g. 100), and use that value as a field
                                          -- from which to return the atlas feature value. Probably wrong as a field named "100" may not exist.
    

小技巧

Use named parameters to ease expression reading

有些功能需要设置许多参数。表达式引擎支持使用命名参数。这意味着,与其编写神秘的表达式,不如 clamp( 1, 2, 9) ,您可以使用 clamp( min:=1, value:=2, max:=9) 。这也允许参数切换,例如 clamp( value:=2, max:=9, min:=1) 。使用命名参数有助于阐明表达式函数的参数引用的是什么,这在稍后尝试解释表达式时很有帮助!

13.1.1.3. 表达式的一些用例

  • 从字段计算器中,使用现有的“Total_POP”和“Area_Km2”字段计算“POP_Density”字段:

    "total_pop" / "area_km2"
    
  • 根据要素的面积对要素进行标记或分类:

    CASE WHEN $area > 10 000 THEN 'Larger' ELSE 'Smaller' END
    
  • 根据“POP_Density”值使用类别更新字段“Density_Level”::

    CASE WHEN "pop_density" < 50 THEN 'Low population density'
         WHEN "pop_density" >= 50 and "pop_density" < 150 THEN 'Medium population density'
         WHEN "pop_density" >= 150 THEN 'High population density'
    END
    
  • 根据平均房价是小于还是高于每平方米10000欧元,对所有功能应用分类样式::

    "price_m2" > 10000
    
  • 使用“按表达式选择...”工具,选择代表人口密度高且平均房价高于每平方米10000欧元的所有要素::

    "density_level" = 'High population density' and "price_m2" > 10000
    

    前面的表达式还可以用于定义要在地图上标记或显示的要素。

  • 使用几何图形生成器为层创建不同的符号(类型):

    point_on_surface( $geometry )
    
  • 给定点要素,生成闭合线(使用 make_line )围绕其几何体::

    make_line(
      -- using an array of points placed around the original
      array_foreach(
        -- list of angles for placing the projected points (every 90°)
        array:=generate_series( 0, 360, 90 ),
        -- translate the point 20 units in the given direction (angle)
        expression:=project( $geometry, distance:=20, azimuth:=radians( @element ) )
      )
    )
    
  • 在打印布局标签中,显示布局“地图1”项目中的“机场”要素的名称:

    with_variable( 'extent',
                   map_get( item_variables( 'Map 1' ), 'map_extent' ),
                   aggregate( 'airports', 'concatenate', "NAME",
                              intersects( $geometry, @extent ), ' ,'
                            )
                 )
    

13.1.1.4. 保存表达式

Using the 文件保存 Add current expression to user expressions button above the expression editor frame, you can save important expressions you want to have quick access to. These are available from the User expressions group in the middle panel. They are saved under the user profile (<userprofile>/QGIS/QGIS3.ini file) and available in all expression dialogs inside all projects of the current user profile.

表达式编辑器框架上方的一组工具可帮助您管理用户表达式:

  • 文件保存 :sup:将当前表达式添加到用户表达式:将该表达式存储在用户配置文件中。可以添加标签和帮助文本以便于识别。

  • 符号系统编辑 Edit selected expression from user expressions ,以及他们的帮助和标签

  • 删除所选内容 Remove selected expression from user expressions

  • 共享导入 Import user expressions 从一个 .json 文件放到活动用户配置文件文件夹中

  • 共享导出 Export user expressions 作为一名 .json 文件;用户配置文件中的所有用户表达式 QGIS3.ini 文件是共享的

13.1.2. 函数编辑器

Function Editor 选项卡中,您可以用Python语言编写自己的函数。这提供了一种方便、舒适的方式来解决预定义函数无法满足的特定需求。

../../../_images/function_editor.png

图 13.2 函数编辑器选项卡

要创建新函数,请执行以下操作:

  1. 按下按钮 符号系统添加 New File 纽扣。

  2. 输入要在弹出的表单中使用的名称,然后按 OK

    的左侧面板中添加一个与您提供的名称相同的新项 Function Editor Tab;这是一条 Python .py 基于QGIS模板文件的文件并存储在 /python/expressions 活动目录下的文件夹 user profile 目录。

  3. 右侧面板显示文件的内容:一个python脚本模板。根据您的需要更新代码及其帮助。

  4. 按下按钮 开始 Save and Load Functions 纽扣。您编写的函数将被添加到 Expression 选项卡中,默认情况下位于 Custom 一群人。

  5. 享受你的新功能。

  6. 如果该功能需要改进,请启用 Function Editor 选项卡中,进行更改,然后再次按 开始 Save and Load Functions 按钮以使它们在文件中可用,因此在任何表达式选项卡中都可用。

定制的Python函数存储在用户配置文件目录下,这意味着在每次启动QGIS时,它将自动加载使用当前用户配置文件定义的所有函数。请注意,新函数仅保存在 /python/expressions 文件夹中,而不在项目文件中。如果您共享的项目使用您的某个自定义函数,则还需要共享 .py 文件中的 /python/expressions 文件夹。

要删除自定义函数,请执行以下操作:

  1. 启用 Function Editor 选项卡

  2. 选择列表中的函数

  3. 按下按钮 符号系统移除 Remove selected function 。该函数将从列表中删除,并且对应的 .py 从用户配置文件文件夹中删除的文件。

Example

这里有一个简短的示例,说明如何创建自己的 my_sum 函数,该函数将以两个值运行。

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

@qgsfunction(args='auto', group='Custom')
def my_sum(value1, value2, feature, parent):
    """
    Calculates the sum of the two parameters value1 and value2.
    <h2>Example usage:</h2>
    <ul>
      <li>my_sum(5, 8) -> 13</li>
      <li>my_sum("field1", "field2") -> 42</li>
    </ul>
    """
    return value1 + value2

这个 @qgsfunction Decorator接受以下参数:

  • args :参数的数量。在使用 args='auto' 参数所需的函数参数数量将根据在Python中定义函数的参数数量计算(减去2- feature ,以及 parent )。使用 args = -1 ,任何数量的论点都可以接受。

  • 这个 group 参数指示函数应在表达式对话框中列出的组。

  • usesgeometry=True 如果表达式需要访问要素几何图形。默认情况下 False

  • handlesnull=True 如果表达式具有对空值的自定义处理。如果 False (默认),只要任何参数为空,结果都将始终为空。

  • referenced_columns=[list] :函数所需的属性名称数组。默认为 [QgsFeatureRequest.ALL_ATTRIBUTES]

该函数本身允许以下参数:

  • 要传递给函数的任何数量和类型的参数,请在以下参数之前设置。

  • feature :当前功能

  • parentQgsExpression 对象

  • context: If there is an argument called context found at the last position, this variable will contain a QgsExpressionContext object, that gives access to various additional information like expression variables. E.g. context.variable( 'layer_id' )

然后,可以在表达式中使用前面的示例函数:

../../../_images/customFunction.png

图 13.3 添加到表达式选项卡中的自定义函数

有关创建Python代码的更多信息,请参阅 《PyQGIS开发人员手册》