🎨 pulling and using individual tile extents in preperation for reduced tiles

This commit is contained in:
Michael Straßburger 2016-11-10 08:00:36 +01:00
parent 6a1eb8afe8
commit f9c16f2d6d
4 changed files with 57 additions and 56 deletions

View File

@ -52,7 +52,7 @@ module.exports = class Renderer
Promise Promise
.resolve @_visibleTiles center, zoom .resolve @_visibleTiles center, zoom
.map (tile) => @_getTile tile .map (tile) => @_getTile tile
.map (tile) => @_getTileFeatures tile .map (tile) => @_getTileFeatures tile, zoom
.then (tiles) => @_renderTiles tiles .then (tiles) => @_renderTiles tiles
.then => @_getFrame() .then => @_getFrame()
@ -70,8 +70,7 @@ module.exports = class Renderer
center = utils.ll2tile center.lon, center.lat, z center = utils.ll2tile center.lon, center.lat, z
tiles = [] tiles = []
scale = @_scaleAtZoom zoom tileSize = utils.tilesizeAtZoom zoom
tileSize = config.tileSize / scale
for y in [Math.floor(center.y)-1..Math.floor(center.y)+1] for y in [Math.floor(center.y)-1..Math.floor(center.y)+1]
for x in [Math.floor(center.x)-1..Math.floor(center.x)+1] for x in [Math.floor(center.x)-1..Math.floor(center.x)+1]
@ -95,7 +94,7 @@ module.exports = class Renderer
position.y>@height position.y>@height
continue continue
tiles.push xyz: tile, zoom: zoom, position: position, scale: scale tiles.push xyz: tile, zoom: zoom, position: position, size: tileSize
tiles tiles
@ -106,37 +105,36 @@ module.exports = class Renderer
tile.data = data tile.data = data
tile tile
_getTileFeatures: (tile) -> _getTileFeatures: (tile, zoom) ->
zoom = tile.xyz.z
position = tile.position position = tile.position
scale = tile.scale layers = {}
box = for layerId in @_generateDrawOrder zoom
minX: -position.x*scale continue unless layer = tile.data.layers?[layerId]
minY: -position.y*scale
maxX: (@width-position.x)*scale
maxY: (@height-position.y)*scale
features = {} scale = layer.extent / utils.tilesizeAtZoom zoom
layers[layerId] =
scale: scale
features: layer.tree.search
minX: -position.x*scale
minY: -position.y*scale
maxX: (@width-position.x)*scale
maxY: (@height-position.y)*scale
for layer in @_generateDrawOrder zoom tile.layers = layers
continue unless tile.data.layers?[layer]
features[layer] = tile.data.layers[layer].search box
tile.features = features
tile tile
_renderTiles: (tiles) -> _renderTiles: (tiles) ->
drawn = {} drawn = {}
for layer in @_generateDrawOrder tiles[0].xyz.z for layerId in @_generateDrawOrder tiles[0].xyz.z
for tile in tiles for tile in tiles
continue unless tile.features[layer]?.length continue unless layer = tile.layers[layerId]
for feature in tile.features[layer] for feature in layer.features
# continue if feature.id and drawn[feature.id] # continue if feature.id and drawn[feature.id]
# drawn[feature.id] = true # drawn[feature.id] = true
@_drawFeature tile, feature @_drawFeature tile, feature, layer.scale
_getFrame: -> _getFrame: ->
frame = "" frame = ""
@ -148,11 +146,7 @@ module.exports = class Renderer
featuresAt: (x, y) -> featuresAt: (x, y) ->
@labelBuffer.featuresAt x, y @labelBuffer.featuresAt x, y
_scaleAtZoom: (zoom) -> _drawFeature: (tile, feature, scale) ->
baseZoom = Math.min config.tileRange, Math.floor Math.max 0, zoom
config.tileSize / config.projectSize / Math.pow(2, zoom-baseZoom)
_drawFeature: (tile, feature) ->
if feature.style.minzoom and tile.zoom < feature.style.minzoom if feature.style.minzoom and tile.zoom < feature.style.minzoom
return false return false
else if feature.style.maxzoom and tile.zoom > feature.style.maxzoom else if feature.style.maxzoom and tile.zoom > feature.style.maxzoom
@ -163,11 +157,11 @@ module.exports = class Renderer
width = feature.style.paint['line-width'] width = feature.style.paint['line-width']
width = width.stops[0][1] if width instanceof Object width = width.stops[0][1] if width instanceof Object
points = @_scaleAndReduce tile, feature, feature.points points = @_scaleAndReduce tile, feature, feature.points, scale
@canvas.polyline points, feature.color, width if points.length @canvas.polyline points, feature.color, width if points.length
when "fill" when "fill"
points = (@_scaleAndReduce tile, feature, p, false for p in feature.points) points = (@_scaleAndReduce tile, feature, p, scale, false for p in feature.points)
@canvas.polygon points, feature.color @canvas.polygon points, feature.color
# if points.length is 3 # if points.length is 3
# @canvas._filledTriangle points[0], points[1], points[2], feature.color # @canvas._filledTriangle points[0], points[1], points[2], feature.color
@ -183,7 +177,7 @@ module.exports = class Renderer
return false if @_seen[text] and not genericSymbol return false if @_seen[text] and not genericSymbol
placed = false placed = false
for point in @_scaleAndReduce tile, feature, feature.points for point in @_scaleAndReduce tile, feature, feature.points, scale
x = point.x - text.length x = point.x - text.length
margin = config.layers[feature.layer]?.margin or config.labelMargin margin = config.layers[feature.layer]?.margin or config.labelMargin
@ -202,7 +196,7 @@ module.exports = class Renderer
true true
_scaleAndReduce: (tile, feature, points, filter = true) -> _scaleAndReduce: (tile, feature, points, scale, filter = true) ->
lastX = lastY = outside = null lastX = lastY = outside = null
scaled = [] scaled = []
@ -211,8 +205,8 @@ module.exports = class Renderer
maxY = @height+@tilePadding maxY = @height+@tilePadding
for point in points for point in points
x = Math.floor tile.position.x+(point.x/tile.scale) x = Math.floor tile.position.x+(point.x/scale)
y = Math.floor tile.position.y+(point.y/tile.scale) y = Math.floor tile.position.y+(point.y/scale)
continue if lastX is x and lastY is y continue if lastX is x and lastY is y

View File

@ -23,7 +23,7 @@ class Tile
load: (buffer) -> load: (buffer) ->
@_unzipIfNeeded buffer @_unzipIfNeeded buffer
.then (buffer) => @_loadTile buffer .then (buffer) => @_loadTile buffer
.then (tile) => @_loadLayers tile .then => @_loadLayers()
.then => this .then => this
_loadTile: (buffer) -> _loadTile: (buffer) ->
@ -41,11 +41,11 @@ class Tile
_isGzipped: (buffer) -> _isGzipped: (buffer) ->
buffer.slice(0,2).indexOf(Buffer.from([0x1f, 0x8b])) is 0 buffer.slice(0,2).indexOf(Buffer.from([0x1f, 0x8b])) is 0
_loadLayers: (tile) -> _loadLayers: () ->
layers = {} layers = {}
colorCache = {} colorCache = {}
for name, layer of tile.layers for name, layer of @tile.layers
nodes = [] nodes = []
#continue if name is "water" #continue if name is "water"
for i in [0...layer.length] for i in [0...layer.length]
@ -97,7 +97,9 @@ class Tile
tree = rbush 18 tree = rbush 18
tree.load nodes tree.load nodes
layers[name] = tree layers[name] =
extent: layer.extent
tree: tree
@layers = layers @layers = layers

View File

@ -1,27 +1,26 @@
module.exports = module.exports =
language: "en" language: "en"
source: "http://nachbar.io/data/osm2vectortiles/" source: "http://nachbar.io/data/osm2vectortiles/"
#source: __dirname+"/../mbtiles/regensburg.mbtiles" #source: __dirname+"/../mbtiles/regensburg.mbtiles"
styleFile: __dirname+"/../styles/dark.json" styleFile: __dirname+"/../styles/dark.json"
initialZoom: false initialZoom: false
maxZoom: 18 maxZoom: 18
zoomStep: 0.2 zoomStep: 0.2
tileSize: 4096 tileRange: 14
tileRange: 14 projectSize: 256
projectSize: 256
labelMargin: 5 labelMargin: 5
layers: layers:
housenum_label: margin: 4 housenum_label: margin: 4
poi_label: cluster: true, margin: 5 poi_label: cluster: true, margin: 5
place_label: cluster: true place_label: cluster: true
state_label: cluster: true state_label: cluster: true
input: process.stdin input: process.stdin
output: process.stdout output: process.stdout
headless: false headless: false

View File

@ -4,6 +4,8 @@
methods used all around methods used all around
### ###
config = require './config'
constants = constants =
RADIUS: 6378137 RADIUS: 6378137
@ -11,6 +13,10 @@ utils =
clamp: (num, min, max) -> clamp: (num, min, max) ->
if num <= min then min else if num >= max then max else num if num <= min then min else if num >= max then max else num
tilesizeAtZoom: (zoom) ->
baseZoom = Math.min config.tileRange, Math.floor Math.max 0, zoom
config.projectSize * Math.pow(2, zoom-baseZoom)
deg2rad: (angle) -> deg2rad: (angle) ->
# (angle / 180) * Math.PI # (angle / 180) * Math.PI
angle * 0.017453292519943295 angle * 0.017453292519943295