@maplibre/mlt 1.1.1 → 1.1.4

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 (122) hide show
  1. package/dist/decoding/decodingTestUtils.d.ts +75 -0
  2. package/dist/decoding/decodingTestUtils.js +285 -0
  3. package/dist/decoding/decodingTestUtils.js.map +1 -0
  4. package/dist/decoding/decodingUtils.d.ts +5 -8
  5. package/dist/decoding/decodingUtils.js +24 -51
  6. package/dist/decoding/decodingUtils.js.map +1 -1
  7. package/dist/decoding/decodingUtils.spec.js +85 -69
  8. package/dist/decoding/decodingUtils.spec.js.map +1 -1
  9. package/dist/decoding/fsstDecoder.spec.js +52 -35
  10. package/dist/decoding/fsstDecoder.spec.js.map +1 -1
  11. package/dist/decoding/geometryDecoder.js +49 -38
  12. package/dist/decoding/geometryDecoder.js.map +1 -1
  13. package/dist/decoding/integerDecodingUtils.d.ts +18 -31
  14. package/dist/decoding/integerDecodingUtils.js +134 -299
  15. package/dist/decoding/integerDecodingUtils.js.map +1 -1
  16. package/dist/decoding/integerDecodingUtils.spec.js +254 -148
  17. package/dist/decoding/integerDecodingUtils.spec.js.map +1 -1
  18. package/dist/decoding/integerStreamDecoder.d.ts +5 -7
  19. package/dist/decoding/integerStreamDecoder.js +104 -122
  20. package/dist/decoding/integerStreamDecoder.js.map +1 -1
  21. package/dist/decoding/integerStreamDecoder.spec.js +370 -113
  22. package/dist/decoding/integerStreamDecoder.spec.js.map +1 -1
  23. package/dist/decoding/propertyDecoder.js +23 -33
  24. package/dist/decoding/propertyDecoder.js.map +1 -1
  25. package/dist/decoding/propertyDecoder.spec.js +397 -605
  26. package/dist/decoding/propertyDecoder.spec.js.map +1 -1
  27. package/dist/decoding/stringDecoder.d.ts +2 -10
  28. package/dist/decoding/stringDecoder.js +146 -158
  29. package/dist/decoding/stringDecoder.js.map +1 -1
  30. package/dist/decoding/stringDecoder.spec.js +322 -321
  31. package/dist/decoding/stringDecoder.spec.js.map +1 -1
  32. package/dist/decoding/unpackNullableUtils.d.ts +25 -0
  33. package/dist/decoding/unpackNullableUtils.js +51 -0
  34. package/dist/decoding/unpackNullableUtils.js.map +1 -0
  35. package/dist/decoding/unpackNullableUtils.spec.js +71 -0
  36. package/dist/decoding/unpackNullableUtils.spec.js.map +1 -0
  37. package/dist/encoding/embeddedTilesetMetadataEncoder.d.ts +16 -0
  38. package/dist/encoding/embeddedTilesetMetadataEncoder.js +40 -0
  39. package/dist/encoding/embeddedTilesetMetadataEncoder.js.map +1 -0
  40. package/dist/encoding/encodingUtils.d.ts +7 -0
  41. package/dist/encoding/encodingUtils.js +107 -0
  42. package/dist/encoding/encodingUtils.js.map +1 -0
  43. package/dist/encoding/fsstEncoder.d.ts +21 -0
  44. package/dist/encoding/fsstEncoder.js +78 -0
  45. package/dist/encoding/fsstEncoder.js.map +1 -0
  46. package/dist/encoding/integerEncodingUtils.d.ts +68 -0
  47. package/dist/encoding/integerEncodingUtils.js +655 -0
  48. package/dist/encoding/integerEncodingUtils.js.map +1 -0
  49. package/dist/encoding/integerStreamEncoder.d.ts +27 -0
  50. package/dist/encoding/integerStreamEncoder.js +139 -0
  51. package/dist/encoding/integerStreamEncoder.js.map +1 -0
  52. package/dist/encoding/packNullableUtils.d.ts +4 -0
  53. package/dist/encoding/packNullableUtils.js +55 -0
  54. package/dist/encoding/packNullableUtils.js.map +1 -0
  55. package/dist/encoding/propertyEncoder.d.ts +78 -0
  56. package/dist/encoding/propertyEncoder.js +335 -0
  57. package/dist/encoding/propertyEncoder.js.map +1 -0
  58. package/dist/encoding/stringEncoder.d.ts +12 -0
  59. package/dist/encoding/stringEncoder.js +182 -0
  60. package/dist/encoding/stringEncoder.js.map +1 -0
  61. package/dist/encoding/zOrderCurveEncoder.d.ts +1 -0
  62. package/dist/encoding/zOrderCurveEncoder.js +10 -0
  63. package/dist/encoding/zOrderCurveEncoder.js.map +1 -0
  64. package/dist/metadata/tile/streamMetadataDecoder.d.ts +28 -4
  65. package/dist/metadata/tile/streamMetadataDecoder.js +81 -15
  66. package/dist/metadata/tile/streamMetadataDecoder.js.map +1 -1
  67. package/dist/metadata/tileset/embeddedTilesetMetadataDecoder.d.ts +5 -1
  68. package/dist/metadata/tileset/embeddedTilesetMetadataDecoder.js +33 -45
  69. package/dist/metadata/tileset/embeddedTilesetMetadataDecoder.js.map +1 -1
  70. package/dist/metadata/tileset/embeddedTilesetMetadataDecoder.spec.d.ts +1 -0
  71. package/dist/metadata/tileset/embeddedTilesetMetadataDecoder.spec.js +142 -0
  72. package/dist/metadata/tileset/embeddedTilesetMetadataDecoder.spec.js.map +1 -0
  73. package/dist/metadata/tileset/typeMap.d.ts +21 -29
  74. package/dist/metadata/tileset/typeMap.js +167 -169
  75. package/dist/metadata/tileset/typeMap.js.map +1 -1
  76. package/dist/mltDecoder.js +12 -11
  77. package/dist/mltDecoder.js.map +1 -1
  78. package/dist/vector/dictionary/stringDictionaryVector.d.ts +1 -1
  79. package/dist/vector/dictionary/stringDictionaryVector.js.map +1 -1
  80. package/dist/vector/flat/stringFlatVector.d.ts +1 -1
  81. package/dist/vector/flat/stringFlatVector.js.map +1 -1
  82. package/dist/vector/fsst-dictionary/stringFsstDictionaryVector.d.ts +1 -1
  83. package/dist/vector/fsst-dictionary/stringFsstDictionaryVector.js.map +1 -1
  84. package/dist/vector/fsst-dictionary/stringFsstDictionaryVector.spec.js +2 -2
  85. package/dist/vector/fsst-dictionary/stringFsstDictionaryVector.spec.js.map +1 -1
  86. package/dist/vector/geometry/constGpuVector.d.ts +2 -2
  87. package/dist/vector/geometry/constGpuVector.js.map +1 -1
  88. package/dist/vector/geometry/flatGpuVector.d.ts +2 -2
  89. package/dist/vector/geometry/flatGpuVector.js.map +1 -1
  90. package/dist/vector/geometry/geometryVector.js +2 -2
  91. package/dist/vector/geometry/geometryVector.js.map +1 -1
  92. package/dist/vector/geometry/geometryVectorConverter.js +4 -4
  93. package/dist/vector/geometry/geometryVectorConverter.js.map +1 -1
  94. package/dist/vector/geometry/gpuVector.d.ts +2 -2
  95. package/dist/vector/geometry/gpuVector.js.map +1 -1
  96. package/dist/vector/geometry/topologyVector.d.ts +4 -4
  97. package/dist/vector/geometry/topologyVector.js +0 -1
  98. package/dist/vector/geometry/topologyVector.js.map +1 -1
  99. package/dist/vector/geometry/zOrderCurve.d.ts +4 -17
  100. package/dist/vector/geometry/zOrderCurve.js +10 -35
  101. package/dist/vector/geometry/zOrderCurve.js.map +1 -1
  102. package/dist/vector/geometry/zOrderCurve.spec.js +21 -10
  103. package/dist/vector/geometry/zOrderCurve.spec.js.map +1 -1
  104. package/dist/vector/variableSizeVector.d.ts +2 -2
  105. package/dist/vector/variableSizeVector.js +0 -1
  106. package/dist/vector/variableSizeVector.js.map +1 -1
  107. package/package.json +6 -8
  108. package/dist/decoding/geometryDecoder.spec.js +0 -5
  109. package/dist/decoding/geometryDecoder.spec.js.map +0 -1
  110. package/dist/metadata/tile/mortonEncodedStreamMetadata.d.ts +0 -15
  111. package/dist/metadata/tile/mortonEncodedStreamMetadata.js +0 -27
  112. package/dist/metadata/tile/mortonEncodedStreamMetadata.js.map +0 -1
  113. package/dist/metadata/tile/rleEncodedStreamMetadata.d.ts +0 -24
  114. package/dist/metadata/tile/rleEncodedStreamMetadata.js +0 -38
  115. package/dist/metadata/tile/rleEncodedStreamMetadata.js.map +0 -1
  116. package/dist/metadata/tile/streamMetadata.d.ts +0 -29
  117. package/dist/metadata/tile/streamMetadata.js +0 -82
  118. package/dist/metadata/tile/streamMetadata.js.map +0 -1
  119. package/dist/vector/geometry/spaceFillingCurve.d.ts +0 -22
  120. package/dist/vector/geometry/spaceFillingCurve.js +0 -31
  121. package/dist/vector/geometry/spaceFillingCurve.js.map +0 -1
  122. /package/dist/decoding/{geometryDecoder.spec.d.ts → unpackNullableUtils.spec.d.ts} +0 -0
@@ -0,0 +1,10 @@
1
+ export function encodeZOrderCurve(x, y, numBits, coordinateShift) {
2
+ const shiftedX = x + coordinateShift;
3
+ const shiftedY = y + coordinateShift;
4
+ let code = 0;
5
+ for (let i = 0; i < numBits; i++) {
6
+ code |= (shiftedX & (1 << i)) << i | (shiftedY & (1 << i)) << (i + 1);
7
+ }
8
+ return code;
9
+ }
10
+ //# sourceMappingURL=zOrderCurveEncoder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zOrderCurveEncoder.js","sourceRoot":"","sources":["../../src/encoding/zOrderCurveEncoder.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,iBAAiB,CAC7B,CAAS,EACT,CAAS,EACT,OAAe,EACf,eAAuB;IAEvB,MAAM,QAAQ,GAAG,CAAC,GAAG,eAAe,CAAC;IACrC,MAAM,QAAQ,GAAG,CAAC,GAAG,eAAe,CAAC;IACrC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9B,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,IAAI,CAAA;AACf,CAAC","sourcesContent":["export function encodeZOrderCurve(\n x: number,\n y: number,\n numBits: number,\n coordinateShift: number,\n): number {\n const shiftedX = x + coordinateShift;\n const shiftedY = y + coordinateShift;\n let code = 0;\n for(let i = 0; i < numBits; i++) {\n code |= (shiftedX & (1 << i)) << i | (shiftedY & (1 << i)) << (i + 1);\n }\n return code\n}\n"]}
@@ -1,5 +1,29 @@
1
- import { StreamMetadata } from "./streamMetadata";
1
+ import { LogicalLevelTechnique } from "./logicalLevelTechnique";
2
+ import { PhysicalLevelTechnique } from "./physicalLevelTechnique";
3
+ import { PhysicalStreamType } from "./physicalStreamType";
4
+ import { LogicalStreamType } from "./logicalStreamType";
2
5
  import type IntWrapper from "../../decoding/intWrapper";
3
- export declare class StreamMetadataDecoder {
4
- static decode(tile: Uint8Array, offset: IntWrapper): StreamMetadata;
5
- }
6
+ export type StreamMetadata = {
7
+ readonly physicalStreamType: PhysicalStreamType;
8
+ readonly logicalStreamType: LogicalStreamType;
9
+ readonly logicalLevelTechnique1: LogicalLevelTechnique;
10
+ readonly logicalLevelTechnique2: LogicalLevelTechnique;
11
+ readonly physicalLevelTechnique: PhysicalLevelTechnique;
12
+ readonly numValues: number;
13
+ readonly byteLength: number;
14
+ /**
15
+ * Returns the number of decompressed values.
16
+ * For non-RLE streams, this is the same as numValues.
17
+ * For RLE streams, this is overridden to return numRleValues.
18
+ */
19
+ readonly decompressedCount: number;
20
+ };
21
+ export type MortonEncodedStreamMetadata = StreamMetadata & {
22
+ readonly numBits: number;
23
+ readonly coordinateShift: number;
24
+ };
25
+ export type RleEncodedStreamMetadata = StreamMetadata & {
26
+ readonly runs: number;
27
+ readonly numRleValues: number;
28
+ };
29
+ export declare function decodeStreamMetadata(tile: Uint8Array, offset: IntWrapper): StreamMetadata;
@@ -1,20 +1,86 @@
1
- import { StreamMetadata } from "./streamMetadata";
2
1
  import { LogicalLevelTechnique } from "./logicalLevelTechnique";
3
2
  import { PhysicalLevelTechnique } from "./physicalLevelTechnique";
4
- import { MortonEncodedStreamMetadata } from "./mortonEncodedStreamMetadata";
5
- import { RleEncodedStreamMetadata } from "./rleEncodedStreamMetadata";
6
- export class StreamMetadataDecoder {
7
- static decode(tile, offset) {
8
- const streamMetadata = StreamMetadata.decode(tile, offset);
9
- if (streamMetadata.logicalLevelTechnique1 === LogicalLevelTechnique.MORTON) {
10
- return MortonEncodedStreamMetadata.decodePartial(streamMetadata, tile, offset);
11
- }
12
- if ((LogicalLevelTechnique.RLE === streamMetadata.logicalLevelTechnique1 ||
13
- LogicalLevelTechnique.RLE === streamMetadata.logicalLevelTechnique2) &&
14
- PhysicalLevelTechnique.NONE !== streamMetadata.physicalLevelTechnique) {
15
- return RleEncodedStreamMetadata.decodePartial(streamMetadata, tile, offset);
16
- }
17
- return streamMetadata;
3
+ import { decodeVarintInt32 } from "../../decoding/integerDecodingUtils";
4
+ import { PhysicalStreamType } from "./physicalStreamType";
5
+ import { LogicalStreamType } from "./logicalStreamType";
6
+ import { DictionaryType } from "./dictionaryType";
7
+ import { OffsetType } from "./offsetType";
8
+ import { LengthType } from "./lengthType";
9
+ export function decodeStreamMetadata(tile, offset) {
10
+ const streamMetadata = decodeStreamMetadataInternal(tile, offset);
11
+ if (streamMetadata.logicalLevelTechnique1 === LogicalLevelTechnique.MORTON) {
12
+ return decodePartialMortonEncodedStreamMetadata(streamMetadata, tile, offset);
18
13
  }
14
+ if ((LogicalLevelTechnique.RLE === streamMetadata.logicalLevelTechnique1 ||
15
+ LogicalLevelTechnique.RLE === streamMetadata.logicalLevelTechnique2) &&
16
+ PhysicalLevelTechnique.NONE !== streamMetadata.physicalLevelTechnique) {
17
+ return decodePartialRleEncodedStreamMetadata(streamMetadata, tile, offset);
18
+ }
19
+ return streamMetadata;
20
+ }
21
+ function decodePartialMortonEncodedStreamMetadata(streamMetadata, tile, offset) {
22
+ const mortonInfo = decodeVarintInt32(tile, offset, 2);
23
+ return {
24
+ physicalStreamType: streamMetadata.physicalStreamType,
25
+ logicalStreamType: streamMetadata.logicalStreamType,
26
+ logicalLevelTechnique1: streamMetadata.logicalLevelTechnique1,
27
+ logicalLevelTechnique2: streamMetadata.logicalLevelTechnique2,
28
+ physicalLevelTechnique: streamMetadata.physicalLevelTechnique,
29
+ numValues: streamMetadata.numValues,
30
+ byteLength: streamMetadata.byteLength,
31
+ decompressedCount: streamMetadata.decompressedCount,
32
+ numBits: mortonInfo[0],
33
+ coordinateShift: mortonInfo[1],
34
+ };
35
+ }
36
+ function decodePartialRleEncodedStreamMetadata(streamMetadata, tile, offset) {
37
+ const rleInfo = decodeVarintInt32(tile, offset, 2);
38
+ return {
39
+ physicalStreamType: streamMetadata.physicalStreamType,
40
+ logicalStreamType: streamMetadata.logicalStreamType,
41
+ logicalLevelTechnique1: streamMetadata.logicalLevelTechnique1,
42
+ logicalLevelTechnique2: streamMetadata.logicalLevelTechnique2,
43
+ physicalLevelTechnique: streamMetadata.physicalLevelTechnique,
44
+ numValues: streamMetadata.numValues,
45
+ byteLength: streamMetadata.byteLength,
46
+ decompressedCount: rleInfo[1],
47
+ runs: rleInfo[0],
48
+ numRleValues: rleInfo[1],
49
+ };
50
+ }
51
+ function decodeStreamMetadataInternal(tile, offset) {
52
+ const stream_type = tile[offset.get()];
53
+ const physicalStreamType = Object.values(PhysicalStreamType)[stream_type >> 4];
54
+ let logicalStreamType = null;
55
+ switch (physicalStreamType) {
56
+ case PhysicalStreamType.DATA:
57
+ logicalStreamType = new LogicalStreamType(Object.values(DictionaryType)[stream_type & 0xf]);
58
+ break;
59
+ case PhysicalStreamType.OFFSET:
60
+ logicalStreamType = new LogicalStreamType(null, Object.values(OffsetType)[stream_type & 0xf]);
61
+ break;
62
+ case PhysicalStreamType.LENGTH:
63
+ logicalStreamType = new LogicalStreamType(null, null, Object.values(LengthType)[stream_type & 0xf]);
64
+ break;
65
+ }
66
+ offset.increment();
67
+ const encodings_header = tile[offset.get()];
68
+ const llt1 = Object.values(LogicalLevelTechnique)[encodings_header >> 5];
69
+ const llt2 = Object.values(LogicalLevelTechnique)[(encodings_header >> 2) & 0x7];
70
+ const plt = Object.values(PhysicalLevelTechnique)[encodings_header & 0x3];
71
+ offset.increment();
72
+ const sizeInfo = decodeVarintInt32(tile, offset, 2);
73
+ const numValues = sizeInfo[0];
74
+ const byteLength = sizeInfo[1];
75
+ return {
76
+ physicalStreamType,
77
+ logicalStreamType,
78
+ logicalLevelTechnique1: llt1,
79
+ logicalLevelTechnique2: llt2,
80
+ physicalLevelTechnique: plt,
81
+ numValues,
82
+ byteLength,
83
+ decompressedCount: numValues,
84
+ };
19
85
  }
20
86
  //# sourceMappingURL=streamMetadataDecoder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"streamMetadataDecoder.js","sourceRoot":"","sources":["../../../src/metadata/tile/streamMetadataDecoder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAGtE,MAAM,OAAO,qBAAqB;IACvB,MAAM,CAAC,MAAM,CAAC,IAAgB,EAAE,MAAkB;QACrD,MAAM,cAAc,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC3D,IAAI,cAAc,CAAC,sBAAsB,KAAK,qBAAqB,CAAC,MAAM,EAAE,CAAC;YACzE,OAAO,2BAA2B,CAAC,aAAa,CAAC,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACnF,CAAC;QAED,IACI,CAAC,qBAAqB,CAAC,GAAG,KAAK,cAAc,CAAC,sBAAsB;YAChE,qBAAqB,CAAC,GAAG,KAAK,cAAc,CAAC,sBAAsB,CAAC;YACxE,sBAAsB,CAAC,IAAI,KAAK,cAAc,CAAC,sBAAsB,EACvE,CAAC;YACC,OAAO,wBAAwB,CAAC,aAAa,CAAC,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAChF,CAAC;QAED,OAAO,cAAc,CAAC;IAC1B,CAAC;CACJ","sourcesContent":["import { StreamMetadata } from \"./streamMetadata\";\nimport { LogicalLevelTechnique } from \"./logicalLevelTechnique\";\nimport { PhysicalLevelTechnique } from \"./physicalLevelTechnique\";\nimport { MortonEncodedStreamMetadata } from \"./mortonEncodedStreamMetadata\";\nimport { RleEncodedStreamMetadata } from \"./rleEncodedStreamMetadata\";\nimport type IntWrapper from \"../../decoding/intWrapper\";\n\nexport class StreamMetadataDecoder {\n public static decode(tile: Uint8Array, offset: IntWrapper): StreamMetadata {\n const streamMetadata = StreamMetadata.decode(tile, offset);\n if (streamMetadata.logicalLevelTechnique1 === LogicalLevelTechnique.MORTON) {\n return MortonEncodedStreamMetadata.decodePartial(streamMetadata, tile, offset);\n }\n\n if (\n (LogicalLevelTechnique.RLE === streamMetadata.logicalLevelTechnique1 ||\n LogicalLevelTechnique.RLE === streamMetadata.logicalLevelTechnique2) &&\n PhysicalLevelTechnique.NONE !== streamMetadata.physicalLevelTechnique\n ) {\n return RleEncodedStreamMetadata.decodePartial(streamMetadata, tile, offset);\n }\n\n return streamMetadata;\n }\n}\n"]}
1
+ {"version":3,"file":"streamMetadataDecoder.js","sourceRoot":"","sources":["../../../src/metadata/tile/streamMetadataDecoder.ts"],"names":[],"mappings":"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","sourcesContent":["import { LogicalLevelTechnique } from \"./logicalLevelTechnique\";\nimport { PhysicalLevelTechnique } from \"./physicalLevelTechnique\";\nimport { decodeVarintInt32 } from \"../../decoding/integerDecodingUtils\";\nimport { PhysicalStreamType } from \"./physicalStreamType\";\nimport { LogicalStreamType } from \"./logicalStreamType\";\nimport { DictionaryType } from \"./dictionaryType\";\nimport { OffsetType } from \"./offsetType\";\nimport { LengthType } from \"./lengthType\";\nimport type IntWrapper from \"../../decoding/intWrapper\";\n\nexport type StreamMetadata = {\n readonly physicalStreamType: PhysicalStreamType;\n readonly logicalStreamType: LogicalStreamType;\n readonly logicalLevelTechnique1: LogicalLevelTechnique;\n readonly logicalLevelTechnique2: LogicalLevelTechnique;\n readonly physicalLevelTechnique: PhysicalLevelTechnique;\n readonly numValues: number;\n readonly byteLength: number;\n /**\n * Returns the number of decompressed values.\n * For non-RLE streams, this is the same as numValues.\n * For RLE streams, this is overridden to return numRleValues.\n */\n readonly decompressedCount: number;\n};\n\nexport type MortonEncodedStreamMetadata = StreamMetadata & {\n readonly numBits: number;\n readonly coordinateShift: number;\n};\n\nexport type RleEncodedStreamMetadata = StreamMetadata & {\n readonly runs: number;\n readonly numRleValues: number;\n};\n\nexport function decodeStreamMetadata(tile: Uint8Array, offset: IntWrapper): StreamMetadata {\n const streamMetadata = decodeStreamMetadataInternal(tile, offset);\n if (streamMetadata.logicalLevelTechnique1 === LogicalLevelTechnique.MORTON) {\n return decodePartialMortonEncodedStreamMetadata(streamMetadata, tile, offset);\n }\n\n if (\n (LogicalLevelTechnique.RLE === streamMetadata.logicalLevelTechnique1 ||\n LogicalLevelTechnique.RLE === streamMetadata.logicalLevelTechnique2) &&\n PhysicalLevelTechnique.NONE !== streamMetadata.physicalLevelTechnique\n ) {\n return decodePartialRleEncodedStreamMetadata(streamMetadata, tile, offset);\n }\n\n return streamMetadata;\n}\n\nfunction decodePartialMortonEncodedStreamMetadata(\n streamMetadata: StreamMetadata,\n tile: Uint8Array,\n offset: IntWrapper,\n): MortonEncodedStreamMetadata {\n const mortonInfo = decodeVarintInt32(tile, offset, 2);\n return {\n physicalStreamType: streamMetadata.physicalStreamType,\n logicalStreamType: streamMetadata.logicalStreamType,\n logicalLevelTechnique1: streamMetadata.logicalLevelTechnique1,\n logicalLevelTechnique2: streamMetadata.logicalLevelTechnique2,\n physicalLevelTechnique: streamMetadata.physicalLevelTechnique,\n numValues: streamMetadata.numValues,\n byteLength: streamMetadata.byteLength,\n decompressedCount: streamMetadata.decompressedCount,\n numBits: mortonInfo[0],\n coordinateShift: mortonInfo[1],\n };\n}\n\nfunction decodePartialRleEncodedStreamMetadata(\n streamMetadata: StreamMetadata,\n tile: Uint8Array,\n offset: IntWrapper,\n): RleEncodedStreamMetadata {\n const rleInfo = decodeVarintInt32(tile, offset, 2);\n return {\n physicalStreamType: streamMetadata.physicalStreamType,\n logicalStreamType: streamMetadata.logicalStreamType,\n logicalLevelTechnique1: streamMetadata.logicalLevelTechnique1,\n logicalLevelTechnique2: streamMetadata.logicalLevelTechnique2,\n physicalLevelTechnique: streamMetadata.physicalLevelTechnique,\n numValues: streamMetadata.numValues,\n byteLength: streamMetadata.byteLength,\n decompressedCount: rleInfo[1],\n runs: rleInfo[0],\n numRleValues: rleInfo[1],\n };\n}\n\nfunction decodeStreamMetadataInternal(tile: Uint8Array, offset: IntWrapper): StreamMetadata {\n const stream_type = tile[offset.get()];\n const physicalStreamType = Object.values(PhysicalStreamType)[stream_type >> 4] as PhysicalStreamType;\n let logicalStreamType: LogicalStreamType | null = null;\n\n switch (physicalStreamType) {\n case PhysicalStreamType.DATA:\n logicalStreamType = new LogicalStreamType(\n Object.values(DictionaryType)[stream_type & 0xf] as DictionaryType,\n );\n break;\n case PhysicalStreamType.OFFSET:\n logicalStreamType = new LogicalStreamType(null, Object.values(OffsetType)[stream_type & 0xf] as OffsetType);\n break;\n case PhysicalStreamType.LENGTH:\n logicalStreamType = new LogicalStreamType(\n null,\n null,\n Object.values(LengthType)[stream_type & 0xf] as LengthType,\n );\n break;\n }\n offset.increment();\n\n const encodings_header = tile[offset.get()];\n const llt1 = Object.values(LogicalLevelTechnique)[encodings_header >> 5] as LogicalLevelTechnique;\n const llt2 = Object.values(LogicalLevelTechnique)[(encodings_header >> 2) & 0x7] as LogicalLevelTechnique;\n const plt = Object.values(PhysicalLevelTechnique)[encodings_header & 0x3] as PhysicalLevelTechnique;\n offset.increment();\n\n const sizeInfo = decodeVarintInt32(tile, offset, 2);\n const numValues = sizeInfo[0];\n const byteLength = sizeInfo[1];\n\n return {\n physicalStreamType,\n logicalStreamType,\n logicalLevelTechnique1: llt1,\n logicalLevelTechnique2: llt2,\n physicalLevelTechnique: plt,\n numValues,\n byteLength,\n decompressedCount: numValues,\n };\n}\n"]}
@@ -1,5 +1,9 @@
1
1
  import type IntWrapper from "../../decoding/intWrapper";
2
- import { type TileSetMetadata } from "./tilesetMetadata";
2
+ import { type Field, type TileSetMetadata } from "./tilesetMetadata";
3
+ /**
4
+ * Decodes a Field used as part of complex types (STRUCT children).
5
+ */
6
+ export declare function decodeField(src: Uint8Array, offset: IntWrapper): Field;
3
7
  /**
4
8
  * Top-level decoder for embedded tileset metadata.
5
9
  * Reads exactly ONE FeatureTableSchema from the stream.
@@ -1,6 +1,8 @@
1
1
  import { decodeVarintInt32 } from "../../decoding/integerDecodingUtils";
2
- import { TypeMap } from "./typeMap";
2
+ import { columnTypeHasChildren, columnTypeHasName, decodeColumnType } from "./typeMap";
3
3
  const textDecoder = new TextDecoder();
4
+ const SUPPORTED_COLUMN_TYPES = "0-3(ID), 4(GEOMETRY), 10-29(scalars), 30(STRUCT)";
5
+ const SUPPORTED_FIELD_TYPES = "10-29(scalars), 30(STRUCT)";
4
6
  /**
5
7
  * Decodes a length-prefixed UTF-8 string.
6
8
  * Layout: [len: varint32][bytes: len]
@@ -16,64 +18,50 @@ function decodeString(src, offset) {
16
18
  offset.add(length);
17
19
  return textDecoder.decode(view);
18
20
  }
21
+ /**
22
+ * Converts a Column to a Field.
23
+ * Used when decoding Field metadata which has the same format as Column.
24
+ */
25
+ function columnToField(column) {
26
+ return {
27
+ name: column.name,
28
+ nullable: column.nullable,
29
+ scalarField: column.scalarType,
30
+ complexField: column.complexType,
31
+ type: column.type === "scalarType" ? "scalarField" : "complexField",
32
+ };
33
+ }
19
34
  /**
20
35
  * Decodes a Field used as part of complex types (STRUCT children).
21
- * Unlike Column, Field still uses the fieldOptions bitfield for flexibility.
22
36
  */
23
- function decodeField(src, offset) {
24
- const fieldOptions = decodeVarintInt32(src, offset, 1)[0] >>> 0;
25
- const isLogical = (fieldOptions & 4 /* FieldOptions.logicalType */) !== 0;
26
- const isComplex = (fieldOptions & 2 /* FieldOptions.complexType */) !== 0;
27
- const typeValue = decodeVarintInt32(src, offset, 1)[0] >>> 0;
28
- const field = {};
29
- if ((fieldOptions & 1 /* FieldOptions.nullable */) !== 0) {
30
- field.nullable = true;
37
+ export function decodeField(src, offset) {
38
+ const typeCode = decodeVarintInt32(src, offset, 1)[0] >>> 0;
39
+ if (typeCode < 10 || typeCode > 30) {
40
+ throw new Error(`Unsupported field type code ${typeCode}. Supported: ${SUPPORTED_FIELD_TYPES}`);
31
41
  }
32
- if (isComplex) {
33
- const complex = {};
34
- if (isLogical) {
35
- complex.type = "logicalType";
36
- complex.logicalType = typeValue;
37
- }
38
- else {
39
- complex.type = "physicalType";
40
- complex.physicalType = typeValue;
41
- }
42
- if ((fieldOptions & 8 /* FieldOptions.hasChildren */) !== 0) {
43
- const childCount = decodeVarintInt32(src, offset, 1)[0] >>> 0;
44
- complex.children = new Array(childCount);
45
- for (let i = 0; i < childCount; i++) {
46
- complex.children[i] = decodeField(src, offset);
47
- }
48
- }
49
- field.type = "complexField";
50
- field.complexField = complex;
42
+ const column = decodeColumnType(typeCode);
43
+ if (columnTypeHasName(typeCode)) {
44
+ column.name = decodeString(src, offset);
51
45
  }
52
- else {
53
- const scalar = {};
54
- if (isLogical) {
55
- scalar.type = "logicalType";
56
- scalar.logicalType = typeValue;
57
- }
58
- else {
59
- scalar.type = "physicalType";
60
- scalar.physicalType = typeValue;
46
+ if (columnTypeHasChildren(typeCode)) {
47
+ const childCount = decodeVarintInt32(src, offset, 1)[0] >>> 0;
48
+ column.complexType.children = new Array(childCount);
49
+ for (let i = 0; i < childCount; i++) {
50
+ column.complexType.children[i] = decodeField(src, offset);
61
51
  }
62
- field.type = "scalarField";
63
- field.scalarField = scalar;
64
52
  }
65
- return field;
53
+ return columnToField(column);
66
54
  }
67
55
  /**
68
56
  * The typeCode encodes the column type, nullable flag, and whether it has name/children.
69
57
  */
70
58
  function decodeColumn(src, offset) {
71
59
  const typeCode = decodeVarintInt32(src, offset, 1)[0] >>> 0;
72
- const column = TypeMap.decodeColumnType(typeCode);
60
+ const column = decodeColumnType(typeCode);
73
61
  if (!column) {
74
- throw new Error(`Unsupported column type code: ${typeCode}`);
62
+ throw new Error(`Unsupported column type code ${typeCode}. Supported: ${SUPPORTED_COLUMN_TYPES}`);
75
63
  }
76
- if (TypeMap.columnTypeHasName(typeCode)) {
64
+ if (columnTypeHasName(typeCode)) {
77
65
  column.name = decodeString(src, offset);
78
66
  }
79
67
  else {
@@ -85,7 +73,7 @@ function decodeColumn(src, offset) {
85
73
  column.name = "geometry";
86
74
  }
87
75
  }
88
- if (TypeMap.columnTypeHasChildren(typeCode)) {
76
+ if (columnTypeHasChildren(typeCode)) {
89
77
  // Only STRUCT (typeCode 30) has children
90
78
  const childCount = decodeVarintInt32(src, offset, 1)[0] >>> 0;
91
79
  const complexCol = column.complexType;
@@ -1 +1 @@
1
- {"version":3,"file":"embeddedTilesetMetadataDecoder.js","sourceRoot":"","sources":["../../../src/metadata/tileset/embeddedTilesetMetadataDecoder.ts"],"names":[],"mappings":"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","sourcesContent":["import type IntWrapper from \"../../decoding/intWrapper\";\nimport { decodeVarintInt32 } from \"../../decoding/integerDecodingUtils\";\nimport {\n type Column,\n type ComplexField,\n type FeatureTableSchema,\n type Field,\n type ScalarField,\n type TileSetMetadata,\n} from \"./tilesetMetadata\";\nimport { TypeMap } from \"./typeMap\";\n\nconst enum FieldOptions {\n nullable = 1 << 0,\n complexType = 1 << 1,\n logicalType = 1 << 2,\n hasChildren = 1 << 3,\n}\n\nconst textDecoder = new TextDecoder();\n\n/**\n * Decodes a length-prefixed UTF-8 string.\n * Layout: [len: varint32][bytes: len]\n */\nfunction decodeString(src: Uint8Array, offset: IntWrapper): string {\n const length = decodeVarintInt32(src, offset, 1)[0];\n if (length === 0) {\n return \"\";\n }\n const start = offset.get();\n const end = start + length;\n const view = src.subarray(start, end);\n offset.add(length);\n return textDecoder.decode(view);\n}\n\n/**\n * Decodes a Field used as part of complex types (STRUCT children).\n * Unlike Column, Field still uses the fieldOptions bitfield for flexibility.\n */\nfunction decodeField(src: Uint8Array, offset: IntWrapper): Field {\n const fieldOptions = decodeVarintInt32(src, offset, 1)[0] >>> 0;\n const isLogical = (fieldOptions & FieldOptions.logicalType) !== 0;\n const isComplex = (fieldOptions & FieldOptions.complexType) !== 0;\n\n const typeValue = decodeVarintInt32(src, offset, 1)[0] >>> 0;\n\n const field = {} as Field;\n if ((fieldOptions & FieldOptions.nullable) !== 0) {\n field.nullable = true;\n }\n\n if (isComplex) {\n const complex = {} as ComplexField;\n if (isLogical) {\n complex.type = \"logicalType\";\n complex.logicalType = typeValue;\n } else {\n complex.type = \"physicalType\";\n complex.physicalType = typeValue;\n }\n\n if ((fieldOptions & FieldOptions.hasChildren) !== 0) {\n const childCount = decodeVarintInt32(src, offset, 1)[0] >>> 0;\n complex.children = new Array(childCount);\n for (let i = 0; i < childCount; i++) {\n complex.children[i] = decodeField(src, offset);\n }\n }\n field.type = \"complexField\";\n field.complexField = complex;\n } else {\n const scalar = {} as ScalarField;\n if (isLogical) {\n scalar.type = \"logicalType\";\n scalar.logicalType = typeValue;\n } else {\n scalar.type = \"physicalType\";\n scalar.physicalType = typeValue;\n }\n field.type = \"scalarField\";\n field.scalarField = scalar;\n }\n\n return field;\n}\n\n/**\n * The typeCode encodes the column type, nullable flag, and whether it has name/children.\n */\nfunction decodeColumn(src: Uint8Array, offset: IntWrapper): Column {\n const typeCode = decodeVarintInt32(src, offset, 1)[0] >>> 0;\n const column = TypeMap.decodeColumnType(typeCode);\n\n if (!column) {\n throw new Error(`Unsupported column type code: ${typeCode}`);\n }\n\n if (TypeMap.columnTypeHasName(typeCode)) {\n column.name = decodeString(src, offset);\n } else {\n // ID and GEOMETRY columns have implicit names\n if (typeCode >= 0 && typeCode <= 3) {\n column.name = \"id\";\n } else if (typeCode === 4) {\n column.name = \"geometry\";\n }\n }\n\n if (TypeMap.columnTypeHasChildren(typeCode)) {\n // Only STRUCT (typeCode 30) has children\n const childCount = decodeVarintInt32(src, offset, 1)[0] >>> 0;\n const complexCol = column.complexType;\n complexCol.children = new Array(childCount);\n for (let i = 0; i < childCount; i++) {\n complexCol.children[i] = decodeField(src, offset);\n }\n }\n\n return column;\n}\n\n/**\n * Top-level decoder for embedded tileset metadata.\n * Reads exactly ONE FeatureTableSchema from the stream.\n *\n * @param bytes The byte array containing the metadata\n * @param offset The current offset in the byte array (will be advanced)\n */\nexport function decodeEmbeddedTileSetMetadata(bytes: Uint8Array, offset: IntWrapper): [TileSetMetadata, number] {\n const meta = {} as TileSetMetadata;\n meta.featureTables = [];\n\n const table = {} as FeatureTableSchema;\n table.name = decodeString(bytes, offset);\n const extent = decodeVarintInt32(bytes, offset, 1)[0] >>> 0;\n\n const columnCount = decodeVarintInt32(bytes, offset, 1)[0] >>> 0;\n table.columns = new Array(columnCount);\n for (let j = 0; j < columnCount; j++) {\n table.columns[j] = decodeColumn(bytes, offset);\n }\n\n meta.featureTables.push(table);\n\n return [meta, extent];\n}\n"]}
1
+ {"version":3,"file":"embeddedTilesetMetadataDecoder.js","sourceRoot":"","sources":["../../../src/metadata/tileset/embeddedTilesetMetadataDecoder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAExE,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAEvF,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;AAEtC,MAAM,sBAAsB,GAAG,kDAAkD,CAAC;AAClF,MAAM,qBAAqB,GAAG,4BAA4B,CAAC;AAE3D;;;GAGG;AACH,SAAS,YAAY,CAAC,GAAe,EAAE,MAAkB;IACrD,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;QACf,OAAO,EAAE,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;IAC3B,MAAM,GAAG,GAAG,KAAK,GAAG,MAAM,CAAC;IAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACtC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACnB,OAAO,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,MAAc;IACjC,OAAO;QACH,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,WAAW,EAAE,MAAM,CAAC,UAAU;QAC9B,YAAY,EAAE,MAAM,CAAC,WAAW;QAChC,IAAI,EAAE,MAAM,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,cAAc;KACtE,CAAC;AACN,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,GAAe,EAAE,MAAkB;IAC3D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAE5D,IAAI,QAAQ,GAAG,EAAE,IAAI,QAAQ,GAAG,EAAE,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,+BAA+B,QAAQ,gBAAgB,qBAAqB,EAAE,CAAC,CAAC;IACpG,CAAC;IAED,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAE1C,IAAI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED,IAAI,qBAAqB,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9D,MAAM,CAAC,WAAW,CAAC,QAAQ,GAAG,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;QACpD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC9D,CAAC;IACL,CAAC;IAED,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,GAAe,EAAE,MAAkB;IACrD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAE1C,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,gCAAgC,QAAQ,gBAAgB,sBAAsB,EAAE,CAAC,CAAC;IACtG,CAAC;IAED,IAAI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;SAAM,CAAC;QACJ,8CAA8C;QAC9C,IAAI,QAAQ,IAAI,CAAC,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;YACjC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;QACvB,CAAC;aAAM,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,IAAI,GAAG,UAAU,CAAC;QAC7B,CAAC;IACL,CAAC;IAED,IAAI,qBAAqB,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClC,yCAAyC;QACzC,MAAM,UAAU,GAAG,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9D,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC;QACtC,UAAU,CAAC,QAAQ,GAAG,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;QAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACtD,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,6BAA6B,CAAC,KAAiB,EAAE,MAAkB;IAC/E,MAAM,IAAI,GAAG,EAAqB,CAAC;IACnC,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;IAExB,MAAM,KAAK,GAAG,EAAwB,CAAC;IACvC,KAAK,CAAC,IAAI,GAAG,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAE5D,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACjE,KAAK,CAAC,OAAO,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAE/B,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC1B,CAAC","sourcesContent":["import type IntWrapper from \"../../decoding/intWrapper\";\nimport { decodeVarintInt32 } from \"../../decoding/integerDecodingUtils\";\nimport { type Column, type FeatureTableSchema, type Field, type TileSetMetadata } from \"./tilesetMetadata\";\nimport { columnTypeHasChildren, columnTypeHasName, decodeColumnType } from \"./typeMap\";\n\nconst textDecoder = new TextDecoder();\n\nconst SUPPORTED_COLUMN_TYPES = \"0-3(ID), 4(GEOMETRY), 10-29(scalars), 30(STRUCT)\";\nconst SUPPORTED_FIELD_TYPES = \"10-29(scalars), 30(STRUCT)\";\n\n/**\n * Decodes a length-prefixed UTF-8 string.\n * Layout: [len: varint32][bytes: len]\n */\nfunction decodeString(src: Uint8Array, offset: IntWrapper): string {\n const length = decodeVarintInt32(src, offset, 1)[0];\n if (length === 0) {\n return \"\";\n }\n const start = offset.get();\n const end = start + length;\n const view = src.subarray(start, end);\n offset.add(length);\n return textDecoder.decode(view);\n}\n\n/**\n * Converts a Column to a Field.\n * Used when decoding Field metadata which has the same format as Column.\n */\nfunction columnToField(column: Column): Field {\n return {\n name: column.name,\n nullable: column.nullable,\n scalarField: column.scalarType,\n complexField: column.complexType,\n type: column.type === \"scalarType\" ? \"scalarField\" : \"complexField\",\n };\n}\n\n/**\n * Decodes a Field used as part of complex types (STRUCT children).\n */\nexport function decodeField(src: Uint8Array, offset: IntWrapper): Field {\n const typeCode = decodeVarintInt32(src, offset, 1)[0] >>> 0;\n\n if (typeCode < 10 || typeCode > 30) {\n throw new Error(`Unsupported field type code ${typeCode}. Supported: ${SUPPORTED_FIELD_TYPES}`);\n }\n\n const column = decodeColumnType(typeCode);\n\n if (columnTypeHasName(typeCode)) {\n column.name = decodeString(src, offset);\n }\n\n if (columnTypeHasChildren(typeCode)) {\n const childCount = decodeVarintInt32(src, offset, 1)[0] >>> 0;\n column.complexType.children = new Array(childCount);\n for (let i = 0; i < childCount; i++) {\n column.complexType.children[i] = decodeField(src, offset);\n }\n }\n\n return columnToField(column);\n}\n\n/**\n * The typeCode encodes the column type, nullable flag, and whether it has name/children.\n */\nfunction decodeColumn(src: Uint8Array, offset: IntWrapper): Column {\n const typeCode = decodeVarintInt32(src, offset, 1)[0] >>> 0;\n const column = decodeColumnType(typeCode);\n\n if (!column) {\n throw new Error(`Unsupported column type code ${typeCode}. Supported: ${SUPPORTED_COLUMN_TYPES}`);\n }\n\n if (columnTypeHasName(typeCode)) {\n column.name = decodeString(src, offset);\n } else {\n // ID and GEOMETRY columns have implicit names\n if (typeCode >= 0 && typeCode <= 3) {\n column.name = \"id\";\n } else if (typeCode === 4) {\n column.name = \"geometry\";\n }\n }\n\n if (columnTypeHasChildren(typeCode)) {\n // Only STRUCT (typeCode 30) has children\n const childCount = decodeVarintInt32(src, offset, 1)[0] >>> 0;\n const complexCol = column.complexType;\n complexCol.children = new Array(childCount);\n for (let i = 0; i < childCount; i++) {\n complexCol.children[i] = decodeField(src, offset);\n }\n }\n\n return column;\n}\n\n/**\n * Top-level decoder for embedded tileset metadata.\n * Reads exactly ONE FeatureTableSchema from the stream.\n *\n * @param bytes The byte array containing the metadata\n * @param offset The current offset in the byte array (will be advanced)\n */\nexport function decodeEmbeddedTileSetMetadata(bytes: Uint8Array, offset: IntWrapper): [TileSetMetadata, number] {\n const meta = {} as TileSetMetadata;\n meta.featureTables = [];\n\n const table = {} as FeatureTableSchema;\n table.name = decodeString(bytes, offset);\n const extent = decodeVarintInt32(bytes, offset, 1)[0] >>> 0;\n\n const columnCount = decodeVarintInt32(bytes, offset, 1)[0] >>> 0;\n table.columns = new Array(columnCount);\n for (let j = 0; j < columnCount; j++) {\n table.columns[j] = decodeColumn(bytes, offset);\n }\n\n meta.featureTables.push(table);\n\n return [meta, extent];\n}\n"]}
@@ -0,0 +1,142 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { decodeField, decodeEmbeddedTileSetMetadata } from "./embeddedTilesetMetadataDecoder";
3
+ import IntWrapper from "../../decoding/intWrapper";
4
+ import { concatenateBuffers } from "../../decoding/decodingTestUtils";
5
+ import { ComplexType, ScalarType } from "./tilesetMetadata";
6
+ import { encodeChildCount, encodeFieldName, encodeTypeCode, scalarTypeCode, } from "../../encoding/embeddedTilesetMetadataEncoder";
7
+ const STRUCT_TYPE_CODE = 30;
8
+ describe("embeddedTilesetMetadataDecoder", () => {
9
+ describe("decodeField", () => {
10
+ describe("scalar fields", () => {
11
+ it("should decode non-nullable STRING field", () => {
12
+ const buffer = concatenateBuffers(encodeTypeCode(scalarTypeCode(ScalarType.STRING, false)), encodeFieldName("street"));
13
+ const field = decodeField(buffer, new IntWrapper(0));
14
+ expect(field.name).toBe("street");
15
+ expect(field.nullable).toBe(false);
16
+ expect(field.type).toBe("scalarField");
17
+ expect(field.scalarField?.physicalType).toBe(ScalarType.STRING);
18
+ });
19
+ it("should decode nullable UINT_64 field", () => {
20
+ const buffer = concatenateBuffers(encodeTypeCode(scalarTypeCode(ScalarType.UINT_64, true)), encodeFieldName("population"));
21
+ const field = decodeField(buffer, new IntWrapper(0));
22
+ expect(field.name).toBe("population");
23
+ expect(field.nullable).toBe(true);
24
+ expect(field.type).toBe("scalarField");
25
+ expect(field.scalarField?.physicalType).toBe(ScalarType.UINT_64);
26
+ });
27
+ it("should decode BOOLEAN field", () => {
28
+ const buffer = concatenateBuffers(encodeTypeCode(scalarTypeCode(ScalarType.BOOLEAN, false)), encodeFieldName("isActive"));
29
+ const field = decodeField(buffer, new IntWrapper(0));
30
+ expect(field.name).toBe("isActive");
31
+ expect(field.nullable).toBe(false);
32
+ expect(field.type).toBe("scalarField");
33
+ expect(field.scalarField?.physicalType).toBe(ScalarType.BOOLEAN);
34
+ });
35
+ it("should decode non-nullable UINT_32 field", () => {
36
+ const buffer = concatenateBuffers(encodeTypeCode(scalarTypeCode(ScalarType.UINT_32, false)), encodeFieldName("count"));
37
+ const field = decodeField(buffer, new IntWrapper(0));
38
+ expect(field.name).toBe("count");
39
+ expect(field.nullable).toBe(false);
40
+ expect(field.type).toBe("scalarField");
41
+ expect(field.scalarField?.physicalType).toBe(ScalarType.UINT_32);
42
+ });
43
+ it("should decode nullable FLOAT field", () => {
44
+ const buffer = concatenateBuffers(encodeTypeCode(scalarTypeCode(ScalarType.FLOAT, true)), encodeFieldName("temperature"));
45
+ const field = decodeField(buffer, new IntWrapper(0));
46
+ expect(field.name).toBe("temperature");
47
+ expect(field.nullable).toBe(true);
48
+ expect(field.type).toBe("scalarField");
49
+ expect(field.scalarField?.physicalType).toBe(ScalarType.FLOAT);
50
+ });
51
+ });
52
+ describe("complex fields", () => {
53
+ it("should decode STRUCT field with nested children", () => {
54
+ const children = [
55
+ {
56
+ typeCode: scalarTypeCode(ScalarType.STRING, false),
57
+ name: "street",
58
+ nullable: false,
59
+ physicalType: ScalarType.STRING,
60
+ },
61
+ {
62
+ typeCode: scalarTypeCode(ScalarType.UINT_32, true),
63
+ name: "zipcode",
64
+ nullable: true,
65
+ physicalType: ScalarType.UINT_32,
66
+ },
67
+ ];
68
+ const buffer = concatenateBuffers(encodeTypeCode(STRUCT_TYPE_CODE), encodeFieldName("address"), encodeChildCount(children.length), ...children.flatMap((c) => [encodeTypeCode(c.typeCode), encodeFieldName(c.name)]));
69
+ const field = decodeField(buffer, new IntWrapper(0));
70
+ expect(field.name).toBe("address");
71
+ expect(field.nullable).toBe(false);
72
+ expect(field.type).toBe("complexField");
73
+ expect(field.complexField?.physicalType).toBe(ComplexType.STRUCT);
74
+ expect(field.complexField?.children).toHaveLength(children.length);
75
+ for (let i = 0; i < children.length; i++) {
76
+ const child = children[i];
77
+ expect(field.complexField?.children[i].name).toBe(child.name);
78
+ expect(field.complexField?.children[i].nullable).toBe(child.nullable);
79
+ expect(field.complexField?.children[i].scalarField?.physicalType).toBe(child.physicalType);
80
+ }
81
+ });
82
+ });
83
+ describe("deeply nested structures", () => {
84
+ it("should decode 3-level nested STRUCT", () => {
85
+ const leafChildren = [
86
+ { typeCode: scalarTypeCode(ScalarType.FLOAT, false), name: "lat" },
87
+ { typeCode: scalarTypeCode(ScalarType.FLOAT, false), name: "lon" },
88
+ ];
89
+ const buffer = concatenateBuffers(
90
+ // Parent STRUCT "location"
91
+ encodeTypeCode(STRUCT_TYPE_CODE), encodeFieldName("location"), encodeChildCount(1),
92
+ // Child STRUCT "address"
93
+ encodeTypeCode(STRUCT_TYPE_CODE), encodeFieldName("address"), encodeChildCount(1),
94
+ // Grandchild STRUCT "coordinates"
95
+ encodeTypeCode(STRUCT_TYPE_CODE), encodeFieldName("coordinates"), encodeChildCount(leafChildren.length),
96
+ // Great-grandchildren
97
+ ...leafChildren.flatMap((c) => [encodeTypeCode(c.typeCode), encodeFieldName(c.name)]));
98
+ const field = decodeField(buffer, new IntWrapper(0));
99
+ expect(field.name).toBe("location");
100
+ expect(field.type).toBe("complexField");
101
+ expect(field.complexField?.physicalType).toBe(ComplexType.STRUCT);
102
+ const address = field.complexField?.children[0];
103
+ expect(address?.name).toBe("address");
104
+ expect(address?.type).toBe("complexField");
105
+ const coordinates = address?.complexField?.children[0];
106
+ expect(coordinates?.name).toBe("coordinates");
107
+ expect(coordinates?.complexField?.children).toHaveLength(leafChildren.length);
108
+ for (let i = 0; i < leafChildren.length; i++) {
109
+ const child = leafChildren[i];
110
+ expect(coordinates?.complexField?.children[i].name).toBe(child.name);
111
+ expect(coordinates?.complexField?.children[i].scalarField?.physicalType).toBe(ScalarType.FLOAT);
112
+ }
113
+ });
114
+ });
115
+ describe("offset tracking", () => {
116
+ it("should correctly advance offset", () => {
117
+ const buffer = concatenateBuffers(encodeTypeCode(scalarTypeCode(ScalarType.STRING, false)), encodeFieldName("test"));
118
+ const offset = new IntWrapper(0);
119
+ decodeField(buffer, offset);
120
+ expect(offset.get()).toBe(buffer.length);
121
+ });
122
+ });
123
+ describe("error handling", () => {
124
+ it("should throw error for unsupported typeCode", () => {
125
+ const buffer = encodeTypeCode(999);
126
+ expect(() => {
127
+ decodeField(buffer, new IntWrapper(0));
128
+ }).toThrow("Unsupported field type code 999. Supported: 10-29(scalars), 30(STRUCT)");
129
+ });
130
+ });
131
+ });
132
+ describe("decodeEmbeddedTileSetMetadata", () => {
133
+ it("should decode tileset with STRUCT column", () => {
134
+ const buffer = concatenateBuffers(encodeFieldName(""), encodeTypeCode(4096), encodeChildCount(1), encodeTypeCode(STRUCT_TYPE_CODE), encodeFieldName("props"), encodeChildCount(1), encodeTypeCode(scalarTypeCode(ScalarType.STRING, false)), encodeFieldName("name"));
135
+ const [metadata, extent] = decodeEmbeddedTileSetMetadata(buffer, new IntWrapper(0));
136
+ expect(extent).toBe(4096);
137
+ expect(metadata.featureTables[0].name).toBe("");
138
+ expect(metadata.featureTables[0].columns[0].complexType.children).toHaveLength(1);
139
+ });
140
+ });
141
+ });
142
+ //# sourceMappingURL=embeddedTilesetMetadataDecoder.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embeddedTilesetMetadataDecoder.spec.js","sourceRoot":"","sources":["../../../src/metadata/tileset/embeddedTilesetMetadataDecoder.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { decodeField, decodeEmbeddedTileSetMetadata } from \"./embeddedTilesetMetadataDecoder\";\nimport IntWrapper from \"../../decoding/intWrapper\";\nimport { concatenateBuffers } from \"../../decoding/decodingTestUtils\";\nimport { ComplexType, ScalarType } from \"./tilesetMetadata\";\nimport {\n encodeChildCount,\n encodeFieldName,\n encodeTypeCode,\n scalarTypeCode,\n} from \"../../encoding/embeddedTilesetMetadataEncoder\";\n\nconst STRUCT_TYPE_CODE = 30;\n\ndescribe(\"embeddedTilesetMetadataDecoder\", () => {\n describe(\"decodeField\", () => {\n describe(\"scalar fields\", () => {\n it(\"should decode non-nullable STRING field\", () => {\n const buffer = concatenateBuffers(\n encodeTypeCode(scalarTypeCode(ScalarType.STRING, false)),\n encodeFieldName(\"street\"),\n );\n const field = decodeField(buffer, new IntWrapper(0));\n\n expect(field.name).toBe(\"street\");\n expect(field.nullable).toBe(false);\n expect(field.type).toBe(\"scalarField\");\n expect(field.scalarField?.physicalType).toBe(ScalarType.STRING);\n });\n\n it(\"should decode nullable UINT_64 field\", () => {\n const buffer = concatenateBuffers(\n encodeTypeCode(scalarTypeCode(ScalarType.UINT_64, true)),\n encodeFieldName(\"population\"),\n );\n const field = decodeField(buffer, new IntWrapper(0));\n\n expect(field.name).toBe(\"population\");\n expect(field.nullable).toBe(true);\n expect(field.type).toBe(\"scalarField\");\n expect(field.scalarField?.physicalType).toBe(ScalarType.UINT_64);\n });\n\n it(\"should decode BOOLEAN field\", () => {\n const buffer = concatenateBuffers(\n encodeTypeCode(scalarTypeCode(ScalarType.BOOLEAN, false)),\n encodeFieldName(\"isActive\"),\n );\n const field = decodeField(buffer, new IntWrapper(0));\n\n expect(field.name).toBe(\"isActive\");\n expect(field.nullable).toBe(false);\n expect(field.type).toBe(\"scalarField\");\n expect(field.scalarField?.physicalType).toBe(ScalarType.BOOLEAN);\n });\n\n it(\"should decode non-nullable UINT_32 field\", () => {\n const buffer = concatenateBuffers(\n encodeTypeCode(scalarTypeCode(ScalarType.UINT_32, false)),\n encodeFieldName(\"count\"),\n );\n const field = decodeField(buffer, new IntWrapper(0));\n\n expect(field.name).toBe(\"count\");\n expect(field.nullable).toBe(false);\n expect(field.type).toBe(\"scalarField\");\n expect(field.scalarField?.physicalType).toBe(ScalarType.UINT_32);\n });\n\n it(\"should decode nullable FLOAT field\", () => {\n const buffer = concatenateBuffers(\n encodeTypeCode(scalarTypeCode(ScalarType.FLOAT, true)),\n encodeFieldName(\"temperature\"),\n );\n const field = decodeField(buffer, new IntWrapper(0));\n\n expect(field.name).toBe(\"temperature\");\n expect(field.nullable).toBe(true);\n expect(field.type).toBe(\"scalarField\");\n expect(field.scalarField?.physicalType).toBe(ScalarType.FLOAT);\n });\n });\n\n describe(\"complex fields\", () => {\n it(\"should decode STRUCT field with nested children\", () => {\n const children = [\n {\n typeCode: scalarTypeCode(ScalarType.STRING, false),\n name: \"street\",\n nullable: false,\n physicalType: ScalarType.STRING,\n },\n {\n typeCode: scalarTypeCode(ScalarType.UINT_32, true),\n name: \"zipcode\",\n nullable: true,\n physicalType: ScalarType.UINT_32,\n },\n ];\n\n const buffer = concatenateBuffers(\n encodeTypeCode(STRUCT_TYPE_CODE),\n encodeFieldName(\"address\"),\n encodeChildCount(children.length),\n ...children.flatMap((c) => [encodeTypeCode(c.typeCode), encodeFieldName(c.name)]),\n );\n\n const field = decodeField(buffer, new IntWrapper(0));\n\n expect(field.name).toBe(\"address\");\n expect(field.nullable).toBe(false);\n expect(field.type).toBe(\"complexField\");\n expect(field.complexField?.physicalType).toBe(ComplexType.STRUCT);\n expect(field.complexField?.children).toHaveLength(children.length);\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n\n expect(field.complexField?.children[i].name).toBe(child.name);\n expect(field.complexField?.children[i].nullable).toBe(child.nullable);\n expect(field.complexField?.children[i].scalarField?.physicalType).toBe(child.physicalType);\n }\n });\n });\n\n describe(\"deeply nested structures\", () => {\n it(\"should decode 3-level nested STRUCT\", () => {\n const leafChildren = [\n { typeCode: scalarTypeCode(ScalarType.FLOAT, false), name: \"lat\" },\n { typeCode: scalarTypeCode(ScalarType.FLOAT, false), name: \"lon\" },\n ];\n\n const buffer = concatenateBuffers(\n // Parent STRUCT \"location\"\n encodeTypeCode(STRUCT_TYPE_CODE),\n encodeFieldName(\"location\"),\n encodeChildCount(1),\n // Child STRUCT \"address\"\n encodeTypeCode(STRUCT_TYPE_CODE),\n encodeFieldName(\"address\"),\n encodeChildCount(1),\n // Grandchild STRUCT \"coordinates\"\n encodeTypeCode(STRUCT_TYPE_CODE),\n encodeFieldName(\"coordinates\"),\n encodeChildCount(leafChildren.length),\n // Great-grandchildren\n ...leafChildren.flatMap((c) => [encodeTypeCode(c.typeCode), encodeFieldName(c.name)]),\n );\n\n const field = decodeField(buffer, new IntWrapper(0));\n\n expect(field.name).toBe(\"location\");\n expect(field.type).toBe(\"complexField\");\n expect(field.complexField?.physicalType).toBe(ComplexType.STRUCT);\n\n const address = field.complexField?.children[0];\n expect(address?.name).toBe(\"address\");\n expect(address?.type).toBe(\"complexField\");\n\n const coordinates = address?.complexField?.children[0];\n expect(coordinates?.name).toBe(\"coordinates\");\n expect(coordinates?.complexField?.children).toHaveLength(leafChildren.length);\n\n for (let i = 0; i < leafChildren.length; i++) {\n const child = leafChildren[i];\n\n expect(coordinates?.complexField?.children[i].name).toBe(child.name);\n expect(coordinates?.complexField?.children[i].scalarField?.physicalType).toBe(ScalarType.FLOAT);\n }\n });\n });\n\n describe(\"offset tracking\", () => {\n it(\"should correctly advance offset\", () => {\n const buffer = concatenateBuffers(\n encodeTypeCode(scalarTypeCode(ScalarType.STRING, false)),\n encodeFieldName(\"test\"),\n );\n const offset = new IntWrapper(0);\n\n decodeField(buffer, offset);\n\n expect(offset.get()).toBe(buffer.length);\n });\n });\n\n describe(\"error handling\", () => {\n it(\"should throw error for unsupported typeCode\", () => {\n const buffer = encodeTypeCode(999);\n\n expect(() => {\n decodeField(buffer, new IntWrapper(0));\n }).toThrow(\"Unsupported field type code 999. Supported: 10-29(scalars), 30(STRUCT)\");\n });\n });\n\n });\n\n describe(\"decodeEmbeddedTileSetMetadata\", () => {\n it(\"should decode tileset with STRUCT column\", () => {\n const buffer = concatenateBuffers(\n encodeFieldName(\"\"),\n encodeTypeCode(4096),\n encodeChildCount(1),\n encodeTypeCode(STRUCT_TYPE_CODE),\n encodeFieldName(\"props\"),\n encodeChildCount(1),\n encodeTypeCode(scalarTypeCode(ScalarType.STRING, false)),\n encodeFieldName(\"name\"),\n );\n\n const [metadata, extent] = decodeEmbeddedTileSetMetadata(buffer, new IntWrapper(0));\n\n expect(extent).toBe(4096);\n expect(metadata.featureTables[0].name).toBe(\"\");\n expect(metadata.featureTables[0].columns[0].complexType.children).toHaveLength(1);\n });\n });\n});\n"]}
@@ -7,32 +7,24 @@ import { type Column } from "./tilesetMetadata";
7
7
  * - Whether the column has children (typeCode == 30 for STRUCT)
8
8
  * - For ID types: whether it uses long (64-bit) IDs
9
9
  */
10
- export declare class TypeMap {
11
- /**
12
- * Decodes a type code into a Column structure.
13
- * ID columns (0-3) are represented as physical UINT_32 or UINT_64 types in TypeScript
14
- */
15
- static decodeColumnType(typeCode: number): Column | null;
16
- /**
17
- * Returns true if this type code requires a name to be stored.
18
- * ID (0-3) and GEOMETRY (4) columns have implicit names.
19
- * All other types (>= 10) require explicit names.
20
- */
21
- static columnTypeHasName(typeCode: number): boolean;
22
- /**
23
- * Returns true if this type code has child fields.
24
- * Only STRUCT (typeCode 30) has children.
25
- */
26
- static columnTypeHasChildren(typeCode: number): boolean;
27
- /**
28
- * Determines if a stream count needs to be read for this column.
29
- * Mirrors the logic in cpp/include/mlt/metadata/type_map.hpp lines 81-118
30
- */
31
- static hasStreamCount(column: Column): boolean;
32
- /**
33
- * Maps a scalar type code to a Column with ScalarType.
34
- * Type codes 10-29 encode scalar types with nullable flag.
35
- * Even codes are non-nullable, odd codes are nullable.
36
- */
37
- private static mapScalarType;
38
- }
10
+ /**
11
+ * Decodes a type code into a Column structure.
12
+ * ID columns (0-3) are represented as physical UINT_32 or UINT_64 types in TypeScript
13
+ */
14
+ export declare function decodeColumnType(typeCode: number): Column | null;
15
+ /**
16
+ * Returns true if this type code requires a name to be stored.
17
+ * ID (0-3) and GEOMETRY (4) columns have implicit names.
18
+ * All other types (>= 10) require explicit names.
19
+ */
20
+ export declare function columnTypeHasName(typeCode: number): boolean;
21
+ /**
22
+ * Returns true if this type code has child fields.
23
+ * Only STRUCT (typeCode 30) has children.
24
+ */
25
+ export declare function columnTypeHasChildren(typeCode: number): boolean;
26
+ /**
27
+ * Determines if a stream count needs to be read for this column.
28
+ * Mirrors the logic in cpp/include/mlt/metadata/type_map.hpp lines 81-118
29
+ */
30
+ export declare function hasStreamCount(column: Column): boolean;