From 461a4ab0492f85be7178f2ca0174e17833426c08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Stra=C3=9Fburger?= Date: Mon, 7 Nov 2016 16:23:22 +0100 Subject: [PATCH] :runner: using rbush's bulk load (2-3 times faster), working on polygon speed --- src/Canvas.coffee | 9 ++++++- src/Renderer.coffee | 60 +++++++++++++++++++++++---------------------- src/Termap.coffee | 2 +- src/Tile.coffee | 30 ++++++++++++++--------- 4 files changed, 58 insertions(+), 43 deletions(-) diff --git a/src/Canvas.coffee b/src/Canvas.coffee index ef6b6eb..e520a92 100644 --- a/src/Canvas.coffee +++ b/src/Canvas.coffee @@ -74,7 +74,14 @@ module.exports = class Canvas [vertices[pointId*2], vertices[pointId*2+1]] for i in [0...triangles.length] by 3 - @_filledTriangle extract(triangles[i]), extract(triangles[i+1]), extract(triangles[i+2]), color + pa = extract(triangles[i]) + pb = extract(triangles[i+1]) + pc = extract(triangles[i+2]) + + if (0 <= pa[0] < @width and 0 <= pa[1] < @height) or + (0 <= pb[0] < @width and 0 <= pb[1] < @height) or + (0 <= pc[0] < @width and 0 <= pc[1] < @height) + @_filledTriangle pa, pb, pc, color # Inspired by Alois Zingl's "The Beauty of Bresenham's Algorithm" # -> http://members.chello.at/~easyfilter/bresenham.html diff --git a/src/Renderer.coffee b/src/Renderer.coffee index e70536b..1968417 100644 --- a/src/Renderer.coffee +++ b/src/Renderer.coffee @@ -210,20 +210,19 @@ module.exports = class Renderer if feature.style.minzoom and tile.zoom < feature.style.minzoom return false - points = @_scaleAndReduce tile, feature - - unless points.length - return false - switch feature.style.type when "line" + points = @_scaleAndReduce tile, feature, feature.points + width = feature.style.paint['line-width'] width = width.stops[0][1] if width instanceof Object - @canvas.polyline points, feature.color, width + @canvas.polyline points, feature.color, width if points.length when "fill" - @canvas.polygon points, feature.color + vertices = (@_scaleAndReduce tile, feature, points, false for points in feature.points) + @canvas.polygon vertices[0], feature.color + true when "symbol" text = feature.properties["name_"+@config.language] or @@ -233,6 +232,7 @@ module.exports = class Renderer #@config.icons[feature.properties.maki] or "◉" + points = @_scaleAndReduce tile, feature, feature.points for point in points x = point[0] - text.length margin = @config.layers[feature.layer]?.margin or @config.labelMargin @@ -243,13 +243,13 @@ module.exports = class Renderer @canvas.text "◉", point[0], point[1], feature.color _seen: {} - _scaleAndReduce: (tile, feature) -> + _scaleAndReduce: (tile, feature, points, filter = true) -> lastX = null lastY = null outside = false scaled = [] - for point in feature.points + for point in points x = Math.floor tile.position.x+(point.x/tile.scale) y = Math.floor tile.position.y+(point.y/tile.scale) @@ -259,29 +259,31 @@ module.exports = class Renderer lastY = y lastX = x - if tile.xyz.z > 1 and ( - x < -@tilePadding or - y < -@tilePadding or - x > @width+@tilePadding or - y > @height+@tilePadding - ) - continue if outside - outside = true - else - if outside - outside = null - scaled.push [lastX, lastY] + if filter + if tile.xyz.z > 1 and ( + x < -@tilePadding or + y < -@tilePadding or + x > @width+@tilePadding or + y > @height+@tilePadding + ) + continue if outside + outside = true + else + if outside + outside = null + scaled.push [lastX, lastY] scaled.push [x, y] - if scaled.length is 2 - if @_seen[ka = scaled[0].concat(scaled[1]).join '-'] or - @_seen[kb = scaled[1].concat(scaled[0]).join '-'] + if filter + if scaled.length is 2 + if @_seen[ka = scaled[0].concat(scaled[1]).join '-'] or + @_seen[kb = scaled[1].concat(scaled[0]).join '-'] + return [] + + @_seen[ka] = @_seen[kb] = true + + if scaled.length < 2 and feature.style.type isnt "symbol" return [] - @_seen[ka] = @_seen[kb] = true - - if scaled.length < 2 and feature.style.type isnt "symbol" - return [] - scaled diff --git a/src/Termap.coffee b/src/Termap.coffee index 649510e..466dd7c 100644 --- a/src/Termap.coffee +++ b/src/Termap.coffee @@ -24,7 +24,7 @@ module.exports = class Termap initialZoom: null maxZoom: 17 - zoomStep: 0.2 + zoomStep: 0.1 headless: false # size: diff --git a/src/Tile.coffee b/src/Tile.coffee index 399c804..becdb49 100644 --- a/src/Tile.coffee +++ b/src/Tile.coffee @@ -45,7 +45,7 @@ class Tile colorCache = {} for name, layer of tile.layers - tree = rbush() + nodes = [] for i in [0...layer.length] # TODO: caching of similar attributes to avoid looking up the style each time #continue if @styler and not @styler.getStyleFor layer, feature @@ -74,17 +74,17 @@ class Tile # TODO: handling polygon holes, only handling outer area for now if style.type is "fill" - @_addToTree tree, + nodes.push @_addBoundaries id: feature.id layer: name style: style properties: feature.properties - points: geometries[0] + points: geometries color: colorCode else for points in geometries - @_addToTree tree, + nodes.push @_addBoundaries id: feature.id layer: name style: style @@ -92,25 +92,31 @@ class Tile points: points color: colorCode + tree = rbush() + tree.load nodes layers[name] = tree @layers = layers - _addToTree: (tree, data) -> + _addBoundaries: (data) -> [minX, maxX, minY, maxY] = [Infinity, -Infinity, Infinity, -Infinity] + minMax = (points) -> + for p in points + minX = p.x if p.x < minX + maxX = p.x if p.x > maxX + minY = p.y if p.y < minY + maxY = p.y if p.y > maxY - for p in data.points - minX = p.x if p.x < minX - maxX = p.x if p.x > maxX - minY = p.y if p.y < minY - maxY = p.y if p.y > maxY + if data.points[0] instanceof Array + minMax points for points in data.points + else + minMax data.points data.minX = minX data.maxX = maxX data.minY = minY data.maxY = maxY - - tree.insert data + data _reduceGeometry: (feature, factor) -> for points, i in feature.loadGeometry()