From f9c16f2d6ded171b7285220d8db61c21e8e138ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Stra=C3=9Fburger?= Date: Thu, 10 Nov 2016 08:00:36 +0100 Subject: [PATCH] :art: pulling and using individual tile extents in preperation for reduced tiles --- src/Renderer.coffee | 60 ++++++++++++++++++++------------------------- src/Tile.coffee | 10 +++++--- src/config.coffee | 37 ++++++++++++++-------------- src/utils.coffee | 6 +++++ 4 files changed, 57 insertions(+), 56 deletions(-) diff --git a/src/Renderer.coffee b/src/Renderer.coffee index 706aad8..a9f53bd 100644 --- a/src/Renderer.coffee +++ b/src/Renderer.coffee @@ -52,7 +52,7 @@ module.exports = class Renderer Promise .resolve @_visibleTiles center, zoom .map (tile) => @_getTile tile - .map (tile) => @_getTileFeatures tile + .map (tile) => @_getTileFeatures tile, zoom .then (tiles) => @_renderTiles tiles .then => @_getFrame() @@ -70,8 +70,7 @@ module.exports = class Renderer center = utils.ll2tile center.lon, center.lat, z tiles = [] - scale = @_scaleAtZoom zoom - tileSize = config.tileSize / scale + tileSize = utils.tilesizeAtZoom zoom for y in [Math.floor(center.y)-1..Math.floor(center.y)+1] for x in [Math.floor(center.x)-1..Math.floor(center.x)+1] @@ -95,7 +94,7 @@ module.exports = class Renderer position.y>@height continue - tiles.push xyz: tile, zoom: zoom, position: position, scale: scale + tiles.push xyz: tile, zoom: zoom, position: position, size: tileSize tiles @@ -106,37 +105,36 @@ module.exports = class Renderer tile.data = data tile - _getTileFeatures: (tile) -> - zoom = tile.xyz.z + _getTileFeatures: (tile, zoom) -> position = tile.position - scale = tile.scale + layers = {} - box = - minX: -position.x*scale - minY: -position.y*scale - maxX: (@width-position.x)*scale - maxY: (@height-position.y)*scale + for layerId in @_generateDrawOrder zoom + continue unless layer = tile.data.layers?[layerId] - features = {} + scale = layer.extent / utils.tilesizeAtZoom zoom + layers[layerId] = + scale: scale + features: layer.tree.search + minX: -position.x*scale + minY: -position.y*scale + maxX: (@width-position.x)*scale + maxY: (@height-position.y)*scale - for layer in @_generateDrawOrder zoom - continue unless tile.data.layers?[layer] - features[layer] = tile.data.layers[layer].search box - - tile.features = features + tile.layers = layers tile _renderTiles: (tiles) -> drawn = {} - for layer in @_generateDrawOrder tiles[0].xyz.z + for layerId in @_generateDrawOrder tiles[0].xyz.z for tile in tiles - continue unless tile.features[layer]?.length - for feature in tile.features[layer] + continue unless layer = tile.layers[layerId] + for feature in layer.features # continue if feature.id and drawn[feature.id] # drawn[feature.id] = true - @_drawFeature tile, feature + @_drawFeature tile, feature, layer.scale _getFrame: -> frame = "" @@ -148,11 +146,7 @@ module.exports = class Renderer featuresAt: (x, y) -> @labelBuffer.featuresAt x, y - _scaleAtZoom: (zoom) -> - baseZoom = Math.min config.tileRange, Math.floor Math.max 0, zoom - config.tileSize / config.projectSize / Math.pow(2, zoom-baseZoom) - - _drawFeature: (tile, feature) -> + _drawFeature: (tile, feature, scale) -> if feature.style.minzoom and tile.zoom < feature.style.minzoom return false else if feature.style.maxzoom and tile.zoom > feature.style.maxzoom @@ -163,11 +157,11 @@ module.exports = class Renderer width = feature.style.paint['line-width'] width = width.stops[0][1] if width instanceof Object - points = @_scaleAndReduce tile, feature, feature.points + points = @_scaleAndReduce tile, feature, feature.points, scale @canvas.polyline points, feature.color, width if points.length when "fill" - points = (@_scaleAndReduce tile, feature, p, false for p in feature.points) + points = (@_scaleAndReduce tile, feature, p, scale, false for p in feature.points) @canvas.polygon points, feature.color # if points.length is 3 # @canvas._filledTriangle points[0], points[1], points[2], feature.color @@ -183,7 +177,7 @@ module.exports = class Renderer return false if @_seen[text] and not genericSymbol placed = false - for point in @_scaleAndReduce tile, feature, feature.points + for point in @_scaleAndReduce tile, feature, feature.points, scale x = point.x - text.length margin = config.layers[feature.layer]?.margin or config.labelMargin @@ -202,7 +196,7 @@ module.exports = class Renderer true - _scaleAndReduce: (tile, feature, points, filter = true) -> + _scaleAndReduce: (tile, feature, points, scale, filter = true) -> lastX = lastY = outside = null scaled = [] @@ -211,8 +205,8 @@ module.exports = class Renderer maxY = @height+@tilePadding for point in points - x = Math.floor tile.position.x+(point.x/tile.scale) - y = Math.floor tile.position.y+(point.y/tile.scale) + x = Math.floor tile.position.x+(point.x/scale) + y = Math.floor tile.position.y+(point.y/scale) continue if lastX is x and lastY is y diff --git a/src/Tile.coffee b/src/Tile.coffee index 2b7b2d9..1702fb9 100644 --- a/src/Tile.coffee +++ b/src/Tile.coffee @@ -23,7 +23,7 @@ class Tile load: (buffer) -> @_unzipIfNeeded buffer .then (buffer) => @_loadTile buffer - .then (tile) => @_loadLayers tile + .then => @_loadLayers() .then => this _loadTile: (buffer) -> @@ -41,11 +41,11 @@ class Tile _isGzipped: (buffer) -> buffer.slice(0,2).indexOf(Buffer.from([0x1f, 0x8b])) is 0 - _loadLayers: (tile) -> + _loadLayers: () -> layers = {} colorCache = {} - for name, layer of tile.layers + for name, layer of @tile.layers nodes = [] #continue if name is "water" for i in [0...layer.length] @@ -97,7 +97,9 @@ class Tile tree = rbush 18 tree.load nodes - layers[name] = tree + layers[name] = + extent: layer.extent + tree: tree @layers = layers diff --git a/src/config.coffee b/src/config.coffee index 19ac610..d011f14 100644 --- a/src/config.coffee +++ b/src/config.coffee @@ -1,27 +1,26 @@ module.exports = - language: "en" + language: "en" - source: "http://nachbar.io/data/osm2vectortiles/" - #source: __dirname+"/../mbtiles/regensburg.mbtiles" - styleFile: __dirname+"/../styles/dark.json" + source: "http://nachbar.io/data/osm2vectortiles/" + #source: __dirname+"/../mbtiles/regensburg.mbtiles" + styleFile: __dirname+"/../styles/dark.json" - initialZoom: false - maxZoom: 18 - zoomStep: 0.2 + initialZoom: false + maxZoom: 18 + zoomStep: 0.2 - tileSize: 4096 - tileRange: 14 - projectSize: 256 + tileRange: 14 + projectSize: 256 - labelMargin: 5 + labelMargin: 5 - layers: - housenum_label: margin: 4 - poi_label: cluster: true, margin: 5 - place_label: cluster: true - state_label: cluster: true + layers: + housenum_label: margin: 4 + poi_label: cluster: true, margin: 5 + place_label: cluster: true + state_label: cluster: true - input: process.stdin - output: process.stdout + input: process.stdin + output: process.stdout - headless: false + headless: false diff --git a/src/utils.coffee b/src/utils.coffee index 3f5b84c..88d1a5a 100644 --- a/src/utils.coffee +++ b/src/utils.coffee @@ -4,6 +4,8 @@ methods used all around ### +config = require './config' + constants = RADIUS: 6378137 @@ -11,6 +13,10 @@ utils = clamp: (num, min, max) -> if num <= min then min else if num >= max then max else num + tilesizeAtZoom: (zoom) -> + baseZoom = Math.min config.tileRange, Math.floor Math.max 0, zoom + config.projectSize * Math.pow(2, zoom-baseZoom) + deg2rad: (angle) -> # (angle / 180) * Math.PI angle * 0.017453292519943295