@truelies/osm-dybuf 0.3.0 → 0.3.1

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
@@ -60,7 +60,7 @@ if (parsed.format === "flat_v1") {
60
60
 
61
61
  ### Grid helpers (grid_index)
62
62
 
63
- `grid_index.ts` exposes the minimal Gridex helpers (integers, pole triangles) aligned with the exporter:
63
+ `grid_index.mjs` exposes Gridex helpers (integers, pole triangles) aligned with the exporter:
64
64
 
65
65
  ```ts
66
66
  import { GridUnit, Gridex, INT_COORD_SCALE } from "@truelies/osm-dybuf/grid_index";
@@ -68,18 +68,44 @@ import { GridUnit, Gridex, INT_COORD_SCALE } from "@truelies/osm-dybuf/grid_inde
68
68
  const unit = new GridUnit(8); // level 8
69
69
  const cell = new Gridex(213, 161);
70
70
  const [minLon, minLat, maxLon, maxLat] = unit.boundsOfGrid(cell);
71
+
72
+ // parent/child conversion (same rules as Python GridUnit)
73
+ const children = unit.toLowerLevelGridexes(cell); // level 9, 4 cells
74
+ const parent = new GridUnit(9).toUpperLevelGridex(children[0]); // back to level 8
71
75
  ```
72
76
 
77
+ - `toLowerLevelGridexes(gridex)`:
78
+ - returns 4 child cells at `level + 1`
79
+ - throws when current unit is already max level (`16`)
80
+ - `toUpperLevelGridex(gridex)`:
81
+ - returns the parent cell at `level - 1`
82
+ - throws when current unit is level `0`
83
+
73
84
  ## Local Development
74
85
 
75
86
  ```bash
76
87
  cd js
77
88
  npm install # installs dybuf runtime for this package
89
+ npm test # runs unit tests (node:test)
78
90
  ```
79
91
 
92
+ Unit test example (`tests/grid_index.test.mjs`) covers:
93
+ - `gridexesAt` near axis (no zero index cell)
94
+ - `toLowerLevelGridexes` and `toUpperLevelGridex` roundtrip
95
+ - level boundary errors (`lv0` has no upper level, `lv16` has no lower level)
96
+
80
97
  - `npm pack`: build a tarball so other repos can install via `npm install ./path/to/osm-dybuf-*.tgz`
81
98
  - `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.
99
+ - Publish to npm (requires `@truelies` scope):
100
+ ```bash
101
+ cd js
102
+ npm version <new-version> --no-git-tag-version
103
+ NPM_CONFIG_CACHE=/tmp/npm-cache npm login --auth-type=web --registry=https://registry.npmjs.org/ --scope=@truelies
104
+ NPM_CONFIG_CACHE=/tmp/npm-cache npm whoami
105
+ NPM_CONFIG_CACHE=/tmp/npm-cache npm publish --access public
106
+ ```
107
+ - If `~/.npm` has permission issues (root-owned cache/logs), keep using `NPM_CONFIG_CACHE=/tmp/npm-cache`.
108
+ - If the scope is not available, rename `package.json` → `"name": "truelies-osm-dybuf"` and publish without a scope.
83
109
 
84
110
  ## Files
85
111
 
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.1",
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
  }