Merge branch 'master' of github.com:openlayers/ol3 into vector
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
@exportObjectLiteralProperty ol.control.MousePositionOptions.map ol.Map|undefined
|
||||
@exportObjectLiteralProperty ol.control.MousePositionOptions.projection ol.Projection|undefined
|
||||
@exportObjectLiteralProperty ol.control.MousePositionOptions.target Element|undefined
|
||||
@exportObjectLiteralProperty ol.control.MousePositionOptions.undefinedHtml string|undefined
|
||||
@exportObjectLiteralProperty ol.control.MousePositionOptions.undefinedHTML string|undefined
|
||||
|
||||
@exportObjectLiteral ol.control.ZoomOptions
|
||||
@exportObjectLiteralProperty ol.control.ZoomOptions.delta number|undefined
|
||||
@@ -24,7 +24,6 @@
|
||||
@exportObjectLiteralProperty ol.layer.LayerOptions.visible boolean|undefined
|
||||
|
||||
@exportObjectLiteral ol.MapOptions
|
||||
@exportObjectLiteralProperty ol.MapOptions.center ol.Coordinate|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.controls ol.Collection|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.doubleClickZoom boolean|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.dragPan boolean|undefined
|
||||
@@ -32,22 +31,14 @@
|
||||
@exportObjectLiteralProperty ol.MapOptions.keyboard boolean|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.keyboardPanOffset number|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.layers ol.Collection|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.maxResolution number|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.mouseWheelZoom boolean|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.mouseWheelZoomDelta number|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.numZoomLevels number|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.projection ol.Projection|string|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.renderer ol.RendererHint|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.renderers Array.<ol.RendererHint>|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.resolution number|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.resolutions Array.<number>|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.rotate boolean|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.shiftDragZoom boolean|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.target Element|string
|
||||
@exportObjectLiteralProperty ol.MapOptions.userProjection ol.Projection|string|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.zoom number|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.view ol.IView|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.zoomDelta number|undefined
|
||||
@exportObjectLiteralProperty ol.MapOptions.zoomFactor number|undefined
|
||||
|
||||
@exportObjectLiteral ol.overlay.OverlayOptions
|
||||
@exportObjectLiteralProperty ol.overlay.OverlayOptions.coordinate ol.Coordinate|undefined
|
||||
@@ -71,3 +62,14 @@
|
||||
@exportObjectLiteralProperty ol.source.TiledWMSOptions.projection ol.Projection|undefined
|
||||
@exportObjectLiteralProperty ol.source.TiledWMSOptions.url string|undefined
|
||||
@exportObjectLiteralProperty ol.source.TiledWMSOptions.urls Array.<string>|undefined
|
||||
|
||||
@exportObjectLiteral ol.View2DOptions
|
||||
@exportObjectLiteralProperty ol.View2DOptions.center ol.Coordinate|undefined
|
||||
@exportObjectLiteralProperty ol.View2DOptions.maxResolution number|undefined
|
||||
@exportObjectLiteralProperty ol.View2DOptions.numZoomLevels number|undefined
|
||||
@exportObjectLiteralProperty ol.View2DOptions.projection ol.Projection|string|undefined
|
||||
@exportObjectLiteralProperty ol.View2DOptions.resolution number|undefined
|
||||
@exportObjectLiteralProperty ol.View2DOptions.resolutions Array.<number>|undefined
|
||||
@exportObjectLiteralProperty ol.View2DOptions.rotation number|undefined
|
||||
@exportObjectLiteralProperty ol.View2DOptions.zoom number|undefined
|
||||
@exportObjectLiteralProperty ol.View2DOptions.zoomFactor number|undefined
|
||||
|
||||
109
src/ol/animation.js
Normal file
109
src/ol/animation.js
Normal file
@@ -0,0 +1,109 @@
|
||||
// FIXME works for View2D only
|
||||
|
||||
goog.provide('ol.animation');
|
||||
|
||||
goog.require('goog.fx.easing');
|
||||
goog.require('ol.PreRenderFunction');
|
||||
goog.require('ol.View2D');
|
||||
goog.require('ol.easing');
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} resolution Resolution.
|
||||
* @param {number=} opt_duration Duration.
|
||||
* @param {number=} opt_start Start.
|
||||
* @param {function(number): number=} opt_easingFunction Easing function.
|
||||
* @return {ol.PreRenderFunction} Pre-render function.
|
||||
*/
|
||||
ol.animation.createBounce =
|
||||
function(resolution, opt_duration, opt_start, opt_easingFunction) {
|
||||
var start = goog.isDef(opt_start) ? opt_start : Date.now();
|
||||
var duration = goog.isDef(opt_duration) ? opt_duration : 1000;
|
||||
var easingFunction = goog.isDef(opt_easingFunction) ?
|
||||
opt_easingFunction : ol.easing.upAndDown;
|
||||
return function(map, frameState) {
|
||||
if (frameState.time < start) {
|
||||
frameState.animate = true;
|
||||
frameState.viewHints[ol.ViewHint.ANIMATING] += 1;
|
||||
return true;
|
||||
} else if (frameState.time < start + duration) {
|
||||
var delta = easingFunction((frameState.time - start) / duration);
|
||||
var deltaResolution = resolution - frameState.view2DState.resolution;
|
||||
frameState.animate = true;
|
||||
frameState.view2DState.resolution += delta * deltaResolution;
|
||||
frameState.viewHints[ol.ViewHint.ANIMATING] += 1;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Coordinate} source Source.
|
||||
* @param {number=} opt_duration Duration.
|
||||
* @param {number=} opt_start Start.
|
||||
* @param {function(number): number=} opt_easingFunction Easing function.
|
||||
* @return {ol.PreRenderFunction} Pre-render function.
|
||||
*/
|
||||
ol.animation.createPanFrom =
|
||||
function(source, opt_duration, opt_start, opt_easingFunction) {
|
||||
var start = goog.isDef(opt_start) ? opt_start : Date.now();
|
||||
var sourceX = source.x;
|
||||
var sourceY = source.y;
|
||||
var duration = goog.isDef(opt_duration) ? opt_duration : 1000;
|
||||
var easingFunction = goog.isDef(opt_easingFunction) ?
|
||||
opt_easingFunction : goog.fx.easing.inAndOut;
|
||||
return function(map, frameState) {
|
||||
if (frameState.time < start) {
|
||||
frameState.animate = true;
|
||||
frameState.viewHints[ol.ViewHint.ANIMATING] += 1;
|
||||
return true;
|
||||
} else if (frameState.time < start + duration) {
|
||||
var delta = 1 - easingFunction((frameState.time - start) / duration);
|
||||
var deltaX = sourceX - frameState.view2DState.center.x;
|
||||
var deltaY = sourceY - frameState.view2DState.center.y;
|
||||
frameState.animate = true;
|
||||
frameState.view2DState.center.x += delta * deltaX;
|
||||
frameState.view2DState.center.y += delta * deltaY;
|
||||
frameState.viewHints[ol.ViewHint.ANIMATING] += 1;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number=} opt_duration Duration.
|
||||
* @param {number=} opt_turns Turns.
|
||||
* @param {number=} opt_start Start.
|
||||
* @param {function(number): number=} opt_easingFunction Easing function.
|
||||
* @return {ol.PreRenderFunction} Pre-render function.
|
||||
*/
|
||||
ol.animation.createSpin =
|
||||
function(opt_duration, opt_turns, opt_start, opt_easingFunction) {
|
||||
var start = goog.isDef(opt_start) ? opt_start : Date.now();
|
||||
var duration = goog.isDef(opt_duration) ? opt_duration : 1000;
|
||||
var turns = goog.isDef(opt_turns) ? opt_turns : 1;
|
||||
var deltaTheta = 2 * turns * Math.PI;
|
||||
var easingFunction = goog.isDef(opt_easingFunction) ?
|
||||
opt_easingFunction : goog.fx.easing.inAndOut;
|
||||
return function(map, frameState) {
|
||||
if (frameState.time < start) {
|
||||
frameState.animate = true;
|
||||
frameState.viewHints[ol.ViewHint.ANIMATING] += 1;
|
||||
return true;
|
||||
} else if (frameState.time < start + duration) {
|
||||
var delta = easingFunction((frameState.time - start) / duration);
|
||||
frameState.animate = true;
|
||||
frameState.view2DState.rotation += delta * deltaTheta;
|
||||
frameState.viewHints[ol.ViewHint.ANIMATING] += 1;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -130,7 +130,7 @@ ol.Collection.prototype.getAt = function(index) {
|
||||
* @return {number} Length.
|
||||
*/
|
||||
ol.Collection.prototype.getLength = function() {
|
||||
return /** @type {number} */ this.get(ol.CollectionProperty.LENGTH);
|
||||
return /** @type {number} */ (this.get(ol.CollectionProperty.LENGTH));
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -46,3 +46,16 @@ ol.Color.createFromString = function(str, opt_a) {
|
||||
var a = opt_a || 255;
|
||||
return new ol.Color(rgb[0], rgb[1], rgb[2], a);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Color} color1 Color 1.
|
||||
* @param {ol.Color} color2 Color 2.
|
||||
* @return {boolean} Equals.
|
||||
*/
|
||||
ol.Color.equals = function(color1, color2) {
|
||||
return (color1.r == color2.r &&
|
||||
color1.g == color2.g &&
|
||||
color1.b == color2.b &&
|
||||
color1.a == color2.a);
|
||||
};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// FIXME handle date line wrap
|
||||
// FIXME handle layer order
|
||||
// FIXME check clean-up code
|
||||
// FIXME works for View2D only
|
||||
|
||||
goog.provide('ol.control.Attribution');
|
||||
|
||||
@@ -14,6 +15,8 @@ goog.require('goog.style');
|
||||
goog.require('ol.Collection');
|
||||
goog.require('ol.CoverageArea');
|
||||
goog.require('ol.TileCoverageArea');
|
||||
goog.require('ol.View2D');
|
||||
goog.require('ol.View2DProperty');
|
||||
goog.require('ol.control.Control');
|
||||
goog.require('ol.layer.Layer');
|
||||
|
||||
@@ -33,12 +36,6 @@ ol.control.Attribution = function(attributionOptions) {
|
||||
'class': 'ol-attribution'
|
||||
}, this.ulElement_);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.layersListenerKeys_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<number, ?number>}
|
||||
@@ -63,6 +60,18 @@ ol.control.Attribution = function(attributionOptions) {
|
||||
*/
|
||||
this.mapListenerKeys_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.layersListenerKeys_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.viewListenerKeys_ = null;
|
||||
|
||||
goog.base(this, {
|
||||
element: element,
|
||||
map: attributionOptions.map,
|
||||
@@ -110,14 +119,17 @@ ol.control.Attribution.prototype.createAttributionElementsForLayer_ =
|
||||
|
||||
var map = this.getMap();
|
||||
var mapIsDef = map.isDef();
|
||||
var mapExtent = /** @type {ol.Extent} */ map.getExtent();
|
||||
var mapProjection = /** @type {ol.Projection} */ map.getProjection();
|
||||
var mapResolution = /** @type {number} */ map.getResolution();
|
||||
|
||||
var layerVisible = layer.getVisible();
|
||||
|
||||
var attributionVisibilities;
|
||||
if (mapIsDef && layerVisible) {
|
||||
var mapSize = /** @type {ol.Size} */ (map.getSize());
|
||||
// FIXME works for View2D only
|
||||
var view = map.getView();
|
||||
goog.asserts.assert(view instanceof ol.View2D);
|
||||
var mapExtent = view.getExtent(mapSize);
|
||||
var mapProjection = /** @type {ol.Projection} */ (view.getProjection());
|
||||
var mapResolution = /** @type {number} */ (view.getResolution());
|
||||
attributionVisibilities = this.getLayerAttributionVisiblities_(
|
||||
layer, mapExtent, mapResolution, mapProjection);
|
||||
} else {
|
||||
@@ -131,7 +143,7 @@ ol.control.Attribution.prototype.createAttributionElementsForLayer_ =
|
||||
var attributionElement = goog.dom.createElement(goog.dom.TagName.LI);
|
||||
attributionElement.innerHTML = attribution.getHtml();
|
||||
|
||||
if (!map.isDef ||
|
||||
if (!mapIsDef ||
|
||||
!layerVisible ||
|
||||
goog.isNull(attributionVisibilities) ||
|
||||
!attributionVisibilities[attributionKey]) {
|
||||
@@ -151,8 +163,8 @@ ol.control.Attribution.prototype.createAttributionElementsForLayer_ =
|
||||
|
||||
/**
|
||||
* @param {ol.layer.Layer} layer Layer.
|
||||
* @param {ol.Extent} mapExtent Map extent.
|
||||
* @param {number} mapResolution Map resolution.
|
||||
* @param {ol.Extent} mapExtent View extent.
|
||||
* @param {number} mapResolution View resolution.
|
||||
* @param {ol.Projection} mapProjection Map projection.
|
||||
* @return {Object.<number, boolean>} Attribution visibilities.
|
||||
* @private
|
||||
@@ -169,7 +181,7 @@ ol.control.Attribution.prototype.getLayerAttributionVisiblities_ =
|
||||
|
||||
var mapZ;
|
||||
if (source instanceof ol.source.TileSource) {
|
||||
var tileSource = /** @type {ol.source.TileSource} */ source;
|
||||
var tileSource = /** @type {ol.source.TileSource} */ (source);
|
||||
var tileGrid = tileSource.getTileGrid();
|
||||
mapZ = tileGrid.getZForResolution(mapResolution);
|
||||
}
|
||||
@@ -230,7 +242,7 @@ ol.control.Attribution.prototype.getLayerAttributionVisiblities_ =
|
||||
* @param {goog.events.Event} event Event.
|
||||
*/
|
||||
ol.control.Attribution.prototype.handleLayerLoad = function(event) {
|
||||
var layer = /** @type {ol.layer.Layer} */ event.target;
|
||||
var layer = /** @type {ol.layer.Layer} */ (event.target);
|
||||
this.createAttributionElementsForLayer_(layer);
|
||||
};
|
||||
|
||||
@@ -240,17 +252,8 @@ ol.control.Attribution.prototype.handleLayerLoad = function(event) {
|
||||
* @protected
|
||||
*/
|
||||
ol.control.Attribution.prototype.handleLayerVisibleChanged = function(event) {
|
||||
|
||||
var map = this.getMap();
|
||||
var mapIsDef = map.isDef();
|
||||
var mapExtent = /** @type {ol.Extent} */ map.getExtent();
|
||||
var mapProjection = /** @type {ol.Projection} */ map.getProjection();
|
||||
var mapResolution = /** @type {number} */ map.getResolution();
|
||||
|
||||
var layer = /** @type {ol.layer.Layer} */ event.target;
|
||||
|
||||
this.updateLayerAttributionsVisibility_(
|
||||
layer, mapIsDef, mapExtent, mapResolution, mapProjection);
|
||||
var layer = /** @type {ol.layer.Layer} */ (event.target);
|
||||
this.updateLayerAttributionsVisibility_(layer);
|
||||
|
||||
};
|
||||
|
||||
@@ -260,7 +263,7 @@ ol.control.Attribution.prototype.handleLayerVisibleChanged = function(event) {
|
||||
* @protected
|
||||
*/
|
||||
ol.control.Attribution.prototype.handleLayersAdd = function(collectionEvent) {
|
||||
var layer = /** @type {ol.layer.Layer} */ collectionEvent.elem;
|
||||
var layer = /** @type {ol.layer.Layer} */ (collectionEvent.elem);
|
||||
this.addLayer(layer);
|
||||
};
|
||||
|
||||
@@ -271,7 +274,7 @@ ol.control.Attribution.prototype.handleLayersAdd = function(collectionEvent) {
|
||||
*/
|
||||
ol.control.Attribution.prototype.handleLayersRemove =
|
||||
function(collectionEvent) {
|
||||
var layer = /** @type {ol.layer.Layer} */ collectionEvent.elem;
|
||||
var layer = /** @type {ol.layer.Layer} */ (collectionEvent.elem);
|
||||
this.removeLayer(layer);
|
||||
};
|
||||
|
||||
@@ -279,20 +282,26 @@ ol.control.Attribution.prototype.handleLayersRemove =
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
ol.control.Attribution.prototype.handleMapChanged = function() {
|
||||
|
||||
ol.control.Attribution.prototype.handleMapViewChanged = function() {
|
||||
if (!goog.isNull(this.viewListenerKeys_)) {
|
||||
goog.array.forEach(this.viewListenerKeys_, goog.events.unlistenByKey);
|
||||
this.viewListenerKeys_ = null;
|
||||
}
|
||||
var map = this.getMap();
|
||||
var mapIsDef = map.isDef();
|
||||
var mapExtent = /** @type {ol.Extent} */ map.getExtent();
|
||||
var mapProjection = /** @type {ol.Projection} */ map.getProjection();
|
||||
var mapResolution = map.getResolution();
|
||||
|
||||
var layers = map.getLayers();
|
||||
layers.forEach(function(layer) {
|
||||
this.updateLayerAttributionsVisibility_(
|
||||
layer, mapIsDef, mapExtent, mapResolution, mapProjection);
|
||||
}, this);
|
||||
|
||||
goog.asserts.assert(!goog.isNull(map));
|
||||
var view = map.getView();
|
||||
if (!goog.isNull(view)) {
|
||||
// FIXME works for View2D only
|
||||
goog.asserts.assert(view instanceof ol.View2D);
|
||||
this.viewListenerKeys_ = [
|
||||
goog.events.listen(
|
||||
view, ol.Object.getChangedEventType(ol.View2DProperty.CENTER),
|
||||
this.updateAttributions, false, this),
|
||||
goog.events.listen(
|
||||
view, ol.Object.getChangedEventType(ol.View2DProperty.RESOLUTION),
|
||||
this.updateAttributions, false, this)
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -359,35 +368,51 @@ ol.control.Attribution.prototype.setMap = function(map) {
|
||||
goog.base(this, 'setMap', map);
|
||||
if (!goog.isNull(map)) {
|
||||
this.mapListenerKeys_ = [
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.CENTER),
|
||||
this.handleMapChanged, false, this),
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.LAYERS),
|
||||
this.handleMapLayersChanged, false, this),
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.RESOLUTION),
|
||||
this.handleMapChanged, false, this),
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.SIZE),
|
||||
this.handleMapChanged, false, this)
|
||||
this.updateAttributions, false, this),
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.VIEW),
|
||||
this.updateAttributions, false, this)
|
||||
];
|
||||
this.handleMapViewChanged();
|
||||
this.handleMapLayersChanged();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
ol.control.Attribution.prototype.updateAttributions = function() {
|
||||
|
||||
var map = this.getMap();
|
||||
var layers = map.getLayers();
|
||||
layers.forEach(function(layer) {
|
||||
this.updateLayerAttributionsVisibility_(layer);
|
||||
}, this);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.layer.Layer} layer Layer.
|
||||
* @param {boolean} mapIsDef Map is defined.
|
||||
* @param {ol.Extent} mapExtent Map extent.
|
||||
* @param {number} mapResolution Map resolution.
|
||||
* @param {ol.Projection} mapProjection Map projection.
|
||||
* @private
|
||||
*/
|
||||
ol.control.Attribution.prototype.updateLayerAttributionsVisibility_ =
|
||||
function(layer, mapIsDef, mapExtent, mapResolution, mapProjection) {
|
||||
if (mapIsDef && layer.getVisible()) {
|
||||
function(layer) {
|
||||
var map = this.getMap();
|
||||
if (map.isDef() && layer.getVisible()) {
|
||||
var mapSize = /** @type {ol.Size} */ (map.getSize());
|
||||
var view = map.getView();
|
||||
// FIXME works for View2D only
|
||||
goog.asserts.assert(view instanceof ol.View2D);
|
||||
var mapExtent = view.getExtent(mapSize);
|
||||
var mapProjection = /** @type {ol.Projection} */ (view.getProjection());
|
||||
var mapResolution = /** @type {number} */ (view.getResolution());
|
||||
var attributionVisibilities = this.getLayerAttributionVisiblities_(
|
||||
layer, mapExtent, mapResolution, mapProjection);
|
||||
goog.object.forEach(
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
// FIXME should listen on appropriate pane, once it is defined
|
||||
// FIXME works for View2D only
|
||||
|
||||
goog.provide('ol.control.MousePosition');
|
||||
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.style');
|
||||
@@ -47,8 +49,20 @@ ol.control.MousePosition = function(mousePositionOptions) {
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.undefinedHtml_ = goog.isDef(mousePositionOptions.undefinedHtml) ?
|
||||
mousePositionOptions.undefinedHtml : '';
|
||||
this.undefinedHTML_ = goog.isDef(mousePositionOptions.undefinedHTML) ?
|
||||
mousePositionOptions.undefinedHTML : '';
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.renderedHTML_ = element.innerHTML;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Projection}
|
||||
*/
|
||||
this.mapProjection_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -58,23 +72,38 @@ ol.control.MousePosition = function(mousePositionOptions) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
* @type {ol.Projection}
|
||||
*/
|
||||
this.listenerKeys_ = [];
|
||||
this.renderedProjection_ = null;
|
||||
|
||||
this.handleMapProjectionChanged();
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Pixel}
|
||||
*/
|
||||
this.lastMouseMovePixel_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<?number>}
|
||||
*/
|
||||
this.listenerKeys_ = null;
|
||||
|
||||
};
|
||||
goog.inherits(ol.control.MousePosition, ol.control.Control);
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.MapEvent} mapEvent Map event.
|
||||
* @protected
|
||||
*/
|
||||
ol.control.MousePosition.prototype.handleMapProjectionChanged = function() {
|
||||
this.updateTransform_();
|
||||
// FIXME should we instead re-calculate using the last known mouse position?
|
||||
this.element.innerHTML = this.undefinedHtml_;
|
||||
ol.control.MousePosition.prototype.handleMapPostrender = function(mapEvent) {
|
||||
var frameState = mapEvent.frameState;
|
||||
if (goog.isNull(frameState)) {
|
||||
this.mapProjection_ = null;
|
||||
} else {
|
||||
this.mapProjection_ = frameState.view2DState.projection;
|
||||
}
|
||||
this.updateHTML_(this.lastMouseMovePixel_);
|
||||
};
|
||||
|
||||
|
||||
@@ -87,19 +116,8 @@ ol.control.MousePosition.prototype.handleMouseMove = function(browserEvent) {
|
||||
var eventPosition = goog.style.getRelativePosition(
|
||||
browserEvent, map.getViewport());
|
||||
var pixel = new ol.Pixel(eventPosition.x, eventPosition.y);
|
||||
var coordinate = map.getCoordinateFromPixel(pixel);
|
||||
var html;
|
||||
if (!goog.isNull(coordinate)) {
|
||||
coordinate = this.transform_(coordinate);
|
||||
if (goog.isDef(this.coordinateFormat_)) {
|
||||
html = this.coordinateFormat_(coordinate);
|
||||
} else {
|
||||
html = coordinate.toString();
|
||||
}
|
||||
} else {
|
||||
html = this.undefinedHtml_;
|
||||
}
|
||||
this.element.innerHTML = html;
|
||||
this.updateHTML_(pixel);
|
||||
this.lastMouseMovePixel_ = pixel;
|
||||
};
|
||||
|
||||
|
||||
@@ -108,7 +126,8 @@ ol.control.MousePosition.prototype.handleMouseMove = function(browserEvent) {
|
||||
* @protected
|
||||
*/
|
||||
ol.control.MousePosition.prototype.handleMouseOut = function(browserEvent) {
|
||||
this.element.innerHTML = this.undefinedHtml_;
|
||||
this.updateHTML_(null);
|
||||
this.lastMouseMovePixel_ = null;
|
||||
};
|
||||
|
||||
|
||||
@@ -123,34 +142,47 @@ ol.control.MousePosition.prototype.setMap = function(map) {
|
||||
goog.base(this, 'setMap', map);
|
||||
if (!goog.isNull(map)) {
|
||||
var viewport = map.getViewport();
|
||||
this.listenerKeys = [
|
||||
goog.events.listen(map,
|
||||
ol.Object.getChangedEventType(ol.MapProperty.PROJECTION),
|
||||
this.handleMapProjectionChanged, false, this),
|
||||
this.listenerKeys_ = [
|
||||
goog.events.listen(viewport, goog.events.EventType.MOUSEMOVE,
|
||||
this.handleMouseMove, false, this),
|
||||
goog.events.listen(viewport, goog.events.EventType.MOUSEOUT,
|
||||
this.handleMouseOut, false, this)
|
||||
this.handleMouseOut, false, this),
|
||||
goog.events.listen(map, ol.MapEventType.POSTRENDER,
|
||||
this.handleMapPostrender, false, this)
|
||||
];
|
||||
this.updateTransform_();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {?ol.Pixel} pixel Pixel.
|
||||
* @private
|
||||
*/
|
||||
ol.control.MousePosition.prototype.updateTransform_ = function() {
|
||||
var map = this.getMap();
|
||||
if (goog.isNull(map)) {
|
||||
this.transform_ = ol.Projection.identityTransform;
|
||||
} else {
|
||||
var mapProjection = map.getProjection();
|
||||
if (!goog.isDef(mapProjection) || !goog.isDef(this.projection_)) {
|
||||
this.transform_ = ol.Projection.identityTransform;
|
||||
} else {
|
||||
this.transform_ =
|
||||
ol.Projection.getTransform(mapProjection, this.projection_);
|
||||
ol.control.MousePosition.prototype.updateHTML_ = function(pixel) {
|
||||
var html = this.undefinedHTML_;
|
||||
if (!goog.isNull(pixel)) {
|
||||
if (this.renderedProjection_ != this.mapProjection_) {
|
||||
if (goog.isDef(this.projection_)) {
|
||||
this.transform_ = ol.Projection.getTransform(
|
||||
this.mapProjection_, this.projection_);
|
||||
} else {
|
||||
this.transform_ = ol.Projection.identityTransform;
|
||||
}
|
||||
this.renderedProjection_ = this.mapProjection_;
|
||||
}
|
||||
var map = this.getMap();
|
||||
var coordinate = map.getCoordinateFromPixel(pixel);
|
||||
if (!goog.isNull(coordinate)) {
|
||||
coordinate = this.transform_(coordinate);
|
||||
if (goog.isDef(this.coordinateFormat_)) {
|
||||
html = this.coordinateFormat_(coordinate);
|
||||
} else {
|
||||
html = coordinate.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!goog.isDef(this.renderedHTML_) || html != this.renderedHTML_) {
|
||||
this.element.innerHTML = html;
|
||||
this.renderedHTML_ = html;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// FIXME works for View2D only
|
||||
|
||||
goog.provide('ol.control.Zoom');
|
||||
|
||||
goog.require('goog.dom');
|
||||
@@ -58,7 +60,9 @@ goog.inherits(ol.control.Zoom, ol.control.Control);
|
||||
ol.control.Zoom.prototype.handleIn_ = function(browserEvent) {
|
||||
// prevent #zoomIn anchor from getting appended to the url
|
||||
browserEvent.preventDefault();
|
||||
this.getMap().zoom(this.delta_);
|
||||
var map = this.getMap();
|
||||
// FIXME works for View2D only
|
||||
map.getView().zoom(map, this.delta_);
|
||||
};
|
||||
|
||||
|
||||
@@ -69,5 +73,7 @@ ol.control.Zoom.prototype.handleIn_ = function(browserEvent) {
|
||||
ol.control.Zoom.prototype.handleOut_ = function(browserEvent) {
|
||||
// prevent #zoomOut anchor from getting appended to the url
|
||||
browserEvent.preventDefault();
|
||||
this.getMap().zoom(-this.delta_);
|
||||
var map = this.getMap();
|
||||
// FIXME works for View2D only
|
||||
map.getView().zoom(map, -this.delta_);
|
||||
};
|
||||
|
||||
86
src/ol/dom/dom.js
Normal file
86
src/ol/dom/dom.js
Normal file
@@ -0,0 +1,86 @@
|
||||
// FIXME add tests for browser features (Modernizr?)
|
||||
// FIXME implement Matrix Filter for IE < 9
|
||||
|
||||
goog.provide('ol.dom');
|
||||
goog.provide('ol.dom.BrowserFeature');
|
||||
|
||||
goog.require('goog.vec.Mat4');
|
||||
|
||||
|
||||
/**
|
||||
* @enum {boolean}
|
||||
*/
|
||||
ol.dom.BrowserFeature = {
|
||||
CAN_USE_CSS_TRANSFORM: false,
|
||||
CAN_USE_CSS_TRANSFORM3D: true,
|
||||
CAN_USE_MATRIX_FILTER: false
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @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.transform = value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Element} element Element.
|
||||
* @param {goog.vec.Mat4.AnyType} 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.BrowserFeature.CAN_USE_CSS_TRANSFORM3D) {
|
||||
var value3D;
|
||||
if (goog.isDef(opt_precision)) {
|
||||
/** @type {Array.<string>} */
|
||||
var strings3D = new Array(16);
|
||||
for (i = 0; i < 16; ++i) {
|
||||
strings3D[i] = transform[i].toFixed(opt_precision);
|
||||
}
|
||||
value3D = strings3D.join(',');
|
||||
} else {
|
||||
value3D = transform.join(',');
|
||||
}
|
||||
ol.dom.setTransform(element, 'matrix3d(' + value3D + ')');
|
||||
} else if (ol.dom.BrowserFeature.CAN_USE_CSS_TRANSFORM) {
|
||||
/** @type {Array.<number>} */
|
||||
var transform2D = [
|
||||
goog.vec.Mat4.getElement(transform, 0, 0),
|
||||
goog.vec.Mat4.getElement(transform, 1, 0),
|
||||
goog.vec.Mat4.getElement(transform, 0, 1),
|
||||
goog.vec.Mat4.getElement(transform, 1, 1),
|
||||
goog.vec.Mat4.getElement(transform, 0, 3),
|
||||
goog.vec.Mat4.getElement(transform, 1, 3)
|
||||
];
|
||||
var value2D;
|
||||
if (goog.isDef(opt_precision)) {
|
||||
/** @type {Array.<string>} */
|
||||
var strings2D = new Array(6);
|
||||
for (i = 0; i < 6; ++i) {
|
||||
strings2D[i] = transform2D[i].toFixed(opt_precision);
|
||||
}
|
||||
value2D = strings2D.join(',');
|
||||
} else {
|
||||
value2D = transform2D.join(',');
|
||||
}
|
||||
ol.dom.setTransform(element, 'matrix(' + value2D + ')');
|
||||
} else if (ol.dom.BrowserFeature.CAN_USE_MATRIX_FILTER) {
|
||||
// http://msdn.microsoft.com/en-us/library/ms533014%28VS.85,loband%29.aspx
|
||||
goog.asserts.assert(false); // FIXME
|
||||
} else {
|
||||
// FIXME check this code!
|
||||
var style = element.style;
|
||||
style.left = Math.round(goog.vec.Mat4.getElement(transform, 0, 3)) + 'px';
|
||||
style.top = Math.round(goog.vec.Mat4.getElement(transform, 1, 3)) + 'px';
|
||||
}
|
||||
};
|
||||
14
src/ol/easing.js
Normal file
14
src/ol/easing.js
Normal file
@@ -0,0 +1,14 @@
|
||||
goog.provide('ol.easing');
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} t Input between 0 and 1.
|
||||
* @return {number} Output between 0 and 1.
|
||||
*/
|
||||
ol.easing.upAndDown = function(t) {
|
||||
if (t < 0.5) {
|
||||
return goog.fx.easing.inAndOut(2 * t);
|
||||
} else {
|
||||
return 1 - goog.fx.easing.inAndOut(2 * (t - 0.5));
|
||||
}
|
||||
};
|
||||
44
src/ol/framestate.js
Normal file
44
src/ol/framestate.js
Normal file
@@ -0,0 +1,44 @@
|
||||
// FIXME add view3DState
|
||||
|
||||
goog.provide('ol.FrameState');
|
||||
goog.provide('ol.PostRenderFunction');
|
||||
goog.provide('ol.PreRenderFunction');
|
||||
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.Color');
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.Size');
|
||||
goog.require('ol.TileQueue');
|
||||
goog.require('ol.View2DState');
|
||||
goog.require('ol.layer.LayerState');
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{animate: boolean,
|
||||
* backgroundColor: ol.Color,
|
||||
* coordinateToPixelMatrix: goog.vec.Mat4.Number,
|
||||
* extent: (null|ol.Extent),
|
||||
* layersArray: Array.<ol.layer.Layer>,
|
||||
* layerStates: Object.<number, ol.layer.LayerState>,
|
||||
* pixelToCoordinateMatrix: goog.vec.Mat4.Number,
|
||||
* postRenderFunctions: Array.<ol.PostRenderFunction>,
|
||||
* size: ol.Size,
|
||||
* tileQueue: ol.TileQueue,
|
||||
* time: number,
|
||||
* view2DState: ol.View2DState,
|
||||
* viewHints: Array.<number>}}
|
||||
*/
|
||||
ol.FrameState;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {function(ol.Map, ?ol.FrameState): boolean}
|
||||
*/
|
||||
ol.PostRenderFunction;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {function(ol.Map, ?ol.FrameState): boolean}
|
||||
*/
|
||||
ol.PreRenderFunction;
|
||||
138
src/ol/imagetile.js
Normal file
138
src/ol/imagetile.js
Normal file
@@ -0,0 +1,138 @@
|
||||
goog.provide('ol.ImageTile');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventTarget');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('ol.Tile');
|
||||
goog.require('ol.TileCoord');
|
||||
goog.require('ol.TileState');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.Tile}
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @param {string} src Image source URI.
|
||||
* @param {?string} crossOrigin Cross origin.
|
||||
*/
|
||||
ol.ImageTile = function(tileCoord, src, crossOrigin) {
|
||||
|
||||
goog.base(this, tileCoord);
|
||||
|
||||
/**
|
||||
* Image URI
|
||||
*
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.src_ = src;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Image}
|
||||
*/
|
||||
this.image_ = new Image();
|
||||
if (!goog.isNull(crossOrigin)) {
|
||||
this.image_.crossOrigin = crossOrigin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<number, Image>}
|
||||
*/
|
||||
this.imageByContext_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.imageListenerKeys_ = null;
|
||||
|
||||
};
|
||||
goog.inherits(ol.ImageTile, ol.Tile);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.ImageTile.prototype.getImage = function(opt_context) {
|
||||
if (goog.isDef(opt_context)) {
|
||||
var image;
|
||||
var key = goog.getUid(opt_context);
|
||||
if (key in this.imageByContext_) {
|
||||
return this.imageByContext_[key];
|
||||
} else if (goog.object.isEmpty(this.imageByContext_)) {
|
||||
image = this.image_;
|
||||
} else {
|
||||
image = /** @type {Image} */ (this.image_.cloneNode(false));
|
||||
}
|
||||
this.imageByContext_[key] = image;
|
||||
return image;
|
||||
} else {
|
||||
return this.image_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.ImageTile.prototype.getKey = function() {
|
||||
return this.src_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Tracks loading or read errors.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
ol.ImageTile.prototype.handleImageError_ = function() {
|
||||
this.state = ol.TileState.ERROR;
|
||||
this.unlistenImage_();
|
||||
this.dispatchChangeEvent();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Tracks successful image load.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
ol.ImageTile.prototype.handleImageLoad_ = function() {
|
||||
this.state = ol.TileState.LOADED;
|
||||
this.unlistenImage_();
|
||||
this.dispatchChangeEvent();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Load not yet loaded URI.
|
||||
*/
|
||||
ol.ImageTile.prototype.load = function() {
|
||||
if (this.state == ol.TileState.IDLE) {
|
||||
this.state = ol.TileState.LOADING;
|
||||
goog.asserts.assert(goog.isNull(this.imageListenerKeys_));
|
||||
this.imageListenerKeys_ = [
|
||||
goog.events.listenOnce(this.image_, goog.events.EventType.ERROR,
|
||||
this.handleImageError_, false, this),
|
||||
goog.events.listenOnce(this.image_, goog.events.EventType.LOAD,
|
||||
this.handleImageLoad_, false, this)
|
||||
];
|
||||
this.image_.src = this.src_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Discards event handlers which listen for load completion or errors.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
ol.ImageTile.prototype.unlistenImage_ = function() {
|
||||
goog.asserts.assert(!goog.isNull(this.imageListenerKeys_));
|
||||
goog.array.forEach(this.imageListenerKeys_, goog.events.unlistenByKey);
|
||||
this.imageListenerKeys_ = null;
|
||||
};
|
||||
@@ -1,7 +1,10 @@
|
||||
// FIXME works for View2D only
|
||||
|
||||
goog.provide('ol.interaction.DblClickZoom');
|
||||
|
||||
goog.require('ol.MapBrowserEvent');
|
||||
goog.require('ol.MapBrowserEvent.EventType');
|
||||
goog.require('ol.View2D');
|
||||
goog.require('ol.interaction.Interaction');
|
||||
|
||||
|
||||
@@ -35,7 +38,10 @@ ol.interaction.DblClickZoom.prototype.handleMapBrowserEvent =
|
||||
var anchor = mapBrowserEvent.getCoordinate();
|
||||
var delta = mapBrowserEvent.browserEvent.shiftKey ?
|
||||
-this.delta_ : this.delta_;
|
||||
map.zoom(delta, anchor);
|
||||
// FIXME works for View2D only
|
||||
var view = map.getView();
|
||||
goog.asserts.assert(view instanceof ol.View2D);
|
||||
view.zoom(map, delta, anchor);
|
||||
mapBrowserEvent.preventDefault();
|
||||
browserEvent.preventDefault();
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ ol.interaction.Drag.prototype.handleMapBrowserEvent =
|
||||
if (!map.isDef()) {
|
||||
return;
|
||||
}
|
||||
var view = map.getView();
|
||||
var browserEvent = mapBrowserEvent.browserEvent;
|
||||
if (this.dragging_) {
|
||||
if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.DRAG) {
|
||||
@@ -109,9 +110,9 @@ ol.interaction.Drag.prototype.handleMapBrowserEvent =
|
||||
this.startY = browserEvent.clientY;
|
||||
this.deltaX = 0;
|
||||
this.deltaY = 0;
|
||||
this.startCenter = /** @type {!ol.Coordinate} */ map.getCenter();
|
||||
this.startCenter = /** @type {!ol.Coordinate} */ (view.getCenter());
|
||||
this.startCoordinate = /** @type {ol.Coordinate} */
|
||||
mapBrowserEvent.getCoordinate();
|
||||
(mapBrowserEvent.getCoordinate());
|
||||
var handled = this.handleDragStart(mapBrowserEvent);
|
||||
if (handled) {
|
||||
this.dragging_ = true;
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
// FIXME works for View2D only
|
||||
|
||||
goog.provide('ol.interaction.DragPan');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.MapBrowserEvent');
|
||||
goog.require('ol.View2D');
|
||||
goog.require('ol.ViewHint');
|
||||
goog.require('ol.interaction.ConditionType');
|
||||
goog.require('ol.interaction.Drag');
|
||||
|
||||
@@ -31,17 +36,28 @@ goog.inherits(ol.interaction.DragPan, ol.interaction.Drag);
|
||||
*/
|
||||
ol.interaction.DragPan.prototype.handleDrag = function(mapBrowserEvent) {
|
||||
var map = mapBrowserEvent.map;
|
||||
var resolution = map.getResolution();
|
||||
var rotation = map.getRotation();
|
||||
// FIXME works for View2D only
|
||||
var view = map.getView();
|
||||
goog.asserts.assert(view instanceof ol.View2D);
|
||||
var resolution = view.getResolution();
|
||||
var rotation = view.getRotation();
|
||||
var delta =
|
||||
new ol.Coordinate(-resolution * this.deltaX, resolution * this.deltaY);
|
||||
if (map.canRotate() && goog.isDef(rotation)) {
|
||||
delta.rotate(rotation);
|
||||
}
|
||||
delta.rotate(rotation);
|
||||
var newCenter = new ol.Coordinate(
|
||||
this.startCenter.x + delta.x, this.startCenter.y + delta.y);
|
||||
map.requestRenderFrame();
|
||||
map.setCenter(newCenter);
|
||||
view.setCenter(newCenter);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.interaction.DragPan.prototype.handleDragEnd = function(mapBrowserEvent) {
|
||||
var map = mapBrowserEvent.map;
|
||||
map.requestRenderFrame();
|
||||
map.getView().setHint(ol.ViewHint.PANNING, -1);
|
||||
};
|
||||
|
||||
|
||||
@@ -51,7 +67,9 @@ ol.interaction.DragPan.prototype.handleDrag = function(mapBrowserEvent) {
|
||||
ol.interaction.DragPan.prototype.handleDragStart = function(mapBrowserEvent) {
|
||||
var browserEvent = mapBrowserEvent.browserEvent;
|
||||
if (this.condition_(browserEvent)) {
|
||||
mapBrowserEvent.map.requestRenderFrame();
|
||||
var map = mapBrowserEvent.map;
|
||||
map.requestRenderFrame();
|
||||
map.getView().setHint(ol.ViewHint.PANNING, 1);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
// FIXME works for View2D only
|
||||
|
||||
goog.provide('ol.interaction.DragRotateAndZoom');
|
||||
|
||||
goog.require('goog.math.Vec2');
|
||||
goog.require('ol.MapBrowserEvent');
|
||||
goog.require('ol.View2D');
|
||||
goog.require('ol.interaction.ConditionType');
|
||||
goog.require('ol.interaction.Drag');
|
||||
|
||||
@@ -50,12 +53,15 @@ ol.interaction.DragRotateAndZoom.prototype.handleDrag =
|
||||
browserEvent.offsetX - size.width / 2,
|
||||
size.height / 2 - browserEvent.offsetY);
|
||||
var theta = Math.atan2(delta.y, delta.x);
|
||||
var resolution = this.startRatio_ * delta.magnitude();
|
||||
// FIXME works for View2D only
|
||||
var view = map.getView();
|
||||
goog.asserts.assert(view instanceof ol.View2D);
|
||||
map.requestRenderFrame();
|
||||
// FIXME the calls to map.rotate and map.zoomToResolution should use
|
||||
// map.withFrozenRendering but an assertion fails :-(
|
||||
map.rotate(this.startRotation_, -theta);
|
||||
var resolution = this.startRatio_ * delta.magnitude();
|
||||
map.zoomToResolution(resolution);
|
||||
view.rotate(map, this.startRotation_, -theta);
|
||||
view.zoomToResolution(map, resolution);
|
||||
};
|
||||
|
||||
|
||||
@@ -66,14 +72,15 @@ ol.interaction.DragRotateAndZoom.prototype.handleDragStart =
|
||||
function(mapBrowserEvent) {
|
||||
var browserEvent = mapBrowserEvent.browserEvent;
|
||||
var map = mapBrowserEvent.map;
|
||||
if (map.canRotate() && this.condition_(browserEvent)) {
|
||||
var resolution = map.getResolution();
|
||||
var view = map.getView().getView2D();
|
||||
if (this.condition_(browserEvent)) {
|
||||
var resolution = view.getResolution();
|
||||
var size = map.getSize();
|
||||
var delta = new goog.math.Vec2(
|
||||
browserEvent.offsetX - size.width / 2,
|
||||
size.height / 2 - browserEvent.offsetY);
|
||||
var theta = Math.atan2(delta.y, delta.x);
|
||||
this.startRotation_ = (map.getRotation() || 0) + theta;
|
||||
this.startRotation_ = (view.getRotation() || 0) + theta;
|
||||
this.startRatio_ = resolution / delta.magnitude();
|
||||
map.requestRenderFrame();
|
||||
return true;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
goog.provide('ol.interaction.DragRotate');
|
||||
|
||||
goog.require('ol.MapBrowserEvent');
|
||||
goog.require('ol.View2D');
|
||||
goog.require('ol.interaction.ConditionType');
|
||||
goog.require('ol.interaction.Drag');
|
||||
|
||||
@@ -42,8 +43,11 @@ ol.interaction.DragRotate.prototype.handleDrag = function(mapBrowserEvent) {
|
||||
var theta = Math.atan2(
|
||||
size.height / 2 - offset.y,
|
||||
offset.x - size.width / 2);
|
||||
// FIXME supports View2D only
|
||||
var view = map.getView();
|
||||
goog.asserts.assert(view instanceof ol.View2D);
|
||||
map.requestRenderFrame();
|
||||
map.rotate(this.startRotation_, -theta);
|
||||
view.rotate(map, this.startRotation_, -theta);
|
||||
};
|
||||
|
||||
|
||||
@@ -54,15 +58,17 @@ ol.interaction.DragRotate.prototype.handleDragStart =
|
||||
function(mapBrowserEvent) {
|
||||
var browserEvent = mapBrowserEvent.browserEvent;
|
||||
var map = mapBrowserEvent.map;
|
||||
if (browserEvent.isMouseActionButton() && this.condition_(browserEvent) &&
|
||||
map.canRotate()) {
|
||||
// FIXME supports View2D only
|
||||
var view = map.getView();
|
||||
goog.asserts.assert(view instanceof ol.View2D);
|
||||
if (browserEvent.isMouseActionButton() && this.condition_(browserEvent)) {
|
||||
map.requestRenderFrame();
|
||||
var size = map.getSize();
|
||||
var offset = mapBrowserEvent.getPixel();
|
||||
var theta = Math.atan2(
|
||||
size.height / 2 - offset.y,
|
||||
offset.x - size.width / 2);
|
||||
this.startRotation_ = (map.getRotation() || 0) + theta;
|
||||
this.startRotation_ = (view.getRotation() || 0) + theta;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// FIXME draw drag box
|
||||
// FIXME works for View2D only
|
||||
|
||||
goog.provide('ol.interaction.DragZoom');
|
||||
|
||||
@@ -63,7 +64,15 @@ ol.interaction.DragZoom.prototype.handleDragEnd =
|
||||
var extent = ol.Extent.boundingExtent(
|
||||
this.startCoordinate,
|
||||
mapBrowserEvent.getCoordinate());
|
||||
map.fitExtent(extent);
|
||||
map.withFrozenRendering(function() {
|
||||
// FIXME works for View2D only
|
||||
var view = map.getView();
|
||||
goog.asserts.assert(view instanceof ol.View2D);
|
||||
var mapSize = /** @type {ol.Size} */ (map.getSize());
|
||||
view.fitExtent(extent, mapSize);
|
||||
// FIXME we should preserve rotation
|
||||
view.setRotation(0);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ ol.interaction.Keyboard.prototype.handleMapBrowserEvent =
|
||||
function(mapBrowserEvent) {
|
||||
if (mapBrowserEvent.type == goog.events.KeyHandler.EventType.KEY) {
|
||||
var keyEvent = /** @type {goog.events.KeyEvent} */
|
||||
mapBrowserEvent.browserEvent;
|
||||
(mapBrowserEvent.browserEvent);
|
||||
var callback = this.charCodeCallbacks_[keyEvent.charCode];
|
||||
if (callback) {
|
||||
callback();
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
// FIXME works for View2D only
|
||||
|
||||
goog.provide('ol.interaction.KeyboardPan');
|
||||
|
||||
goog.require('goog.events.KeyCodes');
|
||||
goog.require('goog.events.KeyHandler.EventType');
|
||||
goog.require('ol.View2D');
|
||||
goog.require('ol.interaction.Interaction');
|
||||
|
||||
|
||||
@@ -32,14 +35,17 @@ ol.interaction.KeyboardPan.prototype.handleMapBrowserEvent =
|
||||
function(mapBrowserEvent) {
|
||||
if (mapBrowserEvent.type == goog.events.KeyHandler.EventType.KEY) {
|
||||
var keyEvent = /** @type {goog.events.KeyEvent} */
|
||||
mapBrowserEvent.browserEvent;
|
||||
(mapBrowserEvent.browserEvent);
|
||||
var keyCode = keyEvent.keyCode;
|
||||
if (keyCode == goog.events.KeyCodes.DOWN ||
|
||||
keyCode == goog.events.KeyCodes.LEFT ||
|
||||
keyCode == goog.events.KeyCodes.RIGHT ||
|
||||
keyCode == goog.events.KeyCodes.UP) {
|
||||
var map = mapBrowserEvent.map;
|
||||
var resolution = map.getResolution();
|
||||
// FIXME works for View2D only
|
||||
var view = map.getView();
|
||||
goog.asserts.assert(view instanceof ol.View2D);
|
||||
var resolution = view.getResolution();
|
||||
var delta;
|
||||
var mapUnitsDelta = resolution * this.pixelDelta_;
|
||||
if (keyCode == goog.events.KeyCodes.DOWN) {
|
||||
@@ -52,10 +58,10 @@ ol.interaction.KeyboardPan.prototype.handleMapBrowserEvent =
|
||||
goog.asserts.assert(keyCode == goog.events.KeyCodes.UP);
|
||||
delta = new ol.Coordinate(0, mapUnitsDelta);
|
||||
}
|
||||
var oldCenter = map.getCenter();
|
||||
var oldCenter = view.getCenter();
|
||||
var newCenter = new ol.Coordinate(
|
||||
oldCenter.x + delta.x, oldCenter.y + delta.y);
|
||||
map.setCenter(newCenter);
|
||||
view.setCenter(newCenter);
|
||||
keyEvent.preventDefault();
|
||||
mapBrowserEvent.preventDefault();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
// FIXME works for View2D only
|
||||
|
||||
goog.provide('ol.interaction.KeyboardZoom');
|
||||
|
||||
goog.require('goog.events.KeyCodes');
|
||||
goog.require('goog.events.KeyHandler.EventType');
|
||||
goog.require('ol.View2D');
|
||||
goog.require('ol.interaction.Interaction');
|
||||
|
||||
|
||||
@@ -23,12 +26,15 @@ ol.interaction.KeyboardZoom.prototype.handleMapBrowserEvent =
|
||||
function(mapBrowserEvent) {
|
||||
if (mapBrowserEvent.type == goog.events.KeyHandler.EventType.KEY) {
|
||||
var keyEvent = /** @type {goog.events.KeyEvent} */
|
||||
mapBrowserEvent.browserEvent;
|
||||
(mapBrowserEvent.browserEvent);
|
||||
var charCode = keyEvent.charCode;
|
||||
if (charCode == '+'.charCodeAt(0) || charCode == '-'.charCodeAt(0)) {
|
||||
var map = mapBrowserEvent.map;
|
||||
var delta = (charCode == '+'.charCodeAt(0)) ? 4 : -4;
|
||||
map.zoom(delta);
|
||||
// FIXME works for View2D only
|
||||
var view = map.getView();
|
||||
goog.asserts.assert(view instanceof ol.View2D);
|
||||
view.zoom(map, delta);
|
||||
keyEvent.preventDefault();
|
||||
mapBrowserEvent.preventDefault();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
// FIXME works for View2D only
|
||||
|
||||
goog.provide('ol.interaction.MouseWheelZoom');
|
||||
|
||||
goog.require('goog.events.MouseWheelEvent');
|
||||
goog.require('goog.events.MouseWheelHandler.EventType');
|
||||
goog.require('ol.MapBrowserEvent');
|
||||
goog.require('ol.View2D');
|
||||
|
||||
|
||||
|
||||
@@ -32,12 +35,15 @@ ol.interaction.MouseWheelZoom.prototype.handleMapBrowserEvent =
|
||||
goog.events.MouseWheelHandler.EventType.MOUSEWHEEL) {
|
||||
var map = mapBrowserEvent.map;
|
||||
var mouseWheelEvent = /** @type {goog.events.MouseWheelEvent} */
|
||||
mapBrowserEvent.browserEvent;
|
||||
(mapBrowserEvent.browserEvent);
|
||||
goog.asserts.assert(mouseWheelEvent instanceof goog.events.MouseWheelEvent);
|
||||
var anchor = mapBrowserEvent.getCoordinate();
|
||||
var delta = mouseWheelEvent.deltaY < 0 ? this.delta_ : -this.delta_;
|
||||
// FIXME works for View2D only
|
||||
var view = map.getView();
|
||||
goog.asserts.assert(view instanceof ol.View2D);
|
||||
map.requestRenderFrame();
|
||||
map.zoom(delta, anchor);
|
||||
view.zoom(map, delta, anchor);
|
||||
mapBrowserEvent.preventDefault();
|
||||
mouseWheelEvent.preventDefault();
|
||||
}
|
||||
|
||||
27
src/ol/iview.js
Normal file
27
src/ol/iview.js
Normal file
@@ -0,0 +1,27 @@
|
||||
goog.provide('ol.IView');
|
||||
|
||||
goog.require('ol.IView2D');
|
||||
goog.require('ol.IView3D');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface for views.
|
||||
* @interface
|
||||
*/
|
||||
ol.IView = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.IView2D} View2D.
|
||||
*/
|
||||
ol.IView.prototype.getView2D = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.IView3D} View3D.
|
||||
*/
|
||||
ol.IView.prototype.getView3D = function() {
|
||||
};
|
||||
59
src/ol/iview2d.js
Normal file
59
src/ol/iview2d.js
Normal file
@@ -0,0 +1,59 @@
|
||||
goog.provide('ol.IView2D');
|
||||
goog.provide('ol.View2DState');
|
||||
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.Projection');
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{center: ol.Coordinate,
|
||||
* projection: ol.Projection,
|
||||
* resolution: number,
|
||||
* rotation: number}}
|
||||
*/
|
||||
ol.View2DState;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface for views.
|
||||
* @interface
|
||||
*/
|
||||
ol.IView2D = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Coordinate|undefined} Map center.
|
||||
*/
|
||||
ol.IView2D.prototype.getCenter = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Projection|undefined} Map projection.
|
||||
*/
|
||||
ol.IView2D.prototype.getProjection = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number|undefined} Map resolution.
|
||||
*/
|
||||
ol.IView2D.prototype.getResolution = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number|undefined} Map rotation.
|
||||
*/
|
||||
ol.IView2D.prototype.getRotation = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.View2DState} View2D state.
|
||||
*/
|
||||
ol.IView2D.prototype.getView2DState = function() {
|
||||
};
|
||||
12
src/ol/iview3d.js
Normal file
12
src/ol/iview3d.js
Normal file
@@ -0,0 +1,12 @@
|
||||
goog.provide('ol.IView3D');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface for views.
|
||||
* @interface
|
||||
*/
|
||||
ol.IView3D = function() {
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
goog.provide('ol.layer.Layer');
|
||||
goog.provide('ol.layer.LayerProperty');
|
||||
goog.provide('ol.layer.LayerState');
|
||||
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventType');
|
||||
@@ -21,6 +22,18 @@ ol.layer.LayerProperty = {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{brightness: number,
|
||||
* contrast: number,
|
||||
* hue: number,
|
||||
* opacity: number,
|
||||
* ready: boolean,
|
||||
* saturation: number,
|
||||
* visible: boolean}}
|
||||
*/
|
||||
ol.layer.LayerState;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
@@ -71,7 +84,7 @@ ol.layer.Layer.prototype.dispatchLoadEvent_ = function() {
|
||||
* @return {number} Brightness.
|
||||
*/
|
||||
ol.layer.Layer.prototype.getBrightness = function() {
|
||||
return /** @type {number} */ this.get(ol.layer.LayerProperty.BRIGHTNESS);
|
||||
return /** @type {number} */ (this.get(ol.layer.LayerProperty.BRIGHTNESS));
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.layer.Layer.prototype,
|
||||
@@ -83,7 +96,7 @@ goog.exportProperty(
|
||||
* @return {number} Contrast.
|
||||
*/
|
||||
ol.layer.Layer.prototype.getContrast = function() {
|
||||
return /** @type {number} */ this.get(ol.layer.LayerProperty.CONTRAST);
|
||||
return /** @type {number} */ (this.get(ol.layer.LayerProperty.CONTRAST));
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.layer.Layer.prototype,
|
||||
@@ -95,7 +108,7 @@ goog.exportProperty(
|
||||
* @return {number} Hue.
|
||||
*/
|
||||
ol.layer.Layer.prototype.getHue = function() {
|
||||
return /** @type {number} */ this.get(ol.layer.LayerProperty.HUE);
|
||||
return /** @type {number} */ (this.get(ol.layer.LayerProperty.HUE));
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.layer.Layer.prototype,
|
||||
@@ -103,11 +116,34 @@ goog.exportProperty(
|
||||
ol.layer.Layer.prototype.getHue);
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.layer.LayerState} Layer state.
|
||||
*/
|
||||
ol.layer.Layer.prototype.getLayerState = function() {
|
||||
var brightness = this.getBrightness();
|
||||
var contrast = this.getContrast();
|
||||
var hue = this.getHue();
|
||||
var opacity = this.getOpacity();
|
||||
var ready = this.isReady();
|
||||
var saturation = this.getSaturation();
|
||||
var visible = this.getVisible();
|
||||
return {
|
||||
brightness: goog.isDef(brightness) ? brightness : 0,
|
||||
contrast: goog.isDef(contrast) ? contrast : 1,
|
||||
hue: goog.isDef(hue) ? hue : 0,
|
||||
opacity: goog.isDef(opacity) ? opacity : 1,
|
||||
ready: ready,
|
||||
saturation: goog.isDef(saturation) ? saturation : 1,
|
||||
visible: goog.isDef(visible) ? visible : true
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Opacity.
|
||||
*/
|
||||
ol.layer.Layer.prototype.getOpacity = function() {
|
||||
return /** @type {number} */ this.get(ol.layer.LayerProperty.OPACITY);
|
||||
return /** @type {number} */ (this.get(ol.layer.LayerProperty.OPACITY));
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.layer.Layer.prototype,
|
||||
@@ -119,7 +155,7 @@ goog.exportProperty(
|
||||
* @return {number} Saturation.
|
||||
*/
|
||||
ol.layer.Layer.prototype.getSaturation = function() {
|
||||
return /** @type {number} */ this.get(ol.layer.LayerProperty.SATURATION);
|
||||
return /** @type {number} */ (this.get(ol.layer.LayerProperty.SATURATION));
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.layer.Layer.prototype,
|
||||
@@ -139,7 +175,7 @@ ol.layer.Layer.prototype.getSource = function() {
|
||||
* @return {boolean} Visible.
|
||||
*/
|
||||
ol.layer.Layer.prototype.getVisible = function() {
|
||||
return /** @type {boolean} */ this.get(ol.layer.LayerProperty.VISIBLE);
|
||||
return /** @type {boolean} */ (this.get(ol.layer.LayerProperty.VISIBLE));
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.layer.Layer.prototype,
|
||||
|
||||
@@ -20,5 +20,5 @@ goog.inherits(ol.layer.TileLayer, ol.layer.Layer);
|
||||
* @return {ol.source.TileSource} Source.
|
||||
*/
|
||||
ol.layer.TileLayer.prototype.getTileSource = function() {
|
||||
return /** @type {ol.source.TileSource} */ this.getSource();
|
||||
return /** @type {ol.source.TileSource} */ (this.getSource());
|
||||
};
|
||||
|
||||
642
src/ol/map.js
642
src/ol/map.js
@@ -3,10 +3,11 @@
|
||||
// FIXME add tilt and height?
|
||||
|
||||
goog.provide('ol.Map');
|
||||
goog.provide('ol.MapEventType');
|
||||
goog.provide('ol.MapProperty');
|
||||
goog.provide('ol.RendererHint');
|
||||
goog.provide('ol.RendererHints');
|
||||
|
||||
goog.require('goog.Uri.QueryData');
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.async.AnimationDelay');
|
||||
goog.require('goog.debug.Logger');
|
||||
@@ -22,22 +23,24 @@ goog.require('goog.events.KeyHandler.EventType');
|
||||
goog.require('goog.events.MouseWheelEvent');
|
||||
goog.require('goog.events.MouseWheelHandler');
|
||||
goog.require('goog.events.MouseWheelHandler.EventType');
|
||||
goog.require('goog.functions');
|
||||
goog.require('goog.object');
|
||||
goog.require('ol.BrowserFeature');
|
||||
goog.require('ol.Collection');
|
||||
goog.require('ol.Color');
|
||||
goog.require('ol.Constraints');
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.FrameState');
|
||||
goog.require('ol.MapBrowserEvent');
|
||||
goog.require('ol.Object');
|
||||
goog.require('ol.Pixel');
|
||||
goog.require('ol.Projection');
|
||||
goog.require('ol.ResolutionConstraint');
|
||||
goog.require('ol.RotationConstraint');
|
||||
goog.require('ol.Size');
|
||||
goog.require('ol.TileQueue');
|
||||
goog.require('ol.TransformFunction');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.View2D');
|
||||
goog.require('ol.View2DState');
|
||||
goog.require('ol.control.Attribution');
|
||||
goog.require('ol.control.Zoom');
|
||||
goog.require('ol.interaction.DblClickZoom');
|
||||
@@ -87,26 +90,14 @@ ol.DEFAULT_RENDERER_HINTS = [
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
ol.MapEventType = {
|
||||
POSTRENDER: 'postrender'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
ol.MapProperty = {
|
||||
BACKGROUND_COLOR: 'backgroundColor',
|
||||
CENTER: 'center',
|
||||
LAYERS: 'layers',
|
||||
PROJECTION: 'projection',
|
||||
RESOLUTION: 'resolution',
|
||||
ROTATION: 'rotation',
|
||||
SIZE: 'size',
|
||||
USER_PROJECTION: 'userProjection'
|
||||
VIEW: 'view'
|
||||
};
|
||||
|
||||
|
||||
@@ -130,18 +121,6 @@ ol.Map = function(mapOptions) {
|
||||
|
||||
var mapOptionsInternal = ol.Map.createOptionsInternal(mapOptions);
|
||||
|
||||
/**
|
||||
* @type {ol.TransformFunction}
|
||||
* @private
|
||||
*/
|
||||
this.userToMapTransform_ = ol.Projection.identityTransform;
|
||||
|
||||
/**
|
||||
* @type {ol.TransformFunction}
|
||||
* @private
|
||||
*/
|
||||
this.mapToUserTransform_ = ol.Projection.cloneTransform;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {goog.async.AnimationDelay}
|
||||
@@ -150,6 +129,24 @@ ol.Map = function(mapOptions) {
|
||||
new goog.async.AnimationDelay(this.renderFrame_, undefined, this);
|
||||
this.registerDisposable(this.animationDelay_);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {goog.vec.Mat4.Number}
|
||||
*/
|
||||
this.coordinateToPixelMatrix_ = goog.vec.Mat4.createNumber();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {goog.vec.Mat4.Number}
|
||||
*/
|
||||
this.pixelToCoordinateMatrix_ = goog.vec.Mat4.createNumber();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {?ol.FrameState}
|
||||
*/
|
||||
this.frameState_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
@@ -168,12 +165,6 @@ ol.Map = function(mapOptions) {
|
||||
*/
|
||||
this.target_ = mapOptionsInternal.target;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Constraints}
|
||||
*/
|
||||
this.constraints_ = mapOptionsInternal.constraints;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Element}
|
||||
@@ -253,13 +244,29 @@ ol.Map = function(mapOptions) {
|
||||
goog.events.listen(this.viewportSizeMonitor_, goog.events.EventType.RESIZE,
|
||||
this.handleBrowserWindowResize, false, this);
|
||||
|
||||
goog.events.listen(
|
||||
this, ol.Object.getChangedEventType(ol.MapProperty.PROJECTION),
|
||||
this.handleProjectionChanged, false, this);
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<ol.PreRenderFunction>}
|
||||
*/
|
||||
this.preRenderFunctions_ = [];
|
||||
|
||||
goog.events.listen(
|
||||
this, ol.Object.getChangedEventType(ol.MapProperty.USER_PROJECTION),
|
||||
this.handleUserProjectionChanged, false, this);
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<ol.PostRenderFunction>}
|
||||
*/
|
||||
this.postRenderFunctions_ = [];
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {function(this: ol.Map)}
|
||||
*/
|
||||
this.handlePostRender_ = goog.bind(this.handlePostRender, this);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.TileQueue}
|
||||
*/
|
||||
this.tileQueue_ = new ol.TileQueue(goog.bind(this.getTilePriority, this));
|
||||
|
||||
this.setValues(mapOptionsInternal.values);
|
||||
|
||||
@@ -278,10 +285,22 @@ goog.inherits(ol.Map, ol.Object);
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Can rotate.
|
||||
* @param {ol.PreRenderFunction} preRenderFunction Pre-render function.
|
||||
*/
|
||||
ol.Map.prototype.canRotate = function() {
|
||||
return this.renderer_.canRotate();
|
||||
ol.Map.prototype.addPreRenderFunction = function(preRenderFunction) {
|
||||
this.requestRenderFrame();
|
||||
this.preRenderFunctions_.push(preRenderFunction);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array.<ol.PreRenderFunction>} preRenderFunctions
|
||||
* Pre-render functions.
|
||||
*/
|
||||
ol.Map.prototype.addPreRenderFunctions = function(preRenderFunctions) {
|
||||
this.requestRenderFrame();
|
||||
Array.prototype.push.apply(
|
||||
this.preRenderFunctions_, preRenderFunctions);
|
||||
};
|
||||
|
||||
|
||||
@@ -295,30 +314,6 @@ ol.Map.prototype.disposeInternal = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} extent Extent.
|
||||
*/
|
||||
ol.Map.prototype.fitExtent = function(extent) {
|
||||
this.withFrozenRendering(function() {
|
||||
this.setCenter(extent.getCenter());
|
||||
var resolution = this.getResolutionForExtent(extent);
|
||||
resolution = this.constraints_.resolution(resolution, 0);
|
||||
this.setResolution(resolution);
|
||||
if (this.canRotate()) {
|
||||
this.setRotation(0);
|
||||
}
|
||||
}, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} userExtent Extent in user projection.
|
||||
*/
|
||||
ol.Map.prototype.fitUserExtent = function(userExtent) {
|
||||
this.fitExtent(userExtent.transform(this.userToMapTransform_));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Freeze rendering.
|
||||
*/
|
||||
@@ -340,18 +335,6 @@ goog.exportProperty(
|
||||
ol.Map.prototype.getBackgroundColor);
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Coordinate|undefined} Center.
|
||||
*/
|
||||
ol.Map.prototype.getCenter = function() {
|
||||
return /** @type {ol.Coordinate} */ this.get(ol.MapProperty.CENTER);
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.Map.prototype,
|
||||
'getCenter',
|
||||
ol.Map.prototype.getCenter);
|
||||
|
||||
|
||||
/**
|
||||
* @return {Element} Container.
|
||||
*/
|
||||
@@ -373,25 +356,13 @@ ol.Map.prototype.getControls = function() {
|
||||
* @return {ol.Coordinate} Coordinate.
|
||||
*/
|
||||
ol.Map.prototype.getCoordinateFromPixel = function(pixel) {
|
||||
return this.isDef() ? this.renderer_.getCoordinateFromPixel(pixel) : null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Extent|undefined} Extent.
|
||||
*/
|
||||
ol.Map.prototype.getExtent = function() {
|
||||
if (this.isDef()) {
|
||||
var center = this.getCenter();
|
||||
var resolution = this.getResolution();
|
||||
var size = this.getSize();
|
||||
var minX = center.x - resolution * size.width / 2;
|
||||
var minY = center.y - resolution * size.height / 2;
|
||||
var maxX = center.x + resolution * size.width / 2;
|
||||
var maxY = center.y + resolution * size.height / 2;
|
||||
return new ol.Extent(minX, minY, maxX, maxY);
|
||||
var frameState = this.frameState_;
|
||||
if (goog.isNull(frameState)) {
|
||||
return null;
|
||||
} else {
|
||||
return undefined;
|
||||
var vec3 = [pixel.x, pixel.y, 0];
|
||||
goog.vec.Mat4.multVec3(frameState.pixelToCoordinateMatrix, vec3, vec3);
|
||||
return new ol.Coordinate(vec3[0], vec3[1]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -414,99 +385,25 @@ ol.Map.prototype.getLayers = function() {
|
||||
|
||||
/**
|
||||
* @param {ol.Coordinate} coordinate Coordinate.
|
||||
* @return {ol.Pixel|undefined} Pixel.
|
||||
* @return {ol.Pixel} Pixel.
|
||||
*/
|
||||
ol.Map.prototype.getPixelFromCoordinate = function(coordinate) {
|
||||
if (this.isDef()) {
|
||||
return this.renderer_.getPixelFromCoordinate(coordinate);
|
||||
var frameState = this.frameState_;
|
||||
if (goog.isNull(frameState)) {
|
||||
return null;
|
||||
} else {
|
||||
return undefined;
|
||||
var vec3 = [coordinate.x, coordinate.y, 0];
|
||||
goog.vec.Mat4.multVec3(frameState.coordinateToPixelMatrix, vec3, vec3);
|
||||
return new ol.Pixel(vec3[0], vec3[1]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Projection|undefined} Projection.
|
||||
*/
|
||||
ol.Map.prototype.getProjection = function() {
|
||||
return /** @type {ol.Projection} */ this.get(ol.MapProperty.PROJECTION);
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.Map.prototype,
|
||||
'getProjection',
|
||||
ol.Map.prototype.getProjection);
|
||||
|
||||
|
||||
/**
|
||||
* @return {number|undefined} Resolution.
|
||||
*/
|
||||
ol.Map.prototype.getResolution = function() {
|
||||
return /** @type {number} */ this.get(ol.MapProperty.RESOLUTION);
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.Map.prototype,
|
||||
'getResolution',
|
||||
ol.Map.prototype.getResolution);
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @return {number|undefined} Resolution.
|
||||
*/
|
||||
ol.Map.prototype.getResolutionForExtent = function(extent) {
|
||||
var size = this.getSize();
|
||||
if (goog.isDef(size)) {
|
||||
var xResolution = (extent.maxX - extent.minX) / size.width;
|
||||
var yResolution = (extent.maxY - extent.minY) / size.height;
|
||||
return Math.max(xResolution, yResolution);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Extent} Rotated extent.
|
||||
*/
|
||||
ol.Map.prototype.getRotatedExtent = function() {
|
||||
goog.asserts.assert(this.isDef());
|
||||
var center = /** @type {!ol.Coordinate} */ this.getCenter();
|
||||
var resolution = this.getResolution();
|
||||
var rotation = this.getRotation() || 0;
|
||||
var size = this.getSize();
|
||||
var xScale = resolution * size.width / 2;
|
||||
var yScale = resolution * size.height / 2;
|
||||
var corners = [
|
||||
new ol.Coordinate(-xScale, -yScale),
|
||||
new ol.Coordinate(-xScale, yScale),
|
||||
new ol.Coordinate(xScale, -yScale),
|
||||
new ol.Coordinate(xScale, yScale)
|
||||
];
|
||||
goog.array.forEach(corners, function(corner) {
|
||||
corner.rotate(rotation);
|
||||
corner.add(center);
|
||||
});
|
||||
return ol.Extent.boundingExtent.apply(null, corners);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Rotation.
|
||||
*/
|
||||
ol.Map.prototype.getRotation = function() {
|
||||
return /** @type {number} */ this.get(ol.MapProperty.ROTATION) || 0;
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.Map.prototype,
|
||||
'getRotation',
|
||||
ol.Map.prototype.getRotation);
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Size|undefined} Size.
|
||||
*/
|
||||
ol.Map.prototype.getSize = function() {
|
||||
return /** @type {ol.Size|undefined} */ this.get(ol.MapProperty.SIZE);
|
||||
return /** @type {ol.Size|undefined} */ (this.get(ol.MapProperty.SIZE));
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.Map.prototype,
|
||||
@@ -515,42 +412,15 @@ goog.exportProperty(
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Coordinate|undefined} Center in user projection.
|
||||
* @return {ol.View} View.
|
||||
*/
|
||||
ol.Map.prototype.getUserCenter = function() {
|
||||
var center = this.getCenter();
|
||||
if (goog.isDef(center)) {
|
||||
return this.mapToUserTransform_(center);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Extent|undefined} Extent in user projection.
|
||||
*/
|
||||
ol.Map.prototype.getUserExtent = function() {
|
||||
var extent = this.getExtent();
|
||||
if (goog.isDef(extent)) {
|
||||
return extent.transform(this.mapToUserTransform_);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Projection|undefined} Projection.
|
||||
*/
|
||||
ol.Map.prototype.getUserProjection = function() {
|
||||
return /** @type {ol.Projection} */ this.get(
|
||||
ol.MapProperty.USER_PROJECTION);
|
||||
ol.Map.prototype.getView = function() {
|
||||
return /** @type {ol.View} */ (this.get(ol.MapProperty.VIEW));
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.Map.prototype,
|
||||
'getUserProjection',
|
||||
ol.Map.prototype.getUserProjection);
|
||||
'getView',
|
||||
ol.Map.prototype.getView);
|
||||
|
||||
|
||||
/**
|
||||
@@ -571,6 +441,24 @@ ol.Map.prototype.getOverlayContainer = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Tile} tile Tile.
|
||||
* @param {ol.Coordinate} tileCenter Tile center.
|
||||
* @param {number} tileResolution Tile resolution.
|
||||
* @return {number|undefined} Tile priority.
|
||||
*/
|
||||
ol.Map.prototype.getTilePriority = function(tile, tileCenter, tileResolution) {
|
||||
if (goog.isNull(this.frameState_)) {
|
||||
return undefined;
|
||||
} else {
|
||||
var center = this.frameState_.view2DState.center;
|
||||
var deltaX = tileCenter.x - center.x;
|
||||
var deltaY = tileCenter.y - center.y;
|
||||
return Math.sqrt(deltaX * deltaX + deltaY * deltaY) / tileResolution;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.events.BrowserEvent} browserEvent Browser event.
|
||||
* @param {string=} opt_type Type.
|
||||
@@ -587,7 +475,7 @@ ol.Map.prototype.handleBrowserEvent = function(browserEvent, opt_type) {
|
||||
* @private
|
||||
*/
|
||||
ol.Map.prototype.handleControlsAdd_ = function(collectionEvent) {
|
||||
var control = /** @type {ol.control.Control} */ collectionEvent.elem;
|
||||
var control = /** @type {ol.control.Control} */ (collectionEvent.elem);
|
||||
control.setMap(this);
|
||||
};
|
||||
|
||||
@@ -597,7 +485,7 @@ ol.Map.prototype.handleControlsAdd_ = function(collectionEvent) {
|
||||
* @private
|
||||
*/
|
||||
ol.Map.prototype.handleControlsRemove_ = function(collectionEvent) {
|
||||
var control = /** @type {ol.control.Control} */ collectionEvent.elem;
|
||||
var control = /** @type {ol.control.Control} */ (collectionEvent.elem);
|
||||
control.setMap(null);
|
||||
};
|
||||
|
||||
@@ -608,7 +496,7 @@ ol.Map.prototype.handleControlsRemove_ = function(collectionEvent) {
|
||||
ol.Map.prototype.handleMapBrowserEvent = function(mapBrowserEvent) {
|
||||
var interactions = this.getInteractions();
|
||||
var interactionsArray = /** @type {Array.<ol.interaction.Interaction>} */
|
||||
interactions.getArray();
|
||||
(interactions.getArray());
|
||||
if (this.dispatchEvent(mapBrowserEvent) !== false) {
|
||||
for (var i = interactionsArray.length - 1; i >= 0; i--) {
|
||||
var interaction = interactionsArray[i];
|
||||
@@ -624,16 +512,16 @@ ol.Map.prototype.handleMapBrowserEvent = function(mapBrowserEvent) {
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
ol.Map.prototype.handleProjectionChanged = function() {
|
||||
this.recalculateTransforms_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
ol.Map.prototype.handleUserProjectionChanged = function() {
|
||||
this.recalculateTransforms_();
|
||||
ol.Map.prototype.handlePostRender = function() {
|
||||
this.tileQueue_.reprioritize(); // FIXME only call if needed
|
||||
this.tileQueue_.loadMoreTiles();
|
||||
goog.array.forEach(
|
||||
this.postRenderFunctions_,
|
||||
function(postRenderFunction) {
|
||||
postRenderFunction(this, this.frameState_);
|
||||
},
|
||||
this);
|
||||
this.postRenderFunctions_.length = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -650,31 +538,12 @@ ol.Map.prototype.handleBrowserWindowResize = function() {
|
||||
* @return {boolean} Is defined.
|
||||
*/
|
||||
ol.Map.prototype.isDef = function() {
|
||||
return goog.isDefAndNotNull(this.getCenter()) &&
|
||||
goog.isDef(this.getResolution()) &&
|
||||
var view = this.getView();
|
||||
return goog.isDef(view) && view.isDef() &&
|
||||
goog.isDefAndNotNull(this.getSize());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
ol.Map.prototype.recalculateTransforms_ = function() {
|
||||
var projection = this.getProjection();
|
||||
var userProjection = this.getUserProjection();
|
||||
if (goog.isDefAndNotNull(projection) &&
|
||||
goog.isDefAndNotNull(userProjection)) {
|
||||
this.mapToUserTransform_ = ol.Projection.getTransform(
|
||||
projection, userProjection);
|
||||
this.userToMapTransform_ = ol.Projection.getTransform(
|
||||
userProjection, projection);
|
||||
} else {
|
||||
this.mapToUserTransform_ = ol.Projection.cloneTransform;
|
||||
this.userToMapTransform_ = ol.Projection.identityTransform;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Render.
|
||||
*/
|
||||
@@ -708,28 +577,98 @@ ol.Map.prototype.requestRenderFrame = function() {
|
||||
* @private
|
||||
*/
|
||||
ol.Map.prototype.renderFrame_ = function(time) {
|
||||
|
||||
var i;
|
||||
|
||||
if (this.freezeRenderingCount_ != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (goog.DEBUG) {
|
||||
this.logger.info('renderFrame_');
|
||||
}
|
||||
this.renderer_.renderFrame(time);
|
||||
this.dirty_ = false;
|
||||
if (goog.DEBUG) {
|
||||
this.logger.info('postrender');
|
||||
|
||||
var size = this.getSize();
|
||||
var layers = this.getLayers();
|
||||
var layersArray = goog.isDef(layers) ?
|
||||
/** @type {Array.<ol.layer.Layer>} */ (layers.getArray()) : undefined;
|
||||
var view = this.getView();
|
||||
var view2D = goog.isDef(view) ? this.getView().getView2D() : undefined;
|
||||
/** @type {?ol.FrameState} */
|
||||
var frameState = null;
|
||||
if (goog.isDef(layersArray) && goog.isDef(size) && goog.isDef(view2D) &&
|
||||
view2D.isDef()) {
|
||||
var backgroundColor = this.getBackgroundColor();
|
||||
var viewHints = view.getHints();
|
||||
var layerStates = {};
|
||||
goog.array.forEach(layersArray, function(layer) {
|
||||
layerStates[goog.getUid(layer)] = layer.getLayerState();
|
||||
});
|
||||
var view2DState = view2D.getView2DState();
|
||||
frameState = {
|
||||
animate: false,
|
||||
backgroundColor: goog.isDef(backgroundColor) ?
|
||||
backgroundColor : new ol.Color(1, 1, 1, 1),
|
||||
coordinateToPixelMatrix: this.coordinateToPixelMatrix_,
|
||||
extent: null,
|
||||
layersArray: layersArray,
|
||||
layerStates: layerStates,
|
||||
pixelToCoordinateMatrix: this.pixelToCoordinateMatrix_,
|
||||
postRenderFunctions: [],
|
||||
size: size,
|
||||
tileQueue: this.tileQueue_,
|
||||
view2DState: view2DState,
|
||||
viewHints: viewHints,
|
||||
time: time
|
||||
};
|
||||
}
|
||||
this.dispatchEvent(ol.MapEventType.POSTRENDER);
|
||||
};
|
||||
|
||||
this.preRenderFunctions_ = goog.array.filter(
|
||||
this.preRenderFunctions_,
|
||||
function(preRenderFunction) {
|
||||
return preRenderFunction(this, frameState);
|
||||
},
|
||||
this);
|
||||
|
||||
if (!goog.isNull(frameState)) {
|
||||
// FIXME works for View2D only
|
||||
var center = view2DState.center;
|
||||
var resolution = view2DState.resolution;
|
||||
var rotation = view2DState.rotation;
|
||||
var x = resolution * size.width / 2;
|
||||
var y = resolution * size.height / 2;
|
||||
var corners = [
|
||||
new ol.Coordinate(-x, -y),
|
||||
new ol.Coordinate(-x, y),
|
||||
new ol.Coordinate(x, -y),
|
||||
new ol.Coordinate(x, y)
|
||||
];
|
||||
var corner;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
corner = corners[i];
|
||||
corner.rotate(rotation);
|
||||
corner.add(center);
|
||||
}
|
||||
frameState.extent = ol.Extent.boundingExtent.apply(null, corners);
|
||||
}
|
||||
|
||||
this.renderer_.renderFrame(frameState);
|
||||
|
||||
if (!goog.isNull(frameState)) {
|
||||
if (frameState.animate) {
|
||||
this.requestRenderFrame();
|
||||
}
|
||||
Array.prototype.push.apply(
|
||||
this.postRenderFunctions_, frameState.postRenderFunctions);
|
||||
}
|
||||
this.frameState_ = frameState;
|
||||
this.dirty_ = false;
|
||||
|
||||
this.dispatchEvent(
|
||||
new ol.MapEvent(ol.MapEventType.POSTRENDER, this, frameState));
|
||||
|
||||
goog.global.setTimeout(this.handlePostRender_, 0);
|
||||
|
||||
/**
|
||||
* @param {number|undefined} rotation Rotation.
|
||||
* @param {number} delta Delta.
|
||||
*/
|
||||
ol.Map.prototype.rotate = function(rotation, delta) {
|
||||
rotation = this.constraints_.rotation(rotation, delta);
|
||||
this.setRotation(rotation);
|
||||
};
|
||||
|
||||
|
||||
@@ -745,18 +684,6 @@ goog.exportProperty(
|
||||
ol.Map.prototype.setBackgroundColor);
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Coordinate|undefined} center Center.
|
||||
*/
|
||||
ol.Map.prototype.setCenter = function(center) {
|
||||
this.set(ol.MapProperty.CENTER, center);
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.Map.prototype,
|
||||
'setCenter',
|
||||
ol.Map.prototype.setCenter);
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Collection} layers Layers.
|
||||
*/
|
||||
@@ -769,42 +696,6 @@ goog.exportProperty(
|
||||
ol.Map.prototype.setLayers);
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Projection} projection Projection.
|
||||
*/
|
||||
ol.Map.prototype.setProjection = function(projection) {
|
||||
this.set(ol.MapProperty.PROJECTION, projection);
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.Map.prototype,
|
||||
'setProjection',
|
||||
ol.Map.prototype.setProjection);
|
||||
|
||||
|
||||
/**
|
||||
* @param {number|undefined} resolution Resolution.
|
||||
*/
|
||||
ol.Map.prototype.setResolution = function(resolution) {
|
||||
this.set(ol.MapProperty.RESOLUTION, resolution);
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.Map.prototype,
|
||||
'setResolution',
|
||||
ol.Map.prototype.setResolution);
|
||||
|
||||
|
||||
/**
|
||||
* @param {number|undefined} rotation Rotation.
|
||||
*/
|
||||
ol.Map.prototype.setRotation = function(rotation) {
|
||||
this.set(ol.MapProperty.ROTATION, rotation);
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.Map.prototype,
|
||||
'setRotation',
|
||||
ol.Map.prototype.setRotation);
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Size} size Size.
|
||||
*/
|
||||
@@ -818,23 +709,15 @@ goog.exportProperty(
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Coordinate} userCenter Center in user projection.
|
||||
* @param {ol.IView} view View.
|
||||
*/
|
||||
ol.Map.prototype.setUserCenter = function(userCenter) {
|
||||
this.setCenter(this.userToMapTransform_(userCenter));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Projection} userProjection User projection.
|
||||
*/
|
||||
ol.Map.prototype.setUserProjection = function(userProjection) {
|
||||
this.set(ol.MapProperty.USER_PROJECTION, userProjection);
|
||||
ol.Map.prototype.setView = function(view) {
|
||||
this.set(ol.MapProperty.VIEW, view);
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.Map.prototype,
|
||||
'setUserProjection',
|
||||
ol.Map.prototype.setUserProjection);
|
||||
'setView',
|
||||
ol.Map.prototype.setView);
|
||||
|
||||
|
||||
/**
|
||||
@@ -863,53 +746,9 @@ ol.Map.prototype.withFrozenRendering = function(f, opt_obj) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {number|undefined} resolution Resolution to go to.
|
||||
* @param {ol.Coordinate=} opt_anchor Anchor coordinate.
|
||||
*/
|
||||
ol.Map.prototype.zoom_ = function(resolution, opt_anchor) {
|
||||
if (goog.isDefAndNotNull(resolution) && goog.isDefAndNotNull(opt_anchor)) {
|
||||
var anchor = opt_anchor;
|
||||
var oldCenter = /** @type {!ol.Coordinate} */ this.getCenter();
|
||||
var oldResolution = this.getResolution();
|
||||
var x = anchor.x - resolution * (anchor.x - oldCenter.x) / oldResolution;
|
||||
var y = anchor.y - resolution * (anchor.y - oldCenter.y) / oldResolution;
|
||||
var center = new ol.Coordinate(x, y);
|
||||
this.withFrozenRendering(function() {
|
||||
this.setCenter(center);
|
||||
this.setResolution(resolution);
|
||||
}, this);
|
||||
} else {
|
||||
this.setResolution(resolution);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} delta Delta from previous zoom level.
|
||||
* @param {ol.Coordinate=} opt_anchor Anchor coordinate.
|
||||
*/
|
||||
ol.Map.prototype.zoom = function(delta, opt_anchor) {
|
||||
var resolution = this.constraints_.resolution(this.getResolution(), delta);
|
||||
this.zoom_(resolution, opt_anchor);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number|undefined} resolution Resolution to go to.
|
||||
* @param {ol.Coordinate=} opt_anchor Anchor coordinate.
|
||||
*/
|
||||
ol.Map.prototype.zoomToResolution = function(resolution, opt_anchor) {
|
||||
resolution = this.constraints_.resolution(resolution, 0);
|
||||
this.zoom_(resolution, opt_anchor);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{controls: ol.Collection,
|
||||
* interactions: ol.Collection,
|
||||
* constraints: ol.Constraints,
|
||||
* rendererConstructor:
|
||||
* function(new: ol.renderer.Map, Element, ol.Map),
|
||||
* target: Element,
|
||||
@@ -929,25 +768,11 @@ ol.Map.createOptionsInternal = function(mapOptions) {
|
||||
*/
|
||||
var values = {};
|
||||
|
||||
if (goog.isDef(mapOptions.center)) {
|
||||
values[ol.MapProperty.CENTER] = mapOptions.center;
|
||||
}
|
||||
|
||||
values[ol.MapProperty.LAYERS] = goog.isDef(mapOptions.layers) ?
|
||||
mapOptions.layers : new ol.Collection();
|
||||
|
||||
values[ol.MapProperty.PROJECTION] = ol.Projection.createProjection(
|
||||
mapOptions.projection, 'EPSG:3857');
|
||||
|
||||
if (goog.isDef(mapOptions.resolution)) {
|
||||
values[ol.MapProperty.RESOLUTION] = mapOptions.resolution;
|
||||
} else if (goog.isDef(mapOptions.zoom)) {
|
||||
values[ol.MapProperty.RESOLUTION] =
|
||||
ol.Projection.EPSG_3857_HALF_SIZE / (128 << mapOptions.zoom);
|
||||
}
|
||||
|
||||
values[ol.MapProperty.USER_PROJECTION] = ol.Projection.createProjection(
|
||||
mapOptions.userProjection, 'EPSG:4326');
|
||||
values[ol.MapProperty.VIEW] = goog.isDef(mapOptions.view) ?
|
||||
mapOptions.view : new ol.View2D();
|
||||
|
||||
/**
|
||||
* @type {function(new: ol.renderer.Map, Element, ol.Map)}
|
||||
@@ -982,11 +807,6 @@ ol.Map.createOptionsInternal = function(mapOptions) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {ol.Constraints}
|
||||
*/
|
||||
var constraints = ol.Map.createConstraints_(mapOptions);
|
||||
|
||||
/**
|
||||
* @type {ol.Collection}
|
||||
*/
|
||||
@@ -1013,7 +833,6 @@ ol.Map.createOptionsInternal = function(mapOptions) {
|
||||
var target = goog.dom.getElement(mapOptions.target);
|
||||
|
||||
return {
|
||||
constraints: constraints,
|
||||
controls: controls,
|
||||
interactions: interactions,
|
||||
rendererConstructor: rendererConstructor,
|
||||
@@ -1024,40 +843,6 @@ ol.Map.createOptionsInternal = function(mapOptions) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {ol.MapOptions} mapOptions Map options.
|
||||
* @return {ol.Constraints} Map constraints.
|
||||
*/
|
||||
ol.Map.createConstraints_ = function(mapOptions) {
|
||||
var resolutionConstraint;
|
||||
if (goog.isDef(mapOptions.resolutions)) {
|
||||
resolutionConstraint = ol.ResolutionConstraint.createSnapToResolutions(
|
||||
mapOptions.resolutions);
|
||||
} else {
|
||||
var maxResolution, numZoomLevels, zoomFactor;
|
||||
if (goog.isDef(mapOptions.maxResolution) &&
|
||||
goog.isDef(mapOptions.numZoomLevels) &&
|
||||
goog.isDef(mapOptions.zoomFactor)) {
|
||||
maxResolution = mapOptions.maxResolution;
|
||||
numZoomLevels = mapOptions.numZoomLevels;
|
||||
zoomFactor = mapOptions.zoomFactor;
|
||||
} else {
|
||||
maxResolution = ol.Projection.EPSG_3857_HALF_SIZE / 128;
|
||||
// number of steps we want between two data resolutions
|
||||
var numSteps = 4;
|
||||
numZoomLevels = 29 * numSteps;
|
||||
zoomFactor = Math.exp(Math.log(2) / numSteps);
|
||||
}
|
||||
resolutionConstraint = ol.ResolutionConstraint.createSnapToPower(
|
||||
zoomFactor, maxResolution, numZoomLevels - 1);
|
||||
}
|
||||
// FIXME rotation constraint is not configurable at the moment
|
||||
var rotationConstraint = ol.RotationConstraint.none;
|
||||
return new ol.Constraints(resolutionConstraint, rotationConstraint);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {ol.MapOptions} mapOptions Map options.
|
||||
@@ -1139,3 +924,20 @@ ol.Map.createInteractions_ = function(mapOptions) {
|
||||
return interactions;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.Uri.QueryData=} opt_queryData Query data.
|
||||
* @return {Array.<ol.RendererHint>} Renderer hints.
|
||||
*/
|
||||
ol.RendererHints.createFromQueryData = function(opt_queryData) {
|
||||
var queryData = goog.isDef(opt_queryData) ?
|
||||
opt_queryData : new goog.Uri.QueryData(goog.global.location.search);
|
||||
if (queryData.containsKey('renderers')) {
|
||||
return queryData.get('renderers').split(',');
|
||||
} else if (queryData.containsKey('renderer')) {
|
||||
return [queryData.get('renderer')];
|
||||
} else {
|
||||
return ol.DEFAULT_RENDERER_HINTS;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -270,7 +270,9 @@ ol.MapBrowserEventHandler.prototype.drag_ = function(browserEvent) {
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
/**
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
ol.MapBrowserEventHandler.prototype.disposeInternal = function() {
|
||||
var element = this.map_.getViewport();
|
||||
goog.events.unlisten(element,
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
goog.provide('ol.MapEvent');
|
||||
goog.provide('ol.MapEventType');
|
||||
|
||||
goog.require('goog.events.Event');
|
||||
goog.require('ol.FrameState');
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
ol.MapEventType = {
|
||||
POSTRENDER: 'postrender'
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -9,8 +19,9 @@ goog.require('goog.events.Event');
|
||||
* @extends {goog.events.Event}
|
||||
* @param {string} type Event type.
|
||||
* @param {ol.Map} map Map.
|
||||
* @param {?ol.FrameState=} opt_frameState Frame state.
|
||||
*/
|
||||
ol.MapEvent = function(type, map) {
|
||||
ol.MapEvent = function(type, map, opt_frameState) {
|
||||
|
||||
goog.base(this, type);
|
||||
|
||||
@@ -24,6 +35,11 @@ ol.MapEvent = function(type, map) {
|
||||
*/
|
||||
this.defaultPrevented = false;
|
||||
|
||||
/**
|
||||
* @type {?ol.FrameState}
|
||||
*/
|
||||
this.frameState = goog.isDef(opt_frameState) ? opt_frameState : null;
|
||||
|
||||
};
|
||||
goog.inherits(ol.MapEvent, goog.events.Event);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
goog.provide('ol.Object');
|
||||
goog.provide('ol.ObjectEventType');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.events');
|
||||
@@ -13,6 +14,14 @@ goog.require('goog.events.EventTarget');
|
||||
goog.require('goog.object');
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
ol.ObjectEventType = {
|
||||
CHANGED: 'changed'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
@@ -192,6 +201,7 @@ ol.Object.prototype.notify = function(key) {
|
||||
ol.Object.prototype.notifyInternal_ = function(key) {
|
||||
var eventType = ol.Object.getChangedEventType(key);
|
||||
this.dispatchEvent(eventType);
|
||||
this.dispatchEvent(ol.ObjectEventType.CHANGED);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -43,7 +43,13 @@ ol.overlay.Overlay = function(overlayOptions) {
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.mapListenerKeys_ = [];
|
||||
this.mapListenerKeys_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.viewListenerKeys_ = null;
|
||||
|
||||
if (goog.isDef(overlayOptions.coordinate)) {
|
||||
this.setCoordinate(overlayOptions.coordinate);
|
||||
@@ -60,6 +66,37 @@ ol.overlay.Overlay = function(overlayOptions) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
ol.overlay.Overlay.prototype.handleViewChanged_ = function() {
|
||||
goog.asserts.assert(!goog.isNull(this.map_));
|
||||
if (!goog.isNull(this.viewListenerKeys_)) {
|
||||
goog.array.forEach(this.viewListenerKeys_, goog.events.unlistenByKey);
|
||||
this.viewListenerKeys_ = null;
|
||||
}
|
||||
var view = this.map_.getView();
|
||||
if (goog.isDefAndNotNull(view)) {
|
||||
// FIXME works for View2D only
|
||||
goog.asserts.assert(view instanceof ol.View2D);
|
||||
this.viewListenerKeys_ = [
|
||||
goog.events.listen(
|
||||
view, ol.Object.getChangedEventType(ol.View2DProperty.CENTER),
|
||||
this.updatePixelPosition_, false, this),
|
||||
|
||||
goog.events.listen(
|
||||
view, ol.Object.getChangedEventType(ol.View2DProperty.RESOLUTION),
|
||||
this.updatePixelPosition_, false, this),
|
||||
|
||||
goog.events.listen(
|
||||
view, ol.Object.getChangedEventType(ol.View2DProperty.ROTATION),
|
||||
this.updatePixelPosition_, false, this)
|
||||
];
|
||||
this.updatePixelPosition_();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Coordinate} coordinate Coordinate for the overlay's position on
|
||||
* the map.
|
||||
@@ -100,25 +137,24 @@ ol.overlay.Overlay.prototype.getElement = function() {
|
||||
*/
|
||||
ol.overlay.Overlay.prototype.setMap = function(map) {
|
||||
this.map_ = map;
|
||||
goog.array.forEach(this.mapListenerKeys_, goog.events.unlistenByKey);
|
||||
if (!goog.isNull(this.mapListenerKeys_)) {
|
||||
goog.array.forEach(this.mapListenerKeys_, goog.events.unlistenByKey);
|
||||
this.mapListenerKeys_ = null;
|
||||
}
|
||||
if (this.element_) {
|
||||
this.setElement(this.element_);
|
||||
}
|
||||
this.mapListenerKeys_ = map ? [
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.CENTER),
|
||||
this.updatePixelPosition_, false, this),
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.RESOLUTION),
|
||||
this.updatePixelPosition_, false, this),
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.ROTATION),
|
||||
this.updatePixelPosition_, false, this),
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.SIZE),
|
||||
this.updatePixelPosition_, false, this)
|
||||
] : [];
|
||||
this.updatePixelPosition_();
|
||||
if (goog.isDefAndNotNull(map)) {
|
||||
this.mapListenerKeys_ = [
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.SIZE),
|
||||
this.updatePixelPosition_, false, this),
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.VIEW),
|
||||
this.handleViewChanged_, false, this)
|
||||
];
|
||||
this.handleViewChanged_();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ ol.Projection.prototype.getUnits = function() {
|
||||
*/
|
||||
ol.Proj4jsProjection = function(code, proj4jsProj) {
|
||||
|
||||
var units = /** @type {ol.ProjectionUnits} */ proj4jsProj.units;
|
||||
var units = /** @type {ol.ProjectionUnits} */ (proj4jsProj.units);
|
||||
|
||||
goog.base(this, code, units, null);
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
goog.provide('ol.renderer.dom.Layer');
|
||||
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.FrameState');
|
||||
goog.require('ol.layer.Layer');
|
||||
goog.require('ol.layer.LayerState');
|
||||
goog.require('ol.renderer.Layer');
|
||||
|
||||
|
||||
@@ -13,6 +16,7 @@ goog.require('ol.renderer.Layer');
|
||||
* @param {!Element} target Target.
|
||||
*/
|
||||
ol.renderer.dom.Layer = function(mapRenderer, layer, target) {
|
||||
|
||||
goog.base(this, mapRenderer, layer);
|
||||
|
||||
/**
|
||||
@@ -21,27 +25,15 @@ ol.renderer.dom.Layer = function(mapRenderer, layer, target) {
|
||||
*/
|
||||
this.target = target;
|
||||
|
||||
/**
|
||||
* Top left corner of the target in map coords.
|
||||
*
|
||||
* @type {ol.Coordinate}
|
||||
* @protected
|
||||
*/
|
||||
this.origin = null;
|
||||
|
||||
this.handleLayerOpacityChange();
|
||||
this.handleLayerVisibleChange();
|
||||
|
||||
};
|
||||
goog.inherits(ol.renderer.dom.Layer, ol.renderer.Layer);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return {ol.renderer.Map} Map renderer.
|
||||
* @return {!Element} Target.
|
||||
*/
|
||||
ol.renderer.dom.Layer.prototype.getMapRenderer = function() {
|
||||
return /** @type {ol.renderer.dom.Map} */ goog.base(this, 'getMapRenderer');
|
||||
ol.renderer.dom.Layer.prototype.getTarget = function() {
|
||||
return this.target;
|
||||
};
|
||||
|
||||
|
||||
@@ -57,7 +49,7 @@ ol.renderer.dom.Layer.prototype.handleLayerLoad = function() {
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.Layer.prototype.handleLayerOpacityChange = function() {
|
||||
goog.style.setOpacity(this.target, this.getLayer().getOpacity());
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
|
||||
@@ -65,22 +57,12 @@ ol.renderer.dom.Layer.prototype.handleLayerOpacityChange = function() {
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.Layer.prototype.handleLayerVisibleChange = function() {
|
||||
goog.style.showElement(this.target, this.getLayer().getVisible());
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Render.
|
||||
* @param {number} time Time.
|
||||
* @param {ol.FrameState} frameState Frame state.
|
||||
* @param {ol.layer.LayerState} layerState Layer state.
|
||||
*/
|
||||
ol.renderer.dom.Layer.prototype.renderFrame = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Set the location of the top left corner of the target.
|
||||
*
|
||||
* @param {ol.Coordinate} origin Origin.
|
||||
*/
|
||||
ol.renderer.dom.Layer.prototype.setOrigin = function(origin) {
|
||||
this.origin = origin;
|
||||
};
|
||||
|
||||
@@ -5,8 +5,9 @@ goog.require('goog.dom');
|
||||
goog.require('goog.dom.TagName');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.Event');
|
||||
goog.require('goog.functions');
|
||||
goog.require('goog.style');
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.FrameState');
|
||||
goog.require('ol.layer.TileLayer');
|
||||
goog.require('ol.renderer.Map');
|
||||
goog.require('ol.renderer.dom.TileLayer');
|
||||
@@ -37,92 +38,32 @@ ol.renderer.dom.Map = function(container, map) {
|
||||
goog.dom.insertChildAt(container, this.layersPane_, 0);
|
||||
|
||||
/**
|
||||
* @type {Object}
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.layerPanes_ = {};
|
||||
this.renderedVisible_ = true;
|
||||
|
||||
/**
|
||||
* @type {ol.Coordinate}
|
||||
* @private
|
||||
*/
|
||||
this.renderedCenter_ = null;
|
||||
|
||||
/**
|
||||
* @type {number | undefined}
|
||||
* @private
|
||||
*/
|
||||
this.renderedResolution_ = undefined;
|
||||
|
||||
/**
|
||||
* @type {ol.Size}
|
||||
* @private
|
||||
*/
|
||||
this.renderedSize_ = null;
|
||||
|
||||
/**
|
||||
* @type {number | undefined}
|
||||
* @private
|
||||
*/
|
||||
this.renderedRotation_ = undefined;
|
||||
|
||||
/**
|
||||
* The origin (top left) of the layers pane in map coordinates.
|
||||
*
|
||||
* @type {ol.Coordinate}
|
||||
* @private
|
||||
*/
|
||||
this.layersPaneOrigin_ = null;
|
||||
};
|
||||
goog.inherits(ol.renderer.dom.Map, ol.renderer.Map);
|
||||
|
||||
|
||||
/**
|
||||
* Apply the given transform to the layers pane.
|
||||
* @param {number} dx Translation along the x-axis.
|
||||
* @param {number} dy Translation along the y-axis.
|
||||
* @param {number} rotation Rotation angle.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.dom.Map.prototype.applyTransform_ = function(dx, dy, rotation) {
|
||||
var transform =
|
||||
'translate(' + Math.round(dx) + 'px, ' + Math.round(dy) + 'px) ' +
|
||||
'rotate(' + rotation.toFixed(6) + 'rad) ' +
|
||||
'scale3d(1, 1, 1)';
|
||||
|
||||
var style = this.layersPane_.style;
|
||||
style.WebkitTransform = transform;
|
||||
style.MozTransform = transform;
|
||||
style.OTransform = transform;
|
||||
style.msTransform = transform;
|
||||
style.transform = transform;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.Map.prototype.canRotate = goog.functions.TRUE;
|
||||
ol.renderer.dom.Map.prototype.addLayer = function(layer) {
|
||||
goog.base(this, 'addLayer', layer);
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.Map.prototype.createLayerRenderer = function(layer) {
|
||||
|
||||
if (layer instanceof ol.layer.TileLayer) {
|
||||
|
||||
var layerPane = goog.dom.createElement(goog.dom.TagName.DIV);
|
||||
layerPane.className = 'ol-layer';
|
||||
layerPane.style.position = 'absolute';
|
||||
goog.dom.appendChild(this.layersPane_, layerPane);
|
||||
|
||||
var layerRenderer = new ol.renderer.dom.TileLayer(this, layer, layerPane);
|
||||
|
||||
this.layerPanes_[goog.getUid(layerRenderer)] = layerPane;
|
||||
|
||||
var layerRenderer = new ol.renderer.dom.TileLayer(this, layer);
|
||||
goog.dom.appendChild(this.layersPane_, layerRenderer.getTarget());
|
||||
return layerRenderer;
|
||||
|
||||
} else {
|
||||
goog.asserts.assert(false);
|
||||
return null;
|
||||
@@ -133,8 +74,8 @@ ol.renderer.dom.Map.prototype.createLayerRenderer = function(layer) {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.Map.prototype.handleCenterChanged = function() {
|
||||
goog.base(this, 'handleCenterChanged');
|
||||
ol.renderer.dom.Map.prototype.removeLayer = function(layer) {
|
||||
goog.base(this, 'removeLayer', layer);
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
@@ -142,145 +83,30 @@ ol.renderer.dom.Map.prototype.handleCenterChanged = function() {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.Map.prototype.handleResolutionChanged = function() {
|
||||
goog.base(this, 'handleResolutionChanged');
|
||||
this.getMap().render();
|
||||
};
|
||||
ol.renderer.dom.Map.prototype.renderFrame = function(frameState) {
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.Map.prototype.handleRotationChanged = function() {
|
||||
goog.base(this, 'handleRotationChanged');
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.Map.prototype.handleSizeChanged = function() {
|
||||
goog.base(this, 'handleSizeChanged');
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Render the map. Sets up the layers pane on first render and adjusts its
|
||||
* position as needed on subsequent calls.
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.Map.prototype.renderFrame = function(time) {
|
||||
var map = this.getMap();
|
||||
if (!map.isDef()) {
|
||||
if (goog.isNull(frameState)) {
|
||||
if (this.renderedVisible_) {
|
||||
goog.style.showElement(this.layersPane_, false);
|
||||
this.renderedVisible_ = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var mapCenter = map.getCenter();
|
||||
var mapSize = map.getSize();
|
||||
var mapResolution = map.getResolution();
|
||||
var mapRotation = map.getRotation();
|
||||
|
||||
goog.asserts.assert(goog.isDefAndNotNull(mapCenter));
|
||||
goog.asserts.assert(goog.isDef(mapResolution));
|
||||
goog.asserts.assert(goog.isDef(mapRotation));
|
||||
goog.asserts.assert(goog.isDefAndNotNull(mapSize));
|
||||
|
||||
if (goog.isNull(this.renderedCenter_)) {
|
||||
// first rendering
|
||||
goog.asserts.assert(!goog.isDef(this.renderedResolution_));
|
||||
goog.asserts.assert(!goog.isDef(this.renderedRotation_));
|
||||
goog.asserts.assert(goog.isNull(this.renderedSize_));
|
||||
this.resetLayersPane_();
|
||||
} else {
|
||||
goog.asserts.assert(goog.isDef(this.renderedResolution_));
|
||||
goog.asserts.assert(!goog.isNull(this.renderedSize_));
|
||||
if (mapResolution !== this.renderedResolution_ ||
|
||||
!mapSize.equals(this.renderedSize_)) {
|
||||
// resolution or size changed, adjust layers pane
|
||||
this.resetLayersPane_();
|
||||
} else if (!mapCenter.equals(this.renderedCenter_) ||
|
||||
mapRotation !== this.renderedRotation_) {
|
||||
// same resolution and size, new center or rotation
|
||||
this.transformLayersPane_();
|
||||
goog.array.forEach(frameState.layersArray, function(layer) {
|
||||
var layerState = frameState.layerStates[goog.getUid(layer)];
|
||||
if (!layerState.ready) {
|
||||
return;
|
||||
}
|
||||
var layerRenderer = this.getLayerRenderer(layer);
|
||||
layerRenderer.renderFrame(frameState, layerState);
|
||||
}, this);
|
||||
|
||||
if (!this.renderedVisible_) {
|
||||
goog.style.showElement(this.layersPane_, true);
|
||||
this.renderedVisible_ = true;
|
||||
}
|
||||
|
||||
this.renderedCenter_ = mapCenter;
|
||||
this.renderedResolution_ = mapResolution;
|
||||
this.renderedRotation_ = mapRotation;
|
||||
this.renderedSize_ = mapSize;
|
||||
|
||||
var requestRenderFrame = false;
|
||||
this.forEachReadyVisibleLayer(function(layer, layerRenderer) {
|
||||
if (layerRenderer.renderFrame(time)) {
|
||||
requestRenderFrame = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (requestRenderFrame) {
|
||||
map.requestRenderFrame();
|
||||
}
|
||||
this.calculateMatrices2D(frameState);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reset the layers pane to its initial position.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.dom.Map.prototype.resetLayersPane_ = function() {
|
||||
var map = this.map;
|
||||
var mapSize = map.getSize();
|
||||
var halfWidth = mapSize.width / 2;
|
||||
var halfHeight = mapSize.height / 2;
|
||||
var center = map.getCenter();
|
||||
var resolution = map.getResolution();
|
||||
var origin = new ol.Coordinate(
|
||||
center.x - resolution * halfWidth,
|
||||
center.y + resolution * halfHeight);
|
||||
this.layersPaneOrigin_ = origin;
|
||||
this.setTransformOrigin_(halfWidth, halfHeight);
|
||||
this.applyTransform_(0, 0, map.getRotation());
|
||||
goog.object.forEach(this.layerRenderers, function(layerRenderer) {
|
||||
layerRenderer.setOrigin(origin);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the transform-origin CSS property of the layers pane.
|
||||
* @param {number} x The x-axis origin.
|
||||
* @param {number} y The y-axis origin.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.dom.Map.prototype.setTransformOrigin_ = function(x, y) {
|
||||
var origin = Math.round(x) + 'px ' + Math.round(y) + 'px';
|
||||
var style = this.layersPane_.style;
|
||||
style.WebkitTransformOrigin = origin;
|
||||
style.MozTransformOrigin = origin;
|
||||
style.OTransformOrigin = origin;
|
||||
style.msTransformOrigin = origin;
|
||||
style.transformOrigin = origin;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Apply the appropriate transform to the layers pane.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.dom.Map.prototype.transformLayersPane_ = function() {
|
||||
var map = this.map;
|
||||
var resolution = map.getResolution();
|
||||
var center = map.getCenter();
|
||||
var size = map.getSize();
|
||||
var origin = this.layersPaneOrigin_;
|
||||
var ox = (center.x - origin.x) / resolution;
|
||||
var oy = (origin.y - center.y) / resolution;
|
||||
this.setTransformOrigin_(ox, oy);
|
||||
var dx = ox - (size.width / 2);
|
||||
var dy = oy - (size.height / 2);
|
||||
this.applyTransform_(-dx, -dy, map.getRotation());
|
||||
};
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
// 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('goog.asserts');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.Event');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.math.Vec2');
|
||||
goog.require('goog.style');
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.Size');
|
||||
goog.require('ol.TileCoord');
|
||||
goog.require('ol.TileRange');
|
||||
goog.require('ol.TileState');
|
||||
goog.require('ol.ViewHint');
|
||||
goog.require('ol.dom');
|
||||
goog.require('ol.renderer.dom.Layer');
|
||||
goog.require('ol.tilegrid.TileGrid');
|
||||
|
||||
|
||||
|
||||
@@ -16,212 +26,363 @@ goog.require('ol.renderer.dom.Layer');
|
||||
* @extends {ol.renderer.dom.Layer}
|
||||
* @param {ol.renderer.Map} mapRenderer Map renderer.
|
||||
* @param {ol.layer.TileLayer} tileLayer Tile layer.
|
||||
* @param {!Element} target Target.
|
||||
*/
|
||||
ol.renderer.dom.TileLayer = function(mapRenderer, tileLayer, target) {
|
||||
ol.renderer.dom.TileLayer = function(mapRenderer, tileLayer) {
|
||||
|
||||
var target = goog.dom.createElement(goog.dom.TagName.DIV);
|
||||
target.className = 'ol-layer';
|
||||
target.style.position = 'absolute';
|
||||
|
||||
goog.base(this, mapRenderer, tileLayer, target);
|
||||
|
||||
/**
|
||||
* @type {Object}
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.renderedTiles_ = {};
|
||||
this.renderedVisible_ = true;
|
||||
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.renderedMapResolution_ = undefined;
|
||||
this.renderedOpacity_ = 1;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<number, ol.renderer.dom.TileLayerZ_>}
|
||||
*/
|
||||
this.tileLayerZs_ = {};
|
||||
|
||||
};
|
||||
goog.inherits(ol.renderer.dom.TileLayer, ol.renderer.dom.Layer);
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.layer.TileLayer} Tile layer.
|
||||
*/
|
||||
ol.renderer.dom.TileLayer.prototype.getTileLayer = function() {
|
||||
return /** @type {ol.layer.TileLayer} */ (this.getLayer());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return {ol.layer.TileLayer} Layer.
|
||||
*/
|
||||
ol.renderer.dom.TileLayer.prototype.getLayer = function() {
|
||||
return /** @type {ol.layer.TileLayer} */ goog.base(this, 'getLayer');
|
||||
};
|
||||
ol.renderer.dom.TileLayer.prototype.renderFrame =
|
||||
function(frameState, layerState) {
|
||||
|
||||
|
||||
/**
|
||||
* Get the pixel offset between the tile origin and the container origin.
|
||||
* @private
|
||||
* @param {number} z Z.
|
||||
* @param {number} resolution Resolution.
|
||||
* @return {ol.Coordinate} Offset.
|
||||
*/
|
||||
ol.renderer.dom.TileLayer.prototype.getTileOffset_ = function(z, resolution) {
|
||||
var tileLayer = this.getLayer();
|
||||
var tileSource = tileLayer.getTileSource();
|
||||
var tileGrid = tileSource.getTileGrid();
|
||||
var tileOrigin = tileGrid.getOrigin(z);
|
||||
var offset = new ol.Coordinate(
|
||||
Math.round((this.origin.x - tileOrigin.x) / resolution),
|
||||
Math.round((tileOrigin.y - this.origin.y) / resolution));
|
||||
return offset;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get rid of all tiles that weren't drawn in the most recent rendering.
|
||||
* @param {Object.<number, Object.<string, ol.Tile>>} tilesDrawnByZ Tiles just
|
||||
* rendered.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.dom.TileLayer.prototype.removeExtraTiles_ =
|
||||
function(tilesDrawnByZ) {
|
||||
var key, tileCoord, tilesDrawn, tile;
|
||||
for (key in this.renderedTiles_) {
|
||||
tileCoord = ol.TileCoord.createFromString(key);
|
||||
tilesDrawn = tilesDrawnByZ[tileCoord.z];
|
||||
if (!(tilesDrawn && key in tilesDrawn)) {
|
||||
tile = this.renderedTiles_[key];
|
||||
delete this.renderedTiles_[key];
|
||||
goog.dom.removeNode(tile.getImage(this));
|
||||
if (!layerState.visible) {
|
||||
if (this.renderedVisible_) {
|
||||
goog.style.showElement(this.target, false);
|
||||
this.renderedVisible_ = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.TileLayer.prototype.renderFrame = function(time) {
|
||||
|
||||
var map = this.getMap();
|
||||
if (!map.isDef()) {
|
||||
return;
|
||||
}
|
||||
var mapExtent = /** @type {!ol.Extent} */ map.getRotatedExtent();
|
||||
var mapResolution = /** @type {number} */ map.getResolution();
|
||||
var resolutionChanged = (mapResolution !== this.renderedMapResolution_);
|
||||
|
||||
var tileLayer = this.getLayer();
|
||||
var view2DState = frameState.view2DState;
|
||||
|
||||
var tileLayer = this.getTileLayer();
|
||||
var tileSource = tileLayer.getTileSource();
|
||||
var tileGrid = tileSource.getTileGrid();
|
||||
var z = tileGrid.getZForResolution(view2DState.resolution);
|
||||
var tileResolution = tileGrid.getResolution(z);
|
||||
var tileRange = tileGrid.getTileRangeForExtentAndResolution(
|
||||
frameState.extent, tileResolution);
|
||||
|
||||
// z represents the "best" resolution
|
||||
var z = tileGrid.getZForResolution(mapResolution);
|
||||
|
||||
/**
|
||||
* @type {Object.<number, Object.<string, ol.Tile>>}
|
||||
*/
|
||||
/** @type {Object.<number, Object.<string, ol.Tile>>} */
|
||||
var tilesToDrawByZ = {};
|
||||
tilesToDrawByZ[z] = {};
|
||||
|
||||
var tileRange =
|
||||
tileGrid.getTileRangeForExtentAndResolution(mapExtent, mapResolution);
|
||||
var findInterimTiles = function(z, tileRange) {
|
||||
// FIXME this could be more efficient about filling partial holes
|
||||
var fullyCovered = true;
|
||||
var tile, tileCoord, tileCoordKey, x, y;
|
||||
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||
tileCoord = new ol.TileCoord(z, x, y);
|
||||
tileCoordKey = tileCoord.toString();
|
||||
if (tilesToDrawByZ[z] && tilesToDrawByZ[z][tileCoordKey]) {
|
||||
return;
|
||||
}
|
||||
tile = tileSource.getTile(tileCoord);
|
||||
if (!goog.isNull(tile) && tile.getState() == ol.TileState.LOADED) {
|
||||
if (!tilesToDrawByZ[z]) {
|
||||
tilesToDrawByZ[z] = {};
|
||||
}
|
||||
tilesToDrawByZ[z][tileCoordKey] = tile;
|
||||
} else {
|
||||
fullyCovered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return fullyCovered;
|
||||
};
|
||||
|
||||
var allTilesLoaded = true;
|
||||
var tile, tileCenter, tileCoord, tileState, x, y;
|
||||
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||
|
||||
tileCoord = new ol.TileCoord(z, x, y);
|
||||
tile = tileSource.getTile(tileCoord);
|
||||
if (goog.isNull(tile)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tileState = tile.getState();
|
||||
if (tileState == ol.TileState.IDLE) {
|
||||
tileCenter = tileGrid.getTileCoordCenter(tileCoord);
|
||||
frameState.tileQueue.enqueue(tile, tileCenter, tileResolution);
|
||||
} else if (tileState == ol.TileState.LOADED) {
|
||||
tilesToDrawByZ[z][tileCoord.toString()] = tile;
|
||||
continue;
|
||||
} else if (tileState == ol.TileState.ERROR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
allTilesLoaded = false;
|
||||
tileGrid.forEachTileCoordParentTileRange(tileCoord, findInterimTiles);
|
||||
|
||||
// first pass through the tile range to determine all the tiles needed
|
||||
tileRange.forEachTileCoord(z, function(tileCoord) {
|
||||
var tile = tileSource.getTile(tileCoord);
|
||||
if (goog.isNull(tile)) {
|
||||
// we're outside the source's extent, continue
|
||||
return;
|
||||
}
|
||||
|
||||
var key = tile.tileCoord.toString();
|
||||
var state = tile.getState();
|
||||
if (state == ol.TileState.IDLE) {
|
||||
tile.load();
|
||||
} else if (state == ol.TileState.LOADED) {
|
||||
tilesToDrawByZ[z][key] = tile;
|
||||
return;
|
||||
}
|
||||
|
||||
allTilesLoaded = false;
|
||||
|
||||
/**
|
||||
* Look for already loaded tiles at alternate z that can serve as
|
||||
* placeholders until tiles at the current z have loaded.
|
||||
*
|
||||
* TODO: make this more efficent for filling partial holes
|
||||
*/
|
||||
tileGrid.forEachTileCoordParentTileRange(
|
||||
tileCoord,
|
||||
function(altZ, altTileRange) {
|
||||
var fullyCovered = true;
|
||||
altTileRange.forEachTileCoord(altZ, function(altTileCoord) {
|
||||
var tileKey = altTileCoord.toString();
|
||||
if (tilesToDrawByZ[altZ] && tilesToDrawByZ[altZ][tileKey]) {
|
||||
return;
|
||||
}
|
||||
var altTile = tileSource.getTile(altTileCoord);
|
||||
if (!goog.isNull(altTile) &&
|
||||
altTile.getState() == ol.TileState.LOADED) {
|
||||
if (!(altZ in tilesToDrawByZ)) {
|
||||
tilesToDrawByZ[altZ] = {};
|
||||
}
|
||||
tilesToDrawByZ[altZ][tileKey] = altTile;
|
||||
} else {
|
||||
fullyCovered = false;
|
||||
}
|
||||
});
|
||||
return fullyCovered;
|
||||
});
|
||||
|
||||
}, this);
|
||||
}
|
||||
|
||||
/** @type {Array.<number>} */
|
||||
var zs = goog.array.map(goog.object.getKeys(tilesToDrawByZ), Number);
|
||||
goog.array.sort(zs);
|
||||
|
||||
var fragment = document.createDocumentFragment();
|
||||
var altFragment = document.createDocumentFragment();
|
||||
var newTiles = false;
|
||||
var newAltTiles = false;
|
||||
for (var i = 0, ii = zs.length; i < ii; ++i) {
|
||||
var tileZ = zs[i];
|
||||
var tilesToDraw = tilesToDrawByZ[tileZ];
|
||||
var tileOffset = this.getTileOffset_(tileZ, mapResolution);
|
||||
for (var key in tilesToDraw) {
|
||||
var tile = tilesToDraw[key];
|
||||
var tileCoord = tile.tileCoord;
|
||||
var pixelBounds = tileGrid.getPixelBoundsForTileCoordAndResolution(
|
||||
tileCoord, mapResolution);
|
||||
var img = tile.getImage(this);
|
||||
var style = img.style;
|
||||
var append = !(key in this.renderedTiles_);
|
||||
if (append || resolutionChanged) {
|
||||
style.left = (pixelBounds.minX - tileOffset.x) + 'px';
|
||||
style.top = (-pixelBounds.maxY - tileOffset.y) + 'px';
|
||||
style.width = pixelBounds.getWidth() + 'px';
|
||||
style.height = pixelBounds.getHeight() + 'px';
|
||||
}
|
||||
if (append) {
|
||||
this.renderedTiles_[key] = tile;
|
||||
style.position = 'absolute';
|
||||
if (tileZ === z) {
|
||||
goog.dom.appendChild(fragment, img);
|
||||
newTiles = true;
|
||||
} else {
|
||||
goog.dom.appendChild(altFragment, img);
|
||||
newAltTiles = true;
|
||||
/** @type {Object.<number, boolean>} */
|
||||
var newTileLayerZKeys = {};
|
||||
|
||||
var tileSize = tileGrid.getTileSize();
|
||||
var iz, tileCoordKey, tileCoordOrigin, tileLayerZ, tileLayerZKey, tilesToDraw;
|
||||
for (iz = 0; iz < zs.length; ++iz) {
|
||||
tileLayerZKey = zs[iz];
|
||||
if (tileLayerZKey in this.tileLayerZs_) {
|
||||
tileLayerZ = this.tileLayerZs_[tileLayerZKey];
|
||||
} else {
|
||||
tileCoordOrigin =
|
||||
tileGrid.getTileCoordForCoordAndZ(view2DState.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]);
|
||||
}
|
||||
tileLayerZ.finalizeAddTiles();
|
||||
}
|
||||
|
||||
/** @type {Array.<number>} */
|
||||
var tileLayerZKeys =
|
||||
goog.array.map(goog.object.getKeys(this.tileLayerZs_), Number);
|
||||
goog.array.sort(tileLayerZKeys);
|
||||
|
||||
var i, j, origin, resolution;
|
||||
var transform = goog.vec.Mat4.createNumber();
|
||||
for (i = 0; i < tileLayerZKeys.length; ++i) {
|
||||
tileLayerZKey = tileLayerZKeys[i];
|
||||
tileLayerZ = this.tileLayerZs_[tileLayerZKey];
|
||||
if (!(tileLayerZKey in tilesToDrawByZ)) {
|
||||
goog.dom.removeNode(tileLayerZ.target);
|
||||
delete this.tileLayerZs_[tileLayerZKey];
|
||||
continue;
|
||||
}
|
||||
resolution = tileLayerZ.getResolution();
|
||||
origin = tileLayerZ.getOrigin();
|
||||
goog.vec.Mat4.makeIdentity(transform);
|
||||
goog.vec.Mat4.translate(
|
||||
transform, frameState.size.width / 2, frameState.size.height / 2, 0);
|
||||
goog.vec.Mat4.rotateZ(transform, view2DState.rotation);
|
||||
goog.vec.Mat4.scale(transform, resolution / view2DState.resolution,
|
||||
resolution / view2DState.resolution, 1);
|
||||
goog.vec.Mat4.translate(
|
||||
transform,
|
||||
(origin.x - view2DState.center.x) / resolution,
|
||||
(view2DState.center.y - origin.y) / resolution,
|
||||
0);
|
||||
tileLayerZ.setTransform(transform);
|
||||
if (tileLayerZKey in newTileLayerZKeys) {
|
||||
for (j = tileLayerZKey - 1; j >= 0; --j) {
|
||||
if (j in this.tileLayerZs_) {
|
||||
goog.dom.insertSiblingAfter(
|
||||
tileLayerZ.target, this.tileLayerZs_[j].target);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newAltTiles) {
|
||||
var child = this.target.firstChild;
|
||||
if (child) {
|
||||
goog.dom.insertSiblingBefore(altFragment, child);
|
||||
if (j < 0) {
|
||||
goog.dom.insertChildAt(this.target, tileLayerZ.target, 0);
|
||||
}
|
||||
} else {
|
||||
goog.dom.appendChild(this.target, altFragment);
|
||||
if (!frameState.viewHints[ol.ViewHint.ANIMATING] &&
|
||||
!frameState.viewHints[ol.ViewHint.PANNING]) {
|
||||
tileLayerZ.removeTilesOutsideExtent(frameState.extent);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (newTiles) {
|
||||
goog.dom.appendChild(this.target, fragment);
|
||||
|
||||
if (layerState.opacity != this.renderedOpacity_) {
|
||||
goog.style.setOpacity(this.target, layerState.opacity);
|
||||
this.renderedOpacity_ = layerState.opacity;
|
||||
}
|
||||
|
||||
this.renderedMapResolution_ = mapResolution;
|
||||
if (layerState.visible && !this.renderedVisible_) {
|
||||
goog.style.showElement(this.target, true);
|
||||
this.renderedVisible_ = true;
|
||||
}
|
||||
|
||||
this.removeExtraTiles_(tilesToDrawByZ);
|
||||
if (!allTilesLoaded) {
|
||||
frameState.animate = true;
|
||||
}
|
||||
|
||||
return !allTilesLoaded;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @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 = goog.dom.createElement(goog.dom.TagName.DIV);
|
||||
this.target.style.position = 'absolute';
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.tilegrid.TileGrid}
|
||||
*/
|
||||
this.tileGrid_ = tileGrid;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.TileCoord}
|
||||
*/
|
||||
this.tileCoordOrigin_ = tileCoordOrigin;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Coordinate}
|
||||
*/
|
||||
this.origin_ = tileGrid.getTileCoordExtent(tileCoordOrigin).getTopLeft();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.resolution_ = tileGrid.getResolution(tileCoordOrigin.z);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, ol.Tile>}
|
||||
*/
|
||||
this.tiles_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {DocumentFragment}
|
||||
*/
|
||||
this.documentFragment_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {goog.vec.Mat4.AnyType}
|
||||
*/
|
||||
this.transform_ = goog.vec.Mat4.createNumberIdentity();
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Tile} tile Tile.
|
||||
*/
|
||||
ol.renderer.dom.TileLayerZ_.prototype.addTile = function(tile) {
|
||||
var tileCoord = tile.tileCoord;
|
||||
goog.asserts.assert(tileCoord.z == this.tileCoordOrigin_.z);
|
||||
var tileCoordKey = tileCoord.toString();
|
||||
if (tileCoordKey in this.tiles_) {
|
||||
return;
|
||||
}
|
||||
var tileSize = this.tileGrid_.getTileSize();
|
||||
var image = tile.getImage(this);
|
||||
var style = image.style;
|
||||
style.position = 'absolute';
|
||||
style.left =
|
||||
((tileCoord.x - this.tileCoordOrigin_.x) * tileSize.width) + 'px';
|
||||
style.top =
|
||||
((this.tileCoordOrigin_.y - tileCoord.y) * tileSize.height) + 'px';
|
||||
if (goog.isNull(this.documentFragment_)) {
|
||||
this.documentFragment_ = document.createDocumentFragment();
|
||||
}
|
||||
goog.dom.appendChild(this.documentFragment_, image);
|
||||
this.tiles_[tileCoordKey] = tile;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
ol.renderer.dom.TileLayerZ_.prototype.finalizeAddTiles = function() {
|
||||
if (!goog.isNull(this.documentFragment_)) {
|
||||
goog.dom.appendChild(this.target, 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.
|
||||
*/
|
||||
ol.renderer.dom.TileLayerZ_.prototype.removeTilesOutsideExtent =
|
||||
function(extent) {
|
||||
var tileRange =
|
||||
this.tileGrid_.getTileRangeForExtentAndZ(extent, this.tileCoordOrigin_.z);
|
||||
var tilesToRemove = [];
|
||||
var tile, tileCoordKey;
|
||||
for (tileCoordKey in this.tiles_) {
|
||||
tile = this.tiles_[tileCoordKey];
|
||||
if (!tileRange.contains(tile.tileCoord)) {
|
||||
tilesToRemove.push(tile);
|
||||
}
|
||||
}
|
||||
var i;
|
||||
for (i = 0; i < tilesToRemove.length; ++i) {
|
||||
tile = tilesToRemove[i];
|
||||
tileCoordKey = tile.tileCoord.toString();
|
||||
goog.dom.removeNode(tile.getImage(this));
|
||||
delete this.tiles_[tileCoordKey];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.vec.Mat4.AnyType} transform Transform.
|
||||
*/
|
||||
ol.renderer.dom.TileLayerZ_.prototype.setTransform = function(transform) {
|
||||
if (!goog.vec.Mat4.equals(transform, this.transform_)) {
|
||||
ol.dom.transformElement2D(this.target, transform, 6);
|
||||
goog.vec.Mat4.setFromArray(this.transform_, transform);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
goog.provide('ol.renderer.Map');
|
||||
|
||||
goog.require('goog.Disposable');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.functions');
|
||||
goog.require('goog.fx.anim');
|
||||
goog.require('goog.fx.anim.Animated');
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.FrameState');
|
||||
goog.require('ol.View2D');
|
||||
goog.require('ol.View2DProperty');
|
||||
|
||||
|
||||
|
||||
@@ -43,23 +47,12 @@ ol.renderer.Map = function(container, map) {
|
||||
*/
|
||||
this.layersListenerKeys_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {goog.vec.Mat4.Number}
|
||||
*/
|
||||
this.coordinateToPixelMatrix_ = goog.vec.Mat4.createNumber();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {goog.vec.Mat4.Number}
|
||||
* @type {?number}
|
||||
*/
|
||||
this.pixelToCoordinateMatrix_ = goog.vec.Mat4.createNumber();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.matricesDirty_ = true;
|
||||
this.viewPropertyListenerKey_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -70,25 +63,17 @@ ol.renderer.Map = function(container, map) {
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.BACKGROUND_COLOR),
|
||||
this.handleBackgroundColorChanged, false, this),
|
||||
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.CENTER),
|
||||
this.handleCenterChanged, false, this),
|
||||
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.LAYERS),
|
||||
this.handleLayersChanged, false, this),
|
||||
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.RESOLUTION),
|
||||
this.handleResolutionChanged, false, this),
|
||||
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.ROTATION),
|
||||
this.handleRotationChanged, false, this),
|
||||
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.SIZE),
|
||||
this.handleSizeChanged, false, this)
|
||||
this.handleSizeChanged, false, this),
|
||||
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.VIEW),
|
||||
this.handleViewChanged, false, this)
|
||||
];
|
||||
|
||||
};
|
||||
@@ -106,9 +91,35 @@ ol.renderer.Map.prototype.addLayer = function(layer) {
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Can rotate.
|
||||
* @param {ol.FrameState} frameState FrameState.
|
||||
* @protected
|
||||
*/
|
||||
ol.renderer.Map.prototype.canRotate = goog.functions.FALSE;
|
||||
ol.renderer.Map.prototype.calculateMatrices2D = function(frameState) {
|
||||
|
||||
var view2DState = frameState.view2DState;
|
||||
var coordinateToPixelMatrix = frameState.coordinateToPixelMatrix;
|
||||
|
||||
goog.vec.Mat4.makeIdentity(coordinateToPixelMatrix);
|
||||
goog.vec.Mat4.translate(coordinateToPixelMatrix,
|
||||
frameState.size.width / 2,
|
||||
frameState.size.height / 2,
|
||||
0);
|
||||
goog.vec.Mat4.scale(coordinateToPixelMatrix,
|
||||
1 / view2DState.resolution,
|
||||
-1 / view2DState.resolution,
|
||||
1);
|
||||
goog.vec.Mat4.rotateZ(coordinateToPixelMatrix,
|
||||
-view2DState.rotation);
|
||||
goog.vec.Mat4.translate(coordinateToPixelMatrix,
|
||||
-view2DState.center.x,
|
||||
-view2DState.center.y,
|
||||
0);
|
||||
|
||||
var inverted = goog.vec.Mat4.invert(
|
||||
coordinateToPixelMatrix, frameState.pixelToCoordinateMatrix);
|
||||
goog.asserts.assert(inverted);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@@ -127,6 +138,9 @@ ol.renderer.Map.prototype.disposeInternal = function() {
|
||||
goog.dispose(layerRenderer);
|
||||
});
|
||||
goog.array.forEach(this.mapListenerKeys_, goog.events.unlistenByKey);
|
||||
if (!goog.isNull(this.viewPropertyListenerKey_)) {
|
||||
goog.events.unlistenByKey(this.viewPropertyListenerKey_);
|
||||
}
|
||||
if (!goog.isNull(this.layersListenerKeys_)) {
|
||||
goog.array.forEach(this.layersListenerKeys_, goog.events.unlistenByKey);
|
||||
}
|
||||
@@ -134,37 +148,6 @@ ol.renderer.Map.prototype.disposeInternal = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {function(this: T, ol.layer.Layer, ol.renderer.Layer, number)} f
|
||||
* Function.
|
||||
* @param {T=} opt_obj Object.
|
||||
* @template T
|
||||
*/
|
||||
ol.renderer.Map.prototype.forEachReadyVisibleLayer = function(f, opt_obj) {
|
||||
var layers = this.map.getLayers();
|
||||
if (goog.isDef(layers)) {
|
||||
layers.forEach(function(layer, index) {
|
||||
if (layer.isReady() && layer.getVisible()) {
|
||||
var layerRenderer = this.getLayerRenderer(layer);
|
||||
f.call(opt_obj, layer, layerRenderer, index);
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Pixel} pixel Pixel.
|
||||
* @return {ol.Coordinate} Coordinate.
|
||||
*/
|
||||
ol.renderer.Map.prototype.getCoordinateFromPixel = function(pixel) {
|
||||
this.updateMatrices_();
|
||||
var vec3 = [pixel.x, pixel.y, 0];
|
||||
goog.vec.Mat4.multVec3(this.pixelToCoordinateMatrix_, vec3, vec3);
|
||||
return new ol.Coordinate(vec3[0], vec3[1]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.layer.Layer} layer Layer.
|
||||
* @protected
|
||||
@@ -186,38 +169,18 @@ ol.renderer.Map.prototype.getMap = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Coordinate} coordinate Coordinate.
|
||||
* @return {ol.Pixel} Pixel.
|
||||
*/
|
||||
ol.renderer.Map.prototype.getPixelFromCoordinate = function(coordinate) {
|
||||
this.updateMatrices_();
|
||||
var vec3 = [coordinate.x, coordinate.y, 0];
|
||||
goog.vec.Mat4.multVec3(this.coordinateToPixelMatrix_, vec3, vec3);
|
||||
return new ol.Pixel(vec3[0], vec3[1]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handle background color changed.
|
||||
*/
|
||||
ol.renderer.Map.prototype.handleBackgroundColorChanged = goog.nullFunction;
|
||||
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
ol.renderer.Map.prototype.handleCenterChanged = function() {
|
||||
this.matricesDirty_ = true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.CollectionEvent} collectionEvent Collection event.
|
||||
* @protected
|
||||
*/
|
||||
ol.renderer.Map.prototype.handleLayersAdd = function(collectionEvent) {
|
||||
var layer = /** @type {ol.layer.Layer} */ collectionEvent.elem;
|
||||
var layer = /** @type {ol.layer.Layer} */ (collectionEvent.elem);
|
||||
this.addLayer(layer);
|
||||
};
|
||||
|
||||
@@ -226,10 +189,7 @@ ol.renderer.Map.prototype.handleLayersAdd = function(collectionEvent) {
|
||||
* @protected
|
||||
*/
|
||||
ol.renderer.Map.prototype.handleLayersChanged = function() {
|
||||
var layerRenderers = goog.object.getValues(this.layerRenderers);
|
||||
goog.array.forEach(layerRenderers, function(layerRenderer) {
|
||||
this.removeLayerRenderer(layerRenderer);
|
||||
}, this);
|
||||
goog.disposeAll(goog.object.getValues(this.layerRenderers));
|
||||
this.layerRenderers = {};
|
||||
if (!goog.isNull(this.layersListenerKeys_)) {
|
||||
goog.array.forEach(this.layersListenerKeys_, goog.events.unlistenByKey);
|
||||
@@ -253,7 +213,7 @@ ol.renderer.Map.prototype.handleLayersChanged = function() {
|
||||
* @protected
|
||||
*/
|
||||
ol.renderer.Map.prototype.handleLayersRemove = function(collectionEvent) {
|
||||
var layer = /** @type {ol.layer.Layer} */ collectionEvent.elem;
|
||||
var layer = /** @type {ol.layer.Layer} */ (collectionEvent.elem);
|
||||
this.removeLayer(layer);
|
||||
};
|
||||
|
||||
@@ -261,16 +221,8 @@ ol.renderer.Map.prototype.handleLayersRemove = function(collectionEvent) {
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
ol.renderer.Map.prototype.handleResolutionChanged = function() {
|
||||
this.matricesDirty_ = true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
ol.renderer.Map.prototype.handleRotationChanged = function() {
|
||||
this.matricesDirty_ = true;
|
||||
ol.renderer.Map.prototype.handleViewPropertyChanged = function() {
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
|
||||
@@ -278,7 +230,25 @@ ol.renderer.Map.prototype.handleRotationChanged = function() {
|
||||
* @protected
|
||||
*/
|
||||
ol.renderer.Map.prototype.handleSizeChanged = function() {
|
||||
this.matricesDirty_ = true;
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
ol.renderer.Map.prototype.handleViewChanged = function() {
|
||||
if (!goog.isNull(this.viewPropertyListenerKey_)) {
|
||||
goog.events.unlistenByKey(this.viewPropertyListenerKey_);
|
||||
this.viewPropertyListenerKey_ = null;
|
||||
}
|
||||
var view = this.getMap().getView();
|
||||
if (goog.isDefAndNotNull(view)) {
|
||||
this.viewPropertyListenerKey_ = goog.events.listen(
|
||||
view, ol.ObjectEventType.CHANGED,
|
||||
this.handleViewPropertyChanged, false, this);
|
||||
}
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
|
||||
@@ -310,9 +280,9 @@ ol.renderer.Map.prototype.removeLayerRenderer = function(layer) {
|
||||
|
||||
/**
|
||||
* Render.
|
||||
* @param {number} time Time.
|
||||
* @param {?ol.FrameState} frameState Frame state.
|
||||
*/
|
||||
ol.renderer.Map.prototype.renderFrame = goog.functions.FALSE;
|
||||
ol.renderer.Map.prototype.renderFrame = goog.nullFunction;
|
||||
|
||||
|
||||
/**
|
||||
@@ -325,44 +295,3 @@ ol.renderer.Map.prototype.setLayerRenderer = function(layer, layerRenderer) {
|
||||
goog.asserts.assert(!(key in this.layerRenderers));
|
||||
this.layerRenderers[key] = layerRenderer;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.Map.prototype.updateMatrices_ = function() {
|
||||
|
||||
if (this.matricesDirty_) {
|
||||
|
||||
var map = this.map;
|
||||
var center = /** @type {!ol.Coordinate} */ map.getCenter();
|
||||
var resolution = /** @type {number} */ map.getResolution();
|
||||
var rotation = map.getRotation();
|
||||
var size = /** @type {!ol.Size} */ map.getSize();
|
||||
|
||||
goog.vec.Mat4.makeIdentity(this.coordinateToPixelMatrix_);
|
||||
goog.vec.Mat4.translate(this.coordinateToPixelMatrix_,
|
||||
size.width / 2,
|
||||
size.height / 2,
|
||||
0);
|
||||
goog.vec.Mat4.scale(this.coordinateToPixelMatrix_,
|
||||
1 / resolution,
|
||||
-1 / resolution,
|
||||
1);
|
||||
if (this.canRotate() && goog.isDef(rotation)) {
|
||||
goog.vec.Mat4.rotateZ(this.coordinateToPixelMatrix_, -rotation);
|
||||
}
|
||||
goog.vec.Mat4.translate(this.coordinateToPixelMatrix_,
|
||||
-center.x,
|
||||
-center.y,
|
||||
0);
|
||||
|
||||
var inverted = goog.vec.Mat4.invert(
|
||||
this.coordinateToPixelMatrix_, this.pixelToCoordinateMatrix_);
|
||||
goog.asserts.assert(inverted);
|
||||
|
||||
this.matricesDirty_ = false;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
// FIXME move colorMatrix_ elsewhere?
|
||||
|
||||
goog.provide('ol.renderer.webgl.Layer');
|
||||
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.FrameState');
|
||||
goog.require('ol.layer.Layer');
|
||||
goog.require('ol.layer.LayerState');
|
||||
goog.require('ol.renderer.Layer');
|
||||
goog.require('ol.vec.Mat4');
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +18,50 @@ goog.require('ol.renderer.Layer');
|
||||
* @param {ol.layer.Layer} layer Layer.
|
||||
*/
|
||||
ol.renderer.webgl.Layer = function(mapRenderer, layer) {
|
||||
|
||||
goog.base(this, mapRenderer, layer);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!goog.vec.Mat4.Float32}
|
||||
*/
|
||||
this.brightnessMatrix_ = goog.vec.Mat4.createFloat32();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!goog.vec.Mat4.Float32}
|
||||
*/
|
||||
this.contrastMatrix_ = goog.vec.Mat4.createFloat32();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!goog.vec.Mat4.Float32}
|
||||
*/
|
||||
this.hueMatrix_ = goog.vec.Mat4.createFloat32();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!goog.vec.Mat4.Float32}
|
||||
*/
|
||||
this.saturationMatrix_ = goog.vec.Mat4.createFloat32();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!goog.vec.Mat4.Float32}
|
||||
*/
|
||||
this.colorMatrix_ = goog.vec.Mat4.createFloat32();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.colorMatrixDirty_ = true;
|
||||
|
||||
this.handleLayerBrightnessChange();
|
||||
this.handleLayerContrastChange();
|
||||
this.handleLayerHueChange();
|
||||
this.handleLayerSaturationChange();
|
||||
|
||||
};
|
||||
goog.inherits(ol.renderer.webgl.Layer, ol.renderer.Layer);
|
||||
|
||||
@@ -27,17 +75,28 @@ ol.renderer.webgl.Layer.prototype.dispatchChangeEvent = function() {
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return {ol.renderer.Map} MapRenderer.
|
||||
* @return {!goog.vec.Mat4.Float32} Color matrix.
|
||||
*/
|
||||
ol.renderer.webgl.Layer.prototype.getMapRenderer = function() {
|
||||
return /** @type {ol.renderer.webgl.Map} */ goog.base(
|
||||
this, 'getMapRenderer');
|
||||
ol.renderer.webgl.Layer.prototype.getColorMatrix = function() {
|
||||
if (this.colorMatrixDirty_) {
|
||||
this.updateColorMatrix_();
|
||||
}
|
||||
return this.colorMatrix_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.vec.Mat4.AnyType} Matrix.
|
||||
* @inheritDoc
|
||||
* @return {ol.renderer.Map} MapRenderer.
|
||||
*/
|
||||
ol.renderer.webgl.Layer.prototype.getMapRenderer = function() {
|
||||
return /** @type {ol.renderer.webgl.Map} */ (goog.base(
|
||||
this, 'getMapRenderer'));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.vec.Mat4.Number} Matrix.
|
||||
*/
|
||||
ol.renderer.webgl.Layer.prototype.getMatrix = goog.abstractMethod;
|
||||
|
||||
@@ -52,6 +111,9 @@ ol.renderer.webgl.Layer.prototype.getTexture = goog.abstractMethod;
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.Layer.prototype.handleLayerBrightnessChange = function() {
|
||||
var value = this.getLayer().getBrightness();
|
||||
ol.vec.Mat4.makeBrightness(this.brightnessMatrix_, value);
|
||||
this.colorMatrixDirty_ = true;
|
||||
this.dispatchChangeEvent();
|
||||
};
|
||||
|
||||
@@ -60,6 +122,9 @@ ol.renderer.webgl.Layer.prototype.handleLayerBrightnessChange = function() {
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.Layer.prototype.handleLayerContrastChange = function() {
|
||||
var value = this.getLayer().getContrast();
|
||||
ol.vec.Mat4.makeContrast(this.contrastMatrix_, value);
|
||||
this.colorMatrixDirty_ = true;
|
||||
this.dispatchChangeEvent();
|
||||
};
|
||||
|
||||
@@ -68,6 +133,9 @@ ol.renderer.webgl.Layer.prototype.handleLayerContrastChange = function() {
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.Layer.prototype.handleLayerHueChange = function() {
|
||||
var value = this.getLayer().getHue();
|
||||
ol.vec.Mat4.makeHue(this.hueMatrix_, value);
|
||||
this.colorMatrixDirty_ = true;
|
||||
this.dispatchChangeEvent();
|
||||
};
|
||||
|
||||
@@ -92,6 +160,9 @@ ol.renderer.webgl.Layer.prototype.handleLayerOpacityChange = function() {
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.Layer.prototype.handleLayerSaturationChange = function() {
|
||||
var saturation = this.getLayer().getSaturation();
|
||||
ol.vec.Mat4.makeSaturation(this.saturationMatrix_, saturation);
|
||||
this.colorMatrixDirty_ = true;
|
||||
this.dispatchChangeEvent();
|
||||
};
|
||||
|
||||
@@ -112,7 +183,21 @@ ol.renderer.webgl.Layer.prototype.handleWebGLContextLost = goog.nullFunction;
|
||||
|
||||
/**
|
||||
* Render.
|
||||
* @param {number} time Time.
|
||||
* @return {boolean} Request render frame.
|
||||
* @param {ol.FrameState} frameState Frame state.
|
||||
* @param {ol.layer.LayerState} layerState Layer state.
|
||||
*/
|
||||
ol.renderer.webgl.Layer.prototype.renderFrame = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.webgl.Layer.prototype.updateColorMatrix_ = function() {
|
||||
var colorMatrix = this.colorMatrix_;
|
||||
goog.vec.Mat4.makeIdentity(colorMatrix);
|
||||
goog.vec.Mat4.multMat(colorMatrix, this.contrastMatrix_, colorMatrix);
|
||||
goog.vec.Mat4.multMat(colorMatrix, this.brightnessMatrix_, colorMatrix);
|
||||
goog.vec.Mat4.multMat(colorMatrix, this.saturationMatrix_, colorMatrix);
|
||||
goog.vec.Mat4.multMat(colorMatrix, this.hueMatrix_, colorMatrix);
|
||||
this.colorMatrixDirty_ = false;
|
||||
};
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// FIXME clear textureCache
|
||||
// FIXME defer texture loads until after render when animating
|
||||
// FIXME generational tile texture garbage collector newFrame/get
|
||||
// FIXME defer cleanup until post-render
|
||||
// FIXME check against gl.getParameter(webgl.MAX_TEXTURE_SIZE)
|
||||
|
||||
goog.provide('ol.renderer.webgl.Map');
|
||||
@@ -14,10 +12,9 @@ goog.require('goog.dom.TagName');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.Event');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.functions');
|
||||
goog.require('goog.style');
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('goog.webgl');
|
||||
goog.require('ol.Tile');
|
||||
goog.require('ol.layer.Layer');
|
||||
goog.require('ol.layer.TileLayer');
|
||||
goog.require('ol.renderer.webgl.FragmentShader');
|
||||
@@ -119,6 +116,12 @@ ol.renderer.webgl.Map = function(container, map) {
|
||||
this.canvas_.className = 'ol-unselectable';
|
||||
goog.dom.insertChildAt(container, this.canvas_, 0);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.renderedVisible_ = true;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Size}
|
||||
@@ -143,12 +146,6 @@ ol.renderer.webgl.Map = function(container, map) {
|
||||
goog.events.listen(this.canvas_, ol.webgl.WebGLContextEventType.RESTORED,
|
||||
this.handleWebGLContextResourced, false, this);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Color}
|
||||
*/
|
||||
this.clearColor_ = new ol.Color(1, 1, 1, 1);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {{aPosition: number,
|
||||
@@ -220,15 +217,15 @@ ol.renderer.webgl.Map.prototype.addLayer = function(layer) {
|
||||
|
||||
|
||||
/**
|
||||
* @param {Image} image Image.
|
||||
* @param {ol.Tile} tile Tile.
|
||||
* @param {number} magFilter Mag filter.
|
||||
* @param {number} minFilter Min filter.
|
||||
*/
|
||||
ol.renderer.webgl.Map.prototype.bindImageTexture =
|
||||
function(image, magFilter, minFilter) {
|
||||
ol.renderer.webgl.Map.prototype.bindTileTexture =
|
||||
function(tile, magFilter, minFilter) {
|
||||
var gl = this.getGL();
|
||||
var imageKey = image.src;
|
||||
var textureCacheEntry = this.textureCache_[imageKey];
|
||||
var tileKey = tile.getKey();
|
||||
var textureCacheEntry = this.textureCache_[tileKey];
|
||||
if (goog.isDef(textureCacheEntry)) {
|
||||
gl.bindTexture(goog.webgl.TEXTURE_2D, textureCacheEntry.texture);
|
||||
if (textureCacheEntry.magFilter != magFilter) {
|
||||
@@ -245,7 +242,7 @@ ol.renderer.webgl.Map.prototype.bindImageTexture =
|
||||
var texture = gl.createTexture();
|
||||
gl.bindTexture(goog.webgl.TEXTURE_2D, texture);
|
||||
gl.texImage2D(goog.webgl.TEXTURE_2D, 0, goog.webgl.RGBA, goog.webgl.RGBA,
|
||||
goog.webgl.UNSIGNED_BYTE, image);
|
||||
goog.webgl.UNSIGNED_BYTE, tile.getImage());
|
||||
gl.texParameteri(
|
||||
goog.webgl.TEXTURE_2D, goog.webgl.TEXTURE_MAG_FILTER, magFilter);
|
||||
gl.texParameteri(
|
||||
@@ -254,7 +251,7 @@ ol.renderer.webgl.Map.prototype.bindImageTexture =
|
||||
goog.webgl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(goog.webgl.TEXTURE_2D, goog.webgl.TEXTURE_WRAP_T,
|
||||
goog.webgl.CLAMP_TO_EDGE);
|
||||
this.textureCache_[imageKey] = {
|
||||
this.textureCache_[tileKey] = {
|
||||
texture: texture,
|
||||
magFilter: magFilter,
|
||||
minFilter: minFilter
|
||||
@@ -263,75 +260,10 @@ ol.renderer.webgl.Map.prototype.bindImageTexture =
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.Map.prototype.canRotate = goog.functions.TRUE;
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} value Hue value.
|
||||
* @return {!goog.vec.Mat4.Float32} Matrix.
|
||||
*/
|
||||
ol.renderer.webgl.Map.prototype.createHueRotateMatrix = function(value) {
|
||||
var cosHue = Math.cos(value);
|
||||
var sinHue = Math.sin(value);
|
||||
var v00 = 0.213 + cosHue * 0.787 - sinHue * 0.213;
|
||||
var v01 = 0.715 - cosHue * 0.715 - sinHue * 0.715;
|
||||
var v02 = 0.072 - cosHue * 0.072 + sinHue * 0.928;
|
||||
var v03 = 0;
|
||||
var v10 = 0.213 - cosHue * 0.213 + sinHue * 0.143;
|
||||
var v11 = 0.715 + cosHue * 0.285 + sinHue * 0.140;
|
||||
var v12 = 0.072 - cosHue * 0.072 - sinHue * 0.283;
|
||||
var v13 = 0;
|
||||
var v20 = 0.213 - cosHue * 0.213 - sinHue * 0.787;
|
||||
var v21 = 0.715 - cosHue * 0.715 + sinHue * 0.715;
|
||||
var v22 = 0.072 + cosHue * 0.928 + sinHue * 0.072;
|
||||
var v23 = 0;
|
||||
var v30 = 0;
|
||||
var v31 = 0;
|
||||
var v32 = 0;
|
||||
var v33 = 1;
|
||||
var matrix = goog.vec.Mat4.createFloat32();
|
||||
goog.vec.Mat4.setFromValues(matrix,
|
||||
v00, v10, v20, v30,
|
||||
v01, v11, v21, v31,
|
||||
v02, v12, v22, v32,
|
||||
v03, v13, v23, v33);
|
||||
return matrix;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} value Brightness value.
|
||||
* @return {!goog.vec.Mat4.Float32} Matrix.
|
||||
*/
|
||||
ol.renderer.webgl.Map.prototype.createBrightnessMatrix = function(value) {
|
||||
var matrix = goog.vec.Mat4.createFloat32Identity();
|
||||
goog.vec.Mat4.setColumnValues(matrix, 3, value, value, value, 1);
|
||||
return matrix;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} value Contrast value.
|
||||
* @return {!goog.vec.Mat4.Float32} Matrix.
|
||||
*/
|
||||
ol.renderer.webgl.Map.prototype.createContrastMatrix = function(value) {
|
||||
var matrix = goog.vec.Mat4.createFloat32();
|
||||
goog.vec.Mat4.setDiagonalValues(matrix, value, value, value, 1);
|
||||
var translateValue = (-0.5 * value + 0.5);
|
||||
goog.vec.Mat4.setColumnValues(matrix, 3,
|
||||
translateValue, translateValue, translateValue, 1);
|
||||
return matrix;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.Map.prototype.createLayerRenderer = function(layer) {
|
||||
var gl = this.getGL();
|
||||
if (layer instanceof ol.layer.TileLayer) {
|
||||
return new ol.renderer.webgl.TileLayer(this, layer);
|
||||
} else {
|
||||
@@ -341,38 +273,6 @@ ol.renderer.webgl.Map.prototype.createLayerRenderer = function(layer) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} value Saturation value.
|
||||
* @return {!goog.vec.Mat4.Float32} Matrix.
|
||||
*/
|
||||
ol.renderer.webgl.Map.prototype.createSaturateMatrix = function(value) {
|
||||
var v00 = 0.213 + 0.787 * value;
|
||||
var v01 = 0.715 - 0.715 * value;
|
||||
var v02 = 0.072 - 0.072 * value;
|
||||
var v03 = 0;
|
||||
var v10 = 0.213 - 0.213 * value;
|
||||
var v11 = 0.715 + 0.285 * value;
|
||||
var v12 = 0.072 - 0.072 * value;
|
||||
var v13 = 0;
|
||||
var v20 = 0.213 - 0.213 * value;
|
||||
var v21 = 0.715 - 0.715 * value;
|
||||
var v22 = 0.072 + 0.928 * value;
|
||||
var v23 = 0;
|
||||
var v30 = 0;
|
||||
var v31 = 0;
|
||||
var v32 = 0;
|
||||
var v33 = 1;
|
||||
var matrix = goog.vec.Mat4.createFloat32();
|
||||
goog.vec.Mat4.setFromValues(matrix,
|
||||
v00, v10, v20, v30,
|
||||
v01, v11, v21, v31,
|
||||
v02, v12, v22, v32,
|
||||
v03, v13, v23, v33);
|
||||
return matrix;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@@ -464,21 +364,6 @@ ol.renderer.webgl.Map.prototype.getShader = function(shaderObject) {
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.Map.prototype.handleBackgroundColorChanged = function() {
|
||||
var backgroundColor = this.getMap().getBackgroundColor();
|
||||
this.clearColor_ = new ol.Color(
|
||||
backgroundColor.r / 255,
|
||||
backgroundColor.g / 255,
|
||||
backgroundColor.b / 255,
|
||||
backgroundColor.a / 255);
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.Map.prototype.handleCenterChanged = function() {
|
||||
goog.base(this, 'handleCenterChanged');
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
@@ -492,33 +377,6 @@ ol.renderer.webgl.Map.prototype.handleLayerRendererChange = function(event) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.Map.prototype.handleResolutionChanged = function() {
|
||||
goog.base(this, 'handleResolutionChanged');
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.Map.prototype.handleRotationChanged = function() {
|
||||
goog.base(this, 'handleRotationChanged');
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.Map.prototype.handleSizeChanged = function() {
|
||||
goog.base(this, 'handleSizeChanged');
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.events.Event} event Event.
|
||||
* @protected
|
||||
@@ -565,11 +423,11 @@ ol.renderer.webgl.Map.prototype.initializeGL_ = function() {
|
||||
|
||||
|
||||
/**
|
||||
* @param {Image} image Image.
|
||||
* @return {boolean} Is image texture loaded.
|
||||
* @param {ol.Tile} tile Tile.
|
||||
* @return {boolean} Is tile texture loaded.
|
||||
*/
|
||||
ol.renderer.webgl.Map.prototype.isImageTextureLoaded = function(image) {
|
||||
return image.src in this.textureCache_;
|
||||
ol.renderer.webgl.Map.prototype.isTileTextureLoaded = function(tile) {
|
||||
return tile.getKey() in this.textureCache_;
|
||||
};
|
||||
|
||||
|
||||
@@ -601,40 +459,38 @@ ol.renderer.webgl.Map.prototype.removeLayerRenderer = function(layer) {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.Map.prototype.renderFrame = function(time) {
|
||||
ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) {
|
||||
|
||||
if (!this.getMap().isDef()) {
|
||||
return;
|
||||
var gl = this.getGL();
|
||||
|
||||
if (goog.isNull(frameState)) {
|
||||
if (this.renderedVisible_) {
|
||||
goog.style.showElement(this.canvas_, false);
|
||||
this.renderedVisible_ = false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var requestRenderFrame = false;
|
||||
|
||||
this.forEachReadyVisibleLayer(function(layer, layerRenderer) {
|
||||
if (layerRenderer.renderFrame(time)) {
|
||||
requestRenderFrame = true;
|
||||
goog.array.forEach(frameState.layersArray, function(layer) {
|
||||
var layerState = frameState.layerStates[goog.getUid(layer)];
|
||||
if (!layerState.visible || !layerState.ready) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
var layerRenderer = this.getLayerRenderer(layer);
|
||||
layerRenderer.renderFrame(frameState, layerState);
|
||||
}, this);
|
||||
|
||||
var size = /** @type {ol.Size} */ this.getMap().getSize();
|
||||
var size = frameState.size;
|
||||
if (!this.canvasSize_.equals(size)) {
|
||||
this.canvas_.width = size.width;
|
||||
this.canvas_.height = size.height;
|
||||
this.canvasSize_ = size;
|
||||
}
|
||||
|
||||
var animate = false;
|
||||
this.forEachReadyVisibleLayer(function(layer, layerRenderer) {
|
||||
if (layerRenderer.renderFrame(time)) {
|
||||
animate = true;
|
||||
}
|
||||
});
|
||||
|
||||
var gl = this.getGL();
|
||||
|
||||
gl.bindFramebuffer(goog.webgl.FRAMEBUFFER, null);
|
||||
|
||||
gl.clearColor(this.clearColor_.r, this.clearColor_.g, this.clearColor_.b,
|
||||
this.clearColor_.a);
|
||||
var clearColor = frameState.backgroundColor;
|
||||
gl.clearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
|
||||
gl.clear(goog.webgl.COLOR_BUFFER_BIT);
|
||||
gl.enable(goog.webgl.BLEND);
|
||||
gl.viewport(0, 0, size.width, size.height);
|
||||
@@ -674,28 +530,28 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(time) {
|
||||
this.locations_.aTexCoord, 2, goog.webgl.FLOAT, false, 16, 8);
|
||||
gl.uniform1i(this.locations_.uTexture, 0);
|
||||
|
||||
this.forEachReadyVisibleLayer(function(layer, layerRenderer) {
|
||||
goog.array.forEach(frameState.layersArray, function(layer) {
|
||||
var layerState = frameState.layerStates[goog.getUid(layer)];
|
||||
if (!layerState.visible || !layerState.ready) {
|
||||
return;
|
||||
}
|
||||
var layerRenderer = this.getLayerRenderer(layer);
|
||||
gl.uniformMatrix4fv(
|
||||
this.locations_.uMatrix, false, layerRenderer.getMatrix());
|
||||
var hueRotateMatrix = this.createHueRotateMatrix(layer.getHue());
|
||||
var saturateMatrix = this.createSaturateMatrix(layer.getSaturation());
|
||||
var brightnessMatrix = this.createBrightnessMatrix(layer.getBrightness());
|
||||
var contrastMatrix = this.createContrastMatrix(layer.getContrast());
|
||||
var colorMatrix = goog.vec.Mat4.createFloat32Identity();
|
||||
goog.vec.Mat4.multMat(colorMatrix, contrastMatrix, colorMatrix);
|
||||
goog.vec.Mat4.multMat(colorMatrix, brightnessMatrix, colorMatrix);
|
||||
goog.vec.Mat4.multMat(colorMatrix, saturateMatrix, colorMatrix);
|
||||
goog.vec.Mat4.multMat(colorMatrix, hueRotateMatrix, colorMatrix);
|
||||
gl.uniformMatrix4fv(this.locations_.uColorMatrix, false, colorMatrix);
|
||||
gl.uniformMatrix4fv(
|
||||
this.locations_.uColorMatrix, false, layerRenderer.getColorMatrix());
|
||||
gl.uniform1f(this.locations_.uOpacity, layer.getOpacity());
|
||||
gl.bindTexture(goog.webgl.TEXTURE_2D, layerRenderer.getTexture());
|
||||
gl.drawArrays(goog.webgl.TRIANGLE_STRIP, 0, 4);
|
||||
}, this);
|
||||
|
||||
if (requestRenderFrame) {
|
||||
this.getMap().requestRenderFrame();
|
||||
if (!this.renderedVisible_) {
|
||||
goog.style.showElement(this.canvas_, true);
|
||||
this.renderedVisible_ = true;
|
||||
}
|
||||
|
||||
this.calculateMatrices2D(frameState);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -3,12 +3,6 @@ goog.provide('ol.renderer.webgl');
|
||||
goog.require('ol.webgl');
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Free resources immediately.
|
||||
*/
|
||||
ol.renderer.webgl.FREE_RESOURCES_IMMEDIATELY = false;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Is supported.
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// FIXME large resolutions lead to too large framebuffers :-(
|
||||
// FIXME animated shaders! check in redraw
|
||||
// FIXME throttle texture uploads
|
||||
// FIXME prioritize texture uploads
|
||||
|
||||
goog.provide('ol.renderer.webgl.TileLayer');
|
||||
goog.provide('ol.renderer.webgl.tilelayerrenderer');
|
||||
@@ -10,13 +8,14 @@ goog.provide('ol.renderer.webgl.tilelayerrenderer.shader.Vertex');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.debug.Logger');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.object');
|
||||
goog.require('goog.structs.PriorityQueue');
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('goog.vec.Vec4');
|
||||
goog.require('goog.webgl');
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.FrameState');
|
||||
goog.require('ol.Size');
|
||||
goog.require('ol.TileState');
|
||||
goog.require('ol.layer.TileLayer');
|
||||
@@ -88,14 +87,6 @@ ol.renderer.webgl.TileLayer = function(mapRenderer, tileLayer) {
|
||||
|
||||
goog.base(this, mapRenderer, tileLayer);
|
||||
|
||||
if (goog.DEBUG) {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
this.logger = goog.debug.Logger.getLogger(
|
||||
'ol.renderer.webgl.tilelayerrenderer.' + goog.getUid(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.renderer.webgl.FragmentShader}
|
||||
@@ -145,7 +136,7 @@ ol.renderer.webgl.TileLayer = function(mapRenderer, tileLayer) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {goog.vec.Mat4.AnyType}
|
||||
* @type {!goog.vec.Mat4.Number}
|
||||
*/
|
||||
this.matrix_ = goog.vec.Mat4.createNumber();
|
||||
|
||||
@@ -166,11 +157,12 @@ goog.inherits(ol.renderer.webgl.TileLayer, ol.renderer.webgl.Layer);
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.FrameState} frameState Frame state.
|
||||
* @param {number} framebufferDimension Framebuffer dimension.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.webgl.TileLayer.prototype.bindFramebuffer_ =
|
||||
function(framebufferDimension) {
|
||||
function(frameState, framebufferDimension) {
|
||||
|
||||
var mapRenderer = this.getMapRenderer();
|
||||
var gl = mapRenderer.getGL();
|
||||
@@ -178,33 +170,14 @@ ol.renderer.webgl.TileLayer.prototype.bindFramebuffer_ =
|
||||
if (!goog.isDef(this.framebufferDimension_) ||
|
||||
this.framebufferDimension_ != framebufferDimension) {
|
||||
|
||||
if (goog.DEBUG) {
|
||||
this.logger.info('re-sizing framebuffer');
|
||||
}
|
||||
|
||||
if (ol.renderer.webgl.FREE_RESOURCES_IMMEDIATELY) {
|
||||
if (goog.DEBUG) {
|
||||
this.logger.info('freeing WebGL resources');
|
||||
}
|
||||
if (!gl.isContextLost()) {
|
||||
gl.deleteFramebuffer(this.framebuffer_);
|
||||
gl.deleteTexture(this.texture_);
|
||||
}
|
||||
} else {
|
||||
var map = this.getMap();
|
||||
goog.events.listenOnce(
|
||||
map,
|
||||
ol.MapEventType.POSTRENDER,
|
||||
goog.partial(function(gl, framebuffer, texture) {
|
||||
if (goog.DEBUG) {
|
||||
this.logger.info('freeing WebGL resources on postrender');
|
||||
}
|
||||
if (!gl.isContextLost()) {
|
||||
gl.deleteFramebuffer(framebuffer);
|
||||
gl.deleteTexture(texture);
|
||||
}
|
||||
}, gl, this.framebuffer_, this.texture_));
|
||||
}
|
||||
var map = this.getMap();
|
||||
frameState.postRenderFunctions.push(
|
||||
goog.partial(function(gl, framebuffer, texture) {
|
||||
if (!gl.isContextLost()) {
|
||||
gl.deleteFramebuffer(framebuffer);
|
||||
gl.deleteTexture(texture);
|
||||
}
|
||||
}, gl, this.framebuffer_, this.texture_));
|
||||
|
||||
var texture = gl.createTexture();
|
||||
gl.bindTexture(goog.webgl.TEXTURE_2D, texture);
|
||||
@@ -247,15 +220,6 @@ ol.renderer.webgl.TileLayer.prototype.disposeInternal = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.layer.TileLayer} Layer.
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.TileLayer.prototype.getLayer = function() {
|
||||
return /** @type {ol.layer.TileLayer} */ goog.base(this, 'getLayer');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@@ -272,6 +236,14 @@ ol.renderer.webgl.TileLayer.prototype.getTexture = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.layer.TileLayer} Tile layer.
|
||||
*/
|
||||
ol.renderer.webgl.TileLayer.prototype.getTileLayer = function() {
|
||||
return /** @type {ol.layer.TileLayer} */ (this.getLayer());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@@ -287,28 +259,22 @@ ol.renderer.webgl.TileLayer.prototype.handleWebGLContextLost = function() {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.TileLayer.prototype.renderFrame = function(time) {
|
||||
|
||||
var requestRenderFrame = false;
|
||||
ol.renderer.webgl.TileLayer.prototype.renderFrame =
|
||||
function(frameState, layerState) {
|
||||
|
||||
var mapRenderer = this.getMapRenderer();
|
||||
var map = this.getMap();
|
||||
var gl = mapRenderer.getGL();
|
||||
|
||||
goog.asserts.assert(map.isDef());
|
||||
var mapCenter = map.getCenter();
|
||||
var mapExtent = map.getExtent();
|
||||
var mapResolution = /** @type {number} */ map.getResolution();
|
||||
var mapRotatedExtent = map.getRotatedExtent();
|
||||
var mapRotation = map.getRotation();
|
||||
var view2DState = frameState.view2DState;
|
||||
var center = view2DState.center;
|
||||
|
||||
var tileLayer = this.getLayer();
|
||||
var tileLayer = this.getTileLayer();
|
||||
var tileSource = tileLayer.getTileSource();
|
||||
var tileGrid = tileSource.getTileGrid();
|
||||
var z = tileGrid.getZForResolution(mapResolution);
|
||||
var z = tileGrid.getZForResolution(view2DState.resolution);
|
||||
var tileResolution = tileGrid.getResolution(z);
|
||||
var tileRange = tileGrid.getTileRangeForExtentAndResolution(
|
||||
mapRotatedExtent, tileResolution);
|
||||
frameState.extent, tileResolution);
|
||||
|
||||
var framebufferExtent;
|
||||
|
||||
@@ -337,7 +303,7 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame = function(time) {
|
||||
minX + framebufferExtentSize.width,
|
||||
minY + framebufferExtentSize.height);
|
||||
|
||||
this.bindFramebuffer_(framebufferDimension);
|
||||
this.bindFramebuffer_(frameState, framebufferDimension);
|
||||
gl.viewport(0, 0, framebufferDimension, framebufferDimension);
|
||||
|
||||
gl.clearColor(0, 0, 0, 0);
|
||||
@@ -382,65 +348,73 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame = function(time) {
|
||||
* @type {Object.<number, Object.<string, ol.Tile>>}
|
||||
*/
|
||||
var tilesToDrawByZ = {};
|
||||
tilesToDrawByZ[z] = {};
|
||||
|
||||
/**
|
||||
* @type {Array.<Image>}
|
||||
*/
|
||||
var imagesToLoad = [];
|
||||
var findInterimTiles = function(z, tileRange) {
|
||||
// FIXME this could be more efficient about filling partial holes
|
||||
var fullyCovered = true;
|
||||
var tile, tileCoord, tileCoordKey, x, y;
|
||||
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||
tileCoord = new ol.TileCoord(z, x, y);
|
||||
tileCoordKey = tileCoord.toString();
|
||||
if (tilesToDrawByZ[z] && tilesToDrawByZ[z][tileCoordKey]) {
|
||||
return;
|
||||
}
|
||||
tile = tileSource.getTile(tileCoord);
|
||||
if (!goog.isNull(tile) &&
|
||||
tile.getState() == ol.TileState.LOADED &&
|
||||
mapRenderer.isTileTextureLoaded(tile)) {
|
||||
if (!tilesToDrawByZ[z]) {
|
||||
tilesToDrawByZ[z] = {};
|
||||
}
|
||||
tilesToDrawByZ[z][tileCoordKey] = tile;
|
||||
} else {
|
||||
fullyCovered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return fullyCovered;
|
||||
};
|
||||
|
||||
var tilesToLoad = new goog.structs.PriorityQueue();
|
||||
|
||||
var allTilesLoaded = true;
|
||||
var deltaX, deltaY, priority, tile, tileCenter, tileCoord, tileState, x, y;
|
||||
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||
|
||||
tilesToDrawByZ[z] = {};
|
||||
tileRange.forEachTileCoord(z, function(tileCoord) {
|
||||
|
||||
var tile = tileSource.getTile(tileCoord);
|
||||
|
||||
if (goog.isNull(tile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var tileState = tile.getState();
|
||||
if (tileState == ol.TileState.IDLE) {
|
||||
tile.load();
|
||||
} else if (tileState == ol.TileState.LOADED) {
|
||||
var image = tile.getImage();
|
||||
if (mapRenderer.isImageTextureLoaded(image)) {
|
||||
tilesToDrawByZ[z][tileCoord.toString()] = tile;
|
||||
return;
|
||||
} else {
|
||||
imagesToLoad.push(image);
|
||||
tileCoord = new ol.TileCoord(z, x, y);
|
||||
tile = tileSource.getTile(tileCoord);
|
||||
if (goog.isNull(tile)) {
|
||||
continue;
|
||||
}
|
||||
} else if (tileState == ol.TileState.ERROR) {
|
||||
return;
|
||||
|
||||
tileState = tile.getState();
|
||||
if (tileState == ol.TileState.IDLE) {
|
||||
tileCenter = tileGrid.getTileCoordCenter(tileCoord);
|
||||
frameState.tileQueue.enqueue(tile, tileCenter, tileResolution);
|
||||
} else if (tileState == ol.TileState.LOADED) {
|
||||
if (mapRenderer.isTileTextureLoaded(tile)) {
|
||||
tilesToDrawByZ[z][tileCoord.toString()] = tile;
|
||||
continue;
|
||||
} else {
|
||||
tileCenter = tileGrid.getTileCoordCenter(tileCoord);
|
||||
deltaX = tileCenter.x - center.x;
|
||||
deltaY = tileCenter.y - center.y;
|
||||
priority = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
||||
tilesToLoad.enqueue(priority, tile);
|
||||
}
|
||||
} else if (tileState == ol.TileState.ERROR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
allTilesLoaded = false;
|
||||
tileGrid.forEachTileCoordParentTileRange(tileCoord, findInterimTiles);
|
||||
|
||||
}
|
||||
|
||||
allTilesLoaded = false;
|
||||
|
||||
// FIXME this could be more efficient about filling partial holes
|
||||
tileGrid.forEachTileCoordParentTileRange(
|
||||
tileCoord,
|
||||
function(z, tileRange) {
|
||||
var fullyCovered = true;
|
||||
tileRange.forEachTileCoord(z, function(tileCoord) {
|
||||
var tileCoordKey = tileCoord.toString();
|
||||
if (tilesToDrawByZ[z] && tilesToDrawByZ[z][tileCoordKey]) {
|
||||
return;
|
||||
}
|
||||
var tile = tileSource.getTile(tileCoord);
|
||||
if (!goog.isNull(tile) &&
|
||||
tile.getState() == ol.TileState.LOADED) {
|
||||
if (!tilesToDrawByZ[z]) {
|
||||
tilesToDrawByZ[z] = {};
|
||||
}
|
||||
tilesToDrawByZ[z][tileCoordKey] = tile;
|
||||
} else {
|
||||
fullyCovered = false;
|
||||
}
|
||||
});
|
||||
return fullyCovered;
|
||||
});
|
||||
|
||||
}, this);
|
||||
}
|
||||
|
||||
/** @type {Array.<number>} */
|
||||
var zs = goog.array.map(goog.object.getKeys(tilesToDrawByZ), Number);
|
||||
@@ -457,29 +431,22 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame = function(time) {
|
||||
framebufferExtentSize.height - 1;
|
||||
goog.vec.Vec4.setFromValues(uTileOffset, sx, sy, tx, ty);
|
||||
gl.uniform4fv(this.locations_.uTileOffset, uTileOffset);
|
||||
mapRenderer.bindImageTexture(
|
||||
tile.getImage(), goog.webgl.LINEAR, goog.webgl.LINEAR);
|
||||
mapRenderer.bindTileTexture(tile, goog.webgl.LINEAR, goog.webgl.LINEAR);
|
||||
gl.drawArrays(goog.webgl.TRIANGLE_STRIP, 0, 4);
|
||||
}, this);
|
||||
}, this);
|
||||
|
||||
if (!goog.array.isEmpty(imagesToLoad)) {
|
||||
goog.events.listenOnce(
|
||||
map,
|
||||
ol.MapEventType.POSTRENDER,
|
||||
goog.partial(function(mapRenderer, imagesToLoad) {
|
||||
if (goog.DEBUG) {
|
||||
this.logger.info(
|
||||
'uploading ' + imagesToLoad.length + ' textures');
|
||||
if (!tilesToLoad.isEmpty()) {
|
||||
frameState.postRenderFunctions.push(
|
||||
goog.partial(function(mapRenderer, tilesToLoad) {
|
||||
var i, tile;
|
||||
// FIXME determine a suitable number of textures to upload per frame
|
||||
for (i = 0; !tilesToLoad.isEmpty() && i < 4; ++i) {
|
||||
tile = /** @type {ol.Tile} */ (tilesToLoad.remove());
|
||||
mapRenderer.bindTileTexture(
|
||||
tile, goog.webgl.LINEAR, goog.webgl.LINEAR);
|
||||
}
|
||||
goog.array.forEach(imagesToLoad, function(image) {
|
||||
mapRenderer.bindImageTexture(
|
||||
image, goog.webgl.LINEAR, goog.webgl.LINEAR);
|
||||
});
|
||||
if (goog.DEBUG) {
|
||||
this.logger.info('uploaded textures');
|
||||
}
|
||||
}, mapRenderer, imagesToLoad));
|
||||
}, mapRenderer, tilesToLoad));
|
||||
}
|
||||
|
||||
if (allTilesLoaded) {
|
||||
@@ -488,25 +455,23 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame = function(time) {
|
||||
} else {
|
||||
this.renderedTileRange_ = null;
|
||||
this.renderedFramebufferExtent_ = null;
|
||||
requestRenderFrame = true;
|
||||
frameState.animate = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
goog.vec.Mat4.makeIdentity(this.matrix_);
|
||||
goog.vec.Mat4.translate(this.matrix_,
|
||||
(mapCenter.x - framebufferExtent.minX) /
|
||||
(view2DState.center.x - framebufferExtent.minX) /
|
||||
(framebufferExtent.maxX - framebufferExtent.minX),
|
||||
(mapCenter.y - framebufferExtent.minY) /
|
||||
(view2DState.center.y - framebufferExtent.minY) /
|
||||
(framebufferExtent.maxY - framebufferExtent.minY),
|
||||
0);
|
||||
if (goog.isDef(mapRotation)) {
|
||||
goog.vec.Mat4.rotateZ(this.matrix_, mapRotation);
|
||||
}
|
||||
goog.vec.Mat4.rotateZ(this.matrix_, view2DState.rotation);
|
||||
goog.vec.Mat4.scale(this.matrix_,
|
||||
(mapExtent.maxX - mapExtent.minX) /
|
||||
frameState.size.width * view2DState.resolution /
|
||||
(framebufferExtent.maxX - framebufferExtent.minX),
|
||||
(mapExtent.maxY - mapExtent.minY) /
|
||||
frameState.size.height * view2DState.resolution /
|
||||
(framebufferExtent.maxY - framebufferExtent.minY),
|
||||
1);
|
||||
goog.vec.Mat4.translate(this.matrix_,
|
||||
@@ -514,6 +479,4 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame = function(time) {
|
||||
-0.5,
|
||||
0);
|
||||
|
||||
return requestRenderFrame;
|
||||
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@ goog.require('goog.events');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.net.Jsonp');
|
||||
goog.require('ol.TileCoverageArea');
|
||||
goog.require('ol.source.TileSource');
|
||||
goog.require('ol.source.ImageTileSource');
|
||||
goog.require('ol.tilegrid.XYZ');
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ ol.BingMapsStyle = {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.source.TileSource}
|
||||
* @extends {ol.source.ImageTileSource}
|
||||
* @param {ol.source.BingMapsOptions} bingMapsOptions Bing Maps options.
|
||||
*/
|
||||
ol.source.BingMaps = function(bingMapsOptions) {
|
||||
@@ -57,7 +57,7 @@ ol.source.BingMaps = function(bingMapsOptions) {
|
||||
}, goog.bind(this.handleImageryMetadataResponse, this));
|
||||
|
||||
};
|
||||
goog.inherits(ol.source.BingMaps, ol.source.TileSource);
|
||||
goog.inherits(ol.source.BingMaps, ol.source.ImageTileSource);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
128
src/ol/source/debugtilesource.js
Normal file
128
src/ol/source/debugtilesource.js
Normal file
@@ -0,0 +1,128 @@
|
||||
goog.provide('ol.source.DebugTileSource');
|
||||
goog.provide('ol.source.DebugTileSourceOptions');
|
||||
|
||||
goog.require('ol.Size');
|
||||
goog.require('ol.Tile');
|
||||
goog.require('ol.TileCoord');
|
||||
goog.require('ol.source.TileSource');
|
||||
goog.require('ol.tilegrid.TileGrid');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.Tile}
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
|
||||
* @private
|
||||
*/
|
||||
ol.DebugTile_ = function(tileCoord, tileGrid) {
|
||||
|
||||
goog.base(this, tileCoord);
|
||||
|
||||
this.state = ol.TileState.LOADED;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.TileCoord}
|
||||
*/
|
||||
this.tileCoord_ = tileCoord;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Size}
|
||||
*/
|
||||
this.tileSize_ = tileGrid.getTileSize();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<number, HTMLCanvasElement>}
|
||||
*/
|
||||
this.canvasByContext_ = {};
|
||||
|
||||
};
|
||||
goog.inherits(ol.DebugTile_, ol.Tile);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.DebugTile_.prototype.getImage = function(opt_context) {
|
||||
var key = goog.isDef(opt_context) ? goog.getUid(opt_context) : -1;
|
||||
if (key in this.canvasByContext_) {
|
||||
return this.canvasByContext_[key];
|
||||
} else {
|
||||
|
||||
var tileSize = this.tileSize_;
|
||||
|
||||
var canvas = /** @type {HTMLCanvasElement} */
|
||||
(goog.dom.createElement(goog.dom.TagName.CANVAS));
|
||||
canvas.width = tileSize.width;
|
||||
canvas.height = tileSize.height;
|
||||
|
||||
var context = canvas.getContext('2d');
|
||||
|
||||
context.strokeStyle = 'black';
|
||||
context.strokeRect(0.5, 0.5, tileSize.width + 0.5, tileSize.height + 0.5);
|
||||
|
||||
context.fillStyle = 'black';
|
||||
context.textAlign = 'center';
|
||||
context.textBaseline = 'middle';
|
||||
context.font = '24px sans-serif';
|
||||
context.fillText(
|
||||
this.tileCoord_.toString(), tileSize.width / 2, tileSize.height / 2);
|
||||
|
||||
this.canvasByContext_[key] = canvas;
|
||||
return canvas;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{extent: (ol.Extent|undefined),
|
||||
* projection: (ol.Projection|undefined),
|
||||
* tileGrid: (ol.tilegrid.TileGrid|undefined)}}
|
||||
*/
|
||||
ol.source.DebugTileSourceOptions;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.source.TileSource}
|
||||
* @param {ol.source.DebugTileSourceOptions} options Options.
|
||||
*/
|
||||
ol.source.DebugTileSource = function(options) {
|
||||
|
||||
goog.base(this, {
|
||||
extent: options.extent,
|
||||
projection: options.projection,
|
||||
tileGrid: options.tileGrid
|
||||
});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, ol.DebugTile_>}
|
||||
* FIXME will need to expire elements from this cache
|
||||
* FIXME see elemoine's work with goog.structs.LinkedMap
|
||||
*/
|
||||
this.tileCache_ = {};
|
||||
|
||||
};
|
||||
goog.inherits(ol.source.DebugTileSource, ol.source.TileSource);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.source.DebugTileSource.prototype.getTile = function(tileCoord) {
|
||||
var key = tileCoord.toString();
|
||||
if (goog.object.containsKey(this.tileCache_, key)) {
|
||||
return this.tileCache_[key];
|
||||
} else {
|
||||
var tile = new ol.DebugTile_(tileCoord, this.tileGrid);
|
||||
this.tileCache_[key] = tile;
|
||||
return tile;
|
||||
}
|
||||
};
|
||||
95
src/ol/source/imagetilesource.js
Normal file
95
src/ol/source/imagetilesource.js
Normal file
@@ -0,0 +1,95 @@
|
||||
goog.provide('ol.source.ImageTileSource');
|
||||
goog.provide('ol.source.ImageTileSourceOptions');
|
||||
|
||||
goog.require('ol.Attribution');
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.ImageTile');
|
||||
goog.require('ol.Projection');
|
||||
goog.require('ol.TileCoord');
|
||||
goog.require('ol.TileUrlFunction');
|
||||
goog.require('ol.TileUrlFunctionType');
|
||||
goog.require('ol.source.TileSource');
|
||||
goog.require('ol.tilegrid.TileGrid');
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{attributions: (Array.<ol.Attribution>|undefined),
|
||||
* crossOrigin: (null|string|undefined),
|
||||
* extent: (ol.Extent|undefined),
|
||||
* projection: (ol.Projection|undefined),
|
||||
* tileGrid: (ol.tilegrid.TileGrid|undefined),
|
||||
* tileUrlFunction: (ol.TileUrlFunctionType|undefined)}}
|
||||
*/
|
||||
ol.source.ImageTileSourceOptions;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.source.TileSource}
|
||||
* @param {ol.source.ImageTileSourceOptions} options Options.
|
||||
*/
|
||||
ol.source.ImageTileSource = function(options) {
|
||||
|
||||
goog.base(this, {
|
||||
attributions: options.attributions,
|
||||
extent: options.extent,
|
||||
projection: options.projection,
|
||||
tileGrid: options.tileGrid
|
||||
});
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @type {ol.TileUrlFunctionType}
|
||||
*/
|
||||
this.tileUrlFunction = goog.isDef(options.tileUrlFunction) ?
|
||||
options.tileUrlFunction :
|
||||
ol.TileUrlFunction.nullTileUrlFunction;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {?string}
|
||||
*/
|
||||
this.crossOrigin_ =
|
||||
goog.isDef(options.crossOrigin) ? options.crossOrigin : 'anonymous';
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, ol.ImageTile>}
|
||||
* FIXME will need to expire elements from this cache
|
||||
* FIXME see elemoine's work with goog.structs.LinkedMap
|
||||
*/
|
||||
this.tileCache_ = {};
|
||||
|
||||
};
|
||||
goog.inherits(ol.source.ImageTileSource, ol.source.TileSource);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.source.ImageTileSource.prototype.getTile = function(tileCoord) {
|
||||
var key = tileCoord.toString();
|
||||
if (goog.object.containsKey(this.tileCache_, key)) {
|
||||
return this.tileCache_[key];
|
||||
} else {
|
||||
var tileUrl = this.getTileCoordUrl(tileCoord);
|
||||
var tile;
|
||||
if (goog.isDef(tileUrl)) {
|
||||
tile = new ol.ImageTile(tileCoord, tileUrl, this.crossOrigin_);
|
||||
} else {
|
||||
tile = null;
|
||||
}
|
||||
this.tileCache_[key] = tile;
|
||||
return tile;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @return {string|undefined} Tile URL.
|
||||
*/
|
||||
ol.source.ImageTileSource.prototype.getTileCoordUrl = function(tileCoord) {
|
||||
return this.tileUrlFunction(tileCoord);
|
||||
};
|
||||
@@ -26,7 +26,7 @@ ol.source.StamenFlavor = {
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{flavor: ol.source.StamenFlavor,
|
||||
* @typedef {{flavor: (ol.source.StamenFlavor|undefined),
|
||||
* provider: ol.source.StamenProvider}}
|
||||
*/
|
||||
ol.source.StamenOptions;
|
||||
|
||||
@@ -10,14 +10,14 @@ goog.require('ol.Attribution');
|
||||
goog.require('ol.Projection');
|
||||
goog.require('ol.TileCoord');
|
||||
goog.require('ol.TileUrlFunction');
|
||||
goog.require('ol.source.TileSource');
|
||||
goog.require('ol.source.ImageTileSource');
|
||||
goog.require('ol.tilegrid.TileGrid');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.source.TileSource}
|
||||
* @extends {ol.source.ImageTileSource}
|
||||
* @param {ol.source.TiledWMSOptions} tiledWMSOptions options.
|
||||
*/
|
||||
ol.source.TiledWMS = function(tiledWMSOptions) {
|
||||
@@ -35,20 +35,8 @@ ol.source.TiledWMS = function(tiledWMSOptions) {
|
||||
if (goog.isDef(tiledWMSOptions.tileGrid)) {
|
||||
tileGrid = tiledWMSOptions.tileGrid;
|
||||
} else {
|
||||
// FIXME Factor this out to a more central/generic place.
|
||||
var size = Math.max(
|
||||
projectionExtent.maxX - projectionExtent.minX,
|
||||
projectionExtent.maxY - projectionExtent.minY);
|
||||
var maxZoom = goog.isDef(tiledWMSOptions.maxZoom) ?
|
||||
tiledWMSOptions.maxZoom : 18;
|
||||
var resolutions = new Array(maxZoom + 1);
|
||||
for (var z = 0, zz = resolutions.length; z < zz; ++z) {
|
||||
resolutions[z] = ol.Projection.EPSG_3857_HALF_SIZE / (128 << z);
|
||||
}
|
||||
tileGrid = new ol.tilegrid.TileGrid({
|
||||
origin: projectionExtent.getTopLeft(),
|
||||
resolutions: resolutions
|
||||
});
|
||||
tileGrid = ol.tilegrid.createForProjection(projection,
|
||||
tiledWMSOptions.maxZoom);
|
||||
}
|
||||
|
||||
var baseParams = {
|
||||
@@ -116,4 +104,4 @@ ol.source.TiledWMS = function(tiledWMSOptions) {
|
||||
});
|
||||
|
||||
};
|
||||
goog.inherits(ol.source.TiledWMS, ol.source.TileSource);
|
||||
goog.inherits(ol.source.TiledWMS, ol.source.ImageTileSource);
|
||||
|
||||
@@ -16,7 +16,7 @@ goog.require('goog.string');
|
||||
goog.require('ol.Projection');
|
||||
goog.require('ol.TileCoverageArea');
|
||||
goog.require('ol.TileUrlFunction');
|
||||
goog.require('ol.source.TileSource');
|
||||
goog.require('ol.source.ImageTileSource');
|
||||
goog.require('ol.tilegrid.XYZ');
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ goog.exportSymbol('grid', grid);
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.source.TileSource}
|
||||
* @extends {ol.source.ImageTileSource}
|
||||
* @param {ol.source.TileJSONOptions} tileJsonOptions TileJSON optios.
|
||||
*/
|
||||
ol.source.TileJSON = function(tileJsonOptions) {
|
||||
@@ -69,7 +69,7 @@ ol.source.TileJSON = function(tileJsonOptions) {
|
||||
this.deferred_.addCallback(this.handleTileJSONResponse, this);
|
||||
|
||||
};
|
||||
goog.inherits(ol.source.TileJSON, ol.source.TileSource);
|
||||
goog.inherits(ol.source.TileJSON, ol.source.ImageTileSource);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,11 +14,9 @@ goog.require('ol.tilegrid.TileGrid');
|
||||
|
||||
/**
|
||||
* @typedef {{attributions: (Array.<ol.Attribution>|undefined),
|
||||
* crossOrigin: (null|string|undefined),
|
||||
* extent: (ol.Extent|undefined),
|
||||
* projection: (ol.Projection|undefined),
|
||||
* tileGrid: (ol.tilegrid.TileGrid|undefined),
|
||||
* tileUrlFunction: (ol.TileUrlFunctionType|undefined)}}
|
||||
* tileGrid: (ol.tilegrid.TileGrid|undefined)}}
|
||||
*/
|
||||
ol.source.TileSourceOptions;
|
||||
|
||||
@@ -44,29 +42,6 @@ ol.source.TileSource = function(tileSourceOptions) {
|
||||
this.tileGrid = goog.isDef(tileSourceOptions.tileGrid) ?
|
||||
tileSourceOptions.tileGrid : null;
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @type {ol.TileUrlFunctionType}
|
||||
*/
|
||||
this.tileUrlFunction = goog.isDef(tileSourceOptions.tileUrlFunction) ?
|
||||
tileSourceOptions.tileUrlFunction :
|
||||
ol.TileUrlFunction.nullTileUrlFunction;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {?string}
|
||||
*/
|
||||
this.crossOrigin_ = goog.isDef(tileSourceOptions.crossOrigin) ?
|
||||
tileSourceOptions.crossOrigin : 'anonymous';
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, ol.Tile>}
|
||||
* FIXME will need to expire elements from this cache
|
||||
* FIXME see elemoine's work with goog.structs.LinkedMap
|
||||
*/
|
||||
this.tileCache_ = {};
|
||||
|
||||
};
|
||||
goog.inherits(ol.source.TileSource, ol.source.Source);
|
||||
|
||||
@@ -83,31 +58,7 @@ ol.source.TileSource.prototype.getResolutions = function() {
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @return {ol.Tile} Tile.
|
||||
*/
|
||||
ol.source.TileSource.prototype.getTile = function(tileCoord) {
|
||||
var key = tileCoord.toString();
|
||||
if (goog.object.containsKey(this.tileCache_, key)) {
|
||||
return this.tileCache_[key];
|
||||
} else {
|
||||
var tileUrl = this.getTileCoordUrl(tileCoord);
|
||||
var tile;
|
||||
if (goog.isDef(tileUrl)) {
|
||||
tile = new ol.Tile(tileCoord, tileUrl, this.crossOrigin_);
|
||||
} else {
|
||||
tile = null;
|
||||
}
|
||||
this.tileCache_[key] = tile;
|
||||
return tile;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @return {string|undefined} Tile URL.
|
||||
*/
|
||||
ol.source.TileSource.prototype.getTileCoordUrl = function(tileCoord) {
|
||||
return this.tileUrlFunction(tileCoord);
|
||||
};
|
||||
ol.source.TileSource.prototype.getTile = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,7 +11,7 @@ goog.require('ol.Size');
|
||||
goog.require('ol.TileCoord');
|
||||
goog.require('ol.TileUrlFunction');
|
||||
goog.require('ol.TileUrlFunctionType');
|
||||
goog.require('ol.source.TileSource');
|
||||
goog.require('ol.source.ImageTileSource');
|
||||
goog.require('ol.tilegrid.XYZ');
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ ol.source.XYZOptions;
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.source.TileSource}
|
||||
* @extends {ol.source.ImageTileSource}
|
||||
* @param {ol.source.XYZOptions} xyzOptions XYZ options.
|
||||
*/
|
||||
ol.source.XYZ = function(xyzOptions) {
|
||||
@@ -110,4 +110,4 @@ ol.source.XYZ = function(xyzOptions) {
|
||||
});
|
||||
|
||||
};
|
||||
goog.inherits(ol.source.XYZ, ol.source.TileSource);
|
||||
goog.inherits(ol.source.XYZ, ol.source.ImageTileSource);
|
||||
|
||||
117
src/ol/tile.js
117
src/ol/tile.js
@@ -24,10 +24,8 @@ ol.TileState = {
|
||||
* @constructor
|
||||
* @extends {goog.events.EventTarget}
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @param {string} src Image source URI.
|
||||
* @param {?string} crossOrigin Cross origin.
|
||||
*/
|
||||
ol.Tile = function(tileCoord, src, crossOrigin) {
|
||||
ol.Tile = function(tileCoord) {
|
||||
|
||||
goog.base(this);
|
||||
|
||||
@@ -37,39 +35,10 @@ ol.Tile = function(tileCoord, src, crossOrigin) {
|
||||
this.tileCoord = tileCoord;
|
||||
|
||||
/**
|
||||
* Image URI
|
||||
*
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.src_ = src;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @protected
|
||||
* @type {ol.TileState}
|
||||
*/
|
||||
this.state_ = ol.TileState.IDLE;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Image}
|
||||
*/
|
||||
this.image_ = new Image();
|
||||
if (!goog.isNull(crossOrigin)) {
|
||||
this.image_.crossOrigin = crossOrigin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<number, Image>}
|
||||
*/
|
||||
this.imageByContext_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.imageListenerKeys_ = null;
|
||||
this.state = ol.TileState.IDLE;
|
||||
|
||||
};
|
||||
goog.inherits(ol.Tile, goog.events.EventTarget);
|
||||
@@ -85,24 +54,16 @@ ol.Tile.prototype.dispatchChangeEvent = function() {
|
||||
|
||||
/**
|
||||
* @param {Object=} opt_context Object.
|
||||
* @return {Image} Image.
|
||||
* @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.
|
||||
*/
|
||||
ol.Tile.prototype.getImage = function(opt_context) {
|
||||
if (goog.isDef(opt_context)) {
|
||||
var image;
|
||||
var key = goog.getUid(opt_context);
|
||||
if (key in this.imageByContext_) {
|
||||
return this.imageByContext_[key];
|
||||
} else if (goog.object.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.Tile.prototype.getImage = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} Key.
|
||||
*/
|
||||
ol.Tile.prototype.getKey = function() {
|
||||
return goog.getUid(this).toString();
|
||||
};
|
||||
|
||||
|
||||
@@ -110,59 +71,11 @@ ol.Tile.prototype.getImage = function(opt_context) {
|
||||
* @return {ol.TileState} State.
|
||||
*/
|
||||
ol.Tile.prototype.getState = function() {
|
||||
return this.state_;
|
||||
return this.state;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Tracks loading or read errors.
|
||||
*
|
||||
* @private
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
ol.Tile.prototype.handleImageError_ = function() {
|
||||
this.state_ = ol.TileState.ERROR;
|
||||
this.unlistenImage_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Tracks successful image load.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
ol.Tile.prototype.handleImageLoad_ = function() {
|
||||
this.state_ = ol.TileState.LOADED;
|
||||
this.unlistenImage_();
|
||||
this.dispatchChangeEvent();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Load not yet loaded URI.
|
||||
*/
|
||||
ol.Tile.prototype.load = function() {
|
||||
if (this.state_ == ol.TileState.IDLE) {
|
||||
this.state_ = ol.TileState.LOADING;
|
||||
goog.asserts.assert(goog.isNull(this.imageListenerKeys_));
|
||||
this.imageListenerKeys_ = [
|
||||
goog.events.listenOnce(this.image_, goog.events.EventType.ERROR,
|
||||
this.handleImageError_, false, this),
|
||||
goog.events.listenOnce(this.image_, goog.events.EventType.LOAD,
|
||||
this.handleImageLoad_, false, this)
|
||||
];
|
||||
this.image_.src = this.src_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Discards event handlers which listen for load completion or errors.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
ol.Tile.prototype.unlistenImage_ = function() {
|
||||
goog.asserts.assert(!goog.isNull(this.imageListenerKeys_));
|
||||
goog.array.forEach(this.imageListenerKeys_, goog.events.unlistenByKey);
|
||||
this.imageListenerKeys_ = null;
|
||||
};
|
||||
|
||||
ol.Tile.prototype.load = goog.abstractMethod;
|
||||
|
||||
@@ -316,3 +316,26 @@ ol.tilegrid.TileGrid.prototype.getTileSize = function() {
|
||||
ol.tilegrid.TileGrid.prototype.getZForResolution = function(resolution) {
|
||||
return ol.array.linearFindNearest(this.resolutions_, resolution);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Projection} projection Projection.
|
||||
* @param {number=} opt_maxZoom Maximum zoom level (optional). Default is 18.
|
||||
* @return {ol.tilegrid.TileGrid} TileGrid instance.
|
||||
*/
|
||||
ol.tilegrid.createForProjection = function(projection, opt_maxZoom) {
|
||||
var projectionExtent = projection.getExtent();
|
||||
var size = Math.max(
|
||||
projectionExtent.maxX - projectionExtent.minX,
|
||||
projectionExtent.maxY - projectionExtent.minY);
|
||||
var maxZoom = goog.isDef(opt_maxZoom) ?
|
||||
opt_maxZoom : 18;
|
||||
var resolutions = new Array(maxZoom + 1);
|
||||
for (var z = 0, zz = resolutions.length; z < zz; ++z) {
|
||||
resolutions[z] = size / (256 << z);
|
||||
}
|
||||
return new ol.tilegrid.TileGrid({
|
||||
origin: projectionExtent.getTopLeft(),
|
||||
resolutions: resolutions
|
||||
});
|
||||
};
|
||||
|
||||
120
src/ol/tilequeue.js
Normal file
120
src/ol/tilequeue.js
Normal file
@@ -0,0 +1,120 @@
|
||||
goog.provide('ol.TilePriorityFunction');
|
||||
goog.provide('ol.TileQueue');
|
||||
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.structs.PriorityQueue');
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.Tile');
|
||||
goog.require('ol.TileState');
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {function(ol.Tile, ol.Coordinate, number): (number|undefined)}
|
||||
*/
|
||||
ol.TilePriorityFunction;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {ol.TilePriorityFunction} tilePriorityFunction
|
||||
* Tile priority function.
|
||||
*/
|
||||
ol.TileQueue = function(tilePriorityFunction) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.TilePriorityFunction}
|
||||
*/
|
||||
this.tilePriorityFunction_ = tilePriorityFunction;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.maxTilesLoading_ = 8;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.tilesLoading_ = 0;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {goog.structs.PriorityQueue}
|
||||
*/
|
||||
this.queue_ = new goog.structs.PriorityQueue();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, boolean>}
|
||||
*/
|
||||
this.queuedTileKeys_ = {};
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Tile} tile Tile.
|
||||
* @param {ol.Coordinate} tileCenter Tile center.
|
||||
* @param {number} tileResolution Tile resolution.
|
||||
*/
|
||||
ol.TileQueue.prototype.enqueue =
|
||||
function(tile, tileCenter, tileResolution) {
|
||||
if (tile.getState() != ol.TileState.IDLE) {
|
||||
return;
|
||||
}
|
||||
var tileKey = tile.getKey();
|
||||
if (!(tileKey in this.queuedTileKeys_)) {
|
||||
var priority = this.tilePriorityFunction_(tile, tileCenter, tileResolution);
|
||||
if (goog.isDef(priority)) {
|
||||
this.queue_.enqueue(priority, arguments);
|
||||
this.queuedTileKeys_[tileKey] = true;
|
||||
} else {
|
||||
// FIXME fire drop event?
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
ol.TileQueue.prototype.handleTileChange = function() {
|
||||
--this.tilesLoading_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
ol.TileQueue.prototype.loadMoreTiles = function() {
|
||||
var tile, tileKey;
|
||||
while (!this.queue_.isEmpty() && this.tilesLoading_ < this.maxTilesLoading_) {
|
||||
tile = (/** @type {Array} */ (this.queue_.dequeue()))[0];
|
||||
tileKey = tile.getKey();
|
||||
delete this.queuedTileKeys_[tileKey];
|
||||
goog.events.listen(tile, goog.events.EventType.CHANGE,
|
||||
this.handleTileChange, false, this);
|
||||
tile.load();
|
||||
++this.tilesLoading_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
ol.TileQueue.prototype.reprioritize = function() {
|
||||
if (!this.queue_.isEmpty()) {
|
||||
var values = /** @type {Array.<Array>} */ (this.queue_.getValues());
|
||||
this.queue_.clear();
|
||||
this.queuedTileKeys_ = {};
|
||||
var i;
|
||||
for (i = 0; i < values.length; ++i) {
|
||||
this.enqueue.apply(this, values[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -28,9 +28,9 @@ ol.TileRange.boundingTileRange = function(var_args) {
|
||||
var tileCoord0 = arguments[0];
|
||||
var tileRange = new ol.TileRange(tileCoord0.x, tileCoord0.y,
|
||||
tileCoord0.x, tileCoord0.y);
|
||||
var i;
|
||||
var i, tileCoord;
|
||||
for (i = 1; i < arguments.length; ++i) {
|
||||
var tileCoord = arguments[i];
|
||||
tileCoord = arguments[i];
|
||||
goog.asserts.assert(tileCoord.z == tileCoord0.z);
|
||||
tileRange.minX = Math.min(tileRange.minX, tileCoord.x);
|
||||
tileRange.minY = Math.min(tileRange.minY, tileCoord.y);
|
||||
@@ -71,22 +71,6 @@ ol.TileRange.prototype.equals = function(tileRange) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} z Z.
|
||||
* @param {function(this: T, ol.TileCoord)} f Callback.
|
||||
* @param {T=} opt_obj The object to be used for the value of 'this' within f.
|
||||
* @template T
|
||||
*/
|
||||
ol.TileRange.prototype.forEachTileCoord = function(z, f, opt_obj) {
|
||||
var x, y;
|
||||
for (x = this.minX; x <= this.maxX; ++x) {
|
||||
for (y = this.minY; y <= this.maxY; ++y) {
|
||||
f.call(opt_obj, new ol.TileCoord(z, x, y));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return {number} Height.
|
||||
|
||||
92
src/ol/vec/mat4.js
Normal file
92
src/ol/vec/mat4.js
Normal file
@@ -0,0 +1,92 @@
|
||||
goog.provide('ol.vec.Mat4');
|
||||
|
||||
goog.require('goog.vec.Mat4');
|
||||
|
||||
|
||||
/**
|
||||
* @param {!goog.vec.Mat4.Float32} matrix Matrix.
|
||||
* @param {number} value Brightness value.
|
||||
* @return {!goog.vec.Mat4.Float32} Matrix.
|
||||
*/
|
||||
ol.vec.Mat4.makeBrightness = function(matrix, value) {
|
||||
goog.vec.Mat4.makeTranslate(matrix, value, value, value);
|
||||
return matrix;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!goog.vec.Mat4.Float32} matrix Matrix.
|
||||
* @param {number} value Contrast value.
|
||||
* @return {!goog.vec.Mat4.Float32} Matrix.
|
||||
*/
|
||||
ol.vec.Mat4.makeContrast = function(matrix, value) {
|
||||
goog.vec.Mat4.makeScale(matrix, value, value, value);
|
||||
var translateValue = (-0.5 * value + 0.5);
|
||||
goog.vec.Mat4.setColumnValues(matrix, 3,
|
||||
translateValue, translateValue, translateValue, 1);
|
||||
return matrix;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!goog.vec.Mat4.Float32} matrix Matrix.
|
||||
* @param {number} value Hue value.
|
||||
* @return {!goog.vec.Mat4.Float32} Matrix.
|
||||
*/
|
||||
ol.vec.Mat4.makeHue = function(matrix, value) {
|
||||
var cosHue = Math.cos(value);
|
||||
var sinHue = Math.sin(value);
|
||||
var v00 = 0.213 + cosHue * 0.787 - sinHue * 0.213;
|
||||
var v01 = 0.715 - cosHue * 0.715 - sinHue * 0.715;
|
||||
var v02 = 0.072 - cosHue * 0.072 + sinHue * 0.928;
|
||||
var v03 = 0;
|
||||
var v10 = 0.213 - cosHue * 0.213 + sinHue * 0.143;
|
||||
var v11 = 0.715 + cosHue * 0.285 + sinHue * 0.140;
|
||||
var v12 = 0.072 - cosHue * 0.072 - sinHue * 0.283;
|
||||
var v13 = 0;
|
||||
var v20 = 0.213 - cosHue * 0.213 - sinHue * 0.787;
|
||||
var v21 = 0.715 - cosHue * 0.715 + sinHue * 0.715;
|
||||
var v22 = 0.072 + cosHue * 0.928 + sinHue * 0.072;
|
||||
var v23 = 0;
|
||||
var v30 = 0;
|
||||
var v31 = 0;
|
||||
var v32 = 0;
|
||||
var v33 = 1;
|
||||
goog.vec.Mat4.setFromValues(matrix,
|
||||
v00, v10, v20, v30,
|
||||
v01, v11, v21, v31,
|
||||
v02, v12, v22, v32,
|
||||
v03, v13, v23, v33);
|
||||
return matrix;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!goog.vec.Mat4.Float32} matrix Matrix.
|
||||
* @param {number} value Saturation value.
|
||||
* @return {!goog.vec.Mat4.Float32} Matrix.
|
||||
*/
|
||||
ol.vec.Mat4.makeSaturation = function(matrix, value) {
|
||||
var v00 = 0.213 + 0.787 * value;
|
||||
var v01 = 0.715 - 0.715 * value;
|
||||
var v02 = 0.072 - 0.072 * value;
|
||||
var v03 = 0;
|
||||
var v10 = 0.213 - 0.213 * value;
|
||||
var v11 = 0.715 + 0.285 * value;
|
||||
var v12 = 0.072 - 0.072 * value;
|
||||
var v13 = 0;
|
||||
var v20 = 0.213 - 0.213 * value;
|
||||
var v21 = 0.715 - 0.715 * value;
|
||||
var v22 = 0.072 + 0.928 * value;
|
||||
var v23 = 0;
|
||||
var v30 = 0;
|
||||
var v31 = 0;
|
||||
var v32 = 0;
|
||||
var v33 = 1;
|
||||
goog.vec.Mat4.setFromValues(matrix,
|
||||
v00, v10, v20, v30,
|
||||
v01, v11, v21, v31,
|
||||
v02, v12, v22, v32,
|
||||
v03, v13, v23, v33);
|
||||
return matrix;
|
||||
};
|
||||
65
src/ol/view.js
Normal file
65
src/ol/view.js
Normal file
@@ -0,0 +1,65 @@
|
||||
goog.provide('ol.View');
|
||||
goog.provide('ol.ViewHint');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('ol.IView');
|
||||
goog.require('ol.IView2D');
|
||||
goog.require('ol.IView3D');
|
||||
|
||||
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
ol.ViewHint = {
|
||||
ANIMATING: 0,
|
||||
PANNING: 1
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements {ol.IView}
|
||||
* @extends {ol.Object}
|
||||
*/
|
||||
ol.View = function() {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.hints_ = [0, 0];
|
||||
|
||||
};
|
||||
goog.inherits(ol.View, ol.Object);
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array.<number>} Hint.
|
||||
*/
|
||||
ol.View.prototype.getHints = function() {
|
||||
return goog.array.clone(this.hints_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.View.prototype.getView2D = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.View.prototype.getView3D = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.ViewHint} hint Hint.
|
||||
* @param {number} delta Delta.
|
||||
*/
|
||||
ol.View.prototype.setHint = function(hint, delta) {
|
||||
goog.asserts.assert(0 <= hint && hint < this.hints_.length);
|
||||
this.hints_[hint] += delta;
|
||||
goog.asserts.assert(this.hints_[hint] >= 0);
|
||||
};
|
||||
344
src/ol/view2d.js
Normal file
344
src/ol/view2d.js
Normal file
@@ -0,0 +1,344 @@
|
||||
// FIXME getView3D has not return type
|
||||
// FIXME remove getExtent?
|
||||
|
||||
goog.provide('ol.View2D');
|
||||
goog.provide('ol.View2DProperty');
|
||||
|
||||
goog.require('ol.Constraints');
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.IView2D');
|
||||
goog.require('ol.IView3D');
|
||||
goog.require('ol.Projection');
|
||||
goog.require('ol.ResolutionConstraint');
|
||||
goog.require('ol.RotationConstraint');
|
||||
goog.require('ol.View');
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
ol.View2DProperty = {
|
||||
CENTER: 'center',
|
||||
PROJECTION: 'projection',
|
||||
RESOLUTION: 'resolution',
|
||||
ROTATION: 'rotation'
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements {ol.IView2D}
|
||||
* @implements {ol.IView3D}
|
||||
* @extends {ol.View}
|
||||
* @param {ol.View2DOptions=} opt_view2DOptions View2D options.
|
||||
*/
|
||||
ol.View2D = function(opt_view2DOptions) {
|
||||
goog.base(this);
|
||||
var view2DOptions = opt_view2DOptions || {};
|
||||
|
||||
/**
|
||||
* @type {Object.<string, *>}
|
||||
*/
|
||||
var values = {};
|
||||
values[ol.View2DProperty.CENTER] = goog.isDef(view2DOptions.center) ?
|
||||
view2DOptions.center : null;
|
||||
values[ol.View2DProperty.PROJECTION] = ol.Projection.createProjection(
|
||||
view2DOptions.projection, 'EPSG:3857');
|
||||
if (goog.isDef(view2DOptions.resolution)) {
|
||||
values[ol.View2DProperty.RESOLUTION] = view2DOptions.resolution;
|
||||
} else if (goog.isDef(view2DOptions.zoom)) {
|
||||
var projectionExtent = values[ol.View2DProperty.PROJECTION].getExtent();
|
||||
var size = Math.max(
|
||||
projectionExtent.maxX - projectionExtent.minX,
|
||||
projectionExtent.maxY - projectionExtent.minY);
|
||||
values[ol.View2DProperty.RESOLUTION] = size / (256 << view2DOptions.zoom);
|
||||
}
|
||||
values[ol.View2DProperty.ROTATION] = view2DOptions.rotation;
|
||||
this.setValues(values);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Constraints}
|
||||
*/
|
||||
this.constraints_ = ol.View2D.createConstraints_(view2DOptions);
|
||||
|
||||
};
|
||||
goog.inherits(ol.View2D, ol.View);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.View2D.prototype.getCenter = function() {
|
||||
return /** @type {ol.Coordinate|undefined} */ (
|
||||
this.get(ol.View2DProperty.CENTER));
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.View2D.prototype,
|
||||
'getCenter',
|
||||
ol.View2D.prototype.getCenter);
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Size} size Box pixel size.
|
||||
* @return {ol.Extent} Extent.
|
||||
*/
|
||||
ol.View2D.prototype.getExtent = function(size) {
|
||||
goog.asserts.assert(this.isDef());
|
||||
var center = this.getCenter();
|
||||
var resolution = this.getResolution();
|
||||
var minX = center.x - resolution * size.width / 2;
|
||||
var minY = center.y - resolution * size.height / 2;
|
||||
var maxX = center.x + resolution * size.width / 2;
|
||||
var maxY = center.y + resolution * size.height / 2;
|
||||
return new ol.Extent(minX, minY, maxX, maxY);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.View2D.prototype.getProjection = function() {
|
||||
return /** @type {ol.Projection|undefined} */ (
|
||||
this.get(ol.View2DProperty.PROJECTION));
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.View2D.prototype,
|
||||
'getProjection',
|
||||
ol.View2D.prototype.getProjection);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.View2D.prototype.getResolution = function() {
|
||||
return /** @type {number|undefined} */ (
|
||||
this.get(ol.View2DProperty.RESOLUTION));
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.View2D.prototype,
|
||||
'getResolution',
|
||||
ol.View2D.prototype.getResolution);
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {ol.Size} size Box pixel size.
|
||||
* @return {number} Resolution.
|
||||
*/
|
||||
ol.View2D.prototype.getResolutionForExtent = function(extent, size) {
|
||||
var xResolution = (extent.maxX - extent.minX) / size.width;
|
||||
var yResolution = (extent.maxY - extent.minY) / size.height;
|
||||
return Math.max(xResolution, yResolution);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Map rotation.
|
||||
*/
|
||||
ol.View2D.prototype.getRotation = function() {
|
||||
return /** @type {number|undefined} */ (
|
||||
this.get(ol.View2DProperty.ROTATION)) || 0;
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.View2D.prototype,
|
||||
'getRotation',
|
||||
ol.View2D.prototype.getRotation);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.View2D.prototype.getView2D = function() {
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.View2D.prototype.getView2DState = function() {
|
||||
goog.asserts.assert(this.isDef());
|
||||
var center = /** @type {ol.Coordinate} */ (this.getCenter());
|
||||
var projection = /** @type {ol.Projection} */ (this.getProjection());
|
||||
var resolution = /** @type {number} */ (this.getResolution());
|
||||
var rotation = /** @type {number} */ (this.getRotation());
|
||||
return {
|
||||
center: new ol.Coordinate(center.x, center.y),
|
||||
projection: projection,
|
||||
resolution: resolution,
|
||||
rotation: rotation
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FIXME return type
|
||||
*/
|
||||
ol.View2D.prototype.getView3D = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {ol.Size} size Box pixel size.
|
||||
*/
|
||||
ol.View2D.prototype.fitExtent = function(extent, size) {
|
||||
this.setCenter(extent.getCenter());
|
||||
var resolution = this.getResolutionForExtent(extent, size);
|
||||
resolution = this.constraints_.resolution(resolution, 0);
|
||||
this.setResolution(resolution);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Is defined.
|
||||
*/
|
||||
ol.View2D.prototype.isDef = function() {
|
||||
return goog.isDefAndNotNull(this.getCenter()) &&
|
||||
goog.isDef(this.getResolution());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Coordinate|undefined} center Center.
|
||||
*/
|
||||
ol.View2D.prototype.setCenter = function(center) {
|
||||
this.set(ol.View2DProperty.CENTER, center);
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.View2D.prototype,
|
||||
'setCenter',
|
||||
ol.View2D.prototype.setCenter);
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Projection|undefined} projection Projection.
|
||||
*/
|
||||
ol.View2D.prototype.setProjection = function(projection) {
|
||||
this.set(ol.View2DProperty.PROJECTION, projection);
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.View2D.prototype,
|
||||
'setProjection',
|
||||
ol.View2D.prototype.setProjection);
|
||||
|
||||
|
||||
/**
|
||||
* @param {number|undefined} resolution Resolution.
|
||||
*/
|
||||
ol.View2D.prototype.setResolution = function(resolution) {
|
||||
this.set(ol.View2DProperty.RESOLUTION, resolution);
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.View2D.prototype,
|
||||
'setResolution',
|
||||
ol.View2D.prototype.setResolution);
|
||||
|
||||
|
||||
/**
|
||||
* @param {number|undefined} rotation Rotation.
|
||||
*/
|
||||
ol.View2D.prototype.setRotation = function(rotation) {
|
||||
this.set(ol.View2DProperty.ROTATION, rotation);
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.View2D.prototype,
|
||||
'setRotation',
|
||||
ol.View2D.prototype.setRotation);
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Map} map Map.
|
||||
* @param {number|undefined} rotation Rotation.
|
||||
* @param {number} delta Delta.
|
||||
*/
|
||||
ol.View2D.prototype.rotate = function(map, rotation, delta) {
|
||||
rotation = this.constraints_.rotation(rotation, delta);
|
||||
this.setRotation(rotation);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {ol.Map} map Map.
|
||||
* @param {number|undefined} resolution Resolution to go to.
|
||||
* @param {ol.Coordinate=} opt_anchor Anchor coordinate.
|
||||
*/
|
||||
ol.View2D.prototype.zoom_ = function(map, resolution, opt_anchor) {
|
||||
if (goog.isDefAndNotNull(resolution) && goog.isDefAndNotNull(opt_anchor)) {
|
||||
var anchor = opt_anchor;
|
||||
var oldCenter = /** @type {!ol.Coordinate} */ (this.getCenter());
|
||||
var oldResolution = this.getResolution();
|
||||
var x = anchor.x - resolution * (anchor.x - oldCenter.x) / oldResolution;
|
||||
var y = anchor.y - resolution * (anchor.y - oldCenter.y) / oldResolution;
|
||||
var center = new ol.Coordinate(x, y);
|
||||
map.withFrozenRendering(function() {
|
||||
this.setCenter(center);
|
||||
this.setResolution(resolution);
|
||||
}, this);
|
||||
} else {
|
||||
this.setResolution(resolution);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Map} map Map.
|
||||
* @param {number} delta Delta from previous zoom level.
|
||||
* @param {ol.Coordinate=} opt_anchor Anchor coordinate.
|
||||
*/
|
||||
ol.View2D.prototype.zoom = function(map, delta, opt_anchor) {
|
||||
var resolution = this.constraints_.resolution(this.getResolution(), delta);
|
||||
this.zoom_(map, resolution, opt_anchor);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Map} map Map.
|
||||
* @param {number|undefined} resolution Resolution to go to.
|
||||
* @param {ol.Coordinate=} opt_anchor Anchor coordinate.
|
||||
*/
|
||||
ol.View2D.prototype.zoomToResolution = function(map, resolution, opt_anchor) {
|
||||
resolution = this.constraints_.resolution(resolution, 0);
|
||||
this.zoom_(map, resolution, opt_anchor);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {ol.View2DOptions} view2DOptions View2D options.
|
||||
* @return {ol.Constraints} Constraints.
|
||||
*/
|
||||
ol.View2D.createConstraints_ = function(view2DOptions) {
|
||||
var resolutionConstraint;
|
||||
if (goog.isDef(view2DOptions.resolutions)) {
|
||||
resolutionConstraint = ol.ResolutionConstraint.createSnapToResolutions(
|
||||
view2DOptions.resolutions);
|
||||
} else {
|
||||
var maxResolution, numZoomLevels, zoomFactor;
|
||||
if (goog.isDef(view2DOptions.maxResolution) &&
|
||||
goog.isDef(view2DOptions.numZoomLevels) &&
|
||||
goog.isDef(view2DOptions.zoomFactor)) {
|
||||
maxResolution = view2DOptions.maxResolution;
|
||||
numZoomLevels = view2DOptions.numZoomLevels;
|
||||
zoomFactor = view2DOptions.zoomFactor;
|
||||
} else {
|
||||
var projectionExtent = ol.Projection.createProjection(
|
||||
view2DOptions.projection, 'EPSG:3857').getExtent();
|
||||
maxResolution = Math.max(
|
||||
projectionExtent.maxX - projectionExtent.minX,
|
||||
projectionExtent.maxY - projectionExtent.minY) / 256;
|
||||
// number of steps we want between two data resolutions
|
||||
var numSteps = 4;
|
||||
numZoomLevels = 29 * numSteps;
|
||||
zoomFactor = Math.exp(Math.log(2) / numSteps);
|
||||
}
|
||||
resolutionConstraint = ol.ResolutionConstraint.createSnapToPower(
|
||||
zoomFactor, maxResolution, numZoomLevels - 1);
|
||||
}
|
||||
// FIXME rotation constraint is not configurable at the moment
|
||||
var rotationConstraint = ol.RotationConstraint.none;
|
||||
return new ol.Constraints(resolutionConstraint, rotationConstraint);
|
||||
};
|
||||
Reference in New Issue
Block a user