我和我的团队正在使用 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,
});