fix root dir writing, refactor js getZxy

This commit is contained in:
Brandon Liu
2021-02-18 16:21:30 +08:00
parent ab8f1e889d
commit f309d81aa2
4 changed files with 79 additions and 52 deletions

View File

@@ -42,7 +42,7 @@
class PMTiles { class PMTiles {
constructor(url,ready) { constructor(url,ready) {
this.url = url this.url = url
this.apex = fetch(this.url,{method:'HEAD',headers:{'Range':'bytes=0-511999'}}).then(resp => { this.rootdir = fetch(this.url,{method:'HEAD',headers:{'Range':'bytes=0-511999'}}).then(resp => {
if (resp.status == 206) { // this does not work on Azure, it returns 200 instead of 206 if (resp.status == 206) { // this does not work on Azure, it returns 200 instead of 206
console.log("Check succeeded: server supports byte ranges") console.log("Check succeeded: server supports byte ranges")
return fetch(this.url,{headers:{'Range':'bytes=0-511999'}}).then(resp => { return fetch(this.url,{headers:{'Range':'bytes=0-511999'}}).then(resp => {
@@ -70,19 +70,20 @@
this.outstanding_requests.get(tilestr).push(resolve) this.outstanding_requests.get(tilestr).push(resolve)
} else { } else {
this.outstanding_requests.set(tilestr,[]) this.outstanding_requests.set(tilestr,[])
this.apex.then(apex_map => { this.rootdir.then(rootdir => {
if (apex_map.has(tilestr)) { if (rootdir.has(tilestr)) {
var val = apex_map.get(tilestr) var val = rootdir.get(tilestr)
if (val[2] == 1) { // it is a directory if (val[2] == 1) { // it is a directory
fetch(this.url, {headers:{'range':'bytes=' + val[0] + '-' + (val[0] + val[1]-1)}}).then(resp => { fetch(this.url, {headers:{'range':'bytes=' + val[0] + '-' + (val[0] + val[1]-1)}}).then(resp => {
return resp.arraybuffer() return resp.arrayBuffer()
}).then(buf => { }).then(buf => {
var map = bytestomap(buf,val[1]/17) var map = bytesToMap(new DataView(buf),val[1]/17)
this.leaves.set(tilestr,map) this.leaves.set(tilestr,map)
resolve(map) resolve(map)
this.outstanding_requests.get(tilestr).foreach(f => { this.outstanding_requests.get(tilestr).forEach(f => {
f(map) f(map)
}) })
// TODO fix duplication of multiple leaves in same directory
console.log("leaves: ", this.leaves.size) console.log("leaves: ", this.leaves.size)
}) })
} }
@@ -92,52 +93,71 @@
}) })
} }
transformRequest = (u,t,tile,done) => { getZxy = (z,x,y) => {
if (t == 'Tile' && done) { var strid = z + '_' + x + '_' + y
var tid = tile.tileID.canonical return this.rootdir.then(rootdir => {
var strid = tid.z + '_' + tid.x + '_' + tid.y if (rootdir.has(strid) && rootdir.get(strid)[2] == 0) {
this.apex.then(map => { return rootdir.get(strid)
if (map.has(strid) && map.get(strid)[2] == 0) { } else {
var val = map.get(strid) if (z >= 7) {
done({url: this.url, headers:{'Range':'bytes=' + val[0] + '-' + (val[0]+val[1]-1)}}) var z7_tile_diff = (z - 7)
} else { var z7_tile = [7,Math.trunc(x / (1 << z7_tile_diff)), Math.trunc(y / (1 << z7_tile_diff))]
if (tid.z >= 7) { var z7_tile_str = z7_tile[0] + "_" + z7_tile[1] + "_" + z7_tile[2]
var z7_tile_diff = (tid.z - 7) return this.getLeaf(z7_tile_str).then(leafdir => {
var z7_tile = [7,Math.trunc(tid.x / (1 << z7_tile_diff)), Math.trunc(tid.y / (1 << z7_tile_diff))] if (leafdir.has(strid)) {
var z7_tile_str = z7_tile[0] + "_" + z7_tile[1] + "_" + z7_tile[2] return leafdir.get(strid)
this.getLeaf(z7_tile_str).then(map => { }
if (map.has(strid)) { return null
var val = map.get(strid) })
done({url: this.url, headers:{'Range':'bytes=' + val[0] + '-' + (val[0]+val[1]-1)}}) }
} }
}) return null
} })
}
})
}
return {url: u}
} }
// transformRequest = (u,t,tile,done) => {
// if (t == 'Tile' && done) {
// var tid = tile.tileID.canonical
// var strid = tid.z + '_' + tid.x + '_' + tid.y
// this.rootdir.then(rootdir => {
// if (rootdir.has(strid) && rootdir.get(strid)[2] == 0) {
// var val = rootdir.get(strid)
// done({url: this.url, headers:{'Range':'bytes=' + val[0] + '-' + (val[0]+val[1]-1)}})
// } else {
// if (tid.z >= 7) {
// var z7_tile_diff = (tid.z - 7)
// var z7_tile = [7,Math.trunc(tid.x / (1 << z7_tile_diff)), Math.trunc(tid.y / (1 << z7_tile_diff))]
// var z7_tile_str = z7_tile[0] + "_" + z7_tile[1] + "_" + z7_tile[2]
// this.getLeaf(z7_tile_str).then(leafdir => {
// if (leafdir.has(strid)) {
// var val = leafdir.get(strid)
// done({url: this.url, headers:{'Range':'bytes=' + val[0] + '-' + (val[0]+val[1]-1)}})
// }
// })
// }
// }
// })
// }
// return {url: u}
// }
leafletLayer = options => { leafletLayer = options => {
const self = this const self = this
var cls = L.GridLayer.extend({ var cls = L.GridLayer.extend({
createTile: function(coords, done){ createTile: function(coord, done){
var tile = document.createElement('img') var tile = document.createElement('img')
var error var error
self.apex.then(map => { self.getZxy(coord.z,coord.x,coord.y).then(result => {
var strid = coords.z + '_' + coords.x + '_' + coords.y if (result === null) return
if (map.has(strid)) { fetch(self.url,{headers:{'Range':'bytes=' + result[0] + '-' + (result[0]+result[1]-1)}}).then(resp => {
var val = map.get(strid) return resp.arrayBuffer()
fetch(self.url,{headers:{'Range':'bytes=' + val[0] + '-' + (val[0]+val[1]-1)}}).then(resp => { }).then(buf => {
return resp.arrayBuffer() var blob = new Blob( [buf], { type: "image/png" } )
}).then(buf => { var imageUrl = window.URL.createObjectURL(blob)
var blob = new Blob( [buf], { type: "image/png" } ) tile.src = imageUrl
var imageUrl = window.URL.createObjectURL(blob) done(error,tile)
tile.src = imageUrl })
done(error,tile)
})
}
}) })
return tile return tile
}, },

View File

@@ -8,8 +8,14 @@ if len(sys.argv) <= 1:
exit(1) exit(1)
with read(sys.argv[1]) as reader: with read(sys.argv[1]) as reader:
print('spec version: ',reader.version) if len(sys.argv) == 2:
print('metadata:') print('spec version: ',reader.version)
for k, v in reader.metadata.items(): print('metadata:')
print(k,'=',v) for k, v in reader.metadata.items():
print('root entries:', reader.root_entries) print(k,'=',v)
print('root entries:', reader.root_entries)
else:
z = int(sys.argv[2])
x = int(sys.argv[3])
y = int(sys.argv[4])
print(reader.get(z,x,y))

View File

@@ -47,6 +47,7 @@ class Reader:
def root_entries(self): def root_entries(self):
return int.from_bytes(self.mmap[8:10],byteorder='little') return int.from_bytes(self.mmap[8:10],byteorder='little')
# TODO support recursive directories
def get(self,z,x,y): def get(self,z,x,y):
val = self.root_dir.get((z,x,y)) val = self.root_dir.get((z,x,y))
if val: if val:

View File

@@ -97,8 +97,8 @@ class Writer:
if len(leafdir_tiles): if len(leafdir_tiles):
self.write_leafdir(leafdir_tiles) self.write_leafdir(leafdir_tiles)
root = [group for group in itertools.groupby(self.tiles,key=by_parent) if group[0][0] == 0][0] root = [(group[0],list(group[1])) for group in itertools.groupby(self.tiles,key=by_parent) if group[0][0] == 0][0]
root_tiles = list(root[1]) root_tiles = root[1]
self.f.seek(0) self.f.seek(0)
self.write_header(metadata,len(root_tiles) + len(self.leaves)) self.write_header(metadata,len(root_tiles) + len(self.leaves))
for entry in root_tiles: for entry in root_tiles: