Cesium GeoserverTerrainProvider插件在地形图块之间显示高度值的锐减

时间:2014-09-19 15:04:23

标签: geoserver cesium

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

  • 使用"样式"图像格式或" bil / dds"插件地形在两个地形图块连接处的高度值中几乎没有明显的切割

  • 使用"转换"图像格式(见下文)地形有海拔高度

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

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

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

我们正在使用5米分辨率的数字高程模型。文件格式为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中服务 我们使用BIL / DDS插件跟踪https://github.com/kaktus40/Cesium-GeoserverTerrainProvider上的说明。

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

1)STYLED:

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)CONVERTED:

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)BIL / 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,      
 });

3 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分: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"

我知道它是如此微不足道,但可能会有所帮助。

答案 2 :(得分: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