UNPKG

b3dm

Version:

A TypeScript library for parsing and building B3DM (Batched 3D Model) files

1 lines 10.9 kB
{"version":3,"sources":["../package.json","../src/parser.ts","../src/builder.ts","../src/index.ts"],"sourcesContent":["{\r\n \"name\": \"b3dm\", \r\n \"version\": \"0.1.1\", \r\n \"description\": \"A TypeScript library for parsing and building B3DM (Batched 3D Model) files\",\r\n \"main\": \"dist/index.cjs\", \r\n \"module\": \"dist/index.js\", \r\n \"types\": \"dist/index.d.ts\", \r\n \"exports\": {\r\n \".\": {\r\n \"import\": \"./dist/index.js\",\r\n \"require\": \"./dist/index.cjs\",\r\n \"types\": \"./dist/index.d.ts\"\r\n }\r\n },\r\n \"scripts\": {\r\n \"build\": \"tsup\",\r\n \"prepublishOnly\": \"npm run build\",\r\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\r\n },\r\n \"keywords\": [\"b3dm\", \"3d-tiles\", \"gltf\", \"3d\", \"geospatial\", \"typescript\"],\r\n \"author\": \"Your Name\",\r\n \"license\": \"MIT\",\r\n \"homepage\": \"https://github.com/your-username/b3dm-ts\", \r\n \"repository\": {\r\n \"type\": \"git\",\r\n \"url\": \"git+https://github.com/your-username/b3dm-ts.git\"\r\n },\r\n \"bugs\": {\r\n \"url\": \"https://github.com/your-username/b3dm-ts/issues\"\r\n },\r\n \"devDependencies\": {\r\n \"@types/node\": \"^20.0.0\",\r\n \"rimraf\": \"^5.0.0\",\r\n \"tsup\": \"^8.0.0\",\r\n \"typescript\": \"^5.0.0\"\r\n }\r\n }","import { B3dmData, B3dmHeader } from './types';\r\n\r\n/**\r\n * 解析B3DM二进制数据\r\n * @param arrayBuffer B3DM文件的ArrayBuffer\r\n * @returns 解析后的B3DM数据结构\r\n */\r\nexport function parseB3dm(arrayBuffer: ArrayBuffer): B3dmData {\r\n const dataView = new DataView(arrayBuffer);\r\n let offset = 0;\r\n\r\n // 1. 解析文件头(28字节)\r\n const header: B3dmHeader = {} as B3dmHeader;\r\n\r\n header.magic = String.fromCharCode(\r\n dataView.getUint8(offset++),\r\n dataView.getUint8(offset++),\r\n dataView.getUint8(offset++),\r\n dataView.getUint8(offset++)\r\n );\r\n header.version = dataView.getUint32(offset, true); offset += 4;\r\n header.byteLength = dataView.getUint32(offset, true); offset += 4;\r\n header.featureTableJSONByteLength = dataView.getUint32(offset, true); offset += 4;\r\n header.featureTableBinaryByteLength = dataView.getUint32(offset, true); offset += 4;\r\n header.batchTableJSONByteLength = dataView.getUint32(offset, true); offset += 4;\r\n header.batchTableBinaryByteLength = dataView.getUint32(offset, true); offset += 4;\r\n\r\n // 校验文件标识\r\n if (header.magic !== 'b3dm') {\r\n throw new Error('Invalid B3DM file: magic number mismatch');\r\n }\r\n\r\n // 2. 解析特征表\r\n const featureTableJSON = JSON.parse(\r\n new TextDecoder().decode(\r\n new Uint8Array(arrayBuffer.slice(offset, offset + header.featureTableJSONByteLength))\r\n )\r\n );\r\n offset += header.featureTableJSONByteLength;\r\n\r\n const featureTableBinary = header.featureTableBinaryByteLength > 0\r\n ? new Uint8Array(arrayBuffer.slice(offset, offset + header.featureTableBinaryByteLength))\r\n : undefined;\r\n offset += header.featureTableBinaryByteLength;\r\n\r\n // 3. 解析批量表(可选)\r\n let batchTable = undefined;\r\n if (header.batchTableJSONByteLength > 0) {\r\n const batchTableJSON = JSON.parse(\r\n new TextDecoder().decode(\r\n new Uint8Array(arrayBuffer.slice(offset, offset + header.batchTableJSONByteLength))\r\n )\r\n );\r\n offset += header.batchTableJSONByteLength;\r\n\r\n const batchTableBinary = header.batchTableBinaryByteLength > 0\r\n ? new Uint8Array(arrayBuffer.slice(offset, offset + header.batchTableBinaryByteLength))\r\n : undefined;\r\n offset += header.batchTableBinaryByteLength;\r\n\r\n batchTable = { json: batchTableJSON, binary: batchTableBinary };\r\n }\r\n\r\n // 4. 提取GLB数据(剩余部分)\r\n const glbData = new Uint8Array(arrayBuffer.slice(offset));\r\n\r\n return { header, featureTable: { json: featureTableJSON, binary: featureTableBinary }, batchTable, glbData };\r\n}","import { B3dmBuildOptions, B3dmHeader } from './types';\r\n\r\n/**\r\n * 构建B3DM二进制数据\r\n * @param options 构建选项(包含GLB和元数据)\r\n * @returns B3DM的ArrayBuffer\r\n */\r\nexport function buildB3dm(options: B3dmBuildOptions): ArrayBuffer {\r\n const {\r\n glbData,\r\n featureTableJSON = {},\r\n featureTableBinary = new Uint8Array(0),\r\n batchTableJSON = {},\r\n batchTableBinary = new Uint8Array(0),\r\n } = options;\r\n\r\n // 1. 计算各部分长度\r\n const featureTableJSONStr = JSON.stringify(featureTableJSON);\r\n const featureTableJSONByteLength = new TextEncoder().encode(featureTableJSONStr).length;\r\n const featureTableBinaryByteLength = featureTableBinary.byteLength;\r\n const batchTableJSONStr = Object.keys(batchTableJSON).length > 0 ? JSON.stringify(batchTableJSON) : '';\r\n const batchTableJSONByteLength = new TextEncoder().encode(batchTableJSONStr).length;\r\n const batchTableBinaryByteLength = batchTableBinary.byteLength;\r\n const glbByteLength = glbData.byteLength;\r\n\r\n // 2. 计算文件总长度(头28字节 + 各部分长度)\r\n const totalByteLength = 28 + featureTableJSONByteLength + featureTableBinaryByteLength + batchTableJSONByteLength + batchTableBinaryByteLength + glbByteLength;\r\n\r\n // 3. 构建文件头\r\n const header: B3dmHeader = {\r\n magic: 'b3dm',\r\n version: 1,\r\n byteLength: totalByteLength,\r\n featureTableJSONByteLength,\r\n featureTableBinaryByteLength,\r\n batchTableJSONByteLength,\r\n batchTableBinaryByteLength,\r\n };\r\n\r\n // 4. 写入二进制数据\r\n const arrayBuffer = new ArrayBuffer(totalByteLength);\r\n const dataView = new DataView(arrayBuffer);\r\n let offset = 0;\r\n\r\n // 写入文件头(28字节)\r\n for (const char of header.magic) {\r\n dataView.setUint8(offset++, char.charCodeAt(0));\r\n }\r\n dataView.setUint32(offset, header.version, true); offset += 4;\r\n dataView.setUint32(offset, header.byteLength, true); offset += 4;\r\n dataView.setUint32(offset, header.featureTableJSONByteLength, true); offset += 4;\r\n dataView.setUint32(offset, header.featureTableBinaryByteLength, true); offset += 4;\r\n dataView.setUint32(offset, header.batchTableJSONByteLength, true); offset += 4;\r\n dataView.setUint32(offset, header.batchTableBinaryByteLength, true); offset += 4;\r\n\r\n // 写入特征表\r\n new Uint8Array(arrayBuffer).set(new TextEncoder().encode(featureTableJSONStr), offset);\r\n offset += featureTableJSONByteLength;\r\n if (featureTableBinaryByteLength > 0) {\r\n new Uint8Array(arrayBuffer).set(featureTableBinary, offset);\r\n offset += featureTableBinaryByteLength;\r\n }\r\n\r\n // 写入批量表\r\n if (batchTableJSONByteLength > 0) {\r\n new Uint8Array(arrayBuffer).set(new TextEncoder().encode(batchTableJSONStr), offset);\r\n offset += batchTableJSONByteLength;\r\n }\r\n if (batchTableBinaryByteLength > 0) {\r\n new Uint8Array(arrayBuffer).set(batchTableBinary, offset);\r\n offset += batchTableBinaryByteLength;\r\n }\r\n\r\n // 写入GLB数据\r\n new Uint8Array(arrayBuffer).set(glbData, offset);\r\n\r\n return arrayBuffer;\r\n}","export * from './parser';\r\nexport * from './builder';\r\nexport * from './types';\r\n\r\n// 导出库版本(从package.json读取)\r\nexport const version = require('../package.json').version;"],"mappings":"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","names":[]}