1

我和我的团队正在使用 Cesium GeoserverTerrainProvider 插件,但是一旦加载了数字高程模型,它就无法正确显示:

  • 使用“样式化”图像格式或“bil/dds”插件,地形在两个地形图块连接处的高度值几乎没有锐减

  • 使用“转换”图像格式(见下文),地形具有高度的峰值

为了更好地理解,您可以查看以下链接: http: //matteodipaolo.bitbucket.org/Geoserver/ 左上角的按钮允许在瓷砖划分时加载地形(以三种可能的格式之一 - 见下文)在西班牙感兴趣的区域上绘制的白线突出显示。

以下是为了操作和显示数字高程模型数据而跟踪的步骤

源数据: 我们使用来自西班牙地理研究所的 DEM 数据

我们正在使用分辨率为 5 m 的数字高程模型。文件格式为 ESRI ASCII 网格 (asc)。相应区域的大地参考系统 ETRS89 UTM 投影。

数据处理: 我们正在使用 GDAL 为我们感兴趣的领域处理 2 个 ASC:

我们将原始 ASC 文件合并到单个 GeoTIFF 中,并进行内部平铺、压缩和 NODATA 值分配

gdal_merge.py -o merged.tif -co "TILED=YES" -co "BLOCKXSIZE=512" -co "BLOCKYSIZE=512" -   co "COMPRESS=DEFLATE" -co "ZLEVEL=9" -init -999 -a_nodata -999 -n -999 -ot Int16 MDT05-1002-H30.asc MDT05-1003-H30.asc

我们分配正确的 CRS。

gdal_translate -a_srs "EPSG:25830" -co "TILED=YES" -co "BLOCKXSIZE=512" -co "BLOCKYSIZE=512" -co "COMPRESS=DEFLATE" -co "ZLEVEL=9" merged.tif merged_CRS.tif

我们创建概览

gdaladdo -r nearest --config COMPRESS_OVERVIEW DEFLATE --config GDAL_TIFF_OVR_BLOCKSIZE 512 merged_CRS.tif 2 4 8 16 32 64

我们创建了一个 5 级金字塔

gdal_retile.py -v -r bilinear -levels 5 -ps 1024 1024 -co "TILED=YES" -co "BLOCKXSIZE=512" -co "BLOCKYSIZE=512" -co "COMPRESS=DEFLATE" -co "ZLEVEL=9" -targetDir pyramid/ merged_CRS.tif

在 Geoserver 中服务: 我们遵循https://github.com/kaktus40/Cesium-GeoserverTerrainProvider上的说明,使用 BIL/DDS 插件。

Cesium 和 Javascript 代码: 我们为 viewer.scene.globe 设置了一个新的 Terrain Provider,可以在 geoserver 插件支持的图像格式之间进行选择:

1) 风格:

var terrainProvider = new Cesium.GeoserverTerrainProvider({
            service: "WMS", 
            url : "http://geoserver.deimos-space.com/geoserver/elevation/wms",            
            xml: "http://geoserver.deimos-space.com/geoserver/elevation/wms?SERVICE=WMS&REQUEST=GetCapabilities&tiled=true",
            layerName: "IGN_22_July_DEM_Pyramid_Transparent_Int16",                               
            styleName: "mySLD",
            hasStyledImage: true,
            formatImage: {format : "image/png",extension: "png"},
            formatArray: {
                format : "image/bil",
                /**
                * bufferIn : buffer to process (switch byte order and check the data limitations)
                * size: defines the dimension of the array (size.height* size.width cells)
                * highest: defines the highest altitude (without offset) of the data. 
                * lowest: defines the lowest altitude (without offset) of the data. 
                * offset: defines the offset of the data in order to adjust the limitations
                */
                postProcessArray : function(bufferIn, size,highest,lowest,offset) {
                    var resultat;
                    var viewerIn = new DataView(bufferIn);
                    var littleEndianBuffer = new ArrayBuffer(size.height * size.width * 2);
                    var viewerOut = new DataView(littleEndianBuffer);
                    if (littleEndianBuffer.byteLength === bufferIn.byteLength) {
                        // time to switch bytes!!
                        var temp, goodCell = 0, somme = 0;
                        for (var i = 0; i < littleEndianBuffer.byteLength; i += 2) {
                            temp = viewerIn.getInt16(i, false)-offset;
                            if (temp > lowest && temp < highest) {
                                viewerOut.setInt16(i, temp, true);
                                somme += temp;
                                goodCell++;
                            } else {
                                var val = (goodCell == 0 ? 1 : somme / goodCell);
                                viewerOut.setInt16(i, val, true);
                            }
                        }
                        resultat = new Int16Array(littleEndianBuffer);
                    }
                    return resultat;
                }
            }               
});

2) 转换:

var terrainProvider = new Cesium.GeoserverTerrainProvider({
            service: "WMS", 
            url : "http://geoserver.deimos-space.com/geoserver/elevation/wms",            
            xml: "http://geoserver.deimos-space.com/geoserver/elevation/wms?SERVICE=WMS&REQUEST=GetCapabilities&tiled=true",
            layerName: "IGN_22_July_DEM_pyramid_Transparent_Converted",
            hasStyledImage: false,         
            formatImage: {format : "image/png",extension: "png"},
            formatArray: {
                format : "image/bil",
                /**
                * bufferIn : buffer to process (switch byte order and check the data limitations)
                * size: defines the dimension of the array (size.height* size.width cells)
                * highest: defines the highest altitude (without offset) of the data. 
                * lowest: defines the lowest altitude (without offset) of the data. 
                * offset: defines the offset of the data in order to adjust the limitations
                */
                postProcessArray : function(bufferIn, size,highest,lowest,offset) {
                    var resultat;
                    var viewerIn = new DataView(bufferIn);
                    var littleEndianBuffer = new ArrayBuffer(size.height * size.width * 2);
                    var viewerOut = new DataView(littleEndianBuffer);
                    if (littleEndianBuffer.byteLength === bufferIn.byteLength) {
                        // time to switch bytes!!
                        var temp, goodCell = 0, somme = 0;
                        for (var i = 0; i < littleEndianBuffer.byteLength; i += 2) {
                            temp = viewerIn.getInt16(i, false)-offset;
                            if (temp > lowest && temp < highest) {
                                viewerOut.setInt16(i, temp, true);
                                somme += temp;
                                goodCell++;
                            } else {
                                var val = (goodCell == 0 ? 1 : somme / goodCell);
                                viewerOut.setInt16(i, val, true);
                            }
                        }
                        resultat = new Int16Array(littleEndianBuffer);
                    }
                    return resultat;
                }
            }               
});

3) 账单/DDS:

var terrainProvider = new Cesium.GeoserverTerrainProvider({
            service: "WMS", 
            url : "http://geoserver.deimos-space.com/geoserver/elevation/wms",            
            xml: "http://geoserver.deimos-space.com/geoserver/elevation/wms?SERVICE=WMS&REQUEST=GetCapabilities&tiled=true",
            layerName: "IGN_22_July_DEM_Pyramid_Transparent_Int16",     
            hasStyledImage: false,      
 });
4

3 回答 3

0

您可以尝试使用 gdal 命令,因为它解决了我的问题(与您的相同):

gdalwarp -ot Int16 -s_srs "EPSG:2154" -t_srs "EPSG:4326" -dstnodata -32762 -r cubicspline -multi -co "TILED=YES" -co "COMPRESS=DEFLATE" -co "ZLEVEL=6" *.asc outFolder/gray.tif

gdal_retile.py -v -r bilinear -levels 3 -ps 2048 2048 -ot Int16 -co "TILED=YES" -co "COMPRESS=DEFLATE" -co "ZLEVEL=6" -targetDir pyramidFolder outFolder/gray.tif

有关详细信息,请参阅https://groups.google.com/d/msg/cesium-dev/6aR35AuZ0mM/mVWaeKsPqg8J

于 2015-02-02T10:26:01.843 回答
0

我不确定 GeoserverTerrainProvider 是否是奇数海拔的根本原因。这里的工作流程中有很多数据操作;其中任何一个都可能产生这些工件。为了确认,您可能需要将 GeoTIFF 拉入 QGIS/ArcGIS 之类的工具中,并检查沿瓷砖边缘的高程。

更大的问题是,对于 5m 分辨率的数据,最好使用量化网格格式来更好地传输高度数据和更高性能的渲染。当直接使用高度图时,您将向客户端发送大量数据,然后 Cesium 必须为请求的每个图块细分高度图。如果您计划可视化整个 DEM 数据集或向您的应用程序添加更多 3d 可视化,这将无法扩展。

预生成量化网格图块的唯一解决方案是 STK 地形服务器(http://www.agi.com/products/stk/terrain-server/),好消息是您将能够直接创建图块集从源 asc 文件。这是商业软件,但您可以获得演示许可证并查看它处理数据的能力。

于 2014-09-22T01:00:45.893 回答
0

我是 Cesium SDK 的新手,但从使用示例:Cesium Terrain Provider Usgae

示例:Cesium Terrain Provider Example

我注意到他们为 StyleName 属性提供了 mySLD.xml 中的StyleName而不是文件名 ( mySLD.Xml )。而您使用的是(Style FileName),因此请尝试使用文件中的 StyleName 而不是文件名本身。

var terrainProvider = new Cesium.GeoserverTerrainProvider({
    url : "http://localhost:8080/geoserver/elevation/wms",
    layerName: "SRTM90",
    styleName:"grayToColor",
    waterMask:true
});

在您的代码中:

styleName:"mySLD"

但在示例中:

styleName:"grayToColor"

我知道这很琐碎,但可能会有所帮助。

于 2015-01-10T12:15:33.260 回答