mirror of
https://github.com/rastapasta/mapscii.git
synced 2024-11-25 01:23:58 +01:00
🏃 removing matrix translations, combinding reduce/move/scale in one loop
This commit is contained in:
parent
2e7f9abfeb
commit
329f6fc26b
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user