🏃 applying styles on tile load, filtering unstyled features, caching style

This commit is contained in:
Michael Straßburger 2016-11-06 15:34:36 +01:00
parent 59b64e8dd2
commit 8aa29a9e28
5 changed files with 51 additions and 42 deletions

View File

@ -87,6 +87,7 @@ module.exports = class Renderer
loadStyleFile: (file) ->
@styler = new Styler file
@tileSource.useStyler @styler
setSize: (@width, @height) ->
@canvas = new Canvas @width, @height
@ -173,7 +174,7 @@ module.exports = class Renderer
features = {}
for layer in @config.drawOrder
continue unless tile.data.layers?[layer]
features[layer] = tile.data.layers[layer].tree.search box
features[layer] = tile.data.layers[layer].search box
tile.features = features
tile
@ -182,8 +183,6 @@ module.exports = class Renderer
drawn = {}
for layer in @config.drawOrder
short = layer.split(":")[0]
for tile in tiles
continue unless tile.features[layer]?.length
@ -191,10 +190,10 @@ module.exports = class Renderer
@canvas.translate tile.position.x, tile.position.y
for feature in tile.features[layer]
continue if feature.data.id and drawn[feature.data.id]
drawn[feature.data.id] = true
continue if feature.id and drawn[feature.id]
drawn[feature.id] = true
@_drawFeature short, feature, tile.scale, tile.zoom
@_drawFeature layer, feature, tile.scale, tile.zoom
@canvas.restore()
@ -210,17 +209,12 @@ module.exports = class Renderer
_scaleAtZoom: (zoom) ->
baseZoom = Math.min @config.maxZoom, Math.floor Math.max 0, zoom
(@config.tileSize/@config.projectSize)/Math.pow(2, zoom-baseZoom)
@config.tileSize / @config.projectSize / Math.pow(2, zoom-baseZoom)
_drawFeature: (layer, data, scale, zoom) ->
feature = data.data
_drawFeature: (layer, feature, scale, zoom) ->
style = feature.style
# TODO: this is ugly :) need to be fixed @style
#return false if feature.properties.class is "ferry"
feature.type = "LineString" if layer is "building" or layer is "road"
unless style = @styler.getStyleFor layer, feature, zoom
return false
return false if style.minzoom and zoom < style.minzoom
toDraw = (@_scaleAndReduce points, scale for points in feature.points)

View File

@ -32,11 +32,10 @@ module.exports = class Styler
@styleById[style.id] = style
getStyleFor: (layer, feature, zoom) ->
# Skip all layers that don't have any styles set
return false unless @styleByLayer[layer]
for style in @styleByLayer[layer]
if style.appliesTo(feature) and ((not style.minzoom) or style.minzoom <= zoom)
if style.appliesTo feature
return style
return false

View File

@ -172,6 +172,7 @@ module.exports = class Termap
# display debug info for unhandled keys
@notify JSON.stringify key
drawn: 0
_draw: ->
@renderer
.draw @center, @zoom
@ -180,6 +181,8 @@ module.exports = class Termap
@notify @_getFooter()
.catch =>
@notify "renderer is busy"
# .then =>
# @_draw() if @drawn++ < 20
_getFooter: ->
# features = @renderer.featuresAt @mousePosition.x-1-(@view[0]>>1), @mousePosition.y-1-(@view[1]>>2)

View File

@ -14,9 +14,11 @@ rbush = require 'rbush'
class Tile
layers: {}
constructor: (@styler) ->
load: (buffer) ->
@_unzipIfNeeded buffer
.then (data) => @_loadTile data
.then (buffer) => @_loadTile buffer
.then (tile) => @_loadLayers tile
.then => this
@ -45,26 +47,19 @@ class Tile
feature = layer.feature i
type = feature.properties.$type =
feature.properties.$type = type =
[undefined, "Point", "LineString", "Polygon"][feature.type]
# TODO: monkey patching test case for tiles with a reduced extent
geo = for sub, i in feature.loadGeometry()
points = []
last = null
for point, j in sub
p =
x: Math.floor point.x/8
y: Math.floor point.y/8
if @styler
style = @styler.getStyleFor name, feature
continue unless style
if last and last.x is p.x and last.y is p.y
continue
points.push p
last = p
points
# TODO: monkey patching test case for tiles with a reduced extent
points = @_reduceGeometry feature, 8
data =
points: geo
style: style
points: points
properties: feature.properties
id: feature.id
type: type
@ -72,7 +67,7 @@ class Tile
@_addToTree tree, data
data
layers[name] = tree: tree, features: features
layers[name] = tree
@layers = layers
@ -85,11 +80,27 @@ class Tile
minY = p.y if p.y < minY
maxY = p.y if p.y > maxY
tree.insert
minX: minX
maxX: maxX
minY: minY
maxY: maxY
data: data
data.minX = minX
data.maxX = maxX
data.minY = minY
data.maxY = maxY
tree.insert data
_reduceGeometry: (feature, factor) ->
for points, i in feature.loadGeometry()
reduced = []
last = null
for point, j in points
p =
x: Math.floor point.x/factor
y: Math.floor point.y/factor
if last and last.x is p.x and last.y is p.y
continue
reduced.push last = p
reduced
module.exports = Tile

View File

@ -34,8 +34,8 @@ module.exports = class TileSource
HTTP: 3
mode: null
mbtiles: null
styler: null
init: (@source) ->
if @source.startsWith "http"
@ -59,6 +59,8 @@ module.exports = class TileSource
if err then reject err
else resolve()
useStyler: (@styler) ->
getTile: (z, x, y) ->
unless @mode
throw new Error "no TileSource defined"
@ -95,7 +97,7 @@ module.exports = class TileSource
resolve @_createTile z, x, y, buffer
_createTile: (z, x, y, buffer) ->
tile = @cache[[z,x,y].join("-")] = new Tile()
tile = @cache[[z,x,y].join("-")] = new Tile @styler
tile.load buffer
_initPersistence: ->