1 简介
大家好我是费老师,geopandas
作为在Python
中开展GIS
分析的利器,可以帮助我们快捷地解决很多日常GIS
操作需求。而我们平时工作研究中使用到的各种矢量数据,由于原始数据加工过程的不规范等问题,偶尔会导致某些要素自身的矢量数据信息「非法」。
这样的「非法」要素读到geopandas
或是PostGIS
等常用GIS
工具中,在进行一些矢量计算操作时会触发拓扑错误问题,而今天的文章中,我们就来学习一下在geopandas
中如何有效地解决此类的要素拓扑非法问题。
2 在geopandas解决拓扑错误问题
2.1 geopandas中常见的要素拓扑错误情况
在geopandas
中,要素的合法性(validity)是针对「面要素」、「多部件面要素」而言的,同其底层依赖的shapely
库一样,遵守着OGC(开放地理空间联盟)标准,在shapely
高度完备的功能封装下,我们在日常创建面要素矢量时只需要注意别出现下面几种常见的情况就行:
- 错误情况1:「坐标串自交叉」
- 错误情况2:「边界线存在重叠」
- 错误情况3:「内部孔洞之间存在共边」
- 错误情况4:「内部孔洞与外边界共边」
- 错误情况5:「多部件面要素之间存在重叠」
值得一提的是,除了查看要素的is_valid
属性是否为True
外,在jupyter
中非法的shapely
要素还会像上面各图那样以红色显示(合法是绿色)。
2.2 对拓扑错误要素进行诊断
上面列举的是我们自行构建面要素、多部件面要素时常见的拓扑错误,但若我们的数据来自从外部读取的矢量文件:
查看is_valid
属性仅能知晓各个矢量是否合法:
而配合shapely
中的explain_validity()
则可以具体诊断出各自具体的拓扑非法原因:
通过这些信息,我们就可以更有的放矢地决定对各个要素进行删除还是修复操作。
2.3 对拓扑问题进行修复
既然发现了拓扑非法问题,通常情况下我们肯定是希望可以尽可能地修复数据,而不是粗暴地予以删除,geopandas
从0.12.0
版本开始提供了基于shapely.validation.make_valid()
的快捷拓扑修复方法make_valid()
,对于小于0.12.0
版本的geopandas
,我们则可以配合map()
快捷实现同样的效果:
下面我们来瞅瞅针对每种情况具体是如何进行「修复」的:
- 修复错误情况1:「坐标串自交叉」
可以看到,通过make_valid()
针对「坐标串自交叉」进行修复的方式是将其拆分为多个合法多边形构成的多部件要素:
如果你希望最后的结果为一个完整的多边形,这里给大家推荐一种奇淫巧技,在不影响原始数据精度的情况下,对结果做一个非常小的缓冲区即可:
- 修复错误情况2:「边界线存在重叠」
类似的,对于「边界线存在重叠」的情况,修复后的结果是将重叠部分作为线要素,剩余部分保留面要素:
这时配合shapely.ops.unary_union()
过滤掉非面要素的要素构件即可:
- 修复错误情况3:「内部孔洞之间存在共边」
针对「内部孔洞之间存在共边」的情况,修复的结果中包含了被剔除的孔洞公共边及剩余的合法面要素,非常舒服:
- 修复错误情况4:「内部孔洞与外边界共边」
针对「内部孔洞与外边界共边」情况下的修复结果,毕竟这种情况下涉及到的孔洞是不可能被保留的:
- 修复错误情况5:「多部件面要素之间存在重叠」
这种情况下的修复策略显而易见,如果你希望修复后的结果「仍然是多部件要素」,那么将公共部分移除是唯一的方案:
至此我们就掌握了geopandas
中常见的各种拓扑非法问题的解决之道~