@osmix/core 0.1.10 → 0.2.0
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.
- package/CHANGELOG.md +25 -0
- package/LICENSE +21 -0
- package/README.md +86 -69
- package/dist/contracts.d.ts +26 -0
- package/dist/contracts.d.ts.map +1 -0
- package/dist/contracts.js +1 -0
- package/dist/contracts.js.map +1 -0
- package/dist/entities.d.ts +1 -1
- package/dist/entities.d.ts.map +1 -1
- package/dist/entities.js +2 -7
- package/dist/entities.js.map +1 -1
- package/dist/ids.d.ts +2 -0
- package/dist/ids.d.ts.map +1 -1
- package/dist/ids.js +23 -15
- package/dist/ids.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/mocks.d.ts.map +1 -1
- package/dist/mocks.js.map +1 -1
- package/dist/nodes.d.ts +9 -3
- package/dist/nodes.d.ts.map +1 -1
- package/dist/nodes.js +6 -13
- package/dist/nodes.js.map +1 -1
- package/dist/osm.d.ts +1 -1
- package/dist/osm.d.ts.map +1 -1
- package/dist/osm.js +1 -4
- package/dist/osm.js.map +1 -1
- package/dist/relations.d.ts +3 -2
- package/dist/relations.d.ts.map +1 -1
- package/dist/relations.js +15 -9
- package/dist/relations.js.map +1 -1
- package/dist/stringtable.d.ts.map +1 -1
- package/dist/stringtable.js +4 -13
- package/dist/stringtable.js.map +1 -1
- package/dist/tags.d.ts +1 -1
- package/dist/tags.d.ts.map +1 -1
- package/dist/tags.js.map +1 -1
- package/dist/typed-arrays.d.ts.map +1 -1
- package/dist/typed-arrays.js.map +1 -1
- package/dist/ways.d.ts +2 -1
- package/dist/ways.d.ts.map +1 -1
- package/dist/ways.js +18 -18
- package/dist/ways.js.map +1 -1
- package/package.json +46 -31
- package/src/contracts.ts +28 -0
- package/src/entities.ts +179 -194
- package/src/ids.ts +228 -235
- package/src/index.ts +12 -9
- package/src/mocks.ts +114 -113
- package/src/nodes.ts +364 -397
- package/src/osm.ts +196 -207
- package/src/relations.ts +530 -558
- package/src/stringtable.ts +174 -183
- package/src/tags.ts +263 -271
- package/src/typed-arrays.ts +184 -194
- package/src/types/geoflatbush.d.ts +28 -33
- package/src/types/geokdbush.d.ts +28 -33
- package/src/types/kdbush.d.ts +34 -34
- package/src/ways.ts +381 -405
- package/test/ids.bench.ts +29 -0
- package/test/ids.test.ts +84 -0
- package/test/memory.test.ts +29 -30
- package/test/relations.bench.ts +27 -0
- package/test/relations.test.ts +101 -0
- package/test/tags-search.test.ts +76 -56
- package/test/typed-arrays.test.ts +100 -99
- package/tsconfig.build.json +6 -6
- package/tsconfig.json +7 -7
package/src/ids.ts
CHANGED
|
@@ -7,40 +7,37 @@
|
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { assertValue } from "@osmix/shared/assert"
|
|
11
|
-
import type { ContentHasher } from "@osmix/shared/content-hasher"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
type BufferType,
|
|
15
|
-
ResizeableTypedArray as RTA,
|
|
16
|
-
} from "./typed-arrays.ts"
|
|
10
|
+
import { assertValue } from "@osmix/shared/assert";
|
|
11
|
+
import type { ContentHasher } from "@osmix/shared/content-hasher";
|
|
12
|
+
|
|
13
|
+
import { BufferConstructor, type BufferType, ResizeableTypedArray as RTA } from "./typed-arrays.ts";
|
|
17
14
|
|
|
18
15
|
/**
|
|
19
16
|
* Union type for looking up entities by either OSM ID or internal array index.
|
|
20
17
|
*/
|
|
21
|
-
export type IdOrIndex = { id: number } | { index: number }
|
|
18
|
+
export type IdOrIndex = { id: number } | { index: number };
|
|
22
19
|
|
|
23
20
|
/**
|
|
24
21
|
* Number of IDs per anchor block for the two-level binary search.
|
|
25
22
|
* Smaller values increase anchor array size but speed up block-level search;
|
|
26
23
|
* larger values reduce anchor overhead but slow the final search.
|
|
27
24
|
*/
|
|
28
|
-
const BLOCK_SIZE = 256
|
|
25
|
+
const BLOCK_SIZE = 256;
|
|
29
26
|
|
|
30
27
|
/**
|
|
31
28
|
* Serializable state for worker transfer.
|
|
32
29
|
*/
|
|
33
30
|
export interface IdsTransferables<T extends BufferType = BufferType> {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
31
|
+
/** Entity IDs in insertion order. */
|
|
32
|
+
ids: T;
|
|
33
|
+
/** Sorted IDs for binary search (aliases `ids` if already sorted). */
|
|
34
|
+
sortedIds: T;
|
|
35
|
+
/** Maps sorted position → original insertion index. */
|
|
36
|
+
sortedIdPositionToIndex: T;
|
|
37
|
+
/** Anchor array: every BLOCK_SIZE-th sorted ID. */
|
|
38
|
+
anchors: T;
|
|
39
|
+
/** True if IDs were inserted in ascending order. */
|
|
40
|
+
idsAreSorted: boolean;
|
|
44
41
|
}
|
|
45
42
|
|
|
46
43
|
/**
|
|
@@ -50,241 +47,237 @@ export interface IdsTransferables<T extends BufferType = BufferType> {
|
|
|
50
47
|
* Max capacity: ~2^32 entities.
|
|
51
48
|
*/
|
|
52
49
|
export class Ids {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
50
|
+
/** All IDs in insertion order */
|
|
51
|
+
private ids: RTA<Float64Array>;
|
|
52
|
+
/** Whether buildIndex() has been called */
|
|
53
|
+
private indexBuilt = false;
|
|
54
|
+
/** True if IDs were added in ascending order (allows index optimization) */
|
|
55
|
+
private idsAreSorted = true;
|
|
56
|
+
/** Sorted view of IDs for binary search */
|
|
57
|
+
private idsSorted: Float64Array;
|
|
58
|
+
/** Maps position in sorted array → original insertion index */
|
|
59
|
+
private sortedIdPositionToIndex: Uint32Array;
|
|
60
|
+
/** Anchor array for two-level binary search: every BLOCK_SIZE-th sorted ID */
|
|
61
|
+
private anchors: Float64Array;
|
|
65
62
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
}
|
|
63
|
+
/**
|
|
64
|
+
* Create a new Ids index.
|
|
65
|
+
* @param transferables - Optional serialized state to reconstruct from.
|
|
66
|
+
*/
|
|
67
|
+
constructor(transferables?: IdsTransferables) {
|
|
68
|
+
if (transferables) {
|
|
69
|
+
this.ids = RTA.from(Float64Array, transferables.ids);
|
|
70
|
+
this.idsSorted = new Float64Array(transferables.sortedIds);
|
|
71
|
+
this.sortedIdPositionToIndex = new Uint32Array(transferables.sortedIdPositionToIndex);
|
|
72
|
+
this.anchors = new Float64Array(transferables.anchors);
|
|
73
|
+
this.idsAreSorted = transferables.idsAreSorted;
|
|
74
|
+
this.indexBuilt = true;
|
|
75
|
+
} else {
|
|
76
|
+
this.ids = new RTA(Float64Array);
|
|
77
|
+
this.idsSorted = new Float64Array(new BufferConstructor(0));
|
|
78
|
+
this.sortedIdPositionToIndex = new Uint32Array(new BufferConstructor(0));
|
|
79
|
+
this.anchors = new Float64Array(new BufferConstructor(0));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
87
82
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
83
|
+
/** Number of IDs stored in this index. */
|
|
84
|
+
get size() {
|
|
85
|
+
return this.ids.length;
|
|
86
|
+
}
|
|
92
87
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
88
|
+
/** Returns true if buildIndex() has been called and lookups are enabled. */
|
|
89
|
+
isReady() {
|
|
90
|
+
return this.indexBuilt;
|
|
91
|
+
}
|
|
97
92
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
93
|
+
/** Returns true if IDs were inserted in ascending order. */
|
|
94
|
+
isSorted() {
|
|
95
|
+
return this.idsAreSorted;
|
|
96
|
+
}
|
|
102
97
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Add an ID to the index.
|
|
100
|
+
* @param id - The OSM entity ID to add.
|
|
101
|
+
* @returns The internal array index where this ID was stored.
|
|
102
|
+
* @throws If the index has already been built.
|
|
103
|
+
*/
|
|
104
|
+
add(id: number): number {
|
|
105
|
+
if (this.indexBuilt) throw Error("ID index already built.");
|
|
106
|
+
if (this.ids.length > 0 && id < this.ids.at(-1)) this.idsAreSorted = false;
|
|
107
|
+
return this.ids.push(id);
|
|
108
|
+
}
|
|
114
109
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
110
|
+
/**
|
|
111
|
+
* Get the ID at a specific internal index.
|
|
112
|
+
* @param index - The internal array index.
|
|
113
|
+
* @returns The OSM entity ID at that index.
|
|
114
|
+
*/
|
|
115
|
+
at(index: number): number {
|
|
116
|
+
return this.ids.at(index);
|
|
117
|
+
}
|
|
123
118
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
119
|
+
/**
|
|
120
|
+
* Check if an ID exists in this index.
|
|
121
|
+
* @param id - The OSM entity ID to check.
|
|
122
|
+
* @returns True if the ID exists in this index.
|
|
123
|
+
*/
|
|
124
|
+
has(id: number): boolean {
|
|
125
|
+
return this.getIndexFromId(id) !== -1;
|
|
126
|
+
}
|
|
132
127
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
this.size * Uint32Array.BYTES_PER_ELEMENT,
|
|
149
|
-
)
|
|
150
|
-
this.idsSorted = new Float64Array(idsBuffer)
|
|
151
|
-
this.sortedIdPositionToIndex = new Uint32Array(posBuffer)
|
|
128
|
+
/**
|
|
129
|
+
* Build the index of IDs to positions.
|
|
130
|
+
*
|
|
131
|
+
* If the IDs are not sorted, we need to sort them and build a new index.
|
|
132
|
+
* If the IDs are sorted, we can use the existing index.
|
|
133
|
+
*/
|
|
134
|
+
buildIndex() {
|
|
135
|
+
if (this.indexBuilt) throw Error("ID index already built.");
|
|
136
|
+
this.ids.compact();
|
|
137
|
+
if (!this.idsAreSorted) {
|
|
138
|
+
// Build the sorted index
|
|
139
|
+
const idsBuffer = new BufferConstructor(this.size * Float64Array.BYTES_PER_ELEMENT);
|
|
140
|
+
const posBuffer = new BufferConstructor(this.size * Uint32Array.BYTES_PER_ELEMENT);
|
|
141
|
+
this.idsSorted = new Float64Array(idsBuffer);
|
|
142
|
+
this.sortedIdPositionToIndex = new Uint32Array(posBuffer);
|
|
152
143
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
144
|
+
// Sort positions by ID, using the original position as a deterministic
|
|
145
|
+
// tie-breaker for duplicate IDs.
|
|
146
|
+
const sortedPositions = new Uint32Array(this.size);
|
|
147
|
+
for (let i = 0; i < this.size; i++) sortedPositions[i] = i;
|
|
148
|
+
sortedPositions.sort((a, b) => {
|
|
149
|
+
const idDifference = this.ids.array[a]! - this.ids.array[b]!;
|
|
150
|
+
return idDifference === 0 ? a - b : idDifference;
|
|
151
|
+
});
|
|
152
|
+
for (let i = 0; i < this.size; i++) {
|
|
153
|
+
const position = sortedPositions[i]!;
|
|
154
|
+
this.idsSorted[i] = this.ids.array[position]!;
|
|
155
|
+
this.sortedIdPositionToIndex[i] = position;
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
// Point to the same array
|
|
159
|
+
this.idsSorted = this.ids.array;
|
|
160
|
+
// Create the sortedIdPositionToIndex array
|
|
161
|
+
const posBuffer = new BufferConstructor(this.size * Uint32Array.BYTES_PER_ELEMENT);
|
|
162
|
+
this.sortedIdPositionToIndex = new Uint32Array(posBuffer);
|
|
163
|
+
for (let i = 0; i < this.size; i++) {
|
|
164
|
+
this.sortedIdPositionToIndex[i] = i;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
158
167
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
tmp.sort((a, b) => a.id - b.id)
|
|
169
|
-
tmp.forEach(({ id, pos }, i) => {
|
|
170
|
-
this.idsSorted[i] = id
|
|
171
|
-
this.sortedIdPositionToIndex[i] = pos
|
|
172
|
-
})
|
|
173
|
-
} else {
|
|
174
|
-
// Point to the same array
|
|
175
|
-
this.idsSorted = this.ids.array
|
|
176
|
-
// Create the sortedIdPositionToIndex array
|
|
177
|
-
const posBuffer = new BufferConstructor(
|
|
178
|
-
this.size * Uint32Array.BYTES_PER_ELEMENT,
|
|
179
|
-
)
|
|
180
|
-
this.sortedIdPositionToIndex = new Uint32Array(posBuffer)
|
|
181
|
-
for (let i = 0; i < this.size; i++) {
|
|
182
|
-
this.sortedIdPositionToIndex[i] = i
|
|
183
|
-
}
|
|
184
|
-
}
|
|
168
|
+
// Build anchors (every blockSize-th key)
|
|
169
|
+
const aLen = Math.ceil(this.size / BLOCK_SIZE);
|
|
170
|
+
const sab = new BufferConstructor(aLen * Float64Array.BYTES_PER_ELEMENT);
|
|
171
|
+
this.anchors = new Float64Array(sab, 0, aLen);
|
|
172
|
+
for (let j = 0; j < aLen; j++) {
|
|
173
|
+
const id = this.idsSorted[Math.min(j * BLOCK_SIZE, this.size - 1)];
|
|
174
|
+
assertValue(id, "ID is undefined");
|
|
175
|
+
this.anchors[j] = id;
|
|
176
|
+
}
|
|
185
177
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const sab = new BufferConstructor(aLen * Float64Array.BYTES_PER_ELEMENT)
|
|
189
|
-
this.anchors = new Float64Array(sab, 0, aLen)
|
|
190
|
-
for (let j = 0; j < aLen; j++) {
|
|
191
|
-
const id = this.idsSorted[Math.min(j * BLOCK_SIZE, this.size - 1)]
|
|
192
|
-
assertValue(id, "ID is undefined")
|
|
193
|
-
this.anchors[j] = id
|
|
194
|
-
}
|
|
178
|
+
this.indexBuilt = true;
|
|
179
|
+
}
|
|
195
180
|
|
|
196
|
-
|
|
197
|
-
|
|
181
|
+
/**
|
|
182
|
+
* Look up the internal array index for an OSM entity ID.
|
|
183
|
+
*
|
|
184
|
+
* @param id - The OSM entity ID to look up.
|
|
185
|
+
* @returns The internal array index, or -1 if not found.
|
|
186
|
+
* @throws If the index has not been built.
|
|
187
|
+
*/
|
|
188
|
+
getIndexFromId(id: number): number {
|
|
189
|
+
if (!this.indexBuilt) throw Error("IdIndex not built.");
|
|
198
190
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
191
|
+
// binary search anchors
|
|
192
|
+
let lo = 0;
|
|
193
|
+
let hi = this.anchors.length - 1;
|
|
194
|
+
while (lo < hi) {
|
|
195
|
+
const mid = (lo + hi + 1) >>> 1;
|
|
196
|
+
const anchor = this.anchors[mid];
|
|
197
|
+
assertValue(anchor, "Anchor is undefined");
|
|
198
|
+
if (anchor <= id) lo = mid;
|
|
199
|
+
else hi = mid - 1;
|
|
200
|
+
}
|
|
201
|
+
const start = lo * BLOCK_SIZE;
|
|
202
|
+
const end = Math.min(start + BLOCK_SIZE, this.idsSorted.length);
|
|
208
203
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
204
|
+
// binary search within block
|
|
205
|
+
let l = start;
|
|
206
|
+
let r = end - 1;
|
|
207
|
+
while (l <= r) {
|
|
208
|
+
const m = (l + r) >>> 1;
|
|
209
|
+
const v = this.idsSorted[m];
|
|
210
|
+
assertValue(v, "Value is undefined");
|
|
211
|
+
if (v === id) {
|
|
212
|
+
if (this.idsAreSorted) return m;
|
|
213
|
+
const index = this.sortedIdPositionToIndex[m];
|
|
214
|
+
assertValue(index, "Position is undefined");
|
|
215
|
+
return index;
|
|
216
|
+
}
|
|
217
|
+
if (v < id) l = m + 1;
|
|
218
|
+
else r = m - 1;
|
|
219
|
+
}
|
|
221
220
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
while (l <= r) {
|
|
226
|
-
const m = (l + r) >>> 1
|
|
227
|
-
const v = this.idsSorted[m]
|
|
228
|
-
assertValue(v, "Value is undefined")
|
|
229
|
-
if (v === id) {
|
|
230
|
-
if (this.idsAreSorted) return m
|
|
231
|
-
const index = this.sortedIdPositionToIndex[m]
|
|
232
|
-
assertValue(index, "Position is undefined")
|
|
233
|
-
return index
|
|
234
|
-
}
|
|
235
|
-
if (v < id) l = m + 1
|
|
236
|
-
else r = m - 1
|
|
237
|
-
}
|
|
221
|
+
// ID not found
|
|
222
|
+
return -1;
|
|
223
|
+
}
|
|
238
224
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
225
|
+
/**
|
|
226
|
+
* Pass an ID or an index, get both.
|
|
227
|
+
*/
|
|
228
|
+
idOrIndex(i: IdOrIndex): [index: number, id: number] {
|
|
229
|
+
if ("id" in i) return [this.getIndexFromId(i.id), i.id];
|
|
230
|
+
return [i.index, this.at(i.index)];
|
|
231
|
+
}
|
|
242
232
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
if ("id" in i) return [this.getIndexFromId(i.id), i.id]
|
|
248
|
-
return [i.index, this.at(i.index)]
|
|
249
|
-
}
|
|
233
|
+
/** Returns the sorted array of IDs for iteration. */
|
|
234
|
+
get sorted() {
|
|
235
|
+
return this.idsSorted;
|
|
236
|
+
}
|
|
250
237
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
238
|
+
/** @internal Iterate sorted IDs with their original storage positions. */
|
|
239
|
+
*sortedEntries(): Generator<readonly [id: number, index: number]> {
|
|
240
|
+
for (let i = 0; i < this.idsSorted.length; i++) {
|
|
241
|
+
const id = this.idsSorted[i];
|
|
242
|
+
const index = this.sortedIdPositionToIndex[i];
|
|
243
|
+
assertValue(id, "Sorted ID is undefined");
|
|
244
|
+
assertValue(index, "Sorted position is undefined");
|
|
245
|
+
yield [id, index];
|
|
246
|
+
}
|
|
247
|
+
}
|
|
255
248
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
249
|
+
/**
|
|
250
|
+
* Get transferable buffers for passing to another thread.
|
|
251
|
+
* @returns Serializable representation of this index.
|
|
252
|
+
*/
|
|
253
|
+
transferables(): IdsTransferables {
|
|
254
|
+
return {
|
|
255
|
+
ids: this.ids.array.buffer,
|
|
256
|
+
sortedIds: this.idsSorted.buffer,
|
|
257
|
+
sortedIdPositionToIndex: this.sortedIdPositionToIndex.buffer,
|
|
258
|
+
anchors: this.anchors.buffer,
|
|
259
|
+
idsAreSorted: this.idsAreSorted,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
269
262
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
263
|
+
/**
|
|
264
|
+
* Get the approximate memory requirements for a given number of IDs in bytes.
|
|
265
|
+
*/
|
|
266
|
+
static getBytesRequired(count: number) {
|
|
267
|
+
if (count === 0) return 0;
|
|
268
|
+
return (
|
|
269
|
+
count * Float64Array.BYTES_PER_ELEMENT + // ids
|
|
270
|
+
count * Float64Array.BYTES_PER_ELEMENT + // sortedIds
|
|
271
|
+
count * Uint32Array.BYTES_PER_ELEMENT + // sortedIdPositionToIndex
|
|
272
|
+
Math.ceil(count / BLOCK_SIZE) * Float64Array.BYTES_PER_ELEMENT // anchors
|
|
273
|
+
);
|
|
274
|
+
}
|
|
282
275
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
276
|
+
/**
|
|
277
|
+
* Update a ContentHasher with the IDs data.
|
|
278
|
+
* Uses the sorted IDs for consistent hashing regardless of insertion order.
|
|
279
|
+
*/
|
|
280
|
+
updateHash(hasher: ContentHasher): ContentHasher {
|
|
281
|
+
return hasher.update(this.idsSorted);
|
|
282
|
+
}
|
|
290
283
|
}
|
package/src/index.ts
CHANGED
|
@@ -22,16 +22,19 @@
|
|
|
22
22
|
* @module @osmix/core
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
+
// oxlint-disable-next-line typescript/triple-slash-reference -- ambient module declarations for untyped packages
|
|
25
26
|
/// <reference path="./types/kdbush.d.ts" />
|
|
27
|
+
// oxlint-disable-next-line typescript/triple-slash-reference -- ambient module declarations for untyped packages
|
|
26
28
|
/// <reference path="./types/geokdbush.d.ts" />
|
|
29
|
+
// oxlint-disable-next-line typescript/triple-slash-reference -- ambient module declarations for untyped packages
|
|
27
30
|
/// <reference path="./types/geoflatbush.d.ts" />
|
|
28
31
|
|
|
29
|
-
export type { IdOrIndex } from "./ids.ts"
|
|
30
|
-
export
|
|
31
|
-
export * from "./nodes.ts"
|
|
32
|
-
export * from "./osm.ts"
|
|
33
|
-
export * from "./relations.ts"
|
|
34
|
-
export * from "./stringtable.ts"
|
|
35
|
-
export * from "./tags.ts"
|
|
36
|
-
export { BufferConstructor, type BufferType } from "./typed-arrays.ts"
|
|
37
|
-
export * from "./ways.ts"
|
|
32
|
+
export type { IdOrIndex } from "./ids.ts";
|
|
33
|
+
export type { OsmReader, OsmWriter } from "./contracts.ts";
|
|
34
|
+
export * from "./nodes.ts";
|
|
35
|
+
export * from "./osm.ts";
|
|
36
|
+
export * from "./relations.ts";
|
|
37
|
+
export * from "./stringtable.ts";
|
|
38
|
+
export * from "./tags.ts";
|
|
39
|
+
export { BufferConstructor, type BufferType } from "./typed-arrays.ts";
|
|
40
|
+
export * from "./ways.ts";
|