.Net离线使用DTED TIFF文件获取指定点高程的方法
问题解决与替代方案
一、ArcGISRuntime库的修正方案
你遇到的错误核心原因有三个:加载了无关文件、未单独加载高程源、坐标点未指定正确空间参考。按以下步骤修正:
筛选有效DTED文件
不要用*.*遍历所有文件,DTED的标准扩展名通常是.dt0、.dt1、.dt2,部分会存为.tif,只筛选这类文件避免引入无效资源:List<string> files = new List<string>(); var validExtensions = new[] { "*.tif", "*.dt0", "*.dt1", "*.dt2" }; foreach (var ext in validExtensions) { files.AddRange(Directory.EnumerateFiles(parentFolder, ext, SearchOption.AllDirectories)); }显式加载RasterElevationSource
Surface的LoadAsync不会自动完成内部高程源的加载,必须单独调用高程源的加载方法并确认状态:var rasterElevationSource = new RasterElevationSource(files); await rasterElevationSource.LoadAsync(); if (rasterElevationSource.LoadStatus != LoadStatus.Loaded) { Console.WriteLine($"高程源加载失败:{rasterElevationSource.LoadError?.Message}"); return; } surface.ElevationSources.Add(rasterElevationSource);给坐标点指定空间参考
DTED默认采用WGS84坐标系(WKID:4326),创建MapPoint时必须显式指定,否则无法匹配高程源的坐标系,注意MapPoint参数顺序是经度、纬度:var sr = SpatialReferences.Wgs84; var mp = new MapPoint(lon, lat, sr);
修正后的完整代码(使用async/await避免阻塞):
// parentFolder - DTED文件所在目录 var validExtensions = new[] { "*.tif", "*.dt0", "*.dt1", "*.dt2" }; List<string> files = new List<string>(); foreach (var ext in validExtensions) { files.AddRange(Directory.EnumerateFiles(parentFolder, ext, SearchOption.AllDirectories)); } var surface = new Esri.ArcGISRuntime.Mapping.Surface(); var rasterElevationSource = new RasterElevationSource(files); // 先加载高程源 await rasterElevationSource.LoadAsync(); if (rasterElevationSource.LoadStatus != LoadStatus.Loaded) { Console.WriteLine($"加载失败:{rasterElevationSource.LoadError?.Message}"); return; } surface.ElevationSources.Add(rasterElevationSource); await surface.LoadAsync(); // 指定经纬度和坐标系(顺序为经度、纬度) var sr = SpatialReferences.Wgs84; var mp = new MapPoint(lon, lat, sr); var res = await surface.GetElevationAsync(mp); Console.WriteLine($"Elevation: {res}");
二、替代类库推荐
如果ArcGISRuntime的方案仍不适用,可以考虑以下开源类库:
1. GDAL(.NET版本)
跨平台支持几乎所有栅格格式(包括DTED、TIFF),可直接读取指定坐标的高程值,无需依赖GIS runtime。
- 安装NuGet包:
GDAL - 示例代码:
using OSGeo.GDAL; // 初始化GDAL Gdal.AllRegister(); // 打开DTED文件 Dataset ds = Gdal.Open("path/to/your/dted.tif", Access.GA_ReadOnly); if (ds == null) { Console.WriteLine("打开文件失败"); return; } // 获取地理变换参数(用于像素坐标与地理坐标转换) double[] transform = new double[6]; ds.GetGeoTransform(transform); // 经纬度转像素坐标 double x = (lon - transform[0]) / transform[1]; double y = (lat - transform[3]) / transform[5]; // 读取像素值(高程) Band band = ds.GetRasterBand(1); float[] buffer = new float[1]; band.ReadRaster((int)Math.Floor(x), (int)Math.Floor(y), 1, 1, buffer, 1, 1, 0, 0); Console.WriteLine($"Elevation: {buffer[0]}"); ds.Dispose();
2. DotSpatial
开源.NET GIS库,封装了GDAL的功能,API更友好,适合快速开发。
- 安装NuGet包:
DotSpatial.Data - 示例代码:
using DotSpatial.Data; // 打开DTED文件 IRaster raster = Raster.Open("path/to/your/dted.tif"); // 经纬度转像素位置 int col = raster.Projection.ToPixel(lon, lat).X; int row = raster.Projection.ToPixel(lon, lat).Y; // 获取高程值 float elevation = raster.Value[row, col]; Console.WriteLine($"Elevation: {elevation}"); raster.Dispose();
内容的提问来源于stack exchange,提问作者WhiteRom
相关产品推荐
相关产品推荐

