Cesium Terrain Builder 非压缩瓦片

Cesium Terrain Builder
输出瓦片默认是zib压缩后的,在业务中如果传输不是问题,反而增加浏览器的解压处理,希望能支持输出非压缩瓦片。
针对此需求,修改代码并重新编译。

一、代码分析

1、输出数据对象
文件格式:主要为heightmap-1.0、quantized-mesh-1.0,其类图结构如下:

  • MeshTile为quantized-mesh-1.0格式数据对象。
  • TerrainTile为heightmap-1.0格式数据对象。

在这里插入图片描述
2、瓦片生成器

  • Meshtiler 用来生成MeshTile对象。
  • TerrainTiler 用来生成TerrainTile对象。
    在这里插入图片描述

3、迭代器和序列化器
在这里插入图片描述

4、ctb-tile.exe的主要流程
在这里插入图片描述

二、功能扩展

1、增加非压缩支持。

  1. ctb-tile.cpp中TerrainBuild类,增加参数
// 内部变量
bool gzib;

// 构造函数设置默认值
gzib(false)

// 设置压缩参数
static void setGzib(command_t* command) {
 static_cast<TerrainBuild *>(Command::self(command))->gzib = true;
}
  1. ctb-tile.cpp中main函数解析参数
command.option("-G", "--gzip", "use zib compress file(defalut uncompress)", TerrainBuild::setGzib);
  1. CTBFileTileSerializer.cpp中,serializeTile函数增加zibFlag参数。根据gzibFlag决定是否使用CTBZFileOutputStream(压缩)或者CTBFileOutputStream(非压缩)
/**
 * @details 
 * Serialize a MeshTile to the Directory store
 * 增加zibFlag,是否输出压缩格式文件
 */
bool
ctb::CTBFileTileSerializer::serializeTile(const ctb::MeshTile *tile, bool writeVertexNormals, bool gzibFlag) {
  const TileCoordinate *coordinate = tile;
  const string filename = getTileFilename(coordinate, moutputDir, "terrain");
  const string temp_filename = concat(filename, ".tmp");

  if (gzibFlag) {
	  CTBZFileOutputStream ostream(temp_filename.c_str());
	  tile->writeFile(ostream, writeVertexNormals);
	  ostream.close();
  } else {
	  FILE *fp = fopen(temp_filename.c_str(), "wb");
	  CTBFileOutputStream ostream(fp);
	  tile->writeFile(ostream, writeVertexNormals);
	  fclose(fp);
  }

  if (VSIRename(temp_filename.c_str(), filename.c_str()) != 0) {
    throw new CTBException("Could not rename temporary file");
  }
  return true;
}
  1. ctb-tile.cpp中buildMesh函数,修改为传递gzlib函数
//serializer.serializeTile(tile, writeVertexNormals);
serializer.serializeTile(tile, writeVertexNormals, command->gzib); 

2、输出指定范围的瓦片

  1. ctb-tile.cpp中TerrainBuild类,增加参数
// 内部变量
int layerStartX, layerStartY, layerEndX, layerEndY;

// 构造函数设置默认值
layerStartX(-1),
layerStartY(-1),
layerEndX(-1),
layerEndY(-1)

//设置参数函数
static void setLayerStartX(command_t *command) {
 static_cast<TerrainBuild *>(Command::self(command))->layerStartX = atoi(command->arg);
}
static void setLayerStartY(command_t *command) {
 static_cast<TerrainBuild *>(Command::self(command))->layerStartY = atoi(command->arg);
}
static void setLayerEndX(command_t *command) {
 static_cast<TerrainBuild *>(Command::self(command))->layerEndX = atoi(command->arg);
}
static void setLayerEndY(command_t *command) {
 static_cast<TerrainBuild *>(Command::self(command))->layerEndY = atoi(command->arg);
}
  1. ctb-tile.cpp中main函数解析参数
command.option("-A", "--start-x <sx>", "tile’s start x ", TerrainBuild::setLayerStartX);
command.option("-D", "--end-x <ex>", "tile’s end x", TerrainBuild::setLayerEndX);
command.option("-W", "--start-y <sy>", "tile’s start y", TerrainBuild::setLayerStartY);
command.option("-S", "--end-y <ey>", "tile’s end y", TerrainBuild::setLayerEndY);
  1. ctb-tile.cpp修改buildMesh方法
/// Output mesh tiles represented by a tiler to a directory
static void buildMesh(MeshSerializer &serializer, const MeshTiler &tiler, TerrainBuild *command, TerrainMetadata *metadata, bool writeVertexNormals = false) {
  i_zoom startZoom = (command->startZoom < 0) ? tiler.maxZoomLevel() : command->startZoom,
    endZoom = (command->endZoom < 0) ? 0 : command->endZoom;

  // 取得参数中瓦片坐标
  int layerStartX = (command->layerStartX < 0)? 0: command->layerStartX,
    layerStartY = (command->layerStartY < 0) ? 0 : command->layerStartY,
    layerEndX = (command->layerEndX < 0) ? 0 : command->layerEndX,
    layerEndY = (command->layerEndY < 0) ? 0 : command->layerEndY;

  MeshIterator iter(tiler, startZoom, endZoom);
  int currentIndex = incrementIterator(iter, 0);
  setIteratorSize(iter);
  GDALDatasetReaderWithOverviews reader(tiler);

  while (!iter.exhausted()) {
	  const TileCoordinate *coordinate = iter.GridIterator::operator*();
	  if (metadata) metadata->add(tiler.grid(), coordinate);

	  // 如果没有指定瓦片坐标或zoom级别不是一个,使用原来逻辑
	  if (layerStartX == 0 && layerEndX == 0 && startZoom != endZoom) {
		  if (serializer.mustSerializeCoordinate(coordinate)) {
			  MeshTile *tile = iter.operator*(&reader);
			  serializer.serializeTile(tile, writeVertexNormals, command->gzib);
			  delete tile;
		  }
	  }
	  else {
		  // 如果有瓦片坐标,只生成瓦片坐标范围内的文件
		  if (coordinate->x >= layerStartX && coordinate->x <= layerEndX && coordinate->y >= layerStartY && coordinate->y <= layerEndY) {
			  if (serializer.mustSerializeCoordinate(coordinate)) {
				  MeshTile *tile = iter.operator*(&reader);
				  serializer.serializeTile(tile, writeVertexNormals, command->gzib);
				  delete tile;
			  }
		  }
	  }

    currentIndex = incrementIterator(iter, currentIndex);
    showProgress(currentIndex);
  }
}

三、命令行说明

编译成功后,就支持非压缩切片和生成指定范围的切片功能了。

  1. 调用说明
ctb-tile.exe -o D:/test/tile D:/test/dem.tif -f Mesh -s 6 -e 6 -A 105 -D 107 -W 45 -S 47
  1. 完整参数说明
参数说明
-V输出程序版本。
-h输出帮助信息。
-o切片输出路径。
-p切片规则。默认geodetic,可以指定mercator
-f切片格式。默认Terrain,可以指定Mesh
-c使用线程数。默认同cpu数
-t瓦片像素大小。默认65*65
-s瓦片开始级别。
-e瓦片结束级别。注意:开始级别 > 结束级别
-r重采样方法。默认平均值,可以指定min,max,average,nearest,bilinear,cubic等。
-R不覆盖现有文件。
-G生成zib压缩切片。
-A切片范围,x开始索引。
-D切片范围,x结束索引。
-W切片范围,y开始索引。
-S切片范围,y结束索引。
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值