tileset
Version:
A TypeScript library for working with 3D Tiles tileset.json files
216 lines (215 loc) • 6.22 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.TilesetClass = void 0;
const validator_1 = require("./validator");
/**
* Tileset 类
* 提供解析、验证和操作 3D Tiles 数据集的功能
*/
class TilesetClass {
/**
* 创建一个 Tileset 实例
* @param data Tileset 数据对象
*/
constructor(data) {
this.data = data;
this.validator = new validator_1.TilesetValidator();
}
/**
* 解析 JSON 字符串为 Tileset 实例
* @param json JSON 字符串
* @param options 解析选项
* @returns Tileset 实例
*/
static parse(json, options = {}) {
try {
const parsedData = JSON.parse(json);
if (!parsedData || typeof parsedData !== 'object') {
throw new Error('Invalid JSON format: Expected an object');
}
const tilesetData = parsedData;
const tileset = new TilesetClass(tilesetData);
if (options.validate) {
const result = tileset.validate();
if (!result.valid) {
throw new Error(`Validation failed: ${result.errors.join('; ')}`);
}
}
return tileset;
}
catch (error) {
throw new Error(`Failed to parse tileset: ${error.message}`);
}
}
/**
* 从对象创建 Tileset 实例
* @param data Tileset 数据对象
* @param options 解析选项
* @returns Tileset 实例
*/
static fromObject(data, options = {}) {
if (!data || typeof data !== 'object') {
throw new Error('Invalid input: Expected an object conforming to Tileset interface');
}
const tileset = new TilesetClass(data);
if (options.validate) {
const result = tileset.validate();
if (!result.valid) {
throw new Error(`Validation failed: ${result.errors.join('; ')}`);
}
}
return tileset;
}
/**
* 验证当前 tileset 的结构
* @returns 验证结果
*/
validate() {
return this.validator.validate(this.data);
}
/**
* 将 tileset 转换为 JSON 字符串
* @param space 缩进空格数
* @returns JSON 字符串
*/
toJSON(space) {
return JSON.stringify(this.data, null, space);
}
/**
* 获取原始数据对象
* @returns Tileset 数据对象
*/
toObject() {
// 返回深拷贝,避免外部修改内部数据
return JSON.parse(JSON.stringify(this.data));
}
/**
* 获取根瓦片
* @returns 根瓦片
*/
getRootTile() {
return this.data.root;
}
/**
* 获取所有瓦片(递归)
* @returns 所有瓦片的数组
*/
getAllTiles() {
const tiles = [];
this.traverse((tile) => tiles.push(tile));
return tiles;
}
/**
* 遍历所有瓦片
* @param callback 处理每个瓦片的回调函数
* @param tile 起始瓦片,默认为根瓦片
*/
traverse(callback, tile = this.data.root, depth = 0) {
callback(tile, depth);
if (Array.isArray(tile.children)) {
tile.children.forEach((child) => {
this.traverse(callback, child, depth + 1);
});
}
}
/**
* 查找符合条件的瓦片
* @param predicate 判断条件
* @returns 第一个符合条件的瓦片,或 undefined
*/
findTile(predicate) {
let result;
this.traverse((tile) => {
if (!result && predicate(tile)) {
result = tile;
}
});
return result;
}
/**
* 查找所有符合条件的瓦片
* @param predicate 判断条件
* @returns 所有符合条件的瓦片数组
*/
findAllTiles(predicate) {
const results = [];
this.traverse((tile) => {
if (predicate(tile)) {
results.push(tile);
}
});
return results;
}
/**
* 获取瓦片总数
* @returns 瓦片总数
*/
getTileCount() {
let count = 0;
this.traverse(() => count++);
return count;
}
/**
* 获取数据集版本
* @returns 版本字符串
*/
getVersion() {
return this.data.asset.version;
}
/**
* 获取自定义属性
* @returns 属性对象
*/
getProperties() {
return this.data.properties;
}
/**
* 设置自定义属性
* @param properties 新的属性对象
*/
setProperties(properties) {
this.data.properties = properties;
}
/**
* 获取使用的扩展
* @returns 扩展名称数组
*/
getExtensionsUsed() {
return this.data.extensionsUsed;
}
/**
* 添加扩展到扩展列表
* @param extension 扩展名称
*/
addExtension(extension) {
if (!this.data.extensionsUsed) {
this.data.extensionsUsed = [];
}
if (!this.data.extensionsUsed.includes(extension)) {
this.data.extensionsUsed.push(extension);
}
}
/**
* 计算整个数据集的边界体积
* @returns 边界体积
*/
computeOverallBoundingVolume() {
const allTiles = this.getAllTiles();
const boundingVolumes = allTiles.map(tile => tile.boundingVolume);
const mergedRegion = boundingVolumes
.filter(bv => bv.region)
.reduce((merged, current) => {
const region = current.region;
return [
Math.min(merged[0], region[0]), // 西经
Math.min(merged[1], region[1]), // 南纬
Math.max(merged[2], region[2]), // 东经
Math.max(merged[3], region[3]), // 北纬
Math.min(merged[4], region[4]), // 最小高度
Math.max(merged[5], region[5]) // 最大高度
];
}, [Infinity, Infinity, -Infinity, -Infinity, Infinity, -Infinity]);
return { region: mergedRegion };
}
}
exports.TilesetClass = TilesetClass;
;