-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathworker.js
92 lines (87 loc) · 3.34 KB
/
worker.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
importScripts('kdbush.js')
importScripts('spectrum.js')
var tree = null
var requestQueue = []
var viewX = null
var viewY = null
var viewZ = null
var viewCount = null
var indices = null
var maxCountByZoom = null
self.addEventListener('message', handler, false)
function handler(e) {
if (e.data.request === 'init') {
// initialize with file content
console.time("build indices")
viewX = new Uint32Array(e.data.x)
viewY = new Uint32Array(e.data.y)
viewZ = new Uint8Array(e.data.z)
viewCount = new Uint32Array(e.data.count)
indices = new Uint32Array(e.data.indices)
maxCountByZoom = e.data.maxCountByZoom
tree = new KDBush(indices, function(i) {return viewX[i]}, function(i) {return viewY[i]}, 256, Uint32Array)
console.timeEnd("build indices")
self.postMessage('building spatial index')
requestQueue.forEach(handler)
requestQueue = null
} else if (e.data.request === 'render') {
if (tree === null) {
requestQueue.push(e)
return
}
// render tile
var overzoom = e.data.overzoom || 0
var zoom = e.data.zoom
var tilePoint = e.data.tilePoint
var tileSize = e.data.tileSize
console.time("search data")
fDataIndices = tree.range(
tilePoint.x*tileSize/Math.pow(2,overzoom),
tilePoint.y*tileSize/Math.pow(2,overzoom),
(tilePoint.x+1)*tileSize/Math.pow(2,overzoom)-1,
(tilePoint.y+1)*tileSize/Math.pow(2,overzoom)-1
).filter(function(index) { return viewZ[index] === zoom+8-overzoom })
console.timeEnd("search data")
console.time("render tile")
var pixels = new Uint32Array(tileSize*tileSize*1)
var pixelsView = new DataView(pixels.buffer)
fDataIndices.forEach(function(index) {
var count = viewCount[index]
var dataX = viewX[index]
var dataY = viewY[index]
var dataZ = viewZ[index]
var color = Math.max(0,1-(Math.log(count)-Math.log(10))/(Math.log(maxCountByZoom[dataZ])-Math.log(10)))
color = (parseInt(magma(color).substr(1), 16) << 8) + 255
for (var y=(dataY*Math.pow(2,overzoom))%tileSize; y<((dataY*Math.pow(2,overzoom))%tileSize)+Math.pow(2,overzoom); y++)
for (var x=(dataX*Math.pow(2,overzoom))%tileSize; x<((dataX*Math.pow(2,overzoom))%tileSize)+Math.pow(2,overzoom); x++)
pixelsView.setInt32(4*(y*tileSize+x), color, false)
})
console.timeEnd("render tile")
console.time("send data")
var data = {
answer: 'render',
tileId: e.data.tileId,
pixels: pixels.buffer
}
self.postMessage(data, [data.pixels])
console.timeEnd("send data")
} else if (e.data.request === 'query') {
if (tree === null) {
requestQueue.push(e)
return
}
fDataIndices = tree.range(
e.data.x, e.data.y,
e.data.x, e.data.y
).filter(function(index) { return viewZ[index] === e.data.z })
self.postMessage({
answer: 'query',
x: e.data.x,
y: e.data.y,
z: e.data.z,
result: fDataIndices[0] && viewCount[fDataIndices[0]]
})
} else {
throw "worker received unknown request"
}
}