创建 NetCDF 文件
您将使用加勒比海的海洋生态单位 (EMU) 要素类在 ArcGIS Pro 中使用 Python 创建 NetCDF 文件。 首先,您将通过工程包设置一个新工程。 然后,您将启动一个新的 Python Notebooks。 接下来,您将使用 EMU 模式创建一个空的 NetCDF 文件。 最后,您要将 EMU 值加载到 NetCDF 文件中。 输出的 EMU NetCDF 文件将具有所需的格式,以便加载并可视化为 ArcGIS Pro 中的体素图层。
设置新工程
您将使用工程包启动一个新的 ArcGIS Pro 工程。 工程包中包含国家/地区和一个 EMU 数据示例。 首先,您将使用 ArcGIS Notebooks 处理此 EMU 数据。
- 下载工程包并双击以将其在 ArcGIS Pro 中打开。 如果出现提示,请登录 ArcGIS 帐户。
注:
如果您没有 ArcGIS Pro 的访问权限或者 ArcGIS 组织帐户,请参阅软件访问权限选项。
工程包含 Caribbean Ecological Marine Units 局部场景和 EMU_Caribbean_Sea 3D 点要素类。
注:
您可以打开 World Ocean Base 图层和WorldElevation3D/TopoBathy3D 图层(并关闭 Countries 图层)以获得更好的地理参考。 地图上的数据越少,其绘制速度就越快。
- 在功能区上,单击插入选项卡,然后选择新建笔记本。
新的笔记本将添加到工程。 可以在目录窗格中编辑 Notebooks 详细信息。
- 在目录窗格中,展开 Notebooks 文件夹。
- 右键单击 New Notebook.ipynb 并选择重命名。
- 输入 Create EMU NetCDF file.ipynb 然后按 Enter 键。
一个包含局部场景和空白 Python 笔记本的 ArcGIS Pro 新工程已经准备就绪。
创建一个空的 NetCDF 文件
首先,您将为加勒比海中的 EMU 创建 NetCDF 文件。 NetCDF 文件将在纬度、经度和深度格网中构建。 该文件还将包括全局属性、维度和变量。 这些是在 3D 模式下绘制(纬度、经度和深度)和显示相关变量(温度、盐度和氧气)所需的基本属性。
- 在笔记本的空单元格中,输入以下命令以加载所需的 Python 模块:
import os import arcpy import netCDF4 import numpy as np import datetime as dt
这些模块是包含脚本中所使用函数的库。 例如,arcpy 模块包含 ArcGIS 地理处理、数据管理和映射函数。 我们可以通过 netCDF4 模块读写 NetCDF 文件。
- 在 Notebooks 功能区上,单击运行。
第一个单元格运行后,大括号将显示数字 1。 新单元格随即添加到第一个单元格下方。
注:
通过单击插入选项卡并选择在下方插入单元格,您可以从笔记本功能区添加新单元格。
- 在新单元格中,粘贴与输出 NetCDF 文件和规则 3D 格网相关的以下命令,然后单击运行。
# Output file output_nc = "EMU_Caribbean_Voxel.nc" # Grid lowerleft_x = -88.625 lowerleft_y = 8.375 cellsize = 0.25 # Number of cells no_rows = 58 no_cols = 117 no_depths = 101 # Values lat_vals = np.arange(lowerleft_y, lowerleft_y + cellsize*no_rows, cellsize) lon_vals = np.arange(lowerleft_x, lowerleft_x + cellsize*no_cols, cellsize) z_vals = np.arange(0, -505, -5) # Print vectors print('Latitude') print(lat_vals) print('Longitude') print(lon_vals) print('Depth') print(z_vals)
每个变量定义都通过相关注释 (#) 进行分隔。 Output_nc 指定输出 NetCDF 文件的名称。 Lowerleft_x 和 lowerleft_y 指定 NetCDF 文件的坐标。 像元大小代表 1/4 度的分辨率。 No_rows 指定与纬度相关的行数;在本例中,0.25 像元大小的 58 行表示纬度为 14.5 度。 No_cols 指定与经度相关的列数;在本例中,0.25 像元大小的 117 行表示经度为 29.25 度。 这表示输出的宽度(经度)将略大于其长度(纬度)的两倍。 No_depths 指定将包含在 NetCDF 文件中的深度值的数量。 这在 3D 模式下表示我们的水体的列空间。 在下一个变量定义(值)中,您可以指定如何将这些变量一起使用,以生成间距固定的水平格网和间距不固定的垂直(深度)格网。
latitude、longitude 和 depth 矢量将显示在屏幕上。
接下来,您将使用 netCDF4 Python 模块的数据集函数创建空白的 NetCDF 文件。 您还将提供全局属性以将文档添加至文件。
- 在空白单元格中,粘贴以下代码,然后单击运行:
# Create File nc_file = netCDF4.Dataset(output_nc, 'w', format="NETCDF4", set_auto_mask=False) # Global Attributes nc_file.title = 'Ecological Marine Units' nc_file.summary = 'Ecological Marine Units (EMUs) for the Caribbean Sea.' nc_file.keywords = 'Global, EMU, USGS, NOAA, Esri, 3D, Ocean, Marine, Ecology' nc_file.license = ('This work is licensed under a Creative Commons Attribution 4.0 ' 'International License.') nc_file.references = ('Please see references Cited in this publication: ' 'http://www.aag.org/galleries/default-file/AAG_Marine_Ecosyst_bklt72.pdf') nc_file.source = 'Esri, USGS, NatureServe, GEO, NOAA, NASA, NIWA' nc_file.Conventions = 'CF-1.6' nc_file.institution = 'Esri' nc_file.history = ('{0} Creation of EMU Caribbean ' 'netcdf file.').format(dt.datetime.now().strftime("%Y-%m-%d"))
注:
为 NetCDF 文件添加文档非常重要,这样,其他人就可以更好地理解文件。 您可以遵循气候和预测 (CF) 元数据公约中关于标准属性和变量名称的指导。
- 在新单元格中,粘贴以下代码以创建经度、纬度和深度维度。
# Create Dimensions lat_dim = nc_file.createDimension('latitude', no_rows) lon_dim = nc_file.createDimension('longitude', no_cols) top_dim = nc_file.createDimension('depth', no_depths)
接下来,您将添加用于对变量进行制图和格网化的代码:crs、latitude、longitude 和 depth,然后将 lat_vals、lon_vals 和 z_vals 矢量加载到其对应的变量(换言之,lat_var、lon_var 和 depth_var)中。
- 在同一单元格的末尾,添加以下代码并单击运行:
# Create the map and grid variables crs_var = nc_file.createVariable('crs', 'l', (), fill_value=-9999, zlib=True) crs_var.standard_name = 'crs' crs_var.grid_mapping_name = 'latitude_longitude' crs_var.crs_wkt = arcpy.SpatialReference(4326).exportToString() lat_var = nc_file.createVariable('latitude', 'f4', ('latitude'), fill_value=-9999) lat_var.units = 'degrees_north' lat_var.standard_name = 'latitude' lat_var.axis = 'Y' lon_var = nc_file.createVariable('longitude', 'f4', ('longitude'), fill_value=-9999) lon_var.units = 'degrees_east' lon_var.standard_name = 'longitude' lon_var.axis = 'X' depth_var = nc_file.createVariable('depth', 'l', ('depth'), fill_value=-9999) depth_var.short_name = 'depth' depth_var.standard_name = 'depth' depth_var.positive = 'up' depth_var.units = 'meters' depth_var.axis = 'Z' # Load data lat_var[:] = lat_vals lon_var[:] = lon_vals depth_var[:] = z_vals
crs 变量没有任何维度或变量;它提供了制图空间参考信息。
- 在新单元格中,为 EMU 数据粘贴三个变量:海水温度、盐度、溶氧量 和 cluster37,然后单击运行。
# Create EMU Variables temp_var = nc_file.createVariable('temp', 'f4', ('depth', 'latitude', 'longitude'), fill_value=-9999) temp_var.short_name = 'temp' temp_var.standard_name = 'sea_water_temperature' temp_var.units = 'degree_Celsius' temp_var.grid_mapping = 'crs' sali_var = nc_file.createVariable('salinity', 'f4', ('depth', 'latitude', 'longitude'), fill_value=-9999) sali_var.short_name = 'salinity' sali_var.long_name = 'sea_water_salinity' sali_var.units = '' sali_var.grid_mapping = 'crs' dissO2_var = nc_file.createVariable('dissO2', 'f4', ('depth', 'latitude', 'longitude'), fill_value=-9999) dissO2_var.short_name = 'dissO2' dissO2_var.long_name = 'mole_concentration_of_dissolved_molecular_oxygen_in_sea_water' dissO2_var.units = 'microliters/liter' dissO2_var.grid_mapping = 'crs' cluster37_var = nc_file.createVariable('cluster37', 'l', ('depth', 'latitude', 'longitude'), fill_value=-9999) cluster37_var.short_name = 'cluster37' cluster37_var.long_name = 'cluster37_id' cluster37_var.units = '' cluster37_var.grid_mapping = 'crs'
海水温度、盐度和溶氧量是描绘海洋及其环境条件的关键变量。 聚类变量保存 EMU 数据集中格网像元的分类。 请注意,前三个变量的数据类型为浮点型(即“f4”)而 cluster37 变量的数据类型为整型(即“l”)。
注:
在本教程中,使用了深度为 500 米的一部分加勒比海数据。 访问 ArcGIS Living Atlas of the World 中的 Ecological Marine Units (EMU) Web 应用程序以了解有关 EMU 数据集的详细信息。 整个 EMU 数据集包含比本练习中列出的三个变量更多的变量。 您可以从 ArcGIS Online 下载完整的 EMU NetCDF 文件。
将数据加载到 NetCDF 文件
接下来,您将把 EMU 点要素类的值加载到 NetCDF 文件中。
- 在内容窗格中,右键单击 EMU_Caribbean_Sea 要素类,然后选择属性表。
属性表随即出现。
每个 3D 点(坐标 X、Y 和 Z)的 temp、salinity、dissO2 和 Cluster37 字段包含将加载到 NetCDF 文件变量的信息。
- 关闭属性表。
- 在笔记本末尾的新单元格中,将 EMU_Caribbean_Sea 要素类分配到 fc 变量中。 创建包含 fc 变量以及 temp、salinity、dissO2、Cluster37 和 Shape@ 字段的搜索游标。 现在不要运行单元格。
# Load EMU data fc = os.path.abspath(r'.\EMU.gdb\EMU_Caribbean_Sea') cursor = arcpy.da.SearchCursor(fc, ['temp', 'salinity', 'dissO2', 'Cluster37', 'Shape@'])
- 在内容窗格中,双击 EMU_Caribbean_Sea 图层。 在图层属性窗口中,单击源选项卡。
- 从数据库行复制源路径并将其粘贴到笔记本中作为 fc 路径变量。 确保在末尾包含文件名 EMU_Caribbean_Sea。
- 在同一单元格中,使用 for 循环迭代游标中的行。 获取 EMU 变量值,用 -9999 替换空值,获取 3D 点的数组索引,并将变量值存储在 NetCDF 数组中。
# For each record in the table for row in cursor: # Get values temp, salinity, dissO2, cluster37 = row[:4] coords = row[4].getPart() # Replace null values with -9999 temp = float(temp) if temp else -9999 salinity = float(salinity) if salinity else -9999 dissO2 = float(dissO2) if dissO2 else -9999 cluster37 = float(cluster37) if cluster37 else -9999 # Get indices in array of current 3D point idx = (np.abs(lon_vals - coords.X)).argmin() idy = (np.abs(lat_vals - coords.Y)).argmin() idz = np.where(z_vals==int(coords.Z))[0] # Store variables values if idz.size > 0: temp_var[idz, idy, idx] = temp sali_var[idz, idy, idx] = salinity dissO2_var[idz, idy, idx] = dissO2 cluster37_var[idz, idy, idx] = cluster37 del(cursor)
- 运行单元格。
单元格可能需要运行一段时间。 在运行单元格时,单元格旁会显示一个星号 (*)。 该星号会在完成后变为数字。
- 在新单元格中,复制粘贴以下代码关闭 NetCDF 文件,然后单击运行。
# Close NetCDF file nc_file.close()
提示:
您可以从 ArcGIS Online 下载最终的 Python 笔记本。
- 在功能区的笔记本选项卡上,单击保存。
您已创建一个空的 NetCDF 文件。 您还在 ArcGIS Pro 中使用 Python Notebooks 将值从点要素类加载到了 NetCDF 文件。 接下来,您将在本地场景中将此 NetCDF 文件加载为多维体素图层。
将 NetCDF 文件添加为体素图层
之前,您在 ArcGIS Pro 中使用 Python 笔记本和 EMU 点要素类创建了一个 NetCDF 文件。 接下来,您需要在局部场景中将 EMU NetCDF 文件加载为多维体素图层。 体素图层可用于以 3D 形式可视化 EMU 变量,例如海水温度、盐度或溶氧量。
添加多维体素图层
首先,您要将 EMU NetCDF 文件添加为体素图层。
- 单击 Caribbean Ecological Marine Units 选项卡以打开该局部场景。
- 在功能区上的地图选项卡中,单击添加数据下拉箭头,然后选择多维体素图层。
添加体素图层窗口随即显示。
- 在添加体素图层窗口中,对于输入源数据,单击浏览,然后选择 EMU_Caribbean_Voxel.nc 文件。
选择该文件后,可用属性字段将填充选择变量部分。
在 NetCDF 文件中定义的每个变量都将在添加体素图层窗口中列出。 通过打开或关闭变量,可以确定要包含在体素图层中的变量。 可以选择要设置为默认变量的变量。 将体素图层添加至场景后,这将是显示的变量。
变量具有的已定义数据类型用于确定符号化变量的方式。 例如,连续数据类型可以为数值,例如海水温度、盐度或溶氧量。 可以使用拉伸值来可视化连续变量。 如果数据类型为离散型,例如 cluster37,则可以使用唯一值对变量进行符号化。
- 对于选择变量,在默认变量列中,将 dissO2 设置为默认值。
- 单击确定。
在 ArcGIS Pro 中,EMU NetCDF 文件将显示为体素图层。
目前,将使用默认颜色和高程值对其进行绘制。 要更加精确地可视化此数据,您需要更改高程和样式。
该图层目前正在海洋顶部绘制。 要正确地将其放置在某深度处,您需要设置垂直夸大。
- 在内容窗格中,单击 EMU_Caribbean_Voxel 图层以将其选中。
- 在功能区上,单击体素图层选项卡。
- 在高程组中,对于垂直夸大,删除负号,以将其设置为 3223.86。
场景中随即更新体素图层。
接下来,出于可视化目的,您将应用专为显示海洋数据而开发的样式。 海洋样式包含多种配色方案,用于可视化海洋中的特征,例如氧含量。 颜色范围和标注需要相匹配,以便于受众解释体素图层中的值。
- 下载 cmocean.stylx 样式包。
- 单击功能区上的插入选项卡。 在样式组中,单击添加并选择添加样式。
- 在添加样式文件窗口中,选择 cmocean.stylx 文件并单击确定。
注:
如果显示升级样式窗口,单击是继续操作。
现在,即可将样式应用于该图层。
- 在功能区上,单击体素图层选项卡。 在绘制组中,单击符号系统。
随即显示符号系统窗格。
- 在符号系统窗格中,对于配色方案,展开菜单并选中显示名称和显示所有。
已下载的海洋样式将显示在列表顶部。
- 查找并选择 oxy 配色方案。
地图将重新绘制以显示新的配色方案。 低溶氧浓度将显示为红色和栗色,而高溶氧浓度将显示为黄色。
中间值将显示为灰色。 要强调高值和低值,您需要使用透明度来隐藏这些中间值。
- 在符号系统窗格中,对于标签和颜色范围,将最小值设置为 3.00,将最大值设置为 4.00。
- 选中透明度功能复选框。
通过添加控制点来定义透明度范围。
- 单击两次添加控制点按钮。
随即将另外两个点添加至符号范围。
- 单击第一个控制点,然后将值设置为 100%,并将位置设置为 3%。
- 对于第二个控制点,将值设置为 100%,并将位置设置为 80%。
体素图层显示了加勒比海中高(黄色)和低(红色)溶氧量的区域。
- 在快速访问工具栏上,单击保存以保存工程。
您已将 EMU NetCDF 文件添加为 ArcGIS Pro 中局部场景中的多维体素图层。 接下来,您将通过定义表面并对体素图层外观进行基本更改(例如选择变量并更改拉伸参数)来直观地分析体素图层。
在 3D 模式下直观分析 EMU
之前,您在 ArcGIS Pro 中将 EMU NetCDF 文件加载为体素图层。 接下来,您将创建面(例如等值面和截面),以直观分析变量。
创建等值面
首先,您将以特定值定义一个等值面,以直观地分析溶氧的分布情况。 等值面描述了体素图层中沿指定值的表面。 例如,以 2.85 微升/升表示的溶氧等值面显示了加勒比海中具有该值的所有位置,这些位置可能位于不同深度。
- 在内容窗格中的 EMU_Caribbean_Voxel 下,单击 mole_concentration_of_dissolved_molecular_oxygen_in_sea_water 两次。
字段变为可编辑状态。
- 将变量命名为 Concentration of Dissolved Oxygen。
- 展开并选择表面。
由于尚未创建表面,因此将从地图上移除体素。
- 在表面下,右键单击等值面,然后选择创建等值面。
随即将在体素图层内创建一个新等值面,并显示体素探索窗格。
- 在体素探索窗格中,对于名称,输入 Concentration of Dissolved Oxygen 2.85。 对于值,输入 2.85。
- 在内容窗格中,打开 World Ocean Base 和 WorldElevation3D/TopoBathy3D 图层。
- 在内容窗格中,单击地面。
- 在功能区高程表面图层选项卡的绘制组中,对于垂直夸大,键入 40,然后按 Enter 键。
- 在内容窗格中,单击 EMU_Caribbean_Voxel 图层。 在功能区体素图层选项卡的高程组中,将垂直夸大设置为 40。
- 右键单击 EMU_Carribbean_Voxel 图层,然后单击属性。
- 在图层属性窗口中,单击高程选项卡,对于夸大模式,选择 Z 坐标,然后单击确定。
创建截面
接下来,您将通过定义跨越体素图层的截面来直观地探索变量。 您将定义一个截面,然后动态更改其位置、倾斜度和方向。 新截面将被锁定为与其他变量一起显示。
- 在功能区体素图层选项卡的变量组中,选择 sea_water_temperature。
- 在绘制组中,单击符号系统。 在符号系统窗格中,对于配色方案,选中显示名称并选择热波段。
- 在内容窗格中,取消选中 Countries 图层。
- 单击功能区上的数据选项卡。 在浏览组中,选择剖切片和截面。
剖切片和截面工具栏随即显示在场景底部。
- 在剖切片和截面工具栏中,选择垂直截面。
- 在地图中,在尼加拉瓜西北海岸上单击一个点,作为剖切片起点,然后在尤卡坦半岛沿海单击第二个点。
新的垂直截面已添加至场景。
- 在内容窗格中,右键单击截面 1,然后选择锁定截面。
锁定截面移动到体素图层的锁定截面组中。 现在,截面为定义位置的快照,即使选择其他变量,仍可以查看此截面。 这允许您同时浏览多个变量。
- 在功能区体素图层选项卡的变量组中,选择 mole_concentration_of_dissolved_molecular_oxygen_in_sea_water 变量。
2.85 溶氧浓度等值面和海水温度截面随即在场景中显示。
示例图像显示了从尼加拉瓜到尤卡坦半岛的海水温度横截面。 它还显示了值为 2.85 微升/升的溶氧等值面。
在本课程中,您使用 ArcGIS Pro 中的 Python 笔记本创建了 NetCDF 文件。 您下载了 EMU 点要素类,并将其值加载到新的 EMU NetCDF 文件中。 您将 NetCDF 文件作为局部场景中的多维体素图层进行了加载并在 3D 模式下对其进行了直观分析。
您可以在教程库中找到更多教程。