PNTSLoaderBase.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // PNTS File Format
  2. // https://github.com/CesiumGS/3d-tiles/blob/master/specification/TileFormats/PointCloud/README.md
  3. import { FeatureTable, BatchTable } from "../utilities/FeatureTable.js";
  4. export class PNTSLoaderBase {
  5. constructor() {
  6. this.fetchOptions = {};
  7. }
  8. load( url ) {
  9. return fetch( url, this.fetchOptions )
  10. .then( res => {
  11. if ( ! res.ok ) {
  12. throw new Error( `Failed to load file "${ url }" with status ${ res.status } : ${ res.statusText }` );
  13. }
  14. return res.arrayBuffer();
  15. } )
  16. .then( buffer => this.parse( buffer ) );
  17. }
  18. parse( buffer ) {
  19. const dataView = new DataView( buffer );
  20. // 28-byte header
  21. // 4 bytes
  22. const magic =
  23. String.fromCharCode( dataView.getUint8( 0 ) ) +
  24. String.fromCharCode( dataView.getUint8( 1 ) ) +
  25. String.fromCharCode( dataView.getUint8( 2 ) ) +
  26. String.fromCharCode( dataView.getUint8( 3 ) );
  27. console.assert( magic === 'pnts' );
  28. // 4 bytes
  29. const version = dataView.getUint32( 4, true );
  30. console.assert( version === 1 );
  31. // 4 bytes
  32. const byteLength = dataView.getUint32( 8, true );
  33. console.assert( byteLength === buffer.byteLength );
  34. // 4 bytes
  35. const featureTableJSONByteLength = dataView.getUint32( 12, true );
  36. // 4 bytes
  37. const featureTableBinaryByteLength = dataView.getUint32( 16, true );
  38. // 4 bytes
  39. const batchTableJSONByteLength = dataView.getUint32( 20, true );
  40. // 4 bytes
  41. const batchTableBinaryByteLength = dataView.getUint32( 24, true );
  42. // Feature Table
  43. const featureTableStart = 28;
  44. const featureTableBuffer = buffer.slice(
  45. featureTableStart,
  46. featureTableStart + featureTableJSONByteLength + featureTableBinaryByteLength,
  47. );
  48. const featureTable = new FeatureTable(
  49. featureTableBuffer,
  50. 0,
  51. featureTableJSONByteLength,
  52. featureTableBinaryByteLength,
  53. );
  54. // Batch Table
  55. const batchTableStart = featureTableStart + featureTableJSONByteLength + featureTableBinaryByteLength;
  56. const batchTableBuffer = buffer.slice(
  57. batchTableStart,
  58. batchTableStart + batchTableJSONByteLength + batchTableBinaryByteLength,
  59. );
  60. const batchTable = new BatchTable(
  61. batchTableBuffer,
  62. featureTable.getData( 'BATCH_LENGTH' ) || featureTable.getData( 'POINTS_LENGTH' ),
  63. 0,
  64. batchTableJSONByteLength,
  65. batchTableBinaryByteLength,
  66. );
  67. return {
  68. version,
  69. featureTable,
  70. batchTable,
  71. };
  72. }
  73. }