150
src/ol/dom.js
150
src/ol/dom.js
@@ -1,15 +1,6 @@
|
||||
goog.provide('ol.dom');
|
||||
|
||||
goog.require('ol');
|
||||
goog.require('ol.has');
|
||||
goog.require('ol.vec.Mat4');
|
||||
|
||||
|
||||
/**
|
||||
* @type {Array.<number>}
|
||||
* @private
|
||||
*/
|
||||
ol.dom.tmpMat4_ = ol.vec.Mat4.create();
|
||||
|
||||
|
||||
/**
|
||||
@@ -30,147 +21,6 @@ ol.dom.createCanvasContext2D = function(opt_width, opt_height) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Detect 2d transform.
|
||||
* Adapted from http://stackoverflow.com/q/5661671/130442
|
||||
* http://caniuse.com/#feat=transforms2d
|
||||
* @return {boolean}
|
||||
*/
|
||||
ol.dom.canUseCssTransform = (function() {
|
||||
var global = ol.global;
|
||||
var canUseCssTransform;
|
||||
return function() {
|
||||
if (canUseCssTransform === undefined) {
|
||||
var el = document.createElement('P'),
|
||||
has2d,
|
||||
transforms = {
|
||||
'webkitTransform': '-webkit-transform',
|
||||
'OTransform': '-o-transform',
|
||||
'msTransform': '-ms-transform',
|
||||
'MozTransform': '-moz-transform',
|
||||
'transform': 'transform'
|
||||
};
|
||||
document.body.appendChild(el);
|
||||
for (var t in transforms) {
|
||||
if (t in el.style) {
|
||||
el.style[t] = 'translate(1px,1px)';
|
||||
has2d = global.getComputedStyle(el).getPropertyValue(
|
||||
transforms[t]);
|
||||
}
|
||||
}
|
||||
document.body.removeChild(el);
|
||||
|
||||
canUseCssTransform = (has2d && has2d !== 'none');
|
||||
}
|
||||
return canUseCssTransform;
|
||||
};
|
||||
}());
|
||||
|
||||
|
||||
/**
|
||||
* Detect 3d transform.
|
||||
* Adapted from http://stackoverflow.com/q/5661671/130442
|
||||
* http://caniuse.com/#feat=transforms3d
|
||||
* @return {boolean}
|
||||
*/
|
||||
ol.dom.canUseCssTransform3D = (function() {
|
||||
var global = ol.global;
|
||||
var canUseCssTransform3D;
|
||||
return function() {
|
||||
if (canUseCssTransform3D === undefined) {
|
||||
var el = document.createElement('P'),
|
||||
has3d,
|
||||
transforms = {
|
||||
'webkitTransform': '-webkit-transform',
|
||||
'OTransform': '-o-transform',
|
||||
'msTransform': '-ms-transform',
|
||||
'MozTransform': '-moz-transform',
|
||||
'transform': 'transform'
|
||||
};
|
||||
document.body.appendChild(el);
|
||||
for (var t in transforms) {
|
||||
if (t in el.style) {
|
||||
el.style[t] = 'translate3d(1px,1px,1px)';
|
||||
has3d = global.getComputedStyle(el).getPropertyValue(
|
||||
transforms[t]);
|
||||
}
|
||||
}
|
||||
document.body.removeChild(el);
|
||||
|
||||
canUseCssTransform3D = (has3d && has3d !== 'none');
|
||||
}
|
||||
return canUseCssTransform3D;
|
||||
};
|
||||
}());
|
||||
|
||||
|
||||
/**
|
||||
* @param {Element} element Element.
|
||||
* @param {string} value Value.
|
||||
*/
|
||||
ol.dom.setTransform = function(element, value) {
|
||||
var style = element.style;
|
||||
style.WebkitTransform = value;
|
||||
style.MozTransform = value;
|
||||
style.OTransform = value;
|
||||
style.msTransform = value;
|
||||
style.transform = value;
|
||||
|
||||
// IE 9+ seems to assume transform-origin: 100% 100%; for some unknown reason
|
||||
if (ol.has.IE) {
|
||||
element.style.transformOrigin = '0 0';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!Element} element Element.
|
||||
* @param {ol.Transform} transform Matrix.
|
||||
* @param {number=} opt_precision Precision.
|
||||
*/
|
||||
ol.dom.transformElement2D = function(element, transform, opt_precision) {
|
||||
// using matrix() causes gaps in Chrome and Firefox on Mac OS X, so prefer
|
||||
// matrix3d()
|
||||
var i;
|
||||
if (ol.dom.canUseCssTransform3D()) {
|
||||
var value3D;
|
||||
var transform3D = ol.vec.Mat4.fromTransform(ol.dom.tmpMat4_, transform);
|
||||
if (opt_precision !== undefined) {
|
||||
/** @type {Array.<string>} */
|
||||
var strings3D = new Array(16);
|
||||
for (i = 0; i < 16; ++i) {
|
||||
strings3D[i] = transform3D[i].toFixed(opt_precision);
|
||||
}
|
||||
value3D = strings3D.join(',');
|
||||
} else {
|
||||
value3D = transform3D.join(',');
|
||||
}
|
||||
ol.dom.setTransform(element, 'matrix3d(' + value3D + ')');
|
||||
} else if (ol.dom.canUseCssTransform()) {
|
||||
/** @type {string} */
|
||||
var value2D;
|
||||
if (opt_precision !== undefined) {
|
||||
/** @type {Array.<string>} */
|
||||
var strings2D = new Array(6);
|
||||
for (i = 0; i < 6; ++i) {
|
||||
strings2D[i] = transform[i].toFixed(opt_precision);
|
||||
}
|
||||
value2D = strings2D.join(',');
|
||||
} else {
|
||||
value2D = transform.join(',');
|
||||
}
|
||||
ol.dom.setTransform(element, 'matrix(' + value2D + ')');
|
||||
} else {
|
||||
element.style.left = Math.round(transform[4]) + 'px';
|
||||
element.style.top = Math.round(transform[5]) + 'px';
|
||||
|
||||
// TODO: Add scaling here. This isn't quite as simple as multiplying
|
||||
// width/height, because that only changes the container size, not the
|
||||
// content size.
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the current computed width for the given element including margin,
|
||||
* padding and border.
|
||||
|
||||
@@ -7,15 +7,6 @@ var olGlobal = ol.global;
|
||||
var ua = typeof navigator !== 'undefined' ?
|
||||
navigator.userAgent.toLowerCase() : '';
|
||||
|
||||
var ie = ua.match(/msie ([0-9]{1,}[\.0-9]{0,})/);
|
||||
var trident = ua.match(/trident\/([0-9]{1,}[\.0-9]{0,})/);
|
||||
|
||||
/**
|
||||
* User agent string says we are dealing with IE >= 9 as browser.
|
||||
* @type {boolean}
|
||||
*/
|
||||
ol.has.IE = !!(ie && parseFloat(ie[1]) >= 9 || trident && parseFloat(trident[1]) >= 6);
|
||||
|
||||
/**
|
||||
* User agent string says we are dealing with Firefox as browser.
|
||||
* @type {boolean}
|
||||
@@ -98,14 +89,6 @@ ol.has.CANVAS = ol.ENABLE_CANVAS && (
|
||||
ol.has.DEVICE_ORIENTATION = 'DeviceOrientationEvent' in olGlobal;
|
||||
|
||||
|
||||
/**
|
||||
* True if `ol.ENABLE_DOM` is set to `true` at compile time.
|
||||
* @const
|
||||
* @type {boolean}
|
||||
*/
|
||||
ol.has.DOM = ol.ENABLE_DOM;
|
||||
|
||||
|
||||
/**
|
||||
* Is HTML5 geolocation supported in the current browser?
|
||||
* @const
|
||||
|
||||
@@ -4,7 +4,6 @@ goog.require('ol');
|
||||
goog.require('ol.Tile');
|
||||
goog.require('ol.events');
|
||||
goog.require('ol.events.EventType');
|
||||
goog.require('ol.obj');
|
||||
|
||||
|
||||
/**
|
||||
@@ -80,22 +79,8 @@ ol.ImageTile.prototype.disposeInternal = function() {
|
||||
* @inheritDoc
|
||||
* @api
|
||||
*/
|
||||
ol.ImageTile.prototype.getImage = function(opt_context) {
|
||||
if (opt_context !== undefined) {
|
||||
var image;
|
||||
var key = ol.getUid(opt_context);
|
||||
if (key in this.imageByContext_) {
|
||||
return this.imageByContext_[key];
|
||||
} else if (ol.obj.isEmpty(this.imageByContext_)) {
|
||||
image = this.image_;
|
||||
} else {
|
||||
image = /** @type {Image} */ (this.image_.cloneNode(false));
|
||||
}
|
||||
this.imageByContext_[key] = image;
|
||||
return image;
|
||||
} else {
|
||||
return this.image_;
|
||||
}
|
||||
ol.ImageTile.prototype.getImage = function() {
|
||||
return this.image_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -67,15 +67,6 @@ ol.DRAG_BOX_HYSTERESIS_PIXELS = 8;
|
||||
ol.ENABLE_CANVAS = true;
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Enable the DOM renderer (used as a fallback where Canvas is
|
||||
* not available). Default is `true`. Setting this to false at compile time
|
||||
* in advanced mode removes all code supporting the DOM renderer from the
|
||||
* build.
|
||||
*/
|
||||
ol.ENABLE_DOM = true;
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Enable rendering of ol.layer.Image based layers. Default
|
||||
* is `true`. Setting this to false at compile time in advanced mode removes
|
||||
|
||||
@@ -33,7 +33,6 @@ goog.require('ol.obj');
|
||||
goog.require('ol.proj.common');
|
||||
goog.require('ol.renderer.Map');
|
||||
goog.require('ol.renderer.canvas.Map');
|
||||
goog.require('ol.renderer.dom.Map');
|
||||
goog.require('ol.renderer.webgl.Map');
|
||||
goog.require('ol.size');
|
||||
goog.require('ol.structs.PriorityQueue');
|
||||
@@ -81,8 +80,7 @@ ol.OL3_LOGO_URL = 'data:image/png;base64,' +
|
||||
*/
|
||||
ol.DEFAULT_RENDERER_TYPES = [
|
||||
ol.RendererType.CANVAS,
|
||||
ol.RendererType.WEBGL,
|
||||
ol.RendererType.DOM
|
||||
ol.RendererType.WEBGL
|
||||
];
|
||||
|
||||
|
||||
@@ -125,8 +123,7 @@ ol.MapProperty = {
|
||||
* `ol-overlaycontainer-stopevent` for controls and some overlays, and one with
|
||||
* CSS class name `ol-overlaycontainer` for other overlays (see the `stopEvent`
|
||||
* option of {@link ol.Overlay} for the difference). The map itself is placed in
|
||||
* a further element within the viewport, either DOM or Canvas, depending on the
|
||||
* renderer.
|
||||
* a further element within the viewport.
|
||||
*
|
||||
* Layers are stored as a `ol.Collection` in layerGroups. A top-level group is
|
||||
* provided by the library. This is what is accessed by `getLayerGroup` and
|
||||
@@ -1481,6 +1478,10 @@ ol.Map.createOptionsInternal = function(options) {
|
||||
} else {
|
||||
ol.asserts.assert(false, 46); // Incorrect format for `renderer` option
|
||||
}
|
||||
if (rendererTypes.indexOf(/** @type {ol.RendererType} */ ('dom')) >= 0) {
|
||||
goog.DEBUG && console.assert(false, 'The DOM render has been removed');
|
||||
rendererTypes = rendererTypes.concat(ol.DEFAULT_RENDERER_TYPES);
|
||||
}
|
||||
} else {
|
||||
rendererTypes = ol.DEFAULT_RENDERER_TYPES;
|
||||
}
|
||||
@@ -1494,11 +1495,6 @@ ol.Map.createOptionsInternal = function(options) {
|
||||
rendererConstructor = ol.renderer.canvas.Map;
|
||||
break;
|
||||
}
|
||||
} else if (ol.ENABLE_DOM && rendererType == ol.RendererType.DOM) {
|
||||
if (ol.has.DOM) {
|
||||
rendererConstructor = ol.renderer.dom.Map;
|
||||
break;
|
||||
}
|
||||
} else if (ol.ENABLE_WEBGL && rendererType == ol.RendererType.WEBGL) {
|
||||
if (ol.has.WEBGL) {
|
||||
rendererConstructor = ol.renderer.webgl.Map;
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
goog.provide('ol.renderer.dom.ImageLayer');
|
||||
|
||||
goog.require('ol');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.array');
|
||||
goog.require('ol.dom');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.renderer.dom.Layer');
|
||||
goog.require('ol.transform');
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.renderer.dom.Layer}
|
||||
* @param {ol.layer.Image} imageLayer Image layer.
|
||||
*/
|
||||
ol.renderer.dom.ImageLayer = function(imageLayer) {
|
||||
var target = document.createElement('DIV');
|
||||
target.style.position = 'absolute';
|
||||
|
||||
ol.renderer.dom.Layer.call(this, imageLayer, target);
|
||||
|
||||
/**
|
||||
* The last rendered image.
|
||||
* @private
|
||||
* @type {?ol.ImageBase}
|
||||
*/
|
||||
this.image_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Transform}
|
||||
*/
|
||||
this.transform_ = ol.transform.create();
|
||||
|
||||
};
|
||||
ol.inherits(ol.renderer.dom.ImageLayer, ol.renderer.dom.Layer);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.ImageLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, callback, thisArg) {
|
||||
var layer = this.getLayer();
|
||||
var source = layer.getSource();
|
||||
var resolution = frameState.viewState.resolution;
|
||||
var rotation = frameState.viewState.rotation;
|
||||
var skippedFeatureUids = frameState.skippedFeatureUids;
|
||||
return source.forEachFeatureAtCoordinate(
|
||||
coordinate, resolution, rotation, skippedFeatureUids,
|
||||
/**
|
||||
* @param {ol.Feature|ol.render.Feature} feature Feature.
|
||||
* @return {?} Callback result.
|
||||
*/
|
||||
function(feature) {
|
||||
return callback.call(thisArg, feature, layer);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.ImageLayer.prototype.clearFrame = function() {
|
||||
ol.dom.removeChildren(this.target);
|
||||
this.image_ = null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.ImageLayer.prototype.prepareFrame = function(frameState, layerState) {
|
||||
|
||||
var viewState = frameState.viewState;
|
||||
var viewCenter = viewState.center;
|
||||
var viewResolution = viewState.resolution;
|
||||
var viewRotation = viewState.rotation;
|
||||
|
||||
var image = this.image_;
|
||||
var imageLayer = /** @type {ol.layer.Image} */ (this.getLayer());
|
||||
var imageSource = imageLayer.getSource();
|
||||
|
||||
var hints = frameState.viewHints;
|
||||
|
||||
var renderedExtent = frameState.extent;
|
||||
if (layerState.extent !== undefined) {
|
||||
renderedExtent = ol.extent.getIntersection(
|
||||
renderedExtent, layerState.extent);
|
||||
}
|
||||
|
||||
if (!hints[ol.View.Hint.ANIMATING] && !hints[ol.View.Hint.INTERACTING] &&
|
||||
!ol.extent.isEmpty(renderedExtent)) {
|
||||
var projection = viewState.projection;
|
||||
if (!ol.ENABLE_RASTER_REPROJECTION) {
|
||||
var sourceProjection = imageSource.getProjection();
|
||||
if (sourceProjection) {
|
||||
ol.DEBUG && console.assert(ol.proj.equivalent(projection, sourceProjection),
|
||||
'projection and sourceProjection are equivalent');
|
||||
projection = sourceProjection;
|
||||
}
|
||||
}
|
||||
var image_ = imageSource.getImage(renderedExtent, viewResolution,
|
||||
frameState.pixelRatio, projection);
|
||||
if (image_) {
|
||||
var loaded = this.loadImage(image_);
|
||||
if (loaded) {
|
||||
image = image_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (image) {
|
||||
var imageExtent = image.getExtent();
|
||||
var imageResolution = image.getResolution();
|
||||
var transform = ol.transform.create();
|
||||
ol.transform.compose(transform,
|
||||
frameState.size[0] / 2, frameState.size[1] / 2,
|
||||
imageResolution / viewResolution, imageResolution / viewResolution,
|
||||
viewRotation,
|
||||
(imageExtent[0] - viewCenter[0]) / imageResolution,
|
||||
(viewCenter[1] - imageExtent[3]) / imageResolution);
|
||||
|
||||
if (image != this.image_) {
|
||||
var imageElement = image.getImage(this);
|
||||
// Bootstrap sets the style max-width: 100% for all images, which breaks
|
||||
// prevents the image from being displayed in FireFox. Workaround by
|
||||
// overriding the max-width style.
|
||||
imageElement.style.maxWidth = 'none';
|
||||
imageElement.style.position = 'absolute';
|
||||
ol.dom.removeChildren(this.target);
|
||||
this.target.appendChild(imageElement);
|
||||
this.image_ = image;
|
||||
}
|
||||
this.setTransform_(transform);
|
||||
this.updateAttributions(frameState.attributions, image.getAttributions());
|
||||
this.updateLogos(frameState, imageSource);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Transform} transform Transform.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.dom.ImageLayer.prototype.setTransform_ = function(transform) {
|
||||
if (!ol.array.equals(transform, this.transform_)) {
|
||||
ol.dom.transformElement2D(this.target, transform, 6);
|
||||
ol.transform.setFromArray(this.transform_, transform);
|
||||
}
|
||||
};
|
||||
@@ -1,54 +0,0 @@
|
||||
goog.provide('ol.renderer.dom.Layer');
|
||||
|
||||
goog.require('ol');
|
||||
goog.require('ol.renderer.Layer');
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.renderer.Layer}
|
||||
* @param {ol.layer.Layer} layer Layer.
|
||||
* @param {!Element} target Target.
|
||||
*/
|
||||
ol.renderer.dom.Layer = function(layer, target) {
|
||||
|
||||
ol.renderer.Layer.call(this, layer);
|
||||
|
||||
/**
|
||||
* @type {!Element}
|
||||
* @protected
|
||||
*/
|
||||
this.target = target;
|
||||
|
||||
};
|
||||
ol.inherits(ol.renderer.dom.Layer, ol.renderer.Layer);
|
||||
|
||||
|
||||
/**
|
||||
* Clear rendered elements.
|
||||
*/
|
||||
ol.renderer.dom.Layer.prototype.clearFrame = ol.nullFunction;
|
||||
|
||||
|
||||
/**
|
||||
* @param {olx.FrameState} frameState Frame state.
|
||||
* @param {ol.LayerState} layerState Layer state.
|
||||
*/
|
||||
ol.renderer.dom.Layer.prototype.composeFrame = ol.nullFunction;
|
||||
|
||||
|
||||
/**
|
||||
* @return {!Element} Target.
|
||||
*/
|
||||
ol.renderer.dom.Layer.prototype.getTarget = function() {
|
||||
return this.target;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @param {olx.FrameState} frameState Frame state.
|
||||
* @param {ol.LayerState} layerState Layer state.
|
||||
* @return {boolean} whether composeFrame should be called.
|
||||
*/
|
||||
ol.renderer.dom.Layer.prototype.prepareFrame = function(frameState, layerState) {};
|
||||
@@ -1,211 +0,0 @@
|
||||
goog.provide('ol.renderer.dom.Map');
|
||||
|
||||
goog.require('ol.events');
|
||||
goog.require('ol.events.Event');
|
||||
goog.require('ol.events.EventType');
|
||||
goog.require('ol.transform');
|
||||
goog.require('ol');
|
||||
goog.require('ol.RendererType');
|
||||
goog.require('ol.array');
|
||||
goog.require('ol.css');
|
||||
goog.require('ol.dom');
|
||||
goog.require('ol.layer.Image');
|
||||
goog.require('ol.layer.Layer');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.render.Event');
|
||||
goog.require('ol.render.EventType');
|
||||
goog.require('ol.render.canvas.Immediate');
|
||||
goog.require('ol.renderer.Map');
|
||||
goog.require('ol.renderer.dom.ImageLayer');
|
||||
goog.require('ol.renderer.dom.TileLayer');
|
||||
goog.require('ol.renderer.dom.VectorLayer');
|
||||
goog.require('ol.source.State');
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.renderer.Map}
|
||||
* @param {Element} container Container.
|
||||
* @param {ol.Map} map Map.
|
||||
*/
|
||||
ol.renderer.dom.Map = function(container, map) {
|
||||
|
||||
ol.renderer.Map.call(this, container, map);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {CanvasRenderingContext2D}
|
||||
*/
|
||||
this.context_ = ol.dom.createCanvasContext2D();
|
||||
var canvas = this.context_.canvas;
|
||||
canvas.style.position = 'absolute';
|
||||
canvas.style.width = '100%';
|
||||
canvas.style.height = '100%';
|
||||
canvas.className = ol.css.CLASS_UNSELECTABLE;
|
||||
container.insertBefore(canvas, container.childNodes[0] || null);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Transform}
|
||||
*/
|
||||
this.transform_ = ol.transform.create();
|
||||
|
||||
/**
|
||||
* @type {!Element}
|
||||
* @private
|
||||
*/
|
||||
this.layersPane_ = document.createElement('DIV');
|
||||
this.layersPane_.className = ol.css.CLASS_UNSELECTABLE;
|
||||
var style = this.layersPane_.style;
|
||||
style.position = 'absolute';
|
||||
style.width = '100%';
|
||||
style.height = '100%';
|
||||
|
||||
// prevent the img context menu on mobile devices
|
||||
ol.events.listen(this.layersPane_, ol.events.EventType.TOUCHSTART,
|
||||
ol.events.Event.preventDefault);
|
||||
|
||||
container.insertBefore(this.layersPane_, container.childNodes[0] || null);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.renderedVisible_ = true;
|
||||
|
||||
};
|
||||
ol.inherits(ol.renderer.dom.Map, ol.renderer.Map);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.Map.prototype.disposeInternal = function() {
|
||||
ol.dom.removeNode(this.layersPane_);
|
||||
ol.renderer.Map.prototype.disposeInternal.call(this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.Map.prototype.createLayerRenderer = function(layer) {
|
||||
var layerRenderer;
|
||||
if (ol.ENABLE_IMAGE && layer instanceof ol.layer.Image) {
|
||||
layerRenderer = new ol.renderer.dom.ImageLayer(layer);
|
||||
} else if (ol.ENABLE_TILE && layer instanceof ol.layer.Tile) {
|
||||
layerRenderer = new ol.renderer.dom.TileLayer(layer);
|
||||
} else if (ol.ENABLE_VECTOR && layer instanceof ol.layer.Vector) {
|
||||
layerRenderer = new ol.renderer.dom.VectorLayer(layer);
|
||||
} else {
|
||||
ol.DEBUG && console.assert(false, 'unexpected layer configuration');
|
||||
return null;
|
||||
}
|
||||
return layerRenderer;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.render.EventType} type Event type.
|
||||
* @param {olx.FrameState} frameState Frame state.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.dom.Map.prototype.dispatchComposeEvent_ = function(type, frameState) {
|
||||
var map = this.getMap();
|
||||
if (map.hasListener(type)) {
|
||||
var extent = frameState.extent;
|
||||
var pixelRatio = frameState.pixelRatio;
|
||||
var viewState = frameState.viewState;
|
||||
var rotation = viewState.rotation;
|
||||
var context = this.context_;
|
||||
var canvas = context.canvas;
|
||||
|
||||
var transform = ol.transform.compose(this.transform_,
|
||||
canvas.width / 2, canvas.height / 2,
|
||||
pixelRatio / viewState.resolution, -pixelRatio / viewState.resolution,
|
||||
-rotation,
|
||||
-viewState.center[0], -viewState.center[1]);
|
||||
|
||||
var vectorContext = new ol.render.canvas.Immediate(context, pixelRatio,
|
||||
extent, transform, rotation);
|
||||
var composeEvent = new ol.render.Event(type, vectorContext,
|
||||
frameState, context, null);
|
||||
map.dispatchEvent(composeEvent);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.Map.prototype.getType = function() {
|
||||
return ol.RendererType.DOM;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.Map.prototype.renderFrame = function(frameState) {
|
||||
|
||||
if (!frameState) {
|
||||
if (this.renderedVisible_) {
|
||||
this.layersPane_.style.display = 'none';
|
||||
this.renderedVisible_ = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var map = this.getMap();
|
||||
if (map.hasListener(ol.render.EventType.PRECOMPOSE) ||
|
||||
map.hasListener(ol.render.EventType.POSTCOMPOSE)) {
|
||||
var canvas = this.context_.canvas;
|
||||
var pixelRatio = frameState.pixelRatio;
|
||||
canvas.width = frameState.size[0] * pixelRatio;
|
||||
canvas.height = frameState.size[1] * pixelRatio;
|
||||
}
|
||||
|
||||
this.dispatchComposeEvent_(ol.render.EventType.PRECOMPOSE, frameState);
|
||||
|
||||
var layerStatesArray = frameState.layerStatesArray;
|
||||
ol.array.stableSort(layerStatesArray, ol.renderer.Map.sortByZIndex);
|
||||
|
||||
var viewResolution = frameState.viewState.resolution;
|
||||
var i, ii, layer, layerRenderer, layerState;
|
||||
for (i = 0, ii = layerStatesArray.length; i < ii; ++i) {
|
||||
layerState = layerStatesArray[i];
|
||||
layer = layerState.layer;
|
||||
layerRenderer = /** @type {ol.renderer.dom.Layer} */ (
|
||||
this.getLayerRenderer(layer));
|
||||
this.layersPane_.insertBefore(layerRenderer.getTarget(), this.layersPane_.childNodes[i] || null);
|
||||
if (ol.layer.Layer.visibleAtResolution(layerState, viewResolution) &&
|
||||
layerState.sourceState == ol.source.State.READY) {
|
||||
if (layerRenderer.prepareFrame(frameState, layerState)) {
|
||||
layerRenderer.composeFrame(frameState, layerState);
|
||||
}
|
||||
} else {
|
||||
layerRenderer.clearFrame();
|
||||
}
|
||||
}
|
||||
|
||||
var layerStates = frameState.layerStates;
|
||||
var layerKey;
|
||||
for (layerKey in this.getLayerRenderers()) {
|
||||
if (!(layerKey in layerStates)) {
|
||||
layerRenderer = /** @type {ol.renderer.dom.Layer} */ (this.getLayerRendererByKey(layerKey));
|
||||
ol.dom.removeNode(layerRenderer.getTarget());
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.renderedVisible_) {
|
||||
this.layersPane_.style.display = '';
|
||||
this.renderedVisible_ = true;
|
||||
}
|
||||
|
||||
this.calculateMatrices2D(frameState);
|
||||
this.scheduleRemoveUnusedLayerRenderers(frameState);
|
||||
this.scheduleExpireIconCache(frameState);
|
||||
|
||||
this.dispatchComposeEvent_(ol.render.EventType.POSTCOMPOSE, frameState);
|
||||
};
|
||||
@@ -1,440 +0,0 @@
|
||||
// FIXME probably need to reset TileLayerZ if offsets get too large
|
||||
// FIXME when zooming out, preserve higher Z divs to avoid white flash
|
||||
|
||||
goog.provide('ol.renderer.dom.TileLayer');
|
||||
|
||||
goog.require('ol');
|
||||
goog.require('ol.Tile');
|
||||
goog.require('ol.TileRange');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.array');
|
||||
goog.require('ol.dom');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.renderer.dom.Layer');
|
||||
goog.require('ol.size');
|
||||
goog.require('ol.transform');
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.renderer.dom.Layer}
|
||||
* @param {ol.layer.Tile} tileLayer Tile layer.
|
||||
*/
|
||||
ol.renderer.dom.TileLayer = function(tileLayer) {
|
||||
|
||||
var target = document.createElement('DIV');
|
||||
target.style.position = 'absolute';
|
||||
|
||||
ol.renderer.dom.Layer.call(this, tileLayer, target);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.renderedVisible_ = true;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.renderedOpacity_ = 1;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.renderedRevision_ = 0;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!Object.<number, ol.renderer.dom.TileLayerZ_>}
|
||||
*/
|
||||
this.tileLayerZs_ = {};
|
||||
|
||||
};
|
||||
ol.inherits(ol.renderer.dom.TileLayer, ol.renderer.dom.Layer);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.TileLayer.prototype.clearFrame = function() {
|
||||
ol.dom.removeChildren(this.target);
|
||||
this.renderedRevision_ = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.TileLayer.prototype.prepareFrame = function(frameState, layerState) {
|
||||
|
||||
if (!layerState.visible) {
|
||||
if (this.renderedVisible_) {
|
||||
this.target.style.display = 'none';
|
||||
this.renderedVisible_ = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
var pixelRatio = frameState.pixelRatio;
|
||||
var viewState = frameState.viewState;
|
||||
var projection = viewState.projection;
|
||||
|
||||
var tileLayer = /** @type {ol.layer.Tile} */ (this.getLayer());
|
||||
var tileSource = tileLayer.getSource();
|
||||
var tileGrid = tileSource.getTileGridForProjection(projection);
|
||||
var tileGutter = pixelRatio * tileSource.getGutter(projection);
|
||||
var z = tileGrid.getZForResolution(viewState.resolution);
|
||||
var tileResolution = tileGrid.getResolution(z);
|
||||
var center = viewState.center;
|
||||
var extent;
|
||||
if (tileResolution == viewState.resolution) {
|
||||
center = this.snapCenterToPixel(center, tileResolution, frameState.size);
|
||||
extent = ol.extent.getForViewAndSize(
|
||||
center, tileResolution, viewState.rotation, frameState.size);
|
||||
} else {
|
||||
extent = frameState.extent;
|
||||
}
|
||||
|
||||
if (layerState.extent !== undefined) {
|
||||
extent = ol.extent.getIntersection(extent, layerState.extent);
|
||||
}
|
||||
|
||||
var tileRange = tileGrid.getTileRangeForExtentAndResolution(
|
||||
extent, tileResolution);
|
||||
|
||||
/** @type {Object.<number, Object.<string, ol.Tile>>} */
|
||||
var tilesToDrawByZ = {};
|
||||
tilesToDrawByZ[z] = {};
|
||||
|
||||
var findLoadedTiles = this.createLoadedTileFinder(
|
||||
tileSource, projection, tilesToDrawByZ);
|
||||
|
||||
var useInterimTilesOnError = tileLayer.getUseInterimTilesOnError();
|
||||
|
||||
var tmpExtent = ol.extent.createEmpty();
|
||||
var tmpTileRange = new ol.TileRange(0, 0, 0, 0);
|
||||
var childTileRange, drawable, fullyLoaded, tile, tileState, x, y;
|
||||
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||
tile = tileSource.getTile(z, x, y, pixelRatio, projection);
|
||||
tileState = tile.getState();
|
||||
drawable = tileState == ol.Tile.State.LOADED ||
|
||||
tileState == ol.Tile.State.EMPTY ||
|
||||
tileState == ol.Tile.State.ERROR && !useInterimTilesOnError;
|
||||
if (!drawable && tile.interimTile) {
|
||||
tile = tile.interimTile;
|
||||
}
|
||||
tileState = tile.getState();
|
||||
if (tileState == ol.Tile.State.LOADED) {
|
||||
tilesToDrawByZ[z][tile.tileCoord.toString()] = tile;
|
||||
continue;
|
||||
} else if (tileState == ol.Tile.State.EMPTY ||
|
||||
(tileState == ol.Tile.State.ERROR &&
|
||||
!useInterimTilesOnError)) {
|
||||
continue;
|
||||
}
|
||||
fullyLoaded = tileGrid.forEachTileCoordParentTileRange(
|
||||
tile.tileCoord, findLoadedTiles, null, tmpTileRange, tmpExtent);
|
||||
if (!fullyLoaded) {
|
||||
childTileRange = tileGrid.getTileCoordChildTileRange(
|
||||
tile.tileCoord, tmpTileRange, tmpExtent);
|
||||
if (childTileRange) {
|
||||
findLoadedTiles(z + 1, childTileRange);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If the tile source revision changes, we destroy the existing DOM structure
|
||||
// so that a new one will be created. It would be more efficient to modify
|
||||
// the existing structure.
|
||||
var tileLayerZ, tileLayerZKey;
|
||||
if (this.renderedRevision_ != tileSource.getRevision()) {
|
||||
for (tileLayerZKey in this.tileLayerZs_) {
|
||||
tileLayerZ = this.tileLayerZs_[+tileLayerZKey];
|
||||
ol.dom.removeNode(tileLayerZ.target);
|
||||
}
|
||||
this.tileLayerZs_ = {};
|
||||
this.renderedRevision_ = tileSource.getRevision();
|
||||
}
|
||||
|
||||
/** @type {Array.<number>} */
|
||||
var zs = Object.keys(tilesToDrawByZ).map(Number);
|
||||
zs.sort(ol.array.numberSafeCompareFunction);
|
||||
|
||||
/** @type {Object.<number, boolean>} */
|
||||
var newTileLayerZKeys = {};
|
||||
|
||||
var iz, iziz, tileCoordKey, tileCoordOrigin, tilesToDraw;
|
||||
for (iz = 0, iziz = zs.length; iz < iziz; ++iz) {
|
||||
tileLayerZKey = zs[iz];
|
||||
if (tileLayerZKey in this.tileLayerZs_) {
|
||||
tileLayerZ = this.tileLayerZs_[tileLayerZKey];
|
||||
} else {
|
||||
tileCoordOrigin =
|
||||
tileGrid.getTileCoordForCoordAndZ(center, tileLayerZKey);
|
||||
tileLayerZ = new ol.renderer.dom.TileLayerZ_(tileGrid, tileCoordOrigin);
|
||||
newTileLayerZKeys[tileLayerZKey] = true;
|
||||
this.tileLayerZs_[tileLayerZKey] = tileLayerZ;
|
||||
}
|
||||
tilesToDraw = tilesToDrawByZ[tileLayerZKey];
|
||||
for (tileCoordKey in tilesToDraw) {
|
||||
tileLayerZ.addTile(tilesToDraw[tileCoordKey], tileGutter);
|
||||
}
|
||||
tileLayerZ.finalizeAddTiles();
|
||||
}
|
||||
|
||||
/** @type {Array.<number>} */
|
||||
var tileLayerZKeys = Object.keys(this.tileLayerZs_).map(Number);
|
||||
tileLayerZKeys.sort(ol.array.numberSafeCompareFunction);
|
||||
|
||||
var i, ii, j, origin, resolution;
|
||||
var transform = ol.transform.create();
|
||||
for (i = 0, ii = tileLayerZKeys.length; i < ii; ++i) {
|
||||
tileLayerZKey = tileLayerZKeys[i];
|
||||
tileLayerZ = this.tileLayerZs_[tileLayerZKey];
|
||||
if (!(tileLayerZKey in tilesToDrawByZ)) {
|
||||
ol.dom.removeNode(tileLayerZ.target);
|
||||
delete this.tileLayerZs_[tileLayerZKey];
|
||||
continue;
|
||||
}
|
||||
resolution = tileLayerZ.getResolution();
|
||||
origin = tileLayerZ.getOrigin();
|
||||
|
||||
ol.transform.compose(transform,
|
||||
frameState.size[0] / 2, frameState.size[1] / 2,
|
||||
resolution / viewState.resolution, resolution / viewState.resolution,
|
||||
viewState.rotation,
|
||||
(origin[0] - center[0]) / resolution, (center[1] - origin[1]) / resolution);
|
||||
|
||||
tileLayerZ.setTransform(transform);
|
||||
if (tileLayerZKey in newTileLayerZKeys) {
|
||||
for (j = tileLayerZKey - 1; j >= 0; --j) {
|
||||
if (j in this.tileLayerZs_) {
|
||||
if (this.tileLayerZs_[j].target.parentNode) {
|
||||
this.tileLayerZs_[j].target.parentNode.insertBefore(tileLayerZ.target, this.tileLayerZs_[j].target.nextSibling);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j < 0) {
|
||||
this.target.insertBefore(tileLayerZ.target, this.target.childNodes[0] || null);
|
||||
}
|
||||
} else {
|
||||
if (!frameState.viewHints[ol.View.Hint.ANIMATING] &&
|
||||
!frameState.viewHints[ol.View.Hint.INTERACTING]) {
|
||||
tileLayerZ.removeTilesOutsideExtent(extent, tmpTileRange);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (layerState.opacity != this.renderedOpacity_) {
|
||||
this.target.style.opacity = layerState.opacity;
|
||||
this.renderedOpacity_ = layerState.opacity;
|
||||
}
|
||||
|
||||
if (layerState.visible && !this.renderedVisible_) {
|
||||
this.target.style.display = '';
|
||||
this.renderedVisible_ = true;
|
||||
}
|
||||
|
||||
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
|
||||
this.manageTilePyramid(frameState, tileSource, tileGrid, pixelRatio,
|
||||
projection, extent, z, tileLayer.getPreload());
|
||||
this.scheduleExpireCache(frameState, tileSource);
|
||||
this.updateLogos(frameState, tileSource);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @private
|
||||
* @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
|
||||
* @param {ol.TileCoord} tileCoordOrigin Tile coord origin.
|
||||
*/
|
||||
ol.renderer.dom.TileLayerZ_ = function(tileGrid, tileCoordOrigin) {
|
||||
|
||||
/**
|
||||
* @type {!Element}
|
||||
*/
|
||||
this.target = document.createElement('DIV');
|
||||
this.target.style.position = 'absolute';
|
||||
this.target.style.width = '100%';
|
||||
this.target.style.height = '100%';
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.tilegrid.TileGrid}
|
||||
*/
|
||||
this.tileGrid_ = tileGrid;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.TileCoord}
|
||||
*/
|
||||
this.tileCoordOrigin_ = tileCoordOrigin;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Coordinate}
|
||||
*/
|
||||
this.origin_ =
|
||||
ol.extent.getTopLeft(tileGrid.getTileCoordExtent(tileCoordOrigin));
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.resolution_ = tileGrid.getResolution(tileCoordOrigin[0]);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, ol.Tile>}
|
||||
*/
|
||||
this.tiles_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {DocumentFragment}
|
||||
*/
|
||||
this.documentFragment_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Transform}
|
||||
*/
|
||||
this.transform_ = ol.transform.create();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Size}
|
||||
*/
|
||||
this.tmpSize_ = [0, 0];
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Tile} tile Tile.
|
||||
* @param {number} tileGutter Tile gutter.
|
||||
*/
|
||||
ol.renderer.dom.TileLayerZ_.prototype.addTile = function(tile, tileGutter) {
|
||||
var tileCoord = tile.tileCoord;
|
||||
var tileCoordZ = tileCoord[0];
|
||||
var tileCoordX = tileCoord[1];
|
||||
var tileCoordY = tileCoord[2];
|
||||
ol.DEBUG && console.assert(tileCoordZ == this.tileCoordOrigin_[0],
|
||||
'tileCoordZ matches z of tileCoordOrigin');
|
||||
var tileCoordKey = tileCoord.toString();
|
||||
if (tileCoordKey in this.tiles_) {
|
||||
return;
|
||||
}
|
||||
var tileSize = ol.size.toSize(
|
||||
this.tileGrid_.getTileSize(tileCoordZ), this.tmpSize_);
|
||||
var image = tile.getImage(this);
|
||||
var imageStyle = image.style;
|
||||
// Bootstrap sets the style max-width: 100% for all images, which
|
||||
// prevents the tile from being displayed in FireFox. Workaround
|
||||
// by overriding the max-width style.
|
||||
imageStyle.maxWidth = 'none';
|
||||
var tileElement;
|
||||
var tileElementStyle;
|
||||
if (tileGutter > 0) {
|
||||
tileElement = document.createElement('DIV');
|
||||
tileElementStyle = tileElement.style;
|
||||
tileElementStyle.overflow = 'hidden';
|
||||
tileElementStyle.width = tileSize[0] + 'px';
|
||||
tileElementStyle.height = tileSize[1] + 'px';
|
||||
imageStyle.position = 'absolute';
|
||||
imageStyle.left = -tileGutter + 'px';
|
||||
imageStyle.top = -tileGutter + 'px';
|
||||
imageStyle.width = (tileSize[0] + 2 * tileGutter) + 'px';
|
||||
imageStyle.height = (tileSize[1] + 2 * tileGutter) + 'px';
|
||||
tileElement.appendChild(image);
|
||||
} else {
|
||||
imageStyle.width = tileSize[0] + 'px';
|
||||
imageStyle.height = tileSize[1] + 'px';
|
||||
tileElement = image;
|
||||
tileElementStyle = imageStyle;
|
||||
}
|
||||
tileElementStyle.position = 'absolute';
|
||||
tileElementStyle.left =
|
||||
((tileCoordX - this.tileCoordOrigin_[1]) * tileSize[0]) + 'px';
|
||||
tileElementStyle.top =
|
||||
((this.tileCoordOrigin_[2] - tileCoordY) * tileSize[1]) + 'px';
|
||||
if (!this.documentFragment_) {
|
||||
this.documentFragment_ = document.createDocumentFragment();
|
||||
}
|
||||
this.documentFragment_.appendChild(tileElement);
|
||||
this.tiles_[tileCoordKey] = tile;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
ol.renderer.dom.TileLayerZ_.prototype.finalizeAddTiles = function() {
|
||||
if (this.documentFragment_) {
|
||||
this.target.appendChild(this.documentFragment_);
|
||||
this.documentFragment_ = null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Coordinate} Origin.
|
||||
*/
|
||||
ol.renderer.dom.TileLayerZ_.prototype.getOrigin = function() {
|
||||
return this.origin_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Resolution.
|
||||
*/
|
||||
ol.renderer.dom.TileLayerZ_.prototype.getResolution = function() {
|
||||
return this.resolution_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {ol.TileRange=} opt_tileRange Temporary ol.TileRange object.
|
||||
*/
|
||||
ol.renderer.dom.TileLayerZ_.prototype.removeTilesOutsideExtent = function(extent, opt_tileRange) {
|
||||
var tileRange = this.tileGrid_.getTileRangeForExtentAndZ(
|
||||
extent, this.tileCoordOrigin_[0], opt_tileRange);
|
||||
/** @type {Array.<ol.Tile>} */
|
||||
var tilesToRemove = [];
|
||||
var tile, tileCoordKey;
|
||||
for (tileCoordKey in this.tiles_) {
|
||||
tile = this.tiles_[tileCoordKey];
|
||||
if (!tileRange.contains(tile.tileCoord)) {
|
||||
tilesToRemove.push(tile);
|
||||
}
|
||||
}
|
||||
var i, ii;
|
||||
for (i = 0, ii = tilesToRemove.length; i < ii; ++i) {
|
||||
tile = tilesToRemove[i];
|
||||
tileCoordKey = tile.tileCoord.toString();
|
||||
ol.dom.removeNode(tile.getImage(this));
|
||||
delete this.tiles_[tileCoordKey];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Transform} transform Transform.
|
||||
*/
|
||||
ol.renderer.dom.TileLayerZ_.prototype.setTransform = function(transform) {
|
||||
if (!ol.array.equals(transform, this.transform_)) {
|
||||
ol.dom.transformElement2D(this.target, transform, 6);
|
||||
ol.transform.setFromArray(this.transform_, transform);
|
||||
}
|
||||
};
|
||||
@@ -1,340 +0,0 @@
|
||||
goog.provide('ol.renderer.dom.VectorLayer');
|
||||
|
||||
goog.require('ol');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.dom');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.render.Event');
|
||||
goog.require('ol.render.EventType');
|
||||
goog.require('ol.render.canvas.Immediate');
|
||||
goog.require('ol.render.canvas.ReplayGroup');
|
||||
goog.require('ol.renderer.dom.Layer');
|
||||
goog.require('ol.renderer.vector');
|
||||
goog.require('ol.transform');
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.renderer.dom.Layer}
|
||||
* @param {ol.layer.Vector} vectorLayer Vector layer.
|
||||
*/
|
||||
ol.renderer.dom.VectorLayer = function(vectorLayer) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {CanvasRenderingContext2D}
|
||||
*/
|
||||
this.context_ = ol.dom.createCanvasContext2D();
|
||||
|
||||
var target = this.context_.canvas;
|
||||
// Bootstrap sets the style max-width: 100% for all images, which breaks
|
||||
// prevents the image from being displayed in FireFox. Workaround by
|
||||
// overriding the max-width style.
|
||||
target.style.maxWidth = 'none';
|
||||
target.style.position = 'absolute';
|
||||
|
||||
ol.renderer.dom.Layer.call(this, vectorLayer, target);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.dirty_ = false;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.renderedRevision_ = -1;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.renderedResolution_ = NaN;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Extent}
|
||||
*/
|
||||
this.renderedExtent_ = ol.extent.createEmpty();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {function(ol.Feature, ol.Feature): number|null}
|
||||
*/
|
||||
this.renderedRenderOrder_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.render.canvas.ReplayGroup}
|
||||
*/
|
||||
this.replayGroup_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Transform}
|
||||
*/
|
||||
this.transform_ = ol.transform.create();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Transform}
|
||||
*/
|
||||
this.elementTransform_ = ol.transform.create();
|
||||
|
||||
};
|
||||
ol.inherits(ol.renderer.dom.VectorLayer, ol.renderer.dom.Layer);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.VectorLayer.prototype.clearFrame = function() {
|
||||
// Clear the canvas
|
||||
var canvas = this.context_.canvas;
|
||||
canvas.width = canvas.width;
|
||||
this.renderedRevision_ = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.VectorLayer.prototype.composeFrame = function(frameState, layerState) {
|
||||
var viewState = frameState.viewState;
|
||||
var viewCenter = viewState.center;
|
||||
var viewRotation = viewState.rotation;
|
||||
var viewResolution = viewState.resolution;
|
||||
var pixelRatio = frameState.pixelRatio;
|
||||
var viewWidth = frameState.size[0];
|
||||
var viewHeight = frameState.size[1];
|
||||
var imageWidth = viewWidth * pixelRatio;
|
||||
var imageHeight = viewHeight * pixelRatio;
|
||||
|
||||
var transform = ol.transform.compose(this.transform_,
|
||||
pixelRatio * viewWidth / 2, pixelRatio * viewHeight / 2,
|
||||
pixelRatio / viewResolution, -pixelRatio / viewResolution,
|
||||
-viewRotation,
|
||||
-viewCenter[0], -viewCenter[1]);
|
||||
|
||||
var context = this.context_;
|
||||
|
||||
// Clear the canvas and set the correct size
|
||||
context.canvas.width = imageWidth;
|
||||
context.canvas.height = imageHeight;
|
||||
|
||||
var elementTransform = ol.transform.reset(this.elementTransform_);
|
||||
ol.transform.scale(elementTransform, 1 / pixelRatio, 1 / pixelRatio);
|
||||
ol.transform.translate(elementTransform,
|
||||
-(imageWidth - viewWidth) / 2 * pixelRatio,
|
||||
-(imageHeight - viewHeight) / 2 * pixelRatio);
|
||||
ol.dom.transformElement2D(context.canvas, elementTransform, 6);
|
||||
|
||||
this.dispatchEvent_(ol.render.EventType.PRECOMPOSE, frameState, transform);
|
||||
|
||||
var replayGroup = this.replayGroup_;
|
||||
|
||||
if (replayGroup && !replayGroup.isEmpty()) {
|
||||
|
||||
context.globalAlpha = layerState.opacity;
|
||||
replayGroup.replay(context, pixelRatio, transform, viewRotation,
|
||||
layerState.managed ? frameState.skippedFeatureUids : {});
|
||||
|
||||
this.dispatchEvent_(ol.render.EventType.RENDER, frameState, transform);
|
||||
}
|
||||
|
||||
this.dispatchEvent_(ol.render.EventType.POSTCOMPOSE, frameState, transform);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.render.EventType} type Event type.
|
||||
* @param {olx.FrameState} frameState Frame state.
|
||||
* @param {ol.Transform} transform Transform.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.dom.VectorLayer.prototype.dispatchEvent_ = function(type, frameState, transform) {
|
||||
var context = this.context_;
|
||||
var layer = this.getLayer();
|
||||
if (layer.hasListener(type)) {
|
||||
var render = new ol.render.canvas.Immediate(
|
||||
context, frameState.pixelRatio, frameState.extent, transform,
|
||||
frameState.viewState.rotation);
|
||||
var event = new ol.render.Event(type, render, frameState, context, null);
|
||||
layer.dispatchEvent(event);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.VectorLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, callback, thisArg) {
|
||||
if (!this.replayGroup_) {
|
||||
return undefined;
|
||||
} else {
|
||||
var resolution = frameState.viewState.resolution;
|
||||
var rotation = frameState.viewState.rotation;
|
||||
var layer = this.getLayer();
|
||||
/** @type {Object.<string, boolean>} */
|
||||
var features = {};
|
||||
return this.replayGroup_.forEachFeatureAtCoordinate(coordinate, resolution,
|
||||
rotation, {},
|
||||
/**
|
||||
* @param {ol.Feature|ol.render.Feature} feature Feature.
|
||||
* @return {?} Callback result.
|
||||
*/
|
||||
function(feature) {
|
||||
var key = ol.getUid(feature).toString();
|
||||
if (!(key in features)) {
|
||||
features[key] = true;
|
||||
return callback.call(thisArg, feature, layer);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handle changes in image style state.
|
||||
* @param {ol.events.Event} event Image style change event.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.dom.VectorLayer.prototype.handleStyleImageChange_ = function(event) {
|
||||
this.renderIfReadyAndVisible();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.VectorLayer.prototype.prepareFrame = function(frameState, layerState) {
|
||||
|
||||
var vectorLayer = /** @type {ol.layer.Vector} */ (this.getLayer());
|
||||
var vectorSource = vectorLayer.getSource();
|
||||
|
||||
this.updateAttributions(
|
||||
frameState.attributions, vectorSource.getAttributions());
|
||||
this.updateLogos(frameState, vectorSource);
|
||||
|
||||
var animating = frameState.viewHints[ol.View.Hint.ANIMATING];
|
||||
var interacting = frameState.viewHints[ol.View.Hint.INTERACTING];
|
||||
var updateWhileAnimating = vectorLayer.getUpdateWhileAnimating();
|
||||
var updateWhileInteracting = vectorLayer.getUpdateWhileInteracting();
|
||||
|
||||
if (!this.dirty_ && (!updateWhileAnimating && animating) ||
|
||||
(!updateWhileInteracting && interacting)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var frameStateExtent = frameState.extent;
|
||||
var viewState = frameState.viewState;
|
||||
var projection = viewState.projection;
|
||||
var resolution = viewState.resolution;
|
||||
var pixelRatio = frameState.pixelRatio;
|
||||
var vectorLayerRevision = vectorLayer.getRevision();
|
||||
var vectorLayerRenderBuffer = vectorLayer.getRenderBuffer();
|
||||
var vectorLayerRenderOrder = vectorLayer.getRenderOrder();
|
||||
|
||||
if (vectorLayerRenderOrder === undefined) {
|
||||
vectorLayerRenderOrder = ol.renderer.vector.defaultOrder;
|
||||
}
|
||||
|
||||
var extent = ol.extent.buffer(frameStateExtent,
|
||||
vectorLayerRenderBuffer * resolution);
|
||||
|
||||
if (!this.dirty_ &&
|
||||
this.renderedResolution_ == resolution &&
|
||||
this.renderedRevision_ == vectorLayerRevision &&
|
||||
this.renderedRenderOrder_ == vectorLayerRenderOrder &&
|
||||
ol.extent.containsExtent(this.renderedExtent_, extent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
this.replayGroup_ = null;
|
||||
|
||||
this.dirty_ = false;
|
||||
|
||||
var replayGroup =
|
||||
new ol.render.canvas.ReplayGroup(
|
||||
ol.renderer.vector.getTolerance(resolution, pixelRatio), extent,
|
||||
resolution, vectorSource.getOverlaps(), vectorLayer.getRenderBuffer());
|
||||
vectorSource.loadFeatures(extent, resolution, projection);
|
||||
/**
|
||||
* @param {ol.Feature} feature Feature.
|
||||
* @this {ol.renderer.dom.VectorLayer}
|
||||
*/
|
||||
var renderFeature = function(feature) {
|
||||
var styles;
|
||||
var styleFunction = feature.getStyleFunction();
|
||||
if (styleFunction) {
|
||||
styles = styleFunction.call(feature, resolution);
|
||||
} else {
|
||||
styleFunction = vectorLayer.getStyleFunction();
|
||||
if (styleFunction) {
|
||||
styles = styleFunction(feature, resolution);
|
||||
}
|
||||
}
|
||||
if (styles) {
|
||||
var dirty = this.renderFeature(
|
||||
feature, resolution, pixelRatio, styles, replayGroup);
|
||||
this.dirty_ = this.dirty_ || dirty;
|
||||
}
|
||||
};
|
||||
if (vectorLayerRenderOrder) {
|
||||
/** @type {Array.<ol.Feature>} */
|
||||
var features = [];
|
||||
vectorSource.forEachFeatureInExtent(extent,
|
||||
/**
|
||||
* @param {ol.Feature} feature Feature.
|
||||
*/
|
||||
function(feature) {
|
||||
features.push(feature);
|
||||
}, this);
|
||||
features.sort(vectorLayerRenderOrder);
|
||||
features.forEach(renderFeature, this);
|
||||
} else {
|
||||
vectorSource.forEachFeatureInExtent(extent, renderFeature, this);
|
||||
}
|
||||
replayGroup.finish();
|
||||
|
||||
this.renderedResolution_ = resolution;
|
||||
this.renderedRevision_ = vectorLayerRevision;
|
||||
this.renderedRenderOrder_ = vectorLayerRenderOrder;
|
||||
this.renderedExtent_ = extent;
|
||||
this.replayGroup_ = replayGroup;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Feature} feature Feature.
|
||||
* @param {number} resolution Resolution.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {(ol.style.Style|Array.<ol.style.Style>)} styles The style or array of
|
||||
* styles.
|
||||
* @param {ol.render.canvas.ReplayGroup} replayGroup Replay group.
|
||||
* @return {boolean} `true` if an image is loading.
|
||||
*/
|
||||
ol.renderer.dom.VectorLayer.prototype.renderFeature = function(feature, resolution, pixelRatio, styles, replayGroup) {
|
||||
if (!styles) {
|
||||
return false;
|
||||
}
|
||||
var loading = false;
|
||||
if (Array.isArray(styles)) {
|
||||
for (var i = 0, ii = styles.length; i < ii; ++i) {
|
||||
loading = ol.renderer.vector.renderFeature(
|
||||
replayGroup, feature, styles[i],
|
||||
ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
|
||||
this.handleStyleImageChange_, this) || loading;
|
||||
}
|
||||
} else {
|
||||
loading = ol.renderer.vector.renderFeature(
|
||||
replayGroup, feature, styles,
|
||||
ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
|
||||
this.handleStyleImageChange_, this) || loading;
|
||||
}
|
||||
return loading;
|
||||
};
|
||||
@@ -13,12 +13,11 @@ goog.require('ol.transform');
|
||||
|
||||
|
||||
/**
|
||||
* Available renderers: `'canvas'`, `'dom'` or `'webgl'`.
|
||||
* Available renderers: `'canvas'` or `'webgl'`.
|
||||
* @enum {string}
|
||||
*/
|
||||
ol.RendererType = {
|
||||
CANVAS: 'canvas',
|
||||
DOM: 'dom',
|
||||
WEBGL: 'webgl'
|
||||
};
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ goog.require('ol.events');
|
||||
goog.require('ol.events.EventType');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.math');
|
||||
goog.require('ol.obj');
|
||||
goog.require('ol.reproj');
|
||||
goog.require('ol.reproj.Triangulation');
|
||||
|
||||
@@ -62,12 +61,6 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid,
|
||||
*/
|
||||
this.canvas_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<number, HTMLCanvasElement>}
|
||||
*/
|
||||
this.canvasByContext_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.tilegrid.TileGrid}
|
||||
@@ -216,22 +209,8 @@ ol.reproj.Tile.prototype.disposeInternal = function() {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.reproj.Tile.prototype.getImage = function(opt_context) {
|
||||
if (opt_context !== undefined) {
|
||||
var image;
|
||||
var key = ol.getUid(opt_context);
|
||||
if (key in this.canvasByContext_) {
|
||||
return this.canvasByContext_[key];
|
||||
} else if (ol.obj.isEmpty(this.canvasByContext_)) {
|
||||
image = this.canvas_;
|
||||
} else {
|
||||
image = /** @type {HTMLCanvasElement} */ (this.canvas_.cloneNode(false));
|
||||
}
|
||||
this.canvasByContext_[key] = image;
|
||||
return image;
|
||||
} else {
|
||||
return this.canvas_;
|
||||
}
|
||||
ol.reproj.Tile.prototype.getImage = function() {
|
||||
return this.canvas_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -79,9 +79,9 @@ ol.source.TileDebug.Tile_ = function(tileCoord, tileSize, text) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<number, HTMLCanvasElement>}
|
||||
* @type {HTMLCanvasElement}
|
||||
*/
|
||||
this.canvasByContext_ = {};
|
||||
this.canvas_ = null;
|
||||
|
||||
};
|
||||
ol.inherits(ol.source.TileDebug.Tile_, ol.Tile);
|
||||
@@ -89,16 +89,12 @@ ol.inherits(ol.source.TileDebug.Tile_, ol.Tile);
|
||||
|
||||
/**
|
||||
* Get the image element for this tile.
|
||||
* @param {Object=} opt_context Optional context. Only used by the DOM
|
||||
* renderer.
|
||||
* @return {HTMLCanvasElement} Image.
|
||||
*/
|
||||
ol.source.TileDebug.Tile_.prototype.getImage = function(opt_context) {
|
||||
var key = opt_context !== undefined ? ol.getUid(opt_context) : -1;
|
||||
if (key in this.canvasByContext_) {
|
||||
return this.canvasByContext_[key];
|
||||
ol.source.TileDebug.Tile_.prototype.getImage = function() {
|
||||
if (this.canvas_) {
|
||||
return this.canvas_;
|
||||
} else {
|
||||
|
||||
var tileSize = this.tileSize_;
|
||||
var context = ol.dom.createCanvasContext2D(tileSize[0], tileSize[1]);
|
||||
|
||||
@@ -111,8 +107,7 @@ ol.source.TileDebug.Tile_.prototype.getImage = function(opt_context) {
|
||||
context.font = '24px sans-serif';
|
||||
context.fillText(this.text_, tileSize[0] / 2, tileSize[1] / 2);
|
||||
|
||||
this.canvasByContext_[key] = context.canvas;
|
||||
this.canvas_ = context.canvas;
|
||||
return context.canvas;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@@ -322,11 +322,9 @@ ol.inherits(ol.source.TileUTFGrid.Tile_, ol.Tile);
|
||||
|
||||
/**
|
||||
* Get the image element for this tile.
|
||||
* @param {Object=} opt_context Optional context. Only used for the DOM
|
||||
* renderer.
|
||||
* @return {Image} Image.
|
||||
*/
|
||||
ol.source.TileUTFGrid.Tile_.prototype.getImage = function(opt_context) {
|
||||
ol.source.TileUTFGrid.Tile_.prototype.getImage = function() {
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
@@ -140,10 +140,9 @@ ol.source.Zoomify.Tile_ = function(
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string,
|
||||
* HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>}
|
||||
* @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement}
|
||||
*/
|
||||
this.zoomifyImageByContext_ = {};
|
||||
this.zoomifyImage_ = null;
|
||||
|
||||
};
|
||||
ol.inherits(ol.source.Zoomify.Tile_, ol.ImageTile);
|
||||
@@ -152,27 +151,24 @@ ol.inherits(ol.source.Zoomify.Tile_, ol.ImageTile);
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.source.Zoomify.Tile_.prototype.getImage = function(opt_context) {
|
||||
ol.source.Zoomify.Tile_.prototype.getImage = function() {
|
||||
if (this.zoomifyImage_) {
|
||||
return this.zoomifyImage_;
|
||||
}
|
||||
var tileSize = ol.DEFAULT_TILE_SIZE;
|
||||
var key = opt_context !== undefined ?
|
||||
ol.getUid(opt_context).toString() : '';
|
||||
if (key in this.zoomifyImageByContext_) {
|
||||
return this.zoomifyImageByContext_[key];
|
||||
} else {
|
||||
var image = ol.ImageTile.prototype.getImage.call(this, opt_context);
|
||||
if (this.state == ol.Tile.State.LOADED) {
|
||||
if (image.width == tileSize && image.height == tileSize) {
|
||||
this.zoomifyImageByContext_[key] = image;
|
||||
return image;
|
||||
} else {
|
||||
var context = ol.dom.createCanvasContext2D(tileSize, tileSize);
|
||||
context.drawImage(image, 0, 0);
|
||||
this.zoomifyImageByContext_[key] = context.canvas;
|
||||
return context.canvas;
|
||||
}
|
||||
} else {
|
||||
var image = ol.ImageTile.prototype.getImage.call(this);
|
||||
if (this.state == ol.Tile.State.LOADED) {
|
||||
if (image.width == tileSize && image.height == tileSize) {
|
||||
this.zoomifyImage_ = image;
|
||||
return image;
|
||||
} else {
|
||||
var context = ol.dom.createCanvasContext2D(tileSize, tileSize);
|
||||
context.drawImage(image, 0, 0);
|
||||
this.zoomifyImage_ = context.canvas;
|
||||
return context.canvas;
|
||||
}
|
||||
} else {
|
||||
return image;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -60,10 +60,9 @@ ol.Tile.prototype.changed = function() {
|
||||
/**
|
||||
* Get the HTML image element for this tile (may be a Canvas, Image, or Video).
|
||||
* @abstract
|
||||
* @param {Object=} opt_context Object.
|
||||
* @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.
|
||||
*/
|
||||
ol.Tile.prototype.getImage = function(opt_context) {};
|
||||
ol.Tile.prototype.getImage = function() {};
|
||||
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user