@osmix/core 0.0.2 → 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 +42 -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/{src → core/src}/ids.js +96 -31
- 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/{src → core/src}/typed-arrays.js +88 -9
- 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/{src → core/src}/utils.js +8 -10
- 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/{test → core/test}/mock-osm.d.ts +3 -3
- package/dist/core/test/mock-osm.d.ts.map +1 -0
- package/dist/{test → core/test}/mock-osm.js +3 -3
- 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.map +1 -0
- package/dist/{test → core/test}/typed-arrays.test.js +19 -17
- 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.map +1 -0
- package/dist/{test → osmix/test}/extract.bench.js +8 -5
- package/dist/osmix/test/extract.bench.js.map +1 -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 +10 -12
- 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/dist/src/entities.d.ts +0 -26
- package/dist/src/entities.d.ts.map +0 -1
- package/dist/src/entities.js +0 -69
- package/dist/src/entities.js.map +0 -1
- package/dist/src/ids.d.ts +0 -50
- package/dist/src/ids.d.ts.map +0 -1
- package/dist/src/ids.js.map +0 -1
- package/dist/src/index.d.ts +0 -6
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/index.js +0 -7
- package/dist/src/index.js.map +0 -1
- package/dist/src/nodes.d.ts +0 -36
- package/dist/src/nodes.d.ts.map +0 -1
- package/dist/src/nodes.js +0 -171
- package/dist/src/nodes.js.map +0 -1
- package/dist/src/osmix.d.ts +0 -88
- package/dist/src/osmix.d.ts.map +0 -1
- package/dist/src/osmix.js +0 -438
- package/dist/src/osmix.js.map +0 -1
- package/dist/src/relations.d.ts +0 -31
- package/dist/src/relations.d.ts.map +0 -1
- package/dist/src/relations.js +0 -161
- package/dist/src/relations.js.map +0 -1
- package/dist/src/stringtable.d.ts +0 -37
- package/dist/src/stringtable.d.ts.map +0 -1
- package/dist/src/stringtable.js +0 -101
- package/dist/src/stringtable.js.map +0 -1
- package/dist/src/tags.d.ts +0 -33
- package/dist/src/tags.d.ts.map +0 -1
- package/dist/src/tags.js +0 -92
- package/dist/src/tags.js.map +0 -1
- package/dist/src/typed-arrays.d.ts +0 -50
- package/dist/src/typed-arrays.d.ts.map +0 -1
- package/dist/src/typed-arrays.js.map +0 -1
- package/dist/src/utils.d.ts +0 -4
- package/dist/src/utils.d.ts.map +0 -1
- package/dist/src/utils.js.map +0 -1
- package/dist/src/ways.d.ts +0 -42
- package/dist/src/ways.d.ts.map +0 -1
- package/dist/src/ways.js +0 -186
- package/dist/src/ways.js.map +0 -1
- package/dist/test/extract.bench.d.ts.map +0 -1
- package/dist/test/extract.bench.js.map +0 -1
- package/dist/test/extract.test.d.ts.map +0 -1
- package/dist/test/extract.test.js +0 -127
- package/dist/test/extract.test.js.map +0 -1
- package/dist/test/mock-osm.d.ts.map +0 -1
- package/dist/test/mock-osm.js.map +0 -1
- package/dist/test/read.test.d.ts +0 -2
- package/dist/test/read.test.d.ts.map +0 -1
- package/dist/test/read.test.js +0 -17
- package/dist/test/read.test.js.map +0 -1
- package/dist/test/typed-arrays.test.d.ts.map +0 -1
- package/dist/test/typed-arrays.test.js.map +0 -1
- package/dist/test/write.test.d.ts +0 -2
- package/dist/test/write.test.d.ts.map +0 -1
- package/dist/test/write.test.js +0 -55
- package/dist/test/write.test.js.map +0 -1
- package/src/osmix.ts +0 -556
- package/test/extract.bench.ts +0 -29
- package/test/extract.test.ts +0 -161
- package/test/read.test.ts +0 -22
- package/test/write.test.ts +0 -69
- /package/dist/{test → core/test}/typed-arrays.test.d.ts +0 -0
- /package/dist/{test → osmix/test}/extract.bench.d.ts +0 -0
- /package/dist/{test → osmix/test}/extract.test.d.ts +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,47 @@
|
|
|
1
1
|
# @osmix/core
|
|
2
2
|
|
|
3
|
+
## 0.0.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 3846a0c: Integrate geographic spatial indexing libraries
|
|
8
|
+
- cdab4db: Add router
|
|
9
|
+
- Updated dependencies [0cd8a2e]
|
|
10
|
+
- @osmix/shared@0.0.6
|
|
11
|
+
|
|
12
|
+
## 0.0.5
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- a33a280: Create an easy way to estimate bytes required for a given OSM size
|
|
17
|
+
- edbb26b: Handle more Relation types
|
|
18
|
+
- 69a36bd: Switch Nodes coordinate storage to Int32Array
|
|
19
|
+
- Updated dependencies [bb629cf]
|
|
20
|
+
- Updated dependencies [edbb26b]
|
|
21
|
+
- Updated dependencies [69a36bd]
|
|
22
|
+
- @osmix/shared@0.0.5
|
|
23
|
+
|
|
24
|
+
## 0.0.4
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- d001d9a: Refactor to align around new main external API
|
|
29
|
+
- 4303c40: Refactor core Osmix index to prepare for future work
|
|
30
|
+
- Updated dependencies [572cbd8]
|
|
31
|
+
- Updated dependencies [d001d9a]
|
|
32
|
+
- @osmix/shared@0.0.4
|
|
33
|
+
|
|
34
|
+
## 0.0.3
|
|
35
|
+
|
|
36
|
+
### Patch Changes
|
|
37
|
+
|
|
38
|
+
- b4a3ff2: Improve Relation handling and display
|
|
39
|
+
- c0193dd: Import GeoJSON into Osmix
|
|
40
|
+
- Updated dependencies [b4a3ff2]
|
|
41
|
+
- @osmix/shared@0.0.3
|
|
42
|
+
- @osmix/json@0.0.3
|
|
43
|
+
- @osmix/pbf@0.0.2
|
|
44
|
+
|
|
3
45
|
## 0.0.2
|
|
4
46
|
|
|
5
47
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,160 +1,171 @@
|
|
|
1
1
|
# @osmix/core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
In-memory OSM entity storage with spatial indexing. Provides core data structures for efficiently storing and querying OpenStreetMap nodes, ways, and relations.
|
|
4
4
|
|
|
5
5
|
## Highlights
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
7
|
+
- **Memory-efficient**: Typed arrays and microdegree coordinates (`Int32Array`) minimize memory while maintaining precision.
|
|
8
|
+
- **Spatial indexing**: KDBush (points) and Flatbush (bboxes) for fast geographic queries. Supports bbox and radius searches via geokdbush/geoflatbush.
|
|
9
|
+
- **Worker-ready**: Serialize to `ArrayBuffer`/`SharedArrayBuffer` for zero-copy transfer via `transferables()`.
|
|
10
|
+
- **Tag search**: Reverse-index lookup for fast entity searches by tag key.
|
|
11
|
+
- **Streaming**: Iterate entities or sorted-by-ID without materializing full arrays.
|
|
12
12
|
|
|
13
13
|
## Installation
|
|
14
14
|
|
|
15
15
|
```sh
|
|
16
|
-
|
|
16
|
+
bun add @osmix/core
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
## Usage
|
|
20
20
|
|
|
21
|
-
###
|
|
21
|
+
### Loading PBF files
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
import { Osmix } from "@osmix/core"
|
|
25
|
-
import { readFile } from "node:fs/promises"
|
|
23
|
+
`@osmix/core` provides the in-memory data structures. To parse `.osm.pbf` files, use the high-level `osmix` package:
|
|
26
24
|
|
|
27
|
-
|
|
25
|
+
```ts
|
|
26
|
+
import { fromPbf } from "osmix"
|
|
28
27
|
|
|
28
|
+
const osm = await fromPbf(Bun.file("./monaco.pbf").stream())
|
|
29
29
|
console.log(osm.nodes.size, osm.ways.size, osm.relations.size)
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
### Building data directly
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Pass a logger or set one later to receive throttled progress messages. Provide `extractBbox` to keep only features intersecting the desired bounds while parsing.
|
|
34
|
+
For synthetic data or tests, instantiate `Osm` directly and call `buildIndexes()` / `buildSpatialIndexes()` before querying:
|
|
37
35
|
|
|
38
36
|
```ts
|
|
39
|
-
import {
|
|
40
|
-
import { createReadStream } from "node:fs"
|
|
37
|
+
import { Osm } from "@osmix/core"
|
|
41
38
|
|
|
42
|
-
const osm = new
|
|
43
|
-
osm.setLogger((message) => console.log(message))
|
|
39
|
+
const osm = new Osm({ id: "fixture" })
|
|
44
40
|
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
osm.nodes.addNode({
|
|
42
|
+
id: 1,
|
|
43
|
+
lon: -122.4,
|
|
44
|
+
lat: 47.6,
|
|
45
|
+
tags: { amenity: "cafe" },
|
|
47
46
|
})
|
|
48
|
-
```
|
|
49
47
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
osm.ways.addWay({
|
|
49
|
+
id: 10,
|
|
50
|
+
refs: [1],
|
|
51
|
+
tags: { highway: "service" },
|
|
52
|
+
})
|
|
53
53
|
|
|
54
|
-
```ts
|
|
55
|
-
const osm = new Osmix({ id: "fixture" })
|
|
56
|
-
osm.nodes.addNode({ id: 1, lon: -0.1, lat: 51.5, tags: { amenity: "cafe" } })
|
|
57
|
-
osm.ways.addWay({ id: 10, refs: [1], tags: { highway: "service" } })
|
|
58
54
|
osm.buildIndexes()
|
|
55
|
+
osm.buildSpatialIndexes()
|
|
59
56
|
```
|
|
60
57
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
- `osm.get("node", 123)` or `osm.getById("n123")` fetches specific entities.
|
|
64
|
-
- `osm.nodes.sorted()` / `osm.ways.sorted()` iterate ids in ascending order.
|
|
65
|
-
- `osm.getEntityGeoJson(entity)` returns a GeoJSON feature with coordinates resolved from the
|
|
66
|
-
indexed nodes.
|
|
67
|
-
|
|
68
|
-
Spatial lookups emit compact typed arrays that can be transferred across Web Workers and used directly in `Deck.gl`:
|
|
58
|
+
### Querying entities
|
|
69
59
|
|
|
70
60
|
```ts
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
const { ids: wayIds, positions: wayCoords, startIndices } = osm.getWaysInBbox(bbox)
|
|
75
|
-
```
|
|
61
|
+
// Get by ID
|
|
62
|
+
const node = osm.nodes.getById(123)
|
|
63
|
+
const way = osm.ways.get({ id: 456 })
|
|
76
64
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
65
|
+
// Iterate all entities
|
|
66
|
+
for (const node of osm.nodes) {
|
|
67
|
+
console.log(node.id, node.lon, node.lat)
|
|
68
|
+
}
|
|
80
69
|
|
|
81
|
-
|
|
82
|
-
const
|
|
70
|
+
// Iterate sorted by ID (useful for PBF export)
|
|
71
|
+
for (const way of osm.ways.sorted()) {
|
|
72
|
+
console.log(way.id, way.refs)
|
|
73
|
+
}
|
|
83
74
|
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
const
|
|
75
|
+
// Search by tag key
|
|
76
|
+
const highways = osm.ways.search("highway")
|
|
77
|
+
const cafes = osm.nodes.search("amenity", "cafe")
|
|
87
78
|
```
|
|
88
79
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
## Changesets and merging
|
|
92
|
-
|
|
93
|
-
Change orchestration now lives in the dedicated [`@osmix/change`](../change/README.md) package. Install it alongside
|
|
94
|
-
`@osmix/core` when you want to deduplicate entities, generate direct merges, or script intersection creation:
|
|
80
|
+
### Spatial queries
|
|
95
81
|
|
|
96
82
|
```ts
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
83
|
+
// Bounding box query
|
|
84
|
+
const bbox: [number, number, number, number] = [-122.34, 47.57, -122.30, 47.61]
|
|
85
|
+
const { ids, positions } = osm.nodes.withinBbox(bbox)
|
|
86
|
+
const { ids: wayIds, positions: wayCoords, startIndices } = osm.ways.withinBbox(bbox)
|
|
100
87
|
|
|
101
|
-
|
|
102
|
-
const
|
|
88
|
+
// Radius query (uses great-circle distance)
|
|
89
|
+
const nearbyIndexes = osm.nodes.findIndexesWithinRadius(-122.4, 47.6, 10) // 10km
|
|
103
90
|
|
|
104
|
-
|
|
105
|
-
|
|
91
|
+
// Get entities from indexes
|
|
92
|
+
const nearbyNodes = nearbyIndexes.map((i) => osm.nodes.getByIndex(i))
|
|
106
93
|
|
|
107
|
-
|
|
94
|
+
// Ways/relations use Flatbush for bounding-box intersection
|
|
95
|
+
const intersectingWays = osm.ways.intersects(bbox)
|
|
96
|
+
const nearestWays = osm.ways.neighbors(-122.4, 47.6, 5, 10) // 5 results, 10km max
|
|
108
97
|
```
|
|
109
98
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
## Transfer between threads
|
|
113
|
-
|
|
114
|
-
Typed arrays keep the index transferable.
|
|
99
|
+
### Transferring between workers
|
|
115
100
|
|
|
116
101
|
```ts
|
|
117
|
-
// main thread
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
const collect = (value: unknown) => {
|
|
121
|
-
if (value instanceof ArrayBuffer) buffers.push(value)
|
|
122
|
-
else if (ArrayBuffer.isView(value)) buffers.push(value.buffer)
|
|
123
|
-
else if (Array.isArray(value)) value.forEach(collect)
|
|
124
|
-
else if (value && typeof value === "object")
|
|
125
|
-
Object.values(value).forEach(collect)
|
|
126
|
-
return buffers
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
worker.postMessage(payload, { transfer: collect(payload) })
|
|
102
|
+
// In the main thread
|
|
103
|
+
const transferables = osm.transferables()
|
|
104
|
+
worker.postMessage(transferables, Object.values(transferables).filter(ArrayBuffer.isView))
|
|
130
105
|
|
|
131
|
-
// worker
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
self.addEventListener("message", ({ data }) => {
|
|
135
|
-
const osm = Osmix.from(data)
|
|
136
|
-
// ready for queries immediately
|
|
137
|
-
})
|
|
106
|
+
// In the worker
|
|
107
|
+
const osm = new Osm(transferables)
|
|
108
|
+
// Index is already built, ready for queries
|
|
138
109
|
```
|
|
139
110
|
|
|
140
|
-
## API
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
111
|
+
## API
|
|
112
|
+
|
|
113
|
+
### Classes
|
|
114
|
+
|
|
115
|
+
| Class | Description |
|
|
116
|
+
|-------|-------------|
|
|
117
|
+
| `Osm` | Main container with nodes, ways, relations, and shared string table |
|
|
118
|
+
| `Nodes` | Node storage with KDBush spatial index |
|
|
119
|
+
| `Ways` | Way storage with Flatbush spatial index |
|
|
120
|
+
| `Relations` | Relation storage with Flatbush spatial index |
|
|
121
|
+
| `StringTable` | Deduplicated UTF-8 string storage for tags |
|
|
122
|
+
| `Tags` | Bidirectional tag storage (entity→tags, key→entities) |
|
|
123
|
+
|
|
124
|
+
### Osm Methods
|
|
125
|
+
|
|
126
|
+
| Method | Description |
|
|
127
|
+
|--------|-------------|
|
|
128
|
+
| `buildIndexes()` | Finalize ID, tag, and entity indexes after adding data |
|
|
129
|
+
| `buildSpatialIndexes()` | Build spatial indexes for all entity types |
|
|
130
|
+
| `bbox()` | Get bounding box of all entities |
|
|
131
|
+
| `info()` | Get summary info (id, bbox, header, stats) |
|
|
132
|
+
| `transferables()` | Get serializable buffers for worker transfer |
|
|
133
|
+
| `isReady()` | Check if all indexes are built |
|
|
134
|
+
|
|
135
|
+
### Entity Collection Methods
|
|
136
|
+
|
|
137
|
+
| Method | Description |
|
|
138
|
+
|--------|-------------|
|
|
139
|
+
| `getById(id)` | Get entity by OSM ID |
|
|
140
|
+
| `get({ id } \| { index })` | Get by ID or internal index |
|
|
141
|
+
| `getByIndex(index)` | Get by internal array index |
|
|
142
|
+
| `search(key, value?)` | Find entities with tag key (and optional value) |
|
|
143
|
+
| `withinBbox(bbox)` | Get entities within bounding box |
|
|
144
|
+
| `findIndexesWithinRadius(lon, lat, km)` | Find nearby entities (nodes) |
|
|
145
|
+
| `intersects(bbox)` | Find intersecting entities (ways/relations) |
|
|
146
|
+
| `neighbors(lon, lat, max, maxKm)` | Find nearest entities (ways/relations) |
|
|
147
|
+
| `sorted()` | Iterator over entities sorted by ID |
|
|
148
|
+
|
|
149
|
+
## Environment and Limitations
|
|
150
|
+
|
|
151
|
+
- Requires Web Streams, `TextEncoder`/`TextDecoder`, `CompressionStream`/`DecompressionStream` (Bun, Node 20+, modern browsers).
|
|
152
|
+
- Uses ES2024 resizable `ArrayBuffer` and growable `SharedArrayBuffer` when available.
|
|
153
|
+
- Coordinates stored as `Int32Array` microdegrees (1e-7 degree precision, ~1cm at equator); converted to degrees at API boundaries.
|
|
154
|
+
|
|
155
|
+
## Related Packages
|
|
156
|
+
|
|
157
|
+
- [`osmix`](../osmix/README.md) — High-level API for loading PBF files and worker orchestration.
|
|
158
|
+
- [`@osmix/pbf`](../pbf/README.md) — Low-level PBF parsing and serialization.
|
|
159
|
+
- [`@osmix/json`](../json/README.md) — JSON entity conversion.
|
|
160
|
+
- [`@osmix/geojson`](../geojson/README.md) — Convert entities to GeoJSON features.
|
|
161
|
+
- [`@osmix/change`](../change/README.md) — Changeset generation, deduplication, and merge.
|
|
153
162
|
|
|
154
163
|
## Development
|
|
155
164
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
165
|
+
```sh
|
|
166
|
+
bun run test packages/core
|
|
167
|
+
bun run typecheck packages/core
|
|
168
|
+
bun run lint packages/core
|
|
169
|
+
```
|
|
159
170
|
|
|
160
|
-
Run `bun run check` at the repo root before publishing
|
|
171
|
+
Run `bun run check` at the repo root before publishing.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base class for OSM entity collections.
|
|
3
|
+
*
|
|
4
|
+
* Provides common ID and tag storage, streaming iteration, and sorted access.
|
|
5
|
+
* Subclasses implement entity-specific storage and spatial indexing.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import type { GeoBbox2D, OsmEntity, OsmEntityType, OsmTags } from "@osmix/shared/types";
|
|
10
|
+
import type { IdOrIndex, Ids, IdsTransferables } from "./ids";
|
|
11
|
+
import type { Tags, TagsTransferables } from "./tags";
|
|
12
|
+
import type { BufferType } from "./typed-arrays";
|
|
13
|
+
/**
|
|
14
|
+
* Serializable representation of an Entities collection for worker transfer.
|
|
15
|
+
* Combines ID and tag transferables; subclasses add entity-specific data.
|
|
16
|
+
*/
|
|
17
|
+
export interface EntitiesTransferables<T extends BufferType = BufferType> extends IdsTransferables<T>, TagsTransferables<T> {
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Abstract base for typed entity collections.
|
|
21
|
+
*
|
|
22
|
+
* Lifecycle:
|
|
23
|
+
* 1. **Ingest**: `addEntity()` (no lookups).
|
|
24
|
+
* 2. **Finalize**: `buildIndex()`.
|
|
25
|
+
* 3. **Query**: Lookups and iteration enabled.
|
|
26
|
+
*/
|
|
27
|
+
export declare abstract class Entities<T extends OsmEntity> {
|
|
28
|
+
/** The type of entity stored in this collection ("node", "way", or "relation"). */
|
|
29
|
+
indexType: OsmEntityType;
|
|
30
|
+
/** ID storage and lookup */
|
|
31
|
+
ids: Ids;
|
|
32
|
+
/** Tag storage and search */
|
|
33
|
+
tags: Tags;
|
|
34
|
+
/** Whether buildIndex() has been called */
|
|
35
|
+
protected indexBuilt: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Create a new Entities collection.
|
|
38
|
+
* @param indexType - The entity type ("node", "way", or "relation").
|
|
39
|
+
* @param ids - The ID storage instance.
|
|
40
|
+
* @param tags - The tag storage instance.
|
|
41
|
+
*/
|
|
42
|
+
constructor(indexType: OsmEntityType, ids: Ids, tags: Tags);
|
|
43
|
+
/**
|
|
44
|
+
* Get transferable objects for passing to another thread.
|
|
45
|
+
*/
|
|
46
|
+
transferables(): EntitiesTransferables;
|
|
47
|
+
/**
|
|
48
|
+
* Check if the index is built and ready for use.
|
|
49
|
+
*/
|
|
50
|
+
isReady(): boolean;
|
|
51
|
+
/** Number of entities in this collection. */
|
|
52
|
+
get size(): number;
|
|
53
|
+
/**
|
|
54
|
+
* Compact entity-specific typed arrays.
|
|
55
|
+
* Called by `buildIndex()` after ID and tag indexes are built.
|
|
56
|
+
* @abstract
|
|
57
|
+
*/
|
|
58
|
+
abstract buildEntityIndex(): void;
|
|
59
|
+
/**
|
|
60
|
+
* Finalize indexes.
|
|
61
|
+
* Must be called after adding entities and before querying.
|
|
62
|
+
*/
|
|
63
|
+
buildIndex(): void;
|
|
64
|
+
/**
|
|
65
|
+
* Get the bounding box of an entity.
|
|
66
|
+
* @param idOrIndex - Entity identifier (by ID or internal index).
|
|
67
|
+
* @returns Geographic bounding box [minLon, minLat, maxLon, maxLat].
|
|
68
|
+
* @abstract
|
|
69
|
+
*/
|
|
70
|
+
abstract getEntityBbox(idOrIndex: IdOrIndex): GeoBbox2D;
|
|
71
|
+
/**
|
|
72
|
+
* Reconstruct a full entity object from index data.
|
|
73
|
+
* @param index - Internal array index.
|
|
74
|
+
* @param id - OSM entity ID.
|
|
75
|
+
* @param tags - Optional pre-fetched tags.
|
|
76
|
+
* @returns The complete entity object.
|
|
77
|
+
* @abstract
|
|
78
|
+
*/
|
|
79
|
+
abstract getFullEntity(index: number, id: number, tags?: OsmTags): T;
|
|
80
|
+
/**
|
|
81
|
+
* Add an entity to the index. Tags can be provided as an array of keys and values, or as an object.
|
|
82
|
+
*/
|
|
83
|
+
addEntity(id: number, tags: number[], values: number[]): number;
|
|
84
|
+
addEntity(id: number, tags: OsmTags): number;
|
|
85
|
+
/**
|
|
86
|
+
* Get an entity by ID or index.
|
|
87
|
+
*/
|
|
88
|
+
get(idOrIndex: IdOrIndex): T | null;
|
|
89
|
+
/**
|
|
90
|
+
* Get an entity by index.
|
|
91
|
+
*/
|
|
92
|
+
getByIndex(index: number): T;
|
|
93
|
+
/**
|
|
94
|
+
* Get multiple entities by their indexes.
|
|
95
|
+
*/
|
|
96
|
+
getEntitiesByIndex(indexes: number[]): T[];
|
|
97
|
+
/**
|
|
98
|
+
* Iterate over all entities in the index.
|
|
99
|
+
*/
|
|
100
|
+
[Symbol.iterator](): Generator<T>;
|
|
101
|
+
/**
|
|
102
|
+
* Get an entity by ID.
|
|
103
|
+
*/
|
|
104
|
+
getById(id: number): T | null;
|
|
105
|
+
/**
|
|
106
|
+
* Iterate over entities sorted by ID.
|
|
107
|
+
*/
|
|
108
|
+
sorted(): Generator<T>;
|
|
109
|
+
/**
|
|
110
|
+
* Search for entities with a specific tag key and optional value.
|
|
111
|
+
*/
|
|
112
|
+
search(key: string, val?: string): T[];
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=entities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../../src/entities.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACX,SAAS,EACT,SAAS,EACT,aAAa,EACb,OAAO,EACP,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAA;AAC7D,OAAO,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAA;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAEhD;;;GAGG;AACH,MAAM,WAAW,qBAAqB,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,CACvE,SAAQ,gBAAgB,CAAC,CAAC,CAAC,EAC1B,iBAAiB,CAAC,CAAC,CAAC;CAAG;AAEzB;;;;;;;GAOG;AACH,8BAAsB,QAAQ,CAAC,CAAC,SAAS,SAAS;IACjD,mFAAmF;IACnF,SAAS,EAAE,aAAa,CAAA;IACxB,4BAA4B;IAC5B,GAAG,EAAE,GAAG,CAAA;IACR,6BAA6B;IAC7B,IAAI,EAAE,IAAI,CAAA;IAEV,2CAA2C;IAC3C,SAAS,CAAC,UAAU,UAAQ;IAE5B;;;;;OAKG;gBACS,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI;IAM1D;;OAEG;IACH,aAAa,IAAI,qBAAqB;IAOtC;;OAEG;IACH,OAAO;IAIP,6CAA6C;IAC7C,IAAI,IAAI,WAEP;IAED;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,IAAI,IAAI;IAEjC;;;OAGG;IACH,UAAU;IAUV;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,SAAS,EAAE,SAAS,GAAG,SAAS;IAEvD;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,CAAC;IAEpE;;OAEG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM;IAC/D,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM;IAa5C;;OAEG;IACH,GAAG,CAAC,SAAS,EAAE,SAAS,GAAG,CAAC,GAAG,IAAI;IAMnC;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC;IAQ5B;;OAEG;IACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE;IAU1C;;OAEG;IACF,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC;IAMlC;;OAEG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAO7B;;OAEG;IACF,MAAM,IAAI,SAAS,CAAC,CAAC,CAAC;IAQvB;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE;CAQtC"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base class for OSM entity collections.
|
|
3
|
+
*
|
|
4
|
+
* Provides common ID and tag storage, streaming iteration, and sorted access.
|
|
5
|
+
* Subclasses implement entity-specific storage and spatial indexing.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Abstract base for typed entity collections.
|
|
11
|
+
*
|
|
12
|
+
* Lifecycle:
|
|
13
|
+
* 1. **Ingest**: `addEntity()` (no lookups).
|
|
14
|
+
* 2. **Finalize**: `buildIndex()`.
|
|
15
|
+
* 3. **Query**: Lookups and iteration enabled.
|
|
16
|
+
*/
|
|
17
|
+
export class Entities {
|
|
18
|
+
/** The type of entity stored in this collection ("node", "way", or "relation"). */
|
|
19
|
+
indexType;
|
|
20
|
+
/** ID storage and lookup */
|
|
21
|
+
ids;
|
|
22
|
+
/** Tag storage and search */
|
|
23
|
+
tags;
|
|
24
|
+
/** Whether buildIndex() has been called */
|
|
25
|
+
indexBuilt = false;
|
|
26
|
+
/**
|
|
27
|
+
* Create a new Entities collection.
|
|
28
|
+
* @param indexType - The entity type ("node", "way", or "relation").
|
|
29
|
+
* @param ids - The ID storage instance.
|
|
30
|
+
* @param tags - The tag storage instance.
|
|
31
|
+
*/
|
|
32
|
+
constructor(indexType, ids, tags) {
|
|
33
|
+
this.indexType = indexType;
|
|
34
|
+
this.ids = ids;
|
|
35
|
+
this.tags = tags;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get transferable objects for passing to another thread.
|
|
39
|
+
*/
|
|
40
|
+
transferables() {
|
|
41
|
+
return {
|
|
42
|
+
...this.ids.transferables(),
|
|
43
|
+
...this.tags.transferables(),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Check if the index is built and ready for use.
|
|
48
|
+
*/
|
|
49
|
+
isReady() {
|
|
50
|
+
return this.ids.isReady() && this.tags.isReady() && this.indexBuilt;
|
|
51
|
+
}
|
|
52
|
+
/** Number of entities in this collection. */
|
|
53
|
+
get size() {
|
|
54
|
+
return this.ids.size;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Finalize indexes.
|
|
58
|
+
* Must be called after adding entities and before querying.
|
|
59
|
+
*/
|
|
60
|
+
buildIndex() {
|
|
61
|
+
if (this.indexBuilt)
|
|
62
|
+
return;
|
|
63
|
+
console.time(`${this.indexType}Index.buildIndex`);
|
|
64
|
+
this.ids.buildIndex();
|
|
65
|
+
this.tags.buildIndex();
|
|
66
|
+
this.buildEntityIndex();
|
|
67
|
+
this.indexBuilt = true;
|
|
68
|
+
console.timeEnd(`${this.indexType}Index.buildIndex`);
|
|
69
|
+
}
|
|
70
|
+
addEntity(id, tags, values) {
|
|
71
|
+
const entityIndex = this.ids.add(id);
|
|
72
|
+
if (Array.isArray(tags)) {
|
|
73
|
+
if (values === undefined)
|
|
74
|
+
throw Error("Values are required when tags is an array");
|
|
75
|
+
this.tags.addTagKeysAndValues(entityIndex, tags, values);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
this.tags.addTags(entityIndex, tags);
|
|
79
|
+
}
|
|
80
|
+
return entityIndex;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get an entity by ID or index.
|
|
84
|
+
*/
|
|
85
|
+
get(idOrIndex) {
|
|
86
|
+
const [index, id] = this.ids.idOrIndex(idOrIndex);
|
|
87
|
+
if (index === -1)
|
|
88
|
+
return null;
|
|
89
|
+
return this.getFullEntity(index, id, this.tags.getTags(index));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get an entity by index.
|
|
93
|
+
*/
|
|
94
|
+
getByIndex(index) {
|
|
95
|
+
return this.getFullEntity(index, this.ids.at(index), this.tags.getTags(index));
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get multiple entities by their indexes.
|
|
99
|
+
*/
|
|
100
|
+
getEntitiesByIndex(indexes) {
|
|
101
|
+
const entities = [];
|
|
102
|
+
for (const index of indexes) {
|
|
103
|
+
const entity = this.getByIndex(index);
|
|
104
|
+
if (entity)
|
|
105
|
+
entities.push(entity);
|
|
106
|
+
else
|
|
107
|
+
throw Error(`Entity not found at index ${index}`);
|
|
108
|
+
}
|
|
109
|
+
return entities;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Iterate over all entities in the index.
|
|
113
|
+
*/
|
|
114
|
+
*[Symbol.iterator]() {
|
|
115
|
+
for (let i = 0; i < this.size; i++) {
|
|
116
|
+
yield this.getFullEntity(i, this.ids.at(i), this.tags.getTags(i));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Get an entity by ID.
|
|
121
|
+
*/
|
|
122
|
+
getById(id) {
|
|
123
|
+
const index = this.ids.getIndexFromId(id);
|
|
124
|
+
if (index !== -1)
|
|
125
|
+
return this.getFullEntity(index, id, this.tags.getTags(index));
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Iterate over entities sorted by ID.
|
|
130
|
+
*/
|
|
131
|
+
*sorted() {
|
|
132
|
+
for (const id of this.ids.sorted) {
|
|
133
|
+
const index = this.ids.getIndexFromId(id);
|
|
134
|
+
if (index === -1)
|
|
135
|
+
throw Error(`Entity not found at id ${id}`);
|
|
136
|
+
yield this.getFullEntity(index, id, this.tags.getTags(index));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Search for entities with a specific tag key and optional value.
|
|
141
|
+
*/
|
|
142
|
+
search(key, val) {
|
|
143
|
+
const keyIndex = this.tags.find(key);
|
|
144
|
+
const entities = this.tags
|
|
145
|
+
.hasKey(keyIndex)
|
|
146
|
+
.map((index) => this.getByIndex(index));
|
|
147
|
+
if (val === undefined)
|
|
148
|
+
return entities;
|
|
149
|
+
return entities.filter((entity) => entity.tags?.[key] === val);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=entities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entities.js","sourceRoot":"","sources":["../../../src/entities.ts"],"names":[],"mappings":"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"}
|