@loaders.gl/i3s 4.0.0-alpha.5 → 4.0.0-alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/dist/arcgis-webscene-loader.d.ts +7 -0
  2. package/dist/arcgis-webscene-loader.d.ts.map +1 -0
  3. package/dist/arcgis-webscene-loader.js +28 -0
  4. package/dist/bundle.js +2 -2
  5. package/dist/dist.min.js +9390 -8570
  6. package/dist/es5/arcgis-webscene-loader.js +40 -0
  7. package/dist/es5/arcgis-webscene-loader.js.map +1 -0
  8. package/dist/es5/bundle.js +6 -0
  9. package/dist/es5/bundle.js.map +1 -0
  10. package/dist/es5/i3s-attribute-loader.js +195 -0
  11. package/dist/es5/i3s-attribute-loader.js.map +1 -0
  12. package/dist/es5/i3s-building-scene-layer-loader.js +46 -0
  13. package/dist/es5/i3s-building-scene-layer-loader.js.map +1 -0
  14. package/dist/es5/i3s-content-loader.js +56 -0
  15. package/dist/es5/i3s-content-loader.js.map +1 -0
  16. package/dist/es5/i3s-loader.js +193 -0
  17. package/dist/es5/i3s-loader.js.map +1 -0
  18. package/dist/es5/i3s-node-page-loader.js +39 -0
  19. package/dist/es5/i3s-node-page-loader.js.map +1 -0
  20. package/dist/es5/i3s-slpk-loader.js +20 -0
  21. package/dist/es5/i3s-slpk-loader.js.map +1 -0
  22. package/dist/es5/index.js +68 -0
  23. package/dist/es5/index.js.map +1 -0
  24. package/dist/es5/lib/helpers/i3s-nodepages-tiles.js +312 -0
  25. package/dist/es5/lib/helpers/i3s-nodepages-tiles.js.map +1 -0
  26. package/dist/es5/lib/parsers/constants.js +72 -0
  27. package/dist/es5/lib/parsers/constants.js.map +1 -0
  28. package/dist/es5/lib/parsers/parse-arcgis-webscene.js +158 -0
  29. package/dist/es5/lib/parsers/parse-arcgis-webscene.js.map +1 -0
  30. package/dist/es5/lib/parsers/parse-i3s-attribute.js +76 -0
  31. package/dist/es5/lib/parsers/parse-i3s-attribute.js.map +1 -0
  32. package/dist/es5/lib/parsers/parse-i3s-building-scene-layer.js +65 -0
  33. package/dist/es5/lib/parsers/parse-i3s-building-scene-layer.js.map +1 -0
  34. package/dist/es5/lib/parsers/parse-i3s-tile-content.js +510 -0
  35. package/dist/es5/lib/parsers/parse-i3s-tile-content.js.map +1 -0
  36. package/dist/es5/lib/parsers/parse-i3s.js +116 -0
  37. package/dist/es5/lib/parsers/parse-i3s.js.map +1 -0
  38. package/dist/es5/lib/parsers/parse-slpk/parse-slpk.js +94 -0
  39. package/dist/es5/lib/parsers/parse-slpk/parse-slpk.js.map +1 -0
  40. package/dist/es5/lib/parsers/parse-slpk/slpk-archieve.js +112 -0
  41. package/dist/es5/lib/parsers/parse-slpk/slpk-archieve.js.map +1 -0
  42. package/dist/es5/lib/parsers/parse-zip/cd-file-header.js +44 -0
  43. package/dist/es5/lib/parsers/parse-zip/cd-file-header.js.map +1 -0
  44. package/dist/es5/lib/parsers/parse-zip/local-file-header.js +26 -0
  45. package/dist/es5/lib/parsers/parse-zip/local-file-header.js.map +1 -0
  46. package/dist/es5/lib/utils/convert-i3s-obb-to-mbs.js +17 -0
  47. package/dist/es5/lib/utils/convert-i3s-obb-to-mbs.js.map +1 -0
  48. package/dist/es5/lib/utils/customizeColors.js +159 -0
  49. package/dist/es5/lib/utils/customizeColors.js.map +1 -0
  50. package/dist/es5/lib/utils/url-utils.js +33 -0
  51. package/dist/es5/lib/utils/url-utils.js.map +1 -0
  52. package/dist/es5/types.js +26 -0
  53. package/dist/es5/types.js.map +1 -0
  54. package/dist/es5/workers/i3s-content-worker-node.js +7 -0
  55. package/dist/es5/workers/i3s-content-worker-node.js.map +1 -0
  56. package/dist/es5/workers/i3s-content-worker.js +6 -0
  57. package/dist/es5/workers/i3s-content-worker.js.map +1 -0
  58. package/dist/esm/arcgis-webscene-loader.js +16 -0
  59. package/dist/esm/arcgis-webscene-loader.js.map +1 -0
  60. package/dist/esm/bundle.js +4 -0
  61. package/dist/esm/bundle.js.map +1 -0
  62. package/dist/esm/i3s-attribute-loader.js +119 -0
  63. package/dist/esm/i3s-attribute-loader.js.map +1 -0
  64. package/dist/esm/i3s-building-scene-layer-loader.js +19 -0
  65. package/dist/esm/i3s-building-scene-layer-loader.js.map +1 -0
  66. package/dist/esm/i3s-content-loader.js +30 -0
  67. package/dist/esm/i3s-content-loader.js.map +1 -0
  68. package/dist/esm/i3s-loader.js +87 -0
  69. package/dist/esm/i3s-loader.js.map +1 -0
  70. package/dist/esm/i3s-node-page-loader.js +15 -0
  71. package/dist/esm/i3s-node-page-loader.js.map +1 -0
  72. package/dist/esm/i3s-slpk-loader.js +13 -0
  73. package/dist/esm/i3s-slpk-loader.js.map +1 -0
  74. package/dist/esm/index.js +9 -0
  75. package/dist/esm/index.js.map +1 -0
  76. package/dist/esm/lib/helpers/i3s-nodepages-tiles.js +198 -0
  77. package/dist/esm/lib/helpers/i3s-nodepages-tiles.js.map +1 -0
  78. package/dist/esm/lib/parsers/constants.js +57 -0
  79. package/dist/esm/lib/parsers/constants.js.map +1 -0
  80. package/dist/esm/lib/parsers/parse-arcgis-webscene.js +70 -0
  81. package/dist/esm/lib/parsers/parse-arcgis-webscene.js.map +1 -0
  82. package/dist/esm/lib/parsers/parse-i3s-attribute.js +60 -0
  83. package/dist/esm/lib/parsers/parse-i3s-attribute.js.map +1 -0
  84. package/dist/esm/lib/parsers/parse-i3s-building-scene-layer.js +39 -0
  85. package/dist/esm/lib/parsers/parse-i3s-building-scene-layer.js.map +1 -0
  86. package/dist/esm/lib/parsers/parse-i3s-tile-content.js +435 -0
  87. package/dist/esm/lib/parsers/parse-i3s-tile-content.js.map +1 -0
  88. package/dist/esm/lib/parsers/parse-i3s.js +83 -0
  89. package/dist/esm/lib/parsers/parse-i3s.js.map +1 -0
  90. package/dist/esm/lib/parsers/parse-slpk/parse-slpk.js +37 -0
  91. package/dist/esm/lib/parsers/parse-slpk/parse-slpk.js.map +1 -0
  92. package/dist/esm/lib/parsers/parse-slpk/slpk-archieve.js +58 -0
  93. package/dist/esm/lib/parsers/parse-slpk/slpk-archieve.js.map +1 -0
  94. package/dist/esm/lib/parsers/parse-zip/cd-file-header.js +37 -0
  95. package/dist/esm/lib/parsers/parse-zip/cd-file-header.js.map +1 -0
  96. package/dist/esm/lib/parsers/parse-zip/local-file-header.js +19 -0
  97. package/dist/esm/lib/parsers/parse-zip/local-file-header.js.map +1 -0
  98. package/dist/esm/lib/utils/convert-i3s-obb-to-mbs.js +9 -0
  99. package/dist/esm/lib/utils/convert-i3s-obb-to-mbs.js.map +1 -0
  100. package/dist/esm/lib/utils/customizeColors.js +92 -0
  101. package/dist/esm/lib/utils/customizeColors.js.map +1 -0
  102. package/dist/esm/lib/utils/url-utils.js +28 -0
  103. package/dist/esm/lib/utils/url-utils.js.map +1 -0
  104. package/dist/esm/types.js +18 -0
  105. package/dist/esm/types.js.map +1 -0
  106. package/dist/esm/workers/i3s-content-worker-node.js +5 -0
  107. package/dist/esm/workers/i3s-content-worker-node.js.map +1 -0
  108. package/dist/esm/workers/i3s-content-worker.js +4 -0
  109. package/dist/esm/workers/i3s-content-worker.js.map +1 -0
  110. package/dist/i3s-attribute-loader.d.ts +9 -2
  111. package/dist/i3s-attribute-loader.d.ts.map +1 -1
  112. package/dist/i3s-attribute-loader.js +155 -132
  113. package/dist/i3s-building-scene-layer-loader.js +23 -18
  114. package/dist/i3s-content-loader.d.ts.map +1 -1
  115. package/dist/i3s-content-loader.js +29 -22
  116. package/dist/i3s-content-worker-node.js +197 -0
  117. package/dist/i3s-content-worker-node.js.map +7 -0
  118. package/dist/i3s-content-worker.js +1178 -1137
  119. package/dist/i3s-loader.d.ts +5 -0
  120. package/dist/i3s-loader.d.ts.map +1 -1
  121. package/dist/i3s-loader.js +88 -83
  122. package/dist/i3s-node-page-loader.d.ts +3 -2
  123. package/dist/i3s-node-page-loader.d.ts.map +1 -1
  124. package/dist/i3s-node-page-loader.js +20 -20
  125. package/dist/i3s-slpk-loader.d.ts +10 -0
  126. package/dist/i3s-slpk-loader.d.ts.map +1 -0
  127. package/dist/i3s-slpk-loader.js +20 -0
  128. package/dist/index.d.ts +5 -2
  129. package/dist/index.d.ts.map +1 -1
  130. package/dist/index.js +21 -6
  131. package/dist/lib/helpers/i3s-nodepages-tiles.d.ts +1 -0
  132. package/dist/lib/helpers/i3s-nodepages-tiles.d.ts.map +1 -1
  133. package/dist/lib/helpers/i3s-nodepages-tiles.js +231 -228
  134. package/dist/lib/parsers/constants.js +85 -63
  135. package/dist/lib/parsers/parse-arcgis-webscene.d.ts +7 -0
  136. package/dist/lib/parsers/parse-arcgis-webscene.d.ts.map +1 -0
  137. package/dist/lib/parsers/parse-arcgis-webscene.js +88 -0
  138. package/dist/lib/parsers/parse-i3s-attribute.d.ts +6 -4
  139. package/dist/lib/parsers/parse-i3s-attribute.d.ts.map +1 -1
  140. package/dist/lib/parsers/parse-i3s-attribute.js +87 -62
  141. package/dist/lib/parsers/parse-i3s-building-scene-layer.js +41 -40
  142. package/dist/lib/parsers/parse-i3s-tile-content.d.ts +2 -2
  143. package/dist/lib/parsers/parse-i3s-tile-content.d.ts.map +1 -1
  144. package/dist/lib/parsers/parse-i3s-tile-content.js +454 -454
  145. package/dist/lib/parsers/parse-i3s.d.ts +1 -1
  146. package/dist/lib/parsers/parse-i3s.d.ts.map +1 -1
  147. package/dist/lib/parsers/parse-i3s.js +92 -88
  148. package/dist/lib/parsers/parse-slpk/parse-slpk.d.ts +4 -0
  149. package/dist/lib/parsers/parse-slpk/parse-slpk.d.ts.map +1 -0
  150. package/dist/lib/parsers/parse-slpk/parse-slpk.js +50 -0
  151. package/dist/lib/parsers/parse-slpk/slpk-archieve.d.ts +32 -0
  152. package/dist/lib/parsers/parse-slpk/slpk-archieve.d.ts.map +1 -0
  153. package/dist/lib/parsers/parse-slpk/slpk-archieve.js +79 -0
  154. package/dist/lib/parsers/parse-zip/cd-file-header.d.ts +38 -0
  155. package/dist/lib/parsers/parse-zip/cd-file-header.d.ts.map +1 -0
  156. package/dist/lib/parsers/parse-zip/cd-file-header.js +48 -0
  157. package/dist/lib/parsers/parse-zip/local-file-header.d.ts +30 -0
  158. package/dist/lib/parsers/parse-zip/local-file-header.d.ts.map +1 -0
  159. package/dist/lib/parsers/parse-zip/local-file-header.js +28 -0
  160. package/dist/lib/utils/convert-i3s-obb-to-mbs.js +19 -8
  161. package/dist/lib/utils/customizeColors.d.ts +14 -0
  162. package/dist/lib/utils/customizeColors.d.ts.map +1 -0
  163. package/dist/lib/utils/customizeColors.js +94 -0
  164. package/dist/lib/utils/url-utils.js +41 -28
  165. package/dist/types.d.ts +518 -97
  166. package/dist/types.d.ts.map +1 -1
  167. package/dist/types.js +18 -19
  168. package/dist/workers/i3s-content-worker-node.d.ts +2 -0
  169. package/dist/workers/i3s-content-worker-node.d.ts.map +1 -0
  170. package/dist/workers/i3s-content-worker-node.js +7 -0
  171. package/dist/workers/i3s-content-worker.js +5 -4
  172. package/package.json +16 -14
  173. package/src/arcgis-webscene-loader.ts +31 -0
  174. package/src/i3s-attribute-loader.ts +9 -9
  175. package/src/i3s-content-loader.ts +17 -5
  176. package/src/i3s-loader.ts +22 -13
  177. package/src/i3s-node-page-loader.ts +6 -10
  178. package/src/i3s-slpk-loader.ts +25 -0
  179. package/src/index.ts +22 -5
  180. package/src/lib/helpers/i3s-nodepages-tiles.ts +14 -3
  181. package/src/lib/parsers/constants.ts +1 -1
  182. package/src/lib/parsers/parse-arcgis-webscene.ts +102 -0
  183. package/src/lib/parsers/parse-i3s-attribute.ts +21 -14
  184. package/src/lib/parsers/parse-i3s-tile-content.ts +99 -76
  185. package/src/lib/parsers/parse-i3s.ts +8 -3
  186. package/src/lib/parsers/parse-slpk/parse-slpk.ts +61 -0
  187. package/src/lib/parsers/parse-slpk/slpk-archieve.ts +108 -0
  188. package/src/lib/parsers/parse-zip/cd-file-header.ts +93 -0
  189. package/src/lib/parsers/parse-zip/local-file-header.ts +56 -0
  190. package/src/lib/utils/customizeColors.ts +134 -0
  191. package/src/types.ts +482 -33
  192. package/src/workers/i3s-content-worker-node.ts +6 -0
  193. package/dist/bundle.js.map +0 -1
  194. package/dist/i3s-attribute-loader.js.map +0 -1
  195. package/dist/i3s-building-scene-layer-loader.js.map +0 -1
  196. package/dist/i3s-content-loader.js.map +0 -1
  197. package/dist/i3s-loader.js.map +0 -1
  198. package/dist/i3s-node-page-loader.js.map +0 -1
  199. package/dist/index.js.map +0 -1
  200. package/dist/lib/helpers/i3s-nodepages-tiles.js.map +0 -1
  201. package/dist/lib/parsers/constants.js.map +0 -1
  202. package/dist/lib/parsers/parse-i3s-attribute.js.map +0 -1
  203. package/dist/lib/parsers/parse-i3s-building-scene-layer.js.map +0 -1
  204. package/dist/lib/parsers/parse-i3s-tile-content.js.map +0 -1
  205. package/dist/lib/parsers/parse-i3s.js.map +0 -1
  206. package/dist/lib/utils/convert-i3s-obb-to-mbs.js.map +0 -1
  207. package/dist/lib/utils/url-utils.js.map +0 -1
  208. package/dist/types.js.map +0 -1
  209. package/dist/workers/i3s-content-worker.js.map +0 -1
@@ -0,0 +1,108 @@
1
+ import {processOnWorker} from '@loaders.gl/worker-utils';
2
+ import md5 from 'md5';
3
+ import {CompressionWorker} from '@loaders.gl/compression';
4
+ import {parseZipLocalFileHeader} from '../parse-zip/local-file-header';
5
+
6
+ /** Element of hash array */
7
+ type HashElement = {
8
+ /**
9
+ * File name hash
10
+ */
11
+ hash: Buffer;
12
+ /**
13
+ * File offset in the archive
14
+ */
15
+ offset: number;
16
+ };
17
+
18
+ /**
19
+ * Class for handling information about slpk file
20
+ */
21
+ export class SLPKArchive {
22
+ slpkArchive: DataView;
23
+ hashArray: {hash: Buffer; offset: number}[];
24
+ constructor(slpkArchiveBuffer: ArrayBuffer, hashFile: ArrayBuffer) {
25
+ this.slpkArchive = new DataView(slpkArchiveBuffer);
26
+ this.hashArray = this.parseHashFile(hashFile);
27
+ }
28
+
29
+ /**
30
+ * Reads hash file from buffer and returns it in ready-to-use form
31
+ * @param hashFile - bufer containing hash file
32
+ * @returns Array containing file info
33
+ */
34
+ private parseHashFile(hashFile: ArrayBuffer): HashElement[] {
35
+ const hashFileBuffer = Buffer.from(hashFile);
36
+ const hashArray: HashElement[] = [];
37
+ for (let i = 0; i < hashFileBuffer.buffer.byteLength; i = i + 24) {
38
+ const offsetBuffer = new DataView(
39
+ hashFileBuffer.buffer.slice(
40
+ hashFileBuffer.byteOffset + i + 16,
41
+ hashFileBuffer.byteOffset + i + 24
42
+ )
43
+ );
44
+ const offset = offsetBuffer.getUint32(offsetBuffer.byteOffset, true);
45
+ hashArray.push({
46
+ hash: Buffer.from(
47
+ hashFileBuffer.subarray(hashFileBuffer.byteOffset + i, hashFileBuffer.byteOffset + i + 16)
48
+ ),
49
+ offset
50
+ });
51
+ }
52
+ return hashArray;
53
+ }
54
+
55
+ /**
56
+ * Returns file with the given path from slpk archive
57
+ * @param path - path inside the slpk
58
+ * @param mode - currently only raw mode supported
59
+ * @returns buffer with ready to use file
60
+ */
61
+ async getFile(path: string, mode: 'http' | 'raw' = 'raw'): Promise<Buffer> {
62
+ if (mode === 'http') {
63
+ throw new Error('http mode is not supported');
64
+ }
65
+
66
+ const fileToDecompress = this.getFileBytes(`${path}.gz`);
67
+
68
+ if (fileToDecompress) {
69
+ const decompressedData = await processOnWorker(CompressionWorker, fileToDecompress, {
70
+ compression: 'gzip',
71
+ operation: 'decompress',
72
+ _workerType: 'test',
73
+ gzip: {}
74
+ });
75
+ return decompressedData;
76
+ }
77
+ const fileWithoutCompression = this.getFileBytes(path);
78
+ if (fileWithoutCompression) {
79
+ return Promise.resolve(Buffer.from(fileWithoutCompression));
80
+ }
81
+ throw new Error('No such file in the archieve');
82
+ }
83
+
84
+ /**
85
+ * Trying to get raw file data by adress
86
+ * @param path - path inside the archive
87
+ * @returns buffer with the raw file data
88
+ */
89
+ private getFileBytes(path: string): ArrayBuffer | undefined {
90
+ const nameHash = Buffer.from(md5(path), 'hex');
91
+ const fileInfo = this.hashArray.find((val) => Buffer.compare(val.hash, nameHash) === 0);
92
+ if (!fileInfo) {
93
+ return undefined;
94
+ }
95
+
96
+ const localFileHeader = parseZipLocalFileHeader(
97
+ this.slpkArchive.byteOffset + fileInfo?.offset,
98
+ this.slpkArchive
99
+ );
100
+
101
+ const compressedFile = this.slpkArchive.buffer.slice(
102
+ localFileHeader.fileDataOffset,
103
+ localFileHeader.fileDataOffset + localFileHeader.compressedSize
104
+ );
105
+
106
+ return compressedFile;
107
+ }
108
+ }
@@ -0,0 +1,93 @@
1
+ /**
2
+ * zip central directory file header info
3
+ * according to https://en.wikipedia.org/wiki/ZIP_(file_format)
4
+ */
5
+ export type ZipCDFileHeader = {
6
+ /**
7
+ * Compressed size
8
+ */
9
+ compressedSize: number;
10
+ /**
11
+ * Uncompressed size
12
+ */
13
+ uncompressedSize: number;
14
+ /**
15
+ * File name length
16
+ */
17
+ fileNameLength: number;
18
+ /**
19
+ * File name
20
+ */
21
+ fileName: ArrayBuffer;
22
+ /**
23
+ * Extra field offset
24
+ */
25
+ extraOffset: number;
26
+ /**
27
+ * Relative offset of local file header
28
+ */
29
+ localHeaderOffset: number;
30
+ };
31
+
32
+ /**
33
+ * Parses central directory file header of zip file
34
+ * @param headerOffset - offset in the archive where header starts
35
+ * @param buffer - buffer containing whole array
36
+ * @returns Info from the header
37
+ */
38
+ export const parseZipCDFileHeader = (headerOffset: number, buffer: DataView): ZipCDFileHeader => {
39
+ const offsets = {
40
+ CD_COMPRESSED_SIZE_OFFSET: 20,
41
+ CD_UNCOMPRESSED_SIZE_OFFSET: 24,
42
+ CD_FILE_NAME_LENGTH_OFFSET: 28,
43
+ CD_EXTRA_FIELD_LENGTH_OFFSET: 30,
44
+ CD_LOCAL_HEADER_OFFSET_OFFSET: 42,
45
+ CD_FILE_NAME_OFFSET: 46
46
+ };
47
+
48
+ const compressedSize = buffer.getUint32(headerOffset + offsets.CD_COMPRESSED_SIZE_OFFSET, true);
49
+
50
+ const uncompressedSize = buffer.getUint32(
51
+ headerOffset + offsets.CD_UNCOMPRESSED_SIZE_OFFSET,
52
+ true
53
+ );
54
+
55
+ const fileNameLength = buffer.getUint16(headerOffset + offsets.CD_FILE_NAME_LENGTH_OFFSET, true);
56
+
57
+ const fileName = buffer.buffer.slice(
58
+ headerOffset + offsets.CD_FILE_NAME_OFFSET,
59
+ headerOffset + offsets.CD_FILE_NAME_OFFSET + fileNameLength
60
+ );
61
+
62
+ const extraOffset = headerOffset + offsets.CD_FILE_NAME_OFFSET + fileNameLength;
63
+
64
+ const oldFormatOffset = buffer.getUint32(
65
+ headerOffset + offsets.CD_LOCAL_HEADER_OFFSET_OFFSET,
66
+ true
67
+ );
68
+
69
+ let fileDataOffset = oldFormatOffset;
70
+ if (fileDataOffset === 0xffffffff) {
71
+ let offsetInZip64Data = 4;
72
+ // looking for info that might be also be in zip64 extra field
73
+ if (compressedSize === 0xffffffff) {
74
+ offsetInZip64Data += 8;
75
+ }
76
+ if (uncompressedSize === 0xffffffff) {
77
+ offsetInZip64Data += 8;
78
+ }
79
+
80
+ // getUint32 needs to be replaced with getBigUint64 for archieves bigger than 2gb
81
+ fileDataOffset = buffer.getUint32(extraOffset + offsetInZip64Data, true); // setting it to the one from zip64
82
+ }
83
+ const localHeaderOffset = fileDataOffset;
84
+
85
+ return {
86
+ compressedSize,
87
+ uncompressedSize,
88
+ fileNameLength,
89
+ fileName,
90
+ extraOffset,
91
+ localHeaderOffset
92
+ };
93
+ };
@@ -0,0 +1,56 @@
1
+ /**
2
+ * zip local file header info
3
+ * according to https://en.wikipedia.org/wiki/ZIP_(file_format)
4
+ */
5
+ export type ZipLocalFileHeader = {
6
+ /**
7
+ * File name length
8
+ */
9
+ fileNameLength: number;
10
+ /**
11
+ * Extra field length
12
+ */
13
+ extraFieldLength: number;
14
+ /**
15
+ * Offset of the file data
16
+ */
17
+ fileDataOffset: number;
18
+ /**
19
+ * Compressed size
20
+ */
21
+ compressedSize: number;
22
+ };
23
+
24
+ /**
25
+ * Parses local file header of zip file
26
+ * @param headerOffset - offset in the archive where header starts
27
+ * @param buffer - buffer containing whole array
28
+ * @returns Info from the header
29
+ */
30
+ export const parseZipLocalFileHeader = (
31
+ headerOffset: number,
32
+ buffer: DataView
33
+ ): ZipLocalFileHeader => {
34
+ const offsets = {
35
+ COMPRESSED_SIZE_OFFSET: 18,
36
+ FILE_NAME_LENGTH_OFFSET: 26,
37
+ EXTRA_FIELD_LENGTH_OFFSET: 28,
38
+ FILE_NAME_OFFSET: 30
39
+ };
40
+
41
+ const fileNameLength = buffer.getUint16(headerOffset + offsets.FILE_NAME_LENGTH_OFFSET, true);
42
+
43
+ const extraFieldLength = buffer.getUint16(headerOffset + offsets.EXTRA_FIELD_LENGTH_OFFSET, true);
44
+
45
+ const fileDataOffset =
46
+ headerOffset + offsets.FILE_NAME_OFFSET + fileNameLength + extraFieldLength;
47
+
48
+ const compressedSize = buffer.getUint32(headerOffset + offsets.COMPRESSED_SIZE_OFFSET, true);
49
+
50
+ return {
51
+ fileNameLength,
52
+ extraFieldLength,
53
+ fileDataOffset,
54
+ compressedSize
55
+ };
56
+ };
@@ -0,0 +1,134 @@
1
+ import type {MeshAttribute} from '@loaders.gl/schema';
2
+ import type {COLOR, I3STileOptions, I3STilesetOptions} from '../../types';
3
+
4
+ import {load} from '@loaders.gl/core';
5
+ import {getAttributeValueType, I3SAttributeLoader} from '../../i3s-attribute-loader';
6
+ import {I3SLoaderOptions} from '../../i3s-loader';
7
+ import {getUrlWithToken} from '../utils/url-utils';
8
+
9
+ /**
10
+ * Modify vertex colors array to visualize 3D objects in a attribute driven way
11
+ * @param colors - vertex colors attribute
12
+ * @param featureIds - feature Ids attribute
13
+ * @param tileOptions - tile - related options
14
+ * @param tilesetOptions - tileset-related options
15
+ * @param options - loader options
16
+ * @returns midified colors attribute
17
+ */
18
+ export async function customizeColors(
19
+ colors: MeshAttribute,
20
+ featureIds: MeshAttribute,
21
+ tileOptions: I3STileOptions,
22
+ tilesetOptions: I3STilesetOptions,
23
+ options?: I3SLoaderOptions
24
+ ): Promise<MeshAttribute> {
25
+ if (!options?.i3s?.colorsByAttribute) {
26
+ return colors;
27
+ }
28
+
29
+ const colorizeAttributeField = tilesetOptions.fields.find(
30
+ ({name}) => name === options?.i3s?.colorsByAttribute?.attributeName
31
+ );
32
+ if (
33
+ !colorizeAttributeField ||
34
+ !['esriFieldTypeDouble', 'esriFieldTypeInteger', 'esriFieldTypeSmallInteger'].includes(
35
+ colorizeAttributeField.type
36
+ )
37
+ ) {
38
+ return colors;
39
+ }
40
+
41
+ const colorizeAttributeData = await loadFeatureAttributeData(
42
+ colorizeAttributeField.name,
43
+ tileOptions,
44
+ tilesetOptions,
45
+ options
46
+ );
47
+ if (!colorizeAttributeData) {
48
+ return colors;
49
+ }
50
+
51
+ const objectIdField = tilesetOptions.fields.find(({type}) => type === 'esriFieldTypeOID');
52
+ if (!objectIdField) {
53
+ return colors;
54
+ }
55
+
56
+ const objectIdAttributeData = await loadFeatureAttributeData(
57
+ objectIdField.name,
58
+ tileOptions,
59
+ tilesetOptions,
60
+ options
61
+ );
62
+ if (!objectIdAttributeData) {
63
+ return colors;
64
+ }
65
+
66
+ const attributeValuesMap: {[key: number]: COLOR} = {};
67
+ // @ts-expect-error
68
+ for (let i = 0; i < objectIdAttributeData[objectIdField.name].length; i++) {
69
+ // @ts-expect-error
70
+ attributeValuesMap[objectIdAttributeData[objectIdField.name][i]] = calculateColorForAttribute(
71
+ // @ts-expect-error
72
+ colorizeAttributeData[colorizeAttributeField.name][i] as number,
73
+ options
74
+ );
75
+ }
76
+
77
+ for (let i = 0; i < featureIds.value.length; i++) {
78
+ const color = attributeValuesMap[featureIds.value[i]];
79
+ if (!color) {
80
+ continue; // eslint-disable-line no-continue
81
+ }
82
+ colors.value.set(color, i * 4);
83
+ }
84
+
85
+ return colors;
86
+ }
87
+
88
+ /**
89
+ * Calculate rgba color from the attribute value
90
+ * @param attributeValue - value of the attribute
91
+ * @param options - loader options
92
+ * @returns - color array for a specific attribute value
93
+ */
94
+ function calculateColorForAttribute(attributeValue: number, options?: I3SLoaderOptions): COLOR {
95
+ if (!options?.i3s?.colorsByAttribute) {
96
+ return [255, 255, 255, 255];
97
+ }
98
+ const {minValue, maxValue, minColor, maxColor} = options.i3s.colorsByAttribute;
99
+ const rate = (attributeValue - minValue) / (maxValue - minValue);
100
+ const color: COLOR = [255, 255, 255, 255];
101
+ for (let i = 0; i < minColor.length; i++) {
102
+ color[i] = Math.round((maxColor[i] - minColor[i]) * rate + minColor[i]);
103
+ }
104
+ return color;
105
+ }
106
+
107
+ /**
108
+ * Load feature attribute data from the ArcGIS rest service
109
+ * @param attributeName - attribute name
110
+ * @param tileOptions - tile-related options
111
+ * @param tilesetOptions - tileset-related options
112
+ * @param options - loader options
113
+ * @returns - Array-like list of the attribute values
114
+ */
115
+ async function loadFeatureAttributeData(
116
+ attributeName: string,
117
+ {attributeUrls}: I3STileOptions,
118
+ {attributeStorageInfo}: I3STilesetOptions,
119
+ options?: I3SLoaderOptions
120
+ ): Promise<{[key: string]: string[] | Uint32Array | Uint16Array | Float64Array | null} | null> {
121
+ const attributeIndex = attributeStorageInfo.findIndex(({name}) => attributeName === name);
122
+ if (attributeIndex === -1) {
123
+ return null;
124
+ }
125
+ const objectIdAttributeUrl = getUrlWithToken(attributeUrls[attributeIndex], options?.i3s?.token);
126
+ const attributeType = getAttributeValueType(attributeStorageInfo[attributeIndex]);
127
+ const objectIdAttributeData = await load(objectIdAttributeUrl, I3SAttributeLoader, {
128
+ attributeName,
129
+ attributeType
130
+ });
131
+
132
+ // @ts-expect-error TODO action engine
133
+ return objectIdAttributeData;
134
+ }