diff --git a/cmd/mtwebmapper/web/js/auto-update.js b/cmd/mtwebmapper/web/js/auto-update.js new file mode 100644 index 0000000..6ee763a --- /dev/null +++ b/cmd/mtwebmapper/web/js/auto-update.js @@ -0,0 +1,132 @@ +L.Control.AutoUpdate = L.Control.extend({ + options: { + position: 'topleft', + label: 'Automatic update' + }, + + onAdd: function() { + var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control'); + container.innerHTML = '
'; + L.DomEvent.on(container, 'click', this.cbClick, this); + return container; + }, + + cbClick: function (e) { + L.DomEvent.stopPropagation(e); + this.intendedFunction(e); + if (e.target.checked) { + this.autoUpdate(); + } + if (!e.target.checked) { + this.stopUpdate(); + } + }, + + intendedFunction: function() { + alert('no function selected'); + }, + + stopUpdate: function() { + this.socket.close(); + }, + + autoUpdate: function() { + this.socket = new WebSocket('ws://' + window.location.host + '/ws'); + + this.socket.onmessage = function(evt) { + + var invalidate = function(json) { + var invalidateAll = function(x, y, z) { return true }; + + if (!(typeof json === "string")) { + return invalidateAll; + } + var tiles; + try { + tiles = JSON.parse(json); + } catch (err) { + return invalidateAll; + } + + var pyramid = new Array(9); + var last = new Object(); + pyramid[8] = last; + + for (var i = 0; i < tiles.length; i++) { + var xz = tiles[i]; + last[xz.X + "#" + xz.Z] = xz; + } + for (var p = 7; p >= 0; p--) { + var prev = pyramid[p+1] + var curr = new Object(); + pyramid[p] = curr; + for (var k in prev) { + if (prev.hasOwnProperty(k)) { + var oxz = prev[k] + var nxz = { X: oxz.X >> 1, Z: oxz.Z >> 1 }; + curr[nxz.X + "#" + nxz.Z] = nxz; + } + } + } + return function(x, y, z) { + if (y > 8) { + x >>= y - 8; + z >>= y - 8; + y = 8; + } + var level = pyramid[y]; + var k = x + "#" + z; + return level.hasOwnProperty(k); + }; + } (evt.data); + + var tiles = document.getElementsByTagName('img'); + var re = /\/map\/([0-9]+)\/([0-9]+)\/([0-9]+).*/; + for (var i = 0; i < tiles.length; i++) { + var img = tiles[i]; + var cl = img.getAttribute('class'); + if (!cl.contains('leaflet-tile-loaded')) { + continue; + } + var src = img.src; + var coord = src.match(re); + if (coord == null) { + continue; + } + var y = parseInt(coord[1], 10); + var x = parseInt(coord[2], 10); + var z = parseInt(coord[3], 10); + if (invalidate(x, y, z)) { + var idx = src.lastIndexOf('#'); + if (idx >= 0) { + src = src.substring(0, idx); + } + img.src = src + '#' + Math.random(); + } + } + }; + } +}); + +L.autoUpdate = function(cbLabel, cbFunc, cbMap) { + var control = new L.Control.AutoUpdate(); + if (cbLabel) { + control.options.label = cbLabel; + } + + if (cbFunc) { + control.intendedFunction = cbFunc; + } + + if (cbMap === '') { + return control; + } + else if (cbMap) { + cbMap.addControl(control); + } + else { + map.addControl(control); + } + return control; +};