@xyo-network/quadkey 2.88.3 → 2.89.0-rc.10
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/dist/browser/index.cjs +4 -4
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.js +4 -4
- package/dist/browser/index.js.map +1 -1
- package/dist/node/index.cjs +4 -4
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.js +4 -4
- package/dist/node/index.js.map +1 -1
- package/package.json +6 -5
- package/src/Quadkey.ts +4 -4
package/dist/browser/index.cjs
CHANGED
|
@@ -108,9 +108,9 @@ var Quadkey = class _Quadkey {
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
get siblings() {
|
|
111
|
-
const siblings = (0, import_assert.assertEx)(this.parent?.children, `siblings: parentChildren ${this.base4Hash}`);
|
|
111
|
+
const siblings = (0, import_assert.assertEx)(this.parent?.children, () => `siblings: parentChildren ${this.base4Hash}`);
|
|
112
112
|
const filteredSiblings = siblings.filter((quadkey) => quadkey.key !== this.key);
|
|
113
|
-
(0, import_assert.assertEx)(filteredSiblings.length === 3, `siblings: expected 3 [${filteredSiblings.length}]`);
|
|
113
|
+
(0, import_assert.assertEx)(filteredSiblings.length === 3, () => `siblings: expected 3 [${filteredSiblings.length}]`);
|
|
114
114
|
return filteredSiblings;
|
|
115
115
|
}
|
|
116
116
|
get tile() {
|
|
@@ -142,7 +142,7 @@ var Quadkey = class _Quadkey {
|
|
|
142
142
|
let id = 0n;
|
|
143
143
|
for (let i = 0; i < value.length; i++) {
|
|
144
144
|
const nibble = Number.parseInt(value[i]);
|
|
145
|
-
(0, import_assert.assertEx)(nibble < 4 && nibble >= 0, `Invalid Base4 String: ${value}`);
|
|
145
|
+
(0, import_assert.assertEx)(nibble < 4 && nibble >= 0, () => `Invalid Base4 String: ${value}`);
|
|
146
146
|
id = id << 2n | BigInt(nibble);
|
|
147
147
|
}
|
|
148
148
|
return new _Quadkey().setId(id).setZoom(value.length);
|
|
@@ -277,7 +277,7 @@ var Quadkey = class _Quadkey {
|
|
|
277
277
|
return this;
|
|
278
278
|
}
|
|
279
279
|
setZoom(zoom) {
|
|
280
|
-
(0, import_assert.assertEx)(zoom < MAX_ZOOM, `Invalid zoom [${zoom}] max=${MAX_ZOOM}`);
|
|
280
|
+
(0, import_assert.assertEx)(zoom < MAX_ZOOM, () => `Invalid zoom [${zoom}] max=${MAX_ZOOM}`);
|
|
281
281
|
this.key = this.key & ID_MASK | BigInt(zoom) << 248n;
|
|
282
282
|
return this;
|
|
283
283
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/Quadkey.ts","../../src/RelativeDirectionConstantLookup.ts"],"sourcesContent":["export * from './Quadkey'\n","import { assertEx } from '@xylabs/assert'\nimport { hexFromArrayBuffer, hexFromHexString } from '@xylabs/hex'\nimport {\n boundingBoxToCenter,\n GeoJson,\n MercatorBoundingBox,\n MercatorTile,\n tileFromPoint,\n tileFromQuadkey,\n tilesFromBoundingBox,\n tileToBoundingBox,\n tileToQuadkey,\n} from '@xyo-network/sdk-geo'\nimport { LngLat, LngLatLike } from 'mapbox-gl'\n\nimport { RelativeDirectionConstantLookup } from './RelativeDirectionConstantLookup'\n\nconst MAX_ZOOM = 124\n\nexport const isQuadkey = (obj: { type: string }) => obj?.type === Quadkey.type\n\nconst FULL_MASK = 2n ** 256n - 1n\nconst ZOOM_MASK = 0xffn << 248n\nconst ID_MASK = ZOOM_MASK ^ FULL_MASK\n\nconst assertMaxBitUint = (value: bigint, bits = 256n) => {\n assertEx(value < 2n ** bits && value >= 0, 'Not a 256 Bit Uint!')\n}\n\nexport class Quadkey {\n static Zero = Quadkey.from(0, 0n)\n static root = new Quadkey()\n static type = 'Quadkey'\n\n type = Quadkey.type\n\n private _geoJson?: GeoJson\n\n constructor(private key = 0n) {\n assertMaxBitUint(key)\n this.guessZoom()\n }\n\n get base16String() {\n return this.id.toString(16).padStart(62, '0')\n }\n\n get base4Hash() {\n return this.id.toString(4).padStart(this.zoom, '0')\n }\n\n get base4HashLabel() {\n const hash = this.base4Hash\n return hash.length === 0 ? 'fhr' : hash\n }\n\n get boundingBox(): MercatorBoundingBox {\n return tileToBoundingBox(this.tile)\n }\n\n get center() {\n const result = boundingBoxToCenter(this.boundingBox)\n return new LngLat(result[0], result[1])\n }\n\n get children() {\n assertEx(this.zoom < MAX_ZOOM - 1, 'Can not get children of bottom tiles')\n const result: Quadkey[] = []\n const shiftedId = this.id << 2n\n for (let i = 0n; i < 4n; i++) {\n result.push(new Quadkey().setId(shiftedId | i).setZoom(this.zoom + 1))\n }\n return result\n }\n\n get gridLocation() {\n const tileData = tileFromQuadkey(this.base4Hash)\n\n return {\n col: 2 ** tileData[2] - tileData[1] - 1,\n row: tileData[0],\n zoom: tileData[2],\n }\n }\n\n get id() {\n return this.key & ID_MASK\n }\n\n get parent(): Quadkey | undefined {\n if (this.zoom > 0) {\n return new Quadkey().setId(this.id >> 2n).setZoom(this.zoom - 1)\n }\n }\n\n get siblings() {\n const siblings = assertEx(this.parent?.children, `siblings: parentChildren ${this.base4Hash}`)\n const filteredSiblings = siblings.filter((quadkey) => quadkey.key !== this.key)\n assertEx(filteredSiblings.length === 3, `siblings: expected 3 [${filteredSiblings.length}]`)\n return filteredSiblings\n }\n\n get tile(): MercatorTile {\n return tileFromQuadkey(this.base4Hash)\n }\n\n get valid() {\n //check for additional data outside zoom scope\n return this.id.toString(4) === this.base4Hash.padStart(64, '0')\n }\n\n get zoom() {\n //zoom is stored in top byte\n return Number((this.key & ZOOM_MASK) >> 248n)\n }\n\n static from(zoom: number, id: bigint) {\n return new Quadkey().setId(id).setZoom(zoom)\n }\n\n static fromArrayBuffer(zoom: number, id: ArrayBuffer) {\n return new Quadkey().setId(BigInt(hexFromArrayBuffer(id, { prefix: true }))).setZoom(zoom)\n }\n\n static fromBase16String(value: string) {\n return new Quadkey(BigInt(hexFromHexString(value, { prefix: true })))\n }\n\n static fromBase4String(value?: string) {\n if (value === 'fhr' || value === '' || value === undefined) {\n return Quadkey.root\n }\n let id = 0n\n for (let i = 0; i < value.length; i++) {\n const nibble = Number.parseInt(value[i])\n assertEx(nibble < 4 && nibble >= 0, `Invalid Base4 String: ${value}`)\n id = (id << 2n) | BigInt(nibble)\n }\n return new Quadkey().setId(id).setZoom(value.length)\n }\n\n static fromBoundingBox(boundingBox: MercatorBoundingBox, zoom: number) {\n const tiles = tilesFromBoundingBox(boundingBox, Math.floor(zoom))\n const result: Quadkey[] = []\n for (const tile of tiles) {\n result.push(assertEx(Quadkey.fromTile(tile), 'Bad Quadkey'))\n }\n\n return result\n }\n\n static fromLngLat(point: LngLatLike, zoom: number) {\n const tile = tileFromPoint(LngLat.convert(point), zoom)\n const quadkeyString = tileToQuadkey(tile)\n return Quadkey.fromBase4String(quadkeyString)\n }\n\n static fromString(zoom: number, id: string, base = 16) {\n switch (base) {\n case 16: {\n return Quadkey.fromBase16String(id).setZoom(zoom)\n }\n default: {\n throw new Error(`Invalid base [${base}]`)\n }\n }\n }\n\n static fromTile(tile: MercatorTile) {\n return Quadkey.fromBase4String(tileToQuadkey(tile))\n }\n\n childrenByZoom(zoom: number) {\n // if we are limiting by zoom, and we are already at that limit, just return this quadkey\n if (zoom && zoom === this.zoom) {\n return [this]\n }\n\n // recursively get children\n let deepResult: Quadkey[] = []\n for (const quadkey of this.children) {\n deepResult = [...deepResult, ...quadkey.childrenByZoom(zoom)]\n }\n return deepResult\n }\n\n clone() {\n return new Quadkey(this.key)\n }\n\n equals(obj: Quadkey): boolean {\n return obj.key == this.key\n }\n\n geoJson() {\n this._geoJson = this._geoJson ?? new GeoJson(this.base4Hash)\n return this._geoJson\n }\n\n getGridBoundingBox(size: number) {\n const hash = this.base4Hash\n let index = 0\n let left = 0\n let top = 0\n let blockSize = size\n while (index < hash.length) {\n blockSize >>= 1\n switch (hash[index]) {\n case '1': {\n left += blockSize\n break\n }\n case '2': {\n top += blockSize\n break\n }\n case '3': {\n left += blockSize\n top += blockSize\n break\n }\n }\n index++\n }\n if (blockSize < 2) {\n blockSize = 2\n }\n return {\n height: blockSize,\n left,\n top,\n width: blockSize,\n }\n }\n\n /** @deprecated use .gridLocation instead */\n getGridLocation() {\n return this.gridLocation\n }\n\n isInBoundingBox(boundingBox: MercatorBoundingBox) {\n const tileBoundingBox = tileToBoundingBox(this.tile)\n return (\n boundingBox.contains(tileBoundingBox.getNorthEast()) ||\n boundingBox.contains(tileBoundingBox.getNorthWest()) ||\n boundingBox.contains(tileBoundingBox.getSouthEast()) ||\n boundingBox.contains(tileBoundingBox.getSouthWest())\n )\n }\n\n relative(direction: string) {\n const directionConstant = assertEx(RelativeDirectionConstantLookup[direction], 'Invalid direction')\n let quadkey = this.base4Hash\n if (quadkey.length === 0) {\n return this\n }\n let index = quadkey.length - 1\n while (index >= 0) {\n let number = Number.parseInt(quadkey.charAt(index))\n number += directionConstant\n if (number > 3) {\n number -= 4\n quadkey = quadkey.slice(0, Math.max(0, index)) + number.toString() + quadkey.slice(Math.max(0, index + 1))\n index--\n } else if (number < 0) {\n number += 4\n quadkey = quadkey.slice(0, Math.max(0, index)) + number.toString() + quadkey.slice(Math.max(0, index + 1))\n index--\n } else {\n index = -1\n }\n }\n return Quadkey.fromBase4String(quadkey)\n }\n\n setId(id: bigint) {\n assertMaxBitUint(id, 248n)\n this.setKey(this.zoom, id)\n return this\n }\n\n setKey(zoom: number, key: bigint) {\n assertMaxBitUint(key)\n this.key = key\n this.setZoom(zoom)\n return this\n }\n\n setZoom(zoom: number) {\n assertEx(zoom < MAX_ZOOM, `Invalid zoom [${zoom}] max=${MAX_ZOOM}`)\n this.key = (this.key & ID_MASK) | (BigInt(zoom) << 248n)\n return this\n }\n\n toJSON(): string {\n return this.base4HashLabel\n }\n\n toString() {\n return this.base4Hash\n }\n\n protected guessZoom() {\n const quadkeySimple = this.id.toString(4)\n this.setZoom(quadkeySimple.length)\n }\n}\n","export const RelativeDirectionConstantLookup: Record<string, number> = {\n e: 1,\n n: -2,\n s: 2,\n w: -1,\n}\n"],"mappings":"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","names":["RelativeDirectionConstantLookup","e","n","s","w","MAX_ZOOM","isQuadkey","obj","type","Quadkey","FULL_MASK","ZOOM_MASK","ID_MASK","assertMaxBitUint","value","bits","assertEx","Zero","from","root","_geoJson","constructor","key","guessZoom","base16String","id","toString","padStart","base4Hash","zoom","base4HashLabel","hash","length","boundingBox","tileToBoundingBox","tile","center","result","boundingBoxToCenter","LngLat","children","shiftedId","i","push","setId","setZoom","gridLocation","tileData","tileFromQuadkey","col","row","parent","siblings","filteredSiblings","filter","quadkey","valid","Number","fromArrayBuffer","BigInt","hexFromArrayBuffer","prefix","fromBase16String","hexFromHexString","fromBase4String","undefined","nibble","parseInt","fromBoundingBox","tiles","tilesFromBoundingBox","Math","floor","fromTile","fromLngLat","point","tileFromPoint","convert","quadkeyString","tileToQuadkey","fromString","base","Error","childrenByZoom","deepResult","clone","equals","geoJson","GeoJson","getGridBoundingBox","size","index","left","top","blockSize","height","width","getGridLocation","isInBoundingBox","tileBoundingBox","contains","getNorthEast","getNorthWest","getSouthEast","getSouthWest","relative","direction","directionConstant","RelativeDirectionConstantLookup","number","charAt","slice","max","setKey","toJSON","quadkeySimple"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/Quadkey.ts","../../src/RelativeDirectionConstantLookup.ts"],"sourcesContent":["export * from './Quadkey'\n","import { assertEx } from '@xylabs/assert'\nimport { hexFromArrayBuffer, hexFromHexString } from '@xylabs/hex'\nimport {\n boundingBoxToCenter,\n GeoJson,\n MercatorBoundingBox,\n MercatorTile,\n tileFromPoint,\n tileFromQuadkey,\n tilesFromBoundingBox,\n tileToBoundingBox,\n tileToQuadkey,\n} from '@xyo-network/sdk-geo'\nimport { LngLat, LngLatLike } from 'mapbox-gl'\n\nimport { RelativeDirectionConstantLookup } from './RelativeDirectionConstantLookup'\n\nconst MAX_ZOOM = 124\n\nexport const isQuadkey = (obj: { type: string }) => obj?.type === Quadkey.type\n\nconst FULL_MASK = 2n ** 256n - 1n\nconst ZOOM_MASK = 0xffn << 248n\nconst ID_MASK = ZOOM_MASK ^ FULL_MASK\n\nconst assertMaxBitUint = (value: bigint, bits = 256n) => {\n assertEx(value < 2n ** bits && value >= 0, 'Not a 256 Bit Uint!')\n}\n\nexport class Quadkey {\n static Zero = Quadkey.from(0, 0n)\n static root = new Quadkey()\n static type = 'Quadkey'\n\n type = Quadkey.type\n\n private _geoJson?: GeoJson\n\n constructor(private key = 0n) {\n assertMaxBitUint(key)\n this.guessZoom()\n }\n\n get base16String() {\n return this.id.toString(16).padStart(62, '0')\n }\n\n get base4Hash() {\n return this.id.toString(4).padStart(this.zoom, '0')\n }\n\n get base4HashLabel() {\n const hash = this.base4Hash\n return hash.length === 0 ? 'fhr' : hash\n }\n\n get boundingBox(): MercatorBoundingBox {\n return tileToBoundingBox(this.tile)\n }\n\n get center() {\n const result = boundingBoxToCenter(this.boundingBox)\n return new LngLat(result[0], result[1])\n }\n\n get children() {\n assertEx(this.zoom < MAX_ZOOM - 1, 'Can not get children of bottom tiles')\n const result: Quadkey[] = []\n const shiftedId = this.id << 2n\n for (let i = 0n; i < 4n; i++) {\n result.push(new Quadkey().setId(shiftedId | i).setZoom(this.zoom + 1))\n }\n return result\n }\n\n get gridLocation() {\n const tileData = tileFromQuadkey(this.base4Hash)\n\n return {\n col: 2 ** tileData[2] - tileData[1] - 1,\n row: tileData[0],\n zoom: tileData[2],\n }\n }\n\n get id() {\n return this.key & ID_MASK\n }\n\n get parent(): Quadkey | undefined {\n if (this.zoom > 0) {\n return new Quadkey().setId(this.id >> 2n).setZoom(this.zoom - 1)\n }\n }\n\n get siblings() {\n const siblings = assertEx(this.parent?.children, () => `siblings: parentChildren ${this.base4Hash}`)\n const filteredSiblings = siblings.filter((quadkey) => quadkey.key !== this.key)\n assertEx(filteredSiblings.length === 3, () => `siblings: expected 3 [${filteredSiblings.length}]`)\n return filteredSiblings\n }\n\n get tile(): MercatorTile {\n return tileFromQuadkey(this.base4Hash)\n }\n\n get valid() {\n //check for additional data outside zoom scope\n return this.id.toString(4) === this.base4Hash.padStart(64, '0')\n }\n\n get zoom() {\n //zoom is stored in top byte\n return Number((this.key & ZOOM_MASK) >> 248n)\n }\n\n static from(zoom: number, id: bigint) {\n return new Quadkey().setId(id).setZoom(zoom)\n }\n\n static fromArrayBuffer(zoom: number, id: ArrayBuffer) {\n return new Quadkey().setId(BigInt(hexFromArrayBuffer(id, { prefix: true }))).setZoom(zoom)\n }\n\n static fromBase16String(value: string) {\n return new Quadkey(BigInt(hexFromHexString(value, { prefix: true })))\n }\n\n static fromBase4String(value?: string) {\n if (value === 'fhr' || value === '' || value === undefined) {\n return Quadkey.root\n }\n let id = 0n\n for (let i = 0; i < value.length; i++) {\n const nibble = Number.parseInt(value[i])\n assertEx(nibble < 4 && nibble >= 0, () => `Invalid Base4 String: ${value}`)\n id = (id << 2n) | BigInt(nibble)\n }\n return new Quadkey().setId(id).setZoom(value.length)\n }\n\n static fromBoundingBox(boundingBox: MercatorBoundingBox, zoom: number) {\n const tiles = tilesFromBoundingBox(boundingBox, Math.floor(zoom))\n const result: Quadkey[] = []\n for (const tile of tiles) {\n result.push(assertEx(Quadkey.fromTile(tile), 'Bad Quadkey'))\n }\n\n return result\n }\n\n static fromLngLat(point: LngLatLike, zoom: number) {\n const tile = tileFromPoint(LngLat.convert(point), zoom)\n const quadkeyString = tileToQuadkey(tile)\n return Quadkey.fromBase4String(quadkeyString)\n }\n\n static fromString(zoom: number, id: string, base = 16) {\n switch (base) {\n case 16: {\n return Quadkey.fromBase16String(id).setZoom(zoom)\n }\n default: {\n throw new Error(`Invalid base [${base}]`)\n }\n }\n }\n\n static fromTile(tile: MercatorTile) {\n return Quadkey.fromBase4String(tileToQuadkey(tile))\n }\n\n childrenByZoom(zoom: number) {\n // if we are limiting by zoom, and we are already at that limit, just return this quadkey\n if (zoom && zoom === this.zoom) {\n return [this]\n }\n\n // recursively get children\n let deepResult: Quadkey[] = []\n for (const quadkey of this.children) {\n deepResult = [...deepResult, ...quadkey.childrenByZoom(zoom)]\n }\n return deepResult\n }\n\n clone() {\n return new Quadkey(this.key)\n }\n\n equals(obj: Quadkey): boolean {\n return obj.key == this.key\n }\n\n geoJson() {\n this._geoJson = this._geoJson ?? new GeoJson(this.base4Hash)\n return this._geoJson\n }\n\n getGridBoundingBox(size: number) {\n const hash = this.base4Hash\n let index = 0\n let left = 0\n let top = 0\n let blockSize = size\n while (index < hash.length) {\n blockSize >>= 1\n switch (hash[index]) {\n case '1': {\n left += blockSize\n break\n }\n case '2': {\n top += blockSize\n break\n }\n case '3': {\n left += blockSize\n top += blockSize\n break\n }\n }\n index++\n }\n if (blockSize < 2) {\n blockSize = 2\n }\n return {\n height: blockSize,\n left,\n top,\n width: blockSize,\n }\n }\n\n /** @deprecated use .gridLocation instead */\n getGridLocation() {\n return this.gridLocation\n }\n\n isInBoundingBox(boundingBox: MercatorBoundingBox) {\n const tileBoundingBox = tileToBoundingBox(this.tile)\n return (\n boundingBox.contains(tileBoundingBox.getNorthEast()) ||\n boundingBox.contains(tileBoundingBox.getNorthWest()) ||\n boundingBox.contains(tileBoundingBox.getSouthEast()) ||\n boundingBox.contains(tileBoundingBox.getSouthWest())\n )\n }\n\n relative(direction: string) {\n const directionConstant = assertEx(RelativeDirectionConstantLookup[direction], 'Invalid direction')\n let quadkey = this.base4Hash\n if (quadkey.length === 0) {\n return this\n }\n let index = quadkey.length - 1\n while (index >= 0) {\n let number = Number.parseInt(quadkey.charAt(index))\n number += directionConstant\n if (number > 3) {\n number -= 4\n quadkey = quadkey.slice(0, Math.max(0, index)) + number.toString() + quadkey.slice(Math.max(0, index + 1))\n index--\n } else if (number < 0) {\n number += 4\n quadkey = quadkey.slice(0, Math.max(0, index)) + number.toString() + quadkey.slice(Math.max(0, index + 1))\n index--\n } else {\n index = -1\n }\n }\n return Quadkey.fromBase4String(quadkey)\n }\n\n setId(id: bigint) {\n assertMaxBitUint(id, 248n)\n this.setKey(this.zoom, id)\n return this\n }\n\n setKey(zoom: number, key: bigint) {\n assertMaxBitUint(key)\n this.key = key\n this.setZoom(zoom)\n return this\n }\n\n setZoom(zoom: number) {\n assertEx(zoom < MAX_ZOOM, () => `Invalid zoom [${zoom}] max=${MAX_ZOOM}`)\n this.key = (this.key & ID_MASK) | (BigInt(zoom) << 248n)\n return this\n }\n\n toJSON(): string {\n return this.base4HashLabel\n }\n\n toString() {\n return this.base4Hash\n }\n\n protected guessZoom() {\n const quadkeySimple = this.id.toString(4)\n this.setZoom(quadkeySimple.length)\n }\n}\n","export const RelativeDirectionConstantLookup: Record<string, number> = {\n e: 1,\n n: -2,\n s: 2,\n w: -1,\n}\n"],"mappings":"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","names":["RelativeDirectionConstantLookup","e","n","s","w","MAX_ZOOM","isQuadkey","obj","type","Quadkey","FULL_MASK","ZOOM_MASK","ID_MASK","assertMaxBitUint","value","bits","assertEx","Zero","from","root","_geoJson","constructor","key","guessZoom","base16String","id","toString","padStart","base4Hash","zoom","base4HashLabel","hash","length","boundingBox","tileToBoundingBox","tile","center","result","boundingBoxToCenter","LngLat","children","shiftedId","i","push","setId","setZoom","gridLocation","tileData","tileFromQuadkey","col","row","parent","siblings","filteredSiblings","filter","quadkey","valid","Number","fromArrayBuffer","BigInt","hexFromArrayBuffer","prefix","fromBase16String","hexFromHexString","fromBase4String","undefined","nibble","parseInt","fromBoundingBox","tiles","tilesFromBoundingBox","Math","floor","fromTile","fromLngLat","point","tileFromPoint","convert","quadkeyString","tileToQuadkey","fromString","base","Error","childrenByZoom","deepResult","clone","equals","geoJson","GeoJson","getGridBoundingBox","size","index","left","top","blockSize","height","width","getGridLocation","isInBoundingBox","tileBoundingBox","contains","getNorthEast","getNorthWest","getSouthEast","getSouthWest","relative","direction","directionConstant","RelativeDirectionConstantLookup","number","charAt","slice","max","setKey","toJSON","quadkeySimple"]}
|
package/dist/browser/index.js
CHANGED
|
@@ -83,9 +83,9 @@ var Quadkey = class _Quadkey {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
get siblings() {
|
|
86
|
-
const siblings = assertEx(this.parent?.children, `siblings: parentChildren ${this.base4Hash}`);
|
|
86
|
+
const siblings = assertEx(this.parent?.children, () => `siblings: parentChildren ${this.base4Hash}`);
|
|
87
87
|
const filteredSiblings = siblings.filter((quadkey) => quadkey.key !== this.key);
|
|
88
|
-
assertEx(filteredSiblings.length === 3, `siblings: expected 3 [${filteredSiblings.length}]`);
|
|
88
|
+
assertEx(filteredSiblings.length === 3, () => `siblings: expected 3 [${filteredSiblings.length}]`);
|
|
89
89
|
return filteredSiblings;
|
|
90
90
|
}
|
|
91
91
|
get tile() {
|
|
@@ -117,7 +117,7 @@ var Quadkey = class _Quadkey {
|
|
|
117
117
|
let id = 0n;
|
|
118
118
|
for (let i = 0; i < value.length; i++) {
|
|
119
119
|
const nibble = Number.parseInt(value[i]);
|
|
120
|
-
assertEx(nibble < 4 && nibble >= 0, `Invalid Base4 String: ${value}`);
|
|
120
|
+
assertEx(nibble < 4 && nibble >= 0, () => `Invalid Base4 String: ${value}`);
|
|
121
121
|
id = id << 2n | BigInt(nibble);
|
|
122
122
|
}
|
|
123
123
|
return new _Quadkey().setId(id).setZoom(value.length);
|
|
@@ -252,7 +252,7 @@ var Quadkey = class _Quadkey {
|
|
|
252
252
|
return this;
|
|
253
253
|
}
|
|
254
254
|
setZoom(zoom) {
|
|
255
|
-
assertEx(zoom < MAX_ZOOM, `Invalid zoom [${zoom}] max=${MAX_ZOOM}`);
|
|
255
|
+
assertEx(zoom < MAX_ZOOM, () => `Invalid zoom [${zoom}] max=${MAX_ZOOM}`);
|
|
256
256
|
this.key = this.key & ID_MASK | BigInt(zoom) << 248n;
|
|
257
257
|
return this;
|
|
258
258
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/Quadkey.ts","../../src/RelativeDirectionConstantLookup.ts"],"sourcesContent":["import { assertEx } from '@xylabs/assert'\nimport { hexFromArrayBuffer, hexFromHexString } from '@xylabs/hex'\nimport {\n boundingBoxToCenter,\n GeoJson,\n MercatorBoundingBox,\n MercatorTile,\n tileFromPoint,\n tileFromQuadkey,\n tilesFromBoundingBox,\n tileToBoundingBox,\n tileToQuadkey,\n} from '@xyo-network/sdk-geo'\nimport { LngLat, LngLatLike } from 'mapbox-gl'\n\nimport { RelativeDirectionConstantLookup } from './RelativeDirectionConstantLookup'\n\nconst MAX_ZOOM = 124\n\nexport const isQuadkey = (obj: { type: string }) => obj?.type === Quadkey.type\n\nconst FULL_MASK = 2n ** 256n - 1n\nconst ZOOM_MASK = 0xffn << 248n\nconst ID_MASK = ZOOM_MASK ^ FULL_MASK\n\nconst assertMaxBitUint = (value: bigint, bits = 256n) => {\n assertEx(value < 2n ** bits && value >= 0, 'Not a 256 Bit Uint!')\n}\n\nexport class Quadkey {\n static Zero = Quadkey.from(0, 0n)\n static root = new Quadkey()\n static type = 'Quadkey'\n\n type = Quadkey.type\n\n private _geoJson?: GeoJson\n\n constructor(private key = 0n) {\n assertMaxBitUint(key)\n this.guessZoom()\n }\n\n get base16String() {\n return this.id.toString(16).padStart(62, '0')\n }\n\n get base4Hash() {\n return this.id.toString(4).padStart(this.zoom, '0')\n }\n\n get base4HashLabel() {\n const hash = this.base4Hash\n return hash.length === 0 ? 'fhr' : hash\n }\n\n get boundingBox(): MercatorBoundingBox {\n return tileToBoundingBox(this.tile)\n }\n\n get center() {\n const result = boundingBoxToCenter(this.boundingBox)\n return new LngLat(result[0], result[1])\n }\n\n get children() {\n assertEx(this.zoom < MAX_ZOOM - 1, 'Can not get children of bottom tiles')\n const result: Quadkey[] = []\n const shiftedId = this.id << 2n\n for (let i = 0n; i < 4n; i++) {\n result.push(new Quadkey().setId(shiftedId | i).setZoom(this.zoom + 1))\n }\n return result\n }\n\n get gridLocation() {\n const tileData = tileFromQuadkey(this.base4Hash)\n\n return {\n col: 2 ** tileData[2] - tileData[1] - 1,\n row: tileData[0],\n zoom: tileData[2],\n }\n }\n\n get id() {\n return this.key & ID_MASK\n }\n\n get parent(): Quadkey | undefined {\n if (this.zoom > 0) {\n return new Quadkey().setId(this.id >> 2n).setZoom(this.zoom - 1)\n }\n }\n\n get siblings() {\n const siblings = assertEx(this.parent?.children, `siblings: parentChildren ${this.base4Hash}`)\n const filteredSiblings = siblings.filter((quadkey) => quadkey.key !== this.key)\n assertEx(filteredSiblings.length === 3, `siblings: expected 3 [${filteredSiblings.length}]`)\n return filteredSiblings\n }\n\n get tile(): MercatorTile {\n return tileFromQuadkey(this.base4Hash)\n }\n\n get valid() {\n //check for additional data outside zoom scope\n return this.id.toString(4) === this.base4Hash.padStart(64, '0')\n }\n\n get zoom() {\n //zoom is stored in top byte\n return Number((this.key & ZOOM_MASK) >> 248n)\n }\n\n static from(zoom: number, id: bigint) {\n return new Quadkey().setId(id).setZoom(zoom)\n }\n\n static fromArrayBuffer(zoom: number, id: ArrayBuffer) {\n return new Quadkey().setId(BigInt(hexFromArrayBuffer(id, { prefix: true }))).setZoom(zoom)\n }\n\n static fromBase16String(value: string) {\n return new Quadkey(BigInt(hexFromHexString(value, { prefix: true })))\n }\n\n static fromBase4String(value?: string) {\n if (value === 'fhr' || value === '' || value === undefined) {\n return Quadkey.root\n }\n let id = 0n\n for (let i = 0; i < value.length; i++) {\n const nibble = Number.parseInt(value[i])\n assertEx(nibble < 4 && nibble >= 0, `Invalid Base4 String: ${value}`)\n id = (id << 2n) | BigInt(nibble)\n }\n return new Quadkey().setId(id).setZoom(value.length)\n }\n\n static fromBoundingBox(boundingBox: MercatorBoundingBox, zoom: number) {\n const tiles = tilesFromBoundingBox(boundingBox, Math.floor(zoom))\n const result: Quadkey[] = []\n for (const tile of tiles) {\n result.push(assertEx(Quadkey.fromTile(tile), 'Bad Quadkey'))\n }\n\n return result\n }\n\n static fromLngLat(point: LngLatLike, zoom: number) {\n const tile = tileFromPoint(LngLat.convert(point), zoom)\n const quadkeyString = tileToQuadkey(tile)\n return Quadkey.fromBase4String(quadkeyString)\n }\n\n static fromString(zoom: number, id: string, base = 16) {\n switch (base) {\n case 16: {\n return Quadkey.fromBase16String(id).setZoom(zoom)\n }\n default: {\n throw new Error(`Invalid base [${base}]`)\n }\n }\n }\n\n static fromTile(tile: MercatorTile) {\n return Quadkey.fromBase4String(tileToQuadkey(tile))\n }\n\n childrenByZoom(zoom: number) {\n // if we are limiting by zoom, and we are already at that limit, just return this quadkey\n if (zoom && zoom === this.zoom) {\n return [this]\n }\n\n // recursively get children\n let deepResult: Quadkey[] = []\n for (const quadkey of this.children) {\n deepResult = [...deepResult, ...quadkey.childrenByZoom(zoom)]\n }\n return deepResult\n }\n\n clone() {\n return new Quadkey(this.key)\n }\n\n equals(obj: Quadkey): boolean {\n return obj.key == this.key\n }\n\n geoJson() {\n this._geoJson = this._geoJson ?? new GeoJson(this.base4Hash)\n return this._geoJson\n }\n\n getGridBoundingBox(size: number) {\n const hash = this.base4Hash\n let index = 0\n let left = 0\n let top = 0\n let blockSize = size\n while (index < hash.length) {\n blockSize >>= 1\n switch (hash[index]) {\n case '1': {\n left += blockSize\n break\n }\n case '2': {\n top += blockSize\n break\n }\n case '3': {\n left += blockSize\n top += blockSize\n break\n }\n }\n index++\n }\n if (blockSize < 2) {\n blockSize = 2\n }\n return {\n height: blockSize,\n left,\n top,\n width: blockSize,\n }\n }\n\n /** @deprecated use .gridLocation instead */\n getGridLocation() {\n return this.gridLocation\n }\n\n isInBoundingBox(boundingBox: MercatorBoundingBox) {\n const tileBoundingBox = tileToBoundingBox(this.tile)\n return (\n boundingBox.contains(tileBoundingBox.getNorthEast()) ||\n boundingBox.contains(tileBoundingBox.getNorthWest()) ||\n boundingBox.contains(tileBoundingBox.getSouthEast()) ||\n boundingBox.contains(tileBoundingBox.getSouthWest())\n )\n }\n\n relative(direction: string) {\n const directionConstant = assertEx(RelativeDirectionConstantLookup[direction], 'Invalid direction')\n let quadkey = this.base4Hash\n if (quadkey.length === 0) {\n return this\n }\n let index = quadkey.length - 1\n while (index >= 0) {\n let number = Number.parseInt(quadkey.charAt(index))\n number += directionConstant\n if (number > 3) {\n number -= 4\n quadkey = quadkey.slice(0, Math.max(0, index)) + number.toString() + quadkey.slice(Math.max(0, index + 1))\n index--\n } else if (number < 0) {\n number += 4\n quadkey = quadkey.slice(0, Math.max(0, index)) + number.toString() + quadkey.slice(Math.max(0, index + 1))\n index--\n } else {\n index = -1\n }\n }\n return Quadkey.fromBase4String(quadkey)\n }\n\n setId(id: bigint) {\n assertMaxBitUint(id, 248n)\n this.setKey(this.zoom, id)\n return this\n }\n\n setKey(zoom: number, key: bigint) {\n assertMaxBitUint(key)\n this.key = key\n this.setZoom(zoom)\n return this\n }\n\n setZoom(zoom: number) {\n assertEx(zoom < MAX_ZOOM, `Invalid zoom [${zoom}] max=${MAX_ZOOM}`)\n this.key = (this.key & ID_MASK) | (BigInt(zoom) << 248n)\n return this\n }\n\n toJSON(): string {\n return this.base4HashLabel\n }\n\n toString() {\n return this.base4Hash\n }\n\n protected guessZoom() {\n const quadkeySimple = this.id.toString(4)\n this.setZoom(quadkeySimple.length)\n }\n}\n","export const RelativeDirectionConstantLookup: Record<string, number> = {\n e: 1,\n n: -2,\n s: 2,\n w: -1,\n}\n"],"mappings":"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","names":["assertEx","hexFromArrayBuffer","hexFromHexString","boundingBoxToCenter","GeoJson","tileFromPoint","tileFromQuadkey","tilesFromBoundingBox","tileToBoundingBox","tileToQuadkey","LngLat","RelativeDirectionConstantLookup","e","n","s","w","MAX_ZOOM","isQuadkey","obj","type","Quadkey","FULL_MASK","ZOOM_MASK","ID_MASK","assertMaxBitUint","value","bits","assertEx","Zero","from","root","_geoJson","constructor","key","guessZoom","base16String","id","toString","padStart","base4Hash","zoom","base4HashLabel","hash","length","boundingBox","tileToBoundingBox","tile","center","result","boundingBoxToCenter","LngLat","children","shiftedId","i","push","setId","setZoom","gridLocation","tileData","tileFromQuadkey","col","row","parent","siblings","filteredSiblings","filter","quadkey","valid","Number","fromArrayBuffer","BigInt","hexFromArrayBuffer","prefix","fromBase16String","hexFromHexString","fromBase4String","undefined","nibble","parseInt","fromBoundingBox","tiles","tilesFromBoundingBox","Math","floor","fromTile","fromLngLat","point","tileFromPoint","convert","quadkeyString","tileToQuadkey","fromString","base","Error","childrenByZoom","deepResult","clone","equals","geoJson","GeoJson","getGridBoundingBox","size","index","left","top","blockSize","height","width","getGridLocation","isInBoundingBox","tileBoundingBox","contains","getNorthEast","getNorthWest","getSouthEast","getSouthWest","relative","direction","directionConstant","RelativeDirectionConstantLookup","number","charAt","slice","max","setKey","toJSON","quadkeySimple"]}
|
|
1
|
+
{"version":3,"sources":["../../src/Quadkey.ts","../../src/RelativeDirectionConstantLookup.ts"],"sourcesContent":["import { assertEx } from '@xylabs/assert'\nimport { hexFromArrayBuffer, hexFromHexString } from '@xylabs/hex'\nimport {\n boundingBoxToCenter,\n GeoJson,\n MercatorBoundingBox,\n MercatorTile,\n tileFromPoint,\n tileFromQuadkey,\n tilesFromBoundingBox,\n tileToBoundingBox,\n tileToQuadkey,\n} from '@xyo-network/sdk-geo'\nimport { LngLat, LngLatLike } from 'mapbox-gl'\n\nimport { RelativeDirectionConstantLookup } from './RelativeDirectionConstantLookup'\n\nconst MAX_ZOOM = 124\n\nexport const isQuadkey = (obj: { type: string }) => obj?.type === Quadkey.type\n\nconst FULL_MASK = 2n ** 256n - 1n\nconst ZOOM_MASK = 0xffn << 248n\nconst ID_MASK = ZOOM_MASK ^ FULL_MASK\n\nconst assertMaxBitUint = (value: bigint, bits = 256n) => {\n assertEx(value < 2n ** bits && value >= 0, 'Not a 256 Bit Uint!')\n}\n\nexport class Quadkey {\n static Zero = Quadkey.from(0, 0n)\n static root = new Quadkey()\n static type = 'Quadkey'\n\n type = Quadkey.type\n\n private _geoJson?: GeoJson\n\n constructor(private key = 0n) {\n assertMaxBitUint(key)\n this.guessZoom()\n }\n\n get base16String() {\n return this.id.toString(16).padStart(62, '0')\n }\n\n get base4Hash() {\n return this.id.toString(4).padStart(this.zoom, '0')\n }\n\n get base4HashLabel() {\n const hash = this.base4Hash\n return hash.length === 0 ? 'fhr' : hash\n }\n\n get boundingBox(): MercatorBoundingBox {\n return tileToBoundingBox(this.tile)\n }\n\n get center() {\n const result = boundingBoxToCenter(this.boundingBox)\n return new LngLat(result[0], result[1])\n }\n\n get children() {\n assertEx(this.zoom < MAX_ZOOM - 1, 'Can not get children of bottom tiles')\n const result: Quadkey[] = []\n const shiftedId = this.id << 2n\n for (let i = 0n; i < 4n; i++) {\n result.push(new Quadkey().setId(shiftedId | i).setZoom(this.zoom + 1))\n }\n return result\n }\n\n get gridLocation() {\n const tileData = tileFromQuadkey(this.base4Hash)\n\n return {\n col: 2 ** tileData[2] - tileData[1] - 1,\n row: tileData[0],\n zoom: tileData[2],\n }\n }\n\n get id() {\n return this.key & ID_MASK\n }\n\n get parent(): Quadkey | undefined {\n if (this.zoom > 0) {\n return new Quadkey().setId(this.id >> 2n).setZoom(this.zoom - 1)\n }\n }\n\n get siblings() {\n const siblings = assertEx(this.parent?.children, () => `siblings: parentChildren ${this.base4Hash}`)\n const filteredSiblings = siblings.filter((quadkey) => quadkey.key !== this.key)\n assertEx(filteredSiblings.length === 3, () => `siblings: expected 3 [${filteredSiblings.length}]`)\n return filteredSiblings\n }\n\n get tile(): MercatorTile {\n return tileFromQuadkey(this.base4Hash)\n }\n\n get valid() {\n //check for additional data outside zoom scope\n return this.id.toString(4) === this.base4Hash.padStart(64, '0')\n }\n\n get zoom() {\n //zoom is stored in top byte\n return Number((this.key & ZOOM_MASK) >> 248n)\n }\n\n static from(zoom: number, id: bigint) {\n return new Quadkey().setId(id).setZoom(zoom)\n }\n\n static fromArrayBuffer(zoom: number, id: ArrayBuffer) {\n return new Quadkey().setId(BigInt(hexFromArrayBuffer(id, { prefix: true }))).setZoom(zoom)\n }\n\n static fromBase16String(value: string) {\n return new Quadkey(BigInt(hexFromHexString(value, { prefix: true })))\n }\n\n static fromBase4String(value?: string) {\n if (value === 'fhr' || value === '' || value === undefined) {\n return Quadkey.root\n }\n let id = 0n\n for (let i = 0; i < value.length; i++) {\n const nibble = Number.parseInt(value[i])\n assertEx(nibble < 4 && nibble >= 0, () => `Invalid Base4 String: ${value}`)\n id = (id << 2n) | BigInt(nibble)\n }\n return new Quadkey().setId(id).setZoom(value.length)\n }\n\n static fromBoundingBox(boundingBox: MercatorBoundingBox, zoom: number) {\n const tiles = tilesFromBoundingBox(boundingBox, Math.floor(zoom))\n const result: Quadkey[] = []\n for (const tile of tiles) {\n result.push(assertEx(Quadkey.fromTile(tile), 'Bad Quadkey'))\n }\n\n return result\n }\n\n static fromLngLat(point: LngLatLike, zoom: number) {\n const tile = tileFromPoint(LngLat.convert(point), zoom)\n const quadkeyString = tileToQuadkey(tile)\n return Quadkey.fromBase4String(quadkeyString)\n }\n\n static fromString(zoom: number, id: string, base = 16) {\n switch (base) {\n case 16: {\n return Quadkey.fromBase16String(id).setZoom(zoom)\n }\n default: {\n throw new Error(`Invalid base [${base}]`)\n }\n }\n }\n\n static fromTile(tile: MercatorTile) {\n return Quadkey.fromBase4String(tileToQuadkey(tile))\n }\n\n childrenByZoom(zoom: number) {\n // if we are limiting by zoom, and we are already at that limit, just return this quadkey\n if (zoom && zoom === this.zoom) {\n return [this]\n }\n\n // recursively get children\n let deepResult: Quadkey[] = []\n for (const quadkey of this.children) {\n deepResult = [...deepResult, ...quadkey.childrenByZoom(zoom)]\n }\n return deepResult\n }\n\n clone() {\n return new Quadkey(this.key)\n }\n\n equals(obj: Quadkey): boolean {\n return obj.key == this.key\n }\n\n geoJson() {\n this._geoJson = this._geoJson ?? new GeoJson(this.base4Hash)\n return this._geoJson\n }\n\n getGridBoundingBox(size: number) {\n const hash = this.base4Hash\n let index = 0\n let left = 0\n let top = 0\n let blockSize = size\n while (index < hash.length) {\n blockSize >>= 1\n switch (hash[index]) {\n case '1': {\n left += blockSize\n break\n }\n case '2': {\n top += blockSize\n break\n }\n case '3': {\n left += blockSize\n top += blockSize\n break\n }\n }\n index++\n }\n if (blockSize < 2) {\n blockSize = 2\n }\n return {\n height: blockSize,\n left,\n top,\n width: blockSize,\n }\n }\n\n /** @deprecated use .gridLocation instead */\n getGridLocation() {\n return this.gridLocation\n }\n\n isInBoundingBox(boundingBox: MercatorBoundingBox) {\n const tileBoundingBox = tileToBoundingBox(this.tile)\n return (\n boundingBox.contains(tileBoundingBox.getNorthEast()) ||\n boundingBox.contains(tileBoundingBox.getNorthWest()) ||\n boundingBox.contains(tileBoundingBox.getSouthEast()) ||\n boundingBox.contains(tileBoundingBox.getSouthWest())\n )\n }\n\n relative(direction: string) {\n const directionConstant = assertEx(RelativeDirectionConstantLookup[direction], 'Invalid direction')\n let quadkey = this.base4Hash\n if (quadkey.length === 0) {\n return this\n }\n let index = quadkey.length - 1\n while (index >= 0) {\n let number = Number.parseInt(quadkey.charAt(index))\n number += directionConstant\n if (number > 3) {\n number -= 4\n quadkey = quadkey.slice(0, Math.max(0, index)) + number.toString() + quadkey.slice(Math.max(0, index + 1))\n index--\n } else if (number < 0) {\n number += 4\n quadkey = quadkey.slice(0, Math.max(0, index)) + number.toString() + quadkey.slice(Math.max(0, index + 1))\n index--\n } else {\n index = -1\n }\n }\n return Quadkey.fromBase4String(quadkey)\n }\n\n setId(id: bigint) {\n assertMaxBitUint(id, 248n)\n this.setKey(this.zoom, id)\n return this\n }\n\n setKey(zoom: number, key: bigint) {\n assertMaxBitUint(key)\n this.key = key\n this.setZoom(zoom)\n return this\n }\n\n setZoom(zoom: number) {\n assertEx(zoom < MAX_ZOOM, () => `Invalid zoom [${zoom}] max=${MAX_ZOOM}`)\n this.key = (this.key & ID_MASK) | (BigInt(zoom) << 248n)\n return this\n }\n\n toJSON(): string {\n return this.base4HashLabel\n }\n\n toString() {\n return this.base4Hash\n }\n\n protected guessZoom() {\n const quadkeySimple = this.id.toString(4)\n this.setZoom(quadkeySimple.length)\n }\n}\n","export const RelativeDirectionConstantLookup: Record<string, number> = {\n e: 1,\n n: -2,\n s: 2,\n w: -1,\n}\n"],"mappings":"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","names":["assertEx","hexFromArrayBuffer","hexFromHexString","boundingBoxToCenter","GeoJson","tileFromPoint","tileFromQuadkey","tilesFromBoundingBox","tileToBoundingBox","tileToQuadkey","LngLat","RelativeDirectionConstantLookup","e","n","s","w","MAX_ZOOM","isQuadkey","obj","type","Quadkey","FULL_MASK","ZOOM_MASK","ID_MASK","assertMaxBitUint","value","bits","assertEx","Zero","from","root","_geoJson","constructor","key","guessZoom","base16String","id","toString","padStart","base4Hash","zoom","base4HashLabel","hash","length","boundingBox","tileToBoundingBox","tile","center","result","boundingBoxToCenter","LngLat","children","shiftedId","i","push","setId","setZoom","gridLocation","tileData","tileFromQuadkey","col","row","parent","siblings","filteredSiblings","filter","quadkey","valid","Number","fromArrayBuffer","BigInt","hexFromArrayBuffer","prefix","fromBase16String","hexFromHexString","fromBase4String","undefined","nibble","parseInt","fromBoundingBox","tiles","tilesFromBoundingBox","Math","floor","fromTile","fromLngLat","point","tileFromPoint","convert","quadkeyString","tileToQuadkey","fromString","base","Error","childrenByZoom","deepResult","clone","equals","geoJson","GeoJson","getGridBoundingBox","size","index","left","top","blockSize","height","width","getGridLocation","isInBoundingBox","tileBoundingBox","contains","getNorthEast","getNorthWest","getSouthEast","getSouthWest","relative","direction","directionConstant","RelativeDirectionConstantLookup","number","charAt","slice","max","setKey","toJSON","quadkeySimple"]}
|
package/dist/node/index.cjs
CHANGED
|
@@ -108,9 +108,9 @@ var _Quadkey = class _Quadkey {
|
|
|
108
108
|
}
|
|
109
109
|
get siblings() {
|
|
110
110
|
var _a;
|
|
111
|
-
const siblings = (0, import_assert.assertEx)((_a = this.parent) == null ? void 0 : _a.children, `siblings: parentChildren ${this.base4Hash}`);
|
|
111
|
+
const siblings = (0, import_assert.assertEx)((_a = this.parent) == null ? void 0 : _a.children, () => `siblings: parentChildren ${this.base4Hash}`);
|
|
112
112
|
const filteredSiblings = siblings.filter((quadkey) => quadkey.key !== this.key);
|
|
113
|
-
(0, import_assert.assertEx)(filteredSiblings.length === 3, `siblings: expected 3 [${filteredSiblings.length}]`);
|
|
113
|
+
(0, import_assert.assertEx)(filteredSiblings.length === 3, () => `siblings: expected 3 [${filteredSiblings.length}]`);
|
|
114
114
|
return filteredSiblings;
|
|
115
115
|
}
|
|
116
116
|
get tile() {
|
|
@@ -142,7 +142,7 @@ var _Quadkey = class _Quadkey {
|
|
|
142
142
|
let id = 0n;
|
|
143
143
|
for (let i = 0; i < value.length; i++) {
|
|
144
144
|
const nibble = Number.parseInt(value[i]);
|
|
145
|
-
(0, import_assert.assertEx)(nibble < 4 && nibble >= 0, `Invalid Base4 String: ${value}`);
|
|
145
|
+
(0, import_assert.assertEx)(nibble < 4 && nibble >= 0, () => `Invalid Base4 String: ${value}`);
|
|
146
146
|
id = id << 2n | BigInt(nibble);
|
|
147
147
|
}
|
|
148
148
|
return new _Quadkey().setId(id).setZoom(value.length);
|
|
@@ -277,7 +277,7 @@ var _Quadkey = class _Quadkey {
|
|
|
277
277
|
return this;
|
|
278
278
|
}
|
|
279
279
|
setZoom(zoom) {
|
|
280
|
-
(0, import_assert.assertEx)(zoom < MAX_ZOOM, `Invalid zoom [${zoom}] max=${MAX_ZOOM}`);
|
|
280
|
+
(0, import_assert.assertEx)(zoom < MAX_ZOOM, () => `Invalid zoom [${zoom}] max=${MAX_ZOOM}`);
|
|
281
281
|
this.key = this.key & ID_MASK | BigInt(zoom) << 248n;
|
|
282
282
|
return this;
|
|
283
283
|
}
|
package/dist/node/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/Quadkey.ts","../../src/RelativeDirectionConstantLookup.ts"],"sourcesContent":["export * from './Quadkey'\n","import { assertEx } from '@xylabs/assert'\nimport { hexFromArrayBuffer, hexFromHexString } from '@xylabs/hex'\nimport {\n boundingBoxToCenter,\n GeoJson,\n MercatorBoundingBox,\n MercatorTile,\n tileFromPoint,\n tileFromQuadkey,\n tilesFromBoundingBox,\n tileToBoundingBox,\n tileToQuadkey,\n} from '@xyo-network/sdk-geo'\nimport { LngLat, LngLatLike } from 'mapbox-gl'\n\nimport { RelativeDirectionConstantLookup } from './RelativeDirectionConstantLookup'\n\nconst MAX_ZOOM = 124\n\nexport const isQuadkey = (obj: { type: string }) => obj?.type === Quadkey.type\n\nconst FULL_MASK = 2n ** 256n - 1n\nconst ZOOM_MASK = 0xffn << 248n\nconst ID_MASK = ZOOM_MASK ^ FULL_MASK\n\nconst assertMaxBitUint = (value: bigint, bits = 256n) => {\n assertEx(value < 2n ** bits && value >= 0, 'Not a 256 Bit Uint!')\n}\n\nexport class Quadkey {\n static Zero = Quadkey.from(0, 0n)\n static root = new Quadkey()\n static type = 'Quadkey'\n\n type = Quadkey.type\n\n private _geoJson?: GeoJson\n\n constructor(private key = 0n) {\n assertMaxBitUint(key)\n this.guessZoom()\n }\n\n get base16String() {\n return this.id.toString(16).padStart(62, '0')\n }\n\n get base4Hash() {\n return this.id.toString(4).padStart(this.zoom, '0')\n }\n\n get base4HashLabel() {\n const hash = this.base4Hash\n return hash.length === 0 ? 'fhr' : hash\n }\n\n get boundingBox(): MercatorBoundingBox {\n return tileToBoundingBox(this.tile)\n }\n\n get center() {\n const result = boundingBoxToCenter(this.boundingBox)\n return new LngLat(result[0], result[1])\n }\n\n get children() {\n assertEx(this.zoom < MAX_ZOOM - 1, 'Can not get children of bottom tiles')\n const result: Quadkey[] = []\n const shiftedId = this.id << 2n\n for (let i = 0n; i < 4n; i++) {\n result.push(new Quadkey().setId(shiftedId | i).setZoom(this.zoom + 1))\n }\n return result\n }\n\n get gridLocation() {\n const tileData = tileFromQuadkey(this.base4Hash)\n\n return {\n col: 2 ** tileData[2] - tileData[1] - 1,\n row: tileData[0],\n zoom: tileData[2],\n }\n }\n\n get id() {\n return this.key & ID_MASK\n }\n\n get parent(): Quadkey | undefined {\n if (this.zoom > 0) {\n return new Quadkey().setId(this.id >> 2n).setZoom(this.zoom - 1)\n }\n }\n\n get siblings() {\n const siblings = assertEx(this.parent?.children, `siblings: parentChildren ${this.base4Hash}`)\n const filteredSiblings = siblings.filter((quadkey) => quadkey.key !== this.key)\n assertEx(filteredSiblings.length === 3, `siblings: expected 3 [${filteredSiblings.length}]`)\n return filteredSiblings\n }\n\n get tile(): MercatorTile {\n return tileFromQuadkey(this.base4Hash)\n }\n\n get valid() {\n //check for additional data outside zoom scope\n return this.id.toString(4) === this.base4Hash.padStart(64, '0')\n }\n\n get zoom() {\n //zoom is stored in top byte\n return Number((this.key & ZOOM_MASK) >> 248n)\n }\n\n static from(zoom: number, id: bigint) {\n return new Quadkey().setId(id).setZoom(zoom)\n }\n\n static fromArrayBuffer(zoom: number, id: ArrayBuffer) {\n return new Quadkey().setId(BigInt(hexFromArrayBuffer(id, { prefix: true }))).setZoom(zoom)\n }\n\n static fromBase16String(value: string) {\n return new Quadkey(BigInt(hexFromHexString(value, { prefix: true })))\n }\n\n static fromBase4String(value?: string) {\n if (value === 'fhr' || value === '' || value === undefined) {\n return Quadkey.root\n }\n let id = 0n\n for (let i = 0; i < value.length; i++) {\n const nibble = Number.parseInt(value[i])\n assertEx(nibble < 4 && nibble >= 0, `Invalid Base4 String: ${value}`)\n id = (id << 2n) | BigInt(nibble)\n }\n return new Quadkey().setId(id).setZoom(value.length)\n }\n\n static fromBoundingBox(boundingBox: MercatorBoundingBox, zoom: number) {\n const tiles = tilesFromBoundingBox(boundingBox, Math.floor(zoom))\n const result: Quadkey[] = []\n for (const tile of tiles) {\n result.push(assertEx(Quadkey.fromTile(tile), 'Bad Quadkey'))\n }\n\n return result\n }\n\n static fromLngLat(point: LngLatLike, zoom: number) {\n const tile = tileFromPoint(LngLat.convert(point), zoom)\n const quadkeyString = tileToQuadkey(tile)\n return Quadkey.fromBase4String(quadkeyString)\n }\n\n static fromString(zoom: number, id: string, base = 16) {\n switch (base) {\n case 16: {\n return Quadkey.fromBase16String(id).setZoom(zoom)\n }\n default: {\n throw new Error(`Invalid base [${base}]`)\n }\n }\n }\n\n static fromTile(tile: MercatorTile) {\n return Quadkey.fromBase4String(tileToQuadkey(tile))\n }\n\n childrenByZoom(zoom: number) {\n // if we are limiting by zoom, and we are already at that limit, just return this quadkey\n if (zoom && zoom === this.zoom) {\n return [this]\n }\n\n // recursively get children\n let deepResult: Quadkey[] = []\n for (const quadkey of this.children) {\n deepResult = [...deepResult, ...quadkey.childrenByZoom(zoom)]\n }\n return deepResult\n }\n\n clone() {\n return new Quadkey(this.key)\n }\n\n equals(obj: Quadkey): boolean {\n return obj.key == this.key\n }\n\n geoJson() {\n this._geoJson = this._geoJson ?? new GeoJson(this.base4Hash)\n return this._geoJson\n }\n\n getGridBoundingBox(size: number) {\n const hash = this.base4Hash\n let index = 0\n let left = 0\n let top = 0\n let blockSize = size\n while (index < hash.length) {\n blockSize >>= 1\n switch (hash[index]) {\n case '1': {\n left += blockSize\n break\n }\n case '2': {\n top += blockSize\n break\n }\n case '3': {\n left += blockSize\n top += blockSize\n break\n }\n }\n index++\n }\n if (blockSize < 2) {\n blockSize = 2\n }\n return {\n height: blockSize,\n left,\n top,\n width: blockSize,\n }\n }\n\n /** @deprecated use .gridLocation instead */\n getGridLocation() {\n return this.gridLocation\n }\n\n isInBoundingBox(boundingBox: MercatorBoundingBox) {\n const tileBoundingBox = tileToBoundingBox(this.tile)\n return (\n boundingBox.contains(tileBoundingBox.getNorthEast()) ||\n boundingBox.contains(tileBoundingBox.getNorthWest()) ||\n boundingBox.contains(tileBoundingBox.getSouthEast()) ||\n boundingBox.contains(tileBoundingBox.getSouthWest())\n )\n }\n\n relative(direction: string) {\n const directionConstant = assertEx(RelativeDirectionConstantLookup[direction], 'Invalid direction')\n let quadkey = this.base4Hash\n if (quadkey.length === 0) {\n return this\n }\n let index = quadkey.length - 1\n while (index >= 0) {\n let number = Number.parseInt(quadkey.charAt(index))\n number += directionConstant\n if (number > 3) {\n number -= 4\n quadkey = quadkey.slice(0, Math.max(0, index)) + number.toString() + quadkey.slice(Math.max(0, index + 1))\n index--\n } else if (number < 0) {\n number += 4\n quadkey = quadkey.slice(0, Math.max(0, index)) + number.toString() + quadkey.slice(Math.max(0, index + 1))\n index--\n } else {\n index = -1\n }\n }\n return Quadkey.fromBase4String(quadkey)\n }\n\n setId(id: bigint) {\n assertMaxBitUint(id, 248n)\n this.setKey(this.zoom, id)\n return this\n }\n\n setKey(zoom: number, key: bigint) {\n assertMaxBitUint(key)\n this.key = key\n this.setZoom(zoom)\n return this\n }\n\n setZoom(zoom: number) {\n assertEx(zoom < MAX_ZOOM, `Invalid zoom [${zoom}] max=${MAX_ZOOM}`)\n this.key = (this.key & ID_MASK) | (BigInt(zoom) << 248n)\n return this\n }\n\n toJSON(): string {\n return this.base4HashLabel\n }\n\n toString() {\n return this.base4Hash\n }\n\n protected guessZoom() {\n const quadkeySimple = this.id.toString(4)\n this.setZoom(quadkeySimple.length)\n }\n}\n","export const RelativeDirectionConstantLookup: Record<string, number> = {\n e: 1,\n n: -2,\n s: 2,\n w: -1,\n}\n"],"mappings":"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","names":["RelativeDirectionConstantLookup","e","n","s","w","MAX_ZOOM","isQuadkey","obj","type","Quadkey","FULL_MASK","ZOOM_MASK","ID_MASK","assertMaxBitUint","value","bits","assertEx","_geoJson","constructor","key","guessZoom","base16String","id","toString","padStart","base4Hash","zoom","base4HashLabel","hash","length","boundingBox","tileToBoundingBox","tile","center","result","boundingBoxToCenter","LngLat","children","shiftedId","i","push","setId","setZoom","gridLocation","tileData","tileFromQuadkey","col","row","parent","siblings","filteredSiblings","filter","quadkey","valid","Number","from","fromArrayBuffer","BigInt","hexFromArrayBuffer","prefix","fromBase16String","hexFromHexString","fromBase4String","undefined","root","nibble","parseInt","fromBoundingBox","tiles","tilesFromBoundingBox","Math","floor","fromTile","fromLngLat","point","tileFromPoint","convert","quadkeyString","tileToQuadkey","fromString","base","Error","childrenByZoom","deepResult","clone","equals","geoJson","GeoJson","getGridBoundingBox","size","index","left","top","blockSize","height","width","getGridLocation","isInBoundingBox","tileBoundingBox","contains","getNorthEast","getNorthWest","getSouthEast","getSouthWest","relative","direction","directionConstant","RelativeDirectionConstantLookup","number","charAt","slice","max","setKey","toJSON","quadkeySimple","Zero"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/Quadkey.ts","../../src/RelativeDirectionConstantLookup.ts"],"sourcesContent":["export * from './Quadkey'\n","import { assertEx } from '@xylabs/assert'\nimport { hexFromArrayBuffer, hexFromHexString } from '@xylabs/hex'\nimport {\n boundingBoxToCenter,\n GeoJson,\n MercatorBoundingBox,\n MercatorTile,\n tileFromPoint,\n tileFromQuadkey,\n tilesFromBoundingBox,\n tileToBoundingBox,\n tileToQuadkey,\n} from '@xyo-network/sdk-geo'\nimport { LngLat, LngLatLike } from 'mapbox-gl'\n\nimport { RelativeDirectionConstantLookup } from './RelativeDirectionConstantLookup'\n\nconst MAX_ZOOM = 124\n\nexport const isQuadkey = (obj: { type: string }) => obj?.type === Quadkey.type\n\nconst FULL_MASK = 2n ** 256n - 1n\nconst ZOOM_MASK = 0xffn << 248n\nconst ID_MASK = ZOOM_MASK ^ FULL_MASK\n\nconst assertMaxBitUint = (value: bigint, bits = 256n) => {\n assertEx(value < 2n ** bits && value >= 0, 'Not a 256 Bit Uint!')\n}\n\nexport class Quadkey {\n static Zero = Quadkey.from(0, 0n)\n static root = new Quadkey()\n static type = 'Quadkey'\n\n type = Quadkey.type\n\n private _geoJson?: GeoJson\n\n constructor(private key = 0n) {\n assertMaxBitUint(key)\n this.guessZoom()\n }\n\n get base16String() {\n return this.id.toString(16).padStart(62, '0')\n }\n\n get base4Hash() {\n return this.id.toString(4).padStart(this.zoom, '0')\n }\n\n get base4HashLabel() {\n const hash = this.base4Hash\n return hash.length === 0 ? 'fhr' : hash\n }\n\n get boundingBox(): MercatorBoundingBox {\n return tileToBoundingBox(this.tile)\n }\n\n get center() {\n const result = boundingBoxToCenter(this.boundingBox)\n return new LngLat(result[0], result[1])\n }\n\n get children() {\n assertEx(this.zoom < MAX_ZOOM - 1, 'Can not get children of bottom tiles')\n const result: Quadkey[] = []\n const shiftedId = this.id << 2n\n for (let i = 0n; i < 4n; i++) {\n result.push(new Quadkey().setId(shiftedId | i).setZoom(this.zoom + 1))\n }\n return result\n }\n\n get gridLocation() {\n const tileData = tileFromQuadkey(this.base4Hash)\n\n return {\n col: 2 ** tileData[2] - tileData[1] - 1,\n row: tileData[0],\n zoom: tileData[2],\n }\n }\n\n get id() {\n return this.key & ID_MASK\n }\n\n get parent(): Quadkey | undefined {\n if (this.zoom > 0) {\n return new Quadkey().setId(this.id >> 2n).setZoom(this.zoom - 1)\n }\n }\n\n get siblings() {\n const siblings = assertEx(this.parent?.children, () => `siblings: parentChildren ${this.base4Hash}`)\n const filteredSiblings = siblings.filter((quadkey) => quadkey.key !== this.key)\n assertEx(filteredSiblings.length === 3, () => `siblings: expected 3 [${filteredSiblings.length}]`)\n return filteredSiblings\n }\n\n get tile(): MercatorTile {\n return tileFromQuadkey(this.base4Hash)\n }\n\n get valid() {\n //check for additional data outside zoom scope\n return this.id.toString(4) === this.base4Hash.padStart(64, '0')\n }\n\n get zoom() {\n //zoom is stored in top byte\n return Number((this.key & ZOOM_MASK) >> 248n)\n }\n\n static from(zoom: number, id: bigint) {\n return new Quadkey().setId(id).setZoom(zoom)\n }\n\n static fromArrayBuffer(zoom: number, id: ArrayBuffer) {\n return new Quadkey().setId(BigInt(hexFromArrayBuffer(id, { prefix: true }))).setZoom(zoom)\n }\n\n static fromBase16String(value: string) {\n return new Quadkey(BigInt(hexFromHexString(value, { prefix: true })))\n }\n\n static fromBase4String(value?: string) {\n if (value === 'fhr' || value === '' || value === undefined) {\n return Quadkey.root\n }\n let id = 0n\n for (let i = 0; i < value.length; i++) {\n const nibble = Number.parseInt(value[i])\n assertEx(nibble < 4 && nibble >= 0, () => `Invalid Base4 String: ${value}`)\n id = (id << 2n) | BigInt(nibble)\n }\n return new Quadkey().setId(id).setZoom(value.length)\n }\n\n static fromBoundingBox(boundingBox: MercatorBoundingBox, zoom: number) {\n const tiles = tilesFromBoundingBox(boundingBox, Math.floor(zoom))\n const result: Quadkey[] = []\n for (const tile of tiles) {\n result.push(assertEx(Quadkey.fromTile(tile), 'Bad Quadkey'))\n }\n\n return result\n }\n\n static fromLngLat(point: LngLatLike, zoom: number) {\n const tile = tileFromPoint(LngLat.convert(point), zoom)\n const quadkeyString = tileToQuadkey(tile)\n return Quadkey.fromBase4String(quadkeyString)\n }\n\n static fromString(zoom: number, id: string, base = 16) {\n switch (base) {\n case 16: {\n return Quadkey.fromBase16String(id).setZoom(zoom)\n }\n default: {\n throw new Error(`Invalid base [${base}]`)\n }\n }\n }\n\n static fromTile(tile: MercatorTile) {\n return Quadkey.fromBase4String(tileToQuadkey(tile))\n }\n\n childrenByZoom(zoom: number) {\n // if we are limiting by zoom, and we are already at that limit, just return this quadkey\n if (zoom && zoom === this.zoom) {\n return [this]\n }\n\n // recursively get children\n let deepResult: Quadkey[] = []\n for (const quadkey of this.children) {\n deepResult = [...deepResult, ...quadkey.childrenByZoom(zoom)]\n }\n return deepResult\n }\n\n clone() {\n return new Quadkey(this.key)\n }\n\n equals(obj: Quadkey): boolean {\n return obj.key == this.key\n }\n\n geoJson() {\n this._geoJson = this._geoJson ?? new GeoJson(this.base4Hash)\n return this._geoJson\n }\n\n getGridBoundingBox(size: number) {\n const hash = this.base4Hash\n let index = 0\n let left = 0\n let top = 0\n let blockSize = size\n while (index < hash.length) {\n blockSize >>= 1\n switch (hash[index]) {\n case '1': {\n left += blockSize\n break\n }\n case '2': {\n top += blockSize\n break\n }\n case '3': {\n left += blockSize\n top += blockSize\n break\n }\n }\n index++\n }\n if (blockSize < 2) {\n blockSize = 2\n }\n return {\n height: blockSize,\n left,\n top,\n width: blockSize,\n }\n }\n\n /** @deprecated use .gridLocation instead */\n getGridLocation() {\n return this.gridLocation\n }\n\n isInBoundingBox(boundingBox: MercatorBoundingBox) {\n const tileBoundingBox = tileToBoundingBox(this.tile)\n return (\n boundingBox.contains(tileBoundingBox.getNorthEast()) ||\n boundingBox.contains(tileBoundingBox.getNorthWest()) ||\n boundingBox.contains(tileBoundingBox.getSouthEast()) ||\n boundingBox.contains(tileBoundingBox.getSouthWest())\n )\n }\n\n relative(direction: string) {\n const directionConstant = assertEx(RelativeDirectionConstantLookup[direction], 'Invalid direction')\n let quadkey = this.base4Hash\n if (quadkey.length === 0) {\n return this\n }\n let index = quadkey.length - 1\n while (index >= 0) {\n let number = Number.parseInt(quadkey.charAt(index))\n number += directionConstant\n if (number > 3) {\n number -= 4\n quadkey = quadkey.slice(0, Math.max(0, index)) + number.toString() + quadkey.slice(Math.max(0, index + 1))\n index--\n } else if (number < 0) {\n number += 4\n quadkey = quadkey.slice(0, Math.max(0, index)) + number.toString() + quadkey.slice(Math.max(0, index + 1))\n index--\n } else {\n index = -1\n }\n }\n return Quadkey.fromBase4String(quadkey)\n }\n\n setId(id: bigint) {\n assertMaxBitUint(id, 248n)\n this.setKey(this.zoom, id)\n return this\n }\n\n setKey(zoom: number, key: bigint) {\n assertMaxBitUint(key)\n this.key = key\n this.setZoom(zoom)\n return this\n }\n\n setZoom(zoom: number) {\n assertEx(zoom < MAX_ZOOM, () => `Invalid zoom [${zoom}] max=${MAX_ZOOM}`)\n this.key = (this.key & ID_MASK) | (BigInt(zoom) << 248n)\n return this\n }\n\n toJSON(): string {\n return this.base4HashLabel\n }\n\n toString() {\n return this.base4Hash\n }\n\n protected guessZoom() {\n const quadkeySimple = this.id.toString(4)\n this.setZoom(quadkeySimple.length)\n }\n}\n","export const RelativeDirectionConstantLookup: Record<string, number> = {\n e: 1,\n n: -2,\n s: 2,\n w: -1,\n}\n"],"mappings":"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","names":["RelativeDirectionConstantLookup","e","n","s","w","MAX_ZOOM","isQuadkey","obj","type","Quadkey","FULL_MASK","ZOOM_MASK","ID_MASK","assertMaxBitUint","value","bits","assertEx","_geoJson","constructor","key","guessZoom","base16String","id","toString","padStart","base4Hash","zoom","base4HashLabel","hash","length","boundingBox","tileToBoundingBox","tile","center","result","boundingBoxToCenter","LngLat","children","shiftedId","i","push","setId","setZoom","gridLocation","tileData","tileFromQuadkey","col","row","parent","siblings","filteredSiblings","filter","quadkey","valid","Number","from","fromArrayBuffer","BigInt","hexFromArrayBuffer","prefix","fromBase16String","hexFromHexString","fromBase4String","undefined","root","nibble","parseInt","fromBoundingBox","tiles","tilesFromBoundingBox","Math","floor","fromTile","fromLngLat","point","tileFromPoint","convert","quadkeyString","tileToQuadkey","fromString","base","Error","childrenByZoom","deepResult","clone","equals","geoJson","GeoJson","getGridBoundingBox","size","index","left","top","blockSize","height","width","getGridLocation","isInBoundingBox","tileBoundingBox","contains","getNorthEast","getNorthWest","getSouthEast","getSouthWest","relative","direction","directionConstant","RelativeDirectionConstantLookup","number","charAt","slice","max","setKey","toJSON","quadkeySimple","Zero"]}
|
package/dist/node/index.js
CHANGED
|
@@ -83,9 +83,9 @@ var _Quadkey = class _Quadkey {
|
|
|
83
83
|
}
|
|
84
84
|
get siblings() {
|
|
85
85
|
var _a;
|
|
86
|
-
const siblings = assertEx((_a = this.parent) == null ? void 0 : _a.children, `siblings: parentChildren ${this.base4Hash}`);
|
|
86
|
+
const siblings = assertEx((_a = this.parent) == null ? void 0 : _a.children, () => `siblings: parentChildren ${this.base4Hash}`);
|
|
87
87
|
const filteredSiblings = siblings.filter((quadkey) => quadkey.key !== this.key);
|
|
88
|
-
assertEx(filteredSiblings.length === 3, `siblings: expected 3 [${filteredSiblings.length}]`);
|
|
88
|
+
assertEx(filteredSiblings.length === 3, () => `siblings: expected 3 [${filteredSiblings.length}]`);
|
|
89
89
|
return filteredSiblings;
|
|
90
90
|
}
|
|
91
91
|
get tile() {
|
|
@@ -117,7 +117,7 @@ var _Quadkey = class _Quadkey {
|
|
|
117
117
|
let id = 0n;
|
|
118
118
|
for (let i = 0; i < value.length; i++) {
|
|
119
119
|
const nibble = Number.parseInt(value[i]);
|
|
120
|
-
assertEx(nibble < 4 && nibble >= 0, `Invalid Base4 String: ${value}`);
|
|
120
|
+
assertEx(nibble < 4 && nibble >= 0, () => `Invalid Base4 String: ${value}`);
|
|
121
121
|
id = id << 2n | BigInt(nibble);
|
|
122
122
|
}
|
|
123
123
|
return new _Quadkey().setId(id).setZoom(value.length);
|
|
@@ -252,7 +252,7 @@ var _Quadkey = class _Quadkey {
|
|
|
252
252
|
return this;
|
|
253
253
|
}
|
|
254
254
|
setZoom(zoom) {
|
|
255
|
-
assertEx(zoom < MAX_ZOOM, `Invalid zoom [${zoom}] max=${MAX_ZOOM}`);
|
|
255
|
+
assertEx(zoom < MAX_ZOOM, () => `Invalid zoom [${zoom}] max=${MAX_ZOOM}`);
|
|
256
256
|
this.key = this.key & ID_MASK | BigInt(zoom) << 248n;
|
|
257
257
|
return this;
|
|
258
258
|
}
|
package/dist/node/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/Quadkey.ts","../../src/RelativeDirectionConstantLookup.ts"],"sourcesContent":["import { assertEx } from '@xylabs/assert'\nimport { hexFromArrayBuffer, hexFromHexString } from '@xylabs/hex'\nimport {\n boundingBoxToCenter,\n GeoJson,\n MercatorBoundingBox,\n MercatorTile,\n tileFromPoint,\n tileFromQuadkey,\n tilesFromBoundingBox,\n tileToBoundingBox,\n tileToQuadkey,\n} from '@xyo-network/sdk-geo'\nimport { LngLat, LngLatLike } from 'mapbox-gl'\n\nimport { RelativeDirectionConstantLookup } from './RelativeDirectionConstantLookup'\n\nconst MAX_ZOOM = 124\n\nexport const isQuadkey = (obj: { type: string }) => obj?.type === Quadkey.type\n\nconst FULL_MASK = 2n ** 256n - 1n\nconst ZOOM_MASK = 0xffn << 248n\nconst ID_MASK = ZOOM_MASK ^ FULL_MASK\n\nconst assertMaxBitUint = (value: bigint, bits = 256n) => {\n assertEx(value < 2n ** bits && value >= 0, 'Not a 256 Bit Uint!')\n}\n\nexport class Quadkey {\n static Zero = Quadkey.from(0, 0n)\n static root = new Quadkey()\n static type = 'Quadkey'\n\n type = Quadkey.type\n\n private _geoJson?: GeoJson\n\n constructor(private key = 0n) {\n assertMaxBitUint(key)\n this.guessZoom()\n }\n\n get base16String() {\n return this.id.toString(16).padStart(62, '0')\n }\n\n get base4Hash() {\n return this.id.toString(4).padStart(this.zoom, '0')\n }\n\n get base4HashLabel() {\n const hash = this.base4Hash\n return hash.length === 0 ? 'fhr' : hash\n }\n\n get boundingBox(): MercatorBoundingBox {\n return tileToBoundingBox(this.tile)\n }\n\n get center() {\n const result = boundingBoxToCenter(this.boundingBox)\n return new LngLat(result[0], result[1])\n }\n\n get children() {\n assertEx(this.zoom < MAX_ZOOM - 1, 'Can not get children of bottom tiles')\n const result: Quadkey[] = []\n const shiftedId = this.id << 2n\n for (let i = 0n; i < 4n; i++) {\n result.push(new Quadkey().setId(shiftedId | i).setZoom(this.zoom + 1))\n }\n return result\n }\n\n get gridLocation() {\n const tileData = tileFromQuadkey(this.base4Hash)\n\n return {\n col: 2 ** tileData[2] - tileData[1] - 1,\n row: tileData[0],\n zoom: tileData[2],\n }\n }\n\n get id() {\n return this.key & ID_MASK\n }\n\n get parent(): Quadkey | undefined {\n if (this.zoom > 0) {\n return new Quadkey().setId(this.id >> 2n).setZoom(this.zoom - 1)\n }\n }\n\n get siblings() {\n const siblings = assertEx(this.parent?.children, `siblings: parentChildren ${this.base4Hash}`)\n const filteredSiblings = siblings.filter((quadkey) => quadkey.key !== this.key)\n assertEx(filteredSiblings.length === 3, `siblings: expected 3 [${filteredSiblings.length}]`)\n return filteredSiblings\n }\n\n get tile(): MercatorTile {\n return tileFromQuadkey(this.base4Hash)\n }\n\n get valid() {\n //check for additional data outside zoom scope\n return this.id.toString(4) === this.base4Hash.padStart(64, '0')\n }\n\n get zoom() {\n //zoom is stored in top byte\n return Number((this.key & ZOOM_MASK) >> 248n)\n }\n\n static from(zoom: number, id: bigint) {\n return new Quadkey().setId(id).setZoom(zoom)\n }\n\n static fromArrayBuffer(zoom: number, id: ArrayBuffer) {\n return new Quadkey().setId(BigInt(hexFromArrayBuffer(id, { prefix: true }))).setZoom(zoom)\n }\n\n static fromBase16String(value: string) {\n return new Quadkey(BigInt(hexFromHexString(value, { prefix: true })))\n }\n\n static fromBase4String(value?: string) {\n if (value === 'fhr' || value === '' || value === undefined) {\n return Quadkey.root\n }\n let id = 0n\n for (let i = 0; i < value.length; i++) {\n const nibble = Number.parseInt(value[i])\n assertEx(nibble < 4 && nibble >= 0, `Invalid Base4 String: ${value}`)\n id = (id << 2n) | BigInt(nibble)\n }\n return new Quadkey().setId(id).setZoom(value.length)\n }\n\n static fromBoundingBox(boundingBox: MercatorBoundingBox, zoom: number) {\n const tiles = tilesFromBoundingBox(boundingBox, Math.floor(zoom))\n const result: Quadkey[] = []\n for (const tile of tiles) {\n result.push(assertEx(Quadkey.fromTile(tile), 'Bad Quadkey'))\n }\n\n return result\n }\n\n static fromLngLat(point: LngLatLike, zoom: number) {\n const tile = tileFromPoint(LngLat.convert(point), zoom)\n const quadkeyString = tileToQuadkey(tile)\n return Quadkey.fromBase4String(quadkeyString)\n }\n\n static fromString(zoom: number, id: string, base = 16) {\n switch (base) {\n case 16: {\n return Quadkey.fromBase16String(id).setZoom(zoom)\n }\n default: {\n throw new Error(`Invalid base [${base}]`)\n }\n }\n }\n\n static fromTile(tile: MercatorTile) {\n return Quadkey.fromBase4String(tileToQuadkey(tile))\n }\n\n childrenByZoom(zoom: number) {\n // if we are limiting by zoom, and we are already at that limit, just return this quadkey\n if (zoom && zoom === this.zoom) {\n return [this]\n }\n\n // recursively get children\n let deepResult: Quadkey[] = []\n for (const quadkey of this.children) {\n deepResult = [...deepResult, ...quadkey.childrenByZoom(zoom)]\n }\n return deepResult\n }\n\n clone() {\n return new Quadkey(this.key)\n }\n\n equals(obj: Quadkey): boolean {\n return obj.key == this.key\n }\n\n geoJson() {\n this._geoJson = this._geoJson ?? new GeoJson(this.base4Hash)\n return this._geoJson\n }\n\n getGridBoundingBox(size: number) {\n const hash = this.base4Hash\n let index = 0\n let left = 0\n let top = 0\n let blockSize = size\n while (index < hash.length) {\n blockSize >>= 1\n switch (hash[index]) {\n case '1': {\n left += blockSize\n break\n }\n case '2': {\n top += blockSize\n break\n }\n case '3': {\n left += blockSize\n top += blockSize\n break\n }\n }\n index++\n }\n if (blockSize < 2) {\n blockSize = 2\n }\n return {\n height: blockSize,\n left,\n top,\n width: blockSize,\n }\n }\n\n /** @deprecated use .gridLocation instead */\n getGridLocation() {\n return this.gridLocation\n }\n\n isInBoundingBox(boundingBox: MercatorBoundingBox) {\n const tileBoundingBox = tileToBoundingBox(this.tile)\n return (\n boundingBox.contains(tileBoundingBox.getNorthEast()) ||\n boundingBox.contains(tileBoundingBox.getNorthWest()) ||\n boundingBox.contains(tileBoundingBox.getSouthEast()) ||\n boundingBox.contains(tileBoundingBox.getSouthWest())\n )\n }\n\n relative(direction: string) {\n const directionConstant = assertEx(RelativeDirectionConstantLookup[direction], 'Invalid direction')\n let quadkey = this.base4Hash\n if (quadkey.length === 0) {\n return this\n }\n let index = quadkey.length - 1\n while (index >= 0) {\n let number = Number.parseInt(quadkey.charAt(index))\n number += directionConstant\n if (number > 3) {\n number -= 4\n quadkey = quadkey.slice(0, Math.max(0, index)) + number.toString() + quadkey.slice(Math.max(0, index + 1))\n index--\n } else if (number < 0) {\n number += 4\n quadkey = quadkey.slice(0, Math.max(0, index)) + number.toString() + quadkey.slice(Math.max(0, index + 1))\n index--\n } else {\n index = -1\n }\n }\n return Quadkey.fromBase4String(quadkey)\n }\n\n setId(id: bigint) {\n assertMaxBitUint(id, 248n)\n this.setKey(this.zoom, id)\n return this\n }\n\n setKey(zoom: number, key: bigint) {\n assertMaxBitUint(key)\n this.key = key\n this.setZoom(zoom)\n return this\n }\n\n setZoom(zoom: number) {\n assertEx(zoom < MAX_ZOOM, `Invalid zoom [${zoom}] max=${MAX_ZOOM}`)\n this.key = (this.key & ID_MASK) | (BigInt(zoom) << 248n)\n return this\n }\n\n toJSON(): string {\n return this.base4HashLabel\n }\n\n toString() {\n return this.base4Hash\n }\n\n protected guessZoom() {\n const quadkeySimple = this.id.toString(4)\n this.setZoom(quadkeySimple.length)\n }\n}\n","export const RelativeDirectionConstantLookup: Record<string, number> = {\n e: 1,\n n: -2,\n s: 2,\n w: -1,\n}\n"],"mappings":"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","names":["assertEx","hexFromArrayBuffer","hexFromHexString","boundingBoxToCenter","GeoJson","tileFromPoint","tileFromQuadkey","tilesFromBoundingBox","tileToBoundingBox","tileToQuadkey","LngLat","RelativeDirectionConstantLookup","e","n","s","w","MAX_ZOOM","isQuadkey","obj","type","Quadkey","FULL_MASK","ZOOM_MASK","ID_MASK","assertMaxBitUint","value","bits","assertEx","_geoJson","constructor","key","guessZoom","base16String","id","toString","padStart","base4Hash","zoom","base4HashLabel","hash","length","boundingBox","tileToBoundingBox","tile","center","result","boundingBoxToCenter","LngLat","children","shiftedId","i","push","setId","setZoom","gridLocation","tileData","tileFromQuadkey","col","row","parent","siblings","filteredSiblings","filter","quadkey","valid","Number","from","fromArrayBuffer","BigInt","hexFromArrayBuffer","prefix","fromBase16String","hexFromHexString","fromBase4String","undefined","root","nibble","parseInt","fromBoundingBox","tiles","tilesFromBoundingBox","Math","floor","fromTile","fromLngLat","point","tileFromPoint","convert","quadkeyString","tileToQuadkey","fromString","base","Error","childrenByZoom","deepResult","clone","equals","geoJson","GeoJson","getGridBoundingBox","size","index","left","top","blockSize","height","width","getGridLocation","isInBoundingBox","tileBoundingBox","contains","getNorthEast","getNorthWest","getSouthEast","getSouthWest","relative","direction","directionConstant","RelativeDirectionConstantLookup","number","charAt","slice","max","setKey","toJSON","quadkeySimple","Zero"]}
|
|
1
|
+
{"version":3,"sources":["../../src/Quadkey.ts","../../src/RelativeDirectionConstantLookup.ts"],"sourcesContent":["import { assertEx } from '@xylabs/assert'\nimport { hexFromArrayBuffer, hexFromHexString } from '@xylabs/hex'\nimport {\n boundingBoxToCenter,\n GeoJson,\n MercatorBoundingBox,\n MercatorTile,\n tileFromPoint,\n tileFromQuadkey,\n tilesFromBoundingBox,\n tileToBoundingBox,\n tileToQuadkey,\n} from '@xyo-network/sdk-geo'\nimport { LngLat, LngLatLike } from 'mapbox-gl'\n\nimport { RelativeDirectionConstantLookup } from './RelativeDirectionConstantLookup'\n\nconst MAX_ZOOM = 124\n\nexport const isQuadkey = (obj: { type: string }) => obj?.type === Quadkey.type\n\nconst FULL_MASK = 2n ** 256n - 1n\nconst ZOOM_MASK = 0xffn << 248n\nconst ID_MASK = ZOOM_MASK ^ FULL_MASK\n\nconst assertMaxBitUint = (value: bigint, bits = 256n) => {\n assertEx(value < 2n ** bits && value >= 0, 'Not a 256 Bit Uint!')\n}\n\nexport class Quadkey {\n static Zero = Quadkey.from(0, 0n)\n static root = new Quadkey()\n static type = 'Quadkey'\n\n type = Quadkey.type\n\n private _geoJson?: GeoJson\n\n constructor(private key = 0n) {\n assertMaxBitUint(key)\n this.guessZoom()\n }\n\n get base16String() {\n return this.id.toString(16).padStart(62, '0')\n }\n\n get base4Hash() {\n return this.id.toString(4).padStart(this.zoom, '0')\n }\n\n get base4HashLabel() {\n const hash = this.base4Hash\n return hash.length === 0 ? 'fhr' : hash\n }\n\n get boundingBox(): MercatorBoundingBox {\n return tileToBoundingBox(this.tile)\n }\n\n get center() {\n const result = boundingBoxToCenter(this.boundingBox)\n return new LngLat(result[0], result[1])\n }\n\n get children() {\n assertEx(this.zoom < MAX_ZOOM - 1, 'Can not get children of bottom tiles')\n const result: Quadkey[] = []\n const shiftedId = this.id << 2n\n for (let i = 0n; i < 4n; i++) {\n result.push(new Quadkey().setId(shiftedId | i).setZoom(this.zoom + 1))\n }\n return result\n }\n\n get gridLocation() {\n const tileData = tileFromQuadkey(this.base4Hash)\n\n return {\n col: 2 ** tileData[2] - tileData[1] - 1,\n row: tileData[0],\n zoom: tileData[2],\n }\n }\n\n get id() {\n return this.key & ID_MASK\n }\n\n get parent(): Quadkey | undefined {\n if (this.zoom > 0) {\n return new Quadkey().setId(this.id >> 2n).setZoom(this.zoom - 1)\n }\n }\n\n get siblings() {\n const siblings = assertEx(this.parent?.children, () => `siblings: parentChildren ${this.base4Hash}`)\n const filteredSiblings = siblings.filter((quadkey) => quadkey.key !== this.key)\n assertEx(filteredSiblings.length === 3, () => `siblings: expected 3 [${filteredSiblings.length}]`)\n return filteredSiblings\n }\n\n get tile(): MercatorTile {\n return tileFromQuadkey(this.base4Hash)\n }\n\n get valid() {\n //check for additional data outside zoom scope\n return this.id.toString(4) === this.base4Hash.padStart(64, '0')\n }\n\n get zoom() {\n //zoom is stored in top byte\n return Number((this.key & ZOOM_MASK) >> 248n)\n }\n\n static from(zoom: number, id: bigint) {\n return new Quadkey().setId(id).setZoom(zoom)\n }\n\n static fromArrayBuffer(zoom: number, id: ArrayBuffer) {\n return new Quadkey().setId(BigInt(hexFromArrayBuffer(id, { prefix: true }))).setZoom(zoom)\n }\n\n static fromBase16String(value: string) {\n return new Quadkey(BigInt(hexFromHexString(value, { prefix: true })))\n }\n\n static fromBase4String(value?: string) {\n if (value === 'fhr' || value === '' || value === undefined) {\n return Quadkey.root\n }\n let id = 0n\n for (let i = 0; i < value.length; i++) {\n const nibble = Number.parseInt(value[i])\n assertEx(nibble < 4 && nibble >= 0, () => `Invalid Base4 String: ${value}`)\n id = (id << 2n) | BigInt(nibble)\n }\n return new Quadkey().setId(id).setZoom(value.length)\n }\n\n static fromBoundingBox(boundingBox: MercatorBoundingBox, zoom: number) {\n const tiles = tilesFromBoundingBox(boundingBox, Math.floor(zoom))\n const result: Quadkey[] = []\n for (const tile of tiles) {\n result.push(assertEx(Quadkey.fromTile(tile), 'Bad Quadkey'))\n }\n\n return result\n }\n\n static fromLngLat(point: LngLatLike, zoom: number) {\n const tile = tileFromPoint(LngLat.convert(point), zoom)\n const quadkeyString = tileToQuadkey(tile)\n return Quadkey.fromBase4String(quadkeyString)\n }\n\n static fromString(zoom: number, id: string, base = 16) {\n switch (base) {\n case 16: {\n return Quadkey.fromBase16String(id).setZoom(zoom)\n }\n default: {\n throw new Error(`Invalid base [${base}]`)\n }\n }\n }\n\n static fromTile(tile: MercatorTile) {\n return Quadkey.fromBase4String(tileToQuadkey(tile))\n }\n\n childrenByZoom(zoom: number) {\n // if we are limiting by zoom, and we are already at that limit, just return this quadkey\n if (zoom && zoom === this.zoom) {\n return [this]\n }\n\n // recursively get children\n let deepResult: Quadkey[] = []\n for (const quadkey of this.children) {\n deepResult = [...deepResult, ...quadkey.childrenByZoom(zoom)]\n }\n return deepResult\n }\n\n clone() {\n return new Quadkey(this.key)\n }\n\n equals(obj: Quadkey): boolean {\n return obj.key == this.key\n }\n\n geoJson() {\n this._geoJson = this._geoJson ?? new GeoJson(this.base4Hash)\n return this._geoJson\n }\n\n getGridBoundingBox(size: number) {\n const hash = this.base4Hash\n let index = 0\n let left = 0\n let top = 0\n let blockSize = size\n while (index < hash.length) {\n blockSize >>= 1\n switch (hash[index]) {\n case '1': {\n left += blockSize\n break\n }\n case '2': {\n top += blockSize\n break\n }\n case '3': {\n left += blockSize\n top += blockSize\n break\n }\n }\n index++\n }\n if (blockSize < 2) {\n blockSize = 2\n }\n return {\n height: blockSize,\n left,\n top,\n width: blockSize,\n }\n }\n\n /** @deprecated use .gridLocation instead */\n getGridLocation() {\n return this.gridLocation\n }\n\n isInBoundingBox(boundingBox: MercatorBoundingBox) {\n const tileBoundingBox = tileToBoundingBox(this.tile)\n return (\n boundingBox.contains(tileBoundingBox.getNorthEast()) ||\n boundingBox.contains(tileBoundingBox.getNorthWest()) ||\n boundingBox.contains(tileBoundingBox.getSouthEast()) ||\n boundingBox.contains(tileBoundingBox.getSouthWest())\n )\n }\n\n relative(direction: string) {\n const directionConstant = assertEx(RelativeDirectionConstantLookup[direction], 'Invalid direction')\n let quadkey = this.base4Hash\n if (quadkey.length === 0) {\n return this\n }\n let index = quadkey.length - 1\n while (index >= 0) {\n let number = Number.parseInt(quadkey.charAt(index))\n number += directionConstant\n if (number > 3) {\n number -= 4\n quadkey = quadkey.slice(0, Math.max(0, index)) + number.toString() + quadkey.slice(Math.max(0, index + 1))\n index--\n } else if (number < 0) {\n number += 4\n quadkey = quadkey.slice(0, Math.max(0, index)) + number.toString() + quadkey.slice(Math.max(0, index + 1))\n index--\n } else {\n index = -1\n }\n }\n return Quadkey.fromBase4String(quadkey)\n }\n\n setId(id: bigint) {\n assertMaxBitUint(id, 248n)\n this.setKey(this.zoom, id)\n return this\n }\n\n setKey(zoom: number, key: bigint) {\n assertMaxBitUint(key)\n this.key = key\n this.setZoom(zoom)\n return this\n }\n\n setZoom(zoom: number) {\n assertEx(zoom < MAX_ZOOM, () => `Invalid zoom [${zoom}] max=${MAX_ZOOM}`)\n this.key = (this.key & ID_MASK) | (BigInt(zoom) << 248n)\n return this\n }\n\n toJSON(): string {\n return this.base4HashLabel\n }\n\n toString() {\n return this.base4Hash\n }\n\n protected guessZoom() {\n const quadkeySimple = this.id.toString(4)\n this.setZoom(quadkeySimple.length)\n }\n}\n","export const RelativeDirectionConstantLookup: Record<string, number> = {\n e: 1,\n n: -2,\n s: 2,\n w: -1,\n}\n"],"mappings":"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","names":["assertEx","hexFromArrayBuffer","hexFromHexString","boundingBoxToCenter","GeoJson","tileFromPoint","tileFromQuadkey","tilesFromBoundingBox","tileToBoundingBox","tileToQuadkey","LngLat","RelativeDirectionConstantLookup","e","n","s","w","MAX_ZOOM","isQuadkey","obj","type","Quadkey","FULL_MASK","ZOOM_MASK","ID_MASK","assertMaxBitUint","value","bits","assertEx","_geoJson","constructor","key","guessZoom","base16String","id","toString","padStart","base4Hash","zoom","base4HashLabel","hash","length","boundingBox","tileToBoundingBox","tile","center","result","boundingBoxToCenter","LngLat","children","shiftedId","i","push","setId","setZoom","gridLocation","tileData","tileFromQuadkey","col","row","parent","siblings","filteredSiblings","filter","quadkey","valid","Number","from","fromArrayBuffer","BigInt","hexFromArrayBuffer","prefix","fromBase16String","hexFromHexString","fromBase4String","undefined","root","nibble","parseInt","fromBoundingBox","tiles","tilesFromBoundingBox","Math","floor","fromTile","fromLngLat","point","tileFromPoint","convert","quadkeyString","tileToQuadkey","fromString","base","Error","childrenByZoom","deepResult","clone","equals","geoJson","GeoJson","getGridBoundingBox","size","index","left","top","blockSize","height","width","getGridLocation","isInBoundingBox","tileBoundingBox","contains","getNorthEast","getNorthWest","getSouthEast","getSouthWest","relative","direction","directionConstant","RelativeDirectionConstantLookup","number","charAt","slice","max","setKey","toJSON","quadkeySimple","Zero"]}
|
package/package.json
CHANGED
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
"url": "https://github.com/XYOracleNetwork/sdk-xyo-client-js/issues"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@xylabs/assert": "^2.
|
|
14
|
-
"@xylabs/hex": "^2.
|
|
13
|
+
"@xylabs/assert": "^2.14.0",
|
|
14
|
+
"@xylabs/hex": "^2.14.0",
|
|
15
15
|
"@xyo-network/sdk-geo": "^2.11.2",
|
|
16
|
-
"mapbox-gl": "^3.1.
|
|
16
|
+
"mapbox-gl": "^3.1.2"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@types/mapbox-gl": "^2.7.19",
|
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
"url": "https://github.com/XYOracleNetwork/sdk-xyo-client-js.git"
|
|
61
61
|
},
|
|
62
62
|
"sideEffects": false,
|
|
63
|
-
"version": "2.
|
|
64
|
-
"type": "module"
|
|
63
|
+
"version": "2.89.0-rc.10",
|
|
64
|
+
"type": "module",
|
|
65
|
+
"stableVersion": "2.88.3"
|
|
65
66
|
}
|
package/src/Quadkey.ts
CHANGED
|
@@ -94,9 +94,9 @@ export class Quadkey {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
get siblings() {
|
|
97
|
-
const siblings = assertEx(this.parent?.children, `siblings: parentChildren ${this.base4Hash}`)
|
|
97
|
+
const siblings = assertEx(this.parent?.children, () => `siblings: parentChildren ${this.base4Hash}`)
|
|
98
98
|
const filteredSiblings = siblings.filter((quadkey) => quadkey.key !== this.key)
|
|
99
|
-
assertEx(filteredSiblings.length === 3, `siblings: expected 3 [${filteredSiblings.length}]`)
|
|
99
|
+
assertEx(filteredSiblings.length === 3, () => `siblings: expected 3 [${filteredSiblings.length}]`)
|
|
100
100
|
return filteredSiblings
|
|
101
101
|
}
|
|
102
102
|
|
|
@@ -133,7 +133,7 @@ export class Quadkey {
|
|
|
133
133
|
let id = 0n
|
|
134
134
|
for (let i = 0; i < value.length; i++) {
|
|
135
135
|
const nibble = Number.parseInt(value[i])
|
|
136
|
-
assertEx(nibble < 4 && nibble >= 0, `Invalid Base4 String: ${value}`)
|
|
136
|
+
assertEx(nibble < 4 && nibble >= 0, () => `Invalid Base4 String: ${value}`)
|
|
137
137
|
id = (id << 2n) | BigInt(nibble)
|
|
138
138
|
}
|
|
139
139
|
return new Quadkey().setId(id).setZoom(value.length)
|
|
@@ -287,7 +287,7 @@ export class Quadkey {
|
|
|
287
287
|
}
|
|
288
288
|
|
|
289
289
|
setZoom(zoom: number) {
|
|
290
|
-
assertEx(zoom < MAX_ZOOM, `Invalid zoom [${zoom}] max=${MAX_ZOOM}`)
|
|
290
|
+
assertEx(zoom < MAX_ZOOM, () => `Invalid zoom [${zoom}] max=${MAX_ZOOM}`)
|
|
291
291
|
this.key = (this.key & ID_MASK) | (BigInt(zoom) << 248n)
|
|
292
292
|
return this
|
|
293
293
|
}
|