Dart Documentationdartkart.layerCanvasRenderer

CanvasRenderer class

A renderer which renders map tiles on a Canvas element.

class CanvasRenderer extends Renderer {

 CanvasElement _canvas;
 CanvasRenderingContext2D get _context {
   if (_canvas == null) return null;
   return _canvas.context2D;
 }
 
 List<Tile> _tiles = [];

 CanvasRenderer(TileLayer layer): super(layer);

 _clear() {
   if (_context == null) return;
   _context
     ..save()
     ..setTransform(1, 0, 0, 1, 0, 0)
     ..clearRect(0, 0, _canvas.width, _canvas.height)
     ..restore();
   _tiles.forEach((t) => t.detach());
   _tiles.clear();
 }

 @override 
 void beforeRender() {
   if (_layer.map == null) {
     _canvas = null;
   } else {
     if (_canvas == null) {
       _canvas = new Element.tag("canvas");
       _layer.container.children.add(_canvas);
       _canvas.style
         ..width="100%"
         ..height="100%"
         ..top="0px"
         ..left="0px"
         ..position="relative"
         ..zIndex = "inherit";
     }
     _updateSize();
     _clear();
   }
 }

 _updateSize() {
   var vs = _layer.map.viewportSize;
   // make sure the _canvas size is equal to the map
   // size
   if (vs.width != _canvas.width || vs.height != _canvas.height) {
     _canvas
       ..width=vs.width
       ..height=vs.height;
   }
 }

 @override
 void renderTile(Point2D tileCoord) {
   Tile t = new Tile(tileCoord, _canvas, _layer);
   _tiles.add(t);
   t.load();
 }

 /* ------------- rendering the tile border - for debugging  --- */
 bool renderTileBorders = false;
}

Extends

Renderer > CanvasRenderer

Constructors

new CanvasRenderer(TileLayer layer) #

CanvasRenderer(TileLayer layer): super(layer);

Properties

bool renderTileBorders #

bool renderTileBorders = false

Methods

void afterRender() #

inherited from Renderer

Invoked after the tile grid is rendered using renderTileGrid. Default implementation is empty. Override in subclasses if necessary.

void afterRender(){}

void beforeRender() #

Invoked before the tile grid is rendered using renderTileGrid. Default implementation is empty. Override in subclasses if necessary.

docs inherited from Renderer
@override 
void beforeRender() {
 if (_layer.map == null) {
   _canvas = null;
 } else {
   if (_canvas == null) {
     _canvas = new Element.tag("canvas");
     _layer.container.children.add(_canvas);
     _canvas.style
       ..width="100%"
       ..height="100%"
       ..top="0px"
       ..left="0px"
       ..position="relative"
       ..zIndex = "inherit";
   }
   _updateSize();
   _clear();
 }
}

void render() #

inherited from Renderer

Invoked by a TileLayer to render itself

void render() {
 beforeRender();
 renderTileGrid();
 afterRender();
}

void renderTile(Point2D tileCoord) #

Renders the tile at position tileCoord in the current tile plane.

docs inherited from Renderer
@override
void renderTile(Point2D tileCoord) {
 Tile t = new Tile(tileCoord, _canvas, _layer);
 _tiles.add(t);
 t.load();
}

void renderTileGrid() #

inherited from Renderer

Renders the tile grid

void renderTileGrid() {
 var map = _layer._map;
 var tileSize = _layer.tileSize;
 var centerOnZoomPlane = map.mapToZoomPlane(map.earthToMap(map.center));
 var vshalf = (map.viewportSize / 2).toInt();
 var topLeftOnZoomPlane = new Point2D(
     centerOnZoomPlane.x - vshalf.width,
     centerOnZoomPlane.y - vshalf.height
 );
 var viewportOnZoomPlaneBounds = new Bounds(
     topLeftOnZoomPlane,
     topLeftOnZoomPlane + map.viewportSize
 );
 tileIntersectsWithViewport(Point2D t) {
   var tl = t.scale(sx:tileSize.width, sy:tileSize.height);
   var tileBounds = new Bounds(
       tl,
       tl + tileSize
   );
   return viewportOnZoomPlaneBounds.intersects(tileBounds);
 }

 // the tile covering the map center
 var tile = new Point2D(
     centerOnZoomPlane.x ~/ tileSize.width,
     centerOnZoomPlane.y ~/ tileSize.height
 );

 // find the first tile to be rendered
 while(true) {
   var candidate = tile.translate(dx:-1);
   if (candidate.x < 0) break;
   if (! tileIntersectsWithViewport(candidate)) break;
   tile = candidate;
 }
 while(true) {
   var candidate = tile.translate(dy:-1);
   if (candidate.y < 0) break;
   if (! tileIntersectsWithViewport(candidate)) break;
   tile = candidate;
 }

 // render the tile grid intersecting with the viewport
 var maxTileX = (1 << map.zoom);
 var maxTileY = (1 << map.zoom);
 var cur = new Point2D.from(tile);
 while(cur.x < maxTileX && tileIntersectsWithViewport(cur)) {
   while(cur.y < maxTileY && tileIntersectsWithViewport(cur)) {
     renderTile(cur);
     cur = cur.translate(dy:1);
   }
   cur = new Point2D(cur.x + 1, tile.y);
 }
}