tileset
Version:
A TypeScript library for working with 3D Tiles tileset.json files
146 lines (145 loc) • 5.42 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.TilesetValidator = void 0;
/**
* Tileset 验证器
* 负责验证 tileset 结构是否符合 3D Tiles 规范
*/
class TilesetValidator {
/**
* 验证整个 tileset
* @param tileset 要验证的 tileset 对象
* @returns 验证结果
*/
validate(tileset) {
const result = {
valid: true,
errors: [],
warnings: []
};
// 验证顶层必填字段
this.validateAsset(tileset.asset, result);
if (tileset.geometricError === undefined || typeof tileset.geometricError !== 'number' || tileset.geometricError < 0) {
result.errors.push('Tileset must have a valid geometricError (non-negative number)');
result.valid = false;
}
if (!tileset.root) {
result.errors.push('Tileset must have a root tile');
result.valid = false;
}
else {
// 验证根瓦片及其子瓦片
this.validateTile(tileset.root, tileset.geometricError, result);
}
return result;
}
/**
* 验证 asset 字段
*/
validateAsset(asset, result) {
if (!asset) {
result.errors.push('Tileset must have an asset');
result.valid = false;
return;
}
if (!asset.version || typeof asset.version !== 'string') {
result.errors.push('Asset must have a valid version string');
result.valid = false;
}
else if (!this.isValidVersion(asset.version)) {
result.warnings.push(`Unsupported version ${asset.version}, supported versions are 1.0 and 1.1`);
}
}
/**
* 验证瓦片
* @param tile 要验证的瓦片
* @param parentGeometricError 父瓦片的几何误差
* @param result 验证结果
*/
validateTile(tile, parentGeometricError, result) {
// 验证 boundingVolume
if (!tile.boundingVolume) {
result.errors.push('Tile must have a boundingVolume');
result.valid = false;
}
else {
this.validateBoundingVolume(tile.boundingVolume, result);
}
// 验证 geometricError
if (tile.geometricError === undefined || typeof tile.geometricError !== 'number' || tile.geometricError < 0) {
result.errors.push('Tile must have a valid geometricError (non-negative number)');
result.valid = false;
}
else if (tile.geometricError >= parentGeometricError) {
result.errors.push(`Tile's geometricError (${tile.geometricError}) must be less than parent's (${parentGeometricError})`);
result.valid = false;
}
// 验证 refine 字段(如果存在)
if (tile.refine && tile.refine !== 'REPLACE' && tile.refine !== 'ADD') {
result.errors.push(`Tile has invalid refine value: ${tile.refine}, must be 'REPLACE' or 'ADD'`);
result.valid = false;
}
// 验证 content(如果存在)
if (tile.content && tile.content.uri && typeof tile.content.uri !== 'string') {
result.errors.push('Tile content must have a valid uri string');
result.valid = false;
}
// 递归验证子瓦片
if (tile.children && Array.isArray(tile.children)) {
tile.children.forEach(child => {
this.validateTile(child, tile.geometricError, result);
});
}
else if (tile.children) {
result.errors.push('Tile children must be an array');
result.valid = false;
}
}
/**
* 验证包围体
*/
validateBoundingVolume(boundingVolume, result) {
const types = [];
if (boundingVolume.region)
types.push('region');
if (boundingVolume.box)
types.push('box');
if (boundingVolume.sphere)
types.push('sphere');
if (types.length === 0) {
result.errors.push('BoundingVolume must have one of: region, box, or sphere');
result.valid = false;
return;
}
if (types.length > 1) {
result.errors.push(`BoundingVolume must have only one type, found: ${types.join(', ')}`);
result.valid = false;
}
// 验证每种类型的结构
if (boundingVolume.region) {
if (!Array.isArray(boundingVolume.region) || boundingVolume.region.length !== 6) {
result.errors.push('Region must be an array of 6 numbers');
result.valid = false;
}
}
if (boundingVolume.box) {
if (!Array.isArray(boundingVolume.box) || boundingVolume.box.length !== 6) {
result.errors.push('Box must be an array of 6 numbers');
result.valid = false;
}
}
if (boundingVolume.sphere) {
if (!Array.isArray(boundingVolume.sphere) || boundingVolume.sphere.length !== 4) {
result.errors.push('Sphere must be an array of 4 numbers');
result.valid = false;
}
}
}
/**
* 检查版本是否有效
*/
isValidVersion(version) {
return version === '1.0' || version === '1.1';
}
}
exports.TilesetValidator = TilesetValidator;
;