QGIS-示例-全-
QGIS 示例(全)
原文:
zh.annas-archive.org/md5/ec8182c2d64b39081dc73c667fa1c91a译者:飞龙
前言
欢迎使用 QGIS 通过实例学习。本书将帮助你了解 QGIS 的功能,展示如何处理空间数据并执行最常见分析,并通过处理框架将你的生产力提升到新的水平。
QGIS 是一个非常受欢迎且用户友好的开源桌面 GIS。它提供了许多有用的功能和特性,其数量持续增长。它支持广泛的栅格和矢量格式,以及数据库和 OGC 服务。它还与其他 FOSSGIS 应用程序无缝集成。越来越多的用户选择 QGIS 作为他们主要的 GIS 软件。
本书将介绍 QGIS 2.8.x,并展示如何正确准备数据以便舒适地工作,设计美观的地图,并与他人分享。它还将展示如何执行不同类型的分析并解释其结果。在最后几章中,你将学习如何通过使用 QGIS 处理框架自动化重复性任务来提高生产率,以及如何通过开发 Python 插件来扩展 QGIS 功能。
本书涵盖的内容
第一章, 处理您的数据,涵盖了 QGIS 的安装,介绍了其用户界面,并展示了如何自定义它。在本章中,你还将了解如何从不同来源加载数据并将其组装到空间数据库中。
第二章, 可视化和样式化数据,涵盖了为显示而样式化矢量和栅格数据。从基本样式选项开始,我们深入到更高级的主题,包括基于规则的渲染和标签。
第三章, 在打印地图上展示数据,展示了 QGIS 的功能,帮助我们设计美观且易于阅读的打印地图。你将了解打印作曲家,并学习如何使用其功能来创建出色的地图和地图集(也称为地图册)。
第四章, 在线发布地图,解释了为在云服务上发布 QGIS 项目所做的准备。这包括在 QGIS 云服务中创建账户,调整项目设置,上传数据和发布项目。
第五章, 使用密度分析回答问题,涵盖了在处理大型密集点数据集时有用的技术。在本章中,你将学习如何从点数据创建栅格热图,以及如何使用它们来检测最热区域和检查空间分布模式。你还将了解另一种称为分箱的技术,这是热图的替代方法。
第六章, 使用可视性分析回答问题,展示了用于可视性分析的技术和工具。你将了解可视性分析所需的数据以及如何准备这些数据以获得精确和有意义的成果。你还将学习如何计算视域并在 3D 格式中展示最终结果。
第七章, 使用适宜性分析回答问题,涵盖了适宜性分析中使用的方法和技术。我们从解释不同对象之间的空间关系开始,并学习如何在 GIS 语言中表达它们。然后你将了解如何使用栅格数据执行适宜性分析。最后,你将学习如何解释分析结果。
第八章, 使用处理模型自动化分析,教你处理图形模型器的功能。我们从图形模型器的一般概述开始。然后我们通过模型创建的过程,从开始到最终结果——一个可用的模型。
第九章, 使用处理脚本自动化分析,涵盖了使用 QGIS 处理框架进行脚本编写。我们从基本主题开始,例如从 QGIS Python 控制台使用现有的处理算法。然后我们看看如何创建具有所需功能的自定义处理脚本。
第十章, 开发 Python 插件 – 以半径选择,包含了开发你自己的 QGIS Python 插件所需的主题。我们从基本的插件模板开始,然后扩展它,最后解释如何使用 Qt Designer 设计插件 GUI。此外,你还将了解如何为发布准备你的插件。
你需要为这本书准备的内容
为了跟随这本书中的所有示例,你需要以下软件:
-
QGIS 2.8.0 或任何后续版本
-
Python 2.7.6(通常在 Windows 下与 QGIS 一起安装或在类 Unix 操作系统下系统提供的版本)
-
Qt 和 PyQt 开发者工具
-
所有这些软件都可以免费下载,并在 Linux、Mac OS X 和 Windows 上运行
这本书面向的对象
如果你是一个 GIS 初学者或中级用户,这本书就是为你准备的。它非常适合那些对地理空间数据和软件了解甚少或没有了解的从业者、数据分析师和应用开发者。这本书将为你打开 QGIS 美妙世界的大门,并教你如何使用 QGIS 解决最常见的 GIS 任务。
习惯用法
在这本书中,您会发现多种文本样式,用于区分不同类型的信息。以下是一些这些样式的示例及其含义的解释。
文本中的代码单词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 标签应如下所示:"我们可以通过使用include指令来包含其他上下文。"
代码块应如下设置:
( 1) SOURCES = __init__.py \
( 2) selectradius_plugin.py \
( 3) gui/selectradiusdialog.py \
( 4) gui/aboutdialog.py \
( 5)
任何命令行输入或输出都应如下所示:
Calculator------------------------------------------->modelertools:calculator
Raster layer bounds---------------------------------->modelertools:rasterlayerbounds
Vector layer bounds---------------------------------->modelertools:vectorlayerbounds
新 术语 和 重要 单词 以粗体显示。您在屏幕上看到的单词,例如在菜单或对话框中,在文本中如下所示:"点击下一步按钮将您带到下一个屏幕。"
注意
警告或重要注意事项将以如下框的形式出现。
小贴士
小技巧和窍门如下所示。
读者反馈
我们始终欢迎读者的反馈。请告诉我们您对这本书的看法——您喜欢或不喜欢的地方。读者反馈对我们来说非常重要,因为它帮助我们开发出您真正能从中获得最大收益的书籍。
要向我们发送一般反馈,请简单地发送电子邮件至 <feedback@packtpub.com>,并在邮件主题中提及书籍的标题。
如果您在某个主题上具有专业知识,并且您对撰写或为书籍做出贡献感兴趣,请参阅我们的作者指南,网址为 www.packtpub.com/authors。
客户支持
现在您已经是 Packt 图书的骄傲拥有者,我们有一些事情可以帮助您从您的购买中获得最大收益。
下载示例代码
您可以从您的账户下载示例代码文件,网址为 www.packtpub.com,以获取您购买的所有 Packt Publishing 书籍的示例代码。如果您在其他地方购买了这本书,您可以访问 www.packtpub.com/support 并注册,以便将文件直接通过电子邮件发送给您。
下载本书的颜色图像
我们还为您提供了一个包含本书中使用的截图/图表颜色图像的 PDF 文件。这些颜色图像将帮助您更好地理解输出的变化。您可以从 www.packtpub.com/sites/default/files/downloads/4677OS_ColoredImages.pdf 下载此文件。
错误清单
尽管我们已经尽一切努力确保我们内容的准确性,但错误仍然可能发生。如果您在我们的某本书中发现错误——可能是文本或代码中的错误——如果您能向我们报告这个问题,我们将不胜感激。通过这样做,您可以节省其他读者的挫败感,并帮助我们改进本书的后续版本。如果您发现任何勘误,请通过访问 www.packtpub.com/submit-errata,选择您的书籍,点击勘误提交表单链接,并输入您的勘误详情来报告它们。一旦您的勘误得到验证,您的提交将被接受,勘误将被上传到我们的网站或添加到该标题的勘误部分下的现有勘误列表中。
要查看之前提交的勘误,请访问 www.packtpub.com/books/content/support,并在搜索字段中输入书籍名称。所需信息将出现在勘误部分下。
盗版
互联网上对版权材料的盗版是一个跨所有媒体的持续问题。在 Packt,我们非常重视我们版权和许可证的保护。如果您在互联网上发现我们作品的任何非法副本,请立即提供位置地址或网站名称,以便我们可以寻求补救措施。
请通过 <copyright@packtpub.com> 联系我们,并提供涉嫌盗版材料的链接。
我们感谢您在保护我们作者和我们为您提供有价值内容的能力方面的帮助。
问题
如果您在这本书的任何方面遇到问题,您可以通过 <questions@packtpub.com> 联系我们,我们将尽力解决问题。
第一章. 处理您的数据
在本章中,我们将准备所有必要的工具和数据,以便对空间现象进行视觉探索、制图和分析。在了解 QGIS 作为桌面 GIS 的基础知识之后,您将学习如何安装和配置它。然后,我们将介绍最常见的数据源,并在最后将它们聚合到一个单一的空间数据库中,该数据库将在后续章节中用于样式、制图和分析。
在本章中,我们将讨论以下主题:
-
QGIS 安装
-
图形用户界面 (GUI),其元素及其定制
-
从常见来源加载各种类型的空间数据
-
投影的基本知识
-
将数据组装成单一的空间数据库
安装 QGIS
QGIS 是一个免费的开放源代码桌面 GIS,其开发始于 2002 年。自 2007 年以来,该项目在 开源地理空间基金会 (OSGeo) 的支持下发展。作为一个相对较新的项目,QGIS 由于以下原因在全世界个人用户、私营公司和组织中越来越受欢迎:
-
根据 GNU 通用公共许可证 (GPL) 进行分发,该许可证确保用户有权使用、学习、分享和修改软件
-
跨平台支持,这意味着 QGIS 可以在 Linux、Unix、Mac OS、Windows 和 Android 操作系统上运行
-
多种矢量、栅格数据格式支持,以及数据库格式和功能
-
核心功能的持续改进,包括数据创建、编辑、处理、分析、存储和可视化表示
-
来自国际开发者社区支持的所谓插件的可用外部功能的持续增长
注意
您可以从 QGIS 的官方网站
qgis.org/以及其文档章节documentation.qgis.org/获取更多关于 QGIS 的信息。
根据 QGIS 项目的发布计划,每 4 个月就有一个新的 QGIS 版本可用。从 QGIS 2.8 开始,每第三个发布版本都是一个长期发布 (LTR)。它将维护一年,然后下一个 LTR 发生。在整个本书中,使用了一个名为 "Wein" 的 QGIS 2.8 LTR 版本。
当前 QGIS 版本的安装程序可以从官方网站的下载页面 download.qgis.org 获取,适用于不同的操作系统。MS Windows 的 32 位和 64 位安装文件如下分发:
-
QGIS 独立安装程序:使用这些安装程序安装 QGIS 与 Windows 下的传统软件安装程序没有区别
-
OSGeo4W 网络安装程序:与独立安装程序相比,它具有以下优点:
-
除了 QGIS 之外,它还允许我们安装大量其他软件包以处理空间数据(命令行工具、库和桌面及服务器应用程序)
-
它确保安装最新版本的软件,这些版本直接链接到不断更新的仓库
-
一旦定义,OSGeo4W 工作环境方便用于自动和及时的更新、添加软件包或删除软件包
-
让我们以最新 32 位版本为例,通过 OSGeo4W 安装程序来了解 QGIS 及其组件的安装过程。由于安装(尤其是初级)需要下载大量文件,因此拥有高速互联网连接是理想的。安装过程如下:
-
下载 OSGeo4W 32 位网络安装程序的最新版本,双击
osgeo4w-setup-x86.exe以运行安装。 -
在安装程序窗口中,选择 高级安装,如下面的截图所示。从现在起,只需仔细阅读并遵循说明。
![安装 QGIS]()
-
选择 从互联网安装,并保留下载的文件以供将来重用。
-
选择 OSGeo4W 软件套件的安装目录。
C:\OSGeo4W是一个常见且方便的选择。如果您想使用另一个目录,请给它一个合适的名称,路径要短,不要包含空格和特殊符号。 -
然后,选择一个目录来保存下载的软件包。您可以通过手动输入其名称来创建一个新目录,例如
C:\OSGeo4W\Downloads。请记住,要下载的文件量大约为 200 MB,您需要足够的空间来保存它们。 -
如果有,配置您的互联网连接参数,然后点击 下一步 按钮继续。点击 下一步 按钮后,将下载所有软件包的列表,并进入软件包选择模式,如下面的截图所示。可用的软件包分为以下类别:命令行工具、桌面、库和网络。
![安装 QGIS]()
-
要安装软件包,点击 + 号以展开类别,并通过点击其旁边的圆形箭头(跳过 将被替换为最新可用版本号)选择一个应用程序。
-
要安装最新版本的 QGIS,选择 qgis: QGIS 桌面版 和 grass: GRASS GIS 稳定版。GRASS 是一个独立的 GIS 应用程序,它与 QGIS 紧密集成,并提供高级地理处理功能。
-
点击 下一步 按钮后,安装程序自动检测必要的依赖项,并继续下载软件包和安装,如下面的截图所示:
![安装 QGIS]()
小贴士
您也可以安装 qgis-dev: QGIS 主分支的夜间构建版本。由于处于持续开发中,这个版本被认为是不稳定的,并且每晚都会更新。它不推荐用于日常使用,但如果您想尝试一些新功能并向开发者提供反馈,则很有用。
安装完成后,您将在 开始 菜单中找到 OSGeo4W 组,包含以下组件:
-
MSYS:这是一组确保传统上依赖于 UNIX 工具的应用程序创建的 GNU 工具
-
OSGe4W Shell:这是 OSGeo4W 工具的命令行界面
-
QGIS 浏览器 2.8.1:这是一个用于导航和数据预览的 QGIS 探索器
-
QGIS 桌面 2.8.1:这是一个 QGIS 桌面应用程序
-
设置:这是一个 OSGeo4W 安装程序启动器
-
GRASS GIS 7.0.0:这是 GRASS GIS 及其组件
如果您想更新 QGIS 或使用一些新组件扩展当前安装,只需从 OSGeo4W 菜单文件夹中点击 设置 快捷方式并运行 高级安装 程序。安装程序将检查可用的更新和必要的依赖项,下载它们,并安装它们。
GUI 元素和自定义
当您第一次启动 QGIS 时,您将看到以下截图所示的界面。根据定义,QGIS 界面使用系统语言。为了本教程的目的,您可以通过转到 设置 | 选项 | 区域 并重新启动 QGIS 来将其更改为英语并应用您的更改。

QGIS 界面由五个主要部分组成:
-
菜单栏:它以传统形式提供对所有 QGIS 功能的访问——下拉菜单。
-
面板:这些是可以停靠或浮动的窗口。默认情况下,您可以在工作区的左侧看到两个激活的面板。
-
图层面板用于显示所有加载图层的树形视图列表。
-
浏览器面板提供快速导航和访问各种本地、服务器或在线数据源。您可以使用其右上角的特殊按钮关闭或缩小面板。您还可以将其拖放到方便的位置。
小贴士
在本书的整个过程中,我们将不时使用 浏览器 面板,因此请尽量将其分配到适当的位置,而不是关闭它。例如,通过将其拖放到 图层 面板,您可以创建两个独立的标签页:一个用于图层,另一个用于数据源导航。在这种情况下,您将不必牺牲窗口空间来扩展和查看项目。
![GUI 元素和自定义]()
您可以通过转到 视图 | 面板 来打开或关闭面板。同样,您可以在工作区上方的任何位置右键单击,并将弹出一个带有切换按钮的窗口。此窗口由一条水平线分隔,面板切换按钮位于其上部。
-
-
工具栏:菜单功能被分组到逻辑工具集中,并放置在栏中的按钮上,以提供方便访问所有必要的工具。默认情况下,以下工具栏被打开并显示:
![GUI 元素和自定义]()
文件工具栏
![GUI 元素和自定义]()
地图导航工具栏
![GUI 元素和自定义]()
属性工具栏
![GUI 元素和自定义]()
数字化工具栏
![GUI 元素和自定义]()
标签工具栏
![GUI 元素和自定义]()
帮助和插件工具栏
![GUI 元素和自定义]()
图层管理工具栏
如果你想查看简短的工具参考,只需将鼠标指针悬停在按钮上,就会弹出一个黄色的信息窗口。一些按钮或工具栏被灰色显示(例如,数字化 工具栏和 标签 工具栏),这意味着它们只能在执行某些操作后使用。例如,数字化 工具栏的按钮只有在某些图层激活了编辑模式后才能使用。工具栏可以停靠,并且可以轻松地在工作区中移动。要移动工具栏,将鼠标箭头放在其由穿孔点标记的边界上。箭头将变成十字形,表示现在可以拖动并放下工具栏到任何其他位置,同时按住鼠标左键。你可以通过导航到 视图 | 工具栏,或从任何工具栏上右键点击调出的窗口中打开或关闭工具栏。
-
地图区域:这是界面窗口中最大的部分,用于数据地图显示和视觉探索。
-
状态栏:此栏简要显示有关当前地图概览的以下信息:渲染进度条(仅在渲染需要一些时间来显示进度时可见)、鼠标指针的位置坐标、比例尺和当前坐标参考系统。它还包含切换到范围坐标和暂时关闭地图渲染的切换按钮。还有用于打开坐标参考系统对话框
和显示 日志消息 面板的按钮
。
通过导航到设置 | 自定义,可以进行高级 GUI 自定义。从这个对话框中,您可以完全控制所有菜单、面板、工具栏和小部件。要开始自定义过程,打开启用自定义切换按钮。如果您不熟悉 QGIS 界面,进入
切换到捕获主应用程序小部件模式会更简单。在此模式下,您可以点击任何想要隐藏的 GUI 项——工具栏上的按钮或工具栏本身。所选项目会被突出显示,相关的自定义树项会展开,如下面的截图所示。如果您不小心选择了某个项目,只需再次点击它即可取消选择。否则,您可以展开相关项目,检查/取消检查一些切换按钮,然后点击确定。更改将在 QGIS 重启后生效。

小贴士
随着你对 QGIS 的熟悉程度提高,并开始用它来完成不同的任务,创建几个针对不同用例的用户 GUI 配置文件可能很方便(例如,数字化、与数据库或栅格数据工作等)。为此,您需要在自定义对话框窗口中调整所有必要的设置,并将
保存到.ini文件中。之后,您只需通过加载预定义的自定义文件
的设置,就可以快速修改界面。
一些小的界面更改,例如通用样式、默认图标大小、字体等,都可以在应用程序组中找到,通过访问设置 | 选项 | 常规来查找。
通过插件扩展功能
从一开始,QGIS 就具有模块化架构,这使得添加新功能或功能变得容易。QGIS 中的大多数功能都是通过所谓的插件实现的,这些插件分为以下类型:
-
核心插件:这些插件默认包含在 QGIS 中,并由开发团队维护。为了使用它们,用户只需激活即可。
-
外部插件:这些插件位于外部仓库中,由作者维护。为了使用它们,用户首先需要安装。随着时间的推移,一些最有用和最受欢迎的插件被整合到了 QGIS 的核心功能中。
管理插件
插件管理意味着它们的激活、安装、更新和删除,这些操作通过导航到插件 | 管理和安装插件来完成。对话框窗口中有几个选项卡。点击这些选项卡中的任何单个插件都会显示详细信息:插件是否为实验性的,功能、评分、作者、版本,以及一些指向其主页、代码仓库和跟踪器的链接:
-
全部:在此选项卡下,您可以查看所有可用的插件列表,包括已安装和未安装的。
-
已安装:此选项卡显示已安装在 QGIS 中的插件。如果您想激活/停用插件,只需检查/取消检查其旁边的切换按钮。
-
未安装:此选项卡包含所有未在您的 QGIS 中安装的可用的插件列表。
以下选项卡不是永久的,只有当有插件满足某些条件时才会显示:
-
可升级:只有当仓库中有可用的较新版本的已安装插件时,此选项卡才会可见。
-
无效:当安装了与您的 QGIS 版本不兼容或损坏的插件时,此选项卡会显示。如果您点击此选项卡中的单个插件,您将看到有关无效可能原因的信息;这样您就可以向开发者提供一致的反馈。
-
新插件:此选项卡显示首次看到的未安装插件。
![管理插件]()
-
-
设置:此选项卡允许您定义更新检查的频率以及是否使用实验性或已弃用的插件。虽然不建议在生产环境中使用实验性插件,但您仍然可以激活选项来探索所有可用的工具。默认情况下,仅连接到QGIS 官方插件仓库,但您可以通过点击添加...按钮连接其他已知仓库。例如,前面的截图显示了如何添加外部 Boundless 插件仓库。
要安装插件,请返回到未安装选项卡,选择您想要安装的插件,然后点击安装插件。之后,安装开始,安装完成后,将显示关于成功安装的消息。默认情况下,已安装的插件被激活,并可能出现在插件菜单中,或者被添加到另一个相关菜单(例如,矢量或栅格)。此外,一些插件作为单独的工具栏和面板出现,可以手动放置并打开或关闭。
由于插件数量超过 400 个且不断增长,寻找和选择满足您需求的插件可能很困难。要探索 QGIS 插件的世界,您可以从 plugins.qgis.org/ 开始,该网站包含有关流行和特色插件的信息。如果您正在寻找特定功能但不知道确切的插件名称,我们建议您使用管理和安装插件对话框窗口中的标签词进行搜索,如图下所示:

小贴士
默认情况下,插件按名称字母顺序排序。如果您想根据下载量、投票或状态进行评分,可以通过右键单击插件列表的上下文菜单应用额外的排序选项。
将数据加载到 QGIS 中
GIS 中的数据可以以单独的文件、数据库或外部在线资源的形式提交。此外,GIS 中使用了不同的数据模型来表示空间对象的几何形状。矢量数据模型主要用于表达离散特征,例如点(例如,单独生长的树木和兴趣点)、线(道路或铁路)和多边形(建筑或行政边界)。栅格数据对于表达比点、线或多边形更好的连续现象来说很方便。最常见的栅格数据源是遥感影像、数字高程模型和扫描并地理定位的地形图。
QGIS 使用 GDAL/OGR 空间数据库来读取和写入多种矢量和栅格文件格式。在接下来的章节中,我们将简要讨论您可以获得数据的最常见的文件格式。此外,我们将探讨最近广泛使用的数据源,例如 CSV 文件、由 GPS 接收器收集的文件和 OpenStreetMap。
加载 shapefiles
我们的大部分数据都是以 ESRI shapefile 格式存储的,这是最常见的矢量数据文件格式之一。有几种不同的方法可以将 shapefile 加载到 QGIS 中。您可以通过访问图层 | 添加图层 | 添加矢量图层来打开对话框窗口,或者通过点击管理图层工具栏上的相关按钮
,或者使用Ctrl + Shift + V 键盘快捷键。
在添加矢量图层对话框窗口中,配置以下项目:
-
数据源类型,可以是文件、目录、数据库或协议。默认情况下,指定的文件数据源类型适用于加载由单独文件表示的空间数据,就像在我们的例子中一样。
-
如果您处理的数据包含特殊符号或其文本属性的字符集与传统的拉丁符号不同,请考虑编码下拉列表选项。在这种情况下,您应从下拉列表中选择适当的编码类型。我们的数据不包含任何特殊符号,所以我们接受默认的系统编码。
-
浏览按钮用于导航到工作目录。在那里,您可以选择一个或多个文件(使用Ctrl键),然后点击打开按钮来添加。
小贴士
第一次使用时,您可能会被可用文件的数量和多样性所淹没。这是因为 GIS 中,数据集通常由具有不同扩展名的多个文件表示。例如,ESRI 形状文件至少由 4 个文件组成(
.shp,.shx,.dbf和.prj),它们具有相同的名称,其中.shp是您应该选择以将数据加载到 QGIS 中的文件。您看到所有文件是因为窗口右下角的文件类型过滤器默认设置为所有文件。要隐藏所有不必要的文件,请选择ESRI 形状文件文件类型。将来,不要忘记根据所需的文件类型调整过滤器。
或者,您可以使用浏览器面板导航到工作目录。选择您想要加载的文件(一个或多个,按住Ctrl键),然后将它们拖放到地图区域。如果您想简化导航,可以从其右键菜单快捷键中将您当前正在工作的文件夹添加到收藏夹。

加载的文件被分配了随机颜色。目前不必担心这个问题;我们将在第二章,可视化和样式化数据中介绍图层符号。
加载栅格数据
添加栅格文件的过程与前面描述的类似,因此我们将简要介绍其示例,即常见的栅格文件格式GeoTIFF:
-
您可以通过访问图层 | 添加图层 | 添加栅格图层,点击管理图层工具栏上的相关按钮
,或者使用Ctrl + Shift + R键盘快捷键来加载数据栅格文件。 -
在打开 GDAL 支持的栅格数据源窗口中,进入工作目录。
-
要查看可用的 GeoTIFF 文件,请记住调整文件类型过滤器,选择一个或多个文件(按住Ctrl键),然后点击打开。或者,您可以从浏览器面板拖放栅格数据。
从个人地理数据库加载数据
ESRI 个人地理数据库是 ArcGIS 的原始数据格式,其中数据库的所有内容都存储在一个单独的.mdb Microsoft Access 文件中。它广泛用于将数据存储在单个数据文件中,而不是多个不同格式的文件中。
将 ESRI 文件地理数据库添加到 QGIS 与添加任何其他矢量格式类似:
-
通过访问图层 | 添加图层 | 添加矢量图层,或者点击管理图层工具栏上的相关按钮
,或者使用Ctrl + Shift + V键盘快捷键来访问对话框窗口。 -
进入工作目录,设置文件类型过滤器为ESRI 个人地理数据库,并选择您想要从中导入数据的数据库文件。
-
在选择要添加的矢量图层...窗口中,您将看到可用的图层及其特征。点击要添加的图层并点击确定。
![从个人地理数据库加载数据]()
注意
数据库中包含的栅格图层将被解释并作为边界框多边形加载到 QGIS 中。如果数据存储在不含任何空间特征的表中,几何类型将显示为未知。这些表将被加载并可用于导出为其他格式(例如,
.dbf)或与空间数据图层连接。
导入 CSV 文件
逗号分隔值(CSV)文件是另一种流行的数据文件格式。实际上,它只是一个用逗号分隔字段值的电子表格。除了逗号之外,还有各种可能的分隔符(例如,制表符、空格、冒号等)。这些表格通常包含以点经度或纬度(XY)坐标或已知文本(WKT)几何形式表示的位置属性的空间数据。
在我们的数据集中,有一个名为 noise.csv 的 CSV 文件。它包含主要由纽约市警察局登记的噪音投诉的详细信息。要将此文件添加为空间图层,请按照以下步骤操作:
-
通过访问图层 | 添加图层 | 添加分隔文本图层打开从分隔文本文件创建图层对话框,或者只需在管理图层工具栏中点击相关的按钮
。 -
在浏览并指向您的文件后,QGIS 尝试使用指定的分隔符解析它。默认情况下,使用逗号分隔符,但您可以使用自定义分隔符(逗号、制表符、空格等)或正则表达式分隔符指定任何其他分隔符。
![导入 CSV 文件]()
-
对话框还提供了访问许多其他有用设置的途径;例如,开启第一行包含字段名选项将为字段创建标题。在将几何形状定义为点坐标、包含经度和纬度值的X 字段和Y 字段后,这些字段将从数据集中自动加载。
-
在您点击确定后,QGIS 读取数据并可能显示类似于文件 full_path_to_the_file/filename.csv 中存在错误 100 条记录因缺少几何定义而被丢弃的定界文本文件错误消息。这意味着某些点不包含地理坐标,因此它们无法正确定位。在关闭消息窗口后,您将被提示指定图层的坐标参考系统(CRS)。
![导入 CSV 文件]()
如我们从纬度和经度列的值中可以看到,点坐标最初是由全球定位系统(GPS)的接收设备以十进制度数注册的。还知道 GPS 使用 WGS 84 坐标系。这就是为什么在坐标参考系统选择器窗口中,我们输入EPSG: 4326代码过滤器,并在地理坐标系统下指定WGS 84作为初始坐标系。点击确定后,您会看到数据在地图画布上以点的方式呈现。
注意
QGIS 使用基于欧洲石油勘探集团(EPSG)的地理参数数据集的 CRS 定义,该数据集包含全球、区域、国家和地方应用的坐标参考系统和转换的详细结构化描述。EPSG 标识符数据库可用于在 QGIS 中指定 CRS。您可以在
www.epsg-registry.org/了解更多关于 EPSG 地理参数数据集的信息。
加载 GPS 数据
随着 GPS 接收器变得便携且相对便宜,GPS 跟踪成为在野外调查期间收集数据的一种普遍和广泛使用的技巧,或者在跑步或骑自行车时简单地跟踪自己的路线。根据接收器的功能,除了空间坐标外,还可以注册和写入大量信息——例如,时间、海拔等。注册的信息存储在代表位置变化的点(路径、轨迹或路线点)、(如果存在)计划路线以及移动轨迹中。存储 GPS 数据有多种格式。作为主要数据格式,QGIS 使用标准的交换GPX(GPS 交换)格式。
我们将从数据集中加载nyc_marathon.gpx文件。您可以通过前往图层 | 添加图层 | 添加矢量图层,点击管理图层工具栏中的相关按钮
,或者使用Ctrl + Shift + V键盘快捷键来加载一个.gpx文件作为矢量图层。转到数据目录并应用GPS 交换格式(GPX)文件类型过滤器。选择您想要添加的文件(或文件),然后点击打开。或者,您可以从浏览器面板拖放文件。

由于 GPS 数据由点、路线和轨迹组成,窗口会弹出,让您选择您想要打开的确切要素。您可以通过点击一行并按住Ctrl键来选择一个或多个要素。如果您不确定需要哪个要素,请使用全选。每种要素类型都会在单独的图层中呈现。通过打开和关闭图层,您可以检查它们是否包含数据;例如,我们正在处理的文件只包含轨迹和轨迹点。您可以通过右键点击图层上下文快捷方式删除来移除不必要的空图层。
注意
通过GPS Tools核心插件可以访问处理 GPS 数据的高级选项。激活后,可以通过导航到向量 | GPS | GPS Tools或从向量工具栏面板上的
按钮访问插件功能。
获取 OpenStreetMap 数据
OpenStreetMap (OSM)是一个旨在开发世界开放地图的众包项目。全球范围内,OSM 社区使用高分辨率遥感影像、GPS 测量和当地知识来制作尽可能精确和详细的地图。由于 OSM 数据根据 Open Data Commons 的开放数据库许可(ODbL)许可,它最近已成为广泛使用的空间数据来源。理解无限制访问空间数据的重要性,QGIS 支持 OSM,提供对其数据的集成访问和支持。
QGIS 的核心功能可以从向量菜单下的OpenStreetMap访问。在这里,你可以找到所有下载数据并将其导出为传统空间数据格式的所需工具,但如果你是 QGIS 和 OSM 数据概念的初学者,可能会觉得这个过程很繁琐。这就是为什么我们建议你使用外部QuickOSM插件功能来下载 OSM 数据。
如同在通过插件扩展功能部分所述安装后,可以通过访问Web | QuickOSM | QuickOSM来访问插件的主要功能。主窗口的快速查询标签页包含了执行查询并将数据导入 QGIS 所需的所有内容。首先,从下拉列表中定义一个key=value对,或者手动输入它。
注意
如果你不熟悉 OSM 标记系统,第一次选择合适的标记可能相当困难。每个标记都是一个描述某些点、线性或多边形特征的key=value对。键描述了一个广泛的类别(例如,便利设施),而值提供了详细信息(银行、电影院、咖啡馆、自行车停车区等)。使用帮助键/值按钮可以了解更多关于从 OSM 维基页面wiki.openstreetmap.org/wiki/Mapfeatures的标记信息。
然后,通过位置名称、地图画布或图层设置感兴趣区域的范围。如果图层下拉列表不可用,点击其旁边的
按钮来刷新它。在高级部分,你可以开启/关闭不同的几何类型。默认情况下,所有几何类型都是开启的,因此所有相关的点、线和多边形都将被下载。浏览到你想保存数据的目录。在下面的屏幕截图中,你可以看到使用 QuickOSM 查询下载自行车停车点数据的示例。

小贴士
如果你熟悉Overpass API查询语言,可以点击显示查询或查询选项卡来修改初始查询。
点击运行查询按钮后,包含数据的 shapefile 将被加载到地图画布上。
处理投影
投影定义了地球曲面上现实世界对象如何被展平和投影到类似平面的地图上。不同的数据源通常在不同的投影中创建和分发,这取决于获取技术和应用范围。为了能够在 QGIS 中正确地操作和分析它们,理解它如何解释和管理投影信息非常重要。
QGIS 支持大约 2,700 个 CRS。它们构成一个数据库,每个项目都由一个ESPG 标识符和一个描述行来描述,该描述行遵循PROJ.4投影库的格式。为了存储和读取有关投影的信息,QGIS 使用其自有的格式存储在.qpj文件中。在处理投影时,有两个重要点需要记住:数据源投影和项目投影——它们并不总是相同的。
数据源投影
当你将数据加载到 QGIS 中时,它会尝试自动从随附的投影描述文件中定义投影信息,并将其设置为新添加的图层。你可以在图层属性对话框中检查图层的投影信息。要打开它,在图层面板中双击图层名称,或使用右键上下文快捷方式属性。投影信息显示在常规选项卡的坐标参考系统部分,如下所示:

存在着许多投影描述文件格式,它们大多取决于数据格式和来源。其中最常见的一种是.prj文件。这种文件格式有时以简化的形式提供有关投影的信息,而 QGIS 无法正确定义它。如果缺少或信息不完整,你会看到投影描述缺失或看起来像这样:USER:100000 - * 生成 CRS (+proj=etc.)。这意味着 QGIS 在其数据库中没有找到合适的投影,并将其作为自定义 CRS 添加。如果你确信该投影是标准的,但 QGIS 由于简化的描述而无法正确解释它,请手动指定它。评估坐标参考系统选择器对话框有不同的方法如下:
-
在图层面板中双击图层名称以打开图层属性对话框。在常规选项卡下,点击选择 CRS按钮
从坐标参考系统选择器对话框窗口中选择必要的 CRS。 -
通过转到图层 | 设置图层(s)的 CRS。
-
使用Ctrl + Shift + C键盘快捷键。
-
通过右键单击图层快捷方式 设置图层 CRS。
在 坐标参考系统选择器 对话框中,从列表中选择必要的 CRS 并单击 确定。注意,您可以使用关键字或 EPSG 代码进行过滤,以隐藏不必要的投影。随着时间的推移,常用投影将被添加到最近使用的 CRS 列表中。
注意
如果 QGIS 没有自动为您的数据定义投影,并且您不确定投影名称和 EPSG 代码,请使用 prj2epsg.org/ 网站的 Prj2EPSG 服务。在这个服务中,您只需上传您的 .prj 文件,其中的已知文本投影信息将被转换为标准的 EPSG 代码。
注意,从 属性 对话框手动指定投影是一个临时解决方案;在关闭文件和/或退出 QGIS 后,它不会持续存在。这意味着每次您将此文件加载到 QGIS 中时,您都必须再次指定投影。如果您打算在其他项目中使用该文件,最好通过转到 向量 | 数据管理工具 | 定义当前投影 使用 定义当前投影 工具。在这个对话框中,您可以从 坐标参考系统选择器 对话框中选择预定义的坐标参考系统,或者使用已知 CRS 的 从现有图层导入坐标参考系统。在这两种情况下,现有的 .prj 文件将由 QGIS 用所有必要的参数覆盖,您将不必在下次手动调整投影。

当您从外部源导入文件时,所有这些都是正确的。如果您在 QGIS 中创建一个 shapefile,将同时创建 .prj 和 .qpj 文件,因此您不需要手动定义投影。这些文件的投影将在从 .prj 文件读取的其他 GIS 应用程序中正确解释。
您还可以通过转到 设置 | 选项 | CRS 来保持 QGIS 在加载或创建没有 CRS 信息的新图层时的行为,这里有三种新图层 CRS 的选择:
-
提示 CRS:在这种情况下,您将始终被要求手动指定图层的 CRS。
-
使用项目 CRS:数据将被自动分配给项目设置的 CRS。如果您使用的是同一投影的文件,这是一个方便的选择,但如果它们的投影与指定的不同,您将无法看到它们。
-
使用下面显示的默认 CRS:传统上使用 EPSG:4326 - WGS 84,但您可以指定自己的选择。
与投影一起工作可能会很棘手,除非你认识到指定和定义投影选项之间的区别。这全部关于正确分配投影信息,但当你指定它时,结果在当前工作会话中是临时的。一旦你定义了一个投影,除非重新定义,否则它将变得永久。在这两种情况下,如果你选择了错误的投影,你将无法在地图上看到你的数据(至少在你期望它出现的地方)。通常,首先指定投影是一个好习惯,将你的数据与正确投影的数据集进行比较。如果一切正常,定义它以使投影分配永久化。
项目投影
当你加载 QGIS 时,其地图画布投影默认设置为EPSG:4326 – WGS 84。这种行为由全局默认投影定义,可以通过访问设置 | 选项 | 坐标参考系统 | 始终以此 CRS 开始新项目来更改。
然而,当你开始添加数据时,投影标识符会自动更改为第一个加载层的投影。因此,默认情况下,投影投影是由第一个加载层定义的。数据源投影和投影投影并不总是相同的。如果它们不同,QGIS 可以应用所谓的即时转换。这意味着它会读取数据投影,如果它不同,会自动将其与项目投影对齐,并应用必要的转换。有几种方法可以指定项目的投影并启用即时转换:
-
通过访问项目 | 项目属性 | 坐标参考系统。
-
点击状态栏上的当前 CRS
按钮,并在项目属性 | 坐标参考系统窗口中激活启用'即时'CRS 转换。 -
前往设置 | 选项 | 坐标参考系统 | 新项目的默认 CRS。激活如果图层具有不同的 CRS 则自动启用'即时'重投影或默认启用'即时'重投影。
在最后一种方法中,区别非常微妙,主要在添加第一个图层到项目时才会明显。在自动启用重投影的情况下,默认地图画布 CRS 将被第一个图层投影取代,后续图层也将自动调整到它。在默认重投影的情况下,所有图层都将重新投影到项目的初始 CRS(这通常是默认的全局投影,除非你已更改它)。
启用即时转换后,你将在状态栏上的当前 CRS 附近看到OTF缩写,图标将变为实心。
如果你想要根据图层面板中的特定图层快速更改项目 CRS,请右键单击一个图层并选择从图层设置项目 CRS快捷方式。
将图层加载到空间数据库
现在我们已经将所有可用数据加载到 QGIS 中,让我们将其聚合到一个单一数据库中。QGIS 支持与各种数据库管理系统及其空间扩展(PostgreSQL/PostGIS、Oracle Spatial/GeoRaster、MSSQL Spatial、SQL Anywhere 和 SQLite/SpatiaLite)一起工作。其中,PostGIS 和 SpatiaLite 可能是你已经听说过的。作为常见的空间数据库,它们通常用于不同的目的。PostGIS 是一个企业级解决方案的例子,主要用于服务器上,为多个用户提供空间数据维护和访问。SpatiaLite 是一个轻量级的个人使用文件数据库。使用 SpatiaLite 数据库具有以下优点:
-
所有数据都存储在一个单一、便携的文件中,你不会因为不同文件类型(例如,
.shp,.dbf,.shx,.prj,.qpj等)而感到混乱。 -
Shapefile 的大小限制(最多 2 GB)和字段名称长度(10 个字符)可以忽略。
-
内置的空间索引允许你更快地执行大范围搜索。
-
这是一个真正的单一格式的数据库,允许你使用各种空间函数和基于 SQL 的工作流程。
执行以下步骤将你的数据组装成一个单一的 SpatiaLite 数据库:
-
首先,你需要创建一个空的空间数据库来加载你的数据。你可以从浏览器面板中这样做。右键单击SpatiaLite条目并选择创建数据库快捷方式。指定文件夹和
.sqlite数据库文件名。你将得到数据库已创建的消息。现在你可以展开条目并看到你新创建的空数据库。 -
我们将使用提供与不同数据库交互的单个界面的 DB Manager 核心插件来加载数据。可以通过转到数据库 | DB Manger来访问插件功能。在窗口的左侧,你可以看到一个按类型分组的可用数据库连接的树状列表。一旦创建,你的数据库将自动在SpatiaLite项下可用,你可以通过双击来连接它。当连接建立后,你将在窗口右侧的信息选项卡中看到有关数据库或其选定项的一般信息。要将文件导入数据库,请单击导入图层/文件按钮
,或从表菜单访问它。![将图层加载到空间数据库]()
-
在打开的导入矢量图层窗口中,你应该定义你想要导入的图层。它可以是输入下拉列表中可用的已加载图层之一,或者你可以通过单击浏览按钮...从文件系统中选择图层。然后,定义输出表名称(在我们的例子中,它是
ny_boroughs,与输入相同)。![将图层加载到空间数据库]()
以下选项允许你更精细地控制你的数据:
-
主键:如果没有指定,字段将默认命名为
pk -
几何列:如果没有指定,字段将默认命名为
geom -
源 SRID和目标 SRID:这些是从数据中读取的 CRS EPSG 代码,但如果你没有投影文件,或者你想在将数据加载到数据库之前重新投影它,你可以手动指定它们
-
编码:如果没有指定,数据集字符集默认设置为UTF-8
-
删除现有表:如果你导入一个与先前存在的表具有相同名称的表,它将被新表替换
-
创建单部分几何而不是多部分几何:在将多部分要素加载到数据库之前,将它们分解为单部分几何
-
创建空间索引:将创建一个空间索引,它允许更快的空间搜索和查询性能
-
点击确定并稍等片刻(根据文件大小,此过程可能需要一些时间),你将看到“导入成功”的消息。要探索导入的表,请点击刷新按钮
,你将在数据库项目列表中看到一个几何表。从信息选项卡,你可以查看有关表、几何类型、字段和触发器的信息。表选项卡以表格形式显示数据,而预览选项卡显示空间几何(如果有)。通过右键单击任何元素,你可以删除、重命名或将其添加到地图画布上。所有其他打开的图层都可以以类似的方式加载。

注意
除了核心功能之外,还有一个名为QSpatiaLite的外部插件,专门设计用于支持与 SpatiaLite 数据库一起工作。安装后,当你导航到数据库 | SpatiaLite | QSpatiaLite时,它将可用。
摘要
到目前为止,我们已经介绍了一些入门主题并完成了几个任务。首先,你学习了如何安装 QGIS、配置其界面以及通过插件扩展功能。然后我们讨论了你可以用来将数据导入 QGIS 的常见数据源。你现在能够探索和管理不同投影的数据。最后但同样重要的是,你将所有数据导入了一个便携式、轻量级的 SpatiaLite 数据库文件。
在下一章中,我们将继续前进,揭示 QGIS 在数据可视化方面的潜力。
第二章:可视化与样式化数据
从不同来源收集和组织数据只是故事的一半。下一步是在地图上展示它,准确揭示主题内容和特征。为此,GIS 中使用了各种视觉设计技术,或基于其属性对图层进行样式设计。QGIS 具有极其广泛和灵活的地图可视化和数据样式化能力。
在本章中,我们将讨论以下主题和技能:
-
在单个工作文档(项目)中组织数据的良好实践
-
数据的视觉表示,揭示其主题和空间特征
-
图层标签,这是为了增强数据的可读性
-
对样式进行控制
-
用于提供空间背景和背景数据的底图
本章的主要成果将是一个项目,该项目是根据基本的地图可视化要求设计的。
从空间数据库加载图层
在本章中,我们将使用我们之前创建的数据库。如您所记,这是一个 SpatiaLite 文件数据库。为了使用它,我们首先必须建立连接,然后加载数据。在 QGIS 中,始终有几种不同的方法来完成此操作:
-
从菜单中转到图层 | 添加图层 | 添加 SpatiaLite 图层
-
点击
,添加 SpatiaLite 图层按钮,在图层管理工具栏中 -
使用 Ctrl + Shift + L 键盘快捷键
在打开的窗口中,按照以下步骤定义你想要连接的数据库:
-
如果你已如前一章所述创建数据库,你可能会注意到它已经连接。如果没有,则点击新建按钮并导航到你要工作的
.sqlite文件。 -
在选择数据库文件后,点击连接按钮以查看可用图层的列表。您将看到图层的名称和几何类型。
-
选择必要的图层(或多个图层,这可以通过按住 Ctrl 键来完成)并点击添加按钮。
注意
设置过滤器按钮在添加数据时提供了更多灵活性,因为它提供了访问查询构建器窗口的权限,在那里你可以创建一个条件表达式来定义子数据集,如图所示。例如,如果你想从
运动设施数据集中选择一个多功能运动场(MPPA),你可以执行以下操作:-
在查询构建器窗口的左侧,选择一个名为
primary_sp的必要字段(双击其名称将其添加到提供者特定过滤器表达式文本框中的表达式) -
输入或点击操作按钮(在我们的例子中是等号)
-
通过点击全部按钮加载字段值,然后双击
MPPA值将其添加到表达式 -
在提供者特定的过滤表达式文本框中,您将看到以下行:"
primary_sp= 'MPPA'"
测试查询。如果它返回有意义的结果,请点击确定。返回主窗口后,您将在geom列旁边看到条件。点击添加按钮以加载图层。
![从空间数据库加载图层]()
-
从浏览器面板加载图层甚至更简单。要查看可用的图层,依次展开SpatiaLite和相关数据库项。现在您只需将图层拖放到地图画布上即可。
分组和重新排序图层
默认情况下,图层按字母顺序加载(如果从浏览器面板添加,则相反)。每个新图层都放在上一个图层之上,并覆盖它。默认情况下,所有图层都开启,使用简单的统一符号样式,并随机分配颜色。可以通过简单地拖放它们上下移动图例来更改图层的顺序。此外,强烈建议按逻辑分组和排列图层,因为它简化了导航和理解数据。
要管理和重新排列图层以及保持它们的可见性,请使用图层面板中的图层工具栏,如以下截图所示,其中包含随后描述的按钮(从左到右按出现顺序):

-
添加组:这创建一个空的图层组。
-
管理图层可见性:这允许我们快速显示和隐藏图层,并使用预定义的图层组合——所谓的预设来定制它们的可见性。
-
按地图内容过滤图层图例:如果过滤功能处于激活状态,图层图例仅显示地图画布内实际可见的项目。所有其他符号都将从图例中隐藏。
-
全部展开/全部折叠:按钮用于展开或折叠图层、符号图例和图层组(如果有)。
-
删除图层/组:这删除所选的图例条目。
创建图层组有两种方式:
-
点击
,添加组按钮,从图层工具栏。新组将出现在图层列表的底部。输入一个合适的名称,然后将图层拖放到组中。 -
按住Ctrl键选择多个图层,并使用组选中的右键快捷菜单来将它们放置在单个组中。
通过选择组并应用添加组功能,可以开发出具有子组的分层结构。图层图例中的任何项目,无论是单个图层还是组,都可以使用重命名右键快捷键进行重命名。重命名不会影响数据集本身,但允许我们在项目中为其应用一个适当且具有意义的名称。现在尝试自己将图层安排成几个有意义的组,并适当地命名它们。
开发自己的样式
在 QGIS 中,样式是一种地图可视化方式,它考虑了图层的个别和主题特征。它包括符号学的基本特征,如颜色和填充的存在、轮廓参数、标记的使用、基于比例的渲染、图层透明度、与其他图层的交互以及标签。
一个精心挑选的样式可以极大地简化数据感知和可读性,因此学习如何使用样式来以最佳方式表示你的数据是非常重要的。在本节中,我们将分别讨论矢量图层和栅格图层,因为它们的样式化有一些独特的特点。
为矢量图层开发样式
样式 菜单来自 图层属性 对话框,它为你提供了所有必要的工具来表示和样式化你的数据。要打开它,请双击 图层 面板中的图层名称,或使用 属性 右键菜单的快捷方式,然后选择 样式 部分。你将看到类似以下内容:

你首先应该注意到的就是位于左上角的小型 渲染器 下拉列表。它包含以下项目:
-
单个符号:这是最简单的类型,使用相同的符号绘制所有图层要素。
-
分类:这定义了数据驱动的分类,并允许我们单独表示它们。
-
渐变:这根据定量属性定义分类,允许我们逐步排序要素。
-
基于规则的:这是最灵活和高级的渲染器类型。它允许用户使用多个标准定义自己的分类,并单独样式化。
-
点位移:当你处理包含重叠点且坐标相似或彼此过于接近的点图层时,这种渲染器非常有用。它仅适用于单个点图层,并将自动移动标记的位置,以便所有重叠的标记都可见。
-
反转多边形:这些用于样式化多边形外部的区域,并且仅适用于多边形图层。
-
热力图:这表示一个根据点密度具有连续表面的点图层,仅适用于点图层。
根据所选的渲染器类型,样式 菜单部分会改变其视图,如果你错误地选择了不合适类型(例如,为线图层选择热图渲染器),你将收到相应的消息。
选择渲染器类型后,您可以使用符号选择器对话框开始调整符号,其可访问性取决于所选的渲染器类型。例如,对于单个符号和反转多边形渲染器,此对话框直接从样式部分可用。对于分类和分级渲染器,它可以从符号更改按钮访问,其外观如下:
。
基于规则的、点位移和热力图渲染器在符号选择和调整方面有自己的规范,这些规范将在以下章节中介绍。然而,无论选择哪种渲染器类型(除热力图渲染器外),您始终可以访问符号选择器对话框,其外观类似于以下截图,并包含几个部分:

在窗口的左上角,您可以看到符号预览。在预览下方是符号层。默认情况下,只使用一个层,但您可以使用添加符号层按钮(
)添加更多层,或使用删除符号层按钮(
)删除不必要的层,该按钮仅在有两个或更多层可用时才激活。使用锁定层颜色按钮(
),层的颜色将被锁定以防止更改,这可以防止分类或分级渲染器修改颜色。可以使用向上移动(
)和向下移动(
)按钮重新排序图层,并且如果您对结果满意,可以在符号库中使用保存符号按钮。
在对话框窗口的右侧,有可用的选项用于所选的符号层。其中,符号层类型是最重要的。可用类型的列表取决于图层几何形状。对于多边形图层,您可以从以下列表中选择:
-
质心填充:多边形通过在多边形质心处的标记来表示,而不是渲染多边形的整个区域。如果您有很多小多边形,并且最好通过点来可视化而不是通过在放大后才可见的小多边形,这种方法非常有用。
-
渐变填充:使用预定义的渐变或创建自定义渐变来填充多边形。
-
线图案填充:可以将线图案组合起来创建各种网状效果。当您想要使用相同的填充颜色但想通过网状效果突出显示对象之间的某些差异时,这些效果非常有用。
-
点图案填充:规则分布的点(或其他符号)可以填充多边形并创建图案。
-
栅格图像填充:任何栅格图像都可以用来创建背景填充纹理或图案。
-
SVG 填充:可缩放矢量图形
.svg文件(或标记)可以用来创建填充纹理或图案。 -
形状爆发填充:这根据多边形边缘的距离为多边形内部着色,并创建惊人的边界缓冲效果。
-
简单填充:这是默认类型,其特征是填充颜色、图案和边框。
-
轮廓:标记线条:使用标记符号作为轮廓。
-
轮廓:简单线条:只绘制多边形的轮廓,并定义其属性,如线条颜色、宽度和样式。
对于点层,您可以选择由椭圆、字母或符号(字体标记)、各种标记(简单标记)、图标(SVG 标记)或属性字段值(矢量字段标记)表示的不同标记类型。
对于线层,有简单和标记线条类型可用。在前一种情况下,线条按常规渲染,在后一种情况下,使用定期重复的标记符号。标记线条可以用来显示线条的方向(例如道路上的移动、河流的流向等),使用箭头标记符号。
现在我们已经涵盖了基础知识,我们将密切探讨通过我们数据库中一些层的示例来展示不同的渲染风格。
使用单符号渲染器对层进行样式设计
在本例中,我们将使用Brooklyn borough boundaries层来在地图上勾勒出感兴趣的区域。如图下所示,我们使用两个符号层,两者都定义为轮廓:简单线条,但具有不同的笔样式图案。下面放置一个较浅的实线,并用较深的虚线笔样式覆盖它。选择对比颜色使我们能够实现类似边框的条纹效果。

使用分类渲染器对层进行样式设计
让我们设计public schools层以反映学校类型:
-
在将渲染器类型设置为分类后,选择要在列下渲染的分类列。该列来自包含所有层属性字段的下拉列表。由于我们希望学校类型以分类形式显示,请选择
sch_type字段以对层进行分类:![使用分类渲染器对层进行样式设计]()
-
点击符号更改按钮以调整层符号。在符号选择器窗口中,将符号层类型设置为SVG 标记,并导航到名为
svg的训练数据集目录。选择school.svg文件,并将符号的大小值调整为3毫米。点击确定按钮返回主窗口:![使用分类渲染器对层进行样式设计]()
-
点击分类按钮。带有符号、值和图例列的窗口将自动填充来自属性字段中的类别及其描述。值和图例之间的区别在于,值代表唯一的属性,而图例提供它们的描述性特征。例如,当值是一些代码而图例应该解释其含义时,这种区别更为明显。此外,值在图层图例中是不可见的,但它们的描述是可见的。您可以通过双击相关列中的项目来添加或删除类别,或手动编辑其元素的文本(值或图例)。现在,只需点击确定按钮退出样式对话框,查看初步结果。
-
您会看到地图画布上的符号过于密集且重叠,这使得地图显得杂乱。为了提高可读性,我们应该将符号的外观与缩放范围相关联,并且有两种基本方法可以实现这一点:
-
从属性窗口的常规选项卡中激活缩放相关可见性,在那里您应该输入最小(排除)和最大(包含)缩放值。例如,如果您定义的值,如以下截图所示,则图层将在 1:49,999(因为
50000的最小值被排除)及更大的缩放范围内可见。这种方法不会影响符号的大小。它只调节缩放范围,在地图画布放大和缩小时的外观:![使用分类渲染器设置图层样式]()
-
另一种方法,我们实际上会使用,更为复杂,因为它使符号大小依赖于缩放。要应用它,打开属性窗口中的样式对话框,并点击
,符号更改按钮,以打开符号选择器对话框,如图所示。激活必要的符号层,将其大小单位更改为地图单位,并输入30。这意味着符号大小将被设置为 30 英尺,并根据缩放在放大或缩小地图画布时改变。点击确定按钮返回主窗口。![使用分类渲染器设置图层样式]()
提示
在此情况下,可以通过调整缩放范围按钮(
)定义缩放范围,该按钮会打开一个对话框以定义最小和最大缩放值。
-
-
默认情况下,所有类别都根据所选的 SVG 文件分配了相同的符号标记,但你可以通过双击并调整符号选择器对话框中的必要属性(即填充和边框)来修改它。此外,右键单击任何项目都会弹出一个上下文菜单,包含复制、粘贴、更改颜色、更改透明度、更改输出单位和更改大小快捷方式,以简化一些常见操作。
此截图显示了如果你选择分类渲染器并按之前所述调整设置,屏幕可能看起来像什么:

点击确定按钮后,图层的样式属性将被应用,你可以在地图画布中探索图层的可见性。在地图单位相关符号大小的情形下,当你缩小地图时可能看不到标记,但它们将在更大比例尺上出现,并相应地改变大小。请注意,图层面板上图层的图例中的符号行为类似,即在较大比例尺上变大,在较小比例尺上缩小。这有助于你了解图层在此比例尺上是否可见,如果可见,则有助于你看到其标记的外观。
使用渐变渲染器设置图层样式
当你想根据某些定量属性对要素进行分级时,渐变渲染器类型非常有用。在我们的示例数据集中,我们有zipcodes图层,其中包含population字段中的人口数据。我们将使用这个图层和字段来根据居住人数对 ZIP 代码边界进行排序,并演示渐变渲染的工作原理。
小贴士
而不是选择属性字段,你可以点击它旁边的表达式对话框按钮
。如果你需要使用不在属性表中的某些值,但可以从字段值中导出,这将很有用。例如,你可以使用area/ 43560表达式将平方英尺面积转换为英亩。
-
将渲染器类型设置为渐变,并在列部分选择
population字段。 -
定义你希望显示的类别数量(通常建议五到七个类别,否则可能难以在视觉上区分它们),并选择一个颜色渐变。
小贴士
你可以使用预定义的标准颜色渐变或从高级选项中选择。要使用它们,从下拉列表底部选择新颜色渐变。在颜色渐变类型窗口中,你将获得以下选项:
![使用渐变渲染器设置图层样式]()
-
渐变:这提供了创建和修改自定义渐变的选项。
-
随机:这根据各种可自定义的选项创建随机颜色渐变,例如色调、饱和度、亮度和类别。
-
ColorBrewer:使用为地图设计的预定义调色板,以实现最佳清晰度。这包括针对不同类型数据(顺序、发散和定性)的几个颜色方案。
-
cpt-city:这提供了数十种颜色渐变,用于制图、技术插图和设计。
-
-
然后,选择一个合适的毕业模式,如下所示:
-
等间隔:根据设置的类别数将值范围划分为相等的范围类别(例如,从 0 到 100 的值被划分为每个 20 单位的五个类别)。
-
等量分位数:所有数据将被分成设定的类别数,范围将被选择,使得每个类别包含相同数量的项目。
-
自然断点(Jenks):这种方法根据值的相似性分组。因此,类别内的值具有最小方差,但跨类别的特征值差异显著。
-
标准差:类别根据值的标准差进行划分,这显示了数据与其平均值的不同程度。
-
优雅的断点:这为给定的值范围创建n+1个类别(即,如果设置 5 个类别,则结果将是 6),类似于等间隔,但断点被选择,以便值是漂亮的整数(例如,如果使用整数,则为 10 的倍数)。
-
在您点击分类按钮后,符号、值和图例列将被填充。双击任何一项以修改它。右键单击将打开上下文菜单。在决定哪种方式最适合揭示您数据的特点之前,强烈建议您尝试各种类别和分类模式。

使用基于规则的渲染器样式化图层
基于规则的渲染器是最灵活的渲染器,因为它允许您将数据分成您自己的复杂类别,并分别对其进行样式化。我们将通过具有许多可用于可视化的属性的bike routes图层示例来探索基于规则的渲染功能。例如,有两个字段特别适合在地图上可视化。第一个是allclasses,它包含基于纽约市自行车总体规划分类的路由类型分类(针对现有自行车设施)。类型如下:
-
I:绿道/多用途路径。
-
II:街道上标有条纹的自行车道。
-
III:街道上标有标志的自行车路线。
-
0:计划中,但尚未作为自行车路线存在。
-
L:链接。目前没有设施,但建议该元素作为自行车网络部分之间的连接。
-
S:楼梯和人行天桥。
第二个字段是lanecount,它显示车道数。需要使用规则将这些属性组合成单独的类别,这些类别显示路线类型和车道数。按照以下步骤为图层开发基于规则的符号:
-
导航到属性 | 样式,并从下拉列表中选择基于规则的渲染器类型。要创建规则,请单击添加规则
按钮。将打开规则属性对话框窗口。 -
在窗口中,单击过滤器行旁边的...按钮。将打开表达式字符串构建器窗口。此窗口由三个部分组成:
-
左侧部分是表达式,其上方有一行运算符按钮。您可以直接手动输入表达式,或双击字段名称、值和函数来组合它。
-
窗口的中心部分是函数。要展开任何项目,请单击其旁边的+符号,并双击将其添加到表达式中。我们主要对包含所有可用属性字段名称的字段和值项目感兴趣。当您突出显示其中任何一个并单击加载值按钮(全部唯一或10 个样本)时,将返回值列表。同样,您可以在表达式中手动输入值或通过双击将其添加。
-
如果您迷路了,请查看窗口的右侧部分。它包含对函数中突出显示的项目的内容帮助。
在我们的表达式中,我们希望显示属于I类别的绿道和多用途路径。此表达式的
"allclasses" = 'I'如下截图所示:![使用基于规则的渲染器样式化图层]()
-
-
点击确定按钮后,您将再次进入规则属性窗口。首先,测试表达式的一致性。您将收到消息过滤器返回了'一些数字'个要素。如果要素数量为
0,则表示没有要素满足规则。否则,您将得到一个正数,表示类中的要素数量。 -
然后向类中添加标签和,如果需要,描述。如果比例范围切换按钮被激活,您可以定义最大-最小比例范围以在地图上可视化该类。类符号在窗口的符号部分开发,如下所示:
![使用基于规则的渲染器样式化图层]()
点击确定按钮后,您将返回到主样式窗口,在这里可以通过添加规则
、编辑 规则
或删除规则
按钮来管理规则。继续添加此图层中其他可用类的类别。
使用细化当前规则按钮,你可以进一步根据比例、类别或范围开发多级层次结构。例如,我们可以将allclasses作为主要分类属性,然后根据车道数量将其划分为子类别:
-
选择类别,导航到细化当前规则 | 向规则添加类别,并从列下拉列表中选择lanecount字段。点击分类按钮:
![使用基于规则的渲染器设置图层样式]()
类似地,向其他规则添加子类别。
-
现在,我们应该检查我们的规则以删除空类别。通过按住Ctrl键选择所有可用的类别,然后点击计数要素按钮。空类别将通过0计数被识别。点击移除规则按钮
以将其排除在图例之外。 -
因此,你的基于规则的样式可能看起来像这样:
![使用基于规则的渲染器设置图层样式]()
-
你可以通过点击渲染顺序按钮并调整符号级别来大大提高多级符号的可视化。在打开的符号级别对话框中,你可以定义符号层渲染的顺序。单元格中的数字决定了层将在哪个渲染过程中绘制。其理念是某些符号级别应该具有较低的渲染顺序,而其他符号级别应该具有较高的渲染顺序。低级别将被高级别覆盖,使用户能够创建平滑的结合并保留符号层次结构。按照以下截图设置渲染顺序并探索结果:
![使用基于规则的渲染器设置图层样式]()
使用点位移渲染器设置图层样式
一些点图层(例如,来自训练数据集的wifi public图层)包含具有相同或相似坐标的点,由于它们重叠,在地图上无法区分。在这种情况下,点位移渲染器非常有用,因为它在想象中的圆圈内定位重叠点。它将点移动到很小的距离,这样它们都能被看到。请注意,渲染器不会影响数据集中实际点的位置,但会从视觉上改变放置以满足制图要求。要使用此类渲染,图层应是一个单点要素类型。
要将点位移渲染器应用于wifi public图层,请按照以下步骤操作:
-
选择点将围绕其位移的中心符号标记。通过点击符号按钮,您将获得访问传统的符号选择器对话框。在窗口中,将符号图层类型设置为SVG 标记,导航到名为
svg的训练数据集目录,并选择Wi-Fi-Logo.svg文件。将其大小设置为20,并选择地图单位作为尺寸测量单位。点击确定按钮后,您将返回主窗口。 -
前往渲染器 | 单个符号以设置点本身。点击下方的渲染设置按钮后,您将进入符号选择器对话框。再次,将符号图层类型设置为SVG 标记,导航到名为
svg的训练数据集目录,并选择wi-fi.svg文件。将其大小设置为30,并选择地图单位作为尺寸测量单位。点击确定后,您将返回主窗口。 -
渲染圆圈部分定义了出现在地图上以分组具有相似坐标的点并围绕共同中心进行分组的圆圈属性。以下属性包括:
-
圆圈笔宽:这定义了边界圆的轮廓宽度
-
圆圈颜色:这定义了边界圆的轮廓颜色
-
圆半径修改:此值越大,圆圈就越大
-
点距离容差:此值越大,围绕共同中心需要捕捉的点就越多
目前,我们接受默认值并应用设置。在下面的屏幕截图中,您可以看到在多个坐标相似且需要围绕一个共同中心进行分组的情况下,结果可能看起来像什么:
![使用点位移渲染器设置图层样式]()
-
标签部分包含一些主要的标签设置,例如,标签属性、字体、颜色等。我们暂时省略这部分,因为标签设置将在本章的添加标签部分进行介绍。
使用反转多边形渲染器设置图层样式
反转多边形渲染器在多边形边界外进行样式设置,并允许我们实现显著的制图效果。其常见用途之一是在地图上显示具有“渐变模糊”效果的水体。为此,使用鼠标右键的上下文快捷方式复制NY borough boundaries图层,右键点击重命名它为water area,打开样式属性对话框,并选择反转多边形渲染器。
现在,创建一个由两层组成的复杂符号:
-
第一个符号图层类型设置为轮廓:简单线。
-
第二个是形状爆发填充。
-
在渐变颜色部分,我们选择从蓝色到白色的双色渐变。
-
在阴影样式中,激活阴影到设定距离:。此值越大,阴影效果就越大。
-
最后,将模糊强度滑块调整到
10的值以使模糊更柔和。点击确定按钮并享受结果!
![使用反转多边形渲染器样式化图层]()
-
使用热力图渲染器样式化图层
热力图是一种相对较新的渲染类型。它在 QGIS 2.8 版本中引入。它将点表示为连续密度表面,并允许我们应用酷炫的样式效果。请注意,为了能够应用此类型的渲染器,图层和地图画布应处于相同的坐标参考系中。
我们将渲染器应用于包含超过 15000 个点的trees图层。由于它们的密度很高,因此单独在地图上显示这些点很困难:
-
从下拉列表中选择热力图渲染类型后,选择名为绿色的预定义颜色渐变。如果您对颜色渐变不满意,可以点击它旁边的编辑按钮进行修改,或者从列表末尾选择新建颜色渐变来创建自己的颜色渐变,如果需要的话,最后还可以反转颜色渐变。
-
半径字段决定了密度估计的搜索区域。它基本上表示点之间必须有多近才能影响热力图。半径越大,表面越平滑;半径越小,热力图中的细节越精细。您可以使用不同的单位定义点的半径:像素、毫米或地图单位。请记住,地图单位是依赖于比例的。像素和毫米不受比例影响,但会反映缩放效果。
-
最大值通常自动设置,并负责每个面积单位内点的最大密度,但您可以调整它以满足您的需求。
-
此外,如果您希望图层除了密度之外还反映一些重要信息,您可以使用按数值字段加权重。例如,如果我们有相关数据,我们可以按学生人数衡量学校,或按每月访客数衡量咖啡馆。
-
渲染质量滑块用于调整表面的平滑度。您选择的质量越高,渲染过程越慢,而较粗糙的表面渲染得更快。
图层渲染
无论您选择哪种渲染类型,在样式对话框窗口的底部都始终有相同的图层渲染选项。第一个是一个通用的图层透明度百分比滑块。您可以移动它来调整图层透明度。图层混合模式为与底层(或多个底层)交互的图层提供一些特殊的图形效果。默认情况下,设置为正常模式,这意味着底层被隐藏在覆盖层下面,颜色没有混合。这表示为(a, b) = a,其中a是顶层,b是底层。

正常混合模式应用于重叠层的示例
您可以从以下表格中描述的四个组中选择 12 种不同的混合模式:
| 混合模式 | 公式和描述 | 效果示例 |
|---|---|---|
| 亮化模式——这一组混合模式使黑色消失,保留白色,并使中间调变亮。 | ||
| Lighten | max (a, b)选择来自两层的 RGB 组件的最大值。 | ![]() |
| Screen | 1-(1-a)×(1-b)首先,反转两层中的 RGB 组件。然后它们相乘,最终结果再次反转。 | ![]() |
| Dodge | b÷(1-a)底层被反转顶层除以。 | ![]() |
| Addition | a+b这总结了两个图层上的组件。 | ![]() |
| 暗化模式:此组与上一个相反,意味着它保留黑色,使白色消失,并使中间调变暗。 | ||
| Darken | min (a, b)选择来自两层的 RGB 组件的最小值。 | ![]() |
| Multiply | a × b图层相乘。 | ![]() |
| Burn | 1 - (1-b)÷a底层被反转并除以顶层,然后结果再次反转。 | ![]() |
| 对比模式:这些模式丢弃中间调,并将顶层中的暗部和亮部像素分别应用于底层像素以变暗或变亮。 | ||
| Overlay | 根据不同像素结合两种混合模式。对于较亮的像素,应用半强度的 Screen 模式,而对于较暗的像素,则应用 Multiply 模式。结果,灰色中间调变得不可见。计算基于底层,这意味着顶层像素被底层亮化或暗化。 | ![]() |
| 软光 | 这与上一个相同,但使用 Dodge 和 Burn 模式分别用于亮化和暗化,而不是 Screen 和 Multiply 模式。 | ![]() |
| Hard light | 这与 Overlay 类似,但顶层和底层被交换。 | ![]() |
| 反转和消除模式:应用简单的算术操作来反转颜色并抑制黑色 | ||
| 差值 | b-a这从顶层减去底层的像素值,仅保留正值;也就是说,与黑色(0)混合没有变化,而与白色(1)混合则反转颜色。 | ![]() |
| Subtract | b-a这与差值模式类似,但用黑色替换负值。 | ![]() |
要素混合模式将对图层内重叠的要素应用相同的效果。我们建议您尝试不同的模式,以了解它们如何与不同的数据类型和样式选项一起工作。熟悉它们可以让您创建看起来专业的地图,具有惊人的制图设计效果。

上述截图是飓风疏散区域图层与底层主要住宅分区图层通过简单的 50%透明度(左侧)结合的示例,与右侧不使用任何透明度的乘法混合模式相比。

在上述截图中,噪声点图层具有简单的标记填充不透明度设置为 20%;图层混合模式是硬光,要素混合模式是** dodge**。
开发栅格图层样式
我们的数据库包含三个栅格图层:2010 年土地覆盖、海拔高度,英尺和阴影图。所有这些都是遥感派生数据,对于表示土地利用和地形特征非常有用。我们将为它们开发样式,以将 DEM 表示为连续图层,并将其与阴影图结合以获得一些半 3D 的制图效果。2010 年土地覆盖图层将用于展示如何处理离散类别集。
首先,让我们为包含几个土地覆盖类别的2010 年土地覆盖图层进行样式设计。这些类别由元数据中描述的整数值编码,如下所示:
-
1:树冠 -
2:草地/灌木 -
3:裸地 -
4:水域 -
5:建筑物 -
6:道路 -
7:其他铺砌表面
让我们通过以下步骤来开发样式:
-
从属性对话框窗口打开样式选项卡(在图例中双击图层,或选择右键上下文快捷方式的属性)。
-
将渲染类型设置为单波段伪彩色。由于我们的栅格只有一个波段,它将自动加载为波段 1(灰色)在波段下拉列表中。
-
由于我们处理的是离散的土地覆盖类别,我们转到颜色插值 | 离散。
-
现在我们需要将我们的类别添加到图例窗口中。使用手动添加值按钮,
,来添加类别。 -
默认情况下,所有类别都分配了值为
0,相同的颜色,以及自定义颜色图条目而不是标签。您可以通过双击相应的项来更改它们。完成操作后,您的样式部分将类似于以下截图所示:![为栅格图层开发样式]()
-
对于
海拔高度,英尺图层,在样式部分,选择渲染类型为单波段伪彩色。 -
波段将自动设置,在 DEM 中值变化平滑的情况下,保持默认的线性选项(在颜色插值下)不变。
-
现在,我们需要为图层的主题内容选择一个合适的颜色坡道。预定义的坡道下拉列表不会显示所有可用的多样性。要获取这些,请选择新颜色坡道。从颜色坡道类型窗口下拉列表中选择
cpt-city。您将看到所有可用的预定义颜色坡道,按几个主题组排序。 -
点击地形组,选择高程坡道(或您喜欢的任何其他坡道),然后点击确定按钮。
-
我们将被要求为新颜色坡道输入一个名称。由于我们对现有的坡道满意,所以点击确定。然后,我们将返回到主样式窗口。
-
导航到模式 | 连续,点击分类按钮后,QGIS 将创建类别。这些类别将被创建的最小/最大值范围在加载最小/最大值部分定义,如下面的截图所示:
-
累积计数切割:默认情况下,这设置为数据范围的 2-98%,有助于切割非常低或非常高的数据异常值。选择这种类型的数据范围设置,初始图像对比度更高,更好地反映了数据值之间的差异。
-
最小/最大值:考虑整个数据范围,但生成的地图可能看起来比较单调。
-
平均值 ± 标准差 ×:在给定标准差(或偏差)内的值定义了数据范围。
![为栅格图层开发样式]()
-
要根据指定的数据范围模式加载值,请在精度部分选项中选择实际(较慢),然后点击加载按钮。根据数据集的不同,可能需要一些时间,当您看到颜色坡道下方和模式旁边的最小和最大值更新后,点击分类按钮。在左侧的窗口中,您将看到在定义的数据范围内自动设置的类别及其范围。这取决于选择的颜色坡道。重要的是要理解每个值代表类别的最大限制,而最高值不是数据集的真实最大值,而是累积最大计数。您可以通过双击它们并输入整数值来调整值,并通过输入范围而不是单个值来澄清图例。查看前面的截图以了解这些说明。
最后,让我们为hillshade栅格图层着色,以揭示地形细节和粗糙度。在开始之前,请确保图层位于height a.s.l., ft之上,如果不是,请将其拖动并正确放置。阴影模拟阳光照射地形的方式。将其与 DEM 结合是地图可视化中实现半 3D 效果和突出地形细节的非常流行的方法。传统上,半透明阴影叠加在地形图层之上以实现这一点。因此,最终的地面可视化失去了颜色对比度,变得暗淡。为了克服这一点,我们首先将全局透明度滑块移动到图层属性下的透明度部分的 50%,然后在样式部分,从混合模式下拉列表中选择乘法。如果您不确定确切发生了什么,请尝试使用应用应用正常混合模式,然后返回乘法。以下截图显示了差异:

上一张截图显示了使用简单 50%透明度(上方)和 50%透明度的乘法图层混合模式(下方)结合阴影和 DEM 图层。
添加标签
标签是地图可视化的重要部分。它显著提高了数据的可读性和理解性。请注意,标签仅适用于矢量图层,因为它们包含要在地图上显示的地标和属性(通常是名称)。您可以从“图层属性”对话框或通过转到图层 | 标签菜单访问标签部分。此外,还有一个标签工具栏,您可以通过右键单击工具栏面板的上下文菜单来打开或关闭它,以便快速访问标签选项。
如果您想快速为图层添加标签,只需打开使用以下选项标记此图层选项,从旁边的下拉列表中选择用于标签的属性字段,然后单击确定。标签将立即添加到图层。虽然这对于个人和临时使用来说效果很好,但还有许多更多标签属性的可用的标签选项:
-
文本:这定义了文本样式的主体属性,如字体、大小、颜色、字体样式等
-
格式化:这用于组织和格式化标签为多行
-
缓冲:文本缓冲定义了缓冲晕环的属性,如大小、颜色、透明度等
-
背景:它们包含标签的背景选项,如形状、大小、背景颜色等
-
阴影:这些是标签和背景的阴影选项
-
位置:这些是用于排列标签并避免重叠的高级位置选项
-
渲染:这些是用于快速和清晰渲染标签和特征的选项
现在,我们将通过一些使用高级标签选项的图层标签示例。
标注点层
在这个例子中,我们将使用站名和线路 ID 对subway stations点层进行标注。这意味着在一个标签中,我们需要结合来自不同字段的信息,为此,我们将使用"name" || '\n' || "line"表达式。
注意
表达式让你可以更高级地控制标签选项,因为有了它们,你可以结合多个字段、文本和函数以达到最佳效果。构成表达式的规则非常简单:字段名用双引号书写,文本字符串用单引号。要将它们合并成一个单独的表达式,我们使用||连接符号,并且使用\n来开始新的一行。
-
从字体下拉列表中,选择例如OpenSans(或另一个所需的字体)并将它的大小值最大化到 9 点。
-
在格式化部分,我们只设置对齐为居中。
-
在缓冲部分,激活绘制文本缓冲。将缓冲大小设置为
1毫米,并将笔连接样式设置为圆角。 -
不要忘记选择缓冲的颜色。此外,如果你想达到更时尚的效果,可以调整透明度滑块和混合模式。我们不会使用任何背景选项,所以在这个例子中,这一部分被省略,我们将直接进入阴影。
-
激活绘制投影阴影切换按钮。从绘制于下拉列表中,选择最低标签组件。
小贴士
如果你想在不离开对话框窗口的情况下查看结果,请不时点击应用按钮。
-
在偏移部分,你可以定义投影角度。该值可以手动输入或在旁边的旋转开关中用鼠标箭头调整。
-
注意,阴影轮廓取决于标签旋转角度。如果你想忽略它,应激活使用全局阴影切换按钮。
-
最大化模糊半径值可以使阴影变柔和,并且你可以使用透明度、颜色和混合模式来达到更复杂的效果。
-
通过最小化或最大化缩放值,可以使阴影更加微妙或明显。
-
在位置部分,激活从点偏移模式,你将看到放置象限。点击最低中央象限按钮以将标签居中放置在符号标记下方。如果标签复杂,如我们的案例,它可能会部分重叠符号。为了避免重叠,使用X,Y 偏移,这是标签水平位移和垂直位移的值。输入一个小的正Y值(例如,
3.0)以将标签稍微向下移动。 -
最后,在渲染部分,激活基于缩放的可见性并在分母中输入
10000以设置最大可能的缩放比例。这意味着我们的标签仅在 1:1 到 1:10000 的缩放范围内可见。如果您想防止 QGIS 隐藏重叠的标签,请激活显示此图层的所有标签(包括碰撞标签)。一些标签可能会旋转以获得更好的放置,甚至地图画布也可以旋转。然后,您可以使用显示倒置标签来决定是否允许倒置标签旋转。
如果图层包含大量特征,可以使用数字来限制要标记的特征数量。您还可以使用阻止标签覆盖特征。结果,您的地图看起来会更整洁。根据您选择的标记选项,您的标记图层可能看起来类似于以下截图:

标记线层
标记线层的流程与之前描述的类似,但在放置部分,您可以找到一些特定于线条的选项。最重要的选项如下:
-
平行: 标签沿着与标记线条主要方向平行的方向进行调整。这种放置方式适合传达线条曲率,但可能会错过一些小细节。
-
弯曲: 标签将被弯曲以反映原始线条的曲率。这对于标记具有复杂几何形状的对象,如河流和路径,是最好的选择。
-
水平: 不论线条方向如何,标签总是水平放置。
标签可以分别放置在线的上方、上方或下方。在线放置的情况下,线条将被标签部分覆盖。如果您同时选择多个选项,QGIS 将定义最佳位置,甚至当激活线条方向依赖位置时,还会考虑线条方向。距离选项定义标签将放置在离线条多远的位置(仅对上方/在线位置有效)。弯曲字符之间的最大角度定义您可以弯曲标签多远。在渲染部分,主要针对线条的选项位于要素选项中。例如,您可以使用合并连接的线条以避免重复标签,这对于处理道路网络非常有用。使用抑制小于以下大小的标记要素,您可以设置在标记过程中忽略小特征的值。
标记多边形图层
在本节中,我们将向zipocodes图层添加标签:
-
激活标记并选择
zipcode字段以添加标签。 -
在文本部分,将字体设置为Harlow Solid Italic(或您喜欢的任何其他字体)并在大小下输入
10。标签非常简单,因此我们不会使用任何格式化,而是使用背景而不是缓冲区。 -
激活绘制背景切换按钮。
-
在形状下拉列表中,有几种选项可用于定义背景的形状。您可以从简单的几何形状(矩形、正方形、椭圆等)或更复杂的 SVG 形状中选择。选择SVG,导航到训练
dataset/svg文件夹,并选择plate.svg。将其类型设置为缓冲区并将大小调整为1毫米。此外,如果 SVG 参数可修改,您可以选择填充、边框颜色和边框宽度。
在放置部分,您将看到一些特定于多边形的选项,如下所示:
-
从质心偏移:标签将被放置在选定的象限中心的多边形内,如果有任何偏移,则指定偏移量。您还可以指定确切使用哪个质心,可见或整个。如果您选择可见的多边形质心,那么在缩放和平移地图时,标签的可见性和放置将动态改变。如果您选择整个多边形质心,则标签将是静态的。此外,如果您激活强制点在多边形内,则标签将倾向于仅保持在多边形内。
-
围绕质心:标签将被放置在多边形中心,距离指定。
-
使用周长:标签将被放置在边界线上(提供上方/ 在上方/ 在下方放置选项,并且可以组合它们以允许 QGIS 定义最佳位置)。如果您想考虑线条方向,请激活线方向依赖位置。距离值定义了标签将放置在离线条多远的位置,而重复值则改变重复频率。这种类型的标注对于边界来说非常有用。
-
水平(慢速):所有标签都将水平放置,并且会随着缩放和平移动态改变位置以保持在多边形内。由于 QGIS 不断定义最佳位置,因此对于大数据集,这种类型的标注可能会较慢。
-
自由(慢速):QGIS 将在当前地图视图中定义标签的最佳位置(包括旋转)。
尝试不同的选项以更好地理解标签放置。渲染部分与线图层相同,因此您可以避免标注一些小特征或限制它们的数量。
高级标注
在任何标注选项旁边,您都可以看到数据定义覆盖按钮
。它提供了对标注参数的高级控制。您可以使用表达式或使用专门创建的属性字段来执行此操作,该字段使用自定义参数覆盖定义的设置。数据定义属性在您想区分具有不同属性的对象的标签(例如,具有不同人口的城市和城镇)或应用自己的放置位置时非常有用。
让我们根据人口数量创建三种类型的zipcode标签。较小的标签将用于人口少于 40000 的地区,中等大小的标签将用于 40000-80000 的人口,最大的标签将用于人口超过 80000 的地区。
这意味着我们需要根据population字段值调整字体的大小。从数据定义覆盖上下文菜单中选择编辑…,如下所示:

在表达式字符串构建器中,输入以下截图所示的表达式。在这个表达式中,我们使用人口作为字体大小值定义的条件:

但如果我们不仅想要改变大小,还想在具有最大值的标签下划线,那么我们选择数据覆盖上下文菜单中的下划线按钮的编辑,并输入以下表达式:case when "population" > 80000 then 1 else 0 end。
小贴士
如果您对参数定义中确切要输入哪些值以及如何组合它们以获得有意义的结果感到困惑,请从数据定义覆盖中选择描述项。将显示一个窗口,其中包含对预期输入的简要说明。例如,从以下截图,显示了颜色输入的解释,我们可以得出结论,如果我们想根据人口数量更改标签颜色,我们可以使用case when "population" > 80000 then '255,0,0,0' else '25,81,119,0' end:

管理样式
如您从上一节中看到的,开发样式是一个耗时的工作。但好消息是,一旦开发出来,样式就不会丢失。它们可以被保存,应用到其他图层,并从外部源导入和导出。
主要样式管理选项可通过属性下的样式部分底部行的样式按钮获得,如图所示。菜单分为由水平线分隔的几个部分。第一个部分负责加载和保存样式。第二和第三部分用于管理图层的多个样式,底部是切换不同样式的按钮(默认情况下为非活动状态,灰色,当只有一个样式可用时)。

小贴士
您可以通过在图层的样式上下文快捷方式上右键单击来访问一些这些选项。例如,您可以从一个图层复制并粘贴样式到另一个图层,添加新样式或重命名现有样式。此外,这对于在多个图层样式之间快速切换也非常方便。
当您完成样式的润色后,保存它是明智的。从保存样式菜单的样式按钮有三个主要选项来完成此操作:
-
QGIS 图层样式文件:样式保存为
.qml文件,这是存储样式的 QGIS 原生格式。 -
SLD 文件:样式导出为样式层描述符(
.sld)文件。此文件类型将原始符号转换为单符号或基于规则的类型。这意味着分类、渐变、热图和其他类型的符号可能无法正确支持。基于渲染器的符号可能无法正确支持。如果你计划在外部应用程序(如 GeoServer)中处理它,保存符号在.sld文件中可能很方便。 -
保存在数据库中:我们使用此选项将所有数据和样式存储和分发在单个 SpatiaLite 数据库中。当加载样式时,提供有意义的名称和详尽的描述非常重要。这非常方便,因为如果你想让其他人正确地使用你的数据和样式,他们只需连接到数据库,加载空间层和样式,并应用它们。
保存样式后,你可以使用从文件加载(样式 | 加载样式 | 从文件)或从数据库加载来选择并应用样式。
注意
QGIS 社区在开发资源方面非常活跃,并乐于分享,因此,你不必花费大量时间开发自己的样式,可以直接应用由不同用户提供的现成样式。我们建议你查看以下内容:
-
Charley Glynn 的 OSM 形状文件 QGIS 样式表,可在
github.com/charleyglynn/OSM-Shapefile-QGIS-stylesheets找到 -
3liz 为 QGIS 中的 OpenStreetMap 数据提供的样式,请访问
github.com/3liz/osm-in-qgis -
Anita Graser 为 SpatiaLite 数据库提供的样式,请访问
github.com/anitagraser/QGIS-resources/tree/master/qgis2/osm_spatialite -
Ross McDonald 为 QGIS 中的 OSM 形状文件提供的灰度样式,请访问
github.com/mixedbredie/OSM-Shapefile-QGIS-stylesheets/tree/master/QML%20files/greyscale
你可以从那里下载可用的 .qml 文件并将其应用到你的层上,但重要的是你的层属性必须与已用样式中的属性相同。否则,你可以将这些样式作为基本模板,并手动调整字段名称和值。
为同一层使用多个样式
你也可以通过层上下文样式的右键快捷方式快速访问一些样式属性,如下所示:

例如,你可以轻松地将一个样式从一个层复制并粘贴到另一个层。此外,你可以为单个层应用多个样式,并在必要时在它们之间切换。要向层添加更多样式,请按照以下步骤操作:
-
点击样式下的添加层的右键快捷方式。
-
在新样式窗口中,输入新样式的名称,然后点击确定,如图所示
![为同一图层使用多个样式]()
-
图层的外观将不会改变,因为它目前依赖于最后应用的风格。打开图层的属性对话框,并按如下方式调整新样式:
-
您可以在样式部分以常见的方式开发新的样式,如在前面的开发您自己的样式部分所述。
-
此外,您还可以通过访问样式 | 加载样式来上传一个已准备好的样式。
-
-
在完成样式设置后,点击确定按钮。您将看到两种样式都可用,无论是从样式按钮菜单还是从样式右键快捷菜单。
-
您可以开发尽可能多的样式,并使用它们名称旁边的切换按钮在样式之间切换。此外,您还可以使用添加、移除当前和重命名当前快捷键来管理多个样式。
添加基础地图
基础地图是现成的背景地图,提供除您数据之外的环境和空间信息。它们可以是卫星图像、来自各种来源的通用地图,甚至是自行准备的定制地图。在本节中,我们将探讨最流行的背景地图类型以及如何将它们加载到 QGIS 中与您的数据结合使用。
OpenLayers 插件
这是最受欢迎的 QGIS 插件之一,因为它允许简单地添加来自众多流行地图提供商(OpenStreetMap、Google Maps、Bing Maps 等)的基础地图。按照第一章中描述的步骤安装插件,处理您的数据,并确保安装后它是激活的。
加载基础地图很简单;转到网络 | OpenLayers,选择提供商,然后点击您想要添加的地图。地图将被加载到地图画布中,并出现在图层面板中。默认情况下,图层被添加到第一个图层组,但您可以拖放它们到您想要的位置。您可以通过其名称旁边的切换按钮显示或隐藏图层,并使用移除右键快捷菜单从项目中删除图层。
您可以通过激活菜单中的OpenLayers 概览面板来获得对图层和导航的扩展控制。面板将出现在图层面板的左下角。

激活启用地图切换按钮,并从下拉列表中选择一个用于概述的地图。您可以在概述窗口和地图画布窗口中使用两个不同的地图进行比较。如果您想将地图加载到画布中,请点击下拉列表旁边的添加地图按钮。为了简化导航,主地图窗口中有一个红色十字,它标记了概述范围的中心。您可以通过点击相应的切换按钮来隐藏它。此外,概述地图可以保存为.jpeg图像,或者可以将矩形范围复制到剪贴板作为 KML。
OpenLayers插件非常实用,因为它提供了大量的地图和简洁性,但在使用它时,您应该注意一些限制。首先,此插件旨在提供基础地图,在用它执行其他任务之前,强烈建议您研究提供商的许可条款。其次,请注意,从插件列表中添加任何图层都会自动将原始地图投影更改为EPSG: 3857 WGS 84 /伪墨卡托。
这是因为插件获取的是原始以 EPSG: 3857 提供的 EPSG: 3857 数据,而不是重新投影,它抑制了地图投影并自动重新投影用户的数据。最后但同样重要的是,使用 OpenLayers 插件时,您不能依赖于比例尺和地图测量。这是因为它使用的 EPSG: 3857 WGS 84 /伪墨卡托投影是为了将整个地球以适合在 Web 地图上显示的方式拟合,而不是最小化对象扭曲(形状、面积、距离等)。在这个投影中进行的所有测量都是在球体上进行的,并且很可能会比预期的要大得多。简而言之,这种投影适合视觉探索但不适合测量。为了克服这些限制,您可以使用其他方法。
添加 WMS/WMTS 图层
Web 地图服务 / Web 地图瓦片服务(WMS/WMTS)是一种流行的用于空间信息传输的 Web 协议。要将 WMS/WMTS 基本图层添加到您的地图中,请执行以下步骤:
-
从网络服务加载数据,请转到图层 | 添加图层 | 添加 WMS/WMTS,使用管理图层工具栏中的相应按钮,或者使用Ctrl + Shift + W键盘快捷键。
-
在从 WM(T)S 服务器添加图层窗口中,点击新建按钮以配置新的连接参数。
-
在创建新的 WMS 连接中,输入连接详细信息。输入连接的名称和URL以及任何认证参数。填写这些详细信息后,点击确定。新创建的连接将显示在图层选项卡下的下拉列表中。
-
点击连接按钮以获取有关可用图层的信息,选择您想要使用的图层,点击添加,然后点击关闭以离开窗口。
在使用 WMS 层的情况下,数据将自动重新投影。此外,您将能够访问层的属性对话框和样式参数,如透明度、混合和颜色模式等可修改的参数。当然,这些图层可用于创建高分辨率打印地图。
添加 TMS 图层
瓦片地图服务(TMS)是通过互联网以地理参考图像(瓦片)的形式提供空间数据的另一种方式。要将 TMS 数据加载到 QGIS 中,按照第一章中描述的步骤安装并激活TileMapScale插件,即处理您的数据。安装后,该插件在插件下的TileMapScale菜单中可用。插件面板由两个标签页组成。在第一个标签页工具中,您可以看到一个包含可用 TMS 数据集的下拉列表。使用激活缩放级别切换按钮,缩放将自动设置为适合瓦片的缩放级别。在选项标签页下,如果您想将瓦层调整到地图投影,可以激活使用'即时'转换。设置最小/最大缩放级别并点击DPI按钮以直接设置分辨率。
注意
该插件将数据集描述存储在UserName\ .qgis2\ python\ plugins\ TileMapScaleLevels\ datasets文件夹中,以.xml文件的形式。这些文件使用 GDAL TMS 最小驱动程序格式来描述数据源参数。您可以在www.gdal.org/frmt_wms.html了解更多相关信息。通过使用原始插件安装提供的示例以及研究文档,您可以为您自己的数据提供者创建.xml文件。
除了这个插件,您还可以使用瓦片层和QuickMapServices插件来处理 TMS。
摘要
现在您已经了解了组织并样式化您数据所需的所有必要信息。您还能够添加信息标签,保存您的样式以供将来使用和分享,并使用来自各种来源的基础地图提供一些空间背景上下文。
下一步是准备您的地图以供打印。
第三章。在打印地图上展示数据
打印地图是分享您空间信息的一个很好的工具,因为它们可以作为高质量的图形包含在演示文稿、出版物和报告中,或者以传统方式打印。QGIS 具有创建单页或多页(所谓的大地志)地图的强大功能,您可以将其导出为多种易于分发和打印的图形格式(例如,.pdf、.png、.svg 等)。
在本章中,您将接触到 QGIS 创建打印地图的主要工具,称为打印作曲,并学习如何使用它以获得出色的结果。
打印作曲
使用打印作曲,地图设计变得简单直观,因为它允许您设置布局并添加地图及其必要的元素,例如文本标签、图例、比例尺和指向北方的箭头。此外,您可以通过结合多个概述、图像、绘图和 HTML 标签来显著增强您的地图。为了简化地图生成并节省您的宝贵时间,您可以使用地图模板和大地志生成器功能。
要进入打印作曲模式,请从菜单中选择项目 | 新建打印作曲,点击文件工具栏上的
按钮,或者直接使用Ctrl + P键盘快捷键。在作曲标题对话框窗口中,您将被要求为您的地图提供一个标题。点击确定按钮,标题将自动生成(例如作曲 1、作曲 2、作曲 3等;如果您想的话,稍后可以重命名它们)。
在打印作曲窗口的上行中,有下拉菜单,提供访问其选项和功能。工具栏的上行提供了快速访问相同功能的按钮。请注意,作曲项工具栏默认放置在窗口的左侧,因为它提供了快速访问通常构成地图所需的所有元素,例如地图画布、图例、比例尺、标签、注释等。在窗口的中央部分,您可以看到一个空白的页面,它代表可用于项目排列的作曲画布,如图所示:

在打印作曲窗口的右侧,有两个带有标签的面板。上方面板包含以下标签页:
-
项:这显示添加到地图中的地图项列表。它允许您定义它们的可见性、重命名、重新排序并将它们锁定以防止更改。
-
命令历史记录:这显示使用的命令列表。使用历史记录,您可以轻松回滚更改,并更好地控制地图生成过程。
下方面板包含三个标签页,如下所示:
-
组合:这负责纸张和质量(页面大小、数量和分辨率)以及指南和网格(间距和吸附容差),以便简化地图项的放置。
-
项目属性:这是一个动态标签页,其内容会根据当前选定的地图项目自动更改。
-
图集生成:一旦生成图集切换处于活动状态,您就可以设置和修改其参数。
注意
注意,只有默认面板的位置可以重新排列。为了更改面板/标签位置,将鼠标箭头悬停在它的穿孔区域上,它看起来像这样:
![打印作曲家]()
现在,将其拖放到另一个位置。您还可以通过点击右上角按钮关闭任何不必要的面板。此外,您可以通过在菜单或工具栏面板上右键单击后可用的切换来打开或关闭面板,即当您看到类似以下内容时:
![打印作曲家]()
您可以通过其Composer 选项菜单获取对作曲设置的控制,该菜单位于设置下。例如,您可能想更改用于图例和文本标签的默认字体。在网格外观部分进行进一步工作,我们将网格样式设置为实线,并保持网格和引导默认值不变,因为我们将在稍后进行配置。
初始设置 - 页面格式和其他基本设置
在创建地图之前,我们应该设置我们的工作空间,这主要是由页面设置定义的。所有必要的选项都位于编排标签下。让我们更仔细地看看纸张和品质部分。在预设下拉列表中的默认页面大小是A4,但您可以从 23 种其他大小中选择。我们将通过以下步骤创建自己的页面:
-
从列表中选择自定义。
-
宽度和高度字段将被激活。为两者输入
200的值(这意味着我们将为地图编排创建一个方形页面)。该值取决于在单位中选择的单位,默认情况下设置为毫米(毫米)。
由于我们只创建一张地图,我们将页数保留为 1,但如果您打算将多个页面合并成一个文档,您始终可以输入更多。这是因为您可以在单页编排中包含多个地图。如图例所示,我们使用的是方形页面。因此,它是否有纵向或横向页面方向无关紧要。页面背景是一个非常重要的项目,因为它允许您实现酷炫的地图可视化效果。通过点击更改按钮,您可以看到默认情况下,它设置为简单填充,颜色为白色(我们将使用它)。但是,您可以更改它,并从多个填充选项中选择以创建独特的填充图案。
小贴士
例如,您可以选择漂亮的栅格或 SVG 纹理,并通过选择栅格图像填充或SVG 填充分别将它们用作背景图案。否则,您可以选择渐变或形状爆发填充来尝试一些色彩分级效果。
导出分辨率定义了导出地图的 dpi 单位质量。此值越高,地图越好。然而,生成的文件也会更大。对于常见的用途,如出版物、报告和演示图形,300 dpi就足够了。当打印为栅格切换处于活动状态时,整个作品在导出为.pdf之前被转换为栅格。世界文件打开切换允许您将包含地理参考信息的.wld文件附加到图像导出输出。这意味着您的地图不仅可以用于图形或预览软件,还可以直接在 GIS 软件中打开并正确对齐。
现在,我们将调整用于在地图布局中对齐地图元素的网格:
-
在指南和网格部分,将网格间距值设置为
5毫米以使其更密集,并将吸附容差设置为10像素(值越高,吸附力越强)。 -
要显示网格,请激活位于视图下的显示网格按钮,或者使用Ctrl + '键盘快捷键。
-
切换吸附到网格,它位于视图下,或按Ctrl + Shift + '激活吸附。
小贴士
除了使用预定义的网格外,您还可以通过将鼠标箭头放在水平(用于垂直指南)或垂直(用于水平指南)的标尺栏上,并点击并沿页面画布拖动它们来创建自己的指南。禁用吸附到网格,并使用视图菜单中的各种选项,如显示/清除或吸附到指南。智能指南选项可以帮助您根据您作品中的其他项目自动检测最佳放置位置。
添加和自定义地图
在本节中,我们将创建布鲁克林区的人口地图。请确保在主窗口中,以下图层处于活动状态:布鲁克林区边界、zipcode(带有人口样式)、NY 区边界和水域区域。
要将地图添加到您的打印布局中,请点击作曲项目工具栏中的添加新地图
按钮,并按住鼠标左键的同时,将鼠标箭头以对角线方式拖动到页面上。您将在页面上看到一个矩形,并在其中看到一个地图。
注意
注意,地图的内容会动态变化,以反映主窗口中地图画布的内容。这意味着,如果您在主窗口中打开/关闭某些图层或更改它们的样式,打印作曲家窗口中的地图也会发生变化。如果您看不到变化,请点击刷新视图
按钮以更新地图。我们很快将讨论如何抑制这种行为。
可以通过拖动边框中心和角落的特殊方形标记来移动或调整地图框架的大小。如果您看不到框架和标记,这意味着当前项目是无效的。要激活它,请点击作曲家项目工具栏中的选择/移动项目
按钮。如果您想在框架内移动地图,请使用作曲家项目工具栏中的移动项目内容按钮,
。此外,只要此按钮处于活动状态,您就可以使用鼠标滚轮(或使用Ctrl和鼠标滚轮)放大地图。使用标记,以覆盖整个页面的方式扩展地图。
在正确放置地图后,我们可以转到项目属性选项卡上的高级选项。此选项卡汇集了几个可以通过点击它们旁边的
符号来展开或折叠的分区。
主要属性部分允许您从以下地图预览模式中选择:
-
缓存: 此模式将在当前屏幕分辨率下渲染地图,在缩放时不会改变,但图像本身将被适当地缩放。
-
渲染: 在缩放时,地图的分辨率将调整到最大值。此模式提供了更好的预览图片,但与缓存模式相比,速度较慢。
-
矩形: 代替地图,将在一个空框中显示
Map will be printed here消息。
当您在比例字段中输入一些值时,地图范围会动态变化。将其值设置为100000,并使用移动项目内容
按钮将地图正确地定位在框架内。以下截图显示了此阶段项目属性选项卡的外观:

使用地图旋转字段,您可以定义一个角度(以度为单位),在地图的框架内顺时针旋转地图。请注意,旋转角度将自动应用于网格线,以适当地调整它们与地图内容的关系。有三个切换按钮,它们提供以下选项:
-
当绘制地图画布项目切换按钮被激活时,主地图画布窗口中的现有注释将被添加到地图中。
-
如果您不希望打印地图反映主地图画布窗口中做出的更改,锁定地图项图层选项非常有用。因此,图层将保持不变,但它们的样式和标签将根据主窗口进行更改。我们激活此选项是因为我们不希望图层组合发生变化。
-
锁定地图项图层样式阻止地图项在主地图画布窗口中做出的样式更改。也要激活此选项。与上一个选项一起应用,它允许我们阻止作曲图从主地图画布窗口中的更改(即图层的样式和组合)。
在切换按钮的右侧,有一个从可见性预设设置图层列表按钮,
。此按钮允许我们从图层面板的工具栏上的可见性预设中快速定义地图项内容。要加载预设,请点击按钮右下角的小三角形箭头,并选择要在地图上显示的预设。地图的内容将根据预设和图层自动锁定。
范围部分提供了各种选项来定义和调整地图项的范围:
-
手动定义,通过在相应字段中输入X和Y值。
-
设置为地图画布范围:当前地图范围将变为与主地图画布窗口的范围相同。
-
在地图画布中查看范围:这与上一个按钮正好相反。它根据当前地图项范围更改主窗口中的地图画布范围。
由图集控制部分将在我们讨论创建图集部分中的图集生成时再进行介绍。
网格部分允许您向地图框架中添加坐标网格和框架。要添加新的网格,请点击
按钮,并调整其主要属性,如网格类型、间隔、网格框架、坐标等。
小贴士
您可以在单个地图项内组合使用不同坐标参考系统的多个网格。只需添加一个额外的网格。然后,在绘制“网格 2”网格部分中,点击CRS旁边的更改按钮,并选择您想要使用的 CRS。此选项的常见用例是将投影 CRS(使用线性测量单位,如英尺和米)与提供经纬度坐标的地理 CRS(以度为单位)组合。
概述部分允许您将不同比例的多个概述组合成单个地图组合。这将在使用地图概述部分中稍后介绍。
以下部分适用于各种地图项:
-
位置和大小部分允许您以页面单位定义项目框架的大小。参考点决定 X 和 Y 位置指定的是项目的哪个角落。
-
旋转字段值设置项目的旋转角度(以度为单位)。
-
框架切换按钮启用项目周围的框架,并提供访问其选项,例如框架颜色、厚度和连接样式。
-
背景负责框架的填充颜色。
-
项目 ID可用于与网络客户端创建地图项之间的链接,并且也便于在项目面板中识别特定项目。
-
渲染提供了访问混合模式和透明度选项,这些选项允许我们应用专业的图形效果。
添加和自定义图例
图例是任何地图的必要元素。它解释了图层的符号,并帮助我们阅读和理解地图。要添加图例,请点击作曲家项目工具栏中的添加新图例
按钮,并按住鼠标左键的同时,用鼠标箭头斜向拖动页面。您将在页面上看到一个矩形,其中包含一个图例。默认情况下,项目中的所有图层都将包含在图例中,因此它可能看起来太大,无法适应布局。选择图例项后,您可以使用项目属性选项卡来自定义其内容和外观。有几个特定的图例部分应该讨论。
主要属性部分允许您自定义以下选项:
-
标题:默认情况下,使用
图例标题,但您可以在此处输入任何其他文本,或者留空以删除标题。 -
标题对齐:这可以将标题对齐到左对齐、居中对齐或右对齐。
-
地图:默认情况下,只有地图 0可用,但如果您在单个页面布局中组合多个地图,您可以决定图例将引用哪个地图。
-
在此处换行:在此处输入一个符号,该符号将用于将长行文本分割成较短的文本块。稍后,您可以在图例项中编辑文本并在此符号处插入,以强制开始新的一行。
图例项部分负责图例的内容。默认情况下,自动更新模式处于活动状态,所有可用图层都加载到图例中。关闭自动更新模式后,图例内容树下面的按钮将被激活,提供以下选项(从左到右):
-
向下
和 向上
按钮用于移动项并更改它们的顺序。否则,您可以直接拖放项到新位置。任何更改后,图例的项内容将立即更新。 -
添加组
按钮允许您添加新组和子组以构建图例层次结构。 -
加号
和 减号
按钮负责添加和删除任何项,无论是组还是图层。请注意,只有主地图画布窗口中激活的图层才可用于添加。 -
编辑
按钮允许我们更改任何选定项(组、子组、图层或符号标签)的文本。例如,如果您想将长行换行,可以在 主属性 部分定义的文本符号中插入。这些更改仅应用于 打印作曲家图例 项,不会影响主窗口中的地图项。 -
总和
按钮显示矢量图层每个类的要素计数。 -
过滤
按钮通过地图内容过滤图例;也就是说,只有显示在地图项中的图例项(图层和类)将被包括在图例中。
在 字体 部分中,您可以定义标题、子组、组和项目的通用颜色和不同字体,以增强图例的可读性。如果图例包含许多项目并且太长而无法在单列中显示,它可以在 列 部分中拆分。在这里,您可以在 计数 字段中定义列数。默认情况下,列宽根据内容进行调整。如果您希望所有列的宽度相等,请激活 等宽列 切换。如果 拆分图层 模式开启,分类图层符号项将平均分配到各列;否则,不允许将类别移动到另一列。在下面的屏幕截图中,您可以查看这是如何工作的。顶部有一个不允许图层拆分的图例,底部类别在三个列中平均分配。

在 符号 部分中,默认的 宽度 和 高度 值可以手动修改。WMS 图例图形 用于为 WMS 图层添加图例,但这取决于 WMS 服务器是否支持并提供。在对话框窗口中,您可以调整作为栅格图像提供的图例宽度和高度。间距 部分允许您通过调整其各种项目(标题、组、子组、符号、图标标签、边界框和列)之间的空间来细化图例布局和可读性。
其他部分,如 位置和大小、旋转、框架、背景、项目 ID 和 渲染,提供与地图项相同的选项。
其他地图项
目前,我们的地图包含两个必要的项目:地图本身和解释其内容的图例。然而,还有更多项目可以用来改善其美学观感和地理可读性,例如刻度尺、指向北方的箭头、文本标签等。
刻度尺
在添加刻度尺项目之前,请确保您的地图画布使用线性测量单位的投影坐标参考系统(米和英尺)。要添加刻度尺,请单击作曲项目工具栏中的添加新刻度尺
按钮,并按住鼠标左键的同时将鼠标箭头拖动到页面上。您将在页面上看到一个矩形和一个刻度尺在其中。选择刻度尺项目后,使用项目属性选项卡来定制其外观。
在主要属性部分,选择一个地图以将其与刻度尺关联。由于您将只使用一个地图,地图 0将默认设置。样式下拉列表定义了刻度尺的外观:
-
单框或双框分别负责刻度尺以单个或双条纹框的形式出现的外观
-
线刻度中间、向下或向上产生一个带有刻度标记的简单水平线,用于固定比例单位
-
数字显示比例作为数字比例
小贴士
图形刻度尺是表示在演示文稿、报告和出版物中作为图像出现的地图比例的正确方法。建议使用它而不是数字比例尺,因为图形刻度尺在图像缩放时会按比例缩放。如果您仍然需要使用比例尺,请确保图像将以原始大小分布。
为了本教程的目的,请选择双框样式。单位部分负责正确表示测量单位:
-
从下拉列表中选择英尺投影测量单位。刻度尺将转换为测量英里的条形。类似地,米和海里也支持转换。地图单位可以使用原始地图单位,但您必须指定它们。
-
在标签字段中,输入
mi以使用测量单位的缩写(在我们的例子中是英里)。 -
每条刻度线单位表示地图单位与刻度线单位的比例。在此处输入
5280,因为我们知道 1 英里等于 5,280 英尺。
不要担心您的刻度尺看起来奇怪或折叠;我们将在段部分中修复它,如以下解释:
-
在大小部分,您应该输入定义段长度的值。如果您想让它有 1 英里长,请输入
5280;要让它有 2 英里长,请输入10560(5,280×2);依此类推。原理很简单——只需使用每刻度单位地图单位比例,您在主要属性部分中输入的,并将其乘以应在一段中包含的刻度单位数。为了本教程的目的,我们将一个段设为 1 英里,并输入一个值为5280。 -
在段中,为左输入值
2,为右输入值1。 -
将刻度尺的高度值增加到
5毫米。
在显示部分,您可以自定义以下刻度尺属性:
-
框边距:此值越大,刻度尺项目内容与其边界框边界的距离就越长。
-
标签边距:这定义了刻度尺与文本标签之间的空间。
-
线宽:这定义了刻度尺轮廓的宽度。
-
连接样式:这定义了刻度尺角落的外观。它仅适用于框型刻度尺。
-
端头样式:这定义了线条末尾的外观。它仅适用于线型刻度尺。
-
对齐:这将对刻度尺及其标签在边界框内的对齐进行设置。它仅适用于数字刻度类型。
字体和颜色部分提供了相应的功能。要更改字体或颜色,请点击按钮并从对话框窗口中选择必要的项目。请注意,填充颜色和次要填充颜色仅适用于框型刻度尺。在下面的屏幕截图中,您可以看到一个简单的双框刻度尺示例,左侧有两个段,右侧有一个段:

位置和大小、旋转、框架、背景、项目 ID和渲染等部分提供了与地图项目相同的选项。
北箭头
要添加北箭头,请点击作曲工具栏中的
添加图像按钮,并按住鼠标左键拖动鼠标箭头到页面上。您将在页面上看到一个空矩形。选择图像项目后,使用项目属性选项卡来定制其外观。
首先,您应该导航到您想要使用的图像源文件:
-
展开搜索目录部分。在此部分中,您可以设置图像搜索路径。默认情况下,您将看到
QGIS 安装路径\qgis\svg\路径及其子文件夹。您可以使用删除和添加按钮重新定义路径,并访问您自己的图像。 -
在加载预览...窗口中,您将看到可用图像的缩略图,如下面的截图所示。点击它们会自动将它们加载到图像项框架中。为了本教程的目的,我们选择
NorthArrow_02.svg。![北箭头]()
现在您已经选择了北箭头,您可以调整其一些主要属性。调整模式定义了在框架内调整图像的方法:
-
缩放:图像将被调整到框架中,并且其比例将被保存。
-
拉伸:图像将在框架内拉伸,忽略其比例。
-
剪辑:图像将被调整到其原始大小,框架将用于剪辑图像,因此只有其中的一部分将是可见的。此模式仅适用于位图图像。
-
缩放和调整框架:图像和框架都将调整大小以适应彼此。首先,图像将按比例调整以适应框架,然后框架将调整以包含图像。
-
调整框架到图像大小:框架将被调整到原始图像大小。
为了本教程的目的,我们将使用缩放和调整框架模式。在此模式下,放置选项不可用,但您可以在选择缩放和剪辑模式时使用它来在框架内定位图像。同样,图像旋转也适用于缩放和缩放和调整框架模式。如果您想将北箭头与地图同步旋转,请激活与地图同步切换按钮。
其他部分,如位置和大小、旋转、框架、背景、项目 ID和渲染,提供了与地图项相同的选项。
其他项
到目前为止,我们只介绍了最重要的和必要的地图项。您可能已经注意到,项目项面板提供了访问更多项的途径,如下所示:
-
标签项
:这提供了对文本(或 HTML)标签及其各种属性的控制,例如字体、字体颜色、垂直和水平(对齐)、位置和大小、旋转等。 -
形状项
:这允许您向布局添加简单的几何图形,例如矩形、三角形或椭圆。在项目属性选项卡中,您可以更改它们的类型、样式和其他基本选项,例如位置和大小、旋转、框架、背景、项目 ID和渲染。 -
箭头项
:这是一个非常有用的元素,用于突出多个地图和概述之间的关系。在项目属性选项卡中,您可以选择线条样式、箭头轮廓和填充颜色、箭头轮廓和宽度,以及起始和结束标记。 -
属性表项目
:此项目将矢量图层属性表添加到地图布局中。如果您想这样做,请选择项目属性标签页下的图层。通过点击属性按钮,您将被带到选择属性窗口,在那里您可以通过添加或删除不必要的列;更改标题、列对齐和宽度;以及应用排序选项来修改表格的结构和外观。
对于此项目,您还可以应用特征过滤以排除不必要的或多余的元素。在外观和字体和文本样式部分,您可以找到各种增强表格可读性的选项。 -
HTML 框架项目
:这负责使用 HTML 标记添加网页或用户生成的内容。例如,您可以在源窗口中输入以下表达式:地图数据由<a href='https://nycopendata.socrata.com/'>纽约开放数据门户</a>提供。这将在原始网站添加一个链接。
当一切准备就绪时,您可以通过菜单导出您的地图,导航到组合器 | 导出为图像或导出为 SVG或导出为 PDF,或者通过点击组合器工具栏中的相关按钮,其中
负责图像导出,
用于导出为 SVG,
用于导出为 PDF。

在打印组合器中创建的简单地图示例
与多张地图和概览一起工作
有时,需要在单个布局中结合多张地图。例如,假设您需要在单页上结合几张不同的地图,或者在一个大区域内显示感兴趣区域的地理位置。虽然这些任务看起来相似,但它们需要略微不同的解决方案,我们将在以下章节中探讨。
在单个打印组合器中结合多张地图
在我们的示例中,我们将结合两张地图——地形图和飓风疏散区域图——并在单个打印布局中完成:
-
在主窗口中,激活将在地形图中使用的图层——“布鲁克林区边界”、“纽约区边界”、“水域”(以正确显示海岸线和水体),最后是“阴影”和“海拔高度,英尺”。
-
然后,打开新打印组合器窗口,无论是从项目菜单还是使用Ctrl + Shift + P键盘快捷键。为此示例调整页面大小为A3,将网格间距设置为
5毫米,并从视图菜单激活显示网格和吸附到网格选项。 -
在项目属性标签页的位置和大小部分添加一个新的地图项目,并调整其大小为
200×200毫米。将比例设置为100000并正确放置地图内容。之后,激活以下切换按钮以防止更改地图内容:-
锁定地图项目图层
-
锁定地图项目样式
-
-
添加并调整其他必要的地图元素,例如比例尺、图例、北箭头等。创建图例,移除不必要的图层。如果您想阻止某些项目发生变化,请在项目面板中锁定它们,如图所示:
![在单个打印作曲家内组合多个地图]()
-
当您完成等高线地图及其元素后,转到主地图画布窗口并激活您想在地图上显示的图层。例如,激活
飓风疏散区域和主要住宅区划,并停用阴影和海拔高度,ft。 -
添加一个新的地图项目并重复步骤 3 和 4。完成后,结果可能看起来像以下屏幕截图所示:
![在单个打印作曲家内组合多个地图]()
您可以在单个布局中组合任意数量的地图,并为它们使用不同的比例尺和单独的图例。您应该始终记住的是使用锁定地图项目(样式)以防止对地图进行任何更改。
当您需要在单页内展示类似地图时,这种方法简单且有效,但有时需要在不同缩放级别上展示不同的感兴趣区域,并将它们的范围相互关联。在这种情况下,您应该使用所谓的地图概览。
使用地图概览
地图概览在单个布局中关联多个地图范围,并且对于展示感兴趣区域与更大的空间背景之间的关系非常有用,例如,一个国家内的一个地区,一个城市区域内的一个区,等等。
在本例中,我们将结合三个概览到一个单个地图布局中,以展示布鲁克林与整个纽约的关系,以及布鲁克林内的感兴趣区域与该区范围的关系。为了实现这一点,您需要执行以下步骤:
-
在主地图画布窗口中,激活
NY 地区边界图层并停用所有其他图层。创建一个新的打印作曲家,使用默认的A4页面大小,并调整任何其他所需的属性。将一个新的地图项目添加到布局中。此地图将用于显示简单的边界并为主地图提供空间背景,因此它可能被包含在一个小 95 x 95 mm 的框架中,比例为 1:515,000。在调整地图视图后,不要忘记选择锁定地图项目图层和锁定地图项目样式。 -
现在,您将添加主地图,它将是布局的核心。在主地图画布窗口中,激活您想在地图上显示的图层(例如,
飓风疏散区域和主要住宅区划)。再次,将一个新的地图项目添加到布局中并调整其大小、比例和位置。例如,它可能是 200 x 200 mm,比例为 1:97,000。再次,使用锁定地图项目图层和锁定地图项目样式。 -
最后,添加第三个地图。在主地图画布窗口中激活您希望在地图中显示的图层(例如,
hillshade和height a.s.l., ft)。添加一个新的地图元素。调整地图大小为 95 x 95 毫米,并将比例设置为20000。移动项目内容以显示您感兴趣的区域,并选择锁定地图元素图层。 -
现在,我们需要将地图范围相互关联。我们可以通过概述来实现这一点。激活您添加的第一个地图元素,并在项目属性选项卡下展开概述部分。要添加新的概述,请点击
按钮,要将其显示在地图上,请激活绘制“名称”概述切换按钮。要将概述与地图元素范围关联,从地图框架下拉列表中选择地图。您可以使用符号选择器对话框窗口更改默认的框架样式。
混合模式在组合多个概述框架时非常有用,可以实现更时尚的效果。反转概述切换按钮将反转概述区域外的填充。居中于概述将地图元素内容移动到放置概述的中心。使用
按钮添加另一个包含地图框架且范围较小的概述。您可以根据需要组合任意数量的概述。使用
按钮删除不必要的概述,以及使用
和
按钮重新排序它们。 -
前往另一个地图并为其添加一个概述。选择您感兴趣的地图元素,并转到其属性选项卡。展开概述部分,点击
按钮以添加概述。从地图框架下拉列表中选择必要的地图,并调整概述的框架样式。小贴士
QGIS 使您能够组合多个概述并生成复杂的结果。为了突出不同概述之间的差异和关系,请使用单个地图框架和比例尺。
在下面的屏幕截图中,您可以查看生成的地图。它结合了三个地图元素,并关联了它们的范围和概述。

创建图集
在 QGIS 中,图谱是通过自动化的图谱生成功能创建的多页地图。图谱背后的理念非常简单——用户通常需要生成多个小地图,而不是一个大地图。为了在多个页面中正确排列多个地图,使用图谱覆盖层。此覆盖层可能包含各种类型的几何体(点、线和多边形),用于定义地图的一般范围、单独页面的范围、它们的数量和它们的顺序。图谱最常见的一个例子是将一个大区域(例如,一个国家、地区或流域盆地)根据其子单位(例如,地区、州、县或子流域)分成几个部分。
在本示例教程中,我们将使用zipcode图层元素作为多个地图的边界范围,生成多个街道网络地图。此外,我们将使用专门设计的插件来遮罩所有排除区域,并实现时尚的制图效果:
-
首先,我们启用我们将从中创建地图的图层:
布鲁克林地区边界、zipcode、水域面积、公园和道路。 -
为了本教程的目的,我们将使用外部遮罩插件。此插件允许用户创建地图遮罩层,并过滤其他层的标签,移除位于兴趣区域外的标签。它还能够与图谱生成过程交互。按照第一章中所述,处理您的数据,安装并激活遮罩插件。
-
当插件被激活时,我们需要提供它基于哪些图层特征进行遮罩。在我们的案例中,这将是指
zipcode。激活它。然后,使用按区域或单击选择特征
模式,点击地图画布以选择任何特征。 -
一旦选定的多边形被突出显示,请转到插件 | 遮罩 | 创建遮罩并打开创建遮罩对话框。在此窗口中,您可以定义遮罩的以下属性:
-
遮罩多边形的样式,默认使用反转多边形渲染器和形状爆发填充选项,通过透明度进行修改。
-
缓冲区切换会在兴趣区域周围生成一个缓冲区,其宽度和复杂性由单位和段数值定义。
-
在表达式中所使用的遮罩几何体使用即时简化。值越高,几何体越粗糙。
-
用于多边形标签过滤的函数定义了如何确切地消除遮罩多边形外的标签。
-
用于线标签过滤的函数定义了线标签的排除模式。从下拉列表中选择遮罩几何包含线。在可用图层列表中激活
roads(注意,只有当其标签开启时此图层才可用)。 -
激活另存为切换按钮,并导航到您想要保存新创建的掩膜层的目录。否则,将创建一个所谓的内存(临时)层,并且在关闭项目后不会保存。
![创建图集]()
-
-
在您点击确定后,掩膜层将出现在图层面板中,您将看到其应用于地图画布上的华丽样式效果。选定的多边形要素看起来被突出显示,而外围地图则变暗。此外,标签仅出现在掩膜要素内。现在我们可以禁用
zipcode层,因为我们不希望其边界显示在生成的地图上,然后转到打印编者以生成图集。 -
打开一个新的打印编者,并向其中添加一个新地图项以及您想要包含在布局中的任何其他项。在我们的示例中,我们将使用以下内容:
-
自定义页面大小等于 200 x 200 毫米。
-
路网地图项具有相同的尺寸,200 x 200 毫米,比例尺为 1: 20000。不要锁定此地图项的图层,因为它将在图集中动态更改。
-
在右上角添加一个小的 50 x 50 毫米地图项,其中包含
New York borough boundaries层,并添加一个概述。在创建此地图后,锁定其图层及其样式。 -
现在,您可以回到主窗口并激活对路网地图必要的图层。
-
-
在调整所有必要的项目后,转到图集生成选项卡并激活生成图集切换按钮。
-
配置部分提供了以下选项来配置从其覆盖层生成的图集:
-
从覆盖层下拉列表中选择
zipcode。您可以从此列表中选择任何图层,并使用其特征来迭代它们并创建图集页面。 -
当隐藏覆盖层处于活动状态时,覆盖层在地图上不会显示。在我们的案例中,我们不使用它,因为我们已经禁用了覆盖层。
-
在筛选条件区域,您可以创建一个表达式来仅从覆盖区域选择某些要素。例如,您可以使用面积大于某个预定义值的多边形。
-
-
输出部分通过以下选项提供了对结果的控制:
-
输出文件名表达式是一个模板,将用于命名多个输出文件。
-
尽可能生成单个文件在可能的情况下生成单个多页文件(适用于导出到
.pdf)。如果此选项处于活动状态,则输出文件名表达式不适用。 -
排序方式选项提供了访问覆盖层属性字段名称的权限,您可以选择其中的任何一个来按字段值升序或降序排序输出文件,旁边有箭头按钮。
-
-
返回到项目属性选项卡。请注意,应选择包含主地图(路网)的地图项。激活由图集控制部分,您可以从以下选项中进行选择:
-
要素周围边距:你可以为单个地图集页面上映射的每个要素设置周围区域的大小。这意味着地图范围和比例将不会固定。它们将调整以包含要素及其设置的边距。我们选择此选项并设置值为
5百分比。 -
预定义比例尺(最佳匹配):项目的一个预定义比例尺,最适合将要素放入地图集页面中将被使用。
-
固定比例尺:每个要素将以相同的比例显示,地图页面将自动围绕它居中。当你需要打印多个相同比例的地图时,这非常有用。
-
-
现在,一切准备就绪,你可以生成和预览地图集。你会注意到预览地图集按钮在地图集工具栏中是激活的。点击它来生成你的地图集。当生成过程完成后,你会看到工具栏上的其他按钮也变得激活了。点击它们来预览地图集页面。
使用工具栏按钮,你不仅可以探索你的地图集,它包含几分钟内创建的多个页面,还可以快速访问打印
、导出和设置
选项。导出选项显示在本截图上:![创建地图集]()
在以下截图上,你可以看到一个单页地图集的示例:

管理打印作曲家
初学者通常忘记应用地图锁定选项,经常从头开始创建每个地图。结果,他们被多个地图作曲家所压倒,这些地图作曲家中的地图会永久性地改变。如果你想节省时间,那么使用锁定地图项图层和锁定地图项样式来阻止地图中的不希望的变化是明智的。
你可以在单个项目中存储多个地图和地图集,并通过转到项目 | 打印作曲家来访问它们。在项目下的打印作曲家管理器中提供了高级选项。

小贴士
在作曲家管理器中,你可以从模板创建一个新的打印作曲家。任何地图布局都可以从打印作曲家的菜单作曲家 | 另存为模板保存为模板。
摘要
在本章中,你学习了基本地图元素及其与打印作曲家的配置。现在你知道 QGIS 不仅是一个创建简单打印地图的强大工具,而且还提供了将多个地图组合成一个布局、通过概述关联它们以及最终通过几点击生成多页地图集的复杂选项。
虽然打印地图非常有用,但如果你更喜欢在线分享你的结果,它们效率不高。在下一章中,你将学习如何快速有效地在线发布你的数据。
第四章。在线发布地图
在本章中,我们将介绍 QGIS Cloud 服务,这是一个强大的地图托管平台,您将学习如何通过在互联网上发布地图与他人共享您的地图。我们将涵盖所有必要的步骤,例如创建 QGIS Cloud 账户、准备地图以供发布、填写元数据、限制信息访问以及发布地图。此外,您还将学习如何从网络浏览器、QGIS 和其他桌面 GIS 中使用已发布的地图。
在本章中,我们将讨论以下主题:
-
注册 QGIS Cloud 服务
-
QGIS Cloud 插件
-
创建数据库
-
发布地图
-
在 QGIS 和浏览器中查看您的地图
-
删除未使用的地图
注册 QGIS Cloud 服务
QGIS Cloud 是由 Sourcepole AG 开发和维护的云托管服务。使用此服务,我们可以轻松发布地图、与他人共享地图,甚至修改数据——这一切都不需要任何特殊知识,例如服务器设置和管理。
QGIS Cloud 是使用开源技术构建的。为了存储矢量数据,它使用 PostgreSQL/PostGIS 数据库、由 QGIS 服务器渲染的地图以及基于 QGIS Web 客户端的网络查看器。因此,它与桌面 QGIS 集成得非常好。存储在云上的图层可以用 QGIS 加载和编辑。发布的地图将与在 QGIS 中创建的本地地图具有相同的外观和感觉。
首先,我们需要创建一个账户。这可以通过以下简单步骤完成:
-
打开您的浏览器并访问
qgiscloud.com。 -
点击主页上的 注册 按钮。
-
填写并提交注册表格。您需要提供一个有效的电子邮件地址和密码。
-
在提交表格后,您将收到一封确认电子邮件,其中包含确认说明。通过访问电子邮件中提供的链接来确认您的账户。
就这些了!现在您拥有了一个带有免费计划的 QGIS Cloud 账户。此计划允许您发布无限数量的公共地图,创建五个 PostGIS 数据库,并上传高达 50 MB 的数据。
注意
如果您需要更多空间来存储数据,想要限制对您地图的访问,或者需要一些其他特殊功能,请考虑切换到可用的付费计划之一。这些计划及其提供的选项列在 qgiscloud.com/en/pages/plans。
如果 QGIS Cloud 插件已经安装,您也可以直接从 QGIS Cloud 插件打开注册页面。只需激活插件,然后在 账户 或 服务 选项卡下点击 注册 链接。相应的页面将在您的网络浏览器中打开。
QGIS Cloud 插件
QGIS Cloud 插件 为您提供了使用 QGIS Cloud 托管发布数据和地图的用户友好界面。由于它是一个第三方插件,我们首先需要安装它。
如果您有代理服务器,则需要先进行配置。插件管理器使用与 QGIS 相同的代理设置,因此您只需转到设置 | 选项,在网络标签页中设置代理即可:
-
启动 QGIS,通过转到插件 | 管理并安装插件来打开插件管理器。等待 QGIS 从存储库接收插件列表。
-
切换到全部标签页,并在搜索字段中开始键入
cloud以过滤插件列表,如图所示:![QGIS Cloud 插件]()
-
然后,选择插件并点击安装插件按钮。下载可能需要一些时间,请耐心等待。下载完成后,您将看到一个消息栏,显示下载确认,现在您可以关闭插件管理器。有关安装插件的更多信息,请参阅第一章中通过插件扩展功能部分,处理您的数据。
安装后,QGIS Cloud 插件将在插件菜单中可用。QGIS Cloud 插件还在插件工具栏中放置了一个按钮
,并创建了一个QGIS Cloud浮动面板。默认情况下,此面板停靠在 QGIS 主窗口的左侧。
让我们看看插件界面:

插件面板有四个标签页:
-
服务:此标签页用于发布地图和更新已发布的地图。最初,此标签页包含插件及其服务的简短描述,以及到托管网站和注册页面的链接。发布地图后,您将在这里找到指向刚刚发布的地图(包括桌面和移动查看器)的链接以及带有您地图的 WMS 服务 URL。
-
上传数据:这允许您将本地数据上传到 QGIS Cloud 数据库并发布地图。在这里,我们可以选择要使用的数据库,在发布前调整表名,并将我们的本地数据上传到 QGIS Cloud。
-
账户:此标签页用于身份验证和账户管理。使用此标签页,如果您还没有账户,可以注册 QGIS Cloud。此外,我们还可以在这里创建和删除数据库(如果需要)。
-
关于:在这里,您可以找到有关插件作者、QGIS Cloud 支持联系人和插件版本的信息。在出现问题时,这些信息将非常有用。
现在,切换到QGIS Cloud面板的账户标签页,点击登录,并使用您的用户名和密码登录。这可能需要一些时间,因为插件需要与 QGIS Cloud 服务器交互。登录成功后,会弹出一个消息栏,您将在插件面板中看到您当前的计划信息、已用/可用磁盘空间(如果您已有数据库),以及现有数据库列表(如果有)。
创建数据库
QGIS Cloud 将所有您的地理数据存储在 PostgreSQL/PostGIS 数据库中,因此在上传任何图层和发布地图之前,您至少需要为您的数据创建一个数据库。
要创建一个新的数据库,请执行以下步骤:
-
启动 QGIS 并激活 QGIS Cloud 插件,如果尚未激活。
-
切换到 QGIS Cloud 面板中的 账户 选项卡,并使用您的用户名和密码登录。
-
点击 账户 选项卡底部的 创建数据库 按钮,等待操作完成。
数据库创建是一个耗时的操作,所以请耐心等待。完成后,您将在可用数据库列表中看到一个随机命名的新的数据库。此外,插件已将此数据库注册到 QGIS 中,因此它可以像任何其他 PostGIS 数据库一样使用,例如,在 QGIS 中从中加载和编辑图层。
注意
如果你位于防火墙后面并且/或者创建数据库时遇到问题,请通过电子邮件联系 QGIS Cloud 支持:<support@qgiscloud.com>。
如果意外地通过插件从 QGIS 中删除了此 PostGIS 连接,可以手动恢复。只需使用插件登录到 QGIS Cloud,并将光标悬停在数据库名称上。在工具提示中,您将找到创建连接所需的所有信息(主机、端口号、数据库用户名和密码)。我们还可以使用这些信息通过其他 PostgreSQL 客户端连接到数据库,例如 psql 或 pgAdmin。
不幸的是,你不能将数据库重命名为有意义的名称,所以请在一个地方保留一个列表,记录每个数据库中存储的数据信息,以备将来参考。此外,你可以使用 DB 管理员检查数据库的内容。
为了方便起见,我们建议您将每个地图/项目保存在单独的数据库中。这样做会引入一些磁盘使用开销,因为每个空数据库的大小约为 11 MB,但这种方法也大大简化了事情。例如,您可以轻松删除未使用的地图,而不会丢失存储在同一数据库中的另一个地图中使用的数据。当然,您也可以将许多图层保存在单个数据库中并在不同的地图中使用它们,但这在您决定删除某些地图或图层时会导致一些复杂性。
记住,你创建的数据库数量不能超过你的计划允许的数量;使用磁盘存储也是如此。如果你需要更多空间或数据库,请升级到另一个计划。
发布地图
现在,当创建一个新的数据库时,我们可以在互联网上发布在 第二章 中设计的地图,可视化和样式化数据。
让我们先看看我们的项目;它包含栅格和矢量图层。还有几个作曲家。在发布数据和地图之前,我们需要决定哪些信息应该发布,以及我们想要隐藏什么。
默认情况下,所有矢量图层都会发布,其所有属性都可用于 WMS 和 WFS 服务。项目中的所有可用作曲者也会被发布。
如果你需要保留图层(或图层组)的一些属性不发布,那么就需要调整相应图层(或图层组)的属性。
注意
在本章的 WMS 设置 部分中,你将学习如何排除整个图层和作曲者不进行发布。
要这样做,从 QGIS 图层树中选择一个图层,右键单击以打开上下文菜单,然后选择 属性。在 图层属性 对话框中,转到 字段 选项卡,如下面的截图所示:

在这里,我们看到一个包含所有图层属性以及它们附加信息的表格(数据类型、字段长度、精度等)。最后两列,WMS 和 WFS,控制当图层作为 WMS 和/或 WFS 图层发布时属性的可见性。如果你不想发布某些属性,只需取消选中相应的复选框。然后,点击 OK 按钮保存更改并关闭对话框。请注意,同一个属性可以通过 WMS 发布,但通过 WFS 则不可用,反之亦然。检查所有矢量图层,查看它们的属性,并在必要时隐藏它们。
现在是时候考虑光栅图层了。不幸的是,QGIS Cloud 目前只允许你上传本地矢量图层;本地光栅图层支持尚不可用。但不要气馁!你可以使用 WMS 服务和底图来代替。
如果我们的光栅图层也作为 WMS 服务可用,我们可以安全地将本地文件替换为 WMS 图层,并且我们的地图将发布而不会丢失任何数据。已添加的 WMS 图层也将被发布。
但如果只有光栅数据作为本地文件可用,而你又真的需要一个底图怎么办呢?幸运的是,QGIS 允许你添加底图;你只需要安装 OpenLayers 插件。一旦安装了此插件,请转到 Web | OpenLayers 插件,并从可用列表中添加所需的底图。可以添加多个底图,例如 OpenStreetMap 和 Bing,这样在发布项目后,用户将能够在它们之间切换。
注意,可以在同一张地图中同时拥有这两种类型的图层——WMS 和底图。然而,请记住,WMS 图层将覆盖底图,并可能完全覆盖它。如果你想在 WMS 图层下看到底图,发布前别忘了设置 WMS 图层的透明度。
我们地图中只有一个光栅图层——数字高程模型,它已从本地文件加载,因此无法发布。让我们添加一些其他光栅数据,这些数据将可以从发布的地图中获取。
由于我们的地图包含一个 DEM 图层,因此找到合适的替代品将很好。幸运的是,USGS 通过 WMS 提供对一些地图的访问,包括阴影地形。当然,此图层不如我们的 DEM 详细,但对于在线地图来说,这已经足够了。首先,我们需要通过以下步骤创建一个新的 WMS 连接:
-
在图层工具栏中单击添加 WMS/WMTS 图层按钮,或转到图层 | 添加图层 | 添加 WMS/WMTS 图层。在从 WM(T)S 服务器添加图层对话框中,单击新建以创建新的连接。将名称输入为
USGS Relief (base),将basemap.nationalmap.gov/arcgis/services/USGSShadedReliefOnly/MapServer/WMSServer?request=GetCapabilities&service=WMS作为URL,然后单击确定。从组合框中选择新添加的连接,然后单击连接按钮。 -
从图层树中选择第一个节点,称为USGS 阴影地形...。
-
在坐标参考系统组中,单击更改,找到并选择WGS 84 /伪墨卡托(EPSG:3857),然后单击确定。
-
单击添加并关闭 WMS 对话框。
-
最后,将添加的图层移至所有矢量图层之下,使其位于 QGIS 图层树的底部。
注意
注意,此阴影地形图层包含 1:18000 或更小比例尺的数据。如果您想在更详细的尺度上显示地形,则必须添加另一个使用另一个 WMS URL 的图层:
services.nationalmap.gov/arcgis/services/USGSShadedReliefLarge/MapServer/WMSServer?request=GetCapabilities&service=WMS。
您可能已经注意到,我们在EPSG:3857中添加了图层,而所有矢量图层都在 EPSG:2263 中。因此,我们现在启用了“即时”重投影,项目坐标参考系统是 EPSG:3857。这是因为我们还将添加一个背景 Bing 地图,该地图仅在 EPSG:3857 中可用。如果您不需要背景地图,最好使用与您的矢量数据坐标参考系统匹配的 CRS 或知名 CRS,例如WGS 84和WGS 84 /伪墨卡托。
现在,我们将添加带有 Bing 航空图像的背景地图。
注意
注意,使用某些背景地图可能会违反这些地图的服务条款。在添加任何背景地图之前,请检查您是否允许使用该服务与您的在线地图,并重新分发包含该服务数据的地图。
要这样做,请执行以下步骤:
-
安装并激活OpenLayers 插件(有关更多详细信息,请参阅第一章中的通过插件扩展功能部分,处理您的数据),处理您的数据)。
-
转到Web | OpenLayers 插件 | Bing Maps | Bing Aerial。
-
将新添加的图层移动到 QGIS 图层树的底部,这样它就会位于所有其他图层之下。
如果需要,您可以添加更多 WMS 图层和/或背景地图,但不要在没有必要的情况下通过额外的图层超载您的地图。同时选择默认可见的栅格,并关闭其他栅格图层以加快地图加载速度。在实施所有更改后保存项目。
现在我们已准备好发布数据,我们的下一步是项目准备。当然,您可以原样发布地图,但花些时间使您的地图更易于用户使用且看起来更专业,尤其是如果您计划与他人分享它。
一般设置
首先,我们填写一些元数据,这将帮助用户找到我们的地图,并提供一些关于它的信息。为此,通过按Ctrl + Shift + P打开项目属性对话框,或者转到项目 | 项目属性...并切换到OWS 服务器选项卡。此选项卡允许我们配置 QGIS 服务器将如何处理我们的项目。这里有许多不同的设置;目前,我们将查看服务能力组:

这里,我们需要填写以下元数据:
-
标题:这是地图的标题。我们选择
布鲁克林(纽约)演示地图。 -
组织:在这里,我们指定地图的作者或所有者。请在这里输入您的名字。
-
在线资源:在这里,我们指定用于访问我们地图的 URL。目前,我们可以将其留空,因为地图尚未发布,这就是我们不知道其 URL 的原因。但如果您好奇,以下是 QGIS Cloud 中用于 URL 生成的约定:
http://qgiscloud.com/<user_name>/<map_name>/wms。在这里,<user_name>是您的 QGIS Cloud 登录名,<map_name>是已发布项目的文件名,不带扩展名。所以,假设您的登录名是 alex,项目在数据上传后将被保存为brooklyn_demo.qgs。那么,URL 将是http://qgiscloud.com/alex/brooklyn_demo/wms。 -
人员:这是负责已发布地图的人员的姓名。它主要用于支持联系。在我们的情况下,这与组织字段中指定的人员相同。
-
电子邮件和电话:这是负责人的联系详情。我们可以将其留空或只填写一个字段,以便用户在有任何问题或问题时能够联系地图的创作者。
-
摘要:这是我们地图和所使用数据的简要描述。这是重要信息,因为它帮助用户了解地图的目的和覆盖范围。此类信息还可以由元数据目录用于索引和搜索地图的目的。以下是我们的描述;您可以直接使用它,或者根据您的喜好进行修改:
基于纽约市布鲁克林区的官方开放数据门户
data.cityofnewyork.us/的纽约市布鲁克林区演示地图。为 Packt Publishing 的QGIS 实例书籍创建的地图。
-
费用: 这显示了关于费用的信息。如果地图不使用费用,则可以忽略。
-
访问限制: 这描述了使用此地图的约束和法律要求。例如,可以是“仅限内部使用”或某些版权声明。对于公共地图,此字段通常为空。
-
关键词列表: 这是一个描述地图的关键词或短语列表。这些信息有助于搜索和索引。对于我们的地图,我们使用这些关键词;请随意调整以适应您的口味:
纽约,布鲁克林,QGIS 实例,演示。
填写元数据不仅是地图,还包括其中的每个图层,这是一个好习惯,这样当用户查找可用的 WMS 或 WFS 图层时,他们将看到图层的描述,并容易理解某个图层是否适合他们。任何人都会同意,与具有标题和摘要的 WMS 服务器一起工作比与没有此类信息的服务器更舒适。
要编辑图层的元数据,从 QGIS 图层树中选择它,右键单击以打开上下文菜单,并选择属性。在图层属性对话框中,转到元数据选项卡。需要填写的重要元数据包括标题、摘要和关键词列表。编辑元数据后,单击确定以关闭对话框并保存项目。
WMS 设置
现在看看WMS 功能组,它允许您调整从我们的地图创建的 WMS 服务,如图中所示:

默认情况下,整个地图将被发布。如果您只想通过 WMS 发布地图的一部分,请勾选广告范围框,并通过输入其最小和最大坐标来定义允许的范围。单击使用当前画布范围按钮以将可用范围限制为当前地图范围。
QGIS Server,由 QGIS Cloud 使用,实现了 WMS 标准的特殊扩展:GetPrint请求。这允许您使用项目中的可用作曲家之一创建打印地图。默认情况下,所有可用的作曲家都将发布并广告用于打印。如果您根本不需要此功能或想隐藏一些作曲家供用户使用,请激活排除作曲家组,并使用+按钮将需要排除的作曲家添加到此列表。
同样,如果您不想发布所有图层,可以隐藏一些图层。为此,激活排除图层组,并使用+按钮添加要排除的图层。
注意
当然,我们可以简单地删除图层,用不同的名称保存项目,然后发布这个新项目。但在这个情况下,我们将失去一个主要优势——使用同一项目进行离线和在线地图的能力。
想象一下,在发布地图后,您需要更改图层的符号。在两个不同项目的情况下,您需要保持它们同步。拥有一个单一的项目并通过更改设置隐藏图层要简单得多。
下一个重要的设置是CRS 限制。默认情况下,每个图层都可以在任何 QGIS 支持的坐标参考系统(CRS)中加载。因此,服务能力文档变得非常大,尤其是在地图包含许多图层时。这反过来又导致基于网络的查看器和桌面客户端加载地图变慢,因为它们必须下载和解析更多的数据。
在实际应用中,通常只需要很少一部分坐标参考系统。因此,我们可以安全地限制可用的 CRS 列表,而不会带来任何缺点,并且还能加快我们地图的加载速度。为此,激活CRS 限制并添加所有必要的 CRS。使用按钮允许我们只需单击一下就将当前项目的 CRS 添加到列表中。
如果您想在识别时启用特征高亮显示,别忘了勾选添加几何形状到特征响应复选框。您还可以通过调整GetFeatureInfo 几何精度(小数位数)字段中的值来限制坐标精度。
最后,您可以通过在GetMap 请求的最大值中定义宽度和高度以及调整JPEG 图像质量来限制由 GetMap 请求返回的图像大小。
WFS 设置
如果您想使数据不仅作为栅格数据可用,还作为矢量数据可用,您需要配置WFS 功能,如下面的截图所示:

您需要做的就是通过在已发布列中勾选相应的复选框来选择应通过 WFS 可用的图层。如果图层需要可编辑,您需要通过在相应的列中激活复选框来指定支持的操作:
-
更新:用户可以使用此功能在具有此功能的图层中编辑现有特征(包括几何形状和属性)
-
插入:用户可以使用此功能向图层添加新特征
-
删除:此功能允许用户从图层中删除现有特征
注意
记住,使用 QGIS Cloud 的免费计划时,您的地图将公开可用,任何人都可以编辑您的图层。如果您需要限制访问,请考虑切换到其他计划或不要通过 WFS 启用编辑功能。
作为地图所有者,您可以通过连接到相应的 QGIS Cloud 数据库来始终通过 QGIS 编辑已发布的矢量图层。
当您对所有设置满意时,点击应用按钮保存您的更改,然后关闭项目属性对话框。
现在,我们可以发布我们的地图。如果尚未激活,请激活 QGIS Cloud 插件。切换到QGIS Cloud面板中的账户选项卡,并使用您的用户名和密码登录。首先,我们需要创建一个数据库,所有图层都将保存在该数据库中。数据库创建在本章的创建数据库部分有详细说明;如有必要,请返回该部分。我们将假设一个全新的空数据库已经存在。
切换到上传数据选项卡。从数据库下拉菜单中选择之前创建的数据库。在此下拉菜单下方的表格中,您将看到所有由 QGIS Cloud 支持的、可以上传的图层。如果没有图层,请点击刷新图层。如有必要,您可以通过编辑表名列中的文本来调整用于存储图层数据的数据库表名称。
注意
注意,尽管所有其他列也可以编辑,但您不应编辑它们。
还要验证表中列出的所有图层都分配了正确的 CRS。QGIS Cloud 仅支持 EPSG 数据库中可用的 CRS,因此如果某些图层有用户定义的 CRS,在发布之前必须重新投影它们。
如果勾选了替换项目中的本地图层,插件将通过用上传的图层替换所有本地矢量图层来更新项目。因此,您的项目将包含来自 QGIS Cloud 数据库的图层,您可以从 QGIS 中轻松编辑它们。这些图层的所有更改将立即在发布的地图中可见。
要开始数据上传,点击上传数据按钮。上传所需时间取决于数据大小和您的互联网连接速度。完成上传后,系统会提示您保存更新后的项目。我们建议您使用不同的名称保存已发布的项目,以便您将拥有未更改本地数据的原始项目。
小贴士
QGIS Cloud 使用项目文件名作为地图名称,因此请仔细选择项目文件名;使用有意义的名称会更好。
数据上传成功后,将显示一个新的发布地图按钮。点击它以发布您的地图。这就完成了!现在您的地图可在互联网上访问。切换到服务选项卡以获取标准查看器、移动查看器、WMS 服务(同一链接可用于 WFS)和 Web 界面管理面板的 URL。
如果需要,我们可以轻松地更新已发布的地图;例如,我们可以更改图层符号,或隐藏或显示一些属性或作曲家,等等。为此,只需打开包含基于云图层的项目,进行必要的更改,然后按照以下步骤发布地图:
-
如果尚未激活,请激活 QGIS Cloud 插件。
-
切换到QGIS Cloud面板中的账户选项卡,并使用您的用户名和密码登录。
-
现在切换到服务选项卡,然后点击发布地图按钮以发布更新后的地图。
没有必要再次上传数据,因为所有数据都已在前一次上传,并且我们的项目现在包含来自 QGIS Cloud 数据库的图层,而不是本地文件。
在 QGIS 和浏览器中查看您的地图
已发布的地图可以在 QGIS 和浏览器中查看。根据您的需求,使用其中一个可能更好。如果您只需要查看地图和一些基本的 GIS 功能,例如地图导航、要素识别和打印,基于网页的查看器是一个不错的选择。此外,基于网页的查看器也是与他人共享您地图的绝佳方式。
在浏览器中处理地图
QGIS Cloud 提供了两个网页查看器:一个用于移动设备(智能手机或平板电脑),另一个用于桌面。这两个查看器都提供了相同的基本功能,例如地图导航和更改图层可见性。让我们更详细地了解一下它们。
标准桌面查看器基于 QGIS Web 客户端,它看起来像是一个在浏览器中运行的简单 GIS 应用程序,如下面的截图所示:

左侧有一个图层树,您可以在其中更改图层的可见性,如果有的话,还可以启用或禁用背景地图。在右侧,我们可以找到属性数据面板(默认情况下隐藏),它用于显示有关已识别要素的信息。其余的空间由地图视图本身占据。
在前面的截图中,您可以看到一个带有导航按钮的工具栏、识别工具、测量长度和/或面积的工具体,以及打印地图按钮。导航、识别和测量工具的工作方式与 QGIS 中的相应工具类似。
标准查看器最有趣的功能是地图打印。如果发布的项目包含作曲家,它们可以用于制作打印地图。要创建此类地图,使用导航工具将视图缩放到感兴趣的区域,然后点击打印地图按钮。将出现一个打印设置对话框,并在地图上显示一个选择矩形,如下所示:

通过移动和调整矩形的大小来定义您想要打印的区域边界。然后使用浮动的打印设置面板选择所需的地图布局、比例尺和分辨率。如果需要,定义地图旋转。当所有设置完成后,点击打印按钮以生成包含您地图的 PDF 文件。生成的地图将在新的浏览器窗口中打开,并可以保存到磁盘以供进一步使用。
如同其名,移动查看器针对使用移动设备(如平板电脑或智能手机)进行了优化。

所有的可用屏幕区域都用于显示地图。触摸屏上的按钮大且易于使用。要访问图层树,请按左下角的按钮。右上角的按钮允许您启用位置跟踪并设置一些其他选项,例如地图旋转、比例尺显示等。使用移动查看器,您无法访问打印地图功能。尽管如此,您仍然可以使用地图进行导航。查看器将跟踪您的位置并在位置改变时更新地图。如果需要,您还可以激活地图旋转,以便地图可以旋转以使其北方指向实际北方。
在 QGIS 中处理地图
如果您只需要对数据进行只读访问,基于 Web 的查看器就很好。当使用 QGIS 查看已发布的地图时,您将获得更多功能和灵活性。
注意
您可以使用发布的地图,不仅限于 QGIS,还可以使用任何 WMS 或 WFS 客户端。
默认情况下,每个发布的地图都可通过Web 地图服务(WMS)协议访问。因此,您可以使用它作为另一个地图的背景图层,或者借助 OpenLayers 和 Leaflet 等库将其嵌入网页中。
要将发布地图中的图层作为 WMS 图层添加到 QGIS 中,请执行以下步骤:
-
使用管理图层工具栏上的相应按钮或从图层菜单(图层 | 添加图层 | 添加 WM(T)S 服务器图层...)打开从 WM(T)S 服务器添加图层(s)对话框。添加一个新连接。
-
输入连接名称(最好使用有意义的名称)和地图的 URL。
-
从列表中选择创建的连接并点击连接。将出现可用发布的图层列表。如果地图图层已填写元数据,您将看到它们的标题和描述。
-
选择必要的图层并将它们添加到您的项目中。
注意,您只能添加由本地数据创建的图层。背景地图和用于发布地图的 WMS 图层不可用。如果您需要背景地图和/或 WMS 图层,请使用相应的插件或 QGIS 核心功能添加它们。
此外,如果作者允许,地图可以通过Web 要素服务(WFS)访问,甚至可以通过Web 要素服务事务(WFS-T)协议进行修改。要使用 QGIS 通过 WFS-T 访问地图,请执行以下步骤:
-
使用管理图层工具栏中的相应按钮或从图层菜单(图层 | 添加图层 | 添加 WFS 图层...)打开从服务器添加 WFS 图层对话框。
-
添加一个新连接。
-
输入连接名称(最好使用有意义的名称)和地图的 URL。
-
从列表中选择创建的连接并点击连接。将出现可用发布的图层列表。
-
选择必要的图层并将它们添加到您的项目中。
如果选定的图层具有更新、删除和插入功能,你可以使用 QGIS 编辑它们,就像编辑任何其他图层一样。所有更改将立即在发布的地图中可见。
删除未使用的地图
随着时间的推移,由于各种原因,一些地图变得不再必要。如果你不需要某些地图和数据,你会很高兴地知道,你可以删除它们,从而为新项目释放一些磁盘空间。
有几种删除未使用数据的方法:使用 QGIS Cloud 插件、从 QGIS Cloud 网络界面以及使用 DB Manager 或任何其他 PostgreSQL/PostGIS 客户端。它们工作方式不同,互为补充。
使用 DB Manager 删除图层
正如我们之前提到的,QGIS Cloud 使用 PostgreSQL/PostGIS 来存储空间数据。因此,我们可以轻松地使用 DB Manager 或任何其他 PostgreSQL 客户端(例如,pgAdmin)连接到数据库并删除未使用的表。
假设已经创建了 QGIS Cloud 数据库的连接,以下是使用 DB Manager 插件删除图层的必要步骤:
-
启动 DB Manager 插件。由于这是一个核心插件,默认情况下已激活,你可以通过转到 数据库 | DB Manager 来找到它。如果 数据库 菜单不存在,请确保已启用 DB Manager 插件。有关使用 QGIS 插件的信息,请参阅 第一章 的 通过插件扩展功能 部分,处理你的数据。
-
在数据库树中展开 PostGIS 项,找到你的数据库。
-
展开公共模式,找到你想要删除的表。
-
选择表,然后右键单击以打开上下文菜单。选择 删除 以从数据库中删除此表。
注意,你还需要在删除表后删除或更新相应的地图。有关此信息的更多信息,请参阅本章后面的 从网络界面删除地图 部分。
从 QGIS Cloud 插件中删除数据库
QGIS Cloud 插件不仅允许你创建数据库并发布数据和地图,还可以删除未使用的数据库。要删除现有数据库,只需按照以下步骤操作:
-
启动 QGIS 并激活 QGIS Cloud 插件,如果尚未激活。
-
切换到 QGIS Cloud 面板中的 账户 选项卡,并使用你的用户名和密码登录。
-
在 数据库 列表中找到你想要删除的数据库并选择它。单击 删除数据库 按钮,等待操作完成。
注意
请注意!目前,QGIS Cloud 插件允许你删除整个数据库,因此你将丢失存储在已删除数据库中的所有其他地图数据。请确保你有备份,或者查看本章前面的部分以了解如何删除单独的图层。
注意,插件会删除整个数据库,包括其中的所有数据。使用此已删除数据库创建的地图仍将列在您的账户中,但它们将是空的。要删除这些地图,我们需要使用下一节中描述的 QGIS Cloud Web 界面。
删除 Web 界面中的地图
使用 Web 界面,我们只能删除未使用的地图。与它们相关的所有数据都将保留。因此,这是一个补充方法,应该与已描述的方法一起使用。
要删除未使用的地图,请按照以下步骤操作:
-
打开浏览器并访问 QGIS Cloud 网站
qgiscloud.com。 -
使用您的用户名和密码登录您的账户。
-
点击顶部菜单中的地图链接。
-
定位要删除的地图,然后点击销毁。在确认对话框中确认您的操作。
记住,您只删除了地图。用于此地图的数据仍然在数据库中可用(前提是您没有首先删除数据库)。因此,如果您不需要这些数据,则需要删除数据库,除非它被其他地图使用。如果您使用相同的数据库来存储不同地图的数据,您可以使用如使用 DB Manager 删除图层部分所述的任何 PostgreSQL 客户端删除单独的图层。
摘要
在本章中,我们介绍了如何使用 QGIS Cloud 托管从 QGIS 在线发布我们的地图。我们看到了如何为发布准备项目,包括指定项目元数据、限制对某些图层和编者访问、隐藏图层属性以及定义允许的操作。此外,您还学习了如何从不同的程序访问已发布的地图以及如何管理您的 QGIS Cloud 账户。
在下一章中,您将开始熟悉 QGIS 的分析功能。您将了解的第一种分析类型是密度分析。
第五章:使用密度分析回答问题
我们经常需要处理大型且密集的数据集,其中存在大量重叠,并且特征之间存在显著的重叠。这些数据集在渲染时可能非常缓慢,因为它们包含数千甚至数百万个特征,并且由于重叠使得检测任何集群或分布模式变得非常困难。在本章中,你将学习到允许你通过显示特征密度而不是特征本身来以更易读和更快的速度可视化此类数据集的技术。在本章结束时,你将能够对你的数据进行密度分析并从密度图中提取信息。
在本章中,我们将探讨以下主题:
-
密度分析和热力图
-
使用 Heatmap 插件创建热力图
-
使用六边形网格映射密度
密度分析和热力图
密度图允许对研究区域内对象或事件浓度的视觉估计。此类地图对于评估研究区域内特征分布模式非常有用。当我们简单地将特征或事件的位置(例如,作为点)添加到地图上时,我们无法看到它们在不同区域的浓度变化。密度分析通过使用均匀的区域特征,如每英亩或每平方公里的特征计数,为我们提供了这种功能。
密度图使我们能够估计区域内某些特征的浓度。这有助于我们找到需要紧急反应或符合您标准的区域。热力图也有助于控制条件和它们的变化。
当映射的区域(例如,区域)具有不同大小时,密度图也非常有用。例如,如果我们想知道每个区域有多少人居住,我们只需要一个包含人口数据的序数图。根据此图,一个大的区域可能比一个小的区域人口更多。但如果我们想识别人口密度较高的区域,那么我们需要一个密度图来查看每平方公里的居民人数。而密度图将显示,实际上,人口密度高的较小区域可能比较大的区域每平方公里的居民人数更多。
通常,我们可以在地图上显示特征本身的密度分布(例如,学校),以及这些特征的某些数值特征的分布(例如,学校中的学生人数)。在这些情况下,结果将完全不同。学校的热力图可以帮助教育部门找到需要更多学校的地方,而来自每所学校学生人数信息的密度图可能有助于运输公司规划公交线路并决定在哪里设置公交车站。
最常见的用例是创建密度图以显示点要素的密度。此类地图通常被称为热力图。什么是热力图?它是一个栅格层。它的每个单元格都包含其附近要素密度的表示(例如,每平方公里的居民数),这取决于某个区域内要素的数量。
要创建热力图,在最简单的情况下,GIS 会查看单元格中心周围的要素,使用给定的搜索半径。然后计算给定半径内的要素数量,并将其除以该区域的面积。这个值将是单元格值。然后分析下一个单元格,依此类推。结果,我们将得到一系列值,这些值组合在一起形成平滑的表面。为了更好地理解,请参考以下图表:

此图表展示了创建热力图的一般原理。绿色圆点表示用于生成密度图的要素,蓝色方块是当前栅格单元格,红色虚线圆圈标记搜索半径,例如,1 公里。在这种情况下,覆盖的面积约为 3.14 平方公里。如图表左侧所示,有四个要素位于搜索半径内。因此,栅格单元格将获得4/3.14 = 1.27的值。在右侧,我们注意到下一个单元格将获得 1.59 的值,因为现在搜索半径内有五个要素。
这是最简单的方法。在实际应用中,使用更复杂的算法,其中每个点根据其与相邻单元格的距离对其值产生影响。
使用热力图插件创建热力图
在 QGIS 核心插件 Heatmap 的帮助下,我们可以轻松地从矢量点数据创建热力图,并用于进一步分析。首先,我们需要激活此插件,如果尚未激活。激活后,它将在栅格菜单下创建一个子菜单,并将按钮放置在栅格工具栏上。
让我们为包含关于高噪音水平投诉信息的noise图层创建一个密度图。此图层包含 44,397 个要素,很难知道哪些地方是噪音源。
对于警察部门或其他机构计划降低噪音的活动,或者对于寻找公寓且不想与喜欢大声播放音乐的邻居为邻的人来说,此类地点的信息可能很有用:
-
通过点击热力图按钮或导航到栅格 | 热力图 | 热力图...,开始使用插件。
![使用热力图插件创建热力图]()
-
从输入点层组合框中选择
noise图层。 -
使用输出栅格字段右侧的…按钮,指定结果热力图需要保存的位置。请注意,无需指定文件扩展名;它将根据输出文件格式自动选择。
-
使用输出格式下拉框选择热力图所需的格式。这里最常见的选项是GeoTIFF,但对于非常大的地图,最好使用不同的格式,例如Erdas Imagine。
-
我们最后需要指定的是半径。此值定义了 QGIS 将搜索邻居特征并考虑其存在的距离。通常,较大的搜索半径会给出更一般化的结果,因为找到的特征数量将除以更大的面积。较小的半径会给出更精确的结果,但如果此值太小,我们可能找不到任何分布模式。搜索半径可以用米或地图单位定义。
要从已知区域确定搜索半径,我们可以使用从圆面积公式推导出的一个非常简单的公式:

例如,如果我们需要计算每平方千米的密度,那么搜索半径将如下所示:

为了对结果有更精细的控制,我们可以勾选高级复选框并定义一些额外的参数:
-
行和列:这些允许我们定义输出栅格的尺寸。较大的尺寸将导致更大的输出文件大小,而较小的尺寸将导致粗糙和像素化的输出。输入字段是相互链接的,因此更改行字段中的值(例如,将其减半)也会导致列字段中的相应值发生变化,反之亦然。此外,这些值直接影响栅格单元格大小(参见下一点)。值得注意的是,在更改栅格维度时保留的栅格范围。
-
单元格大小 X 和 单元格大小 Y:栅格单元格大小决定了分布模式的显示将有多粗糙或多详细。较小的单元格大小将给出更平滑的结果,但分析所需的处理时间和内存将增加。较大的单元格将更快地处理,但生成的栅格将出现像素化。如果单元格真的很大,某些模式将变得不可见,因此您可能需要多次运行分析,尝试不同的单元格大小以获得满足您要求的结果。
单元格大小取决于并链接到栅格维度。增加它将减少行数和列数,反之亦然。
-
核形状:这控制了从该点距离的变化如何影响点的影响。QGIS Heatmap 插件目前支持以下核:
-
四次方(也称为双权重)
-
三角形
-
均匀
-
三重权重
-
Epanechnikov
以下图表显示了不同核函数的点影响分布:
![使用 Heatmap 插件创建热图]()
-
注意
关于核形状的更多详细信息,请参阅维基百科上的文章en.wikipedia.org/wiki/Kernel_(statistics)#Kernel_functions_in_common_use,以及关于统计学的书籍,例如 B. W. Silverman 的《统计密度估计》和《数据分析》。
根据核形状,我们将得到更平滑的热图,或者更清晰地显示热点。例如,三重权重核将比 Epanechnikov 核给出更清晰、更尖锐的热点,因为 Epanechnikov 核在热点中心附近的影响较低。此外,在不同的科学领域,人们通常偏好不同的核函数;例如,在犯罪分析中,通常使用四次核函数。
还可以通过选择使用半径字段复选框并从下拉菜单中选择具有半径值的属性字段来为每个点使用可变搜索半径。如果您需要通过某些数值属性对点进行加权(换句话说,增加或减少它们的影响),请激活使用权重字段复选框并选择相应的字段。在我们的例子中,我们不会使用此功能,但您可以自己尝试。
正如我们之前所说的,单元格大小直接影响最终热图的质量,因此选择它非常重要。在大多数情况下,单元格大小被选择为每单位面积 10 到 100 个单元格(这反过来又由搜索半径定义)。为了计算单元格大小,我们需要将面积单位与距离单位对齐;例如,如果我们使用平方公里计算密度并定义搜索半径为米,那么将平方公里转换为平方米是必要的。下一步是将面积除以所需的单元格数。最后,由于单元格大小由其宽度或高度定义(因为栅格单元格通常呈方形),我们需要提取这个值的平方根。
在我们的例子中,我们将创建一个搜索半径为 1000 米的热图,因此查找区域将大约是 3.14 平方公里。以米为单位表示如下:

由于我们希望热图平滑,我们将使用每单位面积相对较多的单元格数;比如说每 3.14 平方公里 100 个单元格。因此,我们将面积(平方米)除以所需的单元格数:

最后,我们计算这个值的平方根以得到允许我们在 3.14 平方公里内有 100 个单元格的单元格大小:

当然,这并不是一个严格的规则,而只是一个建议。您可以根据您的数据和期望的结果安全地使用另一个单元格大小。只需记住,较小的值会导致热力图更平滑,但同时也增加了分析时间和输出栅格的大小。
当所有输入和参数都设置好后,按下确定按钮以启动热力图生成过程。热力图形成的过程将在一个小进度对话框中显示。如果这个过程完成时间过长,您可以按中止按钮中断它。请注意,在终止热力图生成后,您仍然会得到输出,但它将是不完整且不适用于进一步分析的。
当过程完成后,生成的热力图将以灰度栅格的形式添加到 QGIS 中,其中较亮的区域对应于较高的密度值,较暗的区域对应于较低的密度值,如下所示:

为了提高可读性并使其看起来像真正的热力图,我们需要更改其样式。为此,请按照以下步骤操作。有关样式栅格层的更详细信息,请参阅第二章的为栅格层开发样式部分,可视化与样式化数据:
-
在 QGIS 图层树中右键点击
热力图层。在上下文菜单中,选择属性。 -
转到样式选项卡,并将渲染类型选择为单波段伪彩色。
-
在加载最小/最大值组中,激活最小/最大选项。将范围设置为全部,将精度设置为实际(较慢)。按下加载按钮以获取栅格统计信息。这将用于进一步的分类。
-
在生成新颜色图组中选择合适的颜色渐变,例如
YlOrBr(颜色从黄色变为橙色,然后变为棕色),或Reds(使用不同深度的红色)。如有必要,更改类别数量并点击分类按钮。 -
点击确定以应用更改并关闭属性对话框。
现在我们可以轻松地定位最热点(如果使用Reds颜色图,则颜色接近红色),甚至可以识别出在我们查看原始点层时不可见的某些分布模式:

现在我们可以轻松地定位最热点(如果使用Reds颜色图,则颜色接近红色),甚至可以识别出在我们查看原始点层时不可见的某些分布模式。此外,我们的热力图层显示得比用于创建此热力图的矢量图层要快得多。
检测“最热点”
有时,您可能不需要热图本身,而只是想找到热点——密度最高的区域——并在进一步的分析中使用它们。在 QGIS 中找到这样的区域并将其提取为矢量形式非常容易。
首先,我们应该定义阈值值,这将用于识别热点。作为一个起始值,我们可以使用我们热图中的最大像素值,然后根据我们的需求进行调整。
找到最大像素值的最简单方法是使用识别特征工具。在 QGIS 图层树中选择一个图层,激活识别特征工具,点击最直观的“最热”区域,并查看报告的值。在我们的热图中,这个值将是540.32。
如果我们直接使用这个值,我们无法找到所有重要的簇,因此这个值应该首先减小。所选值(与最大值相比)越小,找到的簇数量就越多。单独簇的面积也会增大。对于我们的示例,我们选择了一个200的值。
现在,从栅格菜单打开栅格计算器,在输出图层字段中指定输出文件应保存的路径,并在栅格计算器表达式字段中输入"heatmap@1">=200公式,如下所示:

这个公式用于创建所谓的掩码。如果输入层的像素值大于或等于我们的阈值200,则输出像素值将为1。否则,它将为0。因此,我们的输出栅格将是一个二进制栅格,只有两个像素值——0和1——这非常容易转换为矢量。
保持所有其他值不变,以便生成的栅格将具有与输入相同的精确尺寸和单元格大小。按下确定按钮开始计算。完成后,将在 QGIS 画布中添加一个新的黑白栅格图层,如图所示:

要将掩码栅格转换为矢量格式,我们需要从所有具有相同值的连接像素创建多边形。这就是多边形化工具发挥作用的地方。在处理工具箱中,您可以通过在工具箱顶部的过滤器字段中输入其名称来找到多边形化算法。双击算法名称以打开其对话框,您将看到如下内容:

选择之前创建的掩膜图层作为输入层,使用输出层字段指定结果保存的路径,然后点击运行按钮开始算法。完成后,将在 QGIS 中添加一个新的矢量图层。这个图层有一个名为DN(如果你没有更改它)的属性,表示图层中每个多边形的像素值。因此,我们只需要删除所有属性值等于零的要素。剩余的要素将是热点。
要从热点图层中删除不必要的特征,在 QGIS 图层树中选择它,右键点击打开上下文菜单,然后选择打开属性表。点击使用表达式选择要素按钮。在选择表达式对话框中,输入"DN" = 0(如果需要,将DN替换为你的字段名),点击选择按钮,并关闭对话框。通过点击切换编辑模式按钮或按Ctrl + E开始编辑。要删除选定的要素,按Delete键或点击删除选定要素。最后,通过按Ctrl + E或再次点击切换编辑模式来关闭编辑模式。

现在,热点图层只包含热点多边形,可用于进一步分析。例如,我们可以将这个簇与最近建筑物的信息和噪音类型的信息结合起来,以找到依赖关系并为此处降低噪音水平提出一些建议。
使用等高线寻找分布模式
除了检测热点外,热图还可以用于检测强度变化或可视化值变化的方向。完成这两项任务最常见的方法是生成等高线。
幸运的是,QGIS 拥有完成这项任务所需的所有工具。我们将再次使用处理工具,但等高线生成也可在GDALTools插件(可在栅格菜单中找到)中找到。在处理工具箱中,你可以通过在工具箱顶部的过滤器字段中输入其名称来找到Contour算法。双击算法名称以打开其对话框,其外观如下:

选择输入层为heatmap栅格图层。在输出文件字段中,指定结果保存的路径。同时,需要定义等高线之间的间隔。确定这个间隔没有严格的原则。一般规则是选择一个能够检测到密度变化平滑区域模式的间隔。我们将选择10的间隔。
当所有必要的信息都已定义后,点击运行以开始生成等高线。经过一段时间,一个新的多边形矢量层将被添加到 QGIS 中,我们可以开始分析它。首先,如果需要,将等高线层移动到 QGIS 图层树中热图的顶部。此外,调整等高线的符号以使其在热图背景中更易于识别也是更好的选择。

更密集的等高线对应着更强烈的密度变化。此外,我们还可以识别噪声变化的方向。例如,在先前的屏幕截图中,我们可以看到在某些地方,围绕中心的噪声分布并不均匀;东南部的强度比西北部更快地降低。因此,我们可能假设那里有一些噪声障碍物。
使用六边形网格映射密度
还有另一种映射密度的方法,称为分箱。一般来说,分箱是将N个值/特征分组到M个组中的技术,其中M < N。这种操作的成果可以解释为二维直方图。
分箱是热图的替代方案,而不是替代品。方法的选择取决于结果的要求和进一步的使用。然而,值得注意的是,分箱产生矢量输出,而热图产生栅格输出。
通常,分箱可以描述为两个简单的步骤:
-
在点层之上创建一个六边形网格。
-
计算每个网格单元格中的点数。
在本节中,您将学习如何在 QGIS 中通过六边形分箱的示例使用这项技术,换句话说,就是使用六边形网格映射密度。
注意
实际上,对于分箱,我们不仅可以使用六边形,还可以使用其他允许对二维表面进行规则镶嵌的形状——三角形和矩形。
为什么我们选择六边形?因为六边形是所有镶嵌形状中最接近圆形的。因此,它们更自然地表示曲线。六边形的另一个优点是结构更紧凑,因此六边形网格中单元格中心之间的距离比矩形网格中的距离更短。因此,围绕单元格中心的数据聚合更有效率。
注意
在第八章中,我们将创建一个模型,该模型生成两个密度图:六边形和矩形,以便您可以并排比较它们,更好地理解它们的不同用途和用例。
在接下来的章节中,我们将使用这种方法创建一个密度图。为此练习,我们将使用布鲁克林街道树木普查的数据。这是我们地图中的trees层。
创建六边形网格
要创建六边形网格,我们将使用 QGIS 处理框架及其名为创建网格的算法:
-
在处理工具箱中,通过在工具箱顶部的过滤器字段中输入其名称来找到创建网格算法。双击算法名称以打开其对话框,其外观如下:
![创建六边形网格]()
-
在网格类型组合框中,选择六边形(多边形)。
-
要指定网格范围,请按…按钮,该按钮位于网格范围字段的右侧,并从菜单中选择使用图层/画布范围。
-
选择范围对话框将弹出。使用它从组合框中选择
trees图层,然后点击确定。layer范围坐标将被添加到字段中。 -
将水平间距和垂直间距设置为
1000。这些值与热图中的搜索半径具有相同的意义。网格间距决定了网格中会有多少个单元格以及生成的地图将有多平滑。较小的间距会产生更平滑的结果,但非常小的值会阻止我们识别任何分布模式。请注意,间距应与图层使用的单位相同;例如,如果图层 CRS 使用英尺作为单位,则间距也应为英尺。 -
最后,在输出字段中指定结果网格的保存路径,并点击运行以创建网格。当算法执行完成后,一个新的多边形图层将被添加到 QGIS 中。
在网格单元格中计数点
要计算每个网格单元格内的要素数量,我们可以使用 fTools 或处理核心插件。后者更灵活,允许我们自动化任务,如第八章所述,使用处理模型自动化分析。我们将使用处理框架中的计数多边形中的点算法。
小贴士
在处理中还有一个计数唯一点算法,它允许我们只计算所选字段中具有唯一属性的点。当需要更精确的分析时,这可能很有用,例如,用于绘制多样性地图。
在处理工具箱中,通过在工具箱顶部的过滤器字段中输入其名称来找到计数多边形中的点算法。双击算法名称以打开其对话框,您将看到如下内容:

选择上一节创建的网格图层作为多边形,并将trees图层作为点。输入计数字段名称或保持不变。不要忘记形状文件字段名称的 10 个字符限制!最后,在结果字段中指定结果图层将存储的位置,并点击运行按钮以开始分析。请记住,这可能需要一些时间,因为tree图层包含许多要素,而网格大小相对较小。
当算法执行完成后,一个新的网格层将被添加到 QGIS 中,其中包含每个单元格中点的数量字段。我们可以安全地从 QGIS 和文件系统中删除原始网格层,因为它不再需要。
为了更好地展示我们的数据,我们根据单元格中的要素数量应用渐变渲染器来样式化单元格。如果需要,请回到第二章的为矢量图层开发样式部分,可视化和样式化数据。结果可能看起来像这样:

删除冗余数据
如果我们仔细观察我们的网格层及其属性表,我们会发现一些网格单元是空的;它们里面没有点。这些单元在前面的截图中被显示为非常浅的绿色。很明显,空单元的数量远多于非空单元。当然,我们可以简单地通过将它们分配与地图背景相同的颜色或从渲染器中移除它们(分配一个空样式)来隐藏这些空单元。但是,完全移除它们并减小文件大小是否更好?
有两种可能的删除空单元的方法:手动或使用处理工具箱中的现有工具。每种方法都有其自身的优点。
首先,你将学习如何手动删除冗余数据。当您只需要处理一个图层且不想创建任何临时中间文件时,可以使用此方法。此外,它允许您轻松检查将要删除的要素。让我们来做:
-
从 QGIS 图层树中选择
LAYER图层。然后,点击属性工具栏中的使用表达式选择要素按钮以打开按表达式选择对话框。![删除冗余数据]()
-
在函数树中,在字段和值组下,找到
NUMPOINTS字段,并双击它以将其名称添加到表达式中。 -
然后,点击=以将等于运算符添加到表达式中,并在其后输入
0。最终的表达式将看起来像"NUMPOINTS" = 0。 -
点击选择以选择所有符合您条件的要素。选定的要素将以黄色突出显示,以便您可以检查它们是否是您想要的。
-
现在,关闭按表达式选择对话框,通过点击属性工具栏中的打开属性表按钮来打开图层属性表。
-
通过在属性表对话框中点击相应的按钮或简单地按Ctrl + E来切换编辑模式。
-
要删除选定的要素,只需按Delete键或点击删除选定要素按钮。
-
最后,再次按Ctrl + E来关闭编辑模式。现在我们的图层只包含非空单元,并且大小大大减小。
使用处理移除冗余数据比手动移除冗余数据需要更少的步骤,但它不会更新现有图层,而是创建另一个文件。当你需要一次性处理多个图层或想要自动化某些操作时,处理框架非常有用。为了移除空单元格,我们可以使用按属性提取算法。
小贴士
在我们的案例中,比较条件非常简单,所以我们使用按属性提取算法。当需要更复杂的比较条件,包括多个属性或某些计算时,最好使用按表达式选择算法并结合保存所选要素。

这里是必要的步骤:
-
通过在过滤器字段中输入其名称来查找按属性提取算法,并双击其名称以打开其对话框。
-
在输入图层组合框中,选择
LAYER。 -
在选择属性组合框中,选择
NUMPOINTS字段,该字段存储每个单元格中的点数。 -
在运算符组合框中选择不等于运算符 !
=. -
在值字段中输入
0。 -
在输出字段中指定输出文件的名称。
现在,我们可以按下运行按钮开始处理。完成后,新的图层(移除了空单元格)将被添加到 QGIS 中,我们可以移除原始图层。新的图层要小得多,但仍然包含所有信息。此外,我们现在可以更精确地设置样式,并识别出之前不可见的某些分布模式。

如果我们将具有这种密度的街道网络图层叠加到这个密度图上,我们可以轻松地识别出最绿色的街道是 Ocean Parkway。
结果看起来很棒,但手动执行所有这些步骤并不舒服。此外,还有许多中间图层可以,也应该被移除。幸运的是,QGIS 允许我们通过处理图形模型器自动化此类操作。请参阅第八章,使用处理模型自动化分析,了解如何创建模型并使用它们。
摘要
在本章中,我们介绍了密集点数据集的分析。你学习了如何借助 QGIS 热图插件创建栅格热图。然后,我们介绍了热图分析和从其中提取数据。
你还熟悉了一种用于显示密集数据集的替代且流行的技术,称为分箱,并学习了如何在 QGIS 中使用处理框架执行六分箱(一种分箱技术)。
第六章. 使用可视性分析回答问题
可视性分析是 GIS 分析中的一个宝贵部分,它回答了诸如“从这个位置点可以看到什么?”等问题。在本章中,您将通过定义提供该区域最佳景观视角的屋顶以及潜在观景平台的位置,接触到可视性分析的基本知识。在整个章节中,您将学习以下内容:
-
准备数据以表示城市景观特征
-
选择潜在的观测点
-
计算可视域以找到最美丽的点
-
在 3D 场景中展示结果
在我们开始之前,我们将探讨一些可视性分析的基本原则。
可视性分析的基本原理
可视性分析的目标是从指定位置生成一个可见区域的覆盖。这个覆盖称为可视域,这就是为什么使用可视性分析和可视域分析这两个术语可以互换的原因。要执行简单的可视性分析,您至少需要定义以下两个组件:
-
观测点:代表观察者位置且正在分析可视性的点
-
DEM:这代表地球表面的不规则性,并用于检查视线方向上的可视性
这种分析背后的思想是将观测点的海拔高度与给定视线方向上的地球表面点的海拔高度进行比较。如果表面点的海拔低于观测点,则从当前位置可以看到它;如果它更高,则可视线路径将被阻挡。同样,所有在一定半径内的点都与观测点进行比较,并分为以下两类:
-
可见,高度低于观测高度且位于可视线下方
-
不可见,高度高于观测高度且位于可视线上方
可视性分析的主要输出是一个二元真/假可视域覆盖,通常包括可见点并排除不可见点。根据所使用的算法和 GIS 的能力,可以通过以下特性和输出修改和改进这种基本分析方法:
-
与单一观测点不同,可以使用多个点甚至线条
-
可以分析几个物体之间的可视关系,然后生成互视覆盖作为输出
-
相反,对于当前观测点的可视域评估,可以分析地球表面以提供有关可以从特定位置看到某些物体的点和区域的信息
-
地平线线可以建模为可视区域累积边缘
-
视野可以由水平或垂直视角或方位值限制,这些值限制了可视线的延伸
-
地球的曲率和大气折射可以考虑到模拟更真实的结果
可视性分析最典型的实际应用是在通信塔的放置中,而不是可视性,而是模拟信号穿透。视域在领土和城市规划中也非常有用。例如,一些特征,如工厂或垃圾填埋场,由于外观不雅,预计将不会被人眼看到。在这种情况下,该区域将进行可视性分析,以找到无法看到这类物体的地方。与某个点相关的盲点越多,对物体的位置就越有利。此外,除了隐藏某些物体外,视域还用于检测提供该区域最壮观景观的景观点。然后,这种知识被用于最佳放置观景点,这正是我们将在本章中要做的。
第 1 步 – 将建筑矢量图层转换为栅格
我们将处理一个高度城市化的景观,其主要特征已经受到人类的极大改造。在可视性分析的情况下,这意味着视线主要被建筑物阻挡,而原始的地形特征只扮演了较小的角色。在我们的数据集中,我们有两个图层描述感兴趣的区域、外观和特征:
-
lidar_dem:这仅代表裸地,并提供了地形的一般描述 -
building_footprints:这些是多边形,描绘了所有建筑物,并且它们还包含有关建筑物在裸地表面以上英尺高度的信息,这些信息存储在height_roo属性字段中
我们需要添加它们的值以获得有意义的结果,但这些图层使用不同的数据模型:DEM 是栅格覆盖,而建筑足迹是矢量多边形图层。这就是为什么在添加之前,我们应该首先将图层转换为单一的共同数据模型。在 GIS 中,覆盖物的计算通常使用栅格代数进行,这意味着 building_footprints 矢量图层应该转换为栅格,或者进行栅格化。此外,如果我们想使这个栅格层包含有关建筑高度的数据,应使用 height_roo 属性字段作为 Z 值的提供者。
同样重要的是,新建建筑足迹的栅格应该与 lidar_dem 具有相同的范围和分辨率。要获取有关 lidar_dem 的这些信息,请转到 图层属性 | 元数据。在窗口底部,您将看到 属性 滚动窗口部分,其中包含所有重要的信息,以便与栅格一起工作,即 波段 1(统计数据)、维度(行数和列数)、原点(左下角的坐标)等等。对我们特别感兴趣的参数如下:
-
像素大小:这包含像素边的垂直和水平长度。通常,这些值相等,这意味着像素是正方形;但有时,它可以是矩形,具有不等的值。
-
图层范围(图层原始源投影):这表示栅格范围的水平和垂直(x)和垂直(y)的最小和最大值,即栅格边界框在图层原始坐标参考系统中的北部、南部、东部和西部限制。
下面的截图显示了lidar_dem层所描述的参数:

要将图层栅格化,请转到栅格 | 转换 | 栅格化(矢量到栅格)。在对话框窗口中,调整以下参数:
-
输入文件(shapefile):这是一个要栅格化的 shapefile。从下拉列表中选择
building_footprints。 -
属性字段:这定义了一个要烧录到输出栅格中的值属性字段。从下拉列表中选择
HEIGHT_ROO。 -
输出栅格化矢量文件(栅格):在此字段中有两个可能的选项。您可以选择一个已存在的文件,并且具有所选值的矢量几何足迹补丁将被烧录到其中。如果您例如有一些原始栅格层中的空隙,并希望用矢量层中的某些值(如水体的高程和水面)填充它们,这将非常方便。但我们必须处理建筑物相对于裸地面的相对高度。这意味着,为了与 DEM 汇总,建筑物足迹应作为单独的图层进行栅格化。导航到您的工作目录,并输入
building.tif作为新的图层名称。您将看到此消息:输出文件不存在。您必须设置输出大小或分辨率才能创建它。单击确定并继续到下一阶段:![步骤 1 – 将建筑矢量图层转换为栅格]()
-
在前面的步骤中,您定义了一些主要选项。由于我们需要创建一个与
lidar_dem.tif具有完全相同范围和分辨率的栅格,我们将通过编辑gdal_rasterize命令行参数使用高级选项:-
单击编辑
按钮以使线条可编辑。所有先前的选项都将被禁用并变灰。 -
删除
–ts 3000 3000选项,因为我们将指定一个分辨率参数,这使得由–ts定义的栅格宽度和高度参数变得没有意义。 -
–init 0参数定义了输出栅格的初始值。它创建一个具有预先定义值的空栅格,然后矢量值被烧录到其中。在我们的情况下,这意味着无建筑区域将被分配为零值。 -
目标范围由
–te参数定义,该参数使用地理参照单位中的空格分隔的边界框值(Xmin、Ymin、Xmax和Ymax)描述。如果您想使用预定义的范围,只需从相应的栅格元数据中复制其值。别忘了将逗号和分号替换为空格。 -
目标分辨率(
–tr)参数定义了以图层 CRS 指定的单位表示的垂直和水平像素大小。 -
输出数据类型由
–ot参数定义,其默认值为Float64,但我们将其替换为Float32,这与lidar_dem.tif相同。
-
生成的行将如下所示:
gdal_rasterize -a HEIGHT_ROO -l building_footprints -init 0 -te 982199.3000000000465661 188224.6749999999883585 991709.3000000000465661 196484.6749999999883585 -tr 10 10 -ot Float32 fullpath/building_footprints.shp fullpath/building.tif
注意
要将矢量转换为栅格,我们使用了来自地理空间数据抽象库(GDAL)的名为gdal_rasterize的工具。您可以从www.gdal.org/gdal_rasterize.html阅读gdal_rasterize参数及其值的扩展说明。
点击确定后,生成的栅格将被创建并添加到地图画布上。如果您选择识别特征工具并点击任何像素,将显示建筑的高度值;如果您点击空白区域,将显示0。该图层看起来将与以下截图相似:

步骤 2 – 合并 DEM 和建筑图层
现在,我们需要通过添加它们的值将两个图层合并为单个图层。栅格代数是叠加栅格层(或多个层)的常用方法,通过代数运算(加法、减法、乘法、除法等)组合它们的值,并计算新栅格层的值。现代 GIS 软件使用所谓的栅格计算器,有助于创建、验证和应用栅格代数表达式到栅格数据集中。
QGIS 还有一个位于栅格 | 栅格计算器的自己的栅格计算器。计算器对话框窗口由以下部分组成:
-
栅格波段:在窗口的左上角,您可以查看项目中所有可用栅格的列表。栅格波段号通过
@符号与其名称分开。如果图层是单波段栅格,则列表中只出现name@1,但如果它是多波段栅格,则对于每个波段将分别显示name@1、name@2,等等,直到name@n(其中n是多波段栅格中的波段总数)。 -
结果图层:在计算器窗口的右上角,您可以调整输出栅格属性。当前图层范围按钮从左侧栅格波段列表中当前选定的栅格图层设置输出范围。当您处理具有不同范围的图层时,这非常有用,并允许您决定使用哪个范围。
-
运算符:在窗口的中央部分,有各种运算符按钮,可以用来构建表达式。点击相关按钮添加运算符,或者手动输入。
-
栅格计算器表达式:在计算器的底部部分,有一个表达式窗口,其中显示了要使用的计算公式。双击相关图层将其添加到表达式中(它将以双引号显示)。请注意,对于表达式,我们只输入计算公式的右侧,即等于号之后的部分。在表达式下方,您将看到表达式有效/无效消息动态更改,这有助于您控制构建公式的正确性。
在以下屏幕截图中,您可以看到我们应用了一个简单的加法公式("building@1" + "liadar_dem@1")来合并栅格化的建筑高度和 DEM 图层:

点击确定按钮后,计算将被执行,并在图层面板中显示一个新的urban_surface栅格图层。现在,我们可以使用识别特征工具检查其值
:
-
除了
urban_surface、building和lidar_dem之外,取消选中所有不必要的图层。保持它们的顺序简化了识别结果的解释。 -
转到识别结果选项卡。从模式下拉列表中选择自上而下。识别的值将按顺序显示在所有活动图层中,从上到下。
-
从视图下拉列表中选择表格。识别的值将被组织成一个简单的表格,如图所示:
![步骤 2 – 合并 DEM 和建筑图层]()
现在,通过点击地图画布上的任何一点,您可以探索值并确保它们已被正确添加。
第 3 步 – 定义观测点
观察点在现代城市景观的视觉探索中起着重要作用。通常,它们由一个区域内最高的点表示,提供最壮观的视野。因此,城市中的观景平台通常位于屋顶上。在本节中,我们将通过以下步骤创建一个包含几个潜在观景平台的图层:
-
创建一个空矢量图层
-
用代表最高建筑的点填充它
-
从
buildings_footprint图层提供高度信息
创建一个空矢量图层
要创建一个矢量图层,转到图层 | 创建图层。这里有三种选项可用:
-
新 Shapefile 图层:也可以通过Ctrl + Shift + N键盘快捷键访问,这会创建一个新的空 shapefile 图层。
-
新建 SpatiaLite 图层:也可以通过Ctrl + Shift + A键盘快捷键访问,这将在指定的 SpatiaLite 数据库(默认情况下为当前连接的数据库)内创建一个空的 SpatiaLite 图层。
-
新建临时擦除图层:这创建了一个临时图层,可以在工作会话中像任何其他图层一样使用和分析,但如果在关闭项目之前未保存,该图层将消失。这些图层旨在作为草稿,用于测试目的可以防止项目变得杂乱。我们将使用此选项创建一个空图层。
类似地,您可以使用管理图层工具栏中的相关按钮以及其旁边的小三角形来访问选项,如图所示:

在选择新建临时擦除图层后,您将看到此对话框:

考虑新建临时擦除图层窗口中的选项,如下所示:
-
图层名称:输入一个名称或保留默认设置,因为我们打算将图层用于临时工作,其名称实际上并不重要。
-
类型:这定义了几何类型。由于我们将设置观测点,因此默认的点选项是合适的。
-
所选 CRS:已选择默认投影,但您需要设置项目投影,以便正确处理图层。为此,从下拉组合框中选择项目 CRS选项。
点击确定后,将在图层面板中添加一个新擦除图层。默认情况下,图层的编辑模式被激活(您可以在图层名称旁边的标记符号上方看到一个小铅笔,如图所示)。现在我们可以继续到下一阶段,并向其添加一些点。

用点填充图层
如果尚未激活,请激活数字化工具栏。您可以通过转到视图 | 工具栏 | 数字化,或者简单地通过在工具栏面板上的某处右键单击并激活相关切换来完成此操作。该工具栏包含主要的数字化工具,外观如下:

此面板的按钮提供以下选项的访问权限(从左到右):
-
当前编辑:这将在所选图层(或图层组)的当前编辑会话中保持编辑。点击按钮右下角的小黑三角形以访问保存、回滚或取消选项。请注意,这些选项在点击保存图层编辑按钮之前都是可用的。
-
切换编辑:此按钮激活/停用编辑模式。
-
保存图层编辑:此按钮用于保存所有当前编辑而不退出编辑会话。点击此按钮后,无法撤销编辑。如果没有要保存的编辑,则此按钮不可用。
-
添加要素:使用此按钮在图层上绘制新的要素。其外观取决于图层的几何类型。目前,它显示为点,因为你正在编辑一个点图层。
-
移动要素:当选择此按钮时,你可以移动一个或多个要素。重要的是要注意,如果你打算移动多个要素,它们应该事先被选中。
-
节点工具:此工具用于添加、删除或移动几何要素(如线和多边形)的顶点。对于点图层来说是不必要的,因此不可访问。
-
删除选中项:这将删除之前选中的要素(或要素)。在保存编辑之前,可以通过当前编辑按钮选项撤销这些编辑。
-
剪切/复制/粘贴要素:与其他类型的软件类似,你可以使用这些按钮将要素剪切或复制到剪贴板,然后粘贴。如果你想要应用这些选项,要素必须事先被选中。虽然剪切和粘贴仅在编辑模式下可用,但复制可以在任何其他图层中使用,当在图层之间移动要素时非常有用。
小贴士
你还可以使用更复杂的数字化工具和选项,例如要素旋转、简化、添加部分和环等。这些工具在高级数字化面板中可用,如下面的截图所示:
![用点填充图层]()
此外,面板还提供了类似于在计算机辅助设计(CAD)系统中使用的输入工具。这些工具允许使用精确的坐标、距离和角度数值进行数字化;控制线段;平行性和垂直性,如下面的截图所示:
![用点填充图层]()
现在你已经熟悉了数字化工具栏、切换编辑以及使用添加要素,点击不同的地方以定位一些观测点。请记住,这些点应该放在最高建筑的底部。建议使用之前创建的urban_surface栅格作为背景,因为它有助于正确定位这些点。现在,通过点击地图画布添加几个点(五到七个就足够了)。点击切换编辑按钮退出编辑模式。当被询问编辑时,点击保存按钮。结果,你的地图将类似于以下截图:

提供具有高度值的点
由于我们将在屋顶上定位观测平台,考虑到建筑的高度对于获得逼真的建模结果非常重要。我们不会寻找必要的建筑及其高度并手动将高度值添加到可见性点,而是将自动连接属性,考虑到点的位置。这种操作——当你基于两个不同图层之间的空间关系合并属性时——在 GIS 中非常常见,被称为空间连接。
前往矢量 | 数据管理工具 | 通过位置连接属性。在对话框窗口中,有以下选项:
-
目标矢量图层:将连接属性的图层;在我们的案例中,它是新临时图层。
-
连接矢量图层:从中提取属性的图层;在我们的案例中,它是
building_footprints。![提供具有高度值的点]()
-
属性摘要处理可用于连接的多个属性值。取第一个定位特征的属性选项连接单个值,这是我们默认选择的行为。可选地,您可以激活取交集特征的摘要并选择一个或多个汇总函数(平均值、最小值、最大值等)。
-
输出 Shapefile提供了结果矢量图层的路径。点击浏览按钮选择必要的目录并输入名称,例如,
观测点。 -
输出表负责结果属性表中的记录数量。我们保留默认选中的仅保留匹配记录选项,因为我们只需要与观测点匹配的建筑记录。
点击确定并完成空间连接后,您将被告知已创建了一个新图层,并被询问:“您想将新图层添加到目录中吗?”点击是,图层将被加载并显示在地图画布上。点击关闭按钮退出通过位置连接属性对话框。
现在,如果您打开观测点属性表,您将看到所有来自building_footprint图层中匹配建筑的属性都已连接到这些点。当处理大量实体时,此工具可能非常有用。
第 4 步 – 创建视域覆盖
在本节中,我们将应用视域分析插件提供的先进可见性分析工具。按照第一章中通过插件扩展功能部分所述进行安装,处理您的数据。
安装插件后,您可以通过转到插件 | 视域分析来访问其功能。高级视域分析对话框包含三个选项卡。常规选项卡提供对所有可用分析和输出选项的访问。参考选项卡包含选项的简要描述以及到项目主页的链接,您可以在那里阅读有关插件中实现的算法的详细信息,并在必要时报告错误。关于选项卡包含有关作者和插件主页的简要信息。
在常规选项卡下使用以下选项来创建视域覆盖,如图中所示:
-
高程栅格:选择
urban_surface栅格来表示地球表面及其上的建筑物。 -
观测点:选择
observ_points点层。 -
输出文件:点击浏览按钮,导航到工作目录,并为输出栅格图层输入一个名称。请注意,每个观测点将创建一个输出栅格文件,输入的文件名将用作模板,该模板将与输出覆盖类型(视域、互视、不可视和地平线)和索引号一起使用。因此,我们称输出层为
coverage,假设解释参数(覆盖类型和点数)将自动添加。我们的目标是找到风景最美的点(或多个点),因此没有必要分析点的互视性。因此,省略了目标点(互视性)字段。
-
搜索半径:这是在图层测量单位(在我们的例子中是英尺)中围绕图层中的点观测的区域大小。值越高,生成覆盖所需的时间越长。接受默认值 5000。
-
观测者高度:这定义了观测点相对于地球表面的高度。通常,点越高,观测效果越好。而不是选择预定义的高度,从字段下拉列表中选择
HEIGHT_ROO。 -
目标高度:当您想知道从当前位置是否可以看到特定高度的目标物体时,这是必要的。我们省略了这个选项,因为我们更感兴趣的是一般可见性,而不是特定物体的可见性。
-
适应距离内的最高点:此选项在定义的像素区域内找到观测者或目标附近的最高点。当您的观测点提供近似位置,并且需要将它们的高度值调整到周围区域内的最高点时,这可能非常有用。因为我们已经有了精确的高度值,所以此选项将被省略。
-
输出:这可以通过以下覆盖表示:
-
二值视域:这是一个简单的栅格覆盖,其中所有像素值都被分配为
0(不可见)或1(可见)。激活此选项以创建视域。 -
不可见深度:这衡量了一个物体在放置在一个看不见的区域时应该达到的大小,以便变得可见。换句话说,它定义了物体在给定半径内变得可见所需的高度单位数。输出栅格是一种倒置的可见性栅格,其中所有可见像素都被分配为 0 值,所有不可见像素都被分配为负高度值(值越低,物体越不可见)。
![步骤 4 – 创建视域覆盖]()
-
互视性:输出将是一个代表观测点之间视觉关系的网络形状文件。在输出网络中,可以相互看见的点被连接起来。
-
地平线:输出栅格覆盖表示地平线或可见区域的边缘。
可选地,而不是创建多个覆盖,可以创建一个单一的累积栅格,该栅格总结了栅格覆盖以概括分析结果。然后,将
0值分配给不可见像素,将正值分配给可见像素(值越高,表示从多个观测点可见的像素)。 -
-
使用地球曲率选项:这考虑了地球的曲率和光在穿过大气层时的折射效应。激活此选项并接受默认的
0.13折射值。调整完所有选项后,点击确定按钮,等待结果加载到地图画布上。
同样,您可以创建地平线单独的覆盖。结果,总共将添加 18 个栅格覆盖到地图画布上:
-
coverage_N_Binary:一个二进制可见性栅格,其中N是观测点的数量 -
coverage_N_Horizon:一个表示点N的地平线的栅格
在以下屏幕截图中,您可以查看同一观测点的二进制可见性(在左侧)和地平线(在右侧)覆盖的示例组合:

步骤 5 – 寻找景观点
现在,我们应该遍历所有观测点和相应的覆盖,调整它们的可视化选项,并选择提供最佳区域视图的点(或多个点)。
首先,我们需要适当地列举这些点,以便能够区分它们。按照以下步骤进行:
-
通过右键单击上下文快捷方式从
observ_points中选择打开属性表,或者点击属性工具栏中的对应按钮
。 -
从表工具栏中选择打开字段计算器
,或者使用Ctrl + I键盘快捷键。 -
在字段计算器对话框窗口中,激活更新现有字段选项,并确保从下拉列表中选择
OBJECTID属性字段,如以下截图所示。此字段已包含从building_footprints图层合并的值。这些值与点数无关,这就是我们使用更新选项将现有值更改为一致值的原因。 -
在表达式选项卡中,展开包含对记录标识符进行操作的函数的记录组。选择并双击要添加到表达式窗口的$id函数。此函数返回当前行的要素 ID,这将帮助我们正确识别点和相应的覆盖范围。
点击确定按钮。编辑模式将自动开启,并更新记录的值。
![步骤 5 – 寻找景观点]()
-
从表格工具栏切换到编辑模式
或使用Ctrl + E快捷键退出编辑模式。系统会询问您是否要保存对observ_points图层所做的更改。点击保存按钮并关闭属性表。 -
双击
observ_points图层以打开其图层属性对话框窗口。在标签部分,激活使用以下选项标签此图层选项,并选择OBJECTID字段进行标签。如有需要,调整任何其他标签选项,然后点击确定以退出窗口。当观测点被标签化后,分析它们及其视域将变得更加容易。
现在,我们将调整可见图层符号以简化其解释。让我们从最基本的地方开始——点号0。按照以下步骤以获得有意义的结果:
-
激活
coverage_0_Horizon和coverage_0_Binary图层,并关闭所有其他可见图层。确保这些图层位于observ_points之下。激活在分析可见性时可能感兴趣的任何其他图层(例如,urban_surface、roads等),并确保它们位于可见栅格之下。 -
调整
coverage_0_Horizon图层样式。此图层只包含两个值:1代表地平线(即可见区域的边缘),0代表所有其他区域。在图层面板中双击其名称以打开图层属性对话框,转到样式部分,并调整以下参数:-
从渲染类型下拉列表中选择单波段伪彩色。
-
将颜色插值设置为精确,因为我们只有两个值,希望它们被分配到所选颜色。
-
使用
按钮手动添加必要的值。输入0并双击其颜色样本。在更改颜色窗口中,从标准颜色中选择黑色,并使用不透明度滑块将透明度设置为25%。点击确定按钮返回到主要样式选项。 -
再次添加一行,值为
1,并为其分配一个明亮、对比度高的颜色,以便在地图上区分地平线线。在标签字段中输入值的解释性名称。你的颜色表应该类似于以下截图:
![步骤 5 – 寻找风景点]()
-
-
通过双击图层面板中的图层名称打开
coverage_0_Binary属性对话框,并转到透明度部分。我们将使用自定义透明度选项和透明像素列表来根据它们的值调整像素的透明度属性。二值可见性栅格只包含两个值:1表示可见区域,0表示不可见区域。要将这些值添加到列表中,点击
,手动添加值按钮。列表中会出现新的一行。在那里,你应该手动输入从和到的值,并调整或接受默认设置为100的百分比透明度值。由于我们将使用值而不是范围来设置透明度,从和到的条目将是相同的:-
在第一行,输入
1并接受 100%的透明度。 -
再次点击
以添加下一行,在从和到中输入0,并将透明度设置为25%。结果,你的透明像素列表将看起来像这样:
在完成所有必要的调整后,点击确定按钮以应用它们。 -
-
为其他点的图层应用相同的样式选项。而不是逐个处理每个栅格,右键单击并导航到样式 | 复制样式以复制从
coverage_0_Horizon和coverage_0_Horizon预先配置的视觉选项。然后,转到样式 | 粘贴样式以将它们插入适当的图层。
如果覆盖范围被正确可视化,我们只需要在考虑几个标准后,通过视觉解释它们并做出关于最佳点的决定。首先,一个点应该为广阔的区域提供视野,这可以通过二值覆盖来分析;对观察者开放的面积越多,越好。其次,地平线线应该清晰、坚固,尽可能不被伪影破坏。可见边缘的完整性确保了全景视图,这可以通过地平线覆盖来分析;线条越直、越简单,越好。
最后,您始终应考虑由景点、开放空间和其他可能的兴趣点所代表的本地特征。关于纽约市的布鲁克林区,有几个您可能听说过的显著特征:布鲁克林大桥和布鲁克林大桥公园所在的水域。这个区域以其美丽的日落和令人敬畏的曼哈顿和东河景观而闻名。考虑到所有这些标准,第 7 点可能是最佳选择。它不仅提供了该区域南部和东北部的景观,而且几乎完全包括了水域,如图所示:

当选择最佳视图的获胜者后,我们可以进行下一步,并可视化分析结果。我们不会以传统的制图方式表示它们,而是将利用三维可视化的力量,这在处理城市景观时非常有用。
第 6 步 – 在 3D 中设置结果
在本节中,我们将利用Qgis2threejs插件的强大功能,将我们的数据以 3D 场景的形式呈现。按照第一章中“通过插件扩展功能”部分所述,安装此插件,即“处理您的数据”。此插件依赖于three.js库。它允许我们直接将地形数据、地图画布图像和矢量数据导出到网页浏览器中。因此,您可以在支持 WebGL 的网页浏览器中查看和探索导出的对象,就像 3D 场景一样。
安装完成后,该插件可在Web菜单下的Qgis2threejs菜单中找到。有两个可用的子菜单:
-
设置:这负责定义一个将用于打开生成的 3D 场景的浏览器。如果您想使用默认浏览器,则不应更改这些设置。
-
Qgis2threejs:这是插件的主窗口,它提供了对其一般功能的访问。在窗口的左侧,您可以查看所有可用控制参数和项目图层列表。窗口的右侧提供了对它们的设置和更改的访问,这取决于左侧选中的项目。
首先,您需要调整将用于生成覆盖地形的图像的地图图层。在这个例子中,我们激活以下从下到上的图层:water_area、parks、roads和coverage_7_Binary。您始终可以添加更多图层,甚至可以使用预定义的 WMS/WFS 或 OpenLayers 插件覆盖,例如 OpenStreetMap。这些活动图层将被用于提供背景地形。
注意
在以下部分,我们将仅探索插件的基本设置,这些设置对于从训练数据生成有意义的结果是必要的。有关参数的扩展帮助和描述可在github.com/minorua/Qgis2threejs/wiki/ExportSettings找到。
在 3D 场景的一般设置上工作
一旦所有必要的图层都处于活动状态,请通过以下选项调整场景的一般设置:
-
模板文件:在此,您可以从下拉列表中选择不同的输出模板。使用默认的3DViewer(dat-gui).html选项,因为它不仅生成 3D 场景,还添加了一个控件参数面板来调节图层可见性和不透明度以及自定义水平平面的垂直移动。
-
世界:此项目负责 3D 世界中场景的一般外观。我们特别感兴趣的是垂直放大参数,因为它定义了地形外观的复杂性。值越大,地形反映的地形特征就越明显。此外,此值还影响所有矢量 3D 对象的Z位置以及某些具有体积(点和挤出多边形)的对象类型的 3D 对象高度。默认值设置为
1.5,但我们的兴趣区域有一个平面地形,其值变化平滑,因此我们输入2以使高度变化更加明显。 -
控件:有两个可用的控件选项,附有描述。保持默认的
OrbitControl.js不变。 -
DEM:从可用的栅格DEM层下拉列表中选择
lidar_dem,它将用于提供关于该区域高度的实际信息并生成具有预定义垂直放大的地形。有几个部分提供参数来调节 DEM 外观:-
重采样块负责生成的表面分辨率,并提供各种调整选项。在本教程的目的下,我们将简单地将滑块移动到第四个刻度,这将输出分辨率接近 400 x 400 像素,并将原始 DEM 重采样到大约 26.8 英尺。这种方法速度快,生成的输出轻量,但重采样值会影响 DEM 的分辨率,而不是覆盖其上的纹理。如果您想生成更复杂和高分辨率的成果,请阅读有关高级设置的说明,但请记住,高分辨率输出需要更多时间来导出,而且场景本身也需要更多的计算机资源来保持响应和快速渲染。
-
显示类型:接受所有默认设置,假设使用地图画布图像作为纹理。
-
边框和框架:接受默认的构建边框选项。它为 DEM 添加侧面和底部。
-
-
附加 DEM:如果您想结合包含某些Z值(例如,绝对高度和坡度,热图等)的两个栅格,此选项可能非常有用。由于我们主要对建筑和二值可见性栅格感兴趣,此选项被省略。
调整观测点的 3D 可视化
展开窗口左侧的点项,以查看所有可用的点层,并激活observ_point。在窗口的右侧部分,调整以下设置:
-
对于对象类型,接受默认的球体值。观测点将在 3D 空间中以球体表示。
-
将Z 坐标模式设置为+"HEIGHT_ROO",这意味着点的海拔高度将根据以下公式获得:z = 顶点海拔 + 字段值 + 加数 = DEM + HEIGHT_ROO。换句话说,我们只总结了地形的海拔和某一点的建筑高度,没有其他值(加数设置为 0,并排除在公式的第二部分)。因此,该点将考虑局部地形并代表观察者的真实垂直位置。
-
样式部分负责符号的视觉属性:
-
从下拉列表中将颜色设置为随机,球体将被随机分配颜色。
-
在透明度下接受默认的特征样式选项。这将使点变得实心,而不是透明的。
-
由于我们希望所有球体具有相同的大小,我们在半径下接受固定值。在值字段中输入
50。
-
-
现在,让我们考虑与地图画布范围相交的特征。使用此默认选项,只有显示在地图画布上的特征将被导出。
-
属性和标签部分提供了访问标签选项的权限:
-
激活导出属性以启用标签。所有属性将在您在 3D 场景中单击相关对象时导出并显示。
-
从标签字段下拉列表中,选择用于标签的
OBJECTID字段。 -
标签高度选项定义了标签从球体的高度。在此处,我们从下拉列表中选择从点高度选项,并将值设置为
100。
-
以下截图显示了定义所有参数后窗口的外观:

调整建筑轮廓的 3D 可视化
展开窗口左侧的多边形项,以查看所有可用的多边形层,并激活building_footprints。在窗口的右侧,将设置更改为以下截图所示:
-
对象类型:将其设置为拉伸。这意味着二维多边形足迹将被表示为三维平行六面体。
-
模式: 将此设置为 相对于 DEM。这意味着建筑的高度将通过以下公式获得 z = 顶点高程 + 加数 = DEM。换句话说,因为我们没有使用任何额外的值,并且高度设置为 0,所以建筑物的相对高度将仅依赖于 DEM。
-
高度: 将此设置为
HEIGHT_ROO。与之前的设置一起,此设置使得显示建筑物时能够展示其真实高度,相对于从数字高程模型(DEM)获得的绝对高度。![调整建筑物足迹的 3D 可视化]()
完成所有这些设置后,点击 浏览 按钮以指定输出场景的路径和名称。然后点击 运行。当场景生成后,它将自动加载并在你的默认网络浏览器中打开,你可以使用之前定义的控件来可视化地探索分析结果,如图所示:

摘要
在本章中,你接触到了可见性分析的基础,包括输入数据准备、可见点创建以及生成和解释可见性覆盖,以便找到最佳的观测点。此外,你还学习了如何通过逼真的 3D 模型来展示你的结果,这在城市数据的视觉探索及其分析结果中非常有用。
在下一章中,你将学习如何通过空间分析来定义一个完美的位置。
第七章。使用适宜性分析回答问题
我们生活在一个充满各种关系的世界上,这些关系可以在功能、时间或空间背景下进行分析。在 GIS 中,空间关系尤其引人关注,因为在这里,空间中的对象以便于解释和分析其地理关系的方式表示。适宜性分析是 GIS 分析的基本部分,它回答了“某物最佳位置在哪里?”的问题。在本章中,你将通过寻找最佳居住地来了解适宜性分析的基本原理。你将学习如何:
-
解释对象之间的空间关系
-
通过空间数据表达这些关系
-
根据一组预定义的标准分析空间数据
-
叠加图层并解释结果
在开始本章之前,将解释适宜性分析的一些基本原理和对象之间空间关系的类型。
适宜性分析基础
适宜性分析被认可为一种多标准决策支持方法。换句话说,其主要目的是根据一组预定义的标准将感兴趣的区域分为两类:适用于某种用途(居住、建筑、保护等)和不适用。用于适宜性评估的一般方法是多层叠加,支持多标准决策。根据表示适宜性标准和叠加的数据,有两种基本方法可用:
-
使用向量数据的适宜性分析。这主要利用缓冲区等操作,并通过向量叠加操作(如裁剪、交集和并集)的顺序组合。
-
使用栅格数据的适宜性分析。这主要依赖于栅格代数,它用于重新分类初始栅格覆盖,然后将其组合以产生二进制或排序适宜性栅格。这种方法更灵活,因为它使得产生多个适宜性类别并根据其代表因素的重要性改变栅格权重成为可能。因此,用户能够产生复合结果,但工作流程需要更多与数据预处理和整合决策相关的努力。
以下表格总结了使用向量和栅格数据的适宜性评估的主要地理处理阶段、优点和缺点:
| 向量数据 | 栅格数据 | |
|---|---|---|
| 主要地理处理和分析操作 |
-
缓冲区
-
裁剪叠加
-
交集叠加
-
并集叠加
|
-
向量数据栅格化
-
临近栅格创建
-
栅格重分类
-
栅格代数加法
-
栅格代数乘法
-
栅格代数减法
|
| 优点 |
|---|
-
工作流程的快速性
-
工作流程的简单性
-
人工特征的优良表示
|
-
简单数据重分类
-
连续特征的优良表示
-
可能存在清晰和模糊的类别
-
根据其重要性对不同的覆盖范围进行加权
-
可能进行各种评估,如二元、排序和加权
|
| 局限性 |
|---|
-
只提供清晰的类别
-
通常只提供二元(是/否)评估
|
-
重新分类和排序的主观性
-
工作流程复杂性
|
无论你将遵循哪种方法,一般适宜性分析的工作流程涉及几个共同步骤。我们现在将更深入地探讨它们,以确保更好地理解适宜性分析系统:
-
定义分析的目标和目标:要研究的问题被一般性地表述,并确定其应用意义,这将成为后续的适宜性标准集合。一些流行的适宜性应用包括以下内容:
-
农业:评估特定作物种植区域的适宜性。
-
零售:从市场营销的角度评估区域——它是否会吸引新客户或买家。在选择理想的购物地点时,这种分析需求很大。
-
可再生能源:评估风力发电站或太阳能电站的用地适宜性是地理空间规划领域可持续性方面的一个显著趋势。
-
自然保护:通过栖息地适宜性建模优先考虑保护需求,并将区域划分为对某些物种生存和繁殖或多或少有价值的地点。
通常来说,适宜性分析的主要应用领域是土地利用规划,旨在对有限空间和自然资源内各种人类活动进行合理优先排序。
-
-
分析可用数据并定义其与目标和目标的相关性:定义数据与目标和目标的相关性。分析当前数据可用性和未来数据需求,特别是了解当前数据衍生品是否可用于分析。例如,如果我们必须分析农业需求的适宜性,DEM(数字高程模型)可以是一个很好的来源。它不仅提供了关于地形的基本信息,还提供了一些有用的衍生信息,如坡度和方位。这一阶段的主要成果是列出主要数据来源及其潜在衍生品。
-
定义分析的标准:这是最重要的阶段,分析的目标被描述为基于相关数据的清晰数值标准。描述性目标被翻译成 GIS 分析的语言。在这个阶段,分析对象之间各种类型的空间关系被分析,其中一些最流行的关系包括以下内容:
-
点对点关系:
"在...范围内":所有距离居住地 1 公里范围内的学校
"最接近于":离居住地最近的小学
![适宜性分析基础]()
“是...点关系”示例
-
点到线关系:
“最近”:距离地铁站入口最近的街道
![适宜性分析基础]()
“最近点”点到线关系示例
-
点到多边形关系:
“包含于”:所有位于一定社区边界内的公立学校
![适宜性分析基础]()
“包含于”点到多边形关系示例
-
线到线关系:
“穿越”:特定小径是否穿越道路
“在...内”:查找距离特定河流 1 公里范围内的所有小径
“连接到”:查找连接到特定高速公路的所有街道
-
线到多边形关系:
“相交”:查找被自行车道穿越的所有区域
“包含”:查找完全位于某个区域内的所有街道
![适宜性分析基础]()
“相交”线到多边形关系示例
-
多边形到多边形 关系:
“完全包含”:查找完全位于危险区域内的所有区域
“最近”:查找距离公园最近的大楼
![适宜性分析基础]()
“完全包含”多边形到多边形关系示例
-
-
主要分析和准备数据:数据根据先前阶段定义的准则进行分析。常见的分析操作包括按位置选择、缓冲区、栅格化、邻近度(栅格距离)等。所有必要的图层准备就绪后,应准备进行叠加,这涉及到(如果需要)重新投影到共同的坐标系,设置各种排名的范围,并在共同的排名系统中进行重新分类。所有图层应包含统一单位的值,否则它们的叠加将没有意义且难以解释。
-
叠加数据并解释结果:根据用户定义的规则,先前准备好的图层基于一组规则合并成一个单一覆盖。根据可用数据和应用的规则,以下适宜性评估是可能的:
-
二元适宜性评估:整个区域被划分为适宜和不适宜的类别。这是从矢量数据叠加中可以获得的最简单类型的评估。
-
排序适宜性评估:根据预定义的全部标准范围,将地点从最不适宜到最适宜进行排序。此类评估可以从矢量和栅格数据中得出。它让您避免简单的是/否评估,这些评估并非现实世界的固有属性。这种优势被数据排名的主观性和各种因素同等重要性的缺点所抵消。然而,在现实世界中,它们对整体评估的贡献可能会有所不同。
-
加权适宜性评估:这与之前类型的评估类似,只有一个显著的不同点:根据某种活动的不同重要性,各种因素可以有不同的权重。这种评估依赖于栅格代数方法,被认为是全面的,但并非没有主观性,尤其是在因素权重和解释最终结果方面。
-
在接下来的章节中,我们将逐一介绍这些阶段,并对居住进行加权适宜性评估,结合训练数据集中的各种数据类型。
第 1 步 – 定义我们分析的目标和目标
在本教程中,我们将假设我们代表一对年轻夫妇及其小孩进行工作。他们正在寻找一个理想的生活地点,位于他们感兴趣的区域之内。我们的目标是利用基于 GIS 的适宜性分析方法,为他们的问题提供客观和可靠的答案。
本分析的目标是找到符合有小孩年轻家庭的区域,考虑到某些因素。他们的许多要求与传统住宅开发公司的要求相似。例如,地铁站、绿化区和公共安全必须全部考虑在内。还有一些家庭特有的要求需要考虑。如前所述,这个家庭有一个小孩,这意味着我们应该考虑附近是否存在早教或小学。此外,他们热衷于运动,如果他们将要居住的区域有发达和活跃的休闲基础设施那就更好了。经过这样的审查,我们可以制定一些更具体的要求和目标:
-
安全性:该区域不应暴露于各种自然和犯罪风险
-
连通性:应与城市的交通网络良好连接
-
绿色和开放性:它应该靠近公园或其他绿色区域
-
教育潜力:早教或小学应位于附近
-
积极休闲机会:包括自行车网络和体育设施
-
文化生活:艺术画廊和博物馆可以被视为文化脉搏跳动的一般标志
现在主要目标和要求已经明确,我们可以进行下一步,研究所有可用数据,以评估其对我们例子的相关性。
第 2 步 – 分析可用数据并定义其相关性
一旦我们定义了基本要求,就需要探索对我们分析可能有用和相关的数据层。训练数据集包含大量数据集,其中最相关的是以下表格中列出的:
| 要求 | 图层 | 可能的相关性 |
|---|---|---|
| 安全性 | hurricane_evacuation_zones |
飓风疏散区是可能因飓风风暴潮的生命和安全隐患而需要疏散的城市区域。 |
hurricane_inundation_zones |
飓风淹没区是风暴潮淹没最严重的区域。 | |
noise_heatmap |
在第五章的使用 Heatmap 插件创建热图部分中创建的栅格,使用密度分析回答问题,显示了已注册噪音投诉的空间密度,可能有助于对公共安全的潜在评估。 | |
| 连通性 | subway_entrances |
地铁入口的位置。 |
| 绿色和开放性 | parks |
包含开放空间特征(如法院、跑道、公园等)的层。 |
tree_density |
这是一个由树木普查数据创建的栅格层。 | |
| 教育潜力 | elementary_schools |
这些是基于官方地址的学校点位置。该层包含一些关于学校的基本信息,例如名称、地址、类型和校长的联系方式。 |
| 活动休息机会 | bike_routes |
城市中自行车道和路线的位置。 |
athletic_facilities |
该层包含体育设施及其一些基本信息,包括主要运动类型、表面、尺寸等。 | |
| 文化生活 | museumart |
博物馆和艺术画廊的位置。 |
这些层主要被定义为最适合我们的分析,因为它们与指定的要求直接相关,但其中大部分以简单的几何原语或密度栅格覆盖表示,难以直接解释为适宜性标准。在下一阶段,我们将探索它们的主要属性,包括属性,并尝试根据对象之间各种类型的空间关系制定具体和可衡量的标准。
第 3 步 – 定义分析标准
根据hurricane_evacuation_zones的描述,有六个区域,按风暴潮影响风险在属性字段区域中排序,区域1是最可能被淹没的区域。在飓风或热带风暴的情况下,这些区域的居民可能会被命令疏散。区域值为X的区域不在任何疏散区。区域值为0的区域包括以下任何一种:水域、小码头或无人居住的岛屿。为了分析目的,这个层应该被栅格化并根据飓风影响风险排序,排名值从不在任何疏散区的区域到最可能被淹没的区域递减。
hurricane_inundation_zones多边形层包含有关风暴潮淹没风险的category属性字段信息,其中值为英尺单位的海拔高度。最有可能被淹没的区域被分配值为1,而排除在淹没建模之外的区域被分配值为5。这个层应该被栅格化和排序,以最高潜在适宜性值对应排除区域,最低值对应1类区域。
noise_heatmap栅格层是一个应该使用几个类别进行排序的栅格,最不适宜的值对应最嘈杂的地方,反之亦然。这里的好事是,我们不需要像之前那些层一样栅格化这个层。同时,确定排名的数量和范围将使我们的评估带有主观性。tree_density层,也是一个密度栅格,应类似进行分析。
其他选定的层应首先分析其邻近性。为此,我们首先将它们栅格化,然后创建连续的邻近栅格,最后根据邻近值(物体越近,适宜性值越高)对它们进行分类排序。同样,在用户排名的情况下,我们无法避免评估中的主观性。此外,最终的邻近栅格可以根据其在整体适宜性评估中的重要性进行加权。
第 4 步 - 分析和准备数据
原始数据的主要分析方法有三种。这些方法取决于初始数据类型和可用的属性:
-
栅格化和排序分类矢量层:这些层已经包含了所有必要的值,在准备阶段,所有这些层都应栅格化到相似的范围和分辨率。同时,它们的类别应正确排序,最高值对应最适宜的区域,反之亦然。这些层的例子包括
hurricane_evacuation_zones、hurricane_inundation_zones等。 -
排序密度栅格:这些是从连续覆盖转换为分类值的栅格热图,其中最高值表示最适宜的区域,最低值与最不适宜的区域相关。这些层的例子包括
noise_heatmap和tree_density。 -
生成和排序邻近栅格:这是最繁琐的工作流程。首先应将矢量层栅格化,然后创建邻近栅格并正确排序。这一类别包括以下矢量层:
subway_entrances、parks、public_schools、bike_routes、athletic_facilities和museumart。
注意,对于最终输出,我们始终会有按顺序排列的唯一值光栅,最高值表示最合适的区域。此外,所有输出光栅共享一个共同的范围也很重要,这对于它们与光栅计算器和整体适宜性评估的正确叠加是必要的。
在接下来的章节中,我们将通过光栅图层示例来介绍之前提到的流程。一旦你掌握了原理,你将能够独立准备其他图层。
光栅化和对分类矢量图层进行排序
在这个例子中,我们将处理hurricane_evacuation_zones图层。我们特别感兴趣的属性是zone。这是因为通过这个属性,区域被优先考虑进行疏散。具有最低值1的区域最有可能被疏散,反之亦然。在这种情况下,我们可以直接使用这些值来对光栅进行排序。我们已经在第六章,使用可见性分析回答问题,步骤 1 - 将建筑矢量图层转换为光栅部分中进行了光栅化。这次,我们将遵循相同的程序。
阻碍我们直接进行光栅化的一个因素是,用于光栅化的属性字段应该是数值型的。如果你查看属性下的字段部分中的属性字段,你会看到字段区域具有类型 QString,并且包含数字 1-6 和字母(X)的值被解释为符号或字符串的序列,而不是数字。这就是为什么这个字段无法用于光栅化,并且首先应该将其转换为数字。这可以通过字段计算器轻松完成:
-
使用右键单击打开属性表快捷方式或点击属性工具栏中的相关按钮
来打开图层的属性表。在属性表工具栏中,要么点击打开字段计算器按钮,要么使用Ctrl + I键盘快捷方式。 -
首先,我们应该去除无法解释为数字且无法转换为数字的
X值。由于我们只有一行包含X值,我们只需通过点击属性表工具栏中的
按钮切换编辑模式。双击单元格并手动输入新的7值。如果你有多个值需要更改,你可以在字段计算器中使用以下表达式来更改某些区域字段的值:CASE WHEN "zone" = 'X' THEN '7' ELSE "zone" END。 -
点击
按钮打开如图所示的字段计算器对话框窗口,并进行以下调整:-
确保已开启创建新字段切换按钮。
-
手动输入输出字段名称,例如,
rank。 -
从输出字段类型列表中选择整数(整数),因为我们打算使用短整数进行排序。
-
将输出字段宽度减少到
1。这是因为排序值不超过 10,我们不希望通过产生超过实际数据值的字段长度来创建多余的数据。
-
-
在表达式字段中,我们需要输入一个函数,该函数将用于创建新字段的值。在函数列表中,展开转换项,并双击toint函数。根据其描述,它将字符串转换为整数。如果值无法转换为整数(例如,
123asd是无效的),则不会发生任何变化。双击后,函数将以一个开括号添加到表达式中,之后你应该在双引号中输入(或双击从字段和值添加项)要转换的字段名称,然后关闭括号。在我们的例子中,生成的表达式将是toint( "zone" )。 -
点击确定按钮后,新字段将出现在表格末尾。取消编辑模式,确认保存编辑,并退出属性表窗口。
![光栅化和排序分类矢量图层]()
图层已准备好进行光栅化。通过访问栅格 | 转换 | 光栅化(矢量到栅格)打开一个对话框窗口。在此对话框窗口中,如以下截图所示,调整以下设置:
-
从输入文件(shapefile)下拉列表中选择
hurricane_evacuation_zones。 -
从属性下拉列表中选择
rank。 -
在输出文件的栅格化矢量(栅格)中,点击选择按钮。导航到您的当前工作目录,并将新图层名称输入为
hurricane_evacuation_zones.tif。将显示此消息:输出文件不存在。您必须设置输出大小或分辨率才能创建它。点击确定并继续下一阶段。 -
在前面的步骤中,您定义了一些主要选项。为了方便起见,我们将使用
lidar_dem.tif作为模板,在本教程中使用相同的范围和分辨率创建栅格。点击
按钮以使gdal_rasterize命令行参数可编辑。修改后,行应类似于以下示例:gdal_rasterize -a rank -l hurricane_evacuation_zones –a_nodata 0 -te 982199.3000000000465661 188224.6749999999883585 991709.3000000000465661 196484.6749999999883585 -tr 10 10 -ot UInt16 fullpath/hurricane_evacuation_zones.shp fullpath/hurricane_evacuation_zones.tif这意味着输出栅格将包含来自排序属性字段的栅格化值。图层多边形外的区域将被分配一个值为
0,这将被解释为nodata。输出数据类型是 16 位无符号整数。 -
点击确定按钮。光栅化结果将显示在图层面板中。
![光栅化和排序分类矢量图层]()
hurricane_inundation_zones图层应以类似的方式进行预处理。该图层包含一些区域编号。这些可以解释为洪水风险的严重程度;也就是说,数字越高,风险越低。这意味着我们可以直接使用这些值进行排序。对于这个图层,gdal_rasterize命令行参数将如下所示:
gdal_rasterize -a category -l hurricane_inundation_zones -a_nodata 0 -te 982199.3000000000465661 188224.6749999999883585 991709.3000000000465661 196484.6749999999883585 -tr 10 10 -ot UInt16 fullpath/hurricane_inundation_zones.shp fullpath/hurricane_inundation_zones.tif
当结合使用时,这些图层可以根据自然灾害风险的严重程度提供基于适宜性的累积评估。
排名密度栅格
在密度栅格的情况下,我们可以使用在第五章的使用 Heatmap 插件创建热图部分中创建的现成的noise_heatamp.tif,并在使用密度分析回答问题中创建tree_density.tif图层。首先,我们将准备一个noise_heatmap.tif,其范围比我们在本章中工作的感兴趣区域大得多。要裁剪栅格图层,请转到栅格 | 提取 | 裁剪器:
-
从输入文件(栅格)下拉列表中选择noise-heatmap,这是要裁剪的栅格。
-
在输出文件中,点击选择按钮以设置输出文件的路径和名称,例如,
noise_heatmap_clip.tif。 -
在裁剪模式部分,有两种可能的模式:
-
范围是您可以手动输入边界框坐标或通过拖动地图画布的地方。使用这种方法设置输出文件的范围。只需记住,范围应超过由
zipcode_bound形状文件设定的感兴趣区域的边界。 -
如果掩膜层处于活动状态,您可以选择一个多边形形状文件,它将被用作裁剪边界。
在您点击确定按钮后,该图层将被加载到地图画布上。
![排名密度栅格]()
-
以下步骤应执行以评估其值范围,将其分为类别,并对它们进行排序:
-
双击
noise_heatmap_clip图层以打开图层属性窗口。在此窗口中,转到元数据部分。在对话框下方的属性窗口中探索,直到找到带有基本栅格统计信息的波段 1高亮行,如图所示:![排名密度栅格]()
-
我们将处理密度栅格,其值被解释为每像素面积内的噪声投诉数量。这个连续表面应分为类别,并且应根据投诉数量进行排序。为此,应设置一定的投诉临界值。没有官方认可的限制和要求,但我们可以将平均数据集值解释为某个临界值(它略大于 56,但我们将使用 50 以方便起见)。将值分为类别,并分配以下排名(投诉数量越少,排名越好):
类别 值范围 适应性排名 1 小于 50 5 2 50 到 100 4 3 100 到 150 3 4 150 to 200 2 5 大于 200 1 -
对于排名,转到栅格 | 栅格计算器,并在其对话框窗口中调整以下选项:
-
输入输出层路径和名称,例如,
noise_ranked -
选择
noise_heatmap_clip @1栅格波段,并点击当前图层范围按钮,以确保输出层将具有相同的分辨率和范围 -
在栅格计算器表达式窗口中,输入以下表达式:
("noise_heatmap_clip@1" <= 50) *5 + ("noise_heatmap_clip@1" > 50 AND"noise_heatmap_clip@1" <= 100) *4 + ("noise_heatmap_clip@1" > 100 AND "noise_heatmap_clip@1" <= 150) *3 + ("noise_heatmap_clip@1" > 150 AND "noise_heatmap_clip@1" <= 200) *2+ ("noise_heatmap_clip@1" > 200)*1
这个表达式意味着在括号中给出的某个范围内每个落在该范围内的像素首先被分配 1 个值,然后它通过括号外的某个乘数值进行排名。点击确定按钮后,重新分类的栅格将被加载到图层面板中。
![排名密度栅格]()
-
注意:由于排名,热图被反转;也就是说,最嘈杂的热点获得最低排名,而最安静的地方获得最高排名。
以类似的方式,我们可以为其他对我们适应性分析感兴趣的点对象创建和排名热图,即trees和museumart。
生成和排名邻近度栅格
以下将使用subway_entrances点矢量层为例来解释工作流程:
-
首先,该层应以常见的方式进行栅格化。
gdal_rasterize行将包含以下参数:gdal_rasterize -l subway_entrances -burn 1 -a_nodata 0 -te 982199.3000000000465661 188224.6749999999883585 991709.3000000000465661 196484.6749999999883585 -tr 10 10 -ot Byte fullpath/subway_entrances.shp fullpath/subway_entances.tif在输出层中,现有的点位置将通过像素值
1进行标记,而所有其他区域将被分配nodata值的0。 -
转到栅格 | 分析 | 邻近度(栅格距离)。此对话框生成一个栅格邻近度图,指示每个像素中心到最近的被识别为目标像素的像素中心的距离。目标像素是源栅格中其栅格像素值在目标像素值集中的像素。如果没有指定,所有非零像素将被视为目标像素。在对话框窗口中,调整以下参数:
-
从输入文件下拉列表中,选择
subway_entrances层。 -
在输出文件中,点击选择按钮并指定输出图层路径和名称,例如,
subway_entances_proximity.tif。 -
确保已激活距离单位参数并将其设置为GEO。在这种情况下,生成的距离将在地理坐标(英尺)中。
生成的参数行将看起来像这样:
gdal_proximity.bat fullpath/subway_entances.tif Ifullpath/subway_entances_proximity.tif -distunits GEO -of GTiff注意
将矢量转换为栅格时,我们使用了 GDAL 的一个工具。它被称为
gdal_proximity。你可以在www.gdal.org/gdal_proximity.html阅读关于gdal_proximity参数及其值的详细说明。![生成和排名邻近度栅格]()
-
-
邻近度栅格应分为离散的类别,并且应进行排名。为此操作,我们将使用栅格计算器。这里的主要问题是决定数量和正确选择排名的邻近度类别。最佳决策取决于所谓的步行半径,即人们愿意步行到的距离。通常,交通规划者观察到,大多数人似乎能够舒适地覆盖的步行距离——超过这个距离,乘客量会急剧下降——大约是 400 米(约 1300 英尺)。我们将应用这个 400 米规则将层值(最小为零,最大为 4988.71)分类为四个类别,以下排名:
类别 邻近度值范围(英尺) 适宜性排名 1 小于 1,300 4 2 1,300 到 2,600 3 3 2,600 到 3,900 2 4 大于 3,900 1 前往栅格 | 栅格计算器并调整主要选项。输入以下表达式以生成一个新的
subway_entrances_proximity_ranks栅格:("subway_entances_proximity@1" <= 1300) *4 + ("subway_entances_proximity@1" > 1300 AND "subway_entances_proximity@1" <= 2600) *3 + ("subway_entances_proximity@1" > 2600 AND "subway_entances_proximity@1" <= 3900) *2 + ("subway_entances_proximity@1" > 3900)*1
在下面的屏幕截图中,你可以看到连续(在左侧)和排名(在右侧)栅格可能的样子:

以类似的方式,你可以预处理其他需要从邻近位置进行分析的矢量图层,即公园、自行车路线、体育设施和小学。结果,你将拥有一组根据选定对象的邻近度进行分类的栅格图层。排名越高,对象越接近。一般来说,可以将 400 米(或 1300 英尺)的值应用于正确地排名栅格。
第 5 步 – 叠加数据和解释结果
现在我们已经准备好了叠加栅格并生成累积适宜性评估的所有条件。在下面的表格中,你可以看到按其一般适宜性重要性加权的完整图层列表。权重是介于 0 到 1 之间的简单系数,它们被用来正确地修改排名。
| No. | 栅格图层名称 | 栅格图层类型 | 排名最小值 | 排名最大值 | 权重系数 | 最大可能值 = 最大排名 * 权重 |
|---|---|---|---|---|---|---|
| 1 | athletic_facilities_proximity_ranks |
Proximity | 1 | 5 | 0.04 | 0.2 |
| 2 | bike_routes_proximity_ranks |
Proximity | 1 | 3 | 0.06 | 0.18 |
| 3 | hurricane_evacuation_zones |
Zoning | 1 | 7 | 0.16 | 1.12 |
| 4 | hurricane_inundation_zones |
Zoning | 1 | 5 | 0.16 | 0.8 |
| 5 | Museumart_ranked |
Density | 1 | 4 | 0.05 | 0.2 |
| 6 | Noise_ranked |
Density | 1 | 5 | 0.13 | 0.65 |
| 7 | Parks_proximity_ranks |
Proximity | 1 | 3 | 0.12 | 0.36 |
| 8 | Schools_proximity_ranks |
Proximity | 1 | 4 | 0.15 | 0.6 |
| 9 | subway_entrances_proximity_ranks |
Proximity | 1 | 4 | 0.06 | 0.24 |
| 10 | Tree_ranked |
Density | 1 | 4 | 0.07 | 0.28 |
| 总计 | 10 | 44 | 1.0 | 4.63 |
用于我们适宜性评估的表达式可以通过以下步骤构建:
-
所有由栅格图层表示的可用因素都应乘以其权重系数并汇总,如下所示:(factor_1weight + factor_2weight + factor_3weight + … factor_nweight)。这种评估给出的是总适宜性,由于获得的值没有相对于可能的最小值和最大值进行计算,因此难以解释。
-
为了便于解释,总适宜性评估可以分成最大可能值的总和。扩展公式将如下所示:(factor_1weight + factor_2weight + factor_3weight + … factor_nweight)/(factor_1_maxweight + factor_2_maxweight + factor_3_maxweight + … factor_n_maxweight)。结果,输出值范围将从 0 到 1,其中最大适宜性值接近 1。
-
可选地,结果可以乘以 100。然后输出值将是适宜性的百分比。
前往栅格 | 栅格计算器进行评估:
-
设置输出图层的路径和名称
-
从栅格波段列表中选择一个图层来设置当前图层范围,例如,
hurricane_inundataion -
在表达式窗口中,输入以下公式(如果您不确定值,请查看前面的表格):
( ( "athletic_facilities_proximity_ranks@1" * 0.04 + "bike_routes_proximity_ranks@1" * 0.06+"hurricane_evacuation_zones@1" * 0.16+"hurricane_inundation_zones@1" * 0.16+"museumart_ranked@1" * 0.05+"noise_ranked@1" * 0.13+"parks_proximity@1" * 0.12+"schools_proximity@1" * 0.15+"subway_entrances_proximity_ranks@1" * 0.06+"tree_ranked@1"*0.07) / 4.63 ) *1000
点击确定按钮后,生成的图层将被添加到地图画布上。适宜性栅格值的范围从 42% 到 96%。因此,它可以很容易地进行分类和解释。导航到图层属性 | 样式并调整渲染属性,如以下截图所示:

应用这些设置后,图层将如下所示:

我们可以使用这个栅格作为对我们感兴趣区域进行初步视觉适宜性评估的基础,或者进一步将其与其他图层结合,以确定与整个适宜性标准范围最匹配的确切区块。
在那种情况下,我们需要执行步骤的逆序:选择最适宜的区域,矢量化,并将最大适宜性的多边形与住宅生活区域叠加,以识别特别适宜的街区和建筑:
-
初始适宜性栅格应通过 90%适宜性限制分为仅两个类别。转到栅格 | 栅格计算器,定义输出栅格的路径和名称(例如
max_suitability)。在表达式窗口中,输入"suitability, %@1" >= 90。在下一页,你可以看到生成的图层仅包含两个类别:适宜(值为 1;分配给适宜性大于或等于 90%的区域),和不适宜(值为 0)。 -
现在我们需要将这些区域矢量化,以便能够使用它们查询矢量图层。通过转到栅格 | 转换打开多边形化(栅格到矢量)对话框,调整以下参数:
![步骤 5 – 对数据叠加并解释结果]()
-
从输入文件(栅格)中选择
max_suitability作为要矢量的栅格。 -
在输出多边形文件(shapefile)中提供输出形状文件的路径和名称,例如,
max_suitability_polygons。 -
激活字段名切换按钮,并接受默认的
DN值。此选项负责从初始栅格创建并填充具有类别值的字段。
![步骤 5 – 对数据叠加并解释结果]()
-
-
点击确定按钮后,生成的形状文件将被添加到图层面板。最初,该图层包含所有类别的多边形,而我们只对类别 1 感兴趣。为了选择和删除不必要的多边形,我们将使用使用表达式选择要素选项:
-
通过单击属性面板中的
按钮或从右键菜单中选择打开属性表快捷方式,打开max_suitability属性表。 -
在属性表工具栏面板中,单击使用表达式选择要素按钮,
,并输入以下表达式:"DN" = 0。点击确定后,满足条件的所有多边形将在属性表和地图画布上突出显示。 -
由于我们不需要这些多边形进行进一步分析,我们应该删除它们。在属性表工具栏面板中,单击
按钮切换编辑模式,或使用Ctrl + E键盘快捷键。现在我们可以使用
按钮执行删除所选要素,或者直接从键盘按下Del键。 -
在删除不必要的资料后,别忘了保存您的编辑(使用
或 Ctrl + S) 并取消编辑模式。在以下屏幕截图中,您可以看到该图层仅包含那些包含最大适宜值的多边形,这些值设置为 90%:
![步骤 5 – 对数据叠加并解释结果]()
-
-
现在,这个图层可以用来与其他矢量图层叠加,并分析对象之间的空间关系,正如在适宜性分析基础部分所描述的。例如,我们可以根据适宜性标准识别对我们可能感兴趣的主要住宅区的分区区域:
-
通过访问向量 | 研究工具 | 按位置选择来打开一个对话框。在这个对话框中,您首先应从下拉列表中选择要从中选择对象的图层—从选择特征在:下拉列表中选择
residential_zoning—如下所示:![步骤 5 – 对数据叠加并解释结果]()
-
在与特征相交的下拉列表中,选择
max_suitability_polygons,它将被用作选择器。 -
有几种叠加选择选项。激活包括与选择特征相交的输入特征。只有那些在查询掩码边界内或与之相交的多边形将被添加到选择中。点击确定按钮。您将在地图画布上看到以下结果:
![步骤 5 – 对数据叠加并解释结果]()
-
-
同样,您可以尝试另一种类型的查询并确定满足适宜条件的确切建筑物。在这种情况下,对话框将如下所示:
![步骤 5 – 对数据叠加并解释结果]()
点击确定按钮后,您将在地图画布上看到以下结果:
![步骤 5 – 对数据叠加并解释结果]()
注意这次,我们选择了完全位于最大适宜区域内的建筑物。因此,我们准备好为问题“哪个地方最适合居住?”提供一个坚实且具体的答案。
摘要
在本章中,您跟随了整个空间分析的全过程,从提出问题到提供具体的答案,即找到地图上的特定地点和对象。您探索了适宜性分析的一些基础知识,并了解了它是如何定义和解释对象之间的空间关系的。此外,您还探索了许多与数据预处理相关的操作:栅格化、重新分类、栅格代数性能等。最后,您回顾了基于叠加空间对象和分析它们之间空间关系的空间查询。
在学习时,逐步执行分析操作是好的,但如果您有大量数据且时间有限需要提供答案,那么您应该提高您分析的性能。这可以通过 QGIS 处理框架实现。它提供了访问数百个地理处理工具(从最简单的到最复杂的)。
在下一章中,我们将介绍 QGIS 处理,您将学习如何通过创建自己的仪器链(模型)来自动化空间分析流程。
第八章:使用 Processing 模型自动化分析
在本章中,您将学习如何使用 QGIS 处理框架中的图形模型器来创建模型并自动化复杂分析任务。我们将涵盖从创建模型到与其他用户共享模型的必要步骤。
在本章中,我们将讨论以下主题:
-
QGIS 处理框架
-
图形模型器
-
添加输入
-
实施工作流程
-
填写模型元数据和保存
-
编辑模型
-
共享模型
QGIS 处理框架
QGIS 处理框架(以前称为 SEXTANTE)是一个 QGIS 核心插件,它实现了一个强大的分析和地理处理环境,并为各种原生 QGIS 算法和第三方分析软件(如 GRASS、SAGA、Orfeo ToolBox 等)提供了一个用户友好的界面。
小贴士
如需了解更多关于 QGIS 处理框架的信息,请参阅 QGIS 用户指南:docs.qgis.org/testing/en/docs/user_manual/processing/intro.html。
Processing 用户界面由四个主要组件组成。每个组件都允许您以不同的方式运行算法。决定使用哪个组件取决于任务和分析类型。由于 Processing 插件默认激活,我们可以从 Processing 菜单访问所有其组件和功能,除了批处理界面:
-
工具箱:这是主要的 Processing 图形用户界面元素。它提供了对所有可用算法(按提供者或目的分组)的访问,并允许我们在单次传递和批处理模式下运行它们。Processing 工具箱有两种模式:简化(默认)和高级。在简化模式下,所有算法都放置在预定义的组中,并具有用户友好的名称,旨在帮助新手用户找到必要的工具。在高级模式下,算法按提供者分组。每个提供者代表某个分析包或程序,例如 GRASS、Orfeo ToolBox 等。此外,在高级模式下,我们还可以访问更多算法,因为一些特殊提供者仅在此模式下可用。在接下来的章节中,我们将假设工具箱是在高级模式下使用的。要激活高级模式,只需从 Processing 工具箱底部的组合框中选择高级界面。
-
历史管理器:此功能存储有关所有执行算法及其参数的信息,以便在必要时可以轻松地重现过去的行为。此外,所有错误、警告和信息消息都显示在此处。 -
批处理界面:此界面用于在多个数据集上运行单个算法。此界面仅从 Processing 工具箱中访问,并在 Processing 菜单中不可用。
-
图形模型器:这是通过将现有算法组合成一个单一的工作流程来创建新算法的工具。它允许我们轻松自动化涉及多个步骤的复杂分析。
在下一节中,我们将了解如何使用 Processing 图形模型器创建自己的模型以自动化分析任务。
图形模型器
正如我们在前面的章节中已经看到的,即使是简单的分析也可能需要多个步骤。在实际应用中,存在更多更复杂的任务,它们涉及并组合不同的分析过程。手动运行这些任务是一个耗时的过程,可能需要数小时才能完成。当你需要多次运行此分析,使用不同的输入数据或使用相同数据但不同设置时,事情变得更加糟糕和复杂。
这就是 QGIS 处理框架提供帮助的地方。它允许我们自动化重复的任务并创建涉及不同类型数据处理的新复杂算法。借助 Processing 工具箱中的图形模型器,我们可以轻松通过组合现有算法来创建自己的算法。创建的模型可以像任何其他 Processing 算法一样执行,甚至可以作为更复杂模型的一部分使用。
打开图形模型器有两种常见方式:
-
从菜单中,转到Processing | 图形模型器...。
-
使用 Processing 工具箱。确保 Processing 工具箱使用高级模式。转到模型组并展开它。在工具子组中,找到创建新模型项并双击它。
以下任何一种方法都可以打开Processing 模型器窗口,如图下所示:

Processing 模型器窗口可以分为以下主要区域:
-
工具栏:它提供了一些有用的操作,例如打开现有模型、保存和导出模型、帮助编辑器等。
-
输入和算法树:这些位于窗口的左侧,包含两个标签页:一个包含可用的输入,另一个包含可用的算法。值得注意的是,算法标签页支持与工具箱相同的算法显示模式:简化和高级。然而,请注意,此标签页中没有切换按钮来更改显示模式。如果您需要更改它,您应该在打开模型器之前在工具箱中完成。
-
工作区:用于显示模型结构。在这里,我们将放置我们的构建块并将它们相互连接。
模型的创建可以分为两个步骤:
-
定义输入:这意味着我们需要指定哪些数据对于分析是必要的。我们在这里定义的所有输入项都将作为算法参数在以后表示,用户将能够根据他们的需求设置它们。
-
定义工作流程:在此步骤中,我们建立输入项和算法之间的链接。换句话说,我们确定模型中的每个算法将如何使用其他算法的输入和输出。
让我们创建一个模型,使用分箱技术从点矢量层生成密度图,这在第五章的使用六边形网格映射密度部分中已有描述,使用密度分析回答问题。为了使这个例子更有用,我们将创建一个模型,不仅生成六边形密度网格,还生成方形密度网格。这样做是为了让您以后可以比较结果并选择您更喜欢的一个。
添加输入
模型创建的第一步是定义模型所需的输入。为此,我们应该遍历我们想要自动化的所有算法,并找出哪些输入项是必要的。必须记住,某些算法可能不需要单独的输入。它们将仅使用在先前步骤中获得的结果,或者换句话说,其他算法的输出。此外,某些输入可能并不重要,可以在模型中硬编码。
处理模型器支持以下类型的输入,这些输入可以在模型器窗口左侧的输入选项卡中找到:
-
数字:这用于整数和浮点值。添加时,必须指定允许的最小值和最大值以及默认值。
-
字符串:这是一个字符串字面量。只有一个额外的设置,即默认值。
-
布尔值:这是一个布尔值,通常用作复选框。必须指定默认状态:选中或未选中。
-
范围:这表示地理范围。
-
矢量层:这用于矢量层。如果需要,可以将支持的几何类型限制为可用类型之一,并使此输入可选。
-
栅格层:这表示 GDAL 支持的格式中的栅格层。它是可选的。
-
表格:这用于无几何表格,例如 DBF 文件。它是可选的。
-
表字段:这表示层属性表或无几何表的字段。必须指定从该字段中获取字段的父层。
-
文件:这用于表示文件和目录。
要添加输入,双击其名称。将打开一个参数定义对话框。其内容取决于输入类型,但所有输入类型都共有参数名称字段,其中必须指定至少输入的名称。当模型执行时,此文本将用作相应字段的标题。所有其他字段对于不同的输入都是不同的。
小贴士
添加输入或算法时,您也可以从输入/算法树拖放至模型器工作区。
一旦指定了所有设置,点击确定按钮。将在模型器工作区中添加一个新的输入块。
让我们从为我们的模型添加输入开始。第一个输入很明显;它是一个矢量层,用于创建密度图。双击处理模型器窗口中的输入选项卡中的矢量层项以打开参数定义对话框,其外观如下:

在参数名称中输入一个名称,例如,点层。因为我们不希望在以后看到所有可用的层作为输入,并且通过一个长长的列表搜索所需的层,我们可以通过在形状类型组合框中选择点几何类型来限制支持的几何类型。最后,因为这个输入是必需的,所以我们把必需字段保留为是。点击确定按钮将输入添加到模型器工作区。
为了能够根据我们的需求使我们的最终密度图更详细或更一般,我们需要一种调整单元格大小的方法。因此,双击输入选项卡中的数字项以添加另一个输入。

将“垂直网格间距”作为参数名称,如前一张截图所示。我们可以保留所有其他字段不变,但最好还是指定它们。这样做是为了防止用户输入错误。我们应该现在记住这样一个事实:不同的层可能具有不同的坐标参考系统(CRS)。因此,我们可能会有不同的距离单位。所以,我们的数值输入应该允许用户输入适合地理 CRS(度)和投影 CRS(米、英尺等)的值。这就是为什么我们使用0作为最小值,99999999.999999作为最大值。这些值允许我们在广泛的范围内更改单元格大小,而不考虑使用的 CRS。输入任何合理的值作为默认值,完成后点击确定。
由于水平和垂直方向上的单元格大小可能不同,我们需要使用之前看到的相同设置创建另一个名为“水平网格间距”的数值参数。
小贴士
如果您在水平和垂直方向上始终需要相同的间距,最好只使用一个输入参数,因为单个参数可以在同一算法中多次用作输入,甚至在不同算法中使用。稍后,我们可以调整我们的模型,使其只使用一个数值参数来定义网格间距。
如您从第五章的“使用六边形网格映射密度”部分中可能记得,在使用密度分析回答问题时,使用“创建网格”算法时,需要指定所需的网格范围,并且我们从输入层获取这个范围。
现在,为了设计我们的模型,我们有两种选择:
-
定义网格范围的输入。这将使我们的模型变得更加复杂,因为每次我们使用模型时,我们需要指定网格范围,而不是只指定层。但这个选项也带来了更多的灵活性,因为通过为网格范围设置单独的输入,我们将能够生成不仅适用于整个层,而且适用于其中指定区域的密度图。
-
从输入层获取范围。在这种情况下,我们的模型对用户来说将更加简单,因为他们只需要定义层和网格单元大小。但另一方面,密度图将生成整个层。
由于最常见的用例是整个层的密度图,我们选择了第二个选项。网格范围应自动从输入点层计算得出。
因此,我们几乎已经定义了我们模型所需的所有必要输入:输入层,以及代表水平和垂直方向网格单元大小的两个数字。只有一个输入尚未定义——网格范围。你将在下一节中学习如何从输入层中提取它,因为这与工作流程定义密切相关。
实现工作流程
当所有输入项都已就绪时,我们可以开始实现工作流程。所有可用的算法都可以在模型器窗口左侧的算法选项卡中找到。
工作流程实现与手动执行所有分析步骤非常相似:我们逐个添加算法,选择正确的输入,并在必要时定义输出。虽然模型器允许我们以任何随机顺序添加参数和算法,但最好按照它们应该执行的顺序添加算法,以避免混淆。让我们开始吧!
如您所记得,我们没有为网格范围添加单独的输入,您可能想知道我们将如何从点层中提取它,以与模型器输入兼容的格式。答案是简单的:我们将使用特殊的工具,这些工具被称为仅模型器工具。这些是什么?嗯,所有仅在处理模型器中可用的算法在工具箱中不可用。基本上,这些是可以在不同模型中真正有用的辅助工具,例如简单的计算器或值转换器。您可以在算法选项卡(因为它们也是算法)中的仅模型器工具组中找到这些工具。
目前,我们需要一个矢量层范围工具,它以矢量层作为输入,并返回其范围作为输出。
注意
除了范围之外,此工具还返回四个数值:最小和最大x坐标,以及最小和最大y坐标。您可以使用这些值作为不同算法的输入。
此输出值然后可以用于任何需要范围作为输入的算法。在过滤器字段中输入其名称以找到矢量层边界算法,然后双击它以打开如图所示的算法定义对话框。

对话框非常简单。我们将在稍后讨论定义对话框。现在,我们只需在层组合框中选择之前添加的点层输入,然后点击确定按钮关闭对话框并将算法添加到模型器工作区。现在所有准备工作都已完成,我们准备实施主要工作流程。
我们分析的第一步是网格生成,因此切换到算法选项卡,在过滤器字段中输入其名称以找到创建网格算法,然后双击它以打开算法定义对话框。

如您所见,算法定义对话框的内容几乎与从工具箱中打开的算法对话框相同。主要区别如下:
-
没有用于报告算法执行进度和其他信息的日志选项卡。由于算法目前没有执行,因此此选项卡不需要。
-
有一个新的描述字段。它用于在模型中定义算法名称。默认情况下,此名称与原始算法名称相同。当模型包含几个代表相同算法但使用不同输入的算法块时,此功能非常有用。在这种情况下,只需为此算法分配不同的描述,你就不会在其中迷失方向。你将能够轻松识别它们的输出。
-
在定义对话框的底部有一个新的父算法参数,当算法从处理工具箱中执行时,该参数不存在。正如其名称所暗示的,此参数允许我们为所选算法定义父算法,换句话说,设置算法的执行顺序。父算法将按指定顺序执行,并在其子算法之前执行。
默认情况下,当当前算法使用另一个算法的输出作为其输入时,后者自动成为当前算法的父算法,并在这两个算法之间创建一个链接。但有时,一个算法即使没有使用其任何输出,也可能依赖于另一个算法。以下是一个这样的情况的典型例子:在针对数据库层执行查询之前,必须创建数据库和层。
-
选择输入和输出的方法有所不同。所有值都可以从已添加到模型算法的算法生成的已可用模型输入和输出列表中选择。也可以在相应的字段中手动输入诸如数字、字符串、布尔值和表字段之类的值。请注意,如果你的模型是从工具箱中执行或作为另一个模型的一部分使用,则无法在设计时更改手动输入的值。因此,除非有紧急需要,否则不要硬编码值。
现在,继续为我们的模型定义创建网格算法。由于我们将使用相同的算法生成两个网格——六边形和正方形——我们需要区分算法块。因此,将描述字段改为创建六边形网格。我们通过从组合框中选择六边形(多边形)来硬编码网格类型参数,这是我们需要的。
在网格范围组合框中,选择从算法'矢量图层边界'获取'范围'。这是我们的输入图层范围,因此生成的六边形网格将覆盖它。
注意
在从算法'矢量图层边界'获取'范围'文本中,'范围'是算法的输出名称,'矢量图层边界'是从相应定义对话框的描述字段中获取的算法描述。因此,你可以轻松地检测出哪个输出来自哪个算法。
对于水平和垂直网格间距,从相应的组合框中选择之前定义的输入值。你可能注意到,除了我们定义的输入值之外,还有一些由矢量图层边界算法产生的附加值。忽略它们。
不要在输出字段中输入任何文本,因为这个算法生成的六边形网格是一个中间的、临时的输出,而不是最终结果。临时输出将被生成并存储在临时目录中,但在模型执行后永远不会添加到 QGIS 主画布上。如果你想要查看这些中间结果,有必要通过为它们输入描述来将它们转换为模型输出。
当所有参数都已分配值后,点击确定按钮将算法添加到模型器的工作区域。你会看到算法块现在已连接到其输入。点击In或Out标签附近的小+号将展开输入和/或输出的列表,以便你可以验证连接的正确性。第二次点击将它们折叠回原状。
添加另一个创建网格算法。将它的描述字段改为创建正方形网格,选择矩形(多边形)作为网格类型,并将所有其他参数设置为与我们之前创建六边形网格时相同。完成后,点击确定按钮。现在,模型器的工作区域中有两个算法块,它们使用相同的输入,如图所示:

我们接下来应该添加的算法是在多边形中计数点。在模型器窗口的算法选项卡中通过在过滤器字段中输入其名称来找到它,并双击它以打开算法定义对话框:

在这里,我们也编辑描述字段,以便能够区分不同网格的处理结果,例如,Count points in hexagon grid。如果你查看多边形和点组合框中可用的选项,你会看到它们都有一个相同的选项集:点层,'Output' from algorithm 'Create hexagon grid',和'Output' from algorithm 'Create square grid'。第一个是我们之前定义的输入,第二个和第三个是由已添加的创建网格算法产生的结果。正如你所看到的,我们可以很容易地识别算法产生的结果,这要归功于它们不同的描述。
仔细的读者可能会问,“为什么我们在组合框中看到这两个项目?毕竟,它们有不同的几何类型,我们应该只看到具有匹配几何类型的输入项目。” 好吧,这是处理过程中的一个当前限制——模型器不执行任何准确的输入检查。它总是显示所有可用的输入及其对应类型(矢量、栅格或无几何表),尽管有定义的限制。
因此,在多边形组合框中,我们需要选择由创建网格算法生成的六边形网格('Output' from algorithm 'Create hexagon grid'),并在点组合框中选择之前定义的点层输入。保持计数字段名称字段不变。此参数将在下一步中使用,并且可以安全地保持硬编码。
我们再次保持结果字段为空,因为在此阶段产生的密度图是一个临时、中间结果。它可能包含空单元格,应该被删除。最后,按下确定按钮以完成算法定义并将其添加到模型器工作区。
添加另一个在多边形中计数点算法以创建一个正方形密度图。将其描述设置为Count points in square grid,并将多边形输入选择为'Output' from algorithm 'Create square grid'的输出。所有其他参数应与上一个算法相同。同时,保持结果字段为空。
现在,我们可以添加最后一个算法来完成我们的简单模型——按属性提取。使用此算法,我们将从不含任何有用信息的单元格中清理我们的密度图。换句话说,我们将删除空单元格。
在模型器窗口的算法选项卡中通过在过滤器字段中输入其名称来找到按属性提取算法,并双击它以打开算法定义对话框:

与之前一样,我们编辑描述字段以区分相同的算法块及其输出。对于描述,我们选择从六边形网格提取。在输入层组合框中,我们应该选择计数多边形中的点算法的输出——'Result' from algorithm 'Count points in hexagon grid'。由于我们在上一步硬编码了字段名称,我们在选择属性字段中输入相同的名称。从运算符组合框中选择!=(不等于),并在值字段中输入0。
由于此算法将生成我们希望以后使用的输出,因此有必要在输出字段中输入结果描述,例如,六边形密度图。点击确定按钮以完成算法定义并将其添加到模型器工作区。除了算法块外,这次还将添加一个输出块。
最后,添加另一个按属性提取算法以生成最终的方形密度图。别忘了调整算法描述,设置正确的输入,并指定输出名称。
目前,模型元素以略微随机的顺序放置,难以识别它们之间的链接。为了提高可读性并以更结构化的方式组织模型,我们可以拖动工作区内的所有块。它们之间的链接将被保留。如有必要,您也可以使用鼠标滚轮进行缩放。以下可能是最终模型的外观:

那就结束了!我们刚刚创建了我们第一个模型,如果您在 QGIS 中加载了图层,您可以通过点击工具栏上的运行模型按钮来尝试它。

如您所见,模型执行对话框的外观和感觉与其他所有处理算法相同。可以从已提供的层中选择输入向量层,也可以从磁盘加载。数值可以通过旋转框选择,可以附带计算器,并保持我们设置的限制。
但现在不要关闭模型器!为了完全使用我们的模型,我们需要先从工具箱中以批处理方式运行它,并在其他模型中重用它,我们首先需要保存和记录它。这就是我们将在下一节中要做的。
填充模型元数据和保存
创建模型后,是否需要在磁盘上保存它,以便处理能够加载它并在工具箱中注册。
默认情况下,模型以 JSON 格式保存,扩展名为.model,位于 QGIS 用户文件夹中处理目录的子目录内。在 Windows 上,这通常是C:\Users\login\.qgis2(这里的login是您的 Windows 用户名),在 Linux 上则是~/.qgis2。如有必要,您始终可以使用处理设置对话框更改文件夹的位置。
当处理启动时,它会查找此目录中具有.model扩展名的文件并加载它们。加载的模型会出现在工具箱中的模型组中。此外,它们在模型器中与其他处理算法一样可用。
注意
有时,如果你正在加载第三方模型,可能会遇到错误。这主要是因为某些模型中使用的算法不可用。例如,某个算法提供者在处理设置中被禁用,或者模型需要额外的脚本/模型,而这些在处理中不可用。在这种情况下,仔细阅读错误消息并检查处理的日志,以了解哪些算法缺失。激活或安装它们,然后再次尝试加载有问题的模型。
在保存模型之前,有必要定义其名称和它将被放置的组。这些信息应输入在模型器工作区域上方的字段中。我们选择密度图作为模型名称,分箱作为组名称。如果你不喜欢这些名称,可以自由选择自己的名称。
当模型名称和组被定义后,点击工具栏中的保存按钮并输入模型的名称。当模型保存时,你会看到一个确认消息。
我们现在可以关闭模型器窗口,但不要急!记录你的模型是一个好习惯,即描述输入、执行的操作和最终结果。此类信息将极其有用,其他用户可能希望在自己的任务中重用该模型。此外,此元数据将有助于你回忆该模型是用于什么目的。
要开始编辑模型元数据,点击模型器对话框工具栏中的编辑模型帮助按钮。将打开一个帮助编辑器对话框,如下所示:

此对话框分为三个区域。在顶部是预览区域。在这里,当前的帮助内容被显示出来,以便你可以实时看到最终结果的外观。在左下角是元素树,其中列出了所有帮助部分,包括算法描述以及参数、输入和其他信息。在右下角是编辑区域。在这里,我们将输入对应元素的描述。
要编辑元素的描述,在元素列表中选择它,并在元素描述字段中输入文本。要保存更改,只需在元素树中选择另一个元素。
遍历元素树中的所有项目并输入它们的描述。例如,作为算法描述,你可以使用以下文本:
Generates hexagonal and square density maps from point dataset using binning technique. Output maps contain only non-empty cells.
This is demo model from Packt's QGIS by Example book.
描述所有其他字段。尽量简短,同时尽可能提供有用的信息。不要解释明显的事情——最好专注于重要细节。例如,在网格间距输入的描述中,值得提到的是,网格间距应定义为与层使用的相同距离单位。完成操作后,单击确定按钮关闭帮助编辑器对话框。
当您在工具栏中单击保存按钮时,模型元数据将自动保存在与模型本身相同的文件中。
编辑模型
您也可以在模型器中加载任何现有的模型进行编辑。您可以通过以下方式完成此操作,例如调整一些硬编码的参数,重新定义工作流程,或者只是了解其工作原理。加载现有模型有两种方式:
-
通过在搜索字段中输入模型名称,在工具箱中找到模型。右键单击模型以打开上下文菜单,并选择编辑模型。
-
从处理菜单中打开处理模型器,从工具栏中单击打开模型按钮,并导航到模型文件。
要编辑任何输入或算法,请单击相应块右下角的小铅笔图标。您还可以通过右键单击打开的上下文菜单选择编辑。任何这些操作都会打开一个定义对话框,您可以在其中执行必要的更改,例如更新值或限制或重新连接元素。点击确定按钮后,对话框将关闭,如果需要,模型块之间的链接将更新。
要删除不必要的项目(输入或算法),请单击相应块右上角的小叉按钮,或从项目上下文菜单中选择删除。请注意,只有当没有其他元素依赖于它时,才能删除算法或输入。换句话说,输入不应被任何算法使用,算法输出不应在其他算法中用作输入。如果您尝试删除依赖于其他元素的块,您将看到警告消息,并且操作将被取消。
现在,让我们编辑我们的模型。在几乎所有用例中,网格单元在水平和垂直方向上都应该具有相同的尺寸。只保留模型中的一个数值参数是非常好的。这简化了模型,并使用户的生活更加简单,因为他们执行模型时需要输入的数据更少。
首先,我们需要编辑一个数值输入,并将其名称更改为与输入含义相匹配。单击垂直网格间距块右下角的小铅笔图标,将参数名称更改为网格间距,然后单击确定按钮以保存您的编辑。
注意
或者,您可以编辑水平网格间距输入。这种替换是完全安全的。
现在,打开创建网格算法的定义对话框,并在两个字段中:水平间距和垂直间距中选择Grid spacing输入。完成后,点击确定按钮保存您的编辑并关闭对话框。你会看到块之间的连接现在已更改——一个数值输入(其名称取决于你之前编辑的输入)没有连接到任何算法。要删除此输入,点击右上角的交叉。更新后的模型可能看起来像这样:

如果你想,可以将更新后的模型保存为一个新的模型。为此,只需输入一个不同的模型名称,如果需要,还可以输入一个组名称。然后,点击另存为...按钮,并为新的模型文件输入一个名称。
还可以在不删除相应块的情况下停用模型的一些部分——一个特定的算法甚至整个分支。当你不希望得到模型产生的所有输出或需要调试/测试其一小部分时,这个功能非常有用。
要停用算法,右键单击它,并在上下文菜单中选择停用。相应的算法块将被灰色显示,并且所有依赖于它的算法块也将自动停用。停用的算法在模型执行期间将被跳过,不会生成任何输出。这有一个优点——模型的执行时间会减少。请记住,算法的状态(激活/停用)正在模型文件中保存,在保存模型之前,请确保你没有遗漏任何内容。
要激活一个算法,右键单击它,并在上下文菜单中选择激活。请注意,这种激活只影响所选算法。所有依赖于它的算法都将保持未激活状态,你必须逐个激活它们。
例如,假设你不需要生成正方形密度图。当然,我们可以通过删除不必要的块并使用另存为...功能从现有模型创建一个新的模型。当你经常需要只生成六边形密度图时,创建新模型是有意义的。但如果是一次性需求,最好简单地停用模型中的创建正方形网格块,这样所有依赖的块也会被停用。因此,你可以执行模型,只生成六边形密度图,然后再次激活已停用的块。
分享模型
如果你创建了可能帮助其他用户的实用模型,那么与社区分享它们会很好,这样其他人就不需要重新发明轮子了。
由于保存的 Processing 模型是一个 JSON 格式的单个文件,因此与他人分享它的最简单方法是将其发送给感兴趣的人,或者将模型文件上传到任何文件共享或托管网站,并为每个人提供此文件的链接。
这是一种稍微复杂一些,但同时也非常方便和用户友好的方法:在处理模型和脚本社区存储库中发布您的模型。此存储库于 2014 年春季创建,为 QGIS 用户之间共享处理脚本和模型提供了一个集中的方式。
要将您的模型放入此存储库,您需要将 GitHub 存储库 (github.com/qgis/QGIS-Processing) 分叉,在您的分叉中提交您的模型,并发出一个拉取请求。
小贴士
要了解更多关于 Git 的信息,可以使用 Packt 的书籍之一,例如 Git:面向所有人的版本控制,并参考 GitHub 文档,链接为 help.github.com/.
另一个选项是将模型发送到 qgis-developer 邮件列表,或者直接发送给 Processing 的开发者之一,并请他们将其放入存储库。
要从此存储库获取模型,请使用位于处理工具箱中 模型 项下的 工具 子组中的 从在线脚本集合获取模型 工具。
摘要
在本章中,您学习了如何使用 QGIS 处理框架中的图形模型器从多个算法创建地理处理模型。模型器允许我们将需要多个步骤的复杂分析组合成一个单一、易于使用的算法,从而实现自动化分析和提高生产力。
我们还涵盖了其他一些重要主题,包括记录模型并与其他用户共享。
第九章. 使用 Processing 脚本自动化分析
在上一章中,我们介绍了 Processing 图形模型器,并学习了如何使用它来自动化复杂的地处理分析。但这并不是自动化您工作的唯一方式。QGIS 的 Processing 框架还允许您使用 Python 编写自己的脚本,并在以后像使用任何其他算法一样使用它们。这就是本章将要讨论的内容。
在本章中,我们将讨论以下主题:
-
Processing 中的 Python 脚本
-
定义输入和输出
-
实现算法
-
编写帮助并保存
-
分享脚本
Processing 中的 Python 脚本
你已经学会了如何使用 QGIS 处理框架中的图形模型器创建模型和自动化分析任务。尽管 Processing 模型器用户友好且易于使用,但它有一些限制:
-
在模型中,您只能使用 Processing 中已经可用的算法。此外,一些在 Processing 工具箱中可用的算法在模型器中不可用。
-
不支持条件语句和循环。
因此,如果您需要实现更复杂和高级的功能,您将需要另一个工具。幸运的是,模型器并不是自动化分析的唯一方式。Processing 还允许我们通过开发 Python 脚本来结合其自身的能力与 Python 编程语言的力量。然后,这些脚本可以像 Processing 工具箱或模型器中的任何其他算法一样使用,或者作为批处理过程执行。
在我们开始实现脚本之前,了解如何从 QGIS Python 控制台使用 Processing 算法是必要的,因为这种知识对于在脚本中成功使用现有的 Processing 算法是必需的。
现在,通过点击插件工具栏上的
按钮打开 Python 控制台。或者,您可以使用Ctrl + Alt + P键盘快捷键或通过转到插件 | Python 控制台来打开它。QGIS 窗口底部将出现一个新的浮动窗口,如下面的截图所示:

Python 控制台由两个主要区域组成。在顶部是输出区域,其中将打印执行命令及其输出。在其下方是输入区域,您应在此处输入要执行的代码。在这里,代码是逐行输入的。Python 控制台的左侧还有一个工具栏。
小贴士
如果你想了解更多关于 Python 控制台的信息,请点击其工具栏上的帮助按钮并阅读内置文档。
要从 Python 控制台开始使用 Processing,我们应该使用以下命令导入它:
import processing
这行代码将加载所有 Processing 函数并使它们对我们可用。
列出可用算法
你可能希望从你的脚本中运行现有的 Processing 算法,而不是自己重新实现其功能。为此,需要获取该算法的名称,这并不是你在工具箱中看到的名字,而是一个特殊名称——所谓的命令行名称。
注意
Processing 中的每个算法都有两个名称:一个用于工具箱和模型器中的人可读且用户友好的名称,以及另一个内部命令行名称,其中不包含任何歧义字符,例如空格、分号等。它还包含有关算法提供者的信息。命令行名称是唯一的。
要列出所有可用的 Processing 算法及其命令行名称,请运行以下 Python 控制台命令:
processing.alglist()
你将得到一个非常长的输出,可能看起来像这样(已截断):
Calculator------------------------------------------->modelertools:calculator
Raster layer bounds---------------------------------->modelertools:rasterlayerbounds
Vector layer bounds---------------------------------->modelertools:vectorlayerbounds
Add autoincremental field---------------------------->qgis:addautoincrementalfield
Add field to attributes table------------------------>qgis:addfieldtoattributestable
Advanced Python field calculator--------------------->qgis:advancedpythonfieldcalculator
Bar plot--------------------------------------------->qgis:barplot
Basic statistics for numeric fields------------------>qgis:basicstatisticsfornumericfields
Basic statistics for text fields--------------------->qgis:basicstatisticsfortextfields
Clip------------------------------------------------->qgis:clip
在左侧,你可以看到在工具箱中也使用的人可读算法名称,而在右侧是相应的命令行名称。
由于算法的数量——即使在默认的 QGIS 安装中——也非常大,可能很难找到所需算法的命令行名称。幸运的是,可以通过 alglist() 命令减少输出。只需向其中传递一个字符串参数,表示应存在于算法名称中的子串。例如,要仅显示名称中包含count一词的算法,请执行以下代码:
processing.alglist('count')
结果将更短,并且更容易找到你正在寻找的算法:
Count points in polygon------------------------------>qgis:countpointsinpolygon
Count points in polygon(weighted)-------------------->qgis:countpointsinpolygonweighted
Count unique points in polygon----------------------->qgis:countuniquepointsinpolygon
v.qcount - Indices for quadrant counts of sites lists.--->grass:v.qcount
现在我们知道了如何获取所需算法的命令行名称。但为了运行该算法,我们还需要了解一些更多信息。
获取算法信息
要执行一个算法,我们不仅需要其名称,还需要其语法。这包括有关算法输入和输出的列表,以及它们应该按何种顺序传递给算法的信息。所有这些信息都可以通过 processing.alghelp() 命令获得。此命令仅接受一个参数——命令行算法名称,并返回一个包含算法输入和输出的列表,以及它们的类型。
以往章节中使用的 Create grid 算法为例。它的命令行名称是 qgis:creategrid(你可以通过前述部分的信息轻松检查这一点),因此要获取其语法信息,我们应该在 QGIS Python 控制台中执行下一个命令:
processing.alghelp('qgis:creategrid')
这是此命令的输出:
ALGORITHM: Create grid
TYPE <ParameterSelection>
EXTENT <ParameterExtent>
HSPACING <ParameterNumber>
VSPACING <ParameterNumber>
OUTPUT <OutputVector>
TYPE(Grid type)
0 - Rectangle (line)
1 - Rectangle (polygon)
2 - Diamond (polygon)
3 - Hexagon (polygon)
从这个输出中,我们可以看到人类可读的算法名称是Create grid,它接受四个输入字段:TYPE(从预定义值列表中选择)、EXTENT(范围)、HSPACING和VSPACING(这两个都是数字)。该算法已生成一个矢量输出。然而,最有趣的部分是在参数和输出列表下方;它是TYPE选择参数的可用值列表。左侧的数字是可以传递给算法的值,右侧可以看到每个值的可读描述。例如,如果您想创建一个菱形单元格的网格,那么必须将值2传递给TYPE参数。
现在我们来看一下不同的参数类型应该如何传递给算法:
-
栅格或矢量图层和表格 (
ParameterVector,ParameterRaster, 和ParameterTable): 如果该图层已在 QGIS 中加载,则可以指定相应图层或表格的名称。您还可以使用图层文件的路径。最后,可以传递相应 QGIS 类的实例,例如,QgsVectorLayer。如果这是一个可选输入并且您不想使用它,只需使用None值。 -
从预定义值中选择 (
ParameterSelection): 应该用对应值的数值索引表示。值与索引之间的映射作为processing.alghelp()函数输出的部分显示,如前所述。还有一个单独的命令用于列出此类匹配项——processing.algoptions()函数。此命令仅接受一个参数——算法的命令行名称——其输出是所有具有选择类型的算法参数的选项索引与值的匹配。 -
多个输入 (
ParameterMultipleInput): 应该用分号(;)分隔的字符串传递。每个值可以是图层名称或文件的路径。 -
表格字段 (
ParameterTableField): 这只是一个包含字段名称的字符串。请注意,这个值是区分大小写的。 -
用户定义的表格 (
ParameterFixedTable): 这被定义为用逗号分隔的值列表,并用双引号括起来。此外,还可以传递一个包含值的二维列表或数组;例如,一个小型的 2 x 2 表格可以作为一个二维 Python 列表传递,如下所示:[[0, 1], [2, 3]]。请注意,值应从最顶部的行开始,从左到右排列。 -
坐标参考系统 (
ParameterCrs): 使用相应 CRS 的 EPSG 代码。 -
范围 (
ParameterExtent): 这表示为包含xmin、xmax、ymin和ymax值的字符串,这些值由逗号(,)分隔。 -
数值 (
ParameterNumber)、布尔 (ParameterBoolean) 和 字符串 (ParameterString) 参数:这些由相应的原生 Python 数据类型表示:int、float、boolean、str或unicode。此外,此类参数可能有默认值。要使用它们,在相应参数的位置指定None。
对于输出数据,规则要简单得多。如果你想将图层、表格、文件或 HTML 输出保存到特定位置,只需传递文件路径。在栅格和矢量输出的情况下,文件的扩展名将决定输出格式。如果给定的扩展名不受算法支持,输出将保存为默认格式(这取决于算法),并将相应的扩展名添加到指定的文件路径中。要写入临时文件,传递 None 值。
当从 Python 控制台运行算法时,你不需要为数值和字符串输出定义任何变量。这些将自动计算并返回,无需你采取任何行动。有关访问此类输出的更多信息,请参阅本章的 执行算法和加载结果 部分。
现在你已经了解了算法语法以及如何向其传递参数,我们可以从 QGIS Python 控制台执行算法。
执行算法和加载结果
要从 QGIS Python 控制台执行算法,我们需要使用 processing.runalg() 方法。通常,该方法以以下方式调用:
results = processing.runalg(algorithm_name, param1, param2, …, paramN, output1, output2, …, outputM)
在这里,algorithm_name 是命令行算法名称,param1...paramN 是算法参数,而 output1...outputM 是算法输出。参数和输出应该按照 alghelp() 方法显示的顺序传递,考虑到上一节中定义输入和输出的信息。
注意
如我们之前提到的,对于数值、字符串或布尔输出,你不需要指定任何变量。
如果算法报告其执行进度,在执行过程中,主 QGIS 窗口将显示一个带有进度指示器的消息栏。
与从工具箱中执行算法不同,runalg() 方法不会将任何结果加载到 QGIS 中。你可以使用 QGIS API 或以下方式使用 Processing 提供的辅助方法手动加载它们。
算法成功执行后,runalg() 方法返回一个字典,其中输出名称(如 alghelp() 方法所示)是键,它们的值是生成文件的路径或包含计算值。
要加载生成的栅格或矢量图层,将对应文件的路径传递给 load() 方法。例如,如果算法执行的结果保存在 res 变量中,输出名称为 OUTPUT,那么要将此图层加载到 QGIS 中,请执行以下代码:
processing.load(res['OUTPUT'])
然后,该图层将被加载到 QGIS 中。
要访问结果字典中的数字或字符串输出,只需使用相应的键名。
让我们从布鲁克林树木地籍(这是我们数据集中的trees层)加载数据,并尝试理解下一个小型示例是如何工作以及它做了什么。请在 QGIS Python 控制台中逐个运行这些命令。如果需要,可以使用processing辅助方法,例如alglist()和alghelp(),并按照之前所述通过打印或加载到 QGIS 中来检查结果:
(1) import processing
(2) resGrid = processing.runalg('qgis:creategrid', 3, '972921.0000478327274323,1023822.9999672472476959,147696.9999549686908722,208209.0000113248825073', 1000, 1000, None)
(3) resCount = processing.runalg('qgis:countpointsinpolygon', resGrid['OUTPUT'], 'trees', 'NUMPOINTS', None)
(4) finalMap = processing.runalg('qgis:extractbyattribute', resCount['OUTPUT'], 'NUMPOINTS', 1, '0', None)
(5) processing.load(finalMap['OUTPUT'])
如果您仔细阅读了前面的章节,您应该理解这些命令是用来从点层生成六边形密度图的。在第一行,我们导入processing模块及其所有算法。在第二行,执行Create grid算法,并使用trees层的范围和1000的单元格大小创建一个六边形网格(值为3的参数表示六边形网格类型)。结果保存在一个临时文件中,因为我们传递了None值作为最后一个参数。在行3,执行Count points in polygon算法。作为一个多边形层,它使用Create grid算法的输出(resGrid['OUTPUT']),作为点层,使用 QGIS 中已经打开的树木层。同样,结果也保存在临时文件中。然后,在行4,调用Extract by attribute算法来保存非空单元格(值为1的参数对应于不等于运算符,!=)。最后,使用最后一行,将最终结果加载到 QGIS 中。
现在,您已经知道了如何获取有关 Processing 算法的所有必要信息,并且可以从 QGIS Python 控制台使用它们,我们可以深入到 Processing 脚本开发中。
定义输入和输出
正如我们之前所说的,尽管有模型,您可以使用 Python 编程语言创建自己的 Processing 脚本。基本上,Processing 脚本就是 Python 代码加上 Processing 所需的一些附加元数据。
每个 Processing 脚本都以一个特殊的元数据块开始。Processing 需要这些信息来注册脚本作为算法,并从工具箱、模型器等中使用它。每个元数据条目都放在新的一行上,以双 Python 注释符号(##)开始,并具有以下结构:
element_name = element_type [optional_parameters]
元数据项可以分为三组:描述脚本的项目、描述脚本输入的项目和描述脚本输出的项目。
描述脚本的只有三个项目:
-
group:这用于定义脚本将在工具箱中的Scripts组内的子组名称。例如,如果您在脚本标题中放入以下行##Density maps=group,它将被放置在Density maps子组下。如果省略此项目,脚本将放置在User下的Scripts子组中。 -
name:这定义了脚本名称。默认情况下,脚本名称是通过删除扩展名并将下划线替换为空格从脚本文件名生成的。如果您不想使用长描述性文件名来为您的脚本命名,但仍然想在 Processing 工具箱中拥有好名字,请使用name元数据项。其语法与group项相同,例如,##Hexagonal_density_map=name。 -
nomodeler:这是一个标志项。带有此类元数据的脚本只能从工具箱中使用,它们在模型器中不可用。其用法如下:##nomodeler。
用于描述脚本输入的元数据项的数量要大得多。脚本支持几乎在 Processing 中可用的所有输入。有必要指出,项目名称也将是变量名,并且可以在脚本代码中使用。用户在执行脚本时输入或选择的值将被分配给相应的变量。
此外,项目名称将被用作算法执行对话框中相应小部件的标题。为了改善外观,下划线将被替换为空格。因此,如果您在脚本中有一个名为My_cool_parameter的项目,那么其小部件的标题将是My cool parameter。要访问此参数的值,我们需要使用My_cool_parameter变量。
让我们看看可用的输入参数:
-
raster:这描述了输入栅格图层。这里是一个用法示例:##Raster_layer=raster。 -
vector:这描述了输入矢量图层。请注意,如果您的脚本接受任何几何类型的矢量图层(点、线或多边形),则应使用此项目。如果您想限制支持的几何类型,请使用以下项目之一。其用法示例为:##Vector_layer=vector。 -
vector point:这描述了输入点矢量图层。此项目仅接受具有点几何的图层。请注意,这种限制仅适用于已加载到 QGIS 中的图层。如果用户想指定磁盘上的文件,则选择具有正确几何类型的图层是他们的责任。其用法如下:##Vector_layer=vector point。 -
vector line:这描述了输入线矢量图层。此项目仅接受具有线几何的矢量。同样,请注意,这种限制仅适用于已加载到 QGIS 中的图层。如果用户想指定磁盘上的文件,则选择具有正确几何类型的图层是他们的责任。其用法如下:##Vector_layer=vector line。 -
vector polygon: 这描述了输入的多边形矢量层。此项目仅接受具有多边形几何形状的矢量。再次提醒,这种限制仅适用于已在 QGIS 中加载的层。如果用户想指定来自磁盘的文件,则选择具有正确几何类型的层是他们的责任。一个用法示例如下:##Vector_layer=vector polygon。 -
table: 这用于定义一个无几何信息的输入表。其用法如下:##Table_to_join=table。 -
multiple raster: 这用于定义由多个栅格层组成的复合输入。一个用法示例如下:##Layers_to_mosaic=multiple raster。 -
multiple vector: 这用于定义由多个矢量层组成的复合输入。请注意,此输入允许我们选择任何矢量层,无论其几何类型如何。其用法如下:##Layers_to_merge=multiple vector。 -
selection: 这描述了从预定义值列表中的选择。项目类型之后指定的值由分号分隔。一个用法示例如下:##Method=selection Nearest neighbor;Average;Cubic。 -
boolean: 这定义了一个布尔(也常称为逻辑)输入。必须指定一个默认值。其用法如下:##Smooth_results=boolean False。 -
extent: 这定义了输入范围。其用法如下:##Grid_extent=extent。 -
file: 这用于定义一个输入文件(在文本或其他 Processing 无法识别为栅格、矢量或表的任何格式中)。一个用法示例如下:##Index_data=file。 -
folder: 这描述了输入目录。其用法如下:##Input_directory=directory。 -
number: 这定义了一个数值(整数或浮点数)输入。必须指定一个默认值。如果默认值没有小数分隔符,则该参数将仅接受整数值。目前,在脚本中无法为这类参数定义最小和最大限制。一个用法示例如下:##Width=number 1000.0。 -
field: 这描述了矢量层或无几何信息表中的属性字段。必须指定表示父层或表的对应输入的名称。例如,如果矢量层被定义为##Input_layer=vector,那么这个层的字段将被定义为##Classification_field=field Input_layer。 -
string: 这用于定义一个字符串输入。必须指定一个默认值。其用法如下:##Field_name=string NUMPOINTS。 -
longstring: 这定义了一个多行字符串输入。必须指定一个默认值。其用法的一个例子如下:##Options=longstring my cool options。 -
crs: 这描述了坐标参考系统。默认情况下,使用 EPSG:4326。如果您想指定另一个默认 CRS,请指定其EPSG代码。其用法如下:##Assign_CRS=crs EPSG:3857。
输入图层和表始终作为包含对应文件路径的字符串传递给脚本。要从这样的字符串创建 QGIS 对象(QgsVectorLayer或QgsRasterLayer),我们需要使用processing.getObjectFromUri()函数。多个栅格或矢量输入也作为包含由分号分隔的各个文件路径的字符串传递。
这里列出了所有可用的输出:
-
输出栅格: 这代表由脚本生成的栅格图层。其用法如下:##NDVI 栅格输出=输出栅格。 -
输出矢量: 这代表由脚本生成的矢量图层。其用法示例如下:##矢量网格输出=输出矢量。 -
输出表格: 这代表由脚本生成的无几何表格。这可以是 CVS 或 DBF 表格。其用法如下:##最近点输出=输出表格。 -
输出 HTML: 这描述了 HTML 格式的输出。这种输出主要用于可能包含或不包含图形的不同文本报告。其用法示例如下:##统计输出=输出 HTML。 -
输出文件: 这用于格式不同于 HTML 以及 QGIS 支持的所有其他格式的文件。例如,这些可以是纯文本文件、LiDAR 数据等。其用法如下:##点连接输出=输出文件。 -
输出目录: 这描述了输出目录。它主要用于生成许多文件的算法,例如,当按属性值分割矢量图层时。其用法示例如下:##分割文件输出=输出目录。注意
注意,目前,处理工具无法从这样的输出目录中加载文件,即使这些文件是支持的格式。您需要手动从输出目录打开每个文件。
-
输出数值: 这代表由算法生成的数值。此值不会保存到任何地方,只能用作另一个算法的输入。例如,可以编写脚本以计算矢量网格的最佳单元格大小,然后此类算法的数值输出可以用作创建网格算法的输入。其用法示例如下:##最大值输出=输出数值。 -
输出字符串: 这与前面描述的输出数值类似。它代表由算法生成的字符串字面量。其用法如下:##选择条件输出=输出字符串。
数值和字符串输出也称为隐藏输出(因为它们在 QGIS 和处理的输出对话框中不显示),并且不会自动初始化为值。您应手动分配相应的值给它们。
所有其他输出都将始终是一个字符串值,包含对应输出文件或目录的路径。如果用户未指定任何文件名,则输出将保存到自动创建的临时文件中,该文件的名称将用作输出值。
值得注意的是,在成功执行算法后,Processing 将自动加载所有支持的格式中的输出文件。因此,您不需要在脚本中添加任何 processing.load() 函数调用。
实现算法
现在,当我们知道如何定义输入和输出时,我们就准备好为 Processing 开发 Python 脚本了。
创建脚本有两种方法:
-
使用您喜欢的文本编辑器或集成开发环境(IDE)
-
使用 Processing 的内置代码编辑器
使用哪种方法是一个口味和习惯的问题。在这本书中,我们将使用内置脚本编辑器。您可以从 Processing 工具箱中打开它。定位并展开 脚本 组,展开 工具 子组,然后双击 创建新脚本 项。或者,您可以在过滤器字段中开始键入 创建新脚本。工具箱的内容将被过滤,您可以轻松找到相应的项。

脚本编辑器看起来像前面截图所示的普通文本编辑器。顶部有一个工具栏,其余所有区域都由编辑器本身占用。
现在,我们将通过开发一个用于在道路网络上找到两点之间最短路径的脚本,来了解如何创建 Processing Python 脚本。这种分析在许多应用领域都非常常见,例如基础设施规划、旅行/出行规划等。
QGIS 拥有一个简单的内置网络分析库,允许我们使用 Dijkstra 算法在两点之间找到最短路径,并且还可以执行一些其他有趣的事情,例如构建可达区域(也称为服务区域)以及将点匹配到最近的线。
首先,我们需要确定脚本的输入和输出。作为输入,我们需要一个道路图层、一个起点和一个终点。由于 Processing 不支持点作为输入,最简单的解决方案是传递两个矢量,一个用于起点,另一个用于终点。这种解决方案还允许我们定义多个起点和终点,并找到每对起点和终点之间的最短路径。至于输出,我们的脚本显然只有一个输出——一个包含计算出的最短路径(或路径)的矢量图层。
因此,脚本头将看起来像这样。如果您仔细阅读了前面的章节,应该没有问题理解它:
1 ##Network analysis=group
2 ##Shortest paths=name
3 ##Road_layer=vector line
4 ##Start_points=vector point
5 ##End_points=vector point
6 ##Shortest_paths=output vector
在前两行中,我们定义了脚本将放置的组以及脚本名称。然后,我们定义了输入和输出。请注意,我们使用精确的定义来指定输入矢量图层,这样当用户在输入组合框中运行脚本时,他们只会看到与参数定义匹配的几何类型的图层。例如,在道路图层组合框中,只会列出线矢量图层。
在脚本头之后,脚本主体开始。它包含实现所需算法的 Python 代码。脚本主体可以分为两部分:导入部分和代码本身。
仅使用 Python 的基本命令,只能实现非常简单的脚本。任何更复杂或更简单的算法都需要额外的类或库,例如来自 Python 标准库、QGIS 和 Processing 库,甚至是一些第三方包。要在您的代码中使用这些库,您需要导入它们。
通常,这是基于迭代进行的:您编写代码,当需要新的类或库时,添加相应的导入语句。通常,所有导入语句都放置在源文件的非常开始处。为了简化,在我们的示例脚本中,我们将从开始提供所有必要的导入。相应的代码将如下所示:
(1) from PyQt4.QtCore import QVariant
(2)
(3) from qgis.core import QGis, QgsFeature, QgsGeometry, QgsField, QgsFields
(4) from qgis.networkanalysis import (QgsLineVectorLayerDirector,
(5) QgsDistanceArcProperter, QgsGraphBuilder, QgsGraphAnalyzer)
(6)
(7) from processing.core import GeoAlgorithmExecutionException
(8) from processing.tools.vector import VectorWriter
如您所见,所有导入都被分为三个逻辑块,它们之间用空行隔开。在第一行,我们从PyQt4库的QtCore包中导入QVariant类。这个类包含了通用变体数据类型的定义,它将被用来声明矢量层的属性。
在第二个块中,我们导入了来自 QGIS 核心库(块的第一个行)和 QGIS 网络分析库(块的第二个行)的各种非 GUI 类。我们需要这些 QGIS 核心类来构建表示最短路径的输出矢量特征。此外,来自 QGIS 网络分析库的类为我们提供了执行网络分析所需的一切。
最后,在最后一个块中,我们从 QGIS 处理框架的不同模块中导入了一些类。GeoAlgorithmExecutionException类将被用来从我们的脚本中引发异常,而VectorWriter是一个辅助类,它允许我们轻松地将输出矢量数据写入任何 QGIS 支持的格式。
现在我们可以实现算法本身。如您在前面章节中学到的,所有我们的输入——道路层以及起点和终点的层——都是以对应文件路径的形式传递的,因此有必要从它们中创建层对象以供进一步使用。这可以通过以下代码完成:
(1) layerRoads = processing.getObjectFromUri(Road_layer)
(2) layerStartPoints = processing.getObjectFromUri(Start_points)
(3) layerStopPoints = processing.getObjectFromUri(End_points)
我们使用处理包中的getObjectFromUri()函数。它接受文件路径或任何其他 URI,并从中返回一个有效的层(根据 URI 是栅格或矢量)。请注意,我们在getObjectFromUri()函数调用中将脚本头中定义的输入名称作为参数指定。正如我们在“定义输入和输出”部分中提到的,代表输入值具有与相应输入相同的名称。
由于我们为起始点和结束点使用单独的层,因此有必要验证这两个层具有相同数量的特征,因为如果点的数量不同,将无法创建起始点-结束点对;一些点将没有配对。以下是此类检查的代码:
(1) if layerStartPoints.featureCount() != layerStopPoints.featureCount():
(2) GeoAlgorithmExecutionException(
(3) 'Number of features in start and end point layers should be equal!')
我们使用featureCount()方法来获取具有起始点和结束点的层的特征数量,并进行比较。如果数字不相等,将引发异常并终止算法执行。
小贴士
在需要由于任何错误而终止脚本执行时,始终抛出GeoAlgorithmExecutionException。在这种情况下,用户将看到一个带有错误消息的标准对话框,并且错误将被记录在日志中。
通常,算法需要一些时间才能完成,因此通知用户执行进度并提供有关已完成步骤的信息是良好的实践,这样用户就会知道程序没有冻结。为此,Processing 中的每个算法都提供了一个特殊的progress对象。借助它,您可以轻松地向用户显示不同类型的消息(信息、调试、顺序文本等),以及使用进度条显示执行进度。
我们的脚本也不例外。在分析过程中应执行几个可能需要较长时间的任务。首先是收集所有起始点和结束点的坐标,这些坐标将在后续的路线图生成步骤中使用。相应的代码如下:
(1) progress.setInfo('Gathering start and stop points')
(2)
(3) feats = layerStartPoints.getFeatures()
(4) points = [f.geometry().asPoint() for f in feats]
(5)
(6) feats = layerStopPoints.getFeatures()
(7) tmp = [f.geometry().asPoint() for f in feats]
(8) points.extend(tmp)
在第一行,我们使用progress.setInfo()命令向用户显示一条信息消息。
注意
除了显示普通文本(setText())、调试信息(setDebugInfo())、控制台输出(setConsoleInfo())和其他消息类型外,还有专门的命令。
此消息将在算法对话框的日志选项卡中显示。
然后,我们对具有起始点的层的特征使用迭代器,提取每个特征的几何形状,将其转换为QgsPoint实例,并将其存储在points列表中。
使用相同的方法,我们创建另一个名为tmp的列表,其中包含包含我们的终点的层的资料。在最后一行,我们将这两个列表合并为一个,因此我们的points列表将包含起点和终点。我们需要将所有点放入一个单独的列表中,因为稍后所有点都必须与我们的道路网络相关联。此操作是在创建图的同时一次性对所有点进行的。由于两个层中的点数相等,我们可以很容易地使用非常简单的数学方法访问起点和终点的配对。假设每个层中的点数为N,并且知道 Python 中列表索引从0开始,我们可以这样说,起点将具有从0到N-1的索引,而终点的索引将从N到2N-1。因此,如果我们知道一个起点的索引,很容易通过将任何输入层中的点总数加到起点的索引上来得到相应的终点的索引。
由于我们的脚本将生成一个输出矢量层,因此有必要准备一个特殊对象来保存其中的要素。幸运的是,Processing 有VectorWriter类,它为我们提供了一个方便的方式来以任何 OGR 支持的格式或 QGIS 内存层保存矢量数据,而无需编写很多代码。以下是创建此类写入对象的代码:
(1) fields = QgsFields()
(2) fields.append(QgsField('id', QVariant.Int, '', 10))
(3) fields.append(QgsField('startPoint', QVariant.String, '', 254))
(4) fields.append(QgsField('endPoint', QVariant.String, '', 254))
(5) fields.append(QgsField('length', QVariant.Double, '', 20, 7))
(6)
(7) writer = VectorWriter(Shortest_paths, None, fields.toList(),
(8) QGis.WKBLineString, layerRoads.crs())
在这里的前五行代码中,我们创建了一个QgsFields容器的实例,其中将保存我们的属性定义,并对其进行填充。我们的示例脚本输出层将具有四个属性:
-
id:这是路径的整数数字标识符 -
startPoint:这些是路径起点的坐标,以(x, y)格式表示 -
endPoint:这些是路径终点的坐标,以(x, y)格式表示 -
length:这是路径的总长度
在最后一行,创建了一个VectorWriter类的实例。我们将用户定义的输出文件路径、我们之前创建的属性列表、几何类型和坐标参考系统传递给构造函数。请注意,作为输出文件路径,我们指定了在脚本标题中用来描述输出的相同变量。此外,坐标参考系统是从输入的道路层中获取的,因此我们的输出将使用相同的 CRS。
目前所需的大部分准备工作都已完成,现在我们可以使用 QGIS 网络分析库从我们的道路层创建一个图。这一步是必要的,因为网络分析是使用图而不是矢量层进行的。在创建图之前,必须实例化所有所需的类并调整设置。以下代码行展示了如何进行此操作:
(1) director = QgsLineVectorLayerDirector(layerRoads, -1, '', '', '', 3)
(2) properter = QgsDistanceArcProperter()
(3) director.addProperter(properter)
(4) builder = QgsGraphBuilder(layerRoads.crs())
首先,我们实例化所谓的导演,这是一个基类,它调整图创建过程中的某些设置。导演接受以下解释的参数:
-
构建图表的线向量层。
-
存储道路方向的属性字段索引。由于我们不考虑道路方向,我们将传递
-1。 -
表示单行道路直接方向的属性值。直接方向意味着你只能从道路的起点移动到终点。在我们的例子中,我们不会使用方向信息,因此我们传递一个空字符串。
-
表示单行道路反向方向的属性值。当道路有反向方向时,你只能从道路的终点移动到起点。在我们的例子中,我们不会使用方向信息,因此我们传递一个空字符串。
-
表示双向或双向道路的属性值。双向道路是最常见的道路。它们允许我们在两个方向上移动:从起点到终点,以及从终点到起点。在我们的例子中,我们不使用方向信息,因此我们在这里传递一个空字符串。
-
默认的道路方向。此参数定义了如何处理第一个参数指定的字段中无方向信息的道路。它可以取以下值之一:
1表示直接方向,2表示反向方向,3表示双向道路。为了简化,我们将所有道路视为双向道路,因此我们将使用值3。
两个点之间的最短路径可以使用不同的标准(在 QGIS 网络分析库中,这些称为属性)或甚至它们的组合——长度、旅行时间、旅行成本等来计算。目前网络分析库中只有一个内置标准——QgsDistanceArcProperter——它考虑道路长度。当然,我们可以添加我们自己的标准,但为了简化我们的演示脚本,我们将使用内置标准。属性在第二行实例化,并在第三行添加到已创建的导演中。
在第四行,我们创建所谓的构建器——一个使用导演指定的设置生成图表的类。我们传递给构建器的唯一参数是我们想要使用的坐标参考系统。通常,这和输入道路层的 CRS 相同。
现在所有设置都已完成,我们可以创建图表,该图表将用于寻找最短路径,如下所示:
(1) progress.setInfo('Generating road graph...')
(2) tiedPoints = director.makeGraph(builder, points)
(3) graph = builder.graph()
(4) del points
由于图生成是一个耗时操作,尤其是在密集的道路网络和大量起点和终点的情况下,我们在生成图表本身之前会向用户显示一条信息消息。
这段代码中最重要的一行是第二行,其中调用了makeGraph()方法。参数是builder,它包含图形生成过程的全部设置,以及points,这是一个起点和终点的列表。由于点可能不在道路上精确定位,因此有必要将它们匹配到最近的道路链接。这发生在创建图的同时,makeGraph()方法返回一个所谓的绑定点的列表,换句话说,就是放置在最近道路段上的点。
在第三行,我们从构建器获取图对象本身,并存储它以供进一步使用。由于现在我们不需要原始点(所有进一步的工作都将使用绑定点),我们在最后一行删除它们以释放内存。
注意
关于 QGIS 网络分析库的更多信息可以在PyQGIS 开发者手册中找到,链接为docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/network_analysis.html。
既然我们已经有了我们的道路图和与最近的道路链接匹配的点,我们可以开始为每个起点-终点对查找最短路径。但首先,我们需要执行一些辅助操作,如下所示:
(1) count = layerStartPoints.featureCount()
(2) total = 100.0 / float(count)
(3)
(4) ft = QgsFeature()
(5) ft.setFields(fields)
前两行用于为进度报告准备值。进度条显示从0到100的百分比,我们需要处理count对点(等于任何输入点层中的特征数量)。然后,单个步骤值将等于100除以对数。
在最后两行,我们只为我们的输出路线准备一个向量特征实例,并将其分配给之前定义的属性。
最短路径的查找是在循环中完成的,如下所示:
( 1) progress.setInfo('Finding shortest paths...')
( 2) for i in xrange(count):
( 3) nStart = tiedPoints[i]
( 4) nStop = tiedPoints[count + i]
( 5) idxStart = graph.findVertex(nStart)
( 6) idxStop = graph.findVertex(nStop)
( 7)
( 8) tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0)
( 9)
(10) if tree[idxStop] == -1:
(11) progress.setInfo('No path found from point ({:.6f}, {:.6f}) '
(12) 'to point ({:.6f}, {:.6f})'.format(
(13) nStart.x(), nStart.y(), nStop.x(), nStop.y()))
(14) else:
(15) nodes = []
(16) curPos = idxStop
(17) while curPos != idxStart:
(18) nodes.append(graph.vertex(
(19) graph.arc(tree[curPos]).inVertex()).point())
(20) curPos = graph.arc(tree[curPos]).outVertex()
(21)
(22) nodes.append(nStart)
(23) nodes.reverse()
(24)
(25) ft.setGeometry(QgsGeometry.fromPolyline(nodes))
(26) ft['id'] = i
(27) ft['startPoint'] = '({:.6f}, {:.6f})'.format(nStart.x(), nStart.y())
(28) ft['endPoint'] = '({:.6f}, {:.6f})'.format(nStop.x(), nStop.y())
(29) ft['length'] = ft.geometry().length()
(30) writer.addFeature(ft)
(31)
(32) progress.setPercentage(int(i * total))
在第一行,我们通知用户下一个算法步骤。在第3行和第4行,我们从绑定点的列表中获取下一个起点和终点的对。在接下来的两行中,我们获取这些点在道路图上的索引。
在第8行,实际路线计算发生。dijkstra()方法返回一个树,其中包含从具有idxStart索引的点(这是当前点对中的起点)到所有其他图节点的最短路径。
从第10行到第23行,我们遍历最短路径树,收集从终点到起点的所有形成路径的点。
之后,从第25行到第30行,我们从收集到的点创建一个线几何形状,将其分配给特征,并设置其属性。然后,将特征传递给写入对象并存储在输出层中。
最后,在第32行,我们更新进度条以通知用户算法的执行状态。
当所有点对都处理完毕后,我们需要进行清理并删除未使用的对象,例如道路图和输出写入器:
(1) del graph
(2) del writer
就这样!现在您可以保存脚本并通过在脚本 编辑器工具栏上点击运行算法按钮来测试它。算法对话框将看起来如下面的截图所示:

您可以从数据集中加载roads、start_points和end_points层,并使用这些数据运行算法。或者,您可以使用自己的带有道路网络的层,为起点和终点创建两个点层,用特征填充它们,并执行脚本。以下是一些可能的结果示例:

必须提到的是,虽然 QGIS 网络分析库提供了所有必要的网络分析工具,并且可以很容易地由用户扩展,但它也有一些限制,并且不适合处理非常大的密集道路网络。在这种情况下,最好使用更强大的工具,如 pgRouting。
写作帮助和保存
就像模型一样,记录您的脚本是一个好的做法。脚本的文档包含其描述以及所有输入和输出的信息。这有助于用户理解脚本的目的。
要为脚本创建帮助文件,请在内置的 Processing 脚本编辑器中打开它,并在编辑器工具栏上点击编辑 脚本 帮助按钮。一个帮助编辑器对话框,类似于我们在第八章的填充模型元数据和保存部分中看到的,使用处理模型自动化分析,将打开。

此对话框分为三个区域。在顶部是预览区域。在这里显示当前的帮助内容,以便您可以在实时模式下看到最终结果的外观。在左下角是元素树,其中列出了所有帮助部分,包括算法描述、参数、输入和其他信息。在右下角是编辑区域。在这里,我们将输入相应元素的描述。
要编辑元素的描述,请在元素列表中选择它,并在元素 描述字段中输入一些文本。要保存更改,只需在元素树中选择另一个元素。
遍历元素树中的所有项目并输入描述。例如,对于算法描述,您可以使用以下文本:
Calculates shortest path(s) between pairs of the start and end points on the given road network using QGIS network analysis library. Note: script does not takes into account road directions, all roads treated as two-ways roads.
您可以自己描述所有其他字段。尽量简短,同时尽可能提供尽可能多的有用信息。不要解释明显的事情;最好专注于重要细节。例如,在起点和终点层的描述中,值得提到的是它们中的特征数量应该相等。完成之后,点击确定按钮关闭帮助编辑器对话框。
要保存脚本帮助,请点击 脚本编辑器 工具栏上的 保存 按钮。脚本将被保存,其帮助将与之并排写入,脚本文件使用与脚本相同的名称,并添加 .help 后缀。
分享脚本
如果你创建了一个可能帮助其他用户的实用脚本,那么与社区分享它将是一个好主意,这样其他人就不需要重新发明轮子。
分享 Processing Python 脚本最明显且最简单的方法就是将其发送给感兴趣的人,或者上传到任何文件共享或托管网站,并使该文件的链接对每个人可用。有必要记住,与模型不同,脚本帮助存储在单独的文件中,而不是在脚本本身中。因此,在上传或发送时,你不应该忘记包括脚本帮助文件。
一种稍微复杂但同时也非常方便且用户友好的方法是,将你的脚本发布到 Processing 模型和脚本社区仓库。这个仓库是在 2014 年春季创建的,为 QGIS 用户之间共享 Processing 脚本和模型提供了一个集中的方式。
要将你的脚本放入仓库,你需要 fork GitHub 仓库 (github.com/qgis/QGIS-Processing),在你的 fork 中的脚本目录中提交你的脚本及其帮助文件,并发出一个 pull request。
小贴士
要了解更多关于 Git 的信息,请使用 Packt Publishing 的书籍之一,例如,Ravishankar Somasundaram 的 Git: Version Control for Everyone,并参考 GitHub 文档 help.github.com/。
另一个选项是将模型发送到 Qgis-developer 邮件列表,或者直接发送给 Processing 的开发者之一,并请他们将其放入仓库中。
要从该仓库获取脚本,请使用 从在线脚本集合获取脚本 工具,该工具位于 Processing 工具箱下的 脚本 项下的 工具 子组中。
摘要
在本章中,你学习了如何为 QGIS 处理框架开发自己的 Python 脚本,并利用它们自动化分析。Python 脚本是 Processing 模型的替代品,比模型提供了更多的灵活性。你学习了如何获取有关可用 Processing 算法的信息,以及如何从 Python 控制台调用它们。然后,你了解了 Processing 脚本的主要部分:包含元信息的头部和脚本主体。最后,我们开发了一个简单的脚本,用于计算给定道路网络中两点之间的最短路径。
在下一章中,你将了解另一种扩展 QGIS 功能的方法——通过开发你自己的 Python 插件。
第十章. 开发 Python 插件 – 以半径选择
虽然“处理”中的模型和脚本非常适合自动化不同的分析任务,但有时你可能想以另一种方式扩展 QGIS 的功能——通过开发一个插件。
在本章中,我们将讨论以下主题:
-
QGIS 插件
-
创建插件骨架
-
设计插件的 GUI
-
在插件中使用设计器 UI 文件
-
实现特征选择
-
添加翻译
-
准备插件以发布
QGIS 插件
从一开始,QGIS 就是以可扩展和模块化的架构开发的。最初,它只允许我们通过 C++插件来扩展其功能。但是,从版本 0.9 开始,当添加了对 Python 的支持后,用户和开发者能够使用 Python 编程语言创建插件。
每个 QGIS Python 插件都是一个 Python 模块和附加文件捆绑成的单个 Python 包。这些包应该放置在 QGIS 家目录下的一个特殊目录下的单独子目录中。通常,这是~/.qgis2/python/plugins,其中~是用户家目录(配置文件)目录。在 Windows 中,它是C:\Users\your_profile,而在类 UNIX 系统中,它是/home/your_profile。
最小工作插件应该包含这个目录下的两个文件:
-
__init__.py:这是包初始化文件和插件的入口点。它应该包含classFactory()方法。 -
metadata.txt:这个文件包含由插件管理器和插件网站使用的插件元数据。这些元数据包括插件名称、版本、描述和其他信息。
然而,真正的插件通常在其目录中包含许多其他文件:额外的源文件、GUI 表单、相应的逻辑源、图标和其他资源等。当然,所有这些文件都可以放置在插件的根目录下,但为了保持源树整洁且易于维护,文件通常组织在子目录中。例如,Qt Designer 表单放置在ui/子目录中,相应的逻辑源放置在gui/子目录下,图标和其他资源放置在resources/子目录中等。
要使用 Python 开发 QGIS 插件,你需要以下这些软件:
-
QGIS:这是用于测试和调试你的插件。最好使用与插件开发相同的 QGIS 版本。如果你想开发一个在多个 QGIS 版本上工作的插件,例如所有
2.x系列,尽可能使用较旧的版本,因为最新版本可能对 API 有一些小的添加。 -
文本编辑器或 Python IDE:在这里,你将编写你的代码。最好使用比标准记事本或其他任何纯文本编辑器更高级的工具。语法高亮、自动缩进和自动完成将使你的工作更加轻松和舒适。
-
Qt Designer:用于设计用户界面。对于 Windows,可以使用
OSGeo4W安装程序进行安装。相应的包称为qt4-devel。如果您是 Linux 用户,请使用您的包管理器查找并安装 Qt 开发工具。
此外,为了使调试更容易,我们建议您安装插件重载器插件。插件重载器极其有用,因为它允许您在单击一次后重新加载更改代码的插件,而无需重新启动 QGIS。
在本章中,我们将开发一个插件,用于选择位于指定矢量层中、围绕另一个层中已由用户选择的参考特征(已选择的特征)给定距离内的特征。
开发 QGIS Python 插件有两种方式:
-
在插件构建器插件的帮助下创建一个插件模板。然后,完善此模板并添加必要的功能。
-
通过创建所有必需的文件和代码手动开发插件。
第一种方法(使用插件构建器)是最常用的,许多作者推荐它作为新手最容易的方式。然而,有必要记住,虽然插件构建器是一个伟大且用户友好的工具,但它也隐藏了一些细节,强迫您使用特定的目录结构,并对您的插件如何工作做出了一些假设。此外,由该插件生成的模板将包含许多额外的文件,而在所有情况下这些文件并非都是必需的,例如帮助文件模板、单元测试数据、shell 脚本等。当然,所有这些文件都可以根据您的需要进行删除或调整,但您需要具备良好的知识以避免删除必要的文件。
在本章中,我们将通过逐步添加所需的文件和目录来手动创建插件。这使我们能够完全控制插件的结构和外观,并使我们更好地理解事物。
创建插件的骨架
让我们从开发我们的插件开始。在您的磁盘上的某个位置创建一个插件目录。由于我们的插件将在给定半径内选择特征,我们将其称为按半径选择,并使用selectradius作为插件目录的名称。
现在,打开您喜欢的文本编辑器并创建一个包含以下内容的文件:
[general]
name=Select by Radius
description=Select features in the given radius around another one
about=Selects features of the specified vector layer which are located within the given radius around reference pre-selected features of the any other layer
category=Vector
version=0.1.0
qgisMinimumVersion=2.8
author=enter_your_name_here
email=your@email
icon=icons/selectradius.svg
tags=vector,select,selection
homepage=
tracker=
repository=
experimental=True
deprecated=False
将其保存为插件目录中的metadata.txt。这是我们的插件元数据文件。如您所见,它具有非常简单的结构,类似于INI Windows 文件。只有一个名为general的部分,其中包含所有元数据项,以key=value格式表示。用于逻辑分组的元数据项之间的空字符串可以安全地删除。只要所有必要的项都存在且格式正确,元数据项的顺序并不重要。
所有元数据项可以分为两组:必需的和可选的。以下元数据项是必需的,并且应始终在metadata.txt文件中呈现:
-
name: 这是插件的名称。通常,它包含一个可读的名称。允许使用空格和其他字符,如 "
-"。 -
description: 这是插件的简短描述。通常,它是一句简短的句子。更详细的信息应放在可选的 "about" 项中。
-
version: 这是插件的版本,使用点分隔表示法,例如,
1.0.1(如果使用语义版本控制)。在此处避免添加如 "version" 这样的单词。 -
qgisMinimumVersion: 这定义了当前插件版本支持的最早 QGIS 版本。值应使用点分隔表示法;例如,如果插件与 QGIS 版本 2.0 以上兼容,则此项应将
2.0作为值。 -
author: 这是插件作者的姓名。将您的姓名作为值输入。
-
email: 这是插件作者的电子邮件。在此处提供您的有效电子邮件地址。请注意,此电子邮件地址不会在任何地方发布,并且仅在插件存储库管理员需要联系作者时使用。
所有其他元数据项都是可选的,可以是空的。以下是可选元数据项的完整列表:
-
about: 这包含有关插件的更详细信息。它补充了 "description" 元数据项中的信息。
-
category: 这是辅助元数据项。它帮助用户在安装后了解在哪个菜单中查找您的插件。支持的值有
Raster、Vector、Database和Web。例如,如果插件必须放置在 Vector 菜单下,则此元数据应具有Vector值。如果没有设置,则使用默认的Plugins值。请注意,此元数据仅用作参考。您需要自己编写代码以在正确的菜单中创建插件操作。 -
qgisMaximumVersion: 这定义了当前插件版本支持的最后一个 QGIS 版本。其值应使用点分隔表示法。通常,这不用。默认情况下,它等于
qgisMinimumVersion的主要数字加 0.99。例如,如果qgisMinimumVersion是2.0且未显式设置qgisMaximumVersion,则它将是2.99。此元数据仅在罕见情况下使用,即插件支持 QGIS 版本的有限子集或仅支持一个 QGIS 版本。 -
icon: 如果有,这是插件图标的文件名或路径。路径应相对于基本插件目录。如果没有设置,则使用默认图标。
-
tags: 这是一个用逗号分隔的标签列表,用于描述插件。尝试使用插件网站
plugins.qgis.org/上可用的现有标签。 -
changelog: 这是当前插件版本中的更改列表。这是一个多行项。
-
homepage: 如果有,这是插件主页的链接。如果您计划在 QGIS 官方插件存储库中发布您的插件,我们建议填写此元数据。
-
tracker:这是
bugtracker插件的链接(如果有)。如果您计划在 QGIS 官方插件仓库中发布您的插件,我们建议填写此元数据。 -
repository:这是插件源代码仓库的链接(如果有)。如果您计划在 QGIS 官方插件仓库中发布您的插件,我们建议也填写此元数据。
-
experimental:这是一个布尔标志,用于标记插件为实验性。实验性插件可能不稳定且部分功能不完整,因此除非设置了相应的选项,否则它们不会在 插件管理器 中显示。
-
deprecated:这是一个布尔标志,用于标记插件为已弃用。已弃用的插件不受作者支持,可能无法正常工作或可能工作不正确,因此除非设置了相应的选项,否则它们不会在插件管理器中显示。
如您所见,在我们的 metadata.txt 文件中,我们不仅包含了强制性的项目,还有一些可选项目,以向插件用户提供更多信息。请注意,我们的演示插件具有空的 homepage、tracker 和 repository 元数据项。在实际插件中,尤其是如果它将被发布,这些项应包含指向相应页面的有效链接,以便插件用户可以提交错误报告和补丁,并轻松找到相关文档。
此外,如果您查看 icon 元数据项,您会看到它包含到图像文件的相对路径。因此,在我们的插件目录中,有必要创建 icons 子目录并将 selectradius.svg 图标文件放入其中。图标可以是 Qt 库支持的任何光栅格式,但我们建议您使用 PNG 格式用于光栅图标,使用 SVG 格式用于矢量图标。图标的大小至少应为 24 x 24 像素。
下一步是创建一个插件(和 Python 包)初始化文件,__init__.py。此文件应包含一个 classFactory() 函数。当插件在 QGIS 中加载时,将调用此函数。函数体非常简短且简单:
(1) def classFactory(iface):
(2) from selectradius.selectradius_plugin import SelectRadiusPlugin
(3) return SelectRadiusPlugin(iface)
classFactory() 函数接受一个名为 iface 的单个参数——一个 QgsInterface 类的实例,它提供了对正在运行的 QGIS 复制的 GUI 的访问。它返回 SelectRadiusPlugin 对象,这是一个插件实例。SelectRadiusPlugin 类的代码,从 selectradius_plugin.py 文件导入,位于插件的根目录中。
现在,让我们实现主插件类。在插件根目录下创建一个名为 selectradius_plugin.py 的新文件,并将以下代码添加到其中:
( 1) import os
( 2)
( 3) from PyQt4.QtCore import (
( 4) QLocale, QSettings, QFileInfo, QCoreApplication, QTranslator)
( 5) from PyQt4.QtGui import (QMessageBox, QAction, QIcon)
( 6)
( 7) from qgis.core import QGis
( 8)
( 9) pluginPath = os.path.dirname(__file__)
(10)
(11)
(12) class SelectRadiusPlugin:
(13) def __init__(self, iface):
(14) self.iface = iface
(15)
(16) overrideLocale = QSettings().value('locale/overrideFlag', False, bool)
(17) if not overrideLocale:
(18) locale = QLocale.system().name()[:2]
(19) else:
(20) locale = QSettings().value('locale/userLocale', '')
(21)
(22) qmPath = '{}/i18n/selectradius_{}.qm'.format(pluginPath, locale)
(23)
(24) if QFileInfo(qmPath).exists():
(25) self.translator = QTranslator()
(26) self.translator.load(qmPath)
(27) QCoreApplication.installTranslator(self.translator)
(28)
(29) def initGui(self):
(30) self.actionRun = QAction(
(31) self.tr('Select by Radius'), self.iface.mainWindow())
(32) self.actionRun.setIcon(
(33) QIcon(os.path.join(pluginPath, 'icons', 'selectradius.svg')))
(34) self.actionRun.setWhatsThis(
(35) self.tr('Select features within given radius'))
(36) self.actionRun.setObjectName('SelectRadiusRun')
(37)
(38) self.actionAbout = QAction(self.tr('About'), self.iface.mainWindow())
(39) self.actionAbout.setIcon(
(40) QIcon(os.path.join(pluginPath, 'icons', 'about.png')))
(41) self.actionAbout.setWhatsThis(self.tr('About Select by Radius'))
(42) self.actionAbout.setObjectName('SelectRadiusAbout')
(43)
(44) self.iface.addPluginToVectorMenu(
(45) self.tr('Select by Radius'), self.actionRun)
(46) self.iface.addPluginToVectorMenu(
(47) self.tr('Select by Radius'), self.actionAbout)
(48) self.iface.addVectorToolBarIcon(self.actionRun)
(49)
(50) self.actionRun.triggered.connect(self.run)
(51) self.actionAbout.triggered.connect(self.about)
(52)
(53) def unload(self):
(54) self.iface.removePluginVectorMenu(
(55) self.tr('Select by Radius'), self.actionRun)
(56) self.iface.removePluginVectorMenu(
(57) self.tr('Select by Radius'), self.actionAbout)
(58) self.iface.removeVectorToolBarIcon(self.actionRun)
(59)
(60) def run(self):
(61) pass
(62)
(63) def about(self):
(64) pass
(65)
(66) def tr(self, text):
(67) return QCoreApplication.translate('SelectRadius', text)
在此代码的前七行中,我们从 Python 标准库、PyQt4 包和 qgis.core 库中导入所有必要的 Python 包。通常,这些导入语句在开发过程中基于迭代添加和编辑。换句话说,您编写代码,当需要新的类或库时,您添加相应的导入语句。按照规则,所有导入语句都放置在源文件的非常开始处。为了简化,在我们的示例插件中,我们将提供所有必要的导入。
在第 9 行,我们确定插件的路径,该路径将用于稍后构建图标的全路径。
在第 12 行,定义了一个基插件类。其中实现了几个方法。__init__() 方法,也称为构造函数,用于插件实例的基本初始化。在第 14 行,我们存储了对 QGIS 接口的引用——作为 iface 参数传递——以便在后续使用中可以访问和使用它。从第 16 行到第 27 行,激活了国际化支持。我们检查 QGIS 使用的区域设置,并尝试从插件树中的 i18n 子目录加载相应的翻译文件。如果没有找到翻译,则插件将以默认区域设置加载。
小贴士
我们建议您始终将英语作为插件的主要语言。请使用它来设置 GUI 小部件上的所有消息和标题。由于英语是最常见和广泛使用的语言,因此几乎所有的用户都可以使用该插件,即使没有翻译。如果需要,可以通过本地化机制轻松添加对任何其他语言的支持。
在插件基类中应该实现的下一种重要且强制性的方法是 initGui()。当插件被 QGIS 激活并加载时,会调用此方法。在这里,我们添加所需的 GUI 元素,例如菜单项、工具栏按钮,甚至停靠小部件。我们初始化插件所需的所有必要临时文件夹和其他东西。在我们的演示插件中,此方法从第 29 行开始。
从第 30 行到第 36 行,我们创建一个所谓的动作,该动作将启动插件对话框。动作是特殊对象,代表一个命令,并提供了一种统一的方式从不同的地方运行该命令,例如菜单和工具栏。首先,我们创建一个 QAction 实例,并将 Select byRadius 标签分配给它(第 30 行和第 31 行)。请注意,标签文本被包含在 self.tr() 方法调用中。此方法在提供的代码片段的最后两行实现,并使文本字符串可翻译。
然后,在第32行和第33行,我们为我们操作构造了一个图标。使用os.path.join()调用,我们创建了一个指向图标文件的完整路径,该图标文件位于插件树icons子目录中。这是我们在metadata.txt文件中指定的相同图标。当然,您可以使用另一个图标——只需将其放入插件树中的icons子目录即可。接下来,在第34行和第35行,我们为我们的操作设置了工具提示文本。请注意,我们在这里再次使用self.tr(),因此此文本也可以本地化。最后,在第36行,我们设置了操作的objectName属性。这个属性是 QGIS 自定义框架所必需的。
从第38行到42行,我们使用与前面相同的方法创建了另一个操作。此操作将用于显示包含有关我们插件信息的关于对话框。此操作的图标名为about.png,它位于插件树的icons子目录中。
然后,从第44行到45行以及第46行到47行,我们将我们的操作添加到按半径选择子菜单中,该子菜单将在 QGIS 的矢量菜单中创建。在第48行,我们将打开主插件对话框的按钮放入矢量工具栏中。
在此方法中的最后两行(50和51)用于将操作连接到处理程序,这些处理程序将在用户按下按钮或选择菜单项时执行。目前,这两个处理程序——run()和about()——都是空的,我们将在稍后向它们添加代码。
应该存在于插件基类中的第二个强制方法是unload()。当插件被停用并从 QGIS 中移除时,将执行此方法。在这里,我们应该移除插件的所有 GUI 元素(按钮、菜单项、小部件等)并执行任何其他所需的清理操作,例如删除临时文件。在我们的演示插件中,此方法在第53行定义。
由于我们的插件足够简单,我们只需从initGui()方法(第54行到57行)中移除添加的菜单项,以及工具栏按钮(第58行)。
在第60行到64行,我们为我们的操作定义了处理程序。目前,它们没有任何作用。
最后一个方法,tr(),正如我们之前提到的,是用于国际化支持所必需的。它接受英文文本并返回其翻译等效文本,这取决于当前的区域设置和翻译文件的存在。
注意
我们在这里自己实现tr()方法,因为主插件类是一个纯 Python 类。几乎所有的 Qt GUI 类都有内置的国际化支持,并且此方法已经存在于它们的代码中。因此,从它们继承的所有类也将具有tr()方法,您很快就会看到。
现在,我们的插件目录结构应该看起来像这样:

这样的插件骨架可以用作各种插件的开发起点。
到目前为止,我们的插件应该可以被 QGIS 加载。您可以轻松地检查这一点——只需将插件目录复制到 QGIS 插件目录,~/.qgis2/python/plugins。启动 QGIS,通过转到插件 | 管理并安装插件…来打开插件管理器。您应该在已安装选项卡中看到按半径选择插件。激活后,插件将被加载,矢量工具栏上会放置一个新按钮,矢量菜单中会出现一个包含两个条目的新条目。但在这个阶段,这些条目没有任何作用。我们需要实现它们的功能。
设计插件的 GUI
我们插件将有两个对话框:一个是主插件对话框,它将用于接受用户输入;第二个是所谓的“关于”对话框,其中包含有关插件的一些信息。
QGIS 所构建的 Qt 框架提供了一个用于设计对话框和其他 UI 元素(如停靠小部件)的特殊程序。它被称为Qt Designer。Qt Designer 是一个用户友好且易于使用的可视化表单设计器。借助它的帮助,您可以通过使用鼠标在表单上放置 GUI 小部件来创建对话框,而无需编写代码。然后,将表单定义以 XML 格式保存到.ui文件中,该文件由插件或应用程序用于构建用户界面。
为了保持插件结构的整洁,我们将把所有的.ui文件放在一个单独的子目录中,例如,在插件源树中命名为ui。
设计“关于”对话框
启动 Qt Designer。在新建表单欢迎对话框中,选择名为底部按钮对话框的模板,如下所示:

如果在 Designer 启动时没有打开此对话框,请转到文件 | 新建...或使用Ctrl + N键盘快捷键。将创建一个新的空 Qt 表单,底部有两个按钮。
首先,我们将创建“关于”对话框。我们希望在对话框中显示以下信息:插件名称、图标、版本号以及简短描述,可能包含对插件主页和/或错误跟踪器的链接。
在属性编辑器面板(通常位于设计器窗口的右上角),找到windowTitle属性并将其更改为有意义的名称,例如,关于按半径选择。返回到表单并选择按钮框。现在它应该带有蓝色的方块标记。返回到属性编辑器,找到standardButtons属性并清除除关闭按钮之外的所有变体的复选框。因此,现在我们的按钮框只有一个按钮。
现在,在小部件框面板(通常位于设计器窗口的左侧),找到标签小部件,它位于显示小部件组中,并将其拖放到表单中。保持新添加的小部件选中状态,转到属性编辑器并将objectName属性设置为lblLogo。这个小部件将用于显示插件图标。
小贴士
小部件的objectName属性将在我们的代码中用于访问相应的部件。因此,请尝试为所有计划从代码中访问的小部件分配有意义的对象名称。
类似地,向表单中添加另一个标签小部件,并将其放置在之前添加的小部件的右侧。然而,这次不要更改其objectName属性。相反,找到text属性,并按编辑字段右侧标有…的按钮。将打开一个简单的文本编辑器,如下所示:

输入插件名称,然后将字体大小更改为更大的值,例如,16。使字体加粗并将文本居中对齐。通过单击确定按钮关闭编辑器。还要修改alignment属性以启用水平居中对齐。
在表单中添加一个第三标签,该标签将用于显示插件版本,并将其objectName属性更改为lblVersion。修改alignment属性以启用水平居中对齐。将此标签移动到插件名称标签下方。最后,将TextBrowser小部件添加到表单中,并将其放置在所有标签下方。
Qt 使用基于布局的方法来管理小部件,因此无论使用何种主题和字体,您的表单都将始终看起来一致。为了在我们的表单中启用布局,我们只需选择表单并单击工具栏上的在网格中布局按钮,或从表单菜单中选择此选项。
注意
关于 Qt 布局系统的更多信息可以在 Qt 文档中找到,请参阅doc.qt.io/qt-4.8/layout.html。如果你想要创建看起来不错的对话框,这是一篇必读的信息。
现在您的表单应该看起来像以下截图所示:

如果某些小部件放置不正确,请尝试移动它们并调整它们的大小。当你对对话框的外观和感觉满意时,将其保存为aboutdialogbase.ui,位于插件根目录下的ui子目录中。
设计主插件对话框
关闭已保存的关于对话框,并使用相同的带按钮底部的对话框模板创建一个新的空表单作为主插件对话框。将对话框的windowTitle属性更改为按半径选择,并通过更改其standardButtons属性调整按钮框,使其包含两个按钮:确定和关闭。
我们需要指定一个目标层,从该层中我们将选择特征。在小部件框面板的显示小部件部分添加一个标签小部件,并将其text属性更改为从中选择特征。现在需要提供一个用户可以选择要使用的层的控件。组合框是一个不错的选择,但还有一个更好的解决方案。从版本 2.4 开始,QGIS 为 Qt Designer 提供了一套自定义小部件。在这些小部件中,有一个特殊的选择框,称为QgsMapLayerComboBox。它被设计用来显示来自 QGIS 层注册表的层列表。这个控件,以及所有其他与 QGIS 相关的自定义小部件,可以在小部件框面板的QGIS 自定义小部件部分找到。
注意
在这里有必要提到,QGIS 自定义小部件部分可能不在您的系统中可用。如果您找不到它,请确保您已安装所有 QGIS 相关包(例如,名为libqgis-customwidgets的 Debian 包)。
或者,您可以使用序数组合框代替QgsMapLayerCombobox,但在这种情况下,您将需要自己实现代码来填充它以及通过名称检索层的代码。
将一个QgsMapLayerComboBox组合框拖放到表单上,将其放置在之前添加的标签的右侧,并更改其objectName属性为cmbTargetLayer。默认情况下,QgsMapLayerCombobox将显示栅格层、具有多边形几何类型的矢量层和插件层。这不适合我们,因为我们只需要矢量层。要更改此行为,找到filters属性,并清除除PointLayer、LineLayer和PolygonLayer之外的所有变体的复选框(这也会自动激活HasGeometry选项)。现在,这个组合框将只显示之前指定的几何类型的矢量层。栅格层、插件层和没有几何的矢量层将不会显示在其中。
此外,我们还需要指定另一个层——参考层。因此,在表单中添加另一个标签小部件,并将其text属性更改为从参考特征周围选择。在这个标签附近,放置第二个QgsMapLayerComboBox组合框,并将其objectName属性更改为cmbReferenceLayer。对其应用与之前添加的QgsMapLayerCombobox组合框相同的过滤器。
我们还需要另一个输入值,即搜索半径。因此,在表单中添加另一个标签小部件,位于已添加的小部件下方。将其text属性设置为在搜索半径内。在这个标签的右侧,放置一个双精度微调框(可在输入小部件部分找到),并将其objectName属性更改为spnRadius。同时调整其minimum、maximum和value属性到合理的值。
为了使插件更加有用和灵活,我们为用户提供了一种选择来使用所选功能的方式:创建一个新的选择,或者修改现有的选择。表示可用选择的更合理方式是组合框。从显示小部件部分添加另一个标签到表单中,并将其text属性更改为Use the result to。在这个标签的右侧放置组合框(可在输入小部件部分找到)。将新添加的组合框的objectName属性更改为cmbSelectionMode。
将进度条(可在工具箱面板的显示小部件部分找到)放在最后一个标签和组合框下面,并将它的value属性更改为zero。
选择对话框,通过点击设计师工具栏中的在网格中布局按钮将其应用网格布局。现在您的表单应该看起来像这个截图所示:

如果某些小部件位置不正确,尝试移动它们并调整它们的大小。一旦您对对话框的外观和感觉满意,将其保存在插件根目录下的ui子目录中,命名为selectradiusdialogbase.ui。
如您所见,使用 Qt Designer 设计用户界面并没有什么复杂之处。这里最重要的是理解不同类型的布局是如何工作以及如何符合相应项目的人机界面指南(HIG)的建议。QGIS HIG 可以在 QGIS 源代码中的CODING文档中找到。您可以在github.com/qgis/QGIS/blob/master/CODING#L1429在线查看。
在插件中使用设计师 UI 文件
使用 Qt Designer 设计 GUI 是这个过程的第一部分。现在我们需要使用之前创建的.ui文件来构建我们的对话框并实现处理用户操作所需的逻辑,例如点击按钮、从列表中选择项目等。
将关于对话框添加到插件中
我们将从关于对话框开始,因为它很简单。为了保持插件目录结构的整洁,我们将所有与插件 GUI 相关的源代码存储在插件目录内的gui子目录中。
打开您的文本编辑器,创建一个包含以下内容的新的文件:
( 1) import os
( 2) import ConfigParser
( 3)
( 4) from PyQt4 import uic
( 5) from PyQt4.QtCore import QUrl
( 6) from PyQt4.QtGui import QTextDocument, QDialogButtonBox, QPixmap
( 7)
( 8) pluginPath = os.path.split(os.path.dirname(__file__))[0]
( 9) WIDGET, BASE = uic.loadUiType(
(10) os.path.join(pluginPath, 'ui', 'aboutdialogbase.ui'))
(11)
(12)
(13) class AboutDialog(BASE, WIDGET):
(14) def __init__(self, parent=None):
(15) super(AboutDialog, self).__init__(parent)
(16) self.setupUi(self)
(17)
(18) cfg = ConfigParser.SafeConfigParser()
(19) cfg.read(os.path.join(pluginPath, 'metadata.txt'))
(20) version = cfg.get('general', 'version')
(21)
(22) self.lblLogo.setPixmap(
(23) QPixmap(os.path.join(pluginPath, 'icons', 'selectradius.svg')))
(24) self.lblVersion.setText(self.tr('Version: %s') % version)
(25)
(26) doc = QTextDocument()
(27) doc.setHtml(self.getAboutText())
(28) self.textBrowser.setDocument(doc)
(29) self.textBrowser.setOpenExternalLinks(True)
(30)
(31) def getAboutText(self):
(32) return self.tr(
(33) '<p>Select features of the specified vector layer within given '
(34) 'radius around pre-selected reference features from the another '
(35) 'vector layer.</p>'
(36) '<p>Developed as demo plugin for the "QGIS By Example" book by '
(37) '<a href="https://www.packtpub.com/">Packt Publishing</a>.</p>')
将此文件保存在gui子目录下,命名为aboutdialog.py。
在文件的开始部分,从第1行到第6行,我们导入了我们稍后将要使用的所有包和类。在这里,我们使用了 Python 标准库(os和ConfigParser包)以及各种PyQt类(第4行到第6行)。
在第8行,我们确定插件路径,因为我们需要它来构建对话框.ui文件和插件图标的完整路径。
最有趣的部分是第9行和第10行,实际上这是一条命令由于长度原因被拆分成了两行。在这里,我们使用 Qt Designer 加载我们之前创建的.ui文件。uic.loadUiType()命令返回两个值:我们的自定义对话框(存储为WIDGET变量)及其基类(存储为BASE变量)。使用uic可以让我们避免编译 UI 文件,并使插件打包更加简单。
在第13行,开始实现AboutDialog类,它将代表我们的关于对话框。注意,在类定义中,我们使用了从uic.loadUiType()调用中获得的BASE和WIDGET变量。
__init__()方法,也称为构造函数,执行基本的类初始化。在第15行和第16行,我们设置了对话框 GUI。在这些行之后,我们可以使用self.widgetName访问所有对话框小部件,其中widgetName是对应小部件objectName属性的值。这就是为什么为所有将在代码中使用的小部件指定有意义的唯一对象名称很重要的原因。
从第18行到第20行,我们使用 Python 标准库中的ConfigParser模块从metadata.txt文件中读取插件版本。当然,我们可以手动输入版本号,但在这种情况下,每次插件版本更改时,我们都需要编辑两个文件(metadata.txt和aboutdialog.py),而不是一个。
然后,在第22行和第23行,从图标文件的路径构建插件图标,并将其加载到相应的小部件对话框中。在第24行,插件版本在lblVersion标签小部件中显示。
最后,在第26行到第29行,我们实例化了QTextDocument对象,该对象将用于显示关于文本,并将其分配给QTextBrowser小部件。第29行允许用户通过点击来打开链接。
关于对话框的文本是通过第31行到第37行中实现的getAboutText()方法生成的。实现很简单——我们只是返回一个包含插件简短描述的字符串,格式为 HTML。这里唯一重要的是使用self.tr()方法,它允许我们显示翻译后的关于文本。
小贴士
想了解更多关于 Qt 类、它们的目的和功能的信息,请查看 Qt 文档,网址为doc.qt.io/qt-4.8/index.html。
你可能会问为什么我们没有实现任何处理对话框执行和关闭的方法。嗯,因为这个对话框非常简单,我们不需要执行任何特殊操作。我们可以使用默认的处理程序,这些处理程序是在基QDialog类中实现的。这意味着对话框将以模态方式打开,点击关闭按钮将关闭它。
那就是全部了!现在我们需要将这个对话框添加到插件主类中。首先,在gui子目录中创建一个空的__init__.py文件,这样 Python 就会将其识别为包目录。
现在,打开 selectradius_plugin.py 文件。在文件开头的导入部分,添加以下代码行:
from selectradius.gui.aboutdialog import AboutDialog
这行代码使 AboutDialog 类可以从主插件类中访问。现在,找到 about() 方法并按如下方式修改:
(1) def about(self):
(2) d = AboutDialog()
(3) d.exec_()
这里没有什么特别之处。首先,我们实例化 AboutDialog 并执行它。保存您的编辑。如果您愿意,您可以在 QGIS 插件目录中更新插件文件,或者将整个插件目录复制到这里。使用 Plugin Reloader 重新加载插件,并确保现在当您从 Select by Radius 菜单中选择 About 项时,会显示一个 About 对话框。
添加主插件对话框
现在,让我们实现主插件对话框。创建一个新文件,并将其保存在插件目录的 gui 子目录中,命名为 selectradiusdialog.py。由于这个对话框比较复杂,我们将代码分成小块,并将逐一检查它们。
正如您应该已经知道的,我们首先导入所有必要的类:
(1) import os
(2)
(3) from PyQt4 import uic
(4) from PyQt4.QtCore import QSettings
(5) from PyQt4.QtGui import QDialogButtonBox, QDialog
(6)
(7) from qgis.core import QgsGeometry, QgsFeatureRequest, QgsSpatialIndex
(8) from qgis.gui import QgsMessageBar
除了 Python 标准库和 PyQt 类之外,我们还从 qgis.core 和 qgis.gui 库中导入几个类。
然后,就像 AboutDialog 的情况一样,我们确定插件路径并从 Qt Designer 文件中加载对话框 GUI:
(1) pluginPath = os.path.split(os.path.dirname(__file__))[0]
(2) WIDGET, BASE = uic.loadUiType(
(3) os.path.join(pluginPath, 'ui', 'selectradiusdialogbase.ui'))
准备工作已完成。现在我们可以定义主对话框类:
( 1) class SelectRadiusDialog(BASE, WIDGET):
( 2) def __init__(self, iface, parent=None):
( 3) super(SelectRadiusDialog, self).__init__(parent)
( 4) self.setupUi(self)
( 5)
( 6) self.iface = iface
( 7)
( 8) self.btnOk = self.buttonBox.button(QDialogButtonBox.Ok)
( 9) self.btnClose = self.buttonBox.button(QDialogButtonBox.Close)
(10)
(11) self.cmbSelectionMode.clear()
(12) self.cmbSelectionMode.addItem(self.tr('Create new selection'))
(13) self.cmbSelectionMode.addItem(self.tr('Add to current selection'))
(14) self.cmbSelectionMode.addItem(self.tr('Remove from current selection'))
(15)
(16) self.loadSettings()
首先,我们初始化对话框 GUI(行 3 到 4)。在行 6,我们存储对 QGIS 接口的引用,以便以后使用。
在行 8 和 9,我们获取对话框按钮框中单独按钮的引用,因为我们稍后需要将它们作为独立的小部件访问。从行 11 到 14,cmbSelectionMode 组合框被填充了可用的选择模式。为了保持项目文本可翻译,我们将它包装在 self.tr() 调用中。值得注意的是,组合框项有零基编号,因此第一个项将具有索引 0,第二个项将具有索引 1,依此类推。从代码中填充组合框使我们能够轻松检查项目顺序并确定它们的索引。项目索引将稍后用于确定用户选择。
最后,在行 16,我们从之前的运行中恢复插件的设置。
我们的插件足够简单,所以我们只想在设置中保存和恢复几个值。每次用户打开插件对话框时,我们希望恢复之前输入的搜索半径值和从 Use the result to 组合框中使用的最后一种选择模式:
( 1) def loadSettings(self):
( 2) settings = QSettings('PacktPub', 'SelectRadius')
( 3)
( 4) self.spnRadius.setValue(settings.value('radius', 1, float))
( 5) self.cmbSelectionMode.setCurrentIndex(
( 6) settings.value('selectionMode', 0, int))
( 7)
( 8) def saveSettings(self):
( 9) settings = QSettings('PacktPub', 'SelectRadius')
(10)
(11) settings.setValue('radius', self.spnRadius.value())
(12) settings.setValue(
(13) 'selectionMode', self.cmbSelectionMode.currentIndex())
当我们想要恢复插件的设置时,会调用 loadSettings() 方法。在插件的第一次运行中,我们没有保存的设置,所以将选择默认值。saveSettings() 方法用于将当前值从小部件保存到插件设置中。
由于我们希望在用户通过点击关闭按钮关闭主插件对话框时保存设置,并且需要在用户点击确定按钮时启动数据采集过程,因此有必要替换这些信号的默认处理程序。相应的代码如下:
( 1) def reject(self):
( 2) self.saveSettings()
( 3) QDialog.reject(self)
( 4)
( 5) def accept(self):
( 6) self.saveSettings()
( 7)
( 8) targetLayer = self.cmbTargetLayer.currentLayer()
( 9) if targetLayer is None:
(10) self.showMessage(
(11) self.tr('Target layer is not set. '
(12) 'Please specify layer and try again,'),
(13) QgsMessageBar.WARNING)
(14) return
(15)
(16) referenceLayer = self.cmbReferenceLayer.currentLayer()
(17) if referenceLayer is None:
(18) self.showMessage(
(19) self.tr('Reference layer is not set. '
(20) 'Please specify layer and try again.'),
(21) QgsMessageBar.WARNING)
(22) return
(23)
(24) referenceFeatures = referenceLayer.selectedFeatures()
(25) if len(referenceFeatures) == 0:
(26) self.showMessage(
(27) self.tr('There are no reference features selected in the '
(28) 'reference layer. Select at least one feature and '
(29) 'try again.'),
(30) QgsMessageBar.WARNING)
(31) return
当用户点击关闭按钮时,会调用第1行的reject()方法。此方法最初在基类QDialog中实现,并在我们的子类中重新实现。我们在这里做的唯一事情是保存当前的插件设置(第2行)。之后,我们简单地调用基类的reject()方法(第3行)来关闭我们的对话框。
定义在第5行的accept()方法在用户点击确定按钮时被调用。此方法最初在基类QDialog中实现,并在我们的子类中重新实现。当用户点击确定按钮时,插件应检查是否指定了所有必需的参数,从目标层中找到所有符合定义要求的功能,并最终更新目标层中的选择。
首先,在第6行,我们保存当前的插件设置。然后,我们检查用户是否选择了所有必要的输入。在第8行,我们使用QgsMapLayerCombobox的currentLayer()方法来获取当前选定的目标层。如果选择了图层,此方法返回相应的QgsMapLayer实例,否则返回None。
小贴士
关于 QGIS API 的文档可以在qgis.org/api/找到。另外,别忘了查看PyQGIS 开发者手册,其中包含不同主题的详细解释和许多有用的示例。您可以在docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/index.html在线阅读最新的PyQGIS 开发者手册。
注意
注意,由于 API 的变化,最新版本的 PyQGIS 开发者手册中的某些示例可能无法与较旧的 QGIS 版本兼容。
如果没有选择目标层(这在第9行进行检查),我们将使用showMessage()方法(第10至13行)显示警告消息,并返回主插件对话框(第14行)。换句话说,我们不尝试执行任何进一步的操作,因为我们有不完整或无效的输入。用户应指定正确的输入,然后重试。
使用相同的方法,我们检查是否选择了有效的参考层(第16至22行)。
在第24行,我们从参考层中获取预选的参考特征列表。如果参考层中没有选择参考特征,此列表的长度将为零。我们需要捕获这种情况,因为没有参考特征,我们无法继续。这就是第25至31行发生的事情;如果在参考层中没有选择参考特征,我们将显示相应的消息并返回主插件对话框。
目前为止,我们为accept()方法编写的代码就是这些。
你可能已经注意到了在前面代码中广泛使用的showMessage()方法。以下是它的实现:
(1) def showMessage(self, message, level=QgsMessageBar.INFO):
(2) self.iface.messageBar().pushMessage(
(3) message, level, self.iface.messageTimeout())
这只是一个包装器,它使用与全局 QGIS 设置中定义的相同超时显示给定文本和重要性级别的消息栏。默认情况下,将使用INFO级别,但如果需要,我们可以指定任何其他支持的水平。
如你所见,到目前为止,我们只实现了主插件对话框的基本功能。
现在,我们需要将主对话框添加到插件基类中。为此,打开selectradius_plugin.py文件,如果尚未打开。在文件开头的导入部分,添加以下代码行:
from selectradius.gui.selectradiusdialog import SelectRadiusDialog
这行代码使得SelectRadiusDialog类可以从主插件类中访问。现在,找到run()方法,并按如下方式修改它:
(1) def run(self):
(2) dlg = SelectRadiusDialog(self.iface)
(3) dlg.exec_()
再次,这里没有什么特别之处。首先,我们实例化SelectRadiusDialog,然后以模态对话框的形式打开它,就像我们之前为关于对话框所做的那样。
保存你的编辑。如果你想,你可以更新 QGIS 插件目录中的插件文件,或者将整个插件目录复制到这里。使用插件重载器重新加载插件,并确保现在当你从按半径选择菜单中选择按半径选择项时,会显示主插件对话框。
实现特征选择
现在,当对话框创建并连接到我们的插件时,我们可以开始实现主要功能——即使用用户定义的要求进行特征选择。
打开位于插件源树gui子目录中的selectradiusdialog.py文件。在accept()方法的末尾添加以下代码:
( 1) self.btnOk.setEnabled(False)
( 2) self.btnClose.setEnabled(False)
( 3)
( 4) request = QgsFeatureRequest()
( 5) request.setFlags(
( 6) request.flags() ^ QgsFeatureRequest.SubsetOfAttributes)
( 7)
( 8) index = QgsSpatialIndex(targetLayer.getFeatures(request))
( 9)
(10) selection = []
(11) for f in referenceFeatures:
(12) geom = QgsGeometry(f.geometry())
(13) bufferedGeometry = geom.buffer(self.spnRadius.value(), 5)
(14)
(15) intersectedIds = index.intersects(bufferedGeometry.boundingBox())
(16)
(17) self.progressBar.setRange(0, len(intersectedIds))
(18)
(19) for i in intersectedIds:
(20) ft = targetLayer.getFeatures(request.setFilterFid(i)).next()
(21) geom = ft.geometry()
(22) if geom.within(bufferedGeometry):
(23) selection.append(i)
(24)
(25) self.progressBar.setValue(self.progressBar.value() + 1)
(26)
(27) if self.cmbSelectionMode.currentIndex() == 1:
(28) selection = list(
(29) set(targetLayer.selectedFeaturesIds()).union(selection))
(30) elif self.cmbSelectionMode.currentIndex() == 2:
(31) selection = list(
(32) set(targetLayer.selectedFeaturesIds()).difference(selection))
(33) targetLayer.setSelectedFeatures(selection)
(34)
(35) self.progressBar.reset()
(36) self.btnOk.setEnabled(True)
(37) self.btnClose.setEnabled(True)
(38) self.showMessage(self.tr('Completed.'), QgsMessageBar.SUCCESS)
到目前为止,我们已经确保所有必要的输入字段都已正确定义(参见上一节),现在我们可以安全地进行特征选择。
首先,有必要阻止确定和关闭按钮,以防止意外点击,这可能会中断运行中的进程。我们在第1行和第2行这样做。
我们插件需要从矢量图层请求功能。正如你所知,每个功能都有几何形状和属性,并且默认情况下,当我们从图层查询一个功能时,几何形状和属性都会被返回。对于我们来说,我们只需要功能几何形状,所以最好不要查询属性。这将加快功能检索的过程,尤其是在图层有一个大的属性表或者通过慢速网络连接访问时。
因此,在第4行,我们实例化QgsFeatureRequest对象,该对象用于自定义特征检索的过程。从第5行到第6行,我们通过重置其SubsetOfAttributes标志来改变其默认行为(获取几何形状和属性),以便只获取特征几何形状。
然后,我们在目标层上构建空间索引(第8行)。空间索引允许我们对层执行快速查询,并仅获取与某些区域相交或位于给定坐标附近的特征。空间索引还可以通过限制我们应该测试的空间运算符的特征数量来减少处理时间。
现在,我们已经准备好在目标层中搜索位于参考特征给定半径范围内的特征。但首先,我们需要创建一个列表,我们将在此列表中存储此类特征的标识符。这是在第10行完成的。
在第11行,我们开始遍历参考特征(我们已经在referenceFeatures列表中有了它们;详见前文部分以获取详细信息)。对于每个参考特征,我们获取其几何形状(第12行),并使用给定的半径在其周围创建缓冲区(第13行)。作为缓冲距离,我们使用用户定义的搜索半径,该半径通过spnRadius微调框设置。buffer()调用中的第二个参数是用于逼近曲线的段数。更大的值将导致更平滑的曲线和更准确的结果,但也会略微增加处理时间。如果你想要更改此值,请随意。
然后,在第15行,借助空间索引,我们确定目标层中哪些特征可能位于缓冲几何形状内,该几何形状代表当前参考特征。intersects()方法返回所有与给定几何形状边界框相交的特征的标识符。在我们的情况下,这是当前参考几何形状。
在第17行,我们更新进度条的范围。它将被用来提供关于过程执行的视觉反馈。
由于空间索引执行与边界框的交集测试,我们现在应该精确地测试每个匹配的特征。这是从第19行到第25行完成的。让我们更仔细地看看。在第19行,一个循环开始遍历匹配特征索引。在循环中,我们通过其标识符获取一个特征(第20行)。请注意,我们再次使用之前创建的request来仅获取特征几何形状。然后,提取特征几何形状(第21行),并检查此几何形状是否完全位于缓冲的参考几何形状内(第22行)。如果满足此条件,特征标识符将被添加到列表中(第23行)。
注意
如果你想要使用其他标准(例如,选择与参考几何相交的特征)来选择特征,请将within()运算符替换为所需的运算符。可以在QgsGeometry类的 API 文档中找到可用运算符的列表,链接为qgis.org/api/classQgsGeometry.html。
最后,在第25行,我们更新进度条以通知用户进度。
当所有参考特征都处理完毕,并且匹配特征的标识符存储在selection列表中后,我们可以根据请求的选择模式在目标层中选择特征(第27至33行)。首先,我们使用第27行和第30行的条件来确定我们需要使用哪种选择模式。由于选择模式是依次添加到相应的组合框中的(一个接一个),第一个添加的项目(创建新选择)将具有索引0,第二个项目(添加到当前选择)将具有索引1,依此类推。因此,如果cmbSelectionMode组合框当前选中项的索引等于1,则用户将被要求添加特征到当前选择。这意味着组合框索引与项目添加的顺序相匹配。
当选择模式确定后,我们通过添加或删除已选特征的索引来修改所选特征的列表(第28至29行和第31至32行)。最后,在第33行,我们在目标层中选择特征。
我们几乎完成了;现在需要执行一些最终操作。在第35行,我们重置进度条,使其回滚并显示任何进度。然后,我们启用确定和关闭按钮,以便用户可以更改参数并再次运行该过程,或者关闭插件对话框。在第38行,我们通知用户操作已完成。
如果你已正确完成所有编辑,你的插件现在应该完全功能正常,并准备好进行测试。只需通过复制工作目录的内容更新 QGIS 插件目录中的插件文件,使用插件重载器重新加载插件,并对其进行测试。如果有任何错误,请再次检查你的代码或查看本书附带的全套插件代码。
添加翻译
如果你遵循了我们的建议,并使用英语为插件 GUI 中的所有标题以及代码中的所有字符串,那么几乎所有的用户都将能够使用你的插件。此外,由于我们已经通过将它们包含在self.tr()调用中来使所有字符串可翻译,因此将我们的插件翻译成另一种语言非常容易。
要做到这一点,我们需要准备一个所谓的项目文件。这是一个结构非常简单的纯文本文件。创建一个新文件,并将其保存为selectradius.pro在插件根目录下。然后,向其中添加以下内容:
( 1) SOURCES = __init__.py \
( 2) selectradius_plugin.py \
( 3) gui/selectradiusdialog.py \
( 4) gui/aboutdialog.py \
( 5)
( 6) FORMS = ui/selectradiusdialogbase.ui \
( 7) ui/aboutdialogbase.ui
( 8)
( 9) TRANSLATIONS = i18n/selectradius_uk.ts \
(10) i18n/selectradius_de.ts
如你所见,有一个列表列出了所有子目录中的插件源文件(第1至4行),以及所有 Qt Designer UI 文件的列表(第6至7行)。最后,在第9至10行,有一个将要生成的翻译文件列表(在这个例子中,我们有乌克兰语和德语)。
从前面的代码中,你可以看到我们将保留翻译在i18n子目录中,因此如果它还不存在,请创建它。
现在打开命令行窗口(在 Windows 的情况下是 OSGeo shell),使用cd命令切换到插件目录,并运行以下命令:
pylupdate4 -verbose selectradius.pro
这将生成项目文件中指定的每种语言的所需 .ts 文件。这些文件包含插件源代码和 UI 表单中的所有可翻译字符串。使用 Qt Linguist,.ts 文件被翻译并“发布”。在这里,“发布”的意思是将 .ts 文件转换为二进制的 .qm 文件,该文件可以被 Qt 翻译系统使用。
必须指出,在更改字符串或添加新文件(源或 UI)之后,必须更新项目文件并重新生成翻译。不用担心已经翻译的字符串;它们将被保留,你只需要翻译新或修改的字符串。
准备插件以发布
一旦插件准备就绪并且经过充分测试,你可能希望通过将其上传到官方 QGIS Python 插件仓库 plugins.qgis.org/ 与社区分享。
首先,有必要检查插件是否符合以下要求:
-
其中没有恶意代码
-
没有架构相关的二进制文件
-
它包含正确的
metadata.txt文件,其中包含所有必需的项目
我们在这里列出了最重要的要求。其他建议可以在插件仓库页面和 PyQGIS 开发者手册 的 发布你的插件 章节中找到。
下一步是准备插件包。QGIS 插件以 ZIP 归档的形式分发,每个归档只包含一个插件。由于插件被提取到 QGIS 插件目录中,我们必须确保插件在包内有自己的文件夹。
此外,将仅包含插件绝对需要的文件包含在插件包中是一种良好的做法,并省略任何生成的或辅助文件。由于我们动态加载 UI 文件和图标,我们拥有的唯一辅助文件是项目文件和 .ts 文件(.qm 文件也应包含,因为它们被 Qt 翻译系统使用)。因此,我们的插件包内容将如下所示:

当插件包创建完成后,只需使用你的 OSGeo ID 登录 QGIS 插件网站。在顶部菜单中,选择 插件。然后,在页面左侧,点击 分享插件 按钮,上传你的插件包。
小贴士
如果你需要创建一个 OSGeo ID,请访问 OSGeo 门户 www.osgeo.org/osgeo_userid。
就这些了!现在你的插件对所有 QGIS 用户都可用。别忘了创建一个带有关于你的插件文档的 bug 跟踪器和主页,以便用户可以发送有关错误和功能请求的报告。
摘要
在本章中,你学习了如何使用 Python 编程语言开发 QGIS 插件。Python 插件使我们能够通过添加新工具或实现新的分析或地理处理算法来扩展 QGIS 的功能。你熟悉了插件架构及其主要组件。然后我们创建了插件骨架,它可以被许多插件使用。你学习了如何使用 Qt Designer 创建对话框并在插件中使用它们。最后,我们开发了一个简单的插件,用于选择位于任何其他图层参考预选特征给定半径内的指定矢量图层中的要素。













和显示 日志消息 面板的按钮
。
,或者使用Ctrl + Shift + R键盘快捷键来加载数据栅格文件。
。

从坐标参考系统选择器对话框窗口中选择必要的 CRS。
,或从表菜单访问它。

,添加 SpatiaLite 图层按钮,在图层管理工具栏中
,添加组按钮,从图层工具栏。新组将出现在图层列表的底部。输入一个合适的名称,然后将图层拖放到组中。


,符号更改按钮,以打开符号选择器对话框,如图所示。激活必要的符号层,将其大小单位更改为地图单位,并输入
)定义缩放范围,该按钮会打开一个对话框以定义最小和最大缩放值。


或删除规则 





















和 向上
按钮用于移动项并更改它们的顺序。否则,您可以直接拖放项到新位置。任何更改后,图例的项内容将立即更新。
按钮允许您添加新组和子组以构建图例层次结构。
按钮负责添加和删除任何项,无论是组还是图层。请注意,只有主地图画布窗口中激活的图层才可用于添加。
按钮允许我们更改任何选定项(组、子组、图层或符号标签)的文本。例如,如果您想将长行换行,可以在 主属性 部分定义的文本符号中插入。这些更改仅应用于 打印作曲家图例 项,不会影响主窗口中的地图项。
按钮显示矢量图层每个类的要素计数。
按钮通过地图内容过滤图例;也就是说,只有显示在地图项中的图例项(图层和类)将被包括在图例中。
:这提供了对文本(或 HTML)标签及其各种属性的控制,例如字体、字体颜色、垂直和水平(对齐)、位置和大小、旋转等。
:这允许您向布局添加简单的几何图形,例如矩形、三角形或椭圆。在项目属性选项卡中,您可以更改它们的类型、样式和其他基本选项,例如位置和大小、旋转、框架、背景、项目 ID和渲染。
:这是一个非常有用的元素,用于突出多个地图和概述之间的关系。在项目属性选项卡中,您可以选择线条样式、箭头轮廓和填充颜色、箭头轮廓和宽度,以及起始和结束标记。
:此项目将矢量图层属性表添加到地图布局中。如果您想这样做,请选择项目属性标签页下的图层。通过点击属性按钮,您将被带到选择属性窗口,在那里您可以通过添加或删除不必要的列;更改标题、列对齐和宽度;以及应用排序选项来修改表格的结构和外观。
对于此项目,您还可以应用特征过滤以排除不必要的或多余的元素。在外观和字体和文本样式部分,您可以找到各种增强表格可读性的选项。
:这负责使用 HTML 标记添加网页或用户生成的内容。例如,您可以在源窗口中输入以下表达式:

混合模式在组合多个概述框架时非常有用,可以实现更时尚的效果。反转概述切换按钮将反转概述区域外的填充。居中于概述将地图元素内容移动到放置概述的中心。使用
模式,点击地图画布以选择任何特征。
使用工具栏按钮,你不仅可以探索你的地图集,它包含几分钟内创建的多个页面,还可以快速访问打印
、导出和设置
选项。导出选项显示在本截图上:






按钮以使线条可编辑。所有先前的选项都将被禁用并变灰。




。
,或者使用Ctrl + I键盘快捷键。
或使用Ctrl + E快捷键退出编辑模式。系统会询问您是否要保存对
按钮手动添加必要的值。输入
在完成所有必要的调整后,点击确定按钮以应用它们。





来打开图层的属性表。在属性表工具栏中,要么点击打开字段计算器按钮,要么使用Ctrl + I键盘快捷方式。
按钮切换编辑模式。双击单元格并手动输入新的
按钮打开如图所示的字段计算器对话框窗口,并进行以下调整:
按钮以使






,并输入以下表达式:
按钮执行删除所选要素,或者直接从键盘按下Del键。
或 Ctrl + S) 并取消编辑模式。在以下屏幕截图中,您可以看到该图层仅包含那些包含最大适宜值的多边形,这些值设置为 90%:




工具箱:这是主要的 Processing 图形用户界面元素。它提供了对所有可用算法(按提供者或目的分组)的访问,并允许我们在单次传递和批处理模式下运行它们。Processing 工具箱有两种模式:简化(默认)和高级。在简化模式下,所有算法都放置在预定义的组中,并具有用户友好的名称,旨在帮助新手用户找到必要的工具。在高级模式下,算法按提供者分组。每个提供者代表某个分析包或程序,例如 GRASS、Orfeo ToolBox 等。此外,在高级模式下,我们还可以访问更多算法,因为一些特殊提供者仅在此模式下可用。在接下来的章节中,我们将假设工具箱是在高级模式下使用的。
历史管理器:此功能存储有关所有执行算法及其参数的信息,以便在必要时可以轻松地重现过去的行为。此外,所有错误、警告和信息消息都显示在此处。
图形模型器:这是通过将现有算法组合成一个单一的工作流程来创建新算法的工具。它允许我们轻松自动化涉及多个步骤的复杂分析。
浙公网安备 33010602011771号