前言
在许多工作中中,我使用 ArcGIS 平台从事过许多与地理空间相关的项目,我非常喜欢这个平台。 这意味着我可以在具有尖端地理空间技术的项目中进行咨询,例如多维栅格、深度学习和空间物联网自动化。 考虑到这一点,我总是试图跟踪如何在没有 Esri 精心制作的系统的情况下执行我正在处理的相同操作。
此处的计划是执行完整的地理处理和遥感例程,而无需求助于任何 GIS 桌面软件。 我们从一个图层开始,该图层包含一些我们感兴趣的地块,以及一个包含适用特殊法规的保护区的图层。
一、教程内容
检查 parcels geojson 图层是否存在无效的几何图形并进行更正;
计算每个地块的面积(以公顷为单位);
验证每个地块是否与任何保护区相交;
计算每个地块的交叉面积,并将保护区的名称插入地块的属性;
二、geopandas的简单使用
我们必须导入其中存储了地块的 geojson 文件。 为此,我们将使用 geopandas 库。 如果您不熟悉它,我的建议是熟悉它。 Geopandas 基本上模拟了我们在 python 中使用的经典 GIS 桌面软件(GRASS、GDAL、ArcGIS、QGIS……)中的功能,其方式与 pandas(数据科学家中非常流行的工具)一致,以允许对几何类型进行空间操作。
import pandas as pd
import geopandas as gpd
polygonspath = "./test.GeoJSON"
polygons = gpd.read_file(polygonspath)
polygons.geometry.is_valid
为了导入我们的geojson,我们首先要注意的是geopandas中的数据类型。 基本上,当我们运行 .read_file 方法时,我们将地理数据框类型分配给多边形变量。 在每个 geodataframe 中总会有一个 geoseries ,我们可以通过 .geometry 方法访问它。 一旦我们找到 geoseries ,我们就可以使用 .isvalid 方法,它为我们系列中的每条记录生成一个 True/False 值列表。
当然,我们的数据集中存在无效的几何图形。 那么,我们该如何解决呢? 也许习惯于运行 ArcGIS 或 QGIS 中提供的出色的无效几何检查工具,这些工具甚至会生成一份报告,说明表格中每条记录的问题所在。 但是我们无法访问 geopandas 中的那些。 相反,我们将通过对所有几何图形应用 0 米缓冲区来做一些小技巧来更正几何图形。
clean = polygons.geometry.buffer(0)
clean.plot()
现在我们终于可以通过使用 .plot 方法来查看我们的多边形了,它实际上是从 geopandas 中的 matplotlib 组件继承而来的。
这是一种快速且有用的方法,可以快速了解我们的数据在空间上的样子,但它与地图不同。
三、面积计算
由于我们想知道每个地块的面积(以公顷为单位),因此我们需要确保我们的地理数据框位于投影坐标系中。 如果您不熟悉坐标参考系统 (CRS),您至少需要知道地理坐标系统以度数(如纬度和经度)计算,而投影坐标系统以距离计算,使我们能够使用 公制。 从我们刚刚创建的绘图图中,我们可以看到多边形可能是根据纬度和经度绘制的,大约在 -15.7°、-47.7° 左右。 如果我们运行 print(polygons.crs),我们将得到 epsg:4326 作为响应。 有许多可用的坐标系,因此 EPSG 系统是跟踪它们的一种很好的方法; 4326 意味着我们的地理数据框在 WGS84 坐标系中(确实是一个地理坐标系)。
所以我们确实需要转换地理数据框的坐标系。 为此,我们必须首先决定将其转换成哪个系统。 在这一点上,我非常习惯从一个系统转换到另一个系统,但如果你有点迷茫,选择投影坐标系的一个好方法就是使用 WGS84 系统的墨卡托投影的通用横轴。 因此,您所要做的就是找出您的数据位于哪个 UTM 区域,这样您就知道这是您的数据区域失真最小的区域。 这个小 Web 应用程序是一个很好的方法。(https://mangomap.com/robertyoung/maps/69585/what-utm-zone-am-i-in-#)
我们知道我们的数据位于 [-15.7°, -47.7°] 坐标附近,所以现在我们知道它相当于 23S UTM 区。
所以剩下的就是访问 EPSG 权威网站并检查我们选择的投影的 EPSG 代码。 接下来,我们需要使用 .to_crs 方法定义一个新的地理数据框变量。
我们现在终于可以在那个新地理数据框中创建一个新列,我将其命名为 area_ha 并计算面积(以米为单位,因为我们使用的是 UTM 投影),我们必须除以 10,000 才能得到以公顷为单位的面积。
print(polygons.crs)
projetado = polygons.to_crs({'init':'epsg:31983'})
projetado["area_ha"] = projetado['geometry'].area/10**4
projetado.head(2)
这是我们新地理数据框。 现在填充 area_ha 字段的值在正确的范围内。
四、检查多边形相交
我们现在可以导入提供给我们的第二层,该层包含所有保护区(UC,或 Unidades de Conservação),这些保护区可能代表我们正在分析的地块中对农业用途的法律限制。 我们将像之前的 geojson 一样导入它。 这次的主要区别在于,这条数据实际上有更多的字段,有保护区的名称以及创建日期和更多合法的东西。用 geopanda 的 .head 方法绘制如下图所示。
我们有兴趣将所有这些丰富的信息放入与给定保护区相交的地块的属性表中。 Geopandas 使用overlay方法实际上使这很容易做到。 它完全符合我们的要求。 在我们的例子中,它将创建一个新的地理数据框,每个地块的每个相交部分都有一个记录,以及它相交的保护区的信息。 有了它,我们可以像以前一样计算交叉面积的新字段(以公顷为单位)。
ucspath = "./layer_UCs.GeoJSON"
ucsraw = gpd.read_file(ucspath)
ucs = ucsraw.to_crs({'init':'epsg:31983'})
ucs
merged = gpd.overlay(projetado, ucs, how='intersection')
merged["area_intersect"] = merged['geometry'].area/10**4
merged
merged.plot()
它看起来像以前的地块,但现在我们的地块如果与任何保护区相交,就会被分成更小的部分。 此外,它们现在包含更多有用的信息。