@truelies/osm-dybuf 0.3.0 → 0.3.2

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/README.md CHANGED
@@ -4,6 +4,7 @@ Gridex `osm.dybuf` parser utilities shared by the exporter, inspection scripts,
4
4
  This package wraps the shared schema tables (`schema_ids`) and exposes a high-level `parseOsmDybuf` helper.
5
5
  It depends on the published [`dybuf`](https://www.npmjs.com/package/dybuf) runtime (≥ 0.4.2).
6
6
  Feature IDs are packed as `feature_id = sub_id * 64 + main_id` (both 0–63). Use `schema_ids` to decode feature strings.
7
+ Current road groups are `road_express`, `road_major`, `road_minor`, `road_local`, and `road_trail`.
7
8
 
8
9
  ## Current Compatibility Status
9
10
 
@@ -17,6 +18,12 @@ Support matrix:
17
18
 
18
19
  `inspect_dybuf.mjs` now prints by detected format.
19
20
 
21
+ Current frontend-facing schema notes:
22
+
23
+ - `admin_boundary` is retained in schema IDs for compatibility, but new exports no longer send boundary lines to the frontend.
24
+ - Administrative naming should come from `place_label`.
25
+ - `road_express` was added for motorway / controlled-access corridors.
26
+
20
27
  ## Usage
21
28
 
22
29
  ```bash
@@ -60,7 +67,7 @@ if (parsed.format === "flat_v1") {
60
67
 
61
68
  ### Grid helpers (grid_index)
62
69
 
63
- `grid_index.ts` exposes the minimal Gridex helpers (integers, pole triangles) aligned with the exporter:
70
+ `grid_index.mjs` exposes Gridex helpers (integers, pole triangles) aligned with the exporter:
64
71
 
65
72
  ```ts
66
73
  import { GridUnit, Gridex, INT_COORD_SCALE } from "@truelies/osm-dybuf/grid_index";
@@ -68,18 +75,44 @@ import { GridUnit, Gridex, INT_COORD_SCALE } from "@truelies/osm-dybuf/grid_inde
68
75
  const unit = new GridUnit(8); // level 8
69
76
  const cell = new Gridex(213, 161);
70
77
  const [minLon, minLat, maxLon, maxLat] = unit.boundsOfGrid(cell);
78
+
79
+ // parent/child conversion (same rules as Python GridUnit)
80
+ const children = unit.toLowerLevelGridexes(cell); // level 9, 4 cells
81
+ const parent = new GridUnit(9).toUpperLevelGridex(children[0]); // back to level 8
71
82
  ```
72
83
 
84
+ - `toLowerLevelGridexes(gridex)`:
85
+ - returns 4 child cells at `level + 1`
86
+ - throws when current unit is already max level (`16`)
87
+ - `toUpperLevelGridex(gridex)`:
88
+ - returns the parent cell at `level - 1`
89
+ - throws when current unit is level `0`
90
+
73
91
  ## Local Development
74
92
 
75
93
  ```bash
76
94
  cd js
77
95
  npm install # installs dybuf runtime for this package
96
+ npm test # runs unit tests (node:test)
78
97
  ```
79
98
 
99
+ Unit test example (`tests/grid_index.test.mjs`) covers:
100
+ - `gridexesAt` near axis (no zero index cell)
101
+ - `toLowerLevelGridexes` and `toUpperLevelGridex` roundtrip
102
+ - level boundary errors (`lv0` has no upper level, `lv16` has no lower level)
103
+
80
104
  - `npm pack`: build a tarball so other repos can install via `npm install ./path/to/osm-dybuf-*.tgz`
81
105
  - `npm link`: link the package locally (`npm link` here, then `npm link @truelies/osm-dybuf` in the consumer repo)
82
- - `npm publish --access public`: publish to npm (requires the `@truelies` scope). If the scope is not available, rename `package.json` → `"name": "truelies-osm-dybuf"` and publish without a scope.
106
+ - Publish to npm (requires `@truelies` scope):
107
+ ```bash
108
+ cd js
109
+ npm version <new-version> --no-git-tag-version
110
+ NPM_CONFIG_CACHE=/tmp/npm-cache npm login --auth-type=web --registry=https://registry.npmjs.org/ --scope=@truelies
111
+ NPM_CONFIG_CACHE=/tmp/npm-cache npm whoami
112
+ NPM_CONFIG_CACHE=/tmp/npm-cache npm publish --access public
113
+ ```
114
+ - If `~/.npm` has permission issues (root-owned cache/logs), keep using `NPM_CONFIG_CACHE=/tmp/npm-cache`.
115
+ - If the scope is not available, rename `package.json` → `"name": "truelies-osm-dybuf"` and publish without a scope.
83
116
 
84
117
  ## Files
85
118
 
@@ -88,4 +121,4 @@ npm install # installs dybuf runtime for this package
88
121
  - `region_numeric_codes.json`: latest region ID table (generated via `scripts/dump_region_codes.py`)
89
122
  - `inspect_dybuf.mjs`: CLI tool that uses the package locally
90
123
 
91
- When schema IDs or DyBuf layouts change in the exporter, remember to bump the version here and re-publish/install so frontends and tools stay in sync.
124
+ When schema IDs or DyBuf layouts change in the exporter, remember to bump the version here and re-publish/install so frontends and tools stay in sync. Version `0.3.2` adds the `road_express` feature group and aligns the package docs with the current no-`admin_boundary` frontend export policy.
package/grid_index.d.ts CHANGED
@@ -31,6 +31,8 @@ export declare class GridUnit {
31
31
  makeGridex(londex: number, latdex: number): GridexAtLv;
32
32
  gridexesAt(longitudeInt: number, latitudeInt: number): GridexAtLv[];
33
33
  gridexesWithExt(longitudeInt: number, latitudeInt: number, ext?: number): GridexAtLv[];
34
+ toLowerLevelGridexes(gridex: Gridex): GridexAtLv[];
35
+ toUpperLevelGridex(gridex: Gridex): GridexAtLv;
34
36
  boundsOfGridFine(gridex: Gridex, applyTriangle?: boolean): [number, number, number, number];
35
37
  boundsOfGrid(gridex: Gridex, applyTriangle?: boolean): [number, number, number, number];
36
38
  gridexRangeForBounds(
package/grid_index.mjs CHANGED
@@ -158,6 +158,43 @@ export class GridUnit {
158
158
  return result;
159
159
  }
160
160
 
161
+ toLowerLevelGridexes(gridex) {
162
+ if (this.level >= MAX_LEVEL) {
163
+ throw new Error(`No lower level exists for level ${this.level}`);
164
+ }
165
+ const lon = gridex.londex;
166
+ const lat = gridex.latdex;
167
+ const lonInc = lon > 0 ? -1 : 1;
168
+ const latInc = lat > 0 ? -1 : 1;
169
+ const childUnit = new GridUnit(this.level + 1);
170
+ return [
171
+ childUnit.makeGridex(lon * 2 + lonInc, lat * 2 + latInc),
172
+ childUnit.makeGridex(lon * 2 + lonInc, lat * 2),
173
+ childUnit.makeGridex(lon * 2, lat * 2 + latInc),
174
+ childUnit.makeGridex(lon * 2, lat * 2),
175
+ ];
176
+ }
177
+
178
+ toUpperLevelGridex(gridex) {
179
+ if (this.level <= 0) {
180
+ throw new Error("No upper level exists for level 0");
181
+ }
182
+ const lon = gridex.londex;
183
+ const lat = gridex.latdex;
184
+ const lonInc = lon > 0 ? -1 : 1;
185
+ const latInc = lat > 0 ? -1 : 1;
186
+ const upperLon =
187
+ lon > 0
188
+ ? Math.floor((lon - lonInc) / 2)
189
+ : Math.ceil((lon - lonInc) / 2);
190
+ const upperLat =
191
+ lat > 0
192
+ ? Math.floor((lat - latInc) / 2)
193
+ : Math.ceil((lat - latInc) / 2);
194
+ const upperUnit = new GridUnit(this.level - 1);
195
+ return upperUnit.makeGridex(upperLon, upperLat);
196
+ }
197
+
161
198
  boundsOfGridFine(gridex, applyTriangle = false) {
162
199
  const { londex, latdex } = gridex;
163
200
  const minLonFine = (londex - (londex > 0 ? 1 : 0)) * this.unitFine;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truelies/osm-dybuf",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Gridex OSM DyBuf parser and schema utilities",
5
5
  "type": "module",
6
6
  "main": "./osm_dybuf.mjs",
@@ -39,6 +39,9 @@
39
39
  ],
40
40
  "author": "TrueLies",
41
41
  "license": "UNLICENSED",
42
+ "scripts": {
43
+ "test": "node --test tests/*.test.mjs"
44
+ },
42
45
  "dependencies": {
43
46
  "dybuf": "^0.4.2"
44
47
  }
package/schema_ids.mjs CHANGED
@@ -44,10 +44,11 @@ const FEATURE_KIND_CODES = Object.freeze({
44
44
  waterbody: ["waterbody", 0],
45
45
  landuse: ["landuse", 0],
46
46
  park: ["park", 0],
47
- road_major: ["road", 0],
48
- road_minor: ["road", 1],
49
- road_local: ["road", 2],
50
- road_trail: ["road", 3],
47
+ road_express: ["road", 0],
48
+ road_major: ["road", 1],
49
+ road_minor: ["road", 2],
50
+ road_local: ["road", 3],
51
+ road_trail: ["road", 4],
51
52
  waterway_major: ["waterway", 0],
52
53
  waterway_stream: ["waterway", 1],
53
54
  waterway_minor: ["waterway", 2],