You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

按CF-1.0规范生成的NetCDF投影坐标无法被gdalinfo识别

问题:遵循CF-1.0规范创建的NetCDF栅格UTM投影坐标无法被gdalinfo识别

用Python创建NetCDF栅格时,遵循CF-1.0规范(兼容NetCDF GDAL驱动)写入的UTM 19N投影坐标,有时无法被gdalinfo读取识别,进而导致QGIS无法正确投影。该问题与坐标值本身相关:部分坐标值可被gdalinfo正常读取并在QGIS中正确投影,但另一些值则不会被识别为坐标变量。

触发问题的参数

width = 7920
height = 7135

transform = rasterio.transform.from_origin(west=541107.0, north=5438536.5, xsize=1.5, ysize=1.5)

x = rasterio.transform.xy(transform, cols=list(range(0, width, 1)), rows=0)[0]
y = rasterio.transform.xy(transform, cols=0, rows=list(range(0, height, 1)))[1]

此时gdalinfo返回结果:

Corner Coordinates:
Upper Left  (    0.0,    0.0)
Lower Left  (    0.0, 7135.0)
Upper Right ( 7920.0,    0.0)
Lower Right ( 7920.0, 7135.0)
Center      ( 3960.0, 3567.5)

可复现问题的示例代码(含正常与异常场景)

import netCDF4
import numpy as np
import pyproj
import rasterio

fpath = '/D/Data/TEST/test_netcdf_cf.nc'
ds = netCDF4.Dataset(fpath, "w", format="NETCDF4")

# 可被gdalinfo读取的坐标参数
width= 8026
height= 7340

# 无法被gdalinfo读取的坐标参数
width= 7920
height= 7135

# 创建覆盖马尼夸根半岛的仿射变换
# 将像素大小设为1可解决问题
transform = rasterio.transform.from_origin(west=541107.0, north=5438536.5, xsize=1.5, ysize=1.5)

# 使用以下原点坐标也能修复问题...
# 这是怎么回事?GDAL是否要求网格必须规则?
#transform = rasterio.transform.from_origin(west=541107.25, north=5438536.25, xsize=1.5, ysize=1.5)

x = rasterio.transform.xy(transform, cols=list(range(0, width, 1)), rows=0)[0]
y = rasterio.transform.xy(transform, cols=0, rows=list(range(0, height, 1)))[1]

ds.createDimension('y', height)
ds.createDimension('x', width)
y_var = ds.createVariable('y', 'f4', ('y',))
x_var = ds.createVariable('x', 'f4', ('x',))

y_var[:] = y
x_var[:] = x

# 创建CF grid_mapping
grid_mapping = ds.createVariable('grid_mapping', np.int32, ())

grid_mapping.crs_wtk = cf_grid_mapping['crs_wtk']
grid_mapping.semi_major_axis = cf_grid_mapping['semi_major_axis']
grid_mapping.semi_minor_axis = cf_grid_mapping['semi_minor_axis']
grid_mapping.inverse_flattening = cf_grid_mapping['inverse_flattening']
grid_mapping.reference_ellipsoid_name = cf_grid_mapping['reference_ellipsoid_name']
grid_mapping.longitude_of_prime_meridian = cf_grid_mapping['longitude_of_prime_meridian']
grid_mapping.prime_meridian_name = cf_grid_mapping['prime_meridian_name']
grid_mapping.geographic_crs_name = cf_grid_mapping['geographic_crs_name']
grid_mapping.horizontal_datum_name = cf_grid_mapping['horizontal_datum_name']
grid_mapping.projected_crs_name = cf_grid_mapping['projected_crs_name']
grid_mapping.grid_mapping_name = cf_grid_mapping['grid_mapping_name']
grid_mapping.latitude_of_projection_origin = cf_grid_mapping['latitude_of_projection_origin']
grid_mapping.longitude_of_central_meridian = cf_grid_mapping['longitude_of_central_meridian']
grid_mapping.false_easting = cf_grid_mapping['false_easting']
grid_mapping.false_northing = cf_grid_mapping['false_northing']
grid_mapping.scale_factor_at_central_meridian = cf_grid_mapping['scale_factor_at_central_meridian']

y_var.units = 'm'
y_var.standard_name = 'projection_y_coordinate'
y_var.long_name = 'y coordinate of projection'
y_var.axis = 'Y'

x_var.units = 'm'
x_var.standard_name = 'projection_x_coordinate'
y_var.long_name = 'x coordinate of projection'
x_var.axis = 'X'

# 创建波段维度
ds.createDimension('band', 3)
band_var = ds.createVariable('band', 'f4', ('band',), significant_digits=2)

band_var[:] = [350.23, 460.90, 680.7]

band_var.units = 'nm'
band_var.standard_name = 'sensor_band_central_radiation_wavelength'
band_var.axis = 'B'

# 创建数据变量
Rrs_var = ds.createVariable(
    'Rrs',
    'i4',
    ('band', 'y', 'x',),
    fill_value=21474836,
    compression='zlib',
    complevel=1)

Rrs_var.units = 'sr-1'
Rrs_var.standard_name = 'Rrs'
Rrs_var.long_name = 'Remote sensing reflectance'

Rrs_var.grid_mapping = 'grid_mapping'

RrsData = np.random.random(size=(3, height, width))

print(ds.variables['Rrs'].shape)

ds.variables['Rrs'][0:3, 0:height, 0:width] = RrsData

ds.close()

内容的提问来源于stack exchange,提问作者raphidoc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 12:29:50