交通地理空间分析上课笔记 - 第 5 节课:面编辑、对象分解与面对象面积的计算

这份文件是我上课的笔记。

严格来讲,因为笔记里面有一半是老师的课件里面的内容,我只是加上了自己的理解和解释在里面,所以这份笔记的内容创作有一半是我老师完成的。

  • 这门课程最主要是关于一些地理空间分析的实践方法。
  • 比起理论,更关心具体怎么去实现的问题。
  • 我自己结合了平常自己经常使用的 Python 来解释和解决问题
  • 基于 Jupyter Notebook

在这里分享出来,希望能够帮助到一些人。

往期交通地理空间分析笔记回顾:

我们这个课程已经连着有将近九个多月没有更新了。直达去年这个课程结束之后,我一直在忙一系列别的东西,没有心情来更新这个系列。一方面原因是因为我有其他的东西要忙,另一方面原因是因为在我自己看来,MapInfo 12 这个软件不管是出于什么角度来看都实在是太糟糕了,对于今天的交通地理空间分析任务来说,功能和界面都太过古老,不仅有很多跟不上时代的地方,而且会大大拖慢你的工作时间和进度。

但与此同时,很多学校仍然在教授基于 MapInfo 12 的课程,比如我们学校的实验室机房甚至还在使用 32 位的古董Windows XP 操作系统,而 MapInfo 12 是唯一能够运行在该系统上的相对成熟的交通地理空间分析项目的解决方案。

所以我后续的更新可能会转变一下我们这份教程的目标——不再是提供一套完整的 MapInfo 12 的全流程入门教程,而是更多地为不得不使用 MapInfo 12 的大学生提供一些应对 MapInfo 12 各种莫名其妙抽风犯病和完全不现代的操作逻辑的应对措施和方法——换句话说,帮助大家顺利完成自己没用的课程作业,而不是学会 MapInfo。

同时,在各位真正开始自己的交通地理空间分析,或者是出于别的什么目的,需要使用地理信息系统软件的时候,本文作者建议各位读者使用:

  • 至少 MapInfo 17 pro 或者更高的有官方支持的 MapInfo 现代化版本
  • ArcGIS 或者开源的 QGIS 等更加成熟的地理信息系统桌面软件方案
  • 基于编程语言的地理工具,如 GeoPandas、GDAL、geodetector 等

除非你是热衷于自我折磨的受虐狂。

第 5 节课:面编辑

前面几节课我们已经讲了线对象和点对象,那么接下来就该轮到面了。

地理信息系统中的面对象是指具有封闭形状的地理要素,如湖泊、建筑物、行政区划等。它们可以用来表示实际世界中的空间区域或表达特定地理现象的范围。

面对象通常由一系列相连的线段组成,这些线段构成了封闭的边界。每个面对象都有自己的属性,例如名称、面积、周长等,这些属性可以用来描述该面对象所代表的实体。

在 GIS 中,面对象可以通过多种方式创建和编辑。例如,可以使用 GPS 设备收集现场数据并生成面对象,也可以使用遥感图像进行解译和提取。此外,还可以通过数字化手绘图纸或利用地理数据库中已有的线要素构建面对象。

面对象在 GIS 分析和空间查询中具有重要作用。通过对面对象进行空间分析,可以得出各种结论和决策支持。例如,在城市规划中,可以使用面对象来确定土地利用类型及其分布情况;在环境保护方面,可以利用面对象来评估植被覆盖率或土壤侵蚀程度。

地理信息系统中的面对象是一种表示封闭空间区域或特定地理现象范围的地理要素,并通过属性和空间分析来支持地理数据的管理和决策制定。

创建面图层

首先,我们来创建一个面图层,保存为目录下的 surface.TAB 文件。 在 MapInfo 中,没有对点、线、面图层作额外的区分。这就意味着这三者完全可以被放在同一个图层里面。因此,创建图层的步骤也是完全一样的。

image

切换到面图层,开始编辑。

根据线对象生成面

按理来说,我在这里应该先给大家介绍如何利用 MapInfo 软件提供的面创建工具来绘制面对象,但是实际上我在这里想要先讲一下:通过我们已有的线如何生成面对象,这样有助于大家理解软件创建面的工作逻辑。

我们可以根据围成面形状的线对象来生成面。

我们这里来举个例子:我们描绘江苏省的形状,可以通过如下方法:

首先,用折线对象围住江苏省的边界。要注意,这里必须是 完全围住江苏省的边界,即:

  1. 首尾相接
  2. 不能留有开口

绘制完成之后大概如下图所示。

image

我们可以分几次绘制折线对象。 我这里在绘制完之后把几个折线对象合并为了一个线对象,但是其实按理来说也可以不合并。

这里有一个小细节:如果想要在绘制的地图当作显示出所有节点的位置方便我们看,可以在左侧图层管理器中右键图层,选择 Layer Propities...,然后再在右下角勾选 Show Nodes

接下来,我们右键我们刚才绘制的线对象,在打开的菜单中选择 Edit Object,然后再出现的菜单中选择 Convert to Region

image

可以看见,我们的线对象已经成功转化为了面。下面图中的面就是我们想要绘制的江苏省地界的面。

我们打开属性表看一眼:

image

我们这里来整理一下刚才的逻辑:刚才我们的图层上面总共有三个对象,分别是两个线对象和一个面对象。我刚才把两个线对象合并为一个线对象,最后再通过这一个线对象生成了一个面对象。现在我们的属性表里面只有一个面对象,说明在生成这个面对象的时候,软件自动帮我们移除了刚才的一个线对象。那么这个时候整个数据表里面应该总共有三个对象的冗余数据。

通过面工具创建面

MapInfo 软件提供了创建面的工具。(具体参考上期内容 第 4 节课:MapInfo 基础操作,地图元素的组合、分离,以及线对象的创建 中的 MapInfo 工具栏)

image

我们选择多边形工具,绘制与江苏省接邻的安徽省的地界的形状。我们沿着底图仔细地点过去就可以了。

在绘制的过程中要注意:

  1. 首尾相接,形成封闭无开口的图形
  2. 与江苏省地界接壤的部分应当按 s 开启嗅探,沿着江苏省地界已有的点点击过去,确保接壤。

如果在绘制与江苏省接壤的地界的时候不开启嗅探功能,仅仅通过人眼去观察,是无法绘制出真正接壤的图的。这是因为 GIS 软件中的矢量图层可以无限放大,肉眼描的图一定会存在极其细微的缝隙。这样一来就会导致我们在对这些地理数据进行数学分析的时候发生错误。

image

绘制好的结果就是下面这个样子的。

其实到这个时候,细心的同学应该发现了我这里的图层有了一点点变化,这是因为我刚才突然发现我今天早上在导入这一张,中国地图底图图层的时候拿的是一张没有配准的底图,而不是之前已经配准好的底图,这就导致了我之前在上面画的面相当于白画了,因为其中不包含地理信息。每当我点下去一个点的时候,MapInfo 软件没有自动记录这个点所在的地理经纬度坐标。

遇到这种情况就会非常的麻烦:我们必须要把整个图层取消掉,然后把图层文件删除掉,把整个任务从头做一遍。是的,我刚才就经历了这样的情况,我重新画了整个图层。

这个故事告诉我们:绘制地图的时候底图一定要记得配准!一定要记得配准!一定要记得配准!重要的事情说三遍。

image

在面对象的中央挖洞

我们知道,世界上有一些典型的国中之国,这些地区在政治、经济或地理上具有特殊的地位,被认为是在一个国家内部形成了一个独立的实体。比如意大利的梵蒂冈城。当我们绘制这些实体的时候就需要在面内画挖洞。

emmm…… 在中国地图上演示这个,好像不管在哪个省份中间挖洞都给人感觉像是在地域黑,所以我在太平洋上画了一个长方形。 我们在这个长方形上面演示一下:

image

实际上,我们在这里面的中央挖洞的这个操作,跟我们上一篇笔记里面通过画小面的方式分割两条线的操作是非常类似的。

  1. 在想要挖洞的面形上面画出我们想要挖的面的形状。
  2. 选中这个面,右键打开菜单,在 Edit Object... 里面选择 Set Target,设置为目标
  3. 选中画的那个叫小的想要挖掉的形状的面,右键,选择 Erase,也就是擦去面内部的其他图形
  4. 删除较小的面,剩下留有洞的较大的面

image

这样就能取得我们想要的效果了。

可以看见,下图中的长方形按照我们的设想在正当中被挖了一个大洞。

image

同样的道理:你也可以用这种方式在图形的侧面挖取一个洞,或者挖掉一个小角。你可以使用任何图形作为遮罩来 Erase,用你想要的任意方式来挖去图形。

image

分割面

我们可以想象一下,假如有一天我们在描绘区域边界的时候,不小心把两个区域描绘成了同一个区域,我们就需要分割这两个区域。比方说我们不小心把湖南和湖北描画到同一个面对象里面去了,我们就需要在中间画一条线,把湖南湖北分割开来,变成两个独立的面对象。

对于一般的地理信息系统软件,如 ArcGIS 或者 QGIS,已经提供了基本简单的分割面的功能,可以像使用剪刀那样在面的中间直接裁剪。然而对于 MapInfo 这样的远古软件来说并没有这样方便的功能。

我猜测我写到这里的时候应该有很多人已经想到这一步要怎么操作了。没错,我们需要在需要分割的面上沿着需要分割的边界绘制一条线,然后选中我们需要分割的面,使用和之前完全一样的 Set TargetErase

image

接下来选中这条线,然后。但是等一下!

假如现在这个时候我们只是和之前一样简单的使用 Erase,那么 MapInfo 就会弹出提示,告诉你禁止使用一个线对象来 Erase 其他元素。

image

这大约和 MapInfo 的某种机制有关,我也不知道。不过同一级菜单下已经为我们提供了 Polyline Split 这个选项,允许我们使用线对象来分割其他对象。如下图所示:

image

接下来会弹出这个提示框,我们直接无脑点击继续 Next

image

弹出的还是我们熟悉的数据分割、合并选项菜单,前面的博客里面我们已经见过无数次了。但是等等……为什么这个形状默认是这样分割的?只绘制了一条线,但是却默认把图形分成了三块。

image

经过本人的多次尝试,在这个地方,随着绘制的折线的形状不同,MapInfo 会根据某种我们看不见的算法,默认将图形分成两块、三块,四块或 N 块。说来惭愧,我研究了很长时间,但确实没有研究清楚这个地方的分割机制到底是什么样子的。如果有知道的小伙伴麻烦无比在评论区里告诉我一声,不然我真的非常的懵逼。

不过不要着急,我们先把图形分割开来,然后再合并回去不就好了吗?我们在这个地方先选择 OK。这样我们的面对象就被分割好了。

image

为了方便读者们理解,我这里将分别以左、中、右来称呼我们创建的这个面对象的三个板块。

接下来我们:

  1. 首先删除这个线对象:选中线对象,按下键盘上的 Delete 按钮
  2. 选中需要合并的两个面对象。因为我们原本的目的是按照这条线来分割面,因此原则上应当选择的是中间的这个小的面对象和右侧这个大的面对象……但是,等等。

是的,是的,MapInfo 在这个时候又双叒叕出问题了。在我们选择右侧的面对象的时候,我们观察到的现象是左右两侧的面对象被同时选中了。我想看了我们前面几期教程的读者们应该能够明白这意味着什么。

实际上,此时此刻在 MapInfo 中,这两个面虽然已经被分割了,但 MapInfo 却出于某种原因仍然认为这两个面隶属于同一个面对象。也就是说,MapInfo 软件认为这两个面其实只是一个面,只不过面的形状是包含一根分割线从中贯穿的几何图形。也就意味着当你选中了左侧或者右侧的面中的其中一个,就会立刻发现另一侧也被同时选中了。

遇到这种情况,我们该怎么办呢?

在 MapInfo 中,有一种被称为分解对象(Disaggregate)的操作,就是将 同属于同一个 MapInfo 对象,但实际在几何上分属两个或多个互不相接的几何图形的地理几何元素分割开来。这句话虽然有些拗口,但是并不难理解。在我们的这个例子当中,这个面对象包含的左右两侧的两个面就符合我们说的同属于同一个 MapInfo 对象但实际在几何上分属两个或多个互不相接的几何图形的地理几何元素。因此,我们这个时候首先要执行分解对象的操作,将这个面的左半部分和右半部分分割开来,再利用合并对象,将右半部分和中间的部分连接起来。

和之前一样,我们首先选中我们需要分解的这个面对象,然后右键,按照下图所展示的步骤依次点击 Edit Objects -> Disaggregate

image

在此基础之上,我们就会看到下面的弹窗。这个弹窗说实话本人并不理解此处的 Collection Only 到底是什么意思,所以我尝试了一下,发现在当前的情形下如果选择下面一种情况的话什么也不会发生。

所以我们姑且不管这个窗口上的各个选项是什么意思,姑且留到日后再去研究。我们现在直接点击 Next

image

接下来你就会发现弹出了下面这个让我们很熟悉的窗口。显然这个窗口是让你选择分界面之后产生的各个新的面对象的各个字段属性的值。但是因为我们之前来来回回操作了数次,到目前为止都还没有设置过面的各个字段属性的值呢,因此我们直接无视点击 OK 即可。

image

分割后的对象,碍于篇幅有限,我在本文里面就不再展示了。我们现在直接按住 Shift 选中我们需要合并的、位于右侧和中间的两个面对象,然后选择 Edit Objects -> Combine,就会发现两个面已经被正确合并了。

计算面对象的面积

看过我们前面几期教程的读者,朋友们应该能够知道,到了这个时候,我又需要对属性表进行压缩了。是的,在 MapInfo 12 当中,你对图层每一个对象的删除操作都必须要在结束之后对你的属性表进行压缩。这种体验非常的糟糕,因为在大部分现代的地理信息系统软件当中,这个操作都是帮你自动完成的。但是 MapInfo 12 只支持手动作业。

压缩属性表的操作在我们前面几期教程中已经介绍过,所以在这里就不再复述了,不记得操作的读者们请前去自行翻看我们前面几个章节的教程,我们这里假设读者们已经正确完成了压缩属性表的操作。在这种情况下,读者们的属性表里应该只包含四个对象:刚才经过线分割之后的包含,两个洞的长方形的左右两半部分,以及两个省份的地图。

计算每个面对象的面积的方法需要用到更新列,这部分教程在 本教程的第一章。简单的来讲,我们需要点击界面选项卡中的 Table -> Update Column,接下来就会弹出这个我们熟悉的更新列的界面。只不过这一次,我们要点击界面上的 Assist,弹出 SQL 命令的编辑对话框,这个对话框能够帮助我们更加方便的编辑我们用于计算面对象的面积的 SQL。

这里的操作步骤比较冗杂,重复,涉及到点击三个下拉菜单和两个弹窗,所以我在文章中就不再用文字描述了,大家照着下面的图片一步一步操作就可以了。如果看着图片,大家实在是操作不来,也可以在评论区里给我留言,那样的话我就重新补上这一段文字叙述。

image

如果大家前面几步的操作没有错误的话,那么大家最终能够看到的面积的计算结果,就像下面这张图所展示的,每一个面对象的 surface 属性都包含了自身的面积值,单位是 sq km,也就是 Squre Kilometres,平方千米。

这里面积值的计算其实也侧面体现出了我们之前对地图进行配准的重要性,之所以能够估算这几个图形的面积,是因为地理信息系统软件已经对地图进行了配准,所以知道这每一个图形的每一个边界点对应真实世界的地理坐标。换句话说:如果没有对地图进行配准,那么这里的面积值计算就将是完全错误的。

image

posted @ 2024-06-27 14:20  多玩我的世界盒子  阅读(96)  评论(0编辑  收藏  举报