🏃 removing matrix translations, combinding reduce/move/scale in one loop

This commit is contained in:
Michael Straßburger 2016-11-06 17:14:38 +01:00
parent 2e7f9abfeb
commit 329f6fc26b
5 changed files with 53 additions and 67 deletions

View File

@ -54,7 +54,6 @@ If your terminal supports mouse events you can drag the map and use your scroll
#### Juggling the vectors and numbers
* [`earcut`](https://github.com/mapbox/earcut) for polygon triangulation
* [`rbush`](https://github.com/mourner/rbush) for 2D spatial indexing based label and mouse collision detection
* [`gl-matrix`](https://github.com/toji/gl-matrix) for vector and matrix operations
* [`breseham`](https://github.com/madbence/node-bresenham) for line calculations
* [`sphericalmercator`](https://github.com/mapbox/node-sphericalmercator) for [EPSG:3857](http://spatialreference.org/ref/sr-org/6864/) <> [WGS84](http://spatialreference.org/ref/epsg/wgs-84/) conversions
* [`tilebelt`](https://github.com/mapbox/tilebelt) for some [slippy map tilename](https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames) calculations

View File

@ -30,7 +30,6 @@
"bresenham": "0.0.4",
"coffee-script": "^1.10.0",
"earcut": "^2.1.1",
"gl-matrix": "^2.3.2",
"keypress": "^0.2.1",
"pbf": "^3.0.0",
"rbush": "^2.0.1",

View File

@ -12,65 +12,38 @@
###
bresenham = require 'bresenham'
glMatrix = require 'gl-matrix'
earcut = require 'earcut'
BrailleBuffer = require './BrailleBuffer'
utils = require './utils'
vec2 = glMatrix.vec2
mat2d = glMatrix.mat2d
module.exports = class Canvas
matrix: null
stack: []
constructor: (@width, @height) ->
@buffer = new BrailleBuffer @width, @height
@reset()
reset: ->
@matrix = mat2d.create()
frame: ->
@buffer.frame()
translate: (x, y) ->
mat2d.translate @matrix, @matrix, vec2.fromValues(x, y)
rotate: (angle) ->
mat2d.rotate @matrix, @matrix, angle/180*Math.PI
save: ->
@stack.push mat2d.clone mat2d.create(), @matrix
restore: ->
return unless last = @stack.pop()
@matrix = last
clear: ->
@buffer.clear()
text: (text, x, y, color, center = false) ->
position = @_project x, y
@buffer.writeText text, position[0], position[1], color, center
@buffer.writeText text, x, y, color, center
line: (from, to, color, width = 1) ->
from = @_project from[0], from[1]
to = @_project to[0], to[1]
@_line from, to, color, width
polyline: (points, color, width = 1) ->
projected = (@_project point[0], point[1] for point in points)
for i in [1...projected.length]
@_line projected[i-1], projected[i], width, color
for i in [1...points.length]
@_line points[i-1], points[i], width, color
setBackground: (color) ->
@buffer.setGlobalBackground color
background: (x, y, color) ->
point = @_project x, y
@buffer.setBackground point[0], point[1], color
@buffer.setBackground x, y, color
polygon: (polylines, color) ->
vertices = []
@ -86,15 +59,8 @@ module.exports = class Canvas
lastPoint = [-1, -1]
for point in points
point = @_project point[0], point[1]
point[0] = utils.clamp point[0], 0, @width
point[1] = utils.clamp point[1], 0, @height
if point[0] isnt lastPoint[0] or point[1] isnt lastPoint[1]
vertices = vertices.concat point[0], point[1]
xs[point[0]] = ys[point[1]] = true
lastPoint = point
# Check if we actually got a valid polygon after projection and clamping
if Object.keys(xs).length is 1 or Object.keys(ys).length is 1
@ -162,15 +128,11 @@ module.exports = class Canvas
err += dx
y0 += sy
_project: (x, y) ->
point = vec2.transformMat2d vec2.create(), vec2.fromValues(x, y), @matrix
[Math.floor(point[0]), Math.floor(point[1])]
_filledRectangle: (x, y, width, height, color) ->
pointA = @_project x, y
pointB = @_project x+width, y
pointC = @_project x, y+height
pointD = @_project x+width, y+height
pointA = [x, y]
pointB = [x+width, y]
pointC = [x, y+height]
pointD = [x+width, y+height]
@_filledTriangle pointA, pointB, pointC, color
@_filledTriangle pointC, pointB, pointD, color

View File

@ -23,7 +23,7 @@ module.exports = class Renderer
labelMargin: 5
tileSize: 512
tileSize: 4096 #512
projectSize: 256
maxZoom: 14
@ -186,17 +186,12 @@ module.exports = class Renderer
for tile in tiles
continue unless tile.features[layer]?.length
@canvas.save()
@canvas.translate tile.position.x, tile.position.y
for feature in tile.features[layer]
continue if feature.id and drawn[feature.id]
drawn[feature.id] = true
@_drawFeature tile, feature
@canvas.restore()
_getFrame: ->
frame = ""
frame += @terminal.CLEAR unless @lastDrawAt
@ -214,7 +209,8 @@ module.exports = class Renderer
_drawFeature: (tile, feature) ->
return false if feature.style.minzoom and tile.zoom < feature.style.minzoom
toDraw = (@_scaleAndReduce points, tile.scale for points in feature.points)
toDraw = @_scaleAndReduce tile, feature
return false unless toDraw.length
color =
feature.style.paint['line-color'] or
@ -254,18 +250,48 @@ module.exports = class Renderer
else if @config.layers[feature.layer]?.cluster and @labelBuffer.writeIfPossible "X", point[0], point[1], feature, 3
@canvas.text "", point[0], point[1], colorCode
_scaleAndReduce: (points, scale) ->
_scaleAndReduce: (tile, feature) ->
reduced = []
seen = {}
for points in feature.points
lastX = null
lastY = null
firstOutside = null
scaled = []
for point in points
x = Math.floor point.x/scale
y = Math.floor point.y/scale
x = Math.floor tile.position.x+point.x/tile.scale
y = Math.floor tile.position.y+point.y/tile.scale
if lastX is x and lastY is y
continue
if lastX isnt x or lastY isnt y
lastY = y
lastX = x
if x < 0 or y < 0 or x > @width or y > @width
continue if outside
outside = true
else
if outside
outside = null
scaled.push [lastX, lastY]
scaled.push [x, y]
scaled
if scaled.length is 2
ka = scaled[0].concat(scaled[1]).join '-'
kb = scaled[1].concat(scaled[0]).join '-'
if seen[ka] or seen[kb]
continue
seen[ka] = seen[kb] = true
unless scaled.length > 1 or feature.type is "symbol"
continue
reduced.push scaled
reduced

View File

@ -53,7 +53,7 @@ class Tile
continue unless style
# TODO: monkey patching test case for tiles with a reduced extent
points = @_reduceGeometry feature, 8
points = feature.loadGeometry() #@_reduceGeometry feature, 8
data =
style: style