@xyo-network/quadkey 5.3.20 → 5.3.24

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xyo-network/quadkey",
3
- "version": "5.3.20",
3
+ "version": "5.3.24",
4
4
  "description": "Primary SDK for using XYO Protocol 2.0",
5
5
  "homepage": "https://xyo.network",
6
6
  "bugs": {
@@ -30,20 +30,26 @@
30
30
  "types": "dist/neutral/index.d.ts",
31
31
  "files": [
32
32
  "dist",
33
- "src",
34
33
  "!**/*.bench.*",
35
34
  "!**/*.spec.*",
36
- "!**/*.test.*"
35
+ "!**/*.test.*",
36
+ "README.md"
37
37
  ],
38
38
  "devDependencies": {
39
- "@xylabs/geo": "^5.0.90",
40
- "@xylabs/sdk-js": "^5.0.90",
41
- "@xylabs/ts-scripts-common": "~7.5.6",
42
- "@xylabs/ts-scripts-yarn3": "~7.5.6",
43
- "@xylabs/tsconfig": "~7.5.6",
44
- "@xylabs/vitest-extended": "~5.0.90",
45
- "mapbox-gl": "^3.20.0",
39
+ "@opentelemetry/api": "^1.9.1",
40
+ "@types/node": "^25.5.0",
41
+ "@xylabs/geo": "^5.0.93",
42
+ "@xylabs/sdk-js": "^5.0.93",
43
+ "@xylabs/ts-scripts-common": "~7.6.16",
44
+ "@xylabs/ts-scripts-pnpm": "~7.6.16",
45
+ "@xylabs/tsconfig": "~7.6.16",
46
+ "@xylabs/vitest-extended": "~5.0.93",
47
+ "acorn": "^8.16.0",
48
+ "axios": "^1.14.0",
49
+ "esbuild": "^0.28.0",
50
+ "mapbox-gl": "^3.21.0",
46
51
  "typescript": "~5.9.3",
52
+ "vite": "^8.0.3",
47
53
  "vitest": "~4.1.2",
48
54
  "zod": "^4.3.6"
49
55
  },
@@ -56,4 +62,4 @@
56
62
  "publishConfig": {
57
63
  "access": "public"
58
64
  }
59
- }
65
+ }
package/src/Quadkey.ts DELETED
@@ -1,323 +0,0 @@
1
- import type {
2
- MercatorBoundingBox,
3
- MercatorLngLat,
4
- MercatorTile,
5
- } from '@xylabs/geo'
6
- import {
7
- boundingBoxToCenter,
8
- GeoJson,
9
- tileFromPoint,
10
- tileFromQuadkey,
11
- tilesFromBoundingBox,
12
- tileToBoundingBox,
13
- tileToQuadkey,
14
- } from '@xylabs/geo'
15
- import {
16
- assertEx, hexFromArrayBuffer, hexFromHexString,
17
- } from '@xylabs/sdk-js'
18
- import type { LngLatLike } from 'mapbox-gl'
19
- import mb from 'mapbox-gl'
20
- const { LngLat } = mb
21
-
22
- import { RelativeDirectionConstantLookup } from './RelativeDirectionConstantLookup.ts'
23
-
24
- const MAX_ZOOM = 124
25
-
26
- export const isQuadkey = (obj: { type: string }) => obj?.type === Quadkey.type
27
-
28
- const FULL_MASK = 2n ** 256n - 1n
29
- const ZOOM_MASK = 0xffn << 248n
30
- const ID_MASK = ZOOM_MASK ^ FULL_MASK
31
-
32
- const assertMaxBitUint = (value: bigint, bits = 256n) => {
33
- assertEx(value < 2n ** bits && value >= 0, () => 'Not a 256 Bit Uint!')
34
- }
35
-
36
- export class Quadkey {
37
- static readonly Zero = Quadkey.from(0, 0n)
38
- static readonly root = new Quadkey()
39
- static readonly type = 'Quadkey'
40
-
41
- key: bigint
42
-
43
- type = Quadkey.type
44
-
45
- private _geoJson?: GeoJson
46
-
47
- constructor(key = 0n) {
48
- assertMaxBitUint(key)
49
- this.key = key
50
- this.guessZoom()
51
- }
52
-
53
- get base10String() {
54
- return this.id.toString(10)
55
- }
56
-
57
- get base16String() {
58
- return this.id.toString(16).padStart(62, '0')
59
- }
60
-
61
- get base4Hash() {
62
- if (this.id === 0n && this.zoom === 0) {
63
- return ''
64
- }
65
- return this.id.toString(4).padStart(this.zoom, '0')
66
- }
67
-
68
- get base4HashLabel() {
69
- const hash = this.base4Hash
70
- return hash.length === 0 ? 'fhr' : hash
71
- }
72
-
73
- get boundingBox(): MercatorBoundingBox {
74
- return tileToBoundingBox(this.tile)
75
- }
76
-
77
- get center() {
78
- const result = boundingBoxToCenter(this.boundingBox)
79
- return new LngLat(result[0], result[1])
80
- }
81
-
82
- get children() {
83
- assertEx(this.zoom < MAX_ZOOM - 1, () => 'Can not get children of bottom tiles')
84
- const result: Quadkey[] = []
85
- const shiftedId = this.id << 2n
86
- for (let i = 0n; i < 4n; i++) {
87
- result.push(new Quadkey().setId(shiftedId | i).setZoom(this.zoom + 1))
88
- }
89
- return result
90
- }
91
-
92
- get gridLocation(): { col: number; row: number; zoom: number } {
93
- const tileData = tileFromQuadkey(this.base4Hash)
94
-
95
- return {
96
- col: 2 ** tileData[2] - tileData[1] - 1,
97
- row: tileData[0],
98
- zoom: tileData[2],
99
- }
100
- }
101
-
102
- get id() {
103
- return this.key & ID_MASK
104
- }
105
-
106
- get parent(): Quadkey | undefined {
107
- if (this.zoom > 0) {
108
- return new Quadkey().setId(this.id >> 2n).setZoom(this.zoom - 1)
109
- }
110
- }
111
-
112
- get siblings() {
113
- const siblings = assertEx(this.parent?.children, () => `siblings: parentChildren ${this.base4Hash}`)
114
- const filteredSiblings = siblings.filter(quadkey => quadkey.key !== this.key)
115
- assertEx(filteredSiblings.length === 3, () => `siblings: expected 3 [${filteredSiblings.length}]`)
116
- return filteredSiblings
117
- }
118
-
119
- get tile(): MercatorTile {
120
- return tileFromQuadkey(this.base4Hash)
121
- }
122
-
123
- get valid() {
124
- // check for additional data outside zoom scope
125
- return this.id.toString(4) === this.base4Hash.padStart(64, '0')
126
- }
127
-
128
- get zoom() {
129
- // zoom is stored in top byte
130
- return Number((this.key & ZOOM_MASK) >> 248n)
131
- }
132
-
133
- static from(zoom: number, id: bigint) {
134
- return new Quadkey().setId(id).setZoom(zoom)
135
- }
136
-
137
- static fromArrayBuffer(zoom: number, id: ArrayBuffer) {
138
- return new Quadkey().setId(BigInt(hexFromArrayBuffer(id, { prefix: true }))).setZoom(zoom)
139
- }
140
-
141
- static fromBase16String(value: string) {
142
- return new Quadkey(BigInt(hexFromHexString(value, { prefix: true })))
143
- }
144
-
145
- static fromBase4String(value?: string) {
146
- if (value === 'fhr' || value === '' || value === undefined) {
147
- return Quadkey.root
148
- }
149
- let id = 0n
150
- for (let i = 0; i < value.length; i++) {
151
- const nibble = Number.parseInt(value[i])
152
- assertEx(nibble < 4 && nibble >= 0, () => `Invalid Base4 String: ${value}`)
153
- id = (id << 2n) | BigInt(nibble)
154
- }
155
- return new Quadkey().setId(id).setZoom(value.length)
156
- }
157
-
158
- static fromBoundingBox(boundingBox: MercatorBoundingBox, zoom: number) {
159
- const tiles = tilesFromBoundingBox(boundingBox, Math.floor(zoom))
160
- const result: Quadkey[] = []
161
- for (const tile of tiles) {
162
- result.push(assertEx(Quadkey.fromTile(tile), () => 'Bad Quadkey'))
163
- }
164
-
165
- return result
166
- }
167
-
168
- static fromLngLat(point: LngLatLike, zoom: number) {
169
- const tile = tileFromPoint(point as MercatorLngLat, zoom)
170
- const quadkeyString = tileToQuadkey(tile)
171
- return Quadkey.fromBase4String(quadkeyString)
172
- }
173
-
174
- static fromString(zoom: number, id: string, base = 16) {
175
- switch (base) {
176
- case 16: {
177
- return Quadkey.fromBase16String(id).setZoom(zoom)
178
- }
179
- default: {
180
- throw new Error(`Invalid base [${base}]`)
181
- }
182
- }
183
- }
184
-
185
- static fromTile(tile: MercatorTile) {
186
- return Quadkey.fromBase4String(tileToQuadkey(tile))
187
- }
188
-
189
- childrenByZoom(zoom: number) {
190
- // if we are limiting by zoom, and we are already at that limit, just return this quadkey
191
- if (zoom > 0 && zoom === this.zoom) {
192
- return [this]
193
- }
194
-
195
- // recursively get children
196
- let deepResult: Quadkey[] = []
197
- for (const quadkey of this.children) {
198
- deepResult = [...deepResult, ...quadkey.childrenByZoom(zoom)]
199
- }
200
- return deepResult
201
- }
202
-
203
- clone() {
204
- return new Quadkey(this.key)
205
- }
206
-
207
- equals(obj: Quadkey): boolean {
208
- return obj.key == this.key
209
- }
210
-
211
- geoJson() {
212
- this._geoJson = this._geoJson ?? new GeoJson(this.base4Hash)
213
- return this._geoJson
214
- }
215
-
216
- getGridBoundingBox(size: number) {
217
- const hash = this.base4Hash
218
- let index = 0
219
- let left = 0
220
- let top = 0
221
- let blockSize = size
222
- while (index < hash.length) {
223
- blockSize >>= 1
224
- switch (hash[index]) {
225
- case '1': {
226
- left += blockSize
227
- break
228
- }
229
- case '2': {
230
- top += blockSize
231
- break
232
- }
233
- case '3': {
234
- left += blockSize
235
- top += blockSize
236
- break
237
- }
238
- }
239
- index++
240
- }
241
- if (blockSize < 2) {
242
- blockSize = 2
243
- }
244
- return {
245
- height: blockSize,
246
- left,
247
- top,
248
- width: blockSize,
249
- }
250
- }
251
-
252
- /** @deprecated use .gridLocation instead */
253
- getGridLocation() {
254
- return this.gridLocation
255
- }
256
-
257
- isInBoundingBox(boundingBox: MercatorBoundingBox) {
258
- const tileBoundingBox = tileToBoundingBox(this.tile)
259
- return (
260
- boundingBox.contains(tileBoundingBox.getNorthEast())
261
- || boundingBox.contains(tileBoundingBox.getNorthWest())
262
- || boundingBox.contains(tileBoundingBox.getSouthEast())
263
- || boundingBox.contains(tileBoundingBox.getSouthWest())
264
- )
265
- }
266
-
267
- relative(direction: string) {
268
- const directionConstant = assertEx(RelativeDirectionConstantLookup[direction], () => 'Invalid direction')
269
- let quadkey = this.base4Hash
270
- if (quadkey.length === 0) {
271
- return this
272
- }
273
- let index = quadkey.length - 1
274
- while (index >= 0) {
275
- let number = Number.parseInt(quadkey.charAt(index))
276
- number += directionConstant
277
- if (number > 3) {
278
- number -= 4
279
- quadkey = quadkey.slice(0, Math.max(0, index)) + number.toString() + quadkey.slice(Math.max(0, index + 1))
280
- index--
281
- } else if (number < 0) {
282
- number += 4
283
- quadkey = quadkey.slice(0, Math.max(0, index)) + number.toString() + quadkey.slice(Math.max(0, index + 1))
284
- index--
285
- } else {
286
- index = -1
287
- }
288
- }
289
- return Quadkey.fromBase4String(quadkey)
290
- }
291
-
292
- setId(id: bigint) {
293
- assertMaxBitUint(id, 248n)
294
- this.setKey(this.zoom, id)
295
- return this
296
- }
297
-
298
- setKey(zoom: number, key: bigint) {
299
- assertMaxBitUint(key)
300
- this.key = key
301
- this.setZoom(zoom)
302
- return this
303
- }
304
-
305
- setZoom(zoom: number) {
306
- assertEx(zoom < MAX_ZOOM, () => `Invalid zoom [${zoom}] max=${MAX_ZOOM}`)
307
- this.key = (this.key & ID_MASK) | (BigInt(zoom) << 248n)
308
- return this
309
- }
310
-
311
- toJSON(): string {
312
- return this.base4HashLabel
313
- }
314
-
315
- toString() {
316
- return this.base4Hash
317
- }
318
-
319
- protected guessZoom() {
320
- const quadkeySimple = this.id.toString(4)
321
- this.setZoom(quadkeySimple.length)
322
- }
323
- }
@@ -1,6 +0,0 @@
1
- export const RelativeDirectionConstantLookup: Record<string, number> = {
2
- e: 1,
3
- n: -2,
4
- s: 2,
5
- w: -1,
6
- }
package/src/index.ts DELETED
@@ -1 +0,0 @@
1
- export * from './Quadkey.ts'