From 8aac294603568479c23fb8f2186982a895321678 Mon Sep 17 00:00:00 2001 From: Brandon Liu Date: Thu, 17 Feb 2022 13:29:26 +0800 Subject: [PATCH] force re-sorting of directory if spec v1 detected [#27] --- js/pmtiles.ts | 52 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/js/pmtiles.ts b/js/pmtiles.ts index 4281fcf..ab786d3 100644 --- a/js/pmtiles.ts +++ b/js/pmtiles.ts @@ -120,6 +120,14 @@ export const parseEntry = (dataview: DataView, i: number): Entry => { }; }; +export const sortDir = (dataview: DataView): ArrayBuffer => { + let entries: Entry[] = []; + for (var i = 0; i < dataview.byteLength / 17; i++) { + entries.push(parseEntry(dataview, i)); + } + return createDirectory(entries); +}; + export const createDirectory = (entries: Entry[]): ArrayBuffer => { entries.sort(entrySort); @@ -240,14 +248,21 @@ export class PMTiles { let a = await resp.arrayBuffer(); let header = parseHeader(new DataView(a, 0, 10)); + + var root_dir = new DataView( + a, + 10 + header.json_size, + 17 * header.root_entries + ); + if (header.version === 1) { + console.log("Sorting pmtiles v1 directory"); + root_dir = new DataView(sortDir(root_dir)); + } + return { buffer: a, header: header, - dir: new DataView( - a, - 10 + header.json_size, - 17 * header.root_entries - ), + dir: root_dir, }; }; @@ -271,7 +286,10 @@ export class PMTiles { return result; }; - fetchLeafdir = async (entry: Entry): Promise => { + fetchLeafdir = async ( + version: number, + entry: Entry + ): Promise => { let resp = await fetch(this.url, { headers: { Range: @@ -281,14 +299,25 @@ export class PMTiles { (entry.offset + entry.length - 1), }, }); - return await resp.arrayBuffer(); + var buf = await resp.arrayBuffer(); + + if (version === 1) { + console.log("Sorting pmtiles v1 directory"); + buf = sortDir(new DataView(buf)); + } + + return buf; }; - getLeafdir = async (entry: Entry): Promise => { + getLeafdir = async ( + version: number, + entry: Entry + ): Promise => { let leaf = this.leaves.get(entry.offset); if (leaf) return await leaf.buffer; - let buf = this.fetchLeafdir(entry); + var buf = this.fetchLeafdir(version, entry); + this.leaves.set(entry.offset, { lastUsed: performance.now(), buffer: buf, @@ -321,7 +350,10 @@ export class PMTiles { ); if (leafdir_entry) { - let leafdir = await this.getLeafdir(leafdir_entry); + let leafdir = await this.getLeafdir( + root.header.version, + leafdir_entry + ); return queryTile(new DataView(leafdir), z, x, y); } return null;