Files
massive-cloud/server/pointcloudSample.test.ts

61 lines
2.0 KiB
TypeScript

import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { afterEach, describe, expect, it } from 'vitest';
import { samplePointcloudFile } from './pointcloudSample';
const temporaryDirectories: string[] = [];
afterEach(() => {
while (temporaryDirectories.length > 0) {
rmSync(temporaryDirectories.pop()!, { recursive: true, force: true });
}
});
function writeBinaryPly(properties: string[], records: number[][]): string {
const directory = mkdtempSync(join(tmpdir(), 'pointcloud-sample-'));
temporaryDirectories.push(directory);
const filePath = join(directory, 'cloud.ply');
const header = Buffer.from([
'ply',
'format binary_little_endian 1.0',
`element vertex ${records.length}`,
...properties.map((name) => `property float ${name}`),
'end_header',
'',
].join('\n'), 'ascii');
const body = Buffer.alloc(records.length * properties.length * 4);
records.forEach((record, recordIndex) => {
record.forEach((value, propertyIndex) => {
body.writeFloatLE(value, (recordIndex * properties.length + propertyIndex) * 4);
});
});
writeFileSync(filePath, Buffer.concat([header, body]));
return filePath;
}
describe('samplePointcloudFile', () => {
it('不会为只有 xyz 的输入点云伪造误差', async () => {
const filePath = writeBinaryPly(
['x', 'y', 'z'],
[[1, 2, 3], [4, 5, 6]],
);
const points = await samplePointcloudFile(filePath, 1_000, 2);
expect(points).toHaveLength(2);
expect(points.every((point) => point.error === undefined)).toBe(true);
});
it.each(['error', 'deviation'])('保留 PLY 中真实的 %s 属性', async (errorProperty) => {
const filePath = writeBinaryPly(
['x', 'y', 'z', errorProperty],
[[1, 2, 3, 0.25], [4, 5, 6, -0.5]],
);
const points = await samplePointcloudFile(filePath, 1_000, 2);
expect(points.map((point) => point.error)).toEqual([0.25, -0.5]);
});
});