@osmix/core 0.0.1 → 0.0.6
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 +52 -0
- package/README.md +118 -107
- package/dist/core/src/entities.d.ts +114 -0
- package/dist/core/src/entities.d.ts.map +1 -0
- package/dist/core/src/entities.js +152 -0
- package/dist/core/src/entities.js.map +1 -0
- package/dist/core/src/ids.d.ts +113 -0
- package/dist/core/src/ids.d.ts.map +1 -0
- package/dist/core/src/ids.js +236 -0
- package/dist/core/src/ids.js.map +1 -0
- package/dist/core/src/index.d.ts +32 -0
- package/dist/core/src/index.d.ts.map +1 -0
- package/dist/core/src/index.js +35 -0
- package/dist/core/src/index.js.map +1 -0
- package/dist/core/src/nodes.d.ts +101 -0
- package/dist/core/src/nodes.d.ts.map +1 -0
- package/dist/core/src/nodes.js +309 -0
- package/dist/core/src/nodes.js.map +1 -0
- package/dist/core/src/osm.d.ts +74 -0
- package/dist/core/src/osm.d.ts.map +1 -0
- package/dist/core/src/osm.js +120 -0
- package/dist/core/src/osm.js.map +1 -0
- package/dist/core/src/relations.d.ts +118 -0
- package/dist/core/src/relations.d.ts.map +1 -0
- package/dist/core/src/relations.js +412 -0
- package/dist/core/src/relations.js.map +1 -0
- package/dist/core/src/stringtable.d.ts +95 -0
- package/dist/core/src/stringtable.d.ts.map +1 -0
- package/dist/core/src/stringtable.js +170 -0
- package/dist/core/src/stringtable.js.map +1 -0
- package/dist/core/src/tags.d.ts +126 -0
- package/dist/core/src/tags.d.ts.map +1 -0
- package/dist/core/src/tags.js +228 -0
- package/dist/core/src/tags.js.map +1 -0
- package/dist/core/src/typed-arrays.d.ts +124 -0
- package/dist/core/src/typed-arrays.d.ts.map +1 -0
- package/dist/core/src/typed-arrays.js +198 -0
- package/dist/core/src/typed-arrays.js.map +1 -0
- package/dist/core/src/utils.d.ts +11 -0
- package/dist/core/src/utils.d.ts.map +1 -0
- package/dist/core/src/utils.js +26 -0
- package/dist/core/src/utils.js.map +1 -0
- package/dist/core/src/ways.d.ts +101 -0
- package/dist/core/src/ways.d.ts.map +1 -0
- package/dist/core/src/ways.js +336 -0
- package/dist/core/src/ways.js.map +1 -0
- package/dist/core/test/memory.test.d.ts +7 -0
- package/dist/core/test/memory.test.d.ts.map +1 -0
- package/dist/core/test/memory.test.js +29 -0
- package/dist/core/test/memory.test.js.map +1 -0
- package/dist/core/test/mock-osm.d.ts +13 -0
- package/dist/core/test/mock-osm.d.ts.map +1 -0
- package/dist/core/test/mock-osm.js +122 -0
- package/dist/core/test/mock-osm.js.map +1 -0
- package/dist/core/test/tags-search.test.d.ts +2 -0
- package/dist/core/test/tags-search.test.d.ts.map +1 -0
- package/dist/core/test/tags-search.test.js +56 -0
- package/dist/core/test/tags-search.test.js.map +1 -0
- package/dist/core/test/typed-arrays.test.d.ts +2 -0
- package/dist/core/test/typed-arrays.test.d.ts.map +1 -0
- package/dist/core/test/typed-arrays.test.js +102 -0
- package/dist/core/test/typed-arrays.test.js.map +1 -0
- package/dist/osmix/src/extract.d.ts +43 -0
- package/dist/osmix/src/extract.d.ts.map +1 -0
- package/dist/osmix/src/extract.js +156 -0
- package/dist/osmix/src/extract.js.map +1 -0
- package/dist/osmix/src/pbf.d.ts +55 -0
- package/dist/osmix/src/pbf.d.ts.map +1 -0
- package/dist/osmix/src/pbf.js +187 -0
- package/dist/osmix/src/pbf.js.map +1 -0
- package/dist/osmix/src/utils.d.ts +36 -0
- package/dist/osmix/src/utils.d.ts.map +1 -0
- package/dist/osmix/src/utils.js +108 -0
- package/dist/osmix/src/utils.js.map +1 -0
- package/dist/osmix/test/extract.bench.d.ts +2 -0
- package/dist/osmix/test/extract.bench.d.ts.map +1 -0
- package/dist/osmix/test/extract.bench.js +26 -0
- package/dist/osmix/test/extract.bench.js.map +1 -0
- package/dist/osmix/test/extract.test.d.ts +2 -0
- package/dist/osmix/test/extract.test.d.ts.map +1 -0
- package/dist/osmix/test/extract.test.js +392 -0
- package/dist/osmix/test/extract.test.js.map +1 -0
- package/package.json +11 -11
- package/src/entities.ts +138 -22
- package/src/ids.ts +117 -45
- package/src/index.ts +34 -5
- package/src/nodes.ts +237 -58
- package/src/osm.ts +174 -0
- package/src/relations.ts +383 -54
- package/src/stringtable.ts +111 -36
- package/src/tags.ts +207 -46
- package/src/typed-arrays.ts +97 -10
- package/src/types/geoflatbush.d.ts +37 -0
- package/src/types/geokdbush.d.ts +37 -0
- package/src/types/kdbush.d.ts +24 -6
- package/src/utils.ts +9 -14
- package/src/ways.ts +248 -84
- package/test/memory.test.ts +38 -0
- package/test/mock-osm.ts +8 -8
- package/test/tags-search.test.ts +60 -0
- package/test/typed-arrays.test.ts +5 -6
- package/tsconfig.json +7 -1
- package/src/osmix.ts +0 -556
- package/test/extract.bench.ts +0 -29
- package/test/extract.test.ts +0 -156
- package/test/read.test.ts +0 -22
- package/test/write.test.ts +0 -66
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
import { assertValue } from "@osmix/shared/assert";
|
|
2
|
+
import { buildRelationLineStrings, collectRelationPoints, isAreaRelation, isLineRelation, isPointRelation, isSuperRelation, resolveRelationMembers, } from "@osmix/shared/relation-kind";
|
|
3
|
+
import { buildRelationRings } from "@osmix/shared/relation-multipolygon";
|
|
4
|
+
import Flatbush from "flatbush";
|
|
5
|
+
import { around as geoAround } from "geoflatbush";
|
|
6
|
+
import { Entities } from "./entities";
|
|
7
|
+
import { Ids } from "./ids";
|
|
8
|
+
import { Tags } from "./tags";
|
|
9
|
+
import { BufferConstructor, IdArrayType, ResizeableTypedArray as RTA, } from "./typed-arrays";
|
|
10
|
+
import { bboxFromLonLats } from "./utils";
|
|
11
|
+
const RELATION_MEMBER_TYPES = ["node", "way", "relation"];
|
|
12
|
+
export class Relations extends Entities {
|
|
13
|
+
stringTable;
|
|
14
|
+
memberStart;
|
|
15
|
+
memberCount; // Maximum 65,535 members per relation
|
|
16
|
+
// Store the ID of the member because relations have other relations as members.
|
|
17
|
+
memberRefs;
|
|
18
|
+
memberTypes;
|
|
19
|
+
memberRoles;
|
|
20
|
+
// Spatial index
|
|
21
|
+
spatialIndex = new Flatbush(1);
|
|
22
|
+
// Track if spatial index was properly built (vs default empty)
|
|
23
|
+
spatialIndexBuilt = false;
|
|
24
|
+
// Bounding box of the relation in geographic coordinates
|
|
25
|
+
bbox;
|
|
26
|
+
// Node and Way indexes
|
|
27
|
+
nodes;
|
|
28
|
+
ways;
|
|
29
|
+
/**
|
|
30
|
+
* Create a new Relations index.
|
|
31
|
+
*/
|
|
32
|
+
constructor(stringTable, nodes, ways, transferables) {
|
|
33
|
+
if (transferables) {
|
|
34
|
+
super("relation", new Ids(transferables), new Tags(stringTable, transferables));
|
|
35
|
+
this.memberStart = RTA.from(Uint32Array, transferables.memberStart);
|
|
36
|
+
this.memberCount = RTA.from(Uint16Array, transferables.memberCount);
|
|
37
|
+
this.memberRefs = RTA.from(IdArrayType, transferables.memberRefs);
|
|
38
|
+
this.memberTypes = RTA.from(Uint8Array, transferables.memberTypes);
|
|
39
|
+
this.memberRoles = RTA.from(Uint32Array, transferables.memberRoles);
|
|
40
|
+
this.bbox = RTA.from(Float64Array, transferables.bbox);
|
|
41
|
+
// Only load spatial index if provided (not stored in IndexedDB)
|
|
42
|
+
if (transferables.spatialIndex?.byteLength) {
|
|
43
|
+
this.spatialIndex = Flatbush.from(transferables.spatialIndex);
|
|
44
|
+
this.spatialIndexBuilt = true;
|
|
45
|
+
}
|
|
46
|
+
this.indexBuilt = true;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
super("relation", new Ids(), new Tags(stringTable));
|
|
50
|
+
this.memberStart = new RTA(Uint32Array);
|
|
51
|
+
this.memberCount = new RTA(Uint16Array);
|
|
52
|
+
this.memberRefs = new RTA(IdArrayType);
|
|
53
|
+
this.memberTypes = new RTA(Uint8Array);
|
|
54
|
+
this.memberRoles = new RTA(Uint32Array);
|
|
55
|
+
this.bbox = new RTA(Float64Array);
|
|
56
|
+
}
|
|
57
|
+
this.nodes = nodes;
|
|
58
|
+
this.ways = ways;
|
|
59
|
+
this.stringTable = stringTable;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Add a single relation to the index.
|
|
63
|
+
*/
|
|
64
|
+
addRelation(relation) {
|
|
65
|
+
const relationIndex = this.addEntity(relation.id, relation.tags ?? {});
|
|
66
|
+
this.memberStart.push(this.memberRefs.length);
|
|
67
|
+
this.memberCount.push(relation.members.length);
|
|
68
|
+
for (const member of relation.members) {
|
|
69
|
+
this.memberRefs.push(member.ref);
|
|
70
|
+
this.memberTypes.push(RELATION_MEMBER_TYPES.indexOf(member.type));
|
|
71
|
+
this.memberRoles.push(this.stringTable.add(member.role ?? ""));
|
|
72
|
+
}
|
|
73
|
+
return relationIndex;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Bulk add relations directly from a PBF PrimitiveBlock.
|
|
77
|
+
*/
|
|
78
|
+
addRelations(relations, blockStringIndexMap, filter) {
|
|
79
|
+
const blockToStringTable = (k) => {
|
|
80
|
+
const index = blockStringIndexMap[k];
|
|
81
|
+
if (index === undefined)
|
|
82
|
+
throw Error("Tag key not found");
|
|
83
|
+
return index;
|
|
84
|
+
};
|
|
85
|
+
let added = 0;
|
|
86
|
+
for (const relation of relations) {
|
|
87
|
+
const members = [];
|
|
88
|
+
const memberRefs = [];
|
|
89
|
+
const memberTypes = [];
|
|
90
|
+
const memberRoles = [];
|
|
91
|
+
let refId = 0;
|
|
92
|
+
for (let i = 0; i < relation.memids.length; i++) {
|
|
93
|
+
const memid = relation.memids[i];
|
|
94
|
+
const roleSid = relation.roles_sid[i];
|
|
95
|
+
const typeIndex = relation.types[i];
|
|
96
|
+
assertValue(memid, "Relation member ID is undefined");
|
|
97
|
+
assertValue(roleSid, "Relation member role SID is undefined");
|
|
98
|
+
assertValue(typeIndex, "Relation member type is undefined");
|
|
99
|
+
refId += memid;
|
|
100
|
+
const roleIndex = blockToStringTable(roleSid);
|
|
101
|
+
const type = RELATION_MEMBER_TYPES[typeIndex];
|
|
102
|
+
assertValue(type, "Relation member type not found");
|
|
103
|
+
if (filter) {
|
|
104
|
+
members.push({
|
|
105
|
+
type,
|
|
106
|
+
ref: refId,
|
|
107
|
+
role: this.stringTable.get(roleIndex),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
memberRefs.push(refId);
|
|
111
|
+
memberTypes.push(typeIndex);
|
|
112
|
+
memberRoles.push(roleIndex);
|
|
113
|
+
}
|
|
114
|
+
const tagKeys = relation.keys.map(blockToStringTable);
|
|
115
|
+
const tagValues = relation.vals.map(blockToStringTable);
|
|
116
|
+
const filteredRelation = filter
|
|
117
|
+
? filter({
|
|
118
|
+
id: relation.id,
|
|
119
|
+
members,
|
|
120
|
+
tags: this.tags.getTagsFromIndices(tagKeys, tagValues),
|
|
121
|
+
})
|
|
122
|
+
: null;
|
|
123
|
+
if (filter && filteredRelation === null)
|
|
124
|
+
continue;
|
|
125
|
+
added++;
|
|
126
|
+
this.addEntity(relation.id, tagKeys, tagValues);
|
|
127
|
+
this.memberStart.push(this.memberRefs.length);
|
|
128
|
+
this.memberCount.push(filteredRelation?.members.length ?? memberRefs.length);
|
|
129
|
+
this.memberRefs.pushMany(filteredRelation?.members.map((m) => m.ref) ?? memberRefs);
|
|
130
|
+
this.memberTypes.pushMany(filteredRelation?.members.map((m) => RELATION_MEMBER_TYPES.indexOf(m.type)) ?? memberTypes);
|
|
131
|
+
this.memberRoles.pushMany(filteredRelation?.members.map((m) => this.stringTable.add(m.role ?? "")) ?? memberRoles);
|
|
132
|
+
}
|
|
133
|
+
return added;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Compact the internal arrays to free up memory.
|
|
137
|
+
*/
|
|
138
|
+
buildEntityIndex() {
|
|
139
|
+
this.memberStart.compact();
|
|
140
|
+
this.memberCount.compact();
|
|
141
|
+
this.memberRefs.compact();
|
|
142
|
+
this.memberTypes.compact();
|
|
143
|
+
this.memberRoles.compact();
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Build the spatial index for relations.
|
|
147
|
+
* Handles nested relations by resolving all descendant nodes and ways.
|
|
148
|
+
* If bbox data already exists (e.g., loaded from storage), reuses it.
|
|
149
|
+
*/
|
|
150
|
+
buildSpatialIndex() {
|
|
151
|
+
if (!this.nodes.isReady())
|
|
152
|
+
throw Error("Node index is not ready.");
|
|
153
|
+
if (!this.ways.isReady())
|
|
154
|
+
throw Error("Way index is not ready.");
|
|
155
|
+
if (this.size === 0)
|
|
156
|
+
return this.spatialIndex;
|
|
157
|
+
console.time("RelationIndex.buildSpatialIndex");
|
|
158
|
+
this.spatialIndex = new Flatbush(this.size, 128, Float64Array, BufferConstructor);
|
|
159
|
+
// If bbox already has data (loaded from storage), use it directly
|
|
160
|
+
const hasBboxData = this.bbox.length >= this.size * 4;
|
|
161
|
+
for (let i = 0; i < this.size; i++) {
|
|
162
|
+
let minX;
|
|
163
|
+
let minY;
|
|
164
|
+
let maxX;
|
|
165
|
+
let maxY;
|
|
166
|
+
if (hasBboxData) {
|
|
167
|
+
// Use stored bbox values
|
|
168
|
+
minX = this.bbox.at(i * 4);
|
|
169
|
+
minY = this.bbox.at(i * 4 + 1);
|
|
170
|
+
maxX = this.bbox.at(i * 4 + 2);
|
|
171
|
+
maxY = this.bbox.at(i * 4 + 3);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
// Calculate bbox from coordinates
|
|
175
|
+
const lls = this.collectRelationCoordinates(i);
|
|
176
|
+
const bbox = bboxFromLonLats(lls);
|
|
177
|
+
minX = bbox[0];
|
|
178
|
+
minY = bbox[1];
|
|
179
|
+
maxX = bbox[2];
|
|
180
|
+
maxY = bbox[3];
|
|
181
|
+
this.bbox.push(minX);
|
|
182
|
+
this.bbox.push(minY);
|
|
183
|
+
this.bbox.push(maxX);
|
|
184
|
+
this.bbox.push(maxY);
|
|
185
|
+
}
|
|
186
|
+
this.spatialIndex.add(minX, minY, maxX, maxY);
|
|
187
|
+
}
|
|
188
|
+
if (!hasBboxData) {
|
|
189
|
+
this.bbox.compact();
|
|
190
|
+
}
|
|
191
|
+
this.spatialIndex.finish();
|
|
192
|
+
this.spatialIndexBuilt = true;
|
|
193
|
+
console.timeEnd("RelationIndex.buildSpatialIndex");
|
|
194
|
+
return this.spatialIndex;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Check if the spatial index has been built.
|
|
198
|
+
*/
|
|
199
|
+
hasSpatialIndex() {
|
|
200
|
+
return this.spatialIndexBuilt;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Collect all coordinates from a relation, including nested relations.
|
|
204
|
+
* Used for building bounding boxes and spatial indexes.
|
|
205
|
+
*/
|
|
206
|
+
collectRelationCoordinates(index) {
|
|
207
|
+
const lls = [];
|
|
208
|
+
const relation = this.getByIndex(index);
|
|
209
|
+
// Resolve nested relations to get all descendant nodes and ways
|
|
210
|
+
const resolved = resolveRelationMembers(relation, (relId) => {
|
|
211
|
+
const relIndex = this.ids.getIndexFromId(relId);
|
|
212
|
+
if (relIndex === -1)
|
|
213
|
+
return null;
|
|
214
|
+
return this.getByIndex(relIndex);
|
|
215
|
+
}, 10);
|
|
216
|
+
// Collect coordinates from resolved nodes
|
|
217
|
+
for (const nodeId of resolved.nodes) {
|
|
218
|
+
const ll = this.nodes.getNodeLonLat({ id: nodeId });
|
|
219
|
+
if (ll)
|
|
220
|
+
lls.push(ll);
|
|
221
|
+
}
|
|
222
|
+
// Collect coordinates from resolved ways
|
|
223
|
+
for (const wayId of resolved.ways) {
|
|
224
|
+
const wayIndex = this.ways.ids.getIndexFromId(wayId);
|
|
225
|
+
if (wayIndex === -1)
|
|
226
|
+
continue;
|
|
227
|
+
const wayPositions = this.ways.getCoordinates(wayIndex);
|
|
228
|
+
lls.push(...wayPositions);
|
|
229
|
+
}
|
|
230
|
+
return lls;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Get the bounding box of a relation.
|
|
234
|
+
*/
|
|
235
|
+
getEntityBbox(i) {
|
|
236
|
+
const index = "index" in i ? i.index : this.ids.idOrIndex(i)[0];
|
|
237
|
+
return [
|
|
238
|
+
this.bbox.at(index * 4),
|
|
239
|
+
this.bbox.at(index * 4 + 1),
|
|
240
|
+
this.bbox.at(index * 4 + 2),
|
|
241
|
+
this.bbox.at(index * 4 + 3),
|
|
242
|
+
];
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Get the full relation entity.
|
|
246
|
+
*/
|
|
247
|
+
getFullEntity(index, id, tags) {
|
|
248
|
+
return {
|
|
249
|
+
id,
|
|
250
|
+
members: this.getMembersByIndex(index),
|
|
251
|
+
tags,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Get the members of a relation.
|
|
256
|
+
*/
|
|
257
|
+
getMembersByIndex(index, relationMemberTypes = RELATION_MEMBER_TYPES) {
|
|
258
|
+
const start = this.memberStart.at(index);
|
|
259
|
+
const count = this.memberCount.at(index);
|
|
260
|
+
const members = [];
|
|
261
|
+
for (let i = start; i < start + count; i++) {
|
|
262
|
+
const ref = this.memberRefs.at(i);
|
|
263
|
+
const type = RELATION_MEMBER_TYPES[this.memberTypes.at(i)];
|
|
264
|
+
if (type === undefined)
|
|
265
|
+
throw Error(`Member type not found: ${i}`);
|
|
266
|
+
if (!relationMemberTypes.includes(type))
|
|
267
|
+
continue;
|
|
268
|
+
const role = this.stringTable.get(this.memberRoles.at(i));
|
|
269
|
+
members.push({ ref, type, role });
|
|
270
|
+
}
|
|
271
|
+
return members;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Check if a relation includes a specific member.
|
|
275
|
+
*/
|
|
276
|
+
includesMember(index, memberRef, memberType, memberRole) {
|
|
277
|
+
const start = this.memberStart.at(index);
|
|
278
|
+
const count = this.memberCount.at(index);
|
|
279
|
+
for (let i = start; i < start + count; i++) {
|
|
280
|
+
const type = RELATION_MEMBER_TYPES[this.memberTypes.at(i)];
|
|
281
|
+
if (type !== memberType)
|
|
282
|
+
continue;
|
|
283
|
+
const ref = this.memberRefs.at(i);
|
|
284
|
+
if (ref !== memberRef)
|
|
285
|
+
continue;
|
|
286
|
+
if (memberRole !== undefined &&
|
|
287
|
+
this.stringTable.get(this.memberRoles.at(i)) !== memberRole)
|
|
288
|
+
continue;
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Get all way IDs that are members of relations, including nested relations.
|
|
295
|
+
* Used to exclude these ways from individual rendering.
|
|
296
|
+
*/
|
|
297
|
+
getWayMemberIds() {
|
|
298
|
+
const wayIds = new Set();
|
|
299
|
+
for (let i = 0; i < this.size; i++) {
|
|
300
|
+
const relation = this.getByIndex(i);
|
|
301
|
+
const resolved = resolveRelationMembers(relation, (relId) => {
|
|
302
|
+
const relIndex = this.ids.getIndexFromId(relId);
|
|
303
|
+
if (relIndex === -1)
|
|
304
|
+
return null;
|
|
305
|
+
return this.getByIndex(relIndex);
|
|
306
|
+
}, 10);
|
|
307
|
+
for (const wayId of resolved.ways) {
|
|
308
|
+
wayIds.add(wayId);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return wayIds;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Get relation geometry based on its kind.
|
|
315
|
+
* Returns coordinates suitable for rendering based on relation type.
|
|
316
|
+
* @param index - Relation index
|
|
317
|
+
* @returns Object with geometry data based on relation kind
|
|
318
|
+
*/
|
|
319
|
+
getRelationGeometry(index) {
|
|
320
|
+
const relation = this.getByIndex(index);
|
|
321
|
+
if (isAreaRelation(relation)) {
|
|
322
|
+
return {
|
|
323
|
+
rings: buildRelationRings(relation, (ref) => this.ways.getById(ref), (id) => this.nodes.getNodeLonLat({ id })),
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
// Point relations
|
|
327
|
+
if (isPointRelation(relation)) {
|
|
328
|
+
return {
|
|
329
|
+
points: collectRelationPoints(relation, (id) => this.nodes.getNodeLonLat({ id })),
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
// Line relations
|
|
333
|
+
if (isLineRelation(relation)) {
|
|
334
|
+
return {
|
|
335
|
+
lineStrings: buildRelationLineStrings(relation, (ref) => this.ways.getById(ref), (id) => this.nodes.getNodeLonLat({ id })),
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
// Super relations are handled by individual relation geometry methods
|
|
339
|
+
if (isSuperRelation(relation)) {
|
|
340
|
+
return {};
|
|
341
|
+
}
|
|
342
|
+
// Area relations are handled by buildRelationRings in shared/relation-multipolygon
|
|
343
|
+
// This method doesn't duplicate that logic
|
|
344
|
+
return {};
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Find relations that intersect a bounding box.
|
|
348
|
+
*/
|
|
349
|
+
intersects(bbox, filterFn) {
|
|
350
|
+
if (this.size === 0)
|
|
351
|
+
return [];
|
|
352
|
+
return this.spatialIndex.search(bbox[0], bbox[1], bbox[2], bbox[3], filterFn);
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Find relation indexes near a point using great-circle distance.
|
|
356
|
+
* @param lon - Longitude in degrees.
|
|
357
|
+
* @param lat - Latitude in degrees.
|
|
358
|
+
* @param maxResults - Maximum number of results to return.
|
|
359
|
+
* @param maxDistanceKm - Maximum distance in kilometers.
|
|
360
|
+
* @returns Array of relation indexes sorted by distance.
|
|
361
|
+
*/
|
|
362
|
+
neighbors(lon, lat, maxResults, maxDistanceKm) {
|
|
363
|
+
if (this.size === 0)
|
|
364
|
+
return [];
|
|
365
|
+
// Use geoflatbush for proper geographic distance calculations
|
|
366
|
+
return geoAround(this.spatialIndex, lon, lat, maxResults, maxDistanceKm);
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Get transferable objects for passing to another thread.
|
|
370
|
+
* Only includes spatialIndex if it has been built.
|
|
371
|
+
*/
|
|
372
|
+
transferables() {
|
|
373
|
+
const base = {
|
|
374
|
+
...super.transferables(),
|
|
375
|
+
memberStart: this.memberStart.array.buffer,
|
|
376
|
+
memberCount: this.memberCount.array.buffer,
|
|
377
|
+
memberRefs: this.memberRefs.array.buffer,
|
|
378
|
+
memberTypes: this.memberTypes.array.buffer,
|
|
379
|
+
memberRoles: this.memberRoles.array.buffer,
|
|
380
|
+
bbox: this.bbox.array.buffer,
|
|
381
|
+
};
|
|
382
|
+
// Only include spatial index if it was built
|
|
383
|
+
if (this.spatialIndexBuilt) {
|
|
384
|
+
return { ...base, spatialIndex: this.spatialIndex.data };
|
|
385
|
+
}
|
|
386
|
+
return base;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Get the approximate memory requirements for a given number of relations in bytes.
|
|
390
|
+
*/
|
|
391
|
+
static getBytesRequired(count) {
|
|
392
|
+
if (count === 0)
|
|
393
|
+
return 0;
|
|
394
|
+
// Approximate members per relation
|
|
395
|
+
let numNodes = count;
|
|
396
|
+
let n = count;
|
|
397
|
+
while (n !== 1) {
|
|
398
|
+
n = Math.ceil(n / 128);
|
|
399
|
+
numNodes += n;
|
|
400
|
+
}
|
|
401
|
+
const indexBytes = (numNodes < 16384 ? 2 : 4) * numNodes;
|
|
402
|
+
const boxesBytes = numNodes * 4 * Float64Array.BYTES_PER_ELEMENT;
|
|
403
|
+
const spatialIndexBytes = 8 + indexBytes + boxesBytes;
|
|
404
|
+
return (Ids.getBytesRequired(count) +
|
|
405
|
+
Tags.getBytesRequired(count) +
|
|
406
|
+
count * Uint32Array.BYTES_PER_ELEMENT + // memberStart
|
|
407
|
+
count * Uint16Array.BYTES_PER_ELEMENT + // memberCount
|
|
408
|
+
count * 4 * Float64Array.BYTES_PER_ELEMENT + // bbox
|
|
409
|
+
spatialIndexBytes);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
//# sourceMappingURL=relations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relations.js","sourceRoot":"","sources":["../../../src/relations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deduplicated UTF-8 string storage.
|
|
3
|
+
*
|
|
4
|
+
* Strings are stored in a flat buffer and referenced by index.
|
|
5
|
+
* Supports fast deduplication (string→index) and lazy reconstruction (index→string).
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import type { OsmPbfStringTable } from "@osmix/pbf";
|
|
10
|
+
import { type BufferType, ResizeableTypedArray as RTA } from "./typed-arrays";
|
|
11
|
+
/**
|
|
12
|
+
* Serializable state for worker transfer.
|
|
13
|
+
*/
|
|
14
|
+
export interface StringTableTransferables<T extends BufferType = BufferType> {
|
|
15
|
+
/** Concatenated UTF-8 bytes. */
|
|
16
|
+
bytes: T;
|
|
17
|
+
/** Maps string index → byte offset. */
|
|
18
|
+
start: T;
|
|
19
|
+
/** Maps string index → byte length. */
|
|
20
|
+
count: T;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Append-only deduplicated string table.
|
|
24
|
+
*
|
|
25
|
+
* Limits: Max string length 65,535 bytes.
|
|
26
|
+
* Rebuilds reverse index lazily after transfer.
|
|
27
|
+
*/
|
|
28
|
+
export default class StringTable {
|
|
29
|
+
/** UTF-8 encoder for string→bytes conversion */
|
|
30
|
+
private enc;
|
|
31
|
+
/** UTF-8 decoder for bytes→string conversion */
|
|
32
|
+
private dec;
|
|
33
|
+
/** Concatenated UTF-8 bytes of all strings */
|
|
34
|
+
bytes: RTA<Uint8Array>;
|
|
35
|
+
/** Maps string index → byte offset in bytes array */
|
|
36
|
+
start: RTA<Uint32Array>;
|
|
37
|
+
/** Maps string index → byte length */
|
|
38
|
+
count: RTA<Uint16Array>;
|
|
39
|
+
/** Forward lookup: string → index (populated during add) */
|
|
40
|
+
private stringToIndex;
|
|
41
|
+
/** Whether the reverse index has been built (lazy after transfer) */
|
|
42
|
+
private reverseIndexBuilt;
|
|
43
|
+
/** Cache of decoded strings to avoid repeated UTF-8 decoding */
|
|
44
|
+
private indexToString;
|
|
45
|
+
/**
|
|
46
|
+
* Create a new StringTable.
|
|
47
|
+
*/
|
|
48
|
+
constructor(opts?: StringTableTransferables);
|
|
49
|
+
/**
|
|
50
|
+
* Get transferable objects for passing to another thread.
|
|
51
|
+
*/
|
|
52
|
+
transferables(): StringTableTransferables;
|
|
53
|
+
/**
|
|
54
|
+
* Add a string to the table and return its index.
|
|
55
|
+
*/
|
|
56
|
+
add(str: string): number;
|
|
57
|
+
/**
|
|
58
|
+
* Decode all the strings in a primitive block and add them to the string table.
|
|
59
|
+
* Return a mapping of block index -> string table index
|
|
60
|
+
*/
|
|
61
|
+
createBlockIndexMap(blockStringtable: OsmPbfStringTable): Uint32Array<ArrayBuffer>;
|
|
62
|
+
/**
|
|
63
|
+
* Get a string by its index.
|
|
64
|
+
* Caches results to avoid repeated UTF-8 decoding.
|
|
65
|
+
*/
|
|
66
|
+
get(index: number): string;
|
|
67
|
+
/**
|
|
68
|
+
* Get the raw UTF-8 bytes of a string.
|
|
69
|
+
* Returns a subarray view (not a copy).
|
|
70
|
+
*/
|
|
71
|
+
getBytes(index: number): Uint8Array;
|
|
72
|
+
/** Number of strings in the table. */
|
|
73
|
+
get length(): number;
|
|
74
|
+
/**
|
|
75
|
+
* Finalize the string table by compacting internal arrays.
|
|
76
|
+
*
|
|
77
|
+
* This releases unused buffer capacity and marks the reverse index as built
|
|
78
|
+
* (since all strings were added before this call).
|
|
79
|
+
*/
|
|
80
|
+
buildIndex(): void;
|
|
81
|
+
/**
|
|
82
|
+
* Convert the string table to an OSM PBF string table.
|
|
83
|
+
*/
|
|
84
|
+
toOsmPbfStringTable(): OsmPbfStringTable;
|
|
85
|
+
/**
|
|
86
|
+
* Lazily build the reverse index (string → index).
|
|
87
|
+
* Decodes all strings once to populate the lookup map.
|
|
88
|
+
*/
|
|
89
|
+
private ensureReverseIndex;
|
|
90
|
+
/**
|
|
91
|
+
* Find the index of a string.
|
|
92
|
+
*/
|
|
93
|
+
find(str: string): number;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=stringtable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stringtable.d.ts","sourceRoot":"","sources":["../../../src/stringtable.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AACnD,OAAO,EAAE,KAAK,UAAU,EAAE,oBAAoB,IAAI,GAAG,EAAE,MAAM,gBAAgB,CAAA;AAE7E;;GAEG;AACH,MAAM,WAAW,wBAAwB,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU;IAC1E,gCAAgC;IAChC,KAAK,EAAE,CAAC,CAAA;IACR,uCAAuC;IACvC,KAAK,EAAE,CAAC,CAAA;IACR,uCAAuC;IACvC,KAAK,EAAE,CAAC,CAAA;CACR;AAED;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,WAAW;IAC/B,gDAAgD;IAChD,OAAO,CAAC,GAAG,CAAoB;IAC/B,gDAAgD;IAChD,OAAO,CAAC,GAAG,CAAoB;IAG/B,8CAA8C;IAC9C,KAAK,EAAE,GAAG,CAAC,UAAU,CAAC,CAAA;IACtB,qDAAqD;IACrD,KAAK,EAAE,GAAG,CAAC,WAAW,CAAC,CAAA;IACvB,sCAAsC;IACtC,KAAK,EAAE,GAAG,CAAC,WAAW,CAAC,CAAA;IAGvB,4DAA4D;IAC5D,OAAO,CAAC,aAAa,CAA4B;IAEjD,qEAAqE;IACrE,OAAO,CAAC,iBAAiB,CAAQ;IAGjC,gEAAgE;IAChE,OAAO,CAAC,aAAa,CAA4B;IAEjD;;OAEG;gBACS,IAAI,CAAC,EAAE,wBAAwB;IAY3C;;OAEG;IACH,aAAa,IAAI,wBAAwB;IAQzC;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAYxB;;;OAGG;IACH,mBAAmB,CAAC,gBAAgB,EAAE,iBAAiB;IAevD;;;OAGG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAY1B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU;IAQnC,sCAAsC;IACtC,IAAI,MAAM,WAET;IAED;;;;;OAKG;IACH,UAAU;IAOV;;OAEG;IACH,mBAAmB,IAAI,iBAAiB;IAQxC;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAS1B;;OAEG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CAMzB"}
|