@xyo-network/quadkey 2.75.2 → 2.75.4
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/Quadkey.js +79 -29
- package/dist/browser/Quadkey.js.map +1 -1
- package/dist/browser/RelativeDirectionConstantLookup.js +2 -1
- package/dist/browser/RelativeDirectionConstantLookup.js.map +1 -1
- package/dist/browser/index.js +374 -1
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/utils.js +4 -3
- package/dist/browser/utils.js.map +1 -1
- package/dist/docs.json +132 -132
- package/package.json +6 -6
package/dist/browser/Quadkey.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
// src/Quadkey.ts
|
|
1
2
|
import { assertEx } from "@xylabs/assert";
|
|
2
3
|
import { BigNumber } from "@xylabs/bignumber";
|
|
3
|
-
import { Buffer } from "@xylabs/buffer";
|
|
4
|
+
import { Buffer as Buffer2 } from "@xylabs/buffer";
|
|
4
5
|
import {
|
|
5
6
|
boundingBoxToCenter,
|
|
6
7
|
GeoJson,
|
|
@@ -11,19 +12,65 @@ import {
|
|
|
11
12
|
tileToQuadkey
|
|
12
13
|
} from "@xyo-network/sdk-geo";
|
|
13
14
|
import { LngLat } from "mapbox-gl";
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
|
|
16
|
+
// src/RelativeDirectionConstantLookup.ts
|
|
17
|
+
var RelativeDirectionConstantLookup = {
|
|
18
|
+
e: 1,
|
|
19
|
+
n: -2,
|
|
20
|
+
s: 2,
|
|
21
|
+
w: -1
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// src/utils.ts
|
|
25
|
+
import { Buffer } from "@xylabs/buffer";
|
|
26
|
+
var padHex = (hex, byteCount) => {
|
|
27
|
+
let result = hex;
|
|
28
|
+
if (hex.length % 2 !== 0) {
|
|
29
|
+
result = `0${hex}`;
|
|
30
|
+
}
|
|
31
|
+
if (byteCount) {
|
|
32
|
+
while (result.length / 2 < byteCount) {
|
|
33
|
+
result = `00${result}`;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
var bitShiftLeft = (buffer) => {
|
|
39
|
+
const shifted = Buffer.alloc(buffer.length);
|
|
40
|
+
const last = buffer.length - 1;
|
|
41
|
+
for (let index = 0; index < last; index++) {
|
|
42
|
+
shifted[index] = buffer[index] << 1;
|
|
43
|
+
if (buffer[index + 1] & 128) {
|
|
44
|
+
shifted[index] += 1;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
shifted[last] = buffer[last] << 1;
|
|
48
|
+
return shifted;
|
|
49
|
+
};
|
|
50
|
+
var bitShiftRight = (buffer) => {
|
|
51
|
+
const shifted = Buffer.alloc(buffer.length);
|
|
52
|
+
const last = buffer.length - 1;
|
|
53
|
+
for (let index = last; index > 0; index--) {
|
|
54
|
+
shifted[index] = buffer[index] >> 1;
|
|
55
|
+
if (buffer[index - 1] & 1) {
|
|
56
|
+
shifted[index] += 128;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
shifted[0] = buffer[0] >> 1;
|
|
60
|
+
return shifted;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// src/Quadkey.ts
|
|
64
|
+
var MAX_ZOOM = 124;
|
|
65
|
+
var isQuadkey = (obj) => obj?.type === Quadkey.type;
|
|
66
|
+
var Quadkey = class _Quadkey {
|
|
67
|
+
static Zero = _Quadkey.from(0, Buffer2.alloc(31, 0));
|
|
68
|
+
static root = new _Quadkey();
|
|
22
69
|
static type = "Quadkey";
|
|
23
|
-
type =
|
|
70
|
+
type = _Quadkey.type;
|
|
24
71
|
_geoJson;
|
|
25
|
-
key =
|
|
26
|
-
constructor(key =
|
|
72
|
+
key = Buffer2.alloc(32);
|
|
73
|
+
constructor(key = Buffer2.alloc(32)) {
|
|
27
74
|
key.copy(this.key, this.key.length - key.length);
|
|
28
75
|
this.guessZoom();
|
|
29
76
|
}
|
|
@@ -66,7 +113,7 @@ class Quadkey {
|
|
|
66
113
|
for (let i = 0; i < 4; i++) {
|
|
67
114
|
const currentLastByte = shiftedId.readUInt8(shiftedId.length - 1);
|
|
68
115
|
shiftedId.writeUInt8(currentLastByte & 252 | i, shiftedId.length - 1);
|
|
69
|
-
result.push(new
|
|
116
|
+
result.push(new _Quadkey().setId(shiftedId).setZoom(this.zoom + 1));
|
|
70
117
|
}
|
|
71
118
|
return result;
|
|
72
119
|
}
|
|
@@ -86,7 +133,7 @@ class Quadkey {
|
|
|
86
133
|
}
|
|
87
134
|
get parent() {
|
|
88
135
|
if (this.zoom > 0) {
|
|
89
|
-
return new
|
|
136
|
+
return new _Quadkey().setId(bitShiftRight(bitShiftRight(this.id))).setZoom(this.zoom - 1);
|
|
90
137
|
}
|
|
91
138
|
}
|
|
92
139
|
get siblings() {
|
|
@@ -115,21 +162,21 @@ class Quadkey {
|
|
|
115
162
|
return this.buffer.readUInt8(0);
|
|
116
163
|
}
|
|
117
164
|
static from(zoom, id) {
|
|
118
|
-
return new
|
|
165
|
+
return new _Quadkey().setId(id).setZoom(zoom);
|
|
119
166
|
}
|
|
120
167
|
static fromBase10String(value) {
|
|
121
|
-
return new
|
|
168
|
+
return new _Quadkey(Buffer2.from(padHex(new BigNumber(value, 10).toString(16)), "hex"));
|
|
122
169
|
}
|
|
123
170
|
static fromBase16String(value) {
|
|
124
171
|
const valueToUse = value.startsWith("0x") ? value.slice(2) : value;
|
|
125
|
-
return new
|
|
172
|
+
return new _Quadkey(Buffer2.from(padHex(valueToUse), "hex"));
|
|
126
173
|
}
|
|
127
174
|
static fromBase4String(value) {
|
|
128
175
|
if (value === "fhr" || value === "") {
|
|
129
|
-
return
|
|
176
|
+
return _Quadkey.root;
|
|
130
177
|
}
|
|
131
178
|
if (value && value.length && value.length > 0) {
|
|
132
|
-
const quadkey = new
|
|
179
|
+
const quadkey = new _Quadkey(Buffer2.from(padHex(new BigNumber(value, 4).toString(16)), "hex")).setZoom(value.length);
|
|
133
180
|
return quadkey.valid ? quadkey : void 0;
|
|
134
181
|
}
|
|
135
182
|
}
|
|
@@ -137,30 +184,30 @@ class Quadkey {
|
|
|
137
184
|
const tiles = tilesFromBoundingBox(boundingBox, Math.floor(zoom));
|
|
138
185
|
const result = [];
|
|
139
186
|
for (const tile of tiles) {
|
|
140
|
-
result.push(assertEx(
|
|
187
|
+
result.push(assertEx(_Quadkey.fromTile(tile), "Bad Quadkey"));
|
|
141
188
|
}
|
|
142
189
|
return result;
|
|
143
190
|
}
|
|
144
191
|
static fromBuffer(value) {
|
|
145
|
-
return
|
|
192
|
+
return _Quadkey.fromBase16String(value.toString("hex"));
|
|
146
193
|
}
|
|
147
194
|
static fromLngLat(point, zoom) {
|
|
148
195
|
const tile = tileFromPoint(LngLat.convert(point), zoom);
|
|
149
196
|
const quadkeyString = tileToQuadkey(tile);
|
|
150
|
-
return
|
|
197
|
+
return _Quadkey.fromBase4String(quadkeyString);
|
|
151
198
|
}
|
|
152
199
|
static fromString(zoom, id, base = 10) {
|
|
153
200
|
switch (base) {
|
|
154
201
|
case 10:
|
|
155
|
-
return
|
|
202
|
+
return _Quadkey.fromBase10String(id)?.setZoom(zoom);
|
|
156
203
|
case 16:
|
|
157
|
-
return
|
|
204
|
+
return _Quadkey.fromBase16String(id).setZoom(zoom);
|
|
158
205
|
default:
|
|
159
206
|
throw Error(`Invalid base [${base}]`);
|
|
160
207
|
}
|
|
161
208
|
}
|
|
162
209
|
static fromTile(tile) {
|
|
163
|
-
return
|
|
210
|
+
return _Quadkey.fromBase4String(tileToQuadkey(tile));
|
|
164
211
|
}
|
|
165
212
|
childrenByZoom(zoom) {
|
|
166
213
|
if (zoom && zoom === this.zoom) {
|
|
@@ -173,7 +220,7 @@ class Quadkey {
|
|
|
173
220
|
return deepResult;
|
|
174
221
|
}
|
|
175
222
|
clone() {
|
|
176
|
-
return
|
|
223
|
+
return _Quadkey.fromBase10String(this.base10String);
|
|
177
224
|
}
|
|
178
225
|
compareTo(quadkey) {
|
|
179
226
|
return this.bigNumber.cmp(quadkey.bigNumber);
|
|
@@ -247,7 +294,7 @@ class Quadkey {
|
|
|
247
294
|
index = -1;
|
|
248
295
|
}
|
|
249
296
|
}
|
|
250
|
-
return
|
|
297
|
+
return _Quadkey.fromBase4String(quadkey);
|
|
251
298
|
}
|
|
252
299
|
setId(id) {
|
|
253
300
|
this.setKey(this.zoom, id);
|
|
@@ -317,9 +364,12 @@ class Quadkey {
|
|
|
317
364
|
const quadkeySimple = bn.toString(4);
|
|
318
365
|
this.setZoom(quadkeySimple.length);
|
|
319
366
|
}
|
|
320
|
-
}
|
|
367
|
+
};
|
|
321
368
|
export {
|
|
322
369
|
Quadkey,
|
|
323
|
-
|
|
370
|
+
bitShiftLeft,
|
|
371
|
+
bitShiftRight,
|
|
372
|
+
isQuadkey,
|
|
373
|
+
padHex
|
|
324
374
|
};
|
|
325
375
|
//# sourceMappingURL=Quadkey.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/Quadkey.ts"],"sourcesContent":["import { assertEx } from '@xylabs/assert'\nimport { BigNumber } from '@xylabs/bignumber'\nimport { Buffer } from '@xylabs/buffer'\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'\nimport { bitShiftLeft, bitShiftRight, padHex } from './utils'\n\nexport * from './utils'\n\nconst MAX_ZOOM = 124\n\nexport const isQuadkey = (obj: { type: string }) => obj?.type === Quadkey.type\n\nexport class Quadkey {\n static Zero = Quadkey.from(0, Buffer.alloc(31, 0))\n static root = new Quadkey()\n static type = 'Quadkey'\n\n type = Quadkey.type\n\n private _geoJson?: GeoJson\n private key = Buffer.alloc(32)\n\n constructor(key = Buffer.alloc(32)) {\n key.copy(this.key, this.key.length - key.length)\n this.guessZoom()\n }\n\n get base10String() {\n return this.bigNumber.toString(10)\n }\n\n get base4Hash() {\n const bn = new BigNumber(this.id.toString('hex'), 16)\n const zoom = this.zoom\n if (zoom === 0) {\n return ''\n }\n let quadkeySimple = bn.toString(4)\n while (quadkeySimple.length < zoom) {\n quadkeySimple = `0${quadkeySimple}`\n }\n return quadkeySimple\n }\n\n get base4HashLabel() {\n const hash = this.base4Hash\n return hash.length === 0 ? 'fhr' : hash\n }\n\n get bigNumber() {\n return new BigNumber(`${this.key.toString('hex')}`, 'hex')\n }\n\n get boundingBox(): MercatorBoundingBox {\n return tileToBoundingBox(this.tile)\n }\n\n get buffer() {\n return this.key\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 = bitShiftLeft(bitShiftLeft(this.id))\n for (let i = 0; i < 4; i++) {\n const currentLastByte = shiftedId.readUInt8(shiftedId.length - 1)\n shiftedId.writeUInt8((currentLastByte & 0xfc) | i, shiftedId.length - 1)\n result.push(new Quadkey().setId(shiftedId).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 hex() {\n return `0x${this.key.toString('hex')}`\n }\n\n get id() {\n return this.buffer.slice(1)\n }\n\n get parent(): Quadkey | undefined {\n if (this.zoom > 0) {\n return new Quadkey().setId(bitShiftRight(bitShiftRight(this.id))).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) => this.compareTo(quadkey) !== 0)\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 const zoom = this.zoom\n const shift = (MAX_ZOOM - zoom) * 2\n const id = this.id\n let testId = id\n for (let i = 0; i < shift; i++) {\n testId = bitShiftLeft(testId)\n }\n for (let i = 0; i < shift; i++) {\n testId = bitShiftRight(testId)\n }\n return testId.compare(id) === 0\n }\n\n get zoom() {\n return this.buffer.readUInt8(0)\n }\n\n static from(zoom: number, id: Buffer) {\n return new Quadkey().setId(id).setZoom(zoom)\n }\n\n static fromBase10String(value: string) {\n return new Quadkey(Buffer.from(padHex(new BigNumber(value, 10).toString(16)), 'hex'))\n }\n\n static fromBase16String(value: string) {\n const valueToUse = value.startsWith('0x') ? value.slice(2) : value\n return new Quadkey(Buffer.from(padHex(valueToUse), 'hex'))\n }\n\n static fromBase4String(value?: string) {\n if (value === 'fhr' || value === '') {\n return Quadkey.root\n }\n if (value && value.length && value.length > 0) {\n const quadkey = new Quadkey(Buffer.from(padHex(new BigNumber(value, 4).toString(16)), 'hex')).setZoom(value.length)\n return quadkey.valid ? quadkey : undefined\n }\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 fromBuffer(value: Buffer) {\n return Quadkey.fromBase16String(value.toString('hex'))\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 = 10) {\n switch (base) {\n case 10:\n return Quadkey.fromBase10String(id)?.setZoom(zoom)\n case 16:\n return Quadkey.fromBase16String(id).setZoom(zoom)\n default:\n throw Error(`Invalid base [${base}]`)\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.concat(quadkey.childrenByZoom(zoom))\n }\n return deepResult\n }\n\n clone() {\n return Quadkey.fromBase10String(this.base10String)\n }\n\n compareTo(quadkey: Quadkey) {\n return this.bigNumber.cmp(quadkey.bigNumber)\n }\n\n equals(obj: Quadkey): boolean {\n return obj.base4HashLabel == this.base4HashLabel\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 case '2':\n top += blockSize\n break\n case '3':\n left += blockSize\n top += blockSize\n break\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 = parseInt(quadkey.charAt(index))\n number += directionConstant\n if (number > 3) {\n number -= 4\n quadkey = quadkey.substring(0, index) + number.toString() + quadkey.substring(index + 1)\n index--\n } else if (number < 0) {\n number += 4\n quadkey = quadkey.substring(0, index) + number.toString() + quadkey.substring(index + 1)\n index--\n } else {\n index = -1\n }\n }\n return Quadkey.fromBase4String(quadkey)\n }\n\n setId(id: Buffer) {\n this.setKey(this.zoom, id)\n return this\n }\n\n setKey(zoom: number, id: Buffer) {\n id.copy(this.key, this.key.length - id.length)\n this.key.writeUInt8(zoom, 0)\n return this\n }\n\n setZoom(zoom: number) {\n assertEx(zoom < MAX_ZOOM, `Invalid zoom [${zoom}] max=${MAX_ZOOM}`)\n this.setKey(zoom, this.id)\n return this\n }\n\n /** @deprecated use .base10String*/\n toBase10String() {\n return this.base10String\n }\n\n /** @deprecated use .base4Hash */\n toBase4Hash() {\n return this.base4Hash\n }\n\n /** @deprecated use .base4HashLabel */\n toBase4HashLabel() {\n const hash = this.base4HashLabel\n return hash.length === 0 ? 'fhr' : hash\n }\n\n /** @deprecated use .bigNumber */\n toBigNumber() {\n return this.bigNumber\n }\n\n /** @deprecated use .boundingBox */\n toBoundingBox(): MercatorBoundingBox {\n return this.boundingBox\n }\n\n /** @deprecated use .buffer */\n toBuffer() {\n return this.buffer\n }\n\n /** @deprecated use .center */\n toCenter() {\n return this.center\n }\n\n /** @deprecated use .hex instead */\n toHex() {\n return this.hex\n }\n\n toJSON(): string {\n return this.base4HashLabel\n }\n\n toShortString() {\n const buffer = this.buffer\n const part1 = buffer.slice(0, 2)\n const part2 = buffer.slice(buffer.length - 2, buffer.length)\n return `${part1.toString('hex')}...${part2.toString('hex')}`\n }\n\n toString() {\n return `0x${padHex(this.bigNumber.toString(16))}`\n }\n\n /** @deprecated use .tile instead */\n toTile(): MercatorTile {\n return this.tile\n }\n\n protected guessZoom() {\n const bn = new BigNumber(this.id.toString('hex'), 16)\n const quadkeySimple = bn.toString(4)\n this.setZoom(quadkeySimple.length)\n }\n}\n"],"mappings":"AAAA,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAC1B,SAAS,cAAc;AACvB;AAAA,EACE;AAAA,EACA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,cAA0B;AAEnC,SAAS,uCAAuC;AAChD,SAAS,cAAc,eAAe,cAAc;AAEpD,cAAc;AAEd,MAAM,WAAW;AAEV,MAAM,YAAY,CAAC,QAA0B,KAAK,SAAS,QAAQ;AAEnE,MAAM,QAAQ;AAAA,EACnB,OAAO,OAAO,QAAQ,KAAK,GAAG,OAAO,MAAM,IAAI,CAAC,CAAC;AAAA,EACjD,OAAO,OAAO,IAAI,QAAQ;AAAA,EAC1B,OAAO,OAAO;AAAA,EAEd,OAAO,QAAQ;AAAA,EAEP;AAAA,EACA,MAAM,OAAO,MAAM,EAAE;AAAA,EAE7B,YAAY,MAAM,OAAO,MAAM,EAAE,GAAG;AAClC,QAAI,KAAK,KAAK,KAAK,KAAK,IAAI,SAAS,IAAI,MAAM;AAC/C,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,IAAI,eAAe;AACjB,WAAO,KAAK,UAAU,SAAS,EAAE;AAAA,EACnC;AAAA,EAEA,IAAI,YAAY;AACd,UAAM,KAAK,IAAI,UAAU,KAAK,GAAG,SAAS,KAAK,GAAG,EAAE;AACpD,UAAM,OAAO,KAAK;AAClB,QAAI,SAAS,GAAG;AACd,aAAO;AAAA,IACT;AACA,QAAI,gBAAgB,GAAG,SAAS,CAAC;AACjC,WAAO,cAAc,SAAS,MAAM;AAClC,sBAAgB,IAAI,aAAa;AAAA,IACnC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,iBAAiB;AACnB,UAAM,OAAO,KAAK;AAClB,WAAO,KAAK,WAAW,IAAI,QAAQ;AAAA,EACrC;AAAA,EAEA,IAAI,YAAY;AACd,WAAO,IAAI,UAAU,GAAG,KAAK,IAAI,SAAS,KAAK,CAAC,IAAI,KAAK;AAAA,EAC3D;AAAA,EAEA,IAAI,cAAmC;AACrC,WAAO,kBAAkB,KAAK,IAAI;AAAA,EACpC;AAAA,EAEA,IAAI,SAAS;AACX,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,SAAS;AACX,UAAM,SAAS,oBAAoB,KAAK,WAAW;AACnD,WAAO,IAAI,OAAO,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAAA,EACxC;AAAA,EAEA,IAAI,WAAW;AACb,aAAS,KAAK,OAAO,WAAW,GAAG,sCAAsC;AACzE,UAAM,SAAoB,CAAC;AAC3B,UAAM,YAAY,aAAa,aAAa,KAAK,EAAE,CAAC;AACpD,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAM,kBAAkB,UAAU,UAAU,UAAU,SAAS,CAAC;AAChE,gBAAU,WAAY,kBAAkB,MAAQ,GAAG,UAAU,SAAS,CAAC;AACvE,aAAO,KAAK,IAAI,QAAQ,EAAE,MAAM,SAAS,EAAE,QAAQ,KAAK,OAAO,CAAC,CAAC;AAAA,IACnE;AACA,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,eAAe;AACjB,UAAM,WAAW,gBAAgB,KAAK,SAAS;AAE/C,WAAO;AAAA,MACL,KAAK,KAAK,SAAS,CAAC,IAAI,SAAS,CAAC,IAAI;AAAA,MACtC,KAAK,SAAS,CAAC;AAAA,MACf,MAAM,SAAS,CAAC;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,IAAI,MAAM;AACR,WAAO,KAAK,KAAK,IAAI,SAAS,KAAK,CAAC;AAAA,EACtC;AAAA,EAEA,IAAI,KAAK;AACP,WAAO,KAAK,OAAO,MAAM,CAAC;AAAA,EAC5B;AAAA,EAEA,IAAI,SAA8B;AAChC,QAAI,KAAK,OAAO,GAAG;AACjB,aAAO,IAAI,QAAQ,EAAE,MAAM,cAAc,cAAc,KAAK,EAAE,CAAC,CAAC,EAAE,QAAQ,KAAK,OAAO,CAAC;AAAA,IACzF;AAAA,EACF;AAAA,EAEA,IAAI,WAAW;AACb,UAAM,WAAW,SAAS,KAAK,QAAQ,UAAU,4BAA4B,KAAK,SAAS,EAAE;AAC7F,UAAM,mBAAmB,SAAS,OAAO,CAAC,YAAY,KAAK,UAAU,OAAO,MAAM,CAAC;AACnF,aAAS,iBAAiB,WAAW,GAAG,yBAAyB,iBAAiB,MAAM,GAAG;AAC3F,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,OAAqB;AACvB,WAAO,gBAAgB,KAAK,SAAS;AAAA,EACvC;AAAA,EAEA,IAAI,QAAQ;AACV,UAAM,OAAO,KAAK;AAClB,UAAM,SAAS,WAAW,QAAQ;AAClC,UAAM,KAAK,KAAK;AAChB,QAAI,SAAS;AACb,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,eAAS,aAAa,MAAM;AAAA,IAC9B;AACA,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,eAAS,cAAc,MAAM;AAAA,IAC/B;AACA,WAAO,OAAO,QAAQ,EAAE,MAAM;AAAA,EAChC;AAAA,EAEA,IAAI,OAAO;AACT,WAAO,KAAK,OAAO,UAAU,CAAC;AAAA,EAChC;AAAA,EAEA,OAAO,KAAK,MAAc,IAAY;AACpC,WAAO,IAAI,QAAQ,EAAE,MAAM,EAAE,EAAE,QAAQ,IAAI;AAAA,EAC7C;AAAA,EAEA,OAAO,iBAAiB,OAAe;AACrC,WAAO,IAAI,QAAQ,OAAO,KAAK,OAAO,IAAI,UAAU,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,GAAG,KAAK,CAAC;AAAA,EACtF;AAAA,EAEA,OAAO,iBAAiB,OAAe;AACrC,UAAM,aAAa,MAAM,WAAW,IAAI,IAAI,MAAM,MAAM,CAAC,IAAI;AAC7D,WAAO,IAAI,QAAQ,OAAO,KAAK,OAAO,UAAU,GAAG,KAAK,CAAC;AAAA,EAC3D;AAAA,EAEA,OAAO,gBAAgB,OAAgB;AACrC,QAAI,UAAU,SAAS,UAAU,IAAI;AACnC,aAAO,QAAQ;AAAA,IACjB;AACA,QAAI,SAAS,MAAM,UAAU,MAAM,SAAS,GAAG;AAC7C,YAAM,UAAU,IAAI,QAAQ,OAAO,KAAK,OAAO,IAAI,UAAU,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,QAAQ,MAAM,MAAM;AAClH,aAAO,QAAQ,QAAQ,UAAU;AAAA,IACnC;AAAA,EACF;AAAA,EAEA,OAAO,gBAAgB,aAAkC,MAAc;AACrE,UAAM,QAAQ,qBAAqB,aAAa,KAAK,MAAM,IAAI,CAAC;AAChE,UAAM,SAAoB,CAAC;AAC3B,eAAW,QAAQ,OAAO;AACxB,aAAO,KAAK,SAAS,QAAQ,SAAS,IAAI,GAAG,aAAa,CAAC;AAAA,IAC7D;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,WAAW,OAAe;AAC/B,WAAO,QAAQ,iBAAiB,MAAM,SAAS,KAAK,CAAC;AAAA,EACvD;AAAA,EAEA,OAAO,WAAW,OAAmB,MAAc;AACjD,UAAM,OAAO,cAAc,OAAO,QAAQ,KAAK,GAAG,IAAI;AACtD,UAAM,gBAAgB,cAAc,IAAI;AACxC,WAAO,QAAQ,gBAAgB,aAAa;AAAA,EAC9C;AAAA,EAEA,OAAO,WAAW,MAAc,IAAY,OAAO,IAAI;AACrD,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,eAAO,QAAQ,iBAAiB,EAAE,GAAG,QAAQ,IAAI;AAAA,MACnD,KAAK;AACH,eAAO,QAAQ,iBAAiB,EAAE,EAAE,QAAQ,IAAI;AAAA,MAClD;AACE,cAAM,MAAM,iBAAiB,IAAI,GAAG;AAAA,IACxC;AAAA,EACF;AAAA,EAEA,OAAO,SAAS,MAAoB;AAClC,WAAO,QAAQ,gBAAgB,cAAc,IAAI,CAAC;AAAA,EACpD;AAAA,EAEA,eAAe,MAAc;AAE3B,QAAI,QAAQ,SAAS,KAAK,MAAM;AAC9B,aAAO,CAAC,IAAI;AAAA,IACd;AAGA,QAAI,aAAwB,CAAC;AAC7B,eAAW,WAAW,KAAK,UAAU;AACnC,mBAAa,WAAW,OAAO,QAAQ,eAAe,IAAI,CAAC;AAAA,IAC7D;AACA,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ;AACN,WAAO,QAAQ,iBAAiB,KAAK,YAAY;AAAA,EACnD;AAAA,EAEA,UAAU,SAAkB;AAC1B,WAAO,KAAK,UAAU,IAAI,QAAQ,SAAS;AAAA,EAC7C;AAAA,EAEA,OAAO,KAAuB;AAC5B,WAAO,IAAI,kBAAkB,KAAK;AAAA,EACpC;AAAA,EAEA,UAAU;AACR,SAAK,WAAW,KAAK,YAAY,IAAI,QAAQ,KAAK,SAAS;AAC3D,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,mBAAmB,MAAc;AAC/B,UAAM,OAAO,KAAK;AAClB,QAAI,QAAQ;AACZ,QAAI,OAAO;AACX,QAAI,MAAM;AACV,QAAI,YAAY;AAChB,WAAO,QAAQ,KAAK,QAAQ;AAC1B,oBAAc;AACd,cAAQ,KAAK,KAAK,GAAG;AAAA,QACnB,KAAK;AACH,kBAAQ;AACR;AAAA,QACF,KAAK;AACH,iBAAO;AACP;AAAA,QACF,KAAK;AACH,kBAAQ;AACR,iBAAO;AACP;AAAA,MACJ;AACA;AAAA,IACF;AACA,QAAI,YAAY,GAAG;AACjB,kBAAY;AAAA,IACd;AACA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,OAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA,EAGA,kBAAkB;AAChB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,gBAAgB,aAAkC;AAChD,UAAM,kBAAkB,kBAAkB,KAAK,IAAI;AACnD,WACE,YAAY,SAAS,gBAAgB,aAAa,CAAC,KACnD,YAAY,SAAS,gBAAgB,aAAa,CAAC,KACnD,YAAY,SAAS,gBAAgB,aAAa,CAAC,KACnD,YAAY,SAAS,gBAAgB,aAAa,CAAC;AAAA,EAEvD;AAAA,EAEA,SAAS,WAAmB;AAC1B,UAAM,oBAAoB,SAAS,gCAAgC,SAAS,GAAG,mBAAmB;AAClG,QAAI,UAAU,KAAK;AACnB,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO;AAAA,IACT;AACA,QAAI,QAAQ,QAAQ,SAAS;AAC7B,WAAO,SAAS,GAAG;AACjB,UAAI,SAAS,SAAS,QAAQ,OAAO,KAAK,CAAC;AAC3C,gBAAU;AACV,UAAI,SAAS,GAAG;AACd,kBAAU;AACV,kBAAU,QAAQ,UAAU,GAAG,KAAK,IAAI,OAAO,SAAS,IAAI,QAAQ,UAAU,QAAQ,CAAC;AACvF;AAAA,MACF,WAAW,SAAS,GAAG;AACrB,kBAAU;AACV,kBAAU,QAAQ,UAAU,GAAG,KAAK,IAAI,OAAO,SAAS,IAAI,QAAQ,UAAU,QAAQ,CAAC;AACvF;AAAA,MACF,OAAO;AACL,gBAAQ;AAAA,MACV;AAAA,IACF;AACA,WAAO,QAAQ,gBAAgB,OAAO;AAAA,EACxC;AAAA,EAEA,MAAM,IAAY;AAChB,SAAK,OAAO,KAAK,MAAM,EAAE;AACzB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,MAAc,IAAY;AAC/B,OAAG,KAAK,KAAK,KAAK,KAAK,IAAI,SAAS,GAAG,MAAM;AAC7C,SAAK,IAAI,WAAW,MAAM,CAAC;AAC3B,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,MAAc;AACpB,aAAS,OAAO,UAAU,iBAAiB,IAAI,SAAS,QAAQ,EAAE;AAClE,SAAK,OAAO,MAAM,KAAK,EAAE;AACzB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,iBAAiB;AACf,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,cAAc;AACZ,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,mBAAmB;AACjB,UAAM,OAAO,KAAK;AAClB,WAAO,KAAK,WAAW,IAAI,QAAQ;AAAA,EACrC;AAAA;AAAA,EAGA,cAAc;AACZ,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,gBAAqC;AACnC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,WAAW;AACT,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,WAAW;AACT,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,QAAQ;AACN,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,SAAiB;AACf,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,gBAAgB;AACd,UAAM,SAAS,KAAK;AACpB,UAAM,QAAQ,OAAO,MAAM,GAAG,CAAC;AAC/B,UAAM,QAAQ,OAAO,MAAM,OAAO,SAAS,GAAG,OAAO,MAAM;AAC3D,WAAO,GAAG,MAAM,SAAS,KAAK,CAAC,MAAM,MAAM,SAAS,KAAK,CAAC;AAAA,EAC5D;AAAA,EAEA,WAAW;AACT,WAAO,KAAK,OAAO,KAAK,UAAU,SAAS,EAAE,CAAC,CAAC;AAAA,EACjD;AAAA;AAAA,EAGA,SAAuB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEU,YAAY;AACpB,UAAM,KAAK,IAAI,UAAU,KAAK,GAAG,SAAS,KAAK,GAAG,EAAE;AACpD,UAAM,gBAAgB,GAAG,SAAS,CAAC;AACnC,SAAK,QAAQ,cAAc,MAAM;AAAA,EACnC;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/Quadkey.ts","../../src/RelativeDirectionConstantLookup.ts","../../src/utils.ts"],"sourcesContent":["import { assertEx } from '@xylabs/assert'\nimport { BigNumber } from '@xylabs/bignumber'\nimport { Buffer } from '@xylabs/buffer'\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'\nimport { bitShiftLeft, bitShiftRight, padHex } from './utils'\n\nexport * from './utils'\n\nconst MAX_ZOOM = 124\n\nexport const isQuadkey = (obj: { type: string }) => obj?.type === Quadkey.type\n\nexport class Quadkey {\n static Zero = Quadkey.from(0, Buffer.alloc(31, 0))\n static root = new Quadkey()\n static type = 'Quadkey'\n\n type = Quadkey.type\n\n private _geoJson?: GeoJson\n private key = Buffer.alloc(32)\n\n constructor(key = Buffer.alloc(32)) {\n key.copy(this.key, this.key.length - key.length)\n this.guessZoom()\n }\n\n get base10String() {\n return this.bigNumber.toString(10)\n }\n\n get base4Hash() {\n const bn = new BigNumber(this.id.toString('hex'), 16)\n const zoom = this.zoom\n if (zoom === 0) {\n return ''\n }\n let quadkeySimple = bn.toString(4)\n while (quadkeySimple.length < zoom) {\n quadkeySimple = `0${quadkeySimple}`\n }\n return quadkeySimple\n }\n\n get base4HashLabel() {\n const hash = this.base4Hash\n return hash.length === 0 ? 'fhr' : hash\n }\n\n get bigNumber() {\n return new BigNumber(`${this.key.toString('hex')}`, 'hex')\n }\n\n get boundingBox(): MercatorBoundingBox {\n return tileToBoundingBox(this.tile)\n }\n\n get buffer() {\n return this.key\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 = bitShiftLeft(bitShiftLeft(this.id))\n for (let i = 0; i < 4; i++) {\n const currentLastByte = shiftedId.readUInt8(shiftedId.length - 1)\n shiftedId.writeUInt8((currentLastByte & 0xfc) | i, shiftedId.length - 1)\n result.push(new Quadkey().setId(shiftedId).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 hex() {\n return `0x${this.key.toString('hex')}`\n }\n\n get id() {\n return this.buffer.slice(1)\n }\n\n get parent(): Quadkey | undefined {\n if (this.zoom > 0) {\n return new Quadkey().setId(bitShiftRight(bitShiftRight(this.id))).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) => this.compareTo(quadkey) !== 0)\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 const zoom = this.zoom\n const shift = (MAX_ZOOM - zoom) * 2\n const id = this.id\n let testId = id\n for (let i = 0; i < shift; i++) {\n testId = bitShiftLeft(testId)\n }\n for (let i = 0; i < shift; i++) {\n testId = bitShiftRight(testId)\n }\n return testId.compare(id) === 0\n }\n\n get zoom() {\n return this.buffer.readUInt8(0)\n }\n\n static from(zoom: number, id: Buffer) {\n return new Quadkey().setId(id).setZoom(zoom)\n }\n\n static fromBase10String(value: string) {\n return new Quadkey(Buffer.from(padHex(new BigNumber(value, 10).toString(16)), 'hex'))\n }\n\n static fromBase16String(value: string) {\n const valueToUse = value.startsWith('0x') ? value.slice(2) : value\n return new Quadkey(Buffer.from(padHex(valueToUse), 'hex'))\n }\n\n static fromBase4String(value?: string) {\n if (value === 'fhr' || value === '') {\n return Quadkey.root\n }\n if (value && value.length && value.length > 0) {\n const quadkey = new Quadkey(Buffer.from(padHex(new BigNumber(value, 4).toString(16)), 'hex')).setZoom(value.length)\n return quadkey.valid ? quadkey : undefined\n }\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 fromBuffer(value: Buffer) {\n return Quadkey.fromBase16String(value.toString('hex'))\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 = 10) {\n switch (base) {\n case 10:\n return Quadkey.fromBase10String(id)?.setZoom(zoom)\n case 16:\n return Quadkey.fromBase16String(id).setZoom(zoom)\n default:\n throw Error(`Invalid base [${base}]`)\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.concat(quadkey.childrenByZoom(zoom))\n }\n return deepResult\n }\n\n clone() {\n return Quadkey.fromBase10String(this.base10String)\n }\n\n compareTo(quadkey: Quadkey) {\n return this.bigNumber.cmp(quadkey.bigNumber)\n }\n\n equals(obj: Quadkey): boolean {\n return obj.base4HashLabel == this.base4HashLabel\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 case '2':\n top += blockSize\n break\n case '3':\n left += blockSize\n top += blockSize\n break\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 = parseInt(quadkey.charAt(index))\n number += directionConstant\n if (number > 3) {\n number -= 4\n quadkey = quadkey.substring(0, index) + number.toString() + quadkey.substring(index + 1)\n index--\n } else if (number < 0) {\n number += 4\n quadkey = quadkey.substring(0, index) + number.toString() + quadkey.substring(index + 1)\n index--\n } else {\n index = -1\n }\n }\n return Quadkey.fromBase4String(quadkey)\n }\n\n setId(id: Buffer) {\n this.setKey(this.zoom, id)\n return this\n }\n\n setKey(zoom: number, id: Buffer) {\n id.copy(this.key, this.key.length - id.length)\n this.key.writeUInt8(zoom, 0)\n return this\n }\n\n setZoom(zoom: number) {\n assertEx(zoom < MAX_ZOOM, `Invalid zoom [${zoom}] max=${MAX_ZOOM}`)\n this.setKey(zoom, this.id)\n return this\n }\n\n /** @deprecated use .base10String*/\n toBase10String() {\n return this.base10String\n }\n\n /** @deprecated use .base4Hash */\n toBase4Hash() {\n return this.base4Hash\n }\n\n /** @deprecated use .base4HashLabel */\n toBase4HashLabel() {\n const hash = this.base4HashLabel\n return hash.length === 0 ? 'fhr' : hash\n }\n\n /** @deprecated use .bigNumber */\n toBigNumber() {\n return this.bigNumber\n }\n\n /** @deprecated use .boundingBox */\n toBoundingBox(): MercatorBoundingBox {\n return this.boundingBox\n }\n\n /** @deprecated use .buffer */\n toBuffer() {\n return this.buffer\n }\n\n /** @deprecated use .center */\n toCenter() {\n return this.center\n }\n\n /** @deprecated use .hex instead */\n toHex() {\n return this.hex\n }\n\n toJSON(): string {\n return this.base4HashLabel\n }\n\n toShortString() {\n const buffer = this.buffer\n const part1 = buffer.slice(0, 2)\n const part2 = buffer.slice(buffer.length - 2, buffer.length)\n return `${part1.toString('hex')}...${part2.toString('hex')}`\n }\n\n toString() {\n return `0x${padHex(this.bigNumber.toString(16))}`\n }\n\n /** @deprecated use .tile instead */\n toTile(): MercatorTile {\n return this.tile\n }\n\n protected guessZoom() {\n const bn = new BigNumber(this.id.toString('hex'), 16)\n const quadkeySimple = bn.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","import { Buffer } from '@xylabs/buffer'\n\nexport const padHex = (hex: string, byteCount?: number) => {\n let result = hex\n if (hex.length % 2 !== 0) {\n result = `0${hex}`\n }\n if (byteCount) {\n while (result.length / 2 < byteCount) {\n result = `00${result}`\n }\n }\n return result\n}\n\nexport const bitShiftLeft = (buffer: Buffer) => {\n const shifted = Buffer.alloc(buffer.length)\n const last = buffer.length - 1\n for (let index = 0; index < last; index++) {\n shifted[index] = buffer[index] << 1\n if (buffer[index + 1] & 0x80) {\n shifted[index] += 0x01\n }\n }\n shifted[last] = buffer[last] << 1\n return shifted\n}\n\nexport const bitShiftRight = (buffer: Buffer) => {\n const shifted = Buffer.alloc(buffer.length)\n const last = buffer.length - 1\n for (let index = last; index > 0; index--) {\n shifted[index] = buffer[index] >> 1\n if (buffer[index - 1] & 0x01) {\n shifted[index] += 0x80\n }\n }\n shifted[0] = buffer[0] >> 1\n return shifted\n}\n"],"mappings":"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","names":["Buffer","Buffer"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/RelativeDirectionConstantLookup.ts"],"sourcesContent":["export const RelativeDirectionConstantLookup: Record<string, number> = {\n e: 1,\n n: -2,\n s: 2,\n w: -1,\n}\n"],"mappings":"AAAO,
|
|
1
|
+
{"version":3,"sources":["../../src/RelativeDirectionConstantLookup.ts"],"sourcesContent":["export const RelativeDirectionConstantLookup: Record<string, number> = {\n e: 1,\n n: -2,\n s: 2,\n w: -1,\n}\n"],"mappings":";AAAO,IAAM,kCAA0D;AAAA,EACrE,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;","names":[]}
|
package/dist/browser/index.js
CHANGED
|
@@ -1,2 +1,375 @@
|
|
|
1
|
-
|
|
1
|
+
// src/Quadkey.ts
|
|
2
|
+
import { assertEx } from "@xylabs/assert";
|
|
3
|
+
import { BigNumber } from "@xylabs/bignumber";
|
|
4
|
+
import { Buffer as Buffer2 } from "@xylabs/buffer";
|
|
5
|
+
import {
|
|
6
|
+
boundingBoxToCenter,
|
|
7
|
+
GeoJson,
|
|
8
|
+
tileFromPoint,
|
|
9
|
+
tileFromQuadkey,
|
|
10
|
+
tilesFromBoundingBox,
|
|
11
|
+
tileToBoundingBox,
|
|
12
|
+
tileToQuadkey
|
|
13
|
+
} from "@xyo-network/sdk-geo";
|
|
14
|
+
import { LngLat } from "mapbox-gl";
|
|
15
|
+
|
|
16
|
+
// src/RelativeDirectionConstantLookup.ts
|
|
17
|
+
var RelativeDirectionConstantLookup = {
|
|
18
|
+
e: 1,
|
|
19
|
+
n: -2,
|
|
20
|
+
s: 2,
|
|
21
|
+
w: -1
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// src/utils.ts
|
|
25
|
+
import { Buffer } from "@xylabs/buffer";
|
|
26
|
+
var padHex = (hex, byteCount) => {
|
|
27
|
+
let result = hex;
|
|
28
|
+
if (hex.length % 2 !== 0) {
|
|
29
|
+
result = `0${hex}`;
|
|
30
|
+
}
|
|
31
|
+
if (byteCount) {
|
|
32
|
+
while (result.length / 2 < byteCount) {
|
|
33
|
+
result = `00${result}`;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
var bitShiftLeft = (buffer) => {
|
|
39
|
+
const shifted = Buffer.alloc(buffer.length);
|
|
40
|
+
const last = buffer.length - 1;
|
|
41
|
+
for (let index = 0; index < last; index++) {
|
|
42
|
+
shifted[index] = buffer[index] << 1;
|
|
43
|
+
if (buffer[index + 1] & 128) {
|
|
44
|
+
shifted[index] += 1;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
shifted[last] = buffer[last] << 1;
|
|
48
|
+
return shifted;
|
|
49
|
+
};
|
|
50
|
+
var bitShiftRight = (buffer) => {
|
|
51
|
+
const shifted = Buffer.alloc(buffer.length);
|
|
52
|
+
const last = buffer.length - 1;
|
|
53
|
+
for (let index = last; index > 0; index--) {
|
|
54
|
+
shifted[index] = buffer[index] >> 1;
|
|
55
|
+
if (buffer[index - 1] & 1) {
|
|
56
|
+
shifted[index] += 128;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
shifted[0] = buffer[0] >> 1;
|
|
60
|
+
return shifted;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// src/Quadkey.ts
|
|
64
|
+
var MAX_ZOOM = 124;
|
|
65
|
+
var isQuadkey = (obj) => obj?.type === Quadkey.type;
|
|
66
|
+
var Quadkey = class _Quadkey {
|
|
67
|
+
static Zero = _Quadkey.from(0, Buffer2.alloc(31, 0));
|
|
68
|
+
static root = new _Quadkey();
|
|
69
|
+
static type = "Quadkey";
|
|
70
|
+
type = _Quadkey.type;
|
|
71
|
+
_geoJson;
|
|
72
|
+
key = Buffer2.alloc(32);
|
|
73
|
+
constructor(key = Buffer2.alloc(32)) {
|
|
74
|
+
key.copy(this.key, this.key.length - key.length);
|
|
75
|
+
this.guessZoom();
|
|
76
|
+
}
|
|
77
|
+
get base10String() {
|
|
78
|
+
return this.bigNumber.toString(10);
|
|
79
|
+
}
|
|
80
|
+
get base4Hash() {
|
|
81
|
+
const bn = new BigNumber(this.id.toString("hex"), 16);
|
|
82
|
+
const zoom = this.zoom;
|
|
83
|
+
if (zoom === 0) {
|
|
84
|
+
return "";
|
|
85
|
+
}
|
|
86
|
+
let quadkeySimple = bn.toString(4);
|
|
87
|
+
while (quadkeySimple.length < zoom) {
|
|
88
|
+
quadkeySimple = `0${quadkeySimple}`;
|
|
89
|
+
}
|
|
90
|
+
return quadkeySimple;
|
|
91
|
+
}
|
|
92
|
+
get base4HashLabel() {
|
|
93
|
+
const hash = this.base4Hash;
|
|
94
|
+
return hash.length === 0 ? "fhr" : hash;
|
|
95
|
+
}
|
|
96
|
+
get bigNumber() {
|
|
97
|
+
return new BigNumber(`${this.key.toString("hex")}`, "hex");
|
|
98
|
+
}
|
|
99
|
+
get boundingBox() {
|
|
100
|
+
return tileToBoundingBox(this.tile);
|
|
101
|
+
}
|
|
102
|
+
get buffer() {
|
|
103
|
+
return this.key;
|
|
104
|
+
}
|
|
105
|
+
get center() {
|
|
106
|
+
const result = boundingBoxToCenter(this.boundingBox);
|
|
107
|
+
return new LngLat(result[0], result[1]);
|
|
108
|
+
}
|
|
109
|
+
get children() {
|
|
110
|
+
assertEx(this.zoom < MAX_ZOOM - 1, "Can not get children of bottom tiles");
|
|
111
|
+
const result = [];
|
|
112
|
+
const shiftedId = bitShiftLeft(bitShiftLeft(this.id));
|
|
113
|
+
for (let i = 0; i < 4; i++) {
|
|
114
|
+
const currentLastByte = shiftedId.readUInt8(shiftedId.length - 1);
|
|
115
|
+
shiftedId.writeUInt8(currentLastByte & 252 | i, shiftedId.length - 1);
|
|
116
|
+
result.push(new _Quadkey().setId(shiftedId).setZoom(this.zoom + 1));
|
|
117
|
+
}
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
get gridLocation() {
|
|
121
|
+
const tileData = tileFromQuadkey(this.base4Hash);
|
|
122
|
+
return {
|
|
123
|
+
col: 2 ** tileData[2] - tileData[1] - 1,
|
|
124
|
+
row: tileData[0],
|
|
125
|
+
zoom: tileData[2]
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
get hex() {
|
|
129
|
+
return `0x${this.key.toString("hex")}`;
|
|
130
|
+
}
|
|
131
|
+
get id() {
|
|
132
|
+
return this.buffer.slice(1);
|
|
133
|
+
}
|
|
134
|
+
get parent() {
|
|
135
|
+
if (this.zoom > 0) {
|
|
136
|
+
return new _Quadkey().setId(bitShiftRight(bitShiftRight(this.id))).setZoom(this.zoom - 1);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
get siblings() {
|
|
140
|
+
const siblings = assertEx(this.parent?.children, `siblings: parentChildren ${this.base4Hash}`);
|
|
141
|
+
const filteredSiblings = siblings.filter((quadkey) => this.compareTo(quadkey) !== 0);
|
|
142
|
+
assertEx(filteredSiblings.length === 3, `siblings: expected 3 [${filteredSiblings.length}]`);
|
|
143
|
+
return filteredSiblings;
|
|
144
|
+
}
|
|
145
|
+
get tile() {
|
|
146
|
+
return tileFromQuadkey(this.base4Hash);
|
|
147
|
+
}
|
|
148
|
+
get valid() {
|
|
149
|
+
const zoom = this.zoom;
|
|
150
|
+
const shift = (MAX_ZOOM - zoom) * 2;
|
|
151
|
+
const id = this.id;
|
|
152
|
+
let testId = id;
|
|
153
|
+
for (let i = 0; i < shift; i++) {
|
|
154
|
+
testId = bitShiftLeft(testId);
|
|
155
|
+
}
|
|
156
|
+
for (let i = 0; i < shift; i++) {
|
|
157
|
+
testId = bitShiftRight(testId);
|
|
158
|
+
}
|
|
159
|
+
return testId.compare(id) === 0;
|
|
160
|
+
}
|
|
161
|
+
get zoom() {
|
|
162
|
+
return this.buffer.readUInt8(0);
|
|
163
|
+
}
|
|
164
|
+
static from(zoom, id) {
|
|
165
|
+
return new _Quadkey().setId(id).setZoom(zoom);
|
|
166
|
+
}
|
|
167
|
+
static fromBase10String(value) {
|
|
168
|
+
return new _Quadkey(Buffer2.from(padHex(new BigNumber(value, 10).toString(16)), "hex"));
|
|
169
|
+
}
|
|
170
|
+
static fromBase16String(value) {
|
|
171
|
+
const valueToUse = value.startsWith("0x") ? value.slice(2) : value;
|
|
172
|
+
return new _Quadkey(Buffer2.from(padHex(valueToUse), "hex"));
|
|
173
|
+
}
|
|
174
|
+
static fromBase4String(value) {
|
|
175
|
+
if (value === "fhr" || value === "") {
|
|
176
|
+
return _Quadkey.root;
|
|
177
|
+
}
|
|
178
|
+
if (value && value.length && value.length > 0) {
|
|
179
|
+
const quadkey = new _Quadkey(Buffer2.from(padHex(new BigNumber(value, 4).toString(16)), "hex")).setZoom(value.length);
|
|
180
|
+
return quadkey.valid ? quadkey : void 0;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
static fromBoundingBox(boundingBox, zoom) {
|
|
184
|
+
const tiles = tilesFromBoundingBox(boundingBox, Math.floor(zoom));
|
|
185
|
+
const result = [];
|
|
186
|
+
for (const tile of tiles) {
|
|
187
|
+
result.push(assertEx(_Quadkey.fromTile(tile), "Bad Quadkey"));
|
|
188
|
+
}
|
|
189
|
+
return result;
|
|
190
|
+
}
|
|
191
|
+
static fromBuffer(value) {
|
|
192
|
+
return _Quadkey.fromBase16String(value.toString("hex"));
|
|
193
|
+
}
|
|
194
|
+
static fromLngLat(point, zoom) {
|
|
195
|
+
const tile = tileFromPoint(LngLat.convert(point), zoom);
|
|
196
|
+
const quadkeyString = tileToQuadkey(tile);
|
|
197
|
+
return _Quadkey.fromBase4String(quadkeyString);
|
|
198
|
+
}
|
|
199
|
+
static fromString(zoom, id, base = 10) {
|
|
200
|
+
switch (base) {
|
|
201
|
+
case 10:
|
|
202
|
+
return _Quadkey.fromBase10String(id)?.setZoom(zoom);
|
|
203
|
+
case 16:
|
|
204
|
+
return _Quadkey.fromBase16String(id).setZoom(zoom);
|
|
205
|
+
default:
|
|
206
|
+
throw Error(`Invalid base [${base}]`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
static fromTile(tile) {
|
|
210
|
+
return _Quadkey.fromBase4String(tileToQuadkey(tile));
|
|
211
|
+
}
|
|
212
|
+
childrenByZoom(zoom) {
|
|
213
|
+
if (zoom && zoom === this.zoom) {
|
|
214
|
+
return [this];
|
|
215
|
+
}
|
|
216
|
+
let deepResult = [];
|
|
217
|
+
for (const quadkey of this.children) {
|
|
218
|
+
deepResult = deepResult.concat(quadkey.childrenByZoom(zoom));
|
|
219
|
+
}
|
|
220
|
+
return deepResult;
|
|
221
|
+
}
|
|
222
|
+
clone() {
|
|
223
|
+
return _Quadkey.fromBase10String(this.base10String);
|
|
224
|
+
}
|
|
225
|
+
compareTo(quadkey) {
|
|
226
|
+
return this.bigNumber.cmp(quadkey.bigNumber);
|
|
227
|
+
}
|
|
228
|
+
equals(obj) {
|
|
229
|
+
return obj.base4HashLabel == this.base4HashLabel;
|
|
230
|
+
}
|
|
231
|
+
geoJson() {
|
|
232
|
+
this._geoJson = this._geoJson ?? new GeoJson(this.base4Hash);
|
|
233
|
+
return this._geoJson;
|
|
234
|
+
}
|
|
235
|
+
getGridBoundingBox(size) {
|
|
236
|
+
const hash = this.base4Hash;
|
|
237
|
+
let index = 0;
|
|
238
|
+
let left = 0;
|
|
239
|
+
let top = 0;
|
|
240
|
+
let blockSize = size;
|
|
241
|
+
while (index < hash.length) {
|
|
242
|
+
blockSize >>= 1;
|
|
243
|
+
switch (hash[index]) {
|
|
244
|
+
case "1":
|
|
245
|
+
left += blockSize;
|
|
246
|
+
break;
|
|
247
|
+
case "2":
|
|
248
|
+
top += blockSize;
|
|
249
|
+
break;
|
|
250
|
+
case "3":
|
|
251
|
+
left += blockSize;
|
|
252
|
+
top += blockSize;
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
index++;
|
|
256
|
+
}
|
|
257
|
+
if (blockSize < 2) {
|
|
258
|
+
blockSize = 2;
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
height: blockSize,
|
|
262
|
+
left,
|
|
263
|
+
top,
|
|
264
|
+
width: blockSize
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
/** @deprecated use .gridLocation instead */
|
|
268
|
+
getGridLocation() {
|
|
269
|
+
return this.gridLocation;
|
|
270
|
+
}
|
|
271
|
+
isInBoundingBox(boundingBox) {
|
|
272
|
+
const tileBoundingBox = tileToBoundingBox(this.tile);
|
|
273
|
+
return boundingBox.contains(tileBoundingBox.getNorthEast()) || boundingBox.contains(tileBoundingBox.getNorthWest()) || boundingBox.contains(tileBoundingBox.getSouthEast()) || boundingBox.contains(tileBoundingBox.getSouthWest());
|
|
274
|
+
}
|
|
275
|
+
relative(direction) {
|
|
276
|
+
const directionConstant = assertEx(RelativeDirectionConstantLookup[direction], "Invalid direction");
|
|
277
|
+
let quadkey = this.base4Hash;
|
|
278
|
+
if (quadkey.length === 0) {
|
|
279
|
+
return this;
|
|
280
|
+
}
|
|
281
|
+
let index = quadkey.length - 1;
|
|
282
|
+
while (index >= 0) {
|
|
283
|
+
let number = parseInt(quadkey.charAt(index));
|
|
284
|
+
number += directionConstant;
|
|
285
|
+
if (number > 3) {
|
|
286
|
+
number -= 4;
|
|
287
|
+
quadkey = quadkey.substring(0, index) + number.toString() + quadkey.substring(index + 1);
|
|
288
|
+
index--;
|
|
289
|
+
} else if (number < 0) {
|
|
290
|
+
number += 4;
|
|
291
|
+
quadkey = quadkey.substring(0, index) + number.toString() + quadkey.substring(index + 1);
|
|
292
|
+
index--;
|
|
293
|
+
} else {
|
|
294
|
+
index = -1;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return _Quadkey.fromBase4String(quadkey);
|
|
298
|
+
}
|
|
299
|
+
setId(id) {
|
|
300
|
+
this.setKey(this.zoom, id);
|
|
301
|
+
return this;
|
|
302
|
+
}
|
|
303
|
+
setKey(zoom, id) {
|
|
304
|
+
id.copy(this.key, this.key.length - id.length);
|
|
305
|
+
this.key.writeUInt8(zoom, 0);
|
|
306
|
+
return this;
|
|
307
|
+
}
|
|
308
|
+
setZoom(zoom) {
|
|
309
|
+
assertEx(zoom < MAX_ZOOM, `Invalid zoom [${zoom}] max=${MAX_ZOOM}`);
|
|
310
|
+
this.setKey(zoom, this.id);
|
|
311
|
+
return this;
|
|
312
|
+
}
|
|
313
|
+
/** @deprecated use .base10String*/
|
|
314
|
+
toBase10String() {
|
|
315
|
+
return this.base10String;
|
|
316
|
+
}
|
|
317
|
+
/** @deprecated use .base4Hash */
|
|
318
|
+
toBase4Hash() {
|
|
319
|
+
return this.base4Hash;
|
|
320
|
+
}
|
|
321
|
+
/** @deprecated use .base4HashLabel */
|
|
322
|
+
toBase4HashLabel() {
|
|
323
|
+
const hash = this.base4HashLabel;
|
|
324
|
+
return hash.length === 0 ? "fhr" : hash;
|
|
325
|
+
}
|
|
326
|
+
/** @deprecated use .bigNumber */
|
|
327
|
+
toBigNumber() {
|
|
328
|
+
return this.bigNumber;
|
|
329
|
+
}
|
|
330
|
+
/** @deprecated use .boundingBox */
|
|
331
|
+
toBoundingBox() {
|
|
332
|
+
return this.boundingBox;
|
|
333
|
+
}
|
|
334
|
+
/** @deprecated use .buffer */
|
|
335
|
+
toBuffer() {
|
|
336
|
+
return this.buffer;
|
|
337
|
+
}
|
|
338
|
+
/** @deprecated use .center */
|
|
339
|
+
toCenter() {
|
|
340
|
+
return this.center;
|
|
341
|
+
}
|
|
342
|
+
/** @deprecated use .hex instead */
|
|
343
|
+
toHex() {
|
|
344
|
+
return this.hex;
|
|
345
|
+
}
|
|
346
|
+
toJSON() {
|
|
347
|
+
return this.base4HashLabel;
|
|
348
|
+
}
|
|
349
|
+
toShortString() {
|
|
350
|
+
const buffer = this.buffer;
|
|
351
|
+
const part1 = buffer.slice(0, 2);
|
|
352
|
+
const part2 = buffer.slice(buffer.length - 2, buffer.length);
|
|
353
|
+
return `${part1.toString("hex")}...${part2.toString("hex")}`;
|
|
354
|
+
}
|
|
355
|
+
toString() {
|
|
356
|
+
return `0x${padHex(this.bigNumber.toString(16))}`;
|
|
357
|
+
}
|
|
358
|
+
/** @deprecated use .tile instead */
|
|
359
|
+
toTile() {
|
|
360
|
+
return this.tile;
|
|
361
|
+
}
|
|
362
|
+
guessZoom() {
|
|
363
|
+
const bn = new BigNumber(this.id.toString("hex"), 16);
|
|
364
|
+
const quadkeySimple = bn.toString(4);
|
|
365
|
+
this.setZoom(quadkeySimple.length);
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
export {
|
|
369
|
+
Quadkey,
|
|
370
|
+
bitShiftLeft,
|
|
371
|
+
bitShiftRight,
|
|
372
|
+
isQuadkey,
|
|
373
|
+
padHex
|
|
374
|
+
};
|
|
2
375
|
//# sourceMappingURL=index.js.map
|