UNPKG

geojson-vt

Version:

Slice GeoJSON data into vector tiles efficiently

210 lines (163 loc) 6.25 kB
<!DOCTYPE html> <html> <head> <title>debug page</title> <meta charset='utf-8'> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> body { padding: 0; margin: 0; } #canvas { border-right: 1px dotted #aaa; border-bottom: 1px dotted #aaa;} #canvas.hover { background: #cfc; } button { font-size: 16px; background: white; border: 1px solid #ccc; position: absolute; top: 5px; left: 5px;} button:hover { border-color: black; } </style> </head> <body> <script src='geojson-vt-dev.js'></script> <canvas id="canvas"></canvas> <button id="back">&larr;</button> <script> var options = { maxZoom: 4, maxPoints: 100, debug: 1 }, extent = 4096, padding = 8 / 512, totalExtent = 4096 * (1 + padding * 2), tileIndex, canvas = document.getElementById('canvas'), ctx = canvas.getContext('2d'), height = canvas.height = canvas.width = window.innerHeight - 5, ratio = height / totalExtent, pad = 4096 * padding * ratio, x = 0, y = 0, z = 0; if (devicePixelRatio > 1) { canvas.style.width = canvas.width + 'px'; canvas.style.height = canvas.height + 'px'; canvas.width *= 2; canvas.height *= 2; ctx.scale(2, 2); } ctx.textAlign = 'center'; ctx.font = '48px Helvetica, Arial'; ctx.fillText("Drag a GeoJSON here", height / 2, height / 2); function humanFileSize(size) { var i = Math.floor(Math.log(size) / Math.log(1024)); return Math.round(100 * (size / Math.pow(1024, i))) / 100 + ' ' + ['B', 'kB', 'MB', 'GB'][i]; }; canvas.ondragover = function () { this.className = 'hover'; return false; }; canvas.ondragend = function () { this.className = ''; return false; }; canvas.ondrop = function (e) { this.className = 'loaded'; ctx.clearRect(0, 0, height, height); ctx.fillText("Thanks! Loading...", height / 2, height / 2); var reader = new FileReader(); reader.onload = function (event) { console.log('data size', humanFileSize(event.target.result.length)); console.time('JSON.parse'); var data = JSON.parse(event.target.result); console.timeEnd('JSON.parse'); tileIndex = geojsonvt(data, options); drawTile(); }; reader.readAsText(e.dataTransfer.files[0]); e.preventDefault(); return false; }; ctx.lineWidth = 1; var halfHeight = height / 2; function drawGrid() { ctx.strokeStyle = 'lightgreen'; ctx.strokeRect(pad, pad, height - 2 * pad, height - 2 * pad); ctx.beginPath(); ctx.moveTo(pad, halfHeight); ctx.lineTo(height - pad, halfHeight); ctx.moveTo(halfHeight, pad); ctx.lineTo(halfHeight, height - pad); ctx.stroke(); } function drawSquare(left, top) { ctx.strokeStyle = 'blue'; var x = left ? pad : halfHeight; var y = top ? pad : halfHeight; ctx.strokeRect(x, y, halfHeight - pad, halfHeight - pad); } function drawTile() { var tile = tileIndex.getTile(z, x, y); if (!tile) { console.log('tile empty'); zoomOut(); return; } // console.log('z%d-%d-%d: %d points of %d', z, x, y, tile.numSimplified, tile.numPoints); // console.time('draw'); ctx.clearRect(0, 0, height, height); var features = tile.features; ctx.strokeStyle = 'red'; ctx.fillStyle = 'rgba(255,0,0,0.05)'; for (var i = 0; i < features.length; i++) { var feature = features[i], typeChanged = type !== feature.type, type = feature.type; ctx.beginPath(); for (var j = 0; j < feature.geometry.length; j++) { var ring = feature.geometry[j]; for (var k = 0; k < ring.length; k++) { var p = ring[k]; if (k) ctx.lineTo(p[0] * ratio + pad, p[1] * ratio + pad); else ctx.moveTo(p[0] * ratio + pad, p[1] * ratio + pad); } } if (type === 3) ctx.fill('evenodd'); ctx.stroke(); } drawGrid(); // console.timeEnd('draw'); } canvas.onclick = function (e) { if (!tileIndex || z === 14) return; var mouseX = e.layerX - 10, mouseY = e.layerY - 10, left = mouseX / height < 0.5, top = mouseY / height < 0.5; z++; x *= 2; y *= 2; if (!left) x++; if (!top) y++; drawTile(); drawSquare(left, top); if (z > 0) backButton.style.display = ''; }; canvas.onmousemove = function (e) { if (!tileIndex) return; var mouseX = e.layerX - 10, mouseY = e.layerY - 10, left = mouseX / height < 0.5, top = mouseY / height < 0.5; drawGrid(); drawSquare(left, top); } function zoomOut() { z--; x = Math.floor(x / 2); y = Math.floor(y / 2); } var backButton = document.getElementById('back'); backButton.style.display = 'none'; backButton.onclick = function (e) { if (!tileIndex) return; zoomOut(); drawTile(); if (z === 0) backButton.style.display = 'none'; } function toID(z, x, y) { return (((1 << z) * y + x) * 32) + z; } </script> </body> </html>