diff --git a/old/src/ol/renderer/canvas/canvasvectorlayerrenderer.js b/old/src/ol/renderer/canvas/canvasvectorlayerrenderer.js
deleted file mode 100644
index 5203dd6025..0000000000
--- a/old/src/ol/renderer/canvas/canvasvectorlayerrenderer.js
+++ /dev/null
@@ -1,581 +0,0 @@
-goog.provide('ol.renderer.canvas.VectorLayer');
-
-goog.require('goog.asserts');
-goog.require('goog.dom');
-goog.require('goog.dom.TagName');
-goog.require('goog.events');
-goog.require('goog.object');
-goog.require('goog.vec.Mat4');
-goog.require('ol.Pixel');
-goog.require('ol.TileCache');
-goog.require('ol.TileCoord');
-goog.require('ol.TileRange');
-goog.require('ol.ViewHint');
-goog.require('ol.extent');
-goog.require('ol.geom.GeometryType');
-goog.require('ol.layer.Vector');
-goog.require('ol.layer.VectorEventType');
-goog.require('ol.layer.VectorLayerRenderIntent');
-goog.require('ol.renderer.canvas.Layer');
-goog.require('ol.renderer.canvas.Vector');
-goog.require('ol.tilegrid.TileGrid');
-
-
-/**
- * Resolution at zoom level 21 in a web mercator default tiling scheme. This
- * is a workaround for browser bugs that cause line segments to disappear when
- * they get too long. TODO: Use line clipping as a better work around. See
- * https://github.com/openlayers/ol3/issues/404.
- *
- * @define {number} The lowest supported resolution value.
- */
-ol.renderer.canvas.MIN_RESOLUTION = 0.14929107086948487;
-
-
-
-/**
- * @constructor
- * @extends {ol.renderer.canvas.Layer}
- * @param {ol.renderer.Map} mapRenderer Map renderer.
- * @param {ol.layer.Vector} layer Vector layer.
- */
-ol.renderer.canvas.VectorLayer = function(mapRenderer, layer) {
-
- goog.base(this, mapRenderer, layer);
-
- /**
- * Final canvas made available to the map renderer.
- * @private
- * @type {HTMLCanvasElement}
- */
- this.canvas_ = /** @type {HTMLCanvasElement} */
- (goog.dom.createElement(goog.dom.TagName.CANVAS));
-
- /**
- * @private
- * @type {CanvasRenderingContext2D}
- */
- this.context_ = /** @type {CanvasRenderingContext2D} */
- (this.canvas_.getContext('2d'));
-
- /**
- * @private
- * @type {!goog.vec.Mat4.Number}
- */
- this.transform_ = goog.vec.Mat4.createNumber();
-
- /**
- * Interim canvas for drawing newly visible features.
- * @private
- * @type {HTMLCanvasElement}
- */
- this.sketchCanvas_ = /** @type {HTMLCanvasElement} */
- (goog.dom.createElement(goog.dom.TagName.CANVAS));
-
- /**
- * @private
- * @type {!goog.vec.Mat4.Number}
- */
- this.sketchTransform_ = goog.vec.Mat4.createNumber();
-
- /**
- * Tile cache entries are arrays. The first item in each array is the tile
- * itself, the second are the symbol sizes, and the third is the maximum
- * symbol size.
- *
- * @private
- * @type {ol.TileCache}
- */
- this.tileCache_ = new ol.TileCache(
- ol.renderer.canvas.VectorLayer.TILECACHE_SIZE);
- goog.events.listen(layer, [
- ol.layer.VectorEventType.ADD,
- ol.layer.VectorEventType.CHANGE,
- ol.layer.VectorEventType.REMOVE,
- ol.layer.VectorEventType.INTENTCHANGE
- ],
- this.handleLayerChange_, false, this);
-
- /**
- * @private
- * @type {HTMLCanvasElement}
- */
- this.tileArchetype_ = null;
-
- /**
- * The maximum symbol size ever rendered for this layer (in pixels).
- * @private
- * @type {number}
- */
- this.maxSymbolPixelDim_ = 0;
-
- /**
- * @private
- * @type {number}
- */
- this.renderedResolution_;
-
- /**
- * @private
- * @type {ol.Extent}
- */
- this.renderedExtent_ = null;
-
- /**
- * Flag to be set internally when we know something has changed that suggests
- * we need to re-render.
- * TODO: discuss setting this for all layers when something changes before
- * calling map.render().
- * @private
- * @type {boolean}
- */
- this.dirty_ = false;
-
- /**
- * @private
- * @type {boolean}
- */
- this.pendingCachePrune_ = false;
-
- /**
- * Grid used for internal generation of canvas tiles. This is created
- * lazily so we have access to the view projection.
- *
- * @private
- * @type {ol.tilegrid.TileGrid}
- */
- this.tileGrid_ = null;
-
- /**
- * Tile range before the current animation or interaction. This is updated
- * whenever the view is idle.
- *
- * @private
- * @type {ol.TileRange}
- */
- this.tileRange_ = new ol.TileRange(NaN, NaN, NaN, NaN);
-
- /**
- * @private
- * @type {function()}
- */
- this.requestMapRenderFrame_ = goog.bind(function() {
- this.dirty_ = true;
- mapRenderer.getMap().requestRenderFrame();
- }, this);
-
-};
-goog.inherits(ol.renderer.canvas.VectorLayer, ol.renderer.canvas.Layer);
-
-
-/**
- * Get rid cached tiles. If the optional extent is provided, only tiles that
- * intersect that extent will be removed.
- * @param {Array.
} extents extent Expire tiles within the provided
- * extents. If the array is empty, all tiles will be expired.
- * @private
- */
-ol.renderer.canvas.VectorLayer.prototype.expireTiles_ = function(extents) {
- // buffer by max symbolizer size at rendered resolution
- var resolution = this.renderedResolution_;
- goog.asserts.assertNumber(resolution);
- var tileCache = this.tileCache_;
- var length = extents.length;
- var extent;
- if (length > 0) {
- for (var i = 0; i < length; ++i) {
- extent = ol.extent.clone(extents[i]);
- ol.extent.buffer(extent, this.maxSymbolPixelDim_ * resolution / 2);
- tileCache.pruneTileRange(
- this.tileGrid_.getTileRangeForExtentAndZ(extent, 0));
- }
- } else {
- tileCache.clear();
- }
-};
-
-
-/**
- * @inheritDoc
- */
-ol.renderer.canvas.VectorLayer.prototype.getImage = function() {
- return this.canvas_;
-};
-
-
-/**
- * @return {ol.layer.Vector} Vector layer.
- */
-ol.renderer.canvas.VectorLayer.prototype.getVectorLayer = function() {
- return /** @type {ol.layer.Vector} */ (this.getLayer());
-};
-
-
-/**
- * @inheritDoc
- */
-ol.renderer.canvas.VectorLayer.prototype.getTransform = function() {
- return this.transform_;
-};
-
-
-/**
- * @param {ol.Pixel} pixel Pixel coordinate relative to the map viewport.
- * @param {function(string, ol.layer.Layer)} success Callback for
- * successful queries. The passed arguments are the resulting feature
- * information and the layer.
- */
-ol.renderer.canvas.VectorLayer.prototype.getFeatureInfoForPixel =
- function(pixel, success) {
- var callback = function(features, layer) {
- success(layer.getTransformFeatureInfo()(features), layer);
- };
- this.getFeaturesForPixel(pixel, callback);
-};
-
-
-/**
- * @param {ol.Pixel} pixel Pixel coordinate relative to the map viewport.
- * @param {function(Array., ol.layer.Layer)} success Callback for
- * successful queries. The passed arguments are the resulting features
- * and the layer.
- * @param {function()=} opt_error Callback for unsuccessful queries.
- */
-ol.renderer.canvas.VectorLayer.prototype.getFeaturesForPixel =
- function(pixel, success, opt_error) {
- // TODO What do we want to pass to the error callback?
- var map = this.getMap();
- var result = [];
-
- var layer = this.getLayer();
- var location = map.getCoordinateFromPixel(pixel);
- var tileCoord = this.tileGrid_.getTileCoordForCoordAndZ(location, 0);
- var key = tileCoord.toString();
- if (this.tileCache_.containsKey(key)) {
- var cachedTile = this.tileCache_.get(key);
- var symbolSizes = cachedTile[1];
- var maxSymbolSize = cachedTile[2];
- var symbolOffsets = cachedTile[3];
- var halfMaxWidth = maxSymbolSize[0] / 2;
- var halfMaxHeight = maxSymbolSize[1] / 2;
- var locationMin = [location[0] - halfMaxWidth, location[1] - halfMaxHeight];
- var locationMax = [location[0] + halfMaxWidth, location[1] + halfMaxHeight];
- var locationBbox = ol.extent.boundingExtent([locationMin, locationMax]);
- var candidates = layer.getFeaturesObjectForExtent(locationBbox,
- map.getView().getView2D().getProjection());
- if (goog.isNull(candidates)) {
- // data is not loaded
- if (goog.isDef(opt_error)) {
- goog.global.setTimeout(function() { opt_error(); }, 0);
- }
- return;
- }
-
- var candidate, geom, type, symbolBounds, symbolSize, symbolOffset,
- halfWidth, halfHeight, uid, coordinates, j;
- for (var id in candidates) {
- candidate = candidates[id];
- if (candidate.getRenderIntent() ==
- ol.layer.VectorLayerRenderIntent.HIDDEN) {
- continue;
- }
- geom = candidate.getGeometry();
- type = geom.getType();
- if (type === ol.geom.GeometryType.POINT ||
- type === ol.geom.GeometryType.MULTIPOINT) {
- // For points, check if the pixel coordinate is inside the candidate's
- // symbol
- uid = goog.getUid(candidate);
- symbolSize = symbolSizes[uid];
- symbolOffset = symbolOffsets[uid];
- halfWidth = symbolSize[0] / 2;
- halfHeight = symbolSize[1] / 2;
- symbolBounds = ol.extent.boundingExtent([
- [location[0] - halfWidth - symbolOffset[0],
- location[1] - halfHeight + symbolOffset[1]],
- [location[0] + halfWidth - symbolOffset[0],
- location[1] + halfHeight + symbolOffset[1]]
- ]);
- coordinates = geom.getCoordinates();
- if (!goog.isArray(coordinates[0])) {
- coordinates = [coordinates];
- }
- for (j = coordinates.length - 1; j >= 0; --j) {
- if (ol.extent.containsCoordinate(symbolBounds, coordinates[j])) {
- result.push(candidate);
- break;
- }
- }
- } else if (goog.isFunction(geom.containsCoordinate)) {
- // For polygons, check if the pixel location is inside the polygon
- if (geom.containsCoordinate(location)) {
- result.push(candidate);
- }
- } else if (goog.isFunction(geom.distanceFromCoordinate)) {
- // For lines, check if the distance to the pixel location is
- // within the rendered line width
- if (2 * geom.distanceFromCoordinate(location) <=
- symbolSizes[goog.getUid(candidate)][0]) {
- result.push(candidate);
- }
- }
- }
- }
- goog.global.setTimeout(function() { success(result, layer); }, 0);
-};
-
-
-/**
- * @param {ol.layer.VectorEvent} event Vector layer event.
- * @private
- */
-ol.renderer.canvas.VectorLayer.prototype.handleLayerChange_ = function(event) {
- if (goog.isDef(this.renderedResolution_)) {
- this.expireTiles_(event.extents);
- }
- this.requestMapRenderFrame_();
-};
-
-
-/**
- * @inheritDoc
- */
-ol.renderer.canvas.VectorLayer.prototype.prepareFrame =
- function(frameState, layerState) {
-
- // TODO: consider bailing out here if rendered center and resolution
- // have not changed. Requires that other change listeners set a dirty flag.
-
- var view2DState = frameState.view2DState,
- resolution = view2DState.resolution,
- projection = view2DState.projection,
- extent = frameState.extent,
- layer = this.getVectorLayer(),
- tileGrid = this.tileGrid_,
- tileSize = [512, 512],
- idle = !frameState.viewHints[ol.ViewHint.ANIMATING] &&
- !frameState.viewHints[ol.ViewHint.INTERACTING];
-
- // lazy tile grid creation
- if (idle) {
- // avoid rendering issues for very high zoom levels
- var minResolution = ol.renderer.canvas.MIN_RESOLUTION;
- var metersPerUnit = projection.getMetersPerUnit();
- if (metersPerUnit) {
- minResolution = minResolution / metersPerUnit;
- }
- var gridResolution = Math.max(resolution, minResolution);
- if (gridResolution !== this.renderedResolution_) {
- tileGrid = new ol.tilegrid.TileGrid({
- origin: [0, 0],
- projection: projection,
- resolutions: [gridResolution],
- tileSize: tileSize
- });
- this.tileCache_.clear();
- this.tileGrid_ = tileGrid;
- }
- }
-
- if (goog.isNull(tileGrid)) {
- // We should only get here when the first call to prepareFrame happens
- // during an animation. Try again in the next prepareFrame call.
- return;
- }
-
-
- // set up transform for the layer canvas to be drawn to the map canvas
- var tileResolution = tileGrid.getResolution(0);
- if (idle) {
- tileGrid.getTileRangeForExtentAndResolution(
- extent, tileResolution, this.tileRange_);
- }
- var transform = this.transform_,
- tileRange = this.tileRange_,
- tileRangeExtent = tileGrid.getTileRangeExtent(0, tileRange),
- sketchOrigin = ol.extent.getTopLeft(tileRangeExtent);
-
- goog.vec.Mat4.makeIdentity(transform);
- goog.vec.Mat4.translate(transform,
- frameState.size[0] / 2,
- frameState.size[1] / 2,
- 0);
- goog.vec.Mat4.scale(transform,
- tileResolution / resolution, tileResolution / resolution, 1);
- goog.vec.Mat4.rotateZ(transform, view2DState.rotation);
- goog.vec.Mat4.translate(transform,
- (sketchOrigin[0] - view2DState.center[0]) / tileResolution,
- (view2DState.center[1] - sketchOrigin[1]) / tileResolution,
- 0);
-
- /**
- * Fastest path out of here. This method is called many many times while
- * there is nothing to do (e.g. while waiting for tiles from every other
- * layer to load.) Do not put anything above here that is more expensive than
- * necessary. And look for ways to get here faster.
- */
- if (!this.dirty_ && this.renderedResolution_ === tileResolution &&
- ol.extent.equals(this.renderedExtent_, tileRangeExtent)) {
- return;
- }
-
- if (goog.isNull(this.tileArchetype_)) {
- this.tileArchetype_ = /** @type {HTMLCanvasElement} */
- (goog.dom.createElement(goog.dom.TagName.CANVAS));
- this.tileArchetype_.width = tileSize[0];
- this.tileArchetype_.height = tileSize[1];
- }
-
- /**
- * Prepare the sketch canvas. This covers the currently visible tile range
- * and will have rendered all newly visible features.
- */
- var sketchCanvas = this.sketchCanvas_;
- var sketchWidth = tileSize[0] * tileRange.getWidth();
- var sketchHeight = tileSize[1] * tileRange.getHeight();
-
- // transform for map coords to sketch canvas pixel coords
- var sketchTransform = this.sketchTransform_;
- var halfWidth = sketchWidth / 2;
- var halfHeight = sketchHeight / 2;
- goog.vec.Mat4.makeIdentity(sketchTransform);
- goog.vec.Mat4.translate(sketchTransform,
- halfWidth,
- halfHeight,
- 0);
- goog.vec.Mat4.scale(sketchTransform,
- 1 / tileResolution,
- -1 / tileResolution,
- 1);
- goog.vec.Mat4.translate(sketchTransform,
- -(sketchOrigin[0] + halfWidth * tileResolution),
- -(sketchOrigin[1] - halfHeight * tileResolution),
- 0);
-
- // clear/resize sketch canvas
- sketchCanvas.width = sketchWidth;
- sketchCanvas.height = sketchHeight;
-
- var sketchContext = /** @type {CanvasRenderingContext2D} */
- (sketchCanvas.getContext('2d'));
- var sketchCanvasRenderer = new ol.renderer.canvas.Vector(
- sketchContext, sketchTransform, this.requestMapRenderFrame_);
-
- // clear/resize final canvas
- var finalCanvas = this.canvas_;
- finalCanvas.width = sketchWidth;
- finalCanvas.height = sketchHeight;
- var finalContext = this.context_;
-
- var featuresToRender = {};
- var tilesToRender = {};
- var tilesOnSketchCanvas = {};
- // TODO make gutter configurable?
- var tileGutter = 15 * tileResolution;
- var tile, tileCoord, key, x, y, i, type;
- var deferred = false;
- var dirty = false;
- var tileExtent, groups, group, j, numGroups, featuresObject, tileHasFeatures;
- fetchTileData:
- for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
- for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
- tileCoord = new ol.TileCoord(0, x, y);
- key = tileCoord.toString();
- if (this.tileCache_.containsKey(key)) {
- tilesToRender[key] = tileCoord;
- } else if (idle) {
- tileExtent = tileGrid.getTileCoordExtent(tileCoord);
- tileExtent[0] -= tileGutter;
- tileExtent[2] += tileGutter;
- tileExtent[1] -= tileGutter;
- tileExtent[3] += tileGutter;
- tileHasFeatures = false;
- featuresObject = layer.getFeaturesObjectForExtent(tileExtent,
- projection, this.requestMapRenderFrame_);
- if (goog.isNull(featuresObject)) {
- deferred = true;
- break fetchTileData;
- }
- tileHasFeatures = tileHasFeatures ||
- !goog.object.isEmpty(featuresObject);
- goog.object.extend(featuresToRender, featuresObject);
- if (tileHasFeatures) {
- tilesOnSketchCanvas[key] = tileCoord;
- }
- } else {
- dirty = true;
- }
- }
- }
- this.dirty_ = dirty;
-
- groups = layer.groupFeaturesBySymbolizerLiteral(featuresToRender,
- tileResolution);
- numGroups = groups.length;
- for (j = 0; j < numGroups; ++j) {
- group = groups[j];
- deferred = sketchCanvasRenderer.renderFeatures(group[0], group[1],
- group[2]);
- if (deferred) {
- break;
- }
- }
-
- if (!deferred) {
- goog.object.extend(tilesToRender, tilesOnSketchCanvas);
- }
-
- var symbolSizes = sketchCanvasRenderer.getSymbolSizes(),
- maxSymbolSize = sketchCanvasRenderer.getMaxSymbolSize(),
- symbolOffsets = sketchCanvasRenderer.getSymbolOffsets();
-
- // keep track of maximum pixel size for symbols rendered on this layer
- this.maxSymbolPixelDim_ = Math.max(maxSymbolSize[0] / tileResolution,
- maxSymbolSize[1] / tileResolution);
-
- for (key in tilesToRender) {
- tileCoord = tilesToRender[key];
- if (this.tileCache_.containsKey(key)) {
- tile = /** @type {HTMLCanvasElement} */ (this.tileCache_.get(key)[0]);
- } else {
- tile = /** @type {HTMLCanvasElement} */
- (this.tileArchetype_.cloneNode(false));
- tile.getContext('2d').drawImage(sketchCanvas,
- (tileRange.minX - tileCoord.x) * tileSize[0],
- (tileCoord.y - tileRange.maxY) * tileSize[1]);
- // TODO: Create an ol.VectorTile subclass of ol.Tile
- this.tileCache_.set(key,
- [tile, symbolSizes, maxSymbolSize, symbolOffsets]);
- }
- finalContext.drawImage(tile,
- tileSize[0] * (tileCoord.x - tileRange.minX),
- tileSize[1] * (tileRange.maxY - tileCoord.y));
- }
-
- this.renderedResolution_ = tileResolution;
- this.renderedExtent_ = tileRangeExtent;
- if (!this.pendingCachePrune_) {
- this.pendingCachePrune_ = true;
- frameState.postRenderFunctions.push(goog.bind(this.pruneTileCache_, this));
- }
-
-};
-
-
-/**
- * Get rid of tiles that exceed the cache capacity.
- * TODO: add a method to the cache to handle this
- * @private
- */
-ol.renderer.canvas.VectorLayer.prototype.pruneTileCache_ = function() {
- while (this.tileCache_.canExpireCache()) {
- this.tileCache_.pop();
- }
- this.pendingCachePrune_ = false;
-};
-
-
-/**
- * @type {number}
- */
-ol.renderer.canvas.VectorLayer.TILECACHE_SIZE = 128;
diff --git a/old/src/ol/renderer/canvas/canvasvectorrenderer.js b/old/src/ol/renderer/canvas/canvasvectorrenderer.js
deleted file mode 100644
index b3573766a6..0000000000
--- a/old/src/ol/renderer/canvas/canvasvectorrenderer.js
+++ /dev/null
@@ -1,646 +0,0 @@
-goog.provide('ol.renderer.canvas.Vector');
-
-
-goog.require('goog.asserts');
-goog.require('goog.dom');
-goog.require('goog.dom.TagName');
-goog.require('goog.events');
-goog.require('goog.events.EventType');
-goog.require('goog.vec.Mat4');
-goog.require('ol.Feature');
-goog.require('ol.FeatureRenderIntent');
-goog.require('ol.geom.AbstractCollection');
-goog.require('ol.geom.Geometry');
-goog.require('ol.geom.GeometryType');
-goog.require('ol.geom.LineString');
-goog.require('ol.geom.MultiLineString');
-goog.require('ol.geom.MultiPoint');
-goog.require('ol.geom.MultiPolygon');
-goog.require('ol.geom.Point');
-goog.require('ol.geom.Polygon');
-goog.require('ol.style.IconLiteral');
-goog.require('ol.style.LineLiteral');
-goog.require('ol.style.Literal');
-goog.require('ol.style.PointLiteral');
-goog.require('ol.style.PolygonLiteral');
-goog.require('ol.style.ShapeLiteral');
-goog.require('ol.style.ShapeType');
-goog.require('ol.style.TextLiteral');
-
-
-
-/**
- * @constructor
- * @param {CanvasRenderingContext2D} context Context.
- * @param {goog.vec.Mat4.Number} transform Transform.
- * @param {function()=} opt_iconLoadedCallback Callback for deferred rendering
- * when images need to be loaded before rendering.
- */
-ol.renderer.canvas.Vector =
- function(context, transform, opt_iconLoadedCallback) {
-
- /**
- * @type {goog.vec.Mat4.Number}
- * @private
- */
- this.transform_ = transform;
-
- var vec = [1, 0, 0];
- goog.vec.Mat4.multVec3NoTranslate(transform, vec, vec);
-
- /**
- * @type {number}
- * @private
- */
- this.inverseScale_ = 1 / Math.sqrt(vec[0] * vec[0] + vec[1] * vec[1]);
-
- /**
- * @type {CanvasRenderingContext2D}
- * @private
- */
- this.context_ = context;
-
- /**
- * @type {function()|undefined}
- * @private
- */
- this.iconLoadedCallback_ = opt_iconLoadedCallback;
-
- /**
- * @type {Object.>}
- * @private
- */
- this.symbolSizes_ = {};
-
- /**
- * @type {Object.>}
- * @private
- */
- this.symbolOffsets_ = {};
-
- /**
- * @type {Array.}
- * @private
- */
- this.maxSymbolSize_ = [0, 0];
-
-};
-
-
-/**
- * @return {Object.>} Symbolizer sizes.
- */
-ol.renderer.canvas.Vector.prototype.getSymbolSizes = function() {
- return this.symbolSizes_;
-};
-
-
-/**
- * @return {Object.>} Symbolizer offsets.
- */
-ol.renderer.canvas.Vector.prototype.getSymbolOffsets = function() {
- return this.symbolOffsets_;
-};
-
-
-/**
- * @return {Array.} Maximum symbolizer size.
- */
-ol.renderer.canvas.Vector.prototype.getMaxSymbolSize = function() {
- return this.maxSymbolSize_;
-};
-
-
-/**
- * @param {Array.} features Array of features.
- * @param {ol.style.Literal} symbolizer Symbolizer.
- * @param {Array} data Additional data.
- * @return {boolean} true if deferred, false if rendered.
- */
-ol.renderer.canvas.Vector.prototype.renderFeatures =
- function(features, symbolizer, data) {
- var deferred = false;
- if (symbolizer instanceof ol.style.PointLiteral) {
- deferred = this.renderPointFeatures_(features, symbolizer);
- } else if (symbolizer instanceof ol.style.LineLiteral) {
- this.renderLineStringFeatures_(features, symbolizer);
- } else if (symbolizer instanceof ol.style.PolygonLiteral) {
- this.renderPolygonFeatures_(features, symbolizer);
- } else if (symbolizer instanceof ol.style.TextLiteral) {
- this.renderText_(features, symbolizer, data);
- }
- return deferred;
-};
-
-
-/**
- * @param {Array.} features Array of line features.
- * @param {ol.style.LineLiteral} symbolizer Line symbolizer.
- * @private
- */
-ol.renderer.canvas.Vector.prototype.renderLineStringFeatures_ =
- function(features, symbolizer) {
-
- var context = this.context_,
- i, ii, feature, id, currentSize, geometry, components, j, jj,
- coordinates, coordinate, k, kk, strokeSize;
-
- var vec = [NaN, NaN, 0];
- var pixel = [NaN, NaN];
- var lastPixel = [NaN, NaN];
-
- context.globalAlpha = symbolizer.opacity;
- context.strokeStyle = symbolizer.color;
- context.lineWidth = symbolizer.width;
- context.lineCap = 'round'; // TODO: accept this as a symbolizer property
- context.lineJoin = 'round'; // TODO: accept this as a symbolizer property
- strokeSize = context.lineWidth * this.inverseScale_;
- context.beginPath();
- for (i = 0, ii = features.length; i < ii; ++i) {
- feature = features[i];
- if (feature.getRenderIntent() == ol.FeatureRenderIntent.HIDDEN) {
- continue;
- }
- id = goog.getUid(feature);
- currentSize = goog.isDef(this.symbolSizes_[id]) ?
- this.symbolSizes_[id] : [0];
- currentSize[0] = Math.max(currentSize[0], strokeSize);
- this.symbolSizes_[id] = currentSize;
- this.maxSymbolSize_ = [Math.max(currentSize[0], this.maxSymbolSize_[0]),
- Math.max(currentSize[0], this.maxSymbolSize_[1])];
- geometry = feature.getGeometry();
- if (geometry instanceof ol.geom.LineString) {
- components = [geometry];
- } else {
- goog.asserts.assert(geometry instanceof ol.geom.MultiLineString,
- 'Expected MultiLineString');
- components = geometry.getComponents();
- }
- for (j = 0, jj = components.length; j < jj; ++j) {
- coordinates = components[j].getCoordinates();
- for (k = 0, kk = coordinates.length; k < kk; ++k) {
- coordinate = coordinates[k];
- vec[0] = coordinate[0];
- vec[1] = coordinate[1];
- goog.vec.Mat4.multVec3(this.transform_, vec, vec);
- if (k === 0) {
- lastPixel[0] = NaN;
- lastPixel[1] = NaN;
- context.moveTo(vec[0], vec[1]);
- } else {
- pixel[0] = Math.round(vec[0]);
- pixel[1] = Math.round(vec[1]);
- if (pixel[0] !== lastPixel[0] || pixel[1] !== lastPixel[1]) {
- context.lineTo(vec[0], vec[1]);
- lastPixel[0] = pixel[0];
- lastPixel[1] = pixel[1];
- }
- }
- }
- }
- }
-
- context.stroke();
-};
-
-
-/**
- * @param {Array.} features Array of point features.
- * @param {ol.style.PointLiteral} symbolizer Point symbolizer.
- * @return {boolean} true if deferred, false if rendered.
- * @private
- */
-ol.renderer.canvas.Vector.prototype.renderPointFeatures_ =
- function(features, symbolizer) {
-
- var context = this.context_,
- content, alpha, i, ii, feature, id, size, geometry, components, j, jj,
- point, vec;
-
- var xOffset = 0;
- var yOffset = 0;
- if (symbolizer instanceof ol.style.ShapeLiteral) {
- content = ol.renderer.canvas.Vector.renderShape(symbolizer);
- alpha = 1;
- } else if (symbolizer instanceof ol.style.IconLiteral) {
- content = ol.renderer.canvas.Vector.renderIcon(
- symbolizer, this.iconLoadedCallback_);
- alpha = symbolizer.opacity;
- xOffset = symbolizer.xOffset;
- yOffset = symbolizer.yOffset;
- } else {
- throw new Error('Unsupported symbolizer: ' + symbolizer);
- }
-
- if (goog.isNull(content)) {
- return true;
- }
-
- var midWidth = Math.floor(content.width / 2);
- var midHeight = Math.floor(content.height / 2);
- var contentWidth = content.width * this.inverseScale_;
- var contentHeight = content.height * this.inverseScale_;
- var contentXOffset = xOffset * this.inverseScale_;
- var contentYOffset = yOffset * this.inverseScale_;
- context.save();
- context.setTransform(1, 0, 0, 1, -midWidth, -midHeight);
- context.globalAlpha = alpha;
- for (i = 0, ii = features.length; i < ii; ++i) {
- feature = features[i];
- if (feature.getRenderIntent() == ol.FeatureRenderIntent.HIDDEN) {
- continue;
- }
- id = goog.getUid(feature);
- size = this.symbolSizes_[id];
- this.symbolSizes_[id] = goog.isDef(size) ?
- [Math.max(size[0], contentWidth), Math.max(size[1], contentHeight)] :
- [contentWidth, contentHeight];
- this.symbolOffsets_[id] =
- [xOffset * this.inverseScale_, yOffset * this.inverseScale_];
- this.maxSymbolSize_ =
- [Math.max(this.maxSymbolSize_[0],
- this.symbolSizes_[id][0] + 2 * Math.abs(contentXOffset)),
- Math.max(this.maxSymbolSize_[1],
- this.symbolSizes_[id][1] + 2 * Math.abs(contentYOffset))];
- geometry = feature.getGeometry();
- if (geometry instanceof ol.geom.Point) {
- components = [geometry];
- } else {
- goog.asserts.assert(geometry instanceof ol.geom.MultiPoint,
- 'Expected MultiPoint');
- components = geometry.getComponents();
- }
- for (j = 0, jj = components.length; j < jj; ++j) {
- point = components[j];
- goog.asserts.assertInstanceof(point, ol.geom.Point);
- vec = [point.get(0), point.get(1), 0];
- goog.vec.Mat4.multVec3(this.transform_, vec, vec);
- context.drawImage(content, Math.round(vec[0] + xOffset),
- Math.round(vec[1] + yOffset),
- content.width, content.height);
- }
- }
- context.restore();
-
- return false;
-};
-
-
-/**
- * @param {Array.} features Array of features.
- * @param {ol.style.TextLiteral} text Text symbolizer.
- * @param {Array} texts Label text for each feature.
- * @private
- */
-ol.renderer.canvas.Vector.prototype.renderText_ =
- function(features, text, texts) {
- var context = this.context_,
- feature, vecs, vec;
-
- if (context.fillStyle !== text.color) {
- context.fillStyle = text.color;
- }
-
- // font shorthand values must be given in the correct order
- // see http://www.w3.org/TR/CSS21/fonts.html#font-shorthand
- context.font = text.fontWeight + ' ' +
- text.fontSize + 'px ' +
- text.fontFamily;
-
- context.globalAlpha = text.opacity;
-
- // TODO: make alignments configurable
- context.textAlign = 'center';
- context.textBaseline = 'middle';
-
- var stroke = false;
- if (goog.isDef(text.strokeColor)) {
- stroke = true;
- goog.asserts.assertString(text.strokeColor);
- context.strokeStyle = text.strokeColor;
- goog.asserts.assertNumber(text.strokeWidth);
- context.lineWidth = text.strokeWidth;
- }
-
- for (var i = 0, ii = features.length; i < ii; ++i) {
- feature = features[i];
- if (feature.getRenderIntent() == ol.FeatureRenderIntent.HIDDEN) {
- continue;
- }
- vecs = ol.renderer.canvas.Vector.getLabelVectors(
- feature.getGeometry());
- for (var j = 0, jj = vecs.length; j < jj; ++j) {
- vec = vecs[j];
- goog.vec.Mat4.multVec3(this.transform_, vec, vec);
- if (stroke) {
- if (text.strokeOpacity !== text.opacity) {
- goog.asserts.assertNumber(text.strokeOpacity);
- context.globalAlpha = text.strokeOpacity;
- }
- context.strokeText(texts[i], vec[0], vec[1]);
- if (text.strokeOpacity !== text.opacity) {
- context.globalAlpha = text.opacity;
- }
- }
- context.fillText(texts[i], vec[0], vec[1]);
- }
- }
-
-};
-
-
-/**
- * @param {Array.} features Array of polygon features.
- * @param {ol.style.PolygonLiteral} symbolizer Polygon symbolizer.
- * @private
- */
-ol.renderer.canvas.Vector.prototype.renderPolygonFeatures_ =
- function(features, symbolizer) {
- var context = this.context_,
- strokeColor = symbolizer.strokeColor,
- strokeWidth = symbolizer.strokeWidth,
- strokeOpacity = symbolizer.strokeOpacity,
- fillColor = symbolizer.fillColor,
- fillOpacity = symbolizer.fillOpacity,
- globalAlpha,
- i, ii, geometry, components, j, jj, poly,
- rings, numRings, coordinates, coordinate, k, kk, feature;
-
- var vec = [NaN, NaN, 0];
- var pixel = [NaN, NaN];
- var lastPixel = [NaN, NaN];
-
- if (strokeColor) {
- context.strokeStyle = strokeColor;
- if (strokeWidth) {
- context.lineWidth = strokeWidth;
- }
- context.lineCap = 'round'; // TODO: accept this as a symbolizer property
- context.lineJoin = 'round'; // TODO: accept this as a symbolizer property
- }
- if (fillColor) {
- context.fillStyle = fillColor;
- }
-
- /**
- * Four scenarios covered here:
- * 1) stroke only, no holes - only need to have a single path
- * 2) fill only, no holes - only need to have a single path
- * 3) fill and stroke, no holes
- * 4) holes - render polygon to sketch canvas first
- */
- context.beginPath();
- for (i = 0, ii = features.length; i < ii; ++i) {
- feature = features[i];
- if (feature.getRenderIntent() == ol.FeatureRenderIntent.HIDDEN) {
- continue;
- }
- geometry = feature.getGeometry();
- if (geometry instanceof ol.geom.Polygon) {
- components = [geometry];
- } else {
- goog.asserts.assert(geometry instanceof ol.geom.MultiPolygon,
- 'Expected MultiPolygon');
- components = geometry.getComponents();
- }
- for (j = 0, jj = components.length; j < jj; ++j) {
- poly = components[j];
- goog.asserts.assertInstanceof(poly, ol.geom.Polygon);
- rings = poly.getRings();
- numRings = rings.length;
- if (numRings > 0) {
- // TODO: scenario 4
- coordinates = rings[0].getCoordinates();
- for (k = 0, kk = coordinates.length; k < kk; ++k) {
- coordinate = coordinates[k];
- vec[0] = coordinate[0];
- vec[1] = coordinate[1];
- goog.vec.Mat4.multVec3(this.transform_, vec, vec);
- if (k === 0) {
- lastPixel[0] = NaN;
- lastPixel[1] = NaN;
- context.moveTo(vec[0], vec[1]);
- } else {
- pixel[0] = Math.round(vec[0]);
- pixel[1] = Math.round(vec[1]);
- if (pixel[0] !== lastPixel[0] || pixel[1] !== lastPixel[1]) {
- context.lineTo(vec[0], vec[1]);
- lastPixel[0] = pixel[0];
- lastPixel[1] = pixel[1];
- }
- }
- }
- if (fillColor && strokeColor) {
- // scenario 3 - fill and stroke each time
- if (fillOpacity !== globalAlpha) {
- goog.asserts.assertNumber(fillOpacity);
- context.globalAlpha = fillOpacity;
- globalAlpha = fillOpacity;
- }
- context.fill();
- if (strokeOpacity !== globalAlpha) {
- goog.asserts.assertNumber(strokeOpacity);
- context.globalAlpha = strokeOpacity;
- globalAlpha = strokeOpacity;
- }
- context.stroke();
- if (i < ii - 1 || j < jj - 1) {
- context.beginPath();
- }
- }
- }
- }
- }
- if (!(fillColor && strokeColor)) {
- if (fillColor) {
- // scenario 2 - fill all at once
- if (fillOpacity !== globalAlpha) {
- goog.asserts.assertNumber(fillOpacity);
- context.globalAlpha = fillOpacity;
- globalAlpha = fillOpacity;
- }
- context.fill();
- } else {
- // scenario 1 - stroke all at once
- if (strokeOpacity !== globalAlpha) {
- goog.asserts.assertNumber(strokeOpacity);
- context.globalAlpha = strokeOpacity;
- globalAlpha = strokeOpacity;
- }
- context.stroke();
- }
- }
-};
-
-
-/**
- * @param {ol.style.ShapeLiteral} circle Shape symbolizer.
- * @return {!HTMLCanvasElement} Canvas element.
- * @private
- */
-ol.renderer.canvas.Vector.renderCircle_ = function(circle) {
- var strokeWidth = circle.strokeWidth || 0,
- size = circle.size + (2 * strokeWidth) + 1,
- mid = size / 2,
- canvas = /** @type {HTMLCanvasElement} */
- (goog.dom.createElement(goog.dom.TagName.CANVAS)),
- context = /** @type {CanvasRenderingContext2D} */
- (canvas.getContext('2d')),
- fillColor = circle.fillColor,
- strokeColor = circle.strokeColor,
- twoPi = Math.PI * 2;
-
- canvas.height = size;
- canvas.width = size;
-
- if (fillColor) {
- context.fillStyle = fillColor;
- }
- if (strokeColor) {
- context.lineWidth = strokeWidth;
- context.strokeStyle = strokeColor;
- context.lineCap = 'round'; // TODO: accept this as a symbolizer property
- context.lineJoin = 'round'; // TODO: accept this as a symbolizer property
- }
-
- context.beginPath();
- context.arc(mid, mid, circle.size / 2, 0, twoPi, true);
-
- if (fillColor) {
- goog.asserts.assertNumber(circle.fillOpacity);
- context.globalAlpha = circle.fillOpacity;
- context.fill();
- }
- if (strokeColor) {
- goog.asserts.assertNumber(circle.strokeOpacity);
- context.globalAlpha = circle.strokeOpacity;
- context.stroke();
- }
- return canvas;
-};
-
-
-/**
- * @param {ol.geom.Geometry} geometry Geometry.
- * @return {Array.} Renderable geometry vectors.
- */
-ol.renderer.canvas.Vector.getLabelVectors = function(geometry) {
- if (geometry instanceof ol.geom.AbstractCollection) {
- var components = geometry.getComponents();
- var numComponents = components.length;
- var result = [];
- for (var i = 0; i < numComponents; ++i) {
- result.push.apply(result,
- ol.renderer.canvas.Vector.getLabelVectors(components[i]));
- }
- return result;
- }
- var type = geometry.getType();
- if (type == ol.geom.GeometryType.POINT) {
- goog.asserts.assertInstanceof(geometry, ol.geom.Point);
- return [[geometry.get(0), geometry.get(1), 0]];
- }
- if (type == ol.geom.GeometryType.POLYGON) {
- goog.asserts.assertInstanceof(geometry, ol.geom.Polygon);
- var coordinates = geometry.getInteriorPoint();
- return [[coordinates[0], coordinates[1], 0]];
- }
- throw new Error('Label rendering not implemented for geometry type: ' +
- type);
-};
-
-
-/**
- * @param {ol.style.ShapeLiteral} shape Shape symbolizer.
- * @return {!HTMLCanvasElement} Canvas element.
- */
-ol.renderer.canvas.Vector.renderShape = function(shape) {
- var canvas;
- if (shape.type === ol.style.ShapeType.CIRCLE) {
- canvas = ol.renderer.canvas.Vector.renderCircle_(shape);
- } else {
- throw new Error('Unsupported shape type: ' + shape);
- }
- return canvas;
-};
-
-
-/**
- * @param {ol.style.IconLiteral} icon Icon literal.
- * @param {function()=} opt_callback Callback which will be called when
- * the icon is loaded and rendering will work without deferring.
- * @return {HTMLImageElement} image element of null if deferred.
- */
-ol.renderer.canvas.Vector.renderIcon = function(icon, opt_callback) {
- var url = icon.url;
- var image = ol.renderer.canvas.Vector.icons_[url];
- var deferred = false;
- if (!goog.isDef(image)) {
- deferred = true;
- image = /** @type {HTMLImageElement} */
- (goog.dom.createElement(goog.dom.TagName.IMG));
- goog.events.listenOnce(image, goog.events.EventType.ERROR,
- goog.bind(ol.renderer.canvas.Vector.handleIconError_, null,
- opt_callback),
- false, ol.renderer.canvas.Vector.renderIcon);
- goog.events.listenOnce(image, goog.events.EventType.LOAD,
- goog.bind(ol.renderer.canvas.Vector.handleIconLoad_, null,
- opt_callback),
- false, ol.renderer.canvas.Vector.renderIcon);
- image.setAttribute('src', url);
- } else if (!goog.isNull(image)) {
- var width = icon.width,
- height = icon.height;
- if (goog.isDef(width) && goog.isDef(height)) {
- image.width = width;
- image.height = height;
- } else if (goog.isDef(width)) {
- image.height = width / image.width * image.height;
- image.width = width;
- } else if (goog.isDef(height)) {
- image.width = height / image.height * image.width;
- image.height = height;
- }
- }
- return deferred ? null : image;
-};
-
-
-/**
- * @type {Object.}
- * @private
- */
-ol.renderer.canvas.Vector.icons_ = {};
-
-
-/**
- * @param {function()=} opt_callback Callback.
- * @param {Event=} opt_event Event.
- * @private
- */
-ol.renderer.canvas.Vector.handleIconError_ =
- function(opt_callback, opt_event) {
- if (goog.isDef(opt_event)) {
- var url = opt_event.target.getAttribute('src');
- ol.renderer.canvas.Vector.icons_[url] = null;
- ol.renderer.canvas.Vector.handleIconLoad_(opt_callback, opt_event);
- }
-};
-
-
-/**
- * @param {function()=} opt_callback Callback.
- * @param {Event=} opt_event Event.
- * @private
- */
-ol.renderer.canvas.Vector.handleIconLoad_ =
- function(opt_callback, opt_event) {
- if (goog.isDef(opt_event)) {
- var url = opt_event.target.getAttribute('src');
- ol.renderer.canvas.Vector.icons_[url] =
- /** @type {HTMLImageElement} */ (opt_event.target);
- }
- if (goog.isDef(opt_callback)) {
- opt_callback();
- }
-};