UNPKG

tileset

Version:

A TypeScript library for working with 3D Tiles tileset.json files

216 lines (215 loc) 6.22 kB
"use strict"; 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;