This chapter requires the following packages:
import numpy as np
import fiona
import geopandas as gpd
import shapely
import rasterio
# 出现错误CRSError: Invalid projection: epsg:4326: 的解决方案
# 因为装了多个版本的pyproj
# 在anaconda的目录下搜一下其他的proj.db文件的路径
# 复制路径在所装的环境文件夹下的Library文件夹下的那个路径,使用pyproj.datadir.set_data_dir()来更新目录
import pyproj
# pyproj.datadir.get_data_dir()
path = 'D:\work\miniconda3\Library\share\proj'
pyproj.datadir.set_data_dir(path)
d:\work\miniconda3\envs\topojson\lib\site-packages\pyproj\datadir.py:38: UserWarning: pyproj unable to set database path.
_global_context_set_data_dir()
#| echo: false
import pandas as pd
import matplotlib.pyplot as plt
pd.options.display.max_rows = 6
pd.options.display.max_columns = 6
pd.options.display.max_colwidth = 35
plt.rcParams['figure.figsize'] = (5, 5)
本章介绍地理数据的读写。
地理数据导入对于地理计算至关重要:没有数据,现实世界的应用程序就不可能实现。
数据输出也至关重要,使其他人能够使用您工作中产生的有价值的新数据集或改进的数据集。
总的来说,这些导入/输出过程可以称为数据I/O。
地理数据 I/O 通常在项目开始和结束时只需几行代码即可完成。
它作为一个简单的一步过程经常被忽视。
然而,在项目开始时犯下的错误(例如使用过时的或以某种方式有缺陷的数据集)可能会导致以后出现大问题,因此值得投入大量时间来确定哪些数据集可用,哪些数据集可用 可以找到它们以及如何检索它们。
@sec-retriving-open-data 涵盖了这些主题,它描述了各种地理门户(总共包含许多 TB 的数据)以及如何使用它们。
为了进一步简化数据访问,已经开发了许多用于下载地理数据的包,如 @sec-geographic-data-packages 中所述。
有许多地理文件格式,每种格式都有优点和缺点,如 @sec-file-formats 中所述。
@sec-data-input 和 @sec-data-output 节分别介绍了高效读取和写入格式文件的过程。
最后一节 @sec-visual-outputs 演示了保存视觉输出(地图)的方法,为可视化上的 @sec-map-making 做准备。
地理数据集通常存储为文件或空间数据库。
文件格式可以存储矢量或栅格数据,而空间数据库(例如 PostGIS)可以存储这两种数据。
种类繁多的文件格式可能看起来令人困惑,但自 20 世纪 60 年代 GIS 软件问世以来,第一个广泛分发的程序 ([SYMAP](https://news.harvard.edu/gazette/ 哈佛大学创建了用于空间分析的story/2011/10/the-invention-of-gis/)) [@coppock_history_1991]。
GDAL(应发音为“goo-dal”,双“o”表示面向对象),地理空间数据抽象库,自 2000 年发布以来已经解决了与地理文件格式之间不兼容相关的许多问题。
GDAL 提供了一个统一的高性能接口,用于读写多种栅格和矢量数据格式。
许多开放和专有的 GIS 程序,包括 GRASS、ArcGIS 和 QGIS,都在其 GUI 后面使用 GDAL 来以适当的格式进行摄取和吐出地理数据的工作。
GDAL 提供对 200 多种矢量和栅格数据格式的访问。
@tbl-file-formats 提供有关选定且常用的空间文件格式的一些基本信息。
名称 | 扩展 | 信息 | 类型 | 型号 |
---|---|---|---|---|
ESRI 形状文件 | .shp (主文件) |
流行的格式至少包含三个文件。 不支持:文件 > 2GB;混合类型; 名称 > 10 个字符; 列 > 255。 矢量 | 部分开放 | |
GeoJSON | .geojson |
通过包含简单特征表示的子集来扩展 JSON 交换格式; 主要用于存储经度和纬度坐标; 它由 TopoJSON 格式扩展 | 矢量 | 打开 |
KML | .kml |
基于 XML 的空间可视化格式,专为与 Google Earth 一起使用而开发。 压缩的 KML 文件形成 KMZ 格式。 | 矢量 | 打开 |
GPX | .gpx |
为交换 GPS 数据而创建的 XML 架构。 | 矢量 | 打开 |
FlatGeobuf | .fgb |
单一文件格式允许快速读取和写入矢量数据。 具有流媒体功能。 | 矢量 | 打开 |
GeoTIFF | .tif/.tiff |
流行的光栅格式。 包含附加空间元数据的 TIFF 文件。 | 光栅 | 打开 |
弧形 ASCII | .asc |
文本格式,其中前六行表示栅格标题,后面是按行和列排列的栅格像元值。 | 光栅 | 打开 |
SQLite/SpatiaLite | .sqlite |
独立的关系数据库 SpatiaLite 是 SQLite 的空间扩展。 | 矢量和光栅 | 打开 |
ESRI 文件GDB | .gdb |
ArcGIS 创建的空间和非空间对象。 允许:多个要素类; 拓扑。 GDAL 的支持有限。 | 矢量和光栅 | 专有 |
地理包 | .gpkg |
基于 SQLite 的轻量级数据库容器允许轻松且独立于平台的地理数据交换 | 矢量和(非常有限)光栅 | 打开 |
:常用的空间数据文件格式{#tbl-file-formats} |
确保文件格式标准化和开源的一项重要发展是 1994 年开放地理空间联盟 (OGC) 的成立。
除了定义简单要素数据模型(请参阅@sec-simple-features)之外,OGC 还协调开放标准的开发,例如 KML 和 GeoPackage 等文件格式中使用的标准。
OGC 认可的开放文件格式与专有格式相比有几个优点:标准已发布,确保透明度并为用户提供了根据其特定需求进一步开发和调整文件格式的可能性。
ESRI Shapefile 是最流行的矢量数据交换格式; 然而,它不是一种开放格式(尽管其规范是开放的)。
它于 20 世纪 90 年代初开发,有许多局限性。
首先,它是一种多文件格式,至少由三个文件组成。
它仅支持 255 列,列名称限制为 10 个字符,文件大小限制为 2 GB。
此外,ESRI Shapefile 不支持所有可能的几何类型,例如,它无法区分多边形和多边形。
尽管存在这些限制,但长期以来一直缺乏可行的替代方案。
与此同时,GeoPackage 出现了,并且似乎是 ESRI Shapefile 的更合适的替代候选者。
GeoPackage 是一种用于交换地理空间信息的格式和 OGC 标准。
GeoPackage 标准描述了如何在小型 SQLite 容器中存储地理空间信息的规则。
因此,GeoPackage 是一个轻量级的空间数据库容器,它允许存储矢量和栅格数据,也允许存储非空间数据和扩展。
除了 GeoPackage 之外,还有其他值得一试的地理空间数据交换格式(@tbl-file-formats)。
GeoTIFF 格式似乎是最著名的栅格数据格式。
它允许将空间信息(例如 CRS 定义和变换矩阵(请参阅@sec-using-rasterio))嵌入到 TIFF 文件中。
与 ESRI Shapefile 类似,该格式最初于 20 世纪 90 年代开发,但作为一种开放格式。
此外,GeoTIFF 仍在扩展和改进中。
GeoTIFF 格式最近最重要的新增内容之一是其名为 COG(云优化 GeoTIFF)的变体。
保存为 COG 的栅格对象可以托管在 HTTP 服务器上,因此其他人只能读取文件的部分内容,而无需下载整个文件(请参阅第 8.6.2 节和第 8.7.2 节…)。
由于书籍限制,还有大量其他空间数据格式,我们没有在 @tbl-file-formats 中详细解释或提及。
如果您需要使用其他格式,我们鼓励您阅读有关 矢量 和 光栅 的 GDAL 文档 drivers/raster/index.html) 驱动程序。
此外,某些空间数据格式可以存储矢量或栅格以外的其他数据模型(类型)。
它包括用于存储激光雷达点云的 LAS 和 LAZ 格式,以及用于存储多维数组的 NetCDF 和 HDF。
最后,空间数据通常还使用表格(非空间)文本格式存储,包括 CSV 文件或 Excel 电子表格。
这可以方便地与那些对空间数据格式有困难的人或软件共享空间数据集。
执行“geopandas.read_file”(我们用于加载矢量数据的主函数)或“rasterio.open”+“.read”(用于加载栅格数据的主函数)等命令会默默地引发一系列读取事件 来自文件的数据。
此外,有许多 Python 包包含广泛的地理数据或提供对不同数据源的简单访问。
所有这些都将数据加载到 Python 环境中,或者更准确地说,将对象分配到工作区,存储在 RAM 中并在 Python 会话中访问。
空间矢量数据有多种文件格式。
最流行的表示形式,如“.shp”、“.geojson”和“.gpkg”文件可以使用“geopandas”函数“read_file”和“to_file”导入和导出(在 @ref(sec-data- 输出)),分别。
geopandas
使用 GDAL 通过 fiona
(默认)或 pyogrio
包(最近开发的替代方案 fiona
)来读取和写入数据 菲奥娜`)。
导入“fiona”后,可以使用命令“fiona.supported_drivers”列出 GDAL 可用的驱动程序,包括它们是否可以(“r”)、附加(“a”)或写入(“w”)数据, 或全部三个:
fiona.supported_drivers
{'DXF': 'rw',
'CSV': 'raw',
'OpenFileGDB': 'raw',
'ESRIJSON': 'r',
'ESRI Shapefile': 'raw',
'FlatGeobuf': 'raw',
'GeoJSON': 'raw',
'GeoJSONSeq': 'raw',
'GPKG': 'raw',
'GML': 'rw',
'OGR_GMT': 'rw',
'GPX': 'rw',
'Idrisi': 'r',
'MapInfo File': 'raw',
'DGN': 'raw',
'PCIDSK': 'raw',
'OGR_PDS': 'r',
'S57': 'r',
'SQLite': 'raw',
'TopoJSON': 'r',
'KML': 'r'}
其他不太常见的驱动程序可以通过手动补充“fiona.supported_drivers”来“激活”。
“geopandas”多功能数据导入函数“gpd.read_file”的第一个参数是“filename”,它通常是一个字符串,但也可以是一个文件连接。
字符串的内容可能因不同的驱动程序而异。
在大多数情况下,与 ESRI Shapefile (.shp
) 或 GeoPackage 格式 (.gpkg
) 一样,filename
参数将是实际文件的路径或 URL,例如 geodata.gpkg
。
根据文件扩展名自动选择驱动程序,如下面的“.gpkg”文件所示:
world = gpd.read_file('data/world.gpkg')
world
iso_a2 | name_long | continent | ... | lifeExp | gdpPercap | geometry | |
---|---|---|---|---|---|---|---|
0 | FJ | Fiji | Oceania | ... | 69.960000 | 8222.253784 | MULTIPOLYGON (((-180.00000 -16.... |
1 | TZ | Tanzania | Africa | ... | 64.163000 | 2402.099404 | MULTIPOLYGON (((33.90371 -0.950... |
2 | EH | Western Sahara | Africa | ... | NaN | NaN | MULTIPOLYGON (((-8.66559 27.656... |
... | ... | ... | ... | ... | ... | ... | ... |
174 | XK | Kosovo | Europe | ... | 71.097561 | 8698.291559 | MULTIPOLYGON (((20.59025 41.855... |
175 | TT | Trinidad and Tobago | North America | ... | 70.426000 | 31181.821196 | MULTIPOLYGON (((-61.68000 10.76... |
176 | SS | South Sudan | Africa | ... | 55.817000 | 1935.879400 | MULTIPOLYGON (((30.83385 3.5091... |
177 rows × 11 columns
对于某些驱动程序,例如文件地理数据库(“OpenFileGDB”),“文件名”可以作为文件夹名称提供。
GeoJSON 字符串也可以从字符串中读取:
gpd.read_file('{"type":"Point","coordinates":[34.838848,31.296301]}')
geometry | |
---|---|
0 | POINT (34.83885 31.29630) |
或者,可以使用“gpd.read_postgis”函数从 PostGIS 数据库读取矢量图层。
某些矢量格式(例如 GeoPackage)可以存储多个数据层。
默认情况下,gpd.read_file
自动读取filename
中指定的文件的第一层。
但是,使用“layer”参数您可以指定任何其他层。
gpd.read_file