🏃 using rbush's bulk load (2-3 times faster), working on polygon speed

This commit is contained in:
Michael Straßburger 2016-11-07 16:23:22 +01:00
parent 7ed86ceed4
commit 461a4ab049
4 changed files with 58 additions and 43 deletions

View File

@ -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

View File

@ -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

View File

@ -24,7 +24,7 @@ module.exports = class Termap
initialZoom: null
maxZoom: 17
zoomStep: 0.2
zoomStep: 0.1
headless: false
# size:

View File

@ -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()