Merge from master
This commit is contained in:
4
src/ol/animation.exports
Normal file
4
src/ol/animation.exports
Normal file
@@ -0,0 +1,4 @@
|
||||
@exportSymbol ol.animation
|
||||
@exportProperty ol.animation.createBounce
|
||||
@exportProperty ol.animation.createPanFrom
|
||||
@exportProperty ol.animation.createSpin
|
||||
@@ -1,10 +1,10 @@
|
||||
// FIXME works for View2D only
|
||||
// FIXME dependency on ol.View2D suppressed to prevent dependency loop
|
||||
|
||||
goog.provide('ol.animation');
|
||||
|
||||
goog.require('goog.fx.easing');
|
||||
goog.require('ol.PreRenderFunction');
|
||||
goog.require('ol.View2D');
|
||||
goog.require('ol.easing');
|
||||
|
||||
|
||||
@@ -107,3 +107,36 @@ ol.animation.createSpin =
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} sourceResolution Source 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.createZoomFrom =
|
||||
function(sourceResolution, 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.linear;
|
||||
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 deltaResolution =
|
||||
sourceResolution - frameState.view2DState.resolution;
|
||||
frameState.animate = true;
|
||||
frameState.view2DState.resolution += delta * deltaResolution;
|
||||
frameState.viewHints[ol.ViewHint.ANIMATING] += 1;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
goog.provide('ol.Attribution');
|
||||
|
||||
goog.require('ol.CoverageArea');
|
||||
goog.require('ol.Projection');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {string} html HTML.
|
||||
* @param {Array.<ol.CoverageArea>=} opt_coverageAreas Coverage areas.
|
||||
* @param {ol.Projection=} opt_projection Projection.
|
||||
* @param {Object.<string, Array.<ol.TileRange>>=} opt_tileRanges Tile ranges.
|
||||
*/
|
||||
ol.Attribution = function(html, opt_coverageAreas, opt_projection) {
|
||||
ol.Attribution = function(html, opt_tileRanges) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -21,38 +17,40 @@ ol.Attribution = function(html, opt_coverageAreas, opt_projection) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<ol.CoverageArea>}
|
||||
* @type {Object.<string, Array.<ol.TileRange>>}
|
||||
*/
|
||||
this.coverageAreas_ = opt_coverageAreas || null;
|
||||
this.tileRanges_ = opt_tileRanges || null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Projection}
|
||||
*/
|
||||
this.projection_ = opt_projection || null;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array.<ol.CoverageArea>} Coverage areas.
|
||||
*/
|
||||
ol.Attribution.prototype.getCoverageAreas = function() {
|
||||
return this.coverageAreas_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} HTML.
|
||||
*/
|
||||
ol.Attribution.prototype.getHtml = function() {
|
||||
ol.Attribution.prototype.getHTML = function() {
|
||||
return this.html_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Projection} Projection.
|
||||
* @param {Object.<string, ol.TileRange>} tileRanges Tile ranges.
|
||||
* @return {boolean} Intersects any tile range.
|
||||
*/
|
||||
ol.Attribution.prototype.getProjection = function() {
|
||||
return this.projection_;
|
||||
ol.Attribution.prototype.intersectsAnyTileRange = function(tileRanges) {
|
||||
if (goog.isNull(this.tileRanges_)) {
|
||||
return true;
|
||||
}
|
||||
var i, tileRange, z;
|
||||
for (z in tileRanges) {
|
||||
if (!(z in this.tileRanges_)) {
|
||||
continue;
|
||||
}
|
||||
tileRange = tileRanges[z];
|
||||
for (i = 0; i < this.tileRanges_[z].length; ++i) {
|
||||
if (this.tileRanges_[z][i].intersects(tileRange)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
21
src/ol/canvas/canvas.js
Normal file
21
src/ol/canvas/canvas.js
Normal file
@@ -0,0 +1,21 @@
|
||||
goog.provide('ol.canvas');
|
||||
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.dom.TagName');
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Is supported.
|
||||
*/
|
||||
ol.canvas.isSupported = function() {
|
||||
if (!('HTMLCanvasElement' in goog.global)) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
var canvas = /** @type {HTMLCanvasElement} */
|
||||
(goog.dom.createElement(goog.dom.TagName.CANVAS));
|
||||
return !goog.isNull(canvas.getContext('2d'));
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -1,6 +1,7 @@
|
||||
goog.provide('ol.Color');
|
||||
|
||||
goog.require('goog.color');
|
||||
goog.require('goog.math');
|
||||
|
||||
|
||||
|
||||
@@ -9,29 +10,29 @@ goog.require('goog.color');
|
||||
* @param {number} r Red, 0 to 255.
|
||||
* @param {number} g Green, 0 to 255.
|
||||
* @param {number} b Blue, 0 to 255.
|
||||
* @param {number} a Alpha, 0 (fully transparent) to 255 (fully opaque).
|
||||
* @param {number} a Alpha, 0 (fully transparent) to 1 (fully opaque).
|
||||
*/
|
||||
ol.Color = function(r, g, b, a) {
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.r = r;
|
||||
this.r = goog.math.clamp(r, 0, 255);
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.g = g;
|
||||
this.g = goog.math.clamp(g, 0, 255);
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.b = b;
|
||||
this.b = goog.math.clamp(b, 0, 255);
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a = a;
|
||||
this.a = goog.math.clamp(a, 0, 1);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1,24 +1,15 @@
|
||||
// FIXME handle rotation
|
||||
// FIXME handle date line wrap
|
||||
// FIXME handle layer order
|
||||
// FIXME check clean-up code
|
||||
// FIXME works for View2D only
|
||||
|
||||
goog.provide('ol.control.Attribution');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.dom.TagName');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.object');
|
||||
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.MapEventType');
|
||||
goog.require('ol.control.Control');
|
||||
goog.require('ol.layer.Layer');
|
||||
|
||||
|
||||
|
||||
@@ -36,324 +27,50 @@ ol.control.Attribution = function(attributionOptions) {
|
||||
'class': 'ol-attribution'
|
||||
}, this.ulElement_);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<number, ?number>}
|
||||
*/
|
||||
this.layerVisibleChangeListenerKeys_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<number, Element>}
|
||||
*/
|
||||
this.attributionElements_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<number, Array.<ol.CoverageArea>>}
|
||||
*/
|
||||
this.coverageAreass_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
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,
|
||||
target: attributionOptions.target
|
||||
});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.renderedVisible_ = true;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, Element>}
|
||||
*/
|
||||
this.attributionElements_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, boolean>}
|
||||
*/
|
||||
this.attributionElementRenderedVisible_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<?number>}
|
||||
*/
|
||||
this.listenerKeys_ = null;
|
||||
|
||||
};
|
||||
goog.inherits(ol.control.Attribution, ol.control.Control);
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.layer.Layer} layer Layer.
|
||||
* @protected
|
||||
* @param {ol.MapEvent} mapEvent Map event.
|
||||
*/
|
||||
ol.control.Attribution.prototype.addLayer = function(layer) {
|
||||
|
||||
var layerKey = goog.getUid(layer);
|
||||
|
||||
this.layerVisibleChangeListenerKeys_[layerKey] = goog.events.listen(
|
||||
layer, ol.Object.getChangedEventType(ol.layer.LayerProperty.VISIBLE),
|
||||
this.handleLayerVisibleChanged, false, this);
|
||||
|
||||
if (layer.getSource().isReady()) {
|
||||
this.createAttributionElementsForLayer_(layer);
|
||||
ol.control.Attribution.prototype.handleMapPostrender = function(mapEvent) {
|
||||
var frameState = mapEvent.frameState;
|
||||
if (goog.isNull(frameState)) {
|
||||
this.updateElement_(null);
|
||||
} else {
|
||||
goog.events.listenOnce(layer, goog.events.EventType.LOAD,
|
||||
this.handleLayerLoad, false, this);
|
||||
this.updateElement_(frameState.tileUsage);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.layer.Layer} layer Layer.
|
||||
* @private
|
||||
*/
|
||||
ol.control.Attribution.prototype.createAttributionElementsForLayer_ =
|
||||
function(layer) {
|
||||
|
||||
var source = layer.getSource();
|
||||
var attributions = source.getAttributions();
|
||||
if (goog.isNull(attributions)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var map = this.getMap();
|
||||
var mapIsDef = map.isDef();
|
||||
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 {
|
||||
attributionVisibilities = null;
|
||||
}
|
||||
|
||||
goog.array.forEach(attributions, function(attribution) {
|
||||
|
||||
var attributionKey = goog.getUid(attribution);
|
||||
|
||||
var attributionElement = goog.dom.createElement(goog.dom.TagName.LI);
|
||||
attributionElement.innerHTML = attribution.getHtml();
|
||||
|
||||
if (!mapIsDef ||
|
||||
!layerVisible ||
|
||||
goog.isNull(attributionVisibilities) ||
|
||||
!attributionVisibilities[attributionKey]) {
|
||||
if (goog.style.isElementShown(attributionElement)) {
|
||||
goog.style.showElement(attributionElement, false);
|
||||
}
|
||||
}
|
||||
|
||||
goog.dom.appendChild(this.ulElement_, attributionElement);
|
||||
|
||||
this.attributionElements_[attributionKey] = attributionElement;
|
||||
|
||||
}, this);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.layer.Layer} layer Layer.
|
||||
* @param {ol.Extent} mapExtent View extent.
|
||||
* @param {number} mapResolution View resolution.
|
||||
* @param {ol.Projection} mapProjection Map projection.
|
||||
* @return {Object.<number, boolean>} Attribution visibilities.
|
||||
* @private
|
||||
*/
|
||||
ol.control.Attribution.prototype.getLayerAttributionVisiblities_ =
|
||||
function(layer, mapExtent, mapResolution, mapProjection) {
|
||||
|
||||
var source = layer.getSource();
|
||||
var attributions = source.getAttributions();
|
||||
|
||||
if (goog.isNull(attributions)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var mapZ;
|
||||
if (source instanceof ol.source.TileSource) {
|
||||
var tileSource = /** @type {ol.source.TileSource} */ (source);
|
||||
var tileGrid = tileSource.getTileGrid();
|
||||
mapZ = tileGrid.getZForResolution(mapResolution);
|
||||
}
|
||||
|
||||
var attributionVisibilities = {};
|
||||
goog.array.forEach(attributions, function(attribution) {
|
||||
|
||||
var attributionKey = goog.getUid(attribution);
|
||||
|
||||
var attributionVisible = true;
|
||||
|
||||
var coverageAreas;
|
||||
if (attributionKey in this.coverageAreass_) {
|
||||
coverageAreas = this.coverageAreass_[attributionKey];
|
||||
} else {
|
||||
var attributionProjection = attribution.getProjection();
|
||||
coverageAreas = attribution.getCoverageAreas();
|
||||
if (!goog.isNull(coverageAreas) &&
|
||||
!ol.Projection.equivalent(attributionProjection, mapProjection)) {
|
||||
var transformFn = ol.Projection.getTransform(
|
||||
attributionProjection, mapProjection);
|
||||
if (transformFn !== ol.Projection.cloneTransform) {
|
||||
coverageAreas = goog.array.map(coverageAreas, function(coverageArea) {
|
||||
return coverageArea.transform(transformFn);
|
||||
});
|
||||
}
|
||||
}
|
||||
this.coverageAreass_[attributionKey] = coverageAreas;
|
||||
}
|
||||
|
||||
if (!goog.isNull(coverageAreas)) {
|
||||
if (source instanceof ol.source.TileSource) {
|
||||
attributionVisible = goog.array.some(
|
||||
coverageAreas,
|
||||
function(coverageArea, index) {
|
||||
return coverageArea.intersectsExtentAndZ(mapExtent, mapZ);
|
||||
});
|
||||
} else {
|
||||
attributionVisible = goog.array.some(
|
||||
coverageAreas,
|
||||
function(coverageArea) {
|
||||
return coverageArea.intersectsExtentAndResolution(
|
||||
mapExtent, mapResolution);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
attributionVisibilities[attributionKey] = attributionVisible;
|
||||
|
||||
}, this);
|
||||
|
||||
return attributionVisibilities;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.events.Event} event Event.
|
||||
*/
|
||||
ol.control.Attribution.prototype.handleLayerLoad = function(event) {
|
||||
var layer = /** @type {ol.layer.Layer} */ (event.target);
|
||||
this.createAttributionElementsForLayer_(layer);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.events.Event} event Event.
|
||||
* @protected
|
||||
*/
|
||||
ol.control.Attribution.prototype.handleLayerVisibleChanged = function(event) {
|
||||
var layer = /** @type {ol.layer.Layer} */ (event.target);
|
||||
this.updateLayerAttributionsVisibility_(layer);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.CollectionEvent} collectionEvent Collection event.
|
||||
* @protected
|
||||
*/
|
||||
ol.control.Attribution.prototype.handleLayersAdd = function(collectionEvent) {
|
||||
var layer = /** @type {ol.layer.Layer} */ (collectionEvent.elem);
|
||||
this.addLayer(layer);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.CollectionEvent} collectionEvent Collection event.
|
||||
* @protected
|
||||
*/
|
||||
ol.control.Attribution.prototype.handleLayersRemove =
|
||||
function(collectionEvent) {
|
||||
var layer = /** @type {ol.layer.Layer} */ (collectionEvent.elem);
|
||||
this.removeLayer(layer);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
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();
|
||||
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)
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
ol.control.Attribution.prototype.handleMapLayersChanged = function() {
|
||||
if (!goog.isNull(this.layersListenerKeys_)) {
|
||||
goog.array.forEach(this.layersListenerKeys_, goog.events.unlistenByKey);
|
||||
this.layersListenerKeys_ = null;
|
||||
}
|
||||
goog.object.forEach(this.attributionElements_, function(attributionElement) {
|
||||
goog.dom.removeNode(attributionElement);
|
||||
}, this);
|
||||
this.attributionElements_ = {};
|
||||
this.coverageAreass_ = {};
|
||||
var map = this.getMap();
|
||||
var layers = map.getLayers();
|
||||
if (goog.isDefAndNotNull(layers)) {
|
||||
layers.forEach(this.addLayer, this);
|
||||
this.layersListenerKeys_ = [
|
||||
goog.events.listen(layers, ol.CollectionEventType.ADD,
|
||||
this.handleLayersAdd, false, this),
|
||||
goog.events.listen(layers, ol.CollectionEventType.REMOVE,
|
||||
this.handleLayersRemove, false, this)
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.layer.Layer} layer Layer.
|
||||
* @protected
|
||||
*/
|
||||
ol.control.Attribution.prototype.removeLayer = function(layer) {
|
||||
|
||||
var layerKey = goog.getUid(layer);
|
||||
|
||||
goog.events.unlistenByKey(this.layerVisibleChangeListenerKeys_[layerKey]);
|
||||
delete this.layerVisibleChangeListenerKeys_[layerKey];
|
||||
|
||||
goog.array.forEach(
|
||||
layer.getSource().getAttributions(),
|
||||
function(attribution) {
|
||||
var attributionKey = goog.getUid(attribution);
|
||||
delete this.coverageAreass_[attributionKey];
|
||||
var attributionElement = this.attributionElements_[attributionKey];
|
||||
goog.dom.removeNode(attributionElement);
|
||||
delete this.attributionElements_[attributionKey];
|
||||
},
|
||||
this);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -361,79 +78,116 @@ ol.control.Attribution.prototype.removeLayer = function(layer) {
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.control.Attribution.prototype.setMap = function(map) {
|
||||
if (!goog.isNull(this.mapListenerKeys_)) {
|
||||
goog.array.forEach(this.mapListenerKeys_, goog.events.unlistenByKey);
|
||||
if (!goog.isNull(this.listenerKeys_)) {
|
||||
goog.array.forEach(this.listenerKeys_, goog.events.unlistenByKey);
|
||||
this.listenerKeys_ = null;
|
||||
}
|
||||
this.mapListenerKeys_ = null;
|
||||
goog.base(this, 'setMap', map);
|
||||
if (!goog.isNull(map)) {
|
||||
this.mapListenerKeys_ = [
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.LAYERS),
|
||||
this.handleMapLayersChanged, false, this),
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.SIZE),
|
||||
this.updateAttributions, false, this),
|
||||
goog.events.listen(
|
||||
map, ol.Object.getChangedEventType(ol.MapProperty.VIEW),
|
||||
this.updateAttributions, false, this)
|
||||
this.listenerKeys_ = [
|
||||
goog.events.listen(map, ol.MapEventType.POSTRENDER,
|
||||
this.handleMapPostrender, 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.
|
||||
* @private
|
||||
* @param {?Object.<string, Object.<string, ol.TileRange>>} tileUsage Tile
|
||||
* usage.
|
||||
*/
|
||||
ol.control.Attribution.prototype.updateLayerAttributionsVisibility_ =
|
||||
function(layer) {
|
||||
ol.control.Attribution.prototype.updateElement_ = function(tileUsage) {
|
||||
|
||||
if (goog.isNull(tileUsage)) {
|
||||
if (this.renderedVisible_) {
|
||||
goog.style.showElement(this.element, false);
|
||||
this.renderedVisible_ = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
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(
|
||||
attributionVisibilities,
|
||||
function(attributionVisible, attributionKey) {
|
||||
var attributionElement = this.attributionElements_[attributionKey];
|
||||
if (goog.style.isElementShown(attributionElement) !=
|
||||
attributionVisible) {
|
||||
goog.style.showElement(attributionElement, attributionVisible);
|
||||
}
|
||||
},
|
||||
this);
|
||||
} else {
|
||||
var source = layer.getSource();
|
||||
var attributions = source.getAttributions();
|
||||
if (!goog.isNull(attributions)) {
|
||||
goog.array.forEach(attributions, function(attribution) {
|
||||
var attributionKey = goog.getUid(attribution);
|
||||
var attributionElement = this.attributionElements_[attributionKey];
|
||||
goog.style.showElement(attributionElement, false);
|
||||
}, this);
|
||||
|
||||
/** @type {Object.<string, boolean>} */
|
||||
var attributionsToRemove = {};
|
||||
/** @type {Object.<string, ol.source.TileSource>} */
|
||||
var tileSources = {};
|
||||
var layers = map.getLayers();
|
||||
if (goog.isDef(layers)) {
|
||||
layers.forEach(function(layer) {
|
||||
var source = layer.getSource();
|
||||
if (source instanceof ol.source.TileSource) {
|
||||
tileSources[goog.getUid(source).toString()] = source;
|
||||
}
|
||||
var attributions = source.getAttributions();
|
||||
if (!goog.isNull(attributions)) {
|
||||
var attribution, i;
|
||||
for (i = 0; i < attributions.length; ++i) {
|
||||
attribution = attributions[i];
|
||||
attributionKey = goog.getUid(attribution).toString();
|
||||
attributionsToRemove[attributionKey] = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** @type {Object.<string, ol.Attribution>} */
|
||||
var attributions = {};
|
||||
var i, tileRanges, tileSource, tileSourceAttribution,
|
||||
tileSourceAttributionKey, tileSourceAttributions, tileSourceKey, z;
|
||||
for (tileSourceKey in tileUsage) {
|
||||
goog.asserts.assert(tileSourceKey in tileSources);
|
||||
tileSource = tileSources[tileSourceKey];
|
||||
tileSourceAttributions = tileSource.getAttributions();
|
||||
if (goog.isNull(tileSourceAttributions)) {
|
||||
continue;
|
||||
}
|
||||
tileRanges = tileUsage[tileSourceKey];
|
||||
for (i = 0; i < tileSourceAttributions.length; ++i) {
|
||||
tileSourceAttribution = tileSourceAttributions[i];
|
||||
tileSourceAttributionKey = goog.getUid(tileSourceAttribution).toString();
|
||||
if (tileSourceAttributionKey in attributions) {
|
||||
continue;
|
||||
}
|
||||
if (tileSourceAttribution.intersectsAnyTileRange(tileRanges)) {
|
||||
attributions[tileSourceAttributionKey] = tileSourceAttribution;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {Array.<number>} */
|
||||
var attributionKeys =
|
||||
goog.array.map(goog.object.getKeys(attributions), Number);
|
||||
goog.array.sort(attributionKeys);
|
||||
var attributionElement, attributionKey;
|
||||
for (i = 0; i < attributionKeys.length; ++i) {
|
||||
attributionKey = attributionKeys[i].toString();
|
||||
if (attributionKey in this.attributionElements_) {
|
||||
if (!this.attributionElementRenderedVisible_[attributionKey]) {
|
||||
goog.style.showElement(this.attributionElements_[attributionKey], true);
|
||||
this.attributionElementRenderedVisible_[attributionKey] = true;
|
||||
}
|
||||
} else {
|
||||
attributionElement = goog.dom.createElement(goog.dom.TagName.LI);
|
||||
attributionElement.innerHTML = attributions[attributionKey].getHTML();
|
||||
goog.dom.appendChild(this.ulElement_, attributionElement);
|
||||
this.attributionElements_[attributionKey] = attributionElement;
|
||||
this.attributionElementRenderedVisible_[attributionKey] = true;
|
||||
}
|
||||
delete attributionsToRemove[attributionKey];
|
||||
}
|
||||
|
||||
for (attributionKey in attributionsToRemove) {
|
||||
goog.dom.removeNode(this.attributionElements_[attributionKey]);
|
||||
delete this.attributionElements_[attributionKey];
|
||||
delete this.attributionElementRenderedVisible_[attributionKey];
|
||||
}
|
||||
|
||||
var renderVisible = !goog.array.isEmpty(attributionKeys);
|
||||
if (this.renderedVisible_ != renderVisible) {
|
||||
goog.style.showElement(this.element, renderVisible);
|
||||
this.renderedVisible_ = renderVisible;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -11,6 +11,12 @@ goog.require('ol.Projection');
|
||||
goog.require('ol.control.Control');
|
||||
|
||||
|
||||
/**
|
||||
* @define {number} Zoom duration.
|
||||
*/
|
||||
ol.control.ZOOM_DURATION = 250;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
@@ -61,8 +67,9 @@ ol.control.Zoom.prototype.handleIn_ = function(browserEvent) {
|
||||
// prevent #zoomIn anchor from getting appended to the url
|
||||
browserEvent.preventDefault();
|
||||
var map = this.getMap();
|
||||
map.requestRenderFrame();
|
||||
// FIXME works for View2D only
|
||||
map.getView().zoom(map, this.delta_);
|
||||
map.getView().zoom(map, this.delta_, undefined, ol.control.ZOOM_DURATION);
|
||||
};
|
||||
|
||||
|
||||
@@ -74,6 +81,7 @@ ol.control.Zoom.prototype.handleOut_ = function(browserEvent) {
|
||||
// prevent #zoomOut anchor from getting appended to the url
|
||||
browserEvent.preventDefault();
|
||||
var map = this.getMap();
|
||||
map.requestRenderFrame();
|
||||
// FIXME works for View2D only
|
||||
map.getView().zoom(map, -this.delta_);
|
||||
map.getView().zoom(map, -this.delta_, undefined, ol.control.ZOOM_DURATION);
|
||||
};
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
goog.provide('ol.CoverageArea');
|
||||
|
||||
goog.require('ol.Extent');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Represents a rectangular area.
|
||||
*
|
||||
* @constructor
|
||||
* @param {ol.Extent} extent Extent.
|
||||
*/
|
||||
ol.CoverageArea = function(extent) {
|
||||
|
||||
/**
|
||||
* @type {ol.Extent}
|
||||
*/
|
||||
this.extent = extent;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @return {boolean} Intersects.
|
||||
*/
|
||||
ol.CoverageArea.prototype.intersectsExtent = function(extent) {
|
||||
return this.extent.intersects(extent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {number} resolution Resolution.
|
||||
* @return {boolean} Intersects.
|
||||
*/
|
||||
ol.CoverageArea.prototype.intersectsExtentAndResolution = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {number} z Z.
|
||||
* @return {boolean} Intersects.
|
||||
*/
|
||||
ol.CoverageArea.prototype.intersectsExtentAndZ = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.TransformFunction} transformFn Transform.
|
||||
* @return {ol.CoverageArea} Transformed coverage area.
|
||||
*/
|
||||
ol.CoverageArea.prototype.transform = function(transformFn) {
|
||||
var extent = this.extent.transform(transformFn);
|
||||
return new ol.CoverageArea(extent);
|
||||
};
|
||||
@@ -1,6 +1,15 @@
|
||||
goog.provide('ol.easing');
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} t Input between 0 and 1.
|
||||
* @return {number} Output between 0 and 1.
|
||||
*/
|
||||
ol.easing.linear = function(t) {
|
||||
return t;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} t Input between 0 and 1.
|
||||
* @return {number} Output between 0 and 1.
|
||||
|
||||
@@ -10,6 +10,7 @@ goog.require('ol.Coordinate');
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.Size');
|
||||
goog.require('ol.TileQueue');
|
||||
goog.require('ol.TileRange');
|
||||
goog.require('ol.View2DState');
|
||||
goog.require('ol.layer.LayerState');
|
||||
|
||||
@@ -25,6 +26,7 @@ goog.require('ol.layer.LayerState');
|
||||
* postRenderFunctions: Array.<ol.PostRenderFunction>,
|
||||
* size: ol.Size,
|
||||
* tileQueue: ol.TileQueue,
|
||||
* tileUsage: Object.<string, Object.<string, ol.TileRange>>,
|
||||
* time: number,
|
||||
* view2DState: ol.View2DState,
|
||||
* viewHints: Array.<number>}}
|
||||
|
||||
@@ -8,6 +8,12 @@ goog.require('ol.View2D');
|
||||
goog.require('ol.interaction.Interaction');
|
||||
|
||||
|
||||
/**
|
||||
* @define {number} Zoom duration.
|
||||
*/
|
||||
ol.interaction.KEYBOARD_ZOOM_DURATION = 100;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
@@ -31,10 +37,11 @@ ol.interaction.KeyboardZoom.prototype.handleMapBrowserEvent =
|
||||
if (charCode == '+'.charCodeAt(0) || charCode == '-'.charCodeAt(0)) {
|
||||
var map = mapBrowserEvent.map;
|
||||
var delta = (charCode == '+'.charCodeAt(0)) ? 4 : -4;
|
||||
map.requestRenderFrame();
|
||||
// FIXME works for View2D only
|
||||
var view = map.getView();
|
||||
goog.asserts.assert(view instanceof ol.View2D);
|
||||
view.zoom(map, delta);
|
||||
view.zoom(map, delta, undefined, ol.interaction.KEYBOARD_ZOOM_DURATION);
|
||||
keyEvent.preventDefault();
|
||||
mapBrowserEvent.preventDefault();
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
@exportProperty ol.Map.prototype.getInteractions
|
||||
|
||||
@exportSymbol ol.RendererHint
|
||||
@exportProperty ol.RendererHint.CANVAS
|
||||
@exportProperty ol.RendererHint.DOM
|
||||
@exportProperty ol.RendererHint.WEBGL
|
||||
|
||||
|
||||
@exportSymbol ol.RendererHints
|
||||
@exportProperty ol.RendererHints.createFromQueryData
|
||||
|
||||
@@ -54,12 +54,20 @@ goog.require('ol.interaction.MouseWheelZoom');
|
||||
goog.require('ol.interaction.condition');
|
||||
goog.require('ol.renderer.Layer');
|
||||
goog.require('ol.renderer.Map');
|
||||
goog.require('ol.renderer.canvas');
|
||||
goog.require('ol.renderer.canvas.Map');
|
||||
goog.require('ol.renderer.dom');
|
||||
goog.require('ol.renderer.dom.Map');
|
||||
goog.require('ol.renderer.webgl');
|
||||
goog.require('ol.renderer.webgl.Map');
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether to enable canvas.
|
||||
*/
|
||||
ol.ENABLE_CANVAS = true;
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether to enable DOM.
|
||||
*/
|
||||
@@ -76,6 +84,7 @@ ol.ENABLE_WEBGL = true;
|
||||
* @enum {string}
|
||||
*/
|
||||
ol.RendererHint = {
|
||||
CANVAS: 'canvas',
|
||||
DOM: 'dom',
|
||||
WEBGL: 'webgl'
|
||||
};
|
||||
@@ -86,6 +95,7 @@ ol.RendererHint = {
|
||||
*/
|
||||
ol.DEFAULT_RENDERER_HINTS = [
|
||||
ol.RendererHint.WEBGL,
|
||||
ol.RendererHint.CANVAS,
|
||||
ol.RendererHint.DOM
|
||||
];
|
||||
|
||||
@@ -608,7 +618,7 @@ ol.Map.prototype.renderFrame_ = function(time) {
|
||||
frameState = {
|
||||
animate: false,
|
||||
backgroundColor: goog.isDef(backgroundColor) ?
|
||||
backgroundColor : new ol.Color(1, 1, 1, 1),
|
||||
backgroundColor : new ol.Color(255, 255, 255, 1),
|
||||
coordinateToPixelMatrix: this.coordinateToPixelMatrix_,
|
||||
extent: null,
|
||||
layersArray: layersArray,
|
||||
@@ -617,6 +627,7 @@ ol.Map.prototype.renderFrame_ = function(time) {
|
||||
postRenderFunctions: [],
|
||||
size: size,
|
||||
tileQueue: this.tileQueue_,
|
||||
tileUsage: {},
|
||||
view2DState: view2DState,
|
||||
viewHints: viewHints,
|
||||
time: time
|
||||
@@ -794,7 +805,12 @@ ol.Map.createOptionsInternal = function(mapOptions) {
|
||||
var i, rendererHint;
|
||||
for (i = 0; i < rendererHints.length; ++i) {
|
||||
rendererHint = rendererHints[i];
|
||||
if (rendererHint == ol.RendererHint.DOM) {
|
||||
if (rendererHint == ol.RendererHint.CANVAS) {
|
||||
if (ol.ENABLE_CANVAS && ol.renderer.canvas.isSupported()) {
|
||||
rendererConstructor = ol.renderer.canvas.Map;
|
||||
break;
|
||||
}
|
||||
} else if (rendererHint == ol.RendererHint.DOM) {
|
||||
if (ol.ENABLE_DOM && ol.renderer.dom.isSupported()) {
|
||||
rendererConstructor = ol.renderer.dom.Map;
|
||||
break;
|
||||
@@ -931,8 +947,9 @@ ol.Map.createInteractions_ = function(mapOptions) {
|
||||
* @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);
|
||||
var query = goog.global.location.search.substring(1),
|
||||
queryData = goog.isDef(opt_queryData) ?
|
||||
opt_queryData : new goog.Uri.QueryData(query);
|
||||
if (queryData.containsKey('renderers')) {
|
||||
return queryData.get('renderers').split(',');
|
||||
} else if (queryData.containsKey('renderer')) {
|
||||
|
||||
@@ -41,6 +41,17 @@ ol.Rectangle = function(minX, minY, maxX, maxY) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Rectangle} rectangle Rectangle.
|
||||
*/
|
||||
ol.Rectangle.prototype.extend = function(rectangle) {
|
||||
this.minX = Math.min(this.minX, rectangle.minX);
|
||||
this.minY = Math.min(this.minY, rectangle.minY);
|
||||
this.maxX = Math.max(this.maxX, rectangle.maxX);
|
||||
this.maxY = Math.max(this.maxY, rectangle.maxY);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Coordinate} Center.
|
||||
*/
|
||||
|
||||
37
src/ol/renderer/canvas/canvaslayerrenderer.js
Normal file
37
src/ol/renderer/canvas/canvaslayerrenderer.js
Normal file
@@ -0,0 +1,37 @@
|
||||
goog.provide('ol.renderer.canvas.Layer');
|
||||
|
||||
goog.require('ol.FrameState');
|
||||
goog.require('ol.layer.LayerState');
|
||||
goog.require('ol.renderer.Layer');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.renderer.Layer}
|
||||
* @param {ol.renderer.Map} mapRenderer Map renderer.
|
||||
* @param {ol.layer.Layer} layer Layer.
|
||||
*/
|
||||
ol.renderer.canvas.Layer = function(mapRenderer, layer) {
|
||||
goog.base(this, mapRenderer, layer);
|
||||
};
|
||||
goog.inherits(ol.renderer.canvas.Layer, ol.renderer.Layer);
|
||||
|
||||
|
||||
/**
|
||||
* @return {HTMLCanvasElement|HTMLVideoElement|Image} Canvas.
|
||||
*/
|
||||
ol.renderer.canvas.Layer.prototype.getImage = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.vec.Mat4.Number} Transform.
|
||||
*/
|
||||
ol.renderer.canvas.Layer.prototype.getTransform = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.FrameState} frameState Frame state.
|
||||
* @param {ol.layer.LayerState} layerState Layer state.
|
||||
*/
|
||||
ol.renderer.canvas.Layer.prototype.renderFrame = goog.abstractMethod;
|
||||
177
src/ol/renderer/canvas/canvasmaprenderer.js
Normal file
177
src/ol/renderer/canvas/canvasmaprenderer.js
Normal file
@@ -0,0 +1,177 @@
|
||||
// FIXME offset panning
|
||||
|
||||
goog.provide('ol.renderer.canvas.Map');
|
||||
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.style');
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.Size');
|
||||
goog.require('ol.layer.TileLayer');
|
||||
goog.require('ol.renderer.Map');
|
||||
goog.require('ol.renderer.canvas.TileLayer');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.renderer.Map}
|
||||
* @param {Element} container Container.
|
||||
* @param {ol.Map} map Map.
|
||||
*/
|
||||
ol.renderer.canvas.Map = function(container, map) {
|
||||
|
||||
goog.base(this, container, map);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Size}
|
||||
*/
|
||||
this.canvasSize_ = new ol.Size(container.clientHeight, container.clientWidth);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Element}
|
||||
*/
|
||||
this.canvas_ = goog.dom.createElement(goog.dom.TagName.CANVAS);
|
||||
this.canvas_.height = this.canvasSize_.height;
|
||||
this.canvas_.width = this.canvasSize_.width;
|
||||
this.canvas_.className = 'ol-unselectable';
|
||||
goog.dom.insertChildAt(container, this.canvas_, 0);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.renderedVisible_ = true;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {CanvasRenderingContext2D}
|
||||
*/
|
||||
this.context_ = this.canvas_.getContext('2d');
|
||||
|
||||
};
|
||||
goog.inherits(ol.renderer.canvas.Map, ol.renderer.Map);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.canvas.Map.prototype.createLayerRenderer = function(layer) {
|
||||
if (layer instanceof ol.layer.TileLayer) {
|
||||
return new ol.renderer.canvas.TileLayer(this, layer);
|
||||
} else {
|
||||
goog.asserts.assert(false);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.canvas.Map.prototype.handleBackgroundColorChanged = function() {
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.canvas.Map.prototype.handleViewPropertyChanged = function() {
|
||||
goog.base(this, 'handleViewPropertyChanged');
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.events.Event} event Event.
|
||||
* @protected
|
||||
*/
|
||||
ol.renderer.canvas.Map.prototype.handleLayerRendererChange = function(event) {
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.canvas.Map.prototype.handleSizeChanged = function() {
|
||||
goog.base(this, 'handleSizeChanged');
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.canvas.Map.prototype.handleViewChanged = function() {
|
||||
goog.base(this, 'handleViewChanged');
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.canvas.Map.prototype.renderFrame = function(frameState) {
|
||||
|
||||
if (goog.isNull(frameState)) {
|
||||
if (this.renderedVisible_) {
|
||||
goog.style.showElement(this.canvas_, false);
|
||||
this.renderedVisible_ = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var size = frameState.size;
|
||||
if (!this.canvasSize_.equals(size)) {
|
||||
this.canvas_.width = size.width;
|
||||
this.canvas_.height = size.height;
|
||||
this.canvasSize_ = size;
|
||||
}
|
||||
|
||||
var context = this.context_;
|
||||
context.setTransform(1, 0, 0, 1, 0, 0);
|
||||
var backgroundColor = frameState.backgroundColor;
|
||||
context.fillStyle = 'rgb(' +
|
||||
backgroundColor.r.toFixed(0) + ',' +
|
||||
backgroundColor.g.toFixed(0) + ',' +
|
||||
backgroundColor.b.toFixed(0) + ')';
|
||||
context.globalAlpha = 1;
|
||||
context.fillRect(0, 0, size.width, size.height);
|
||||
|
||||
goog.array.forEach(frameState.layersArray, function(layer) {
|
||||
|
||||
var layerState = frameState.layerStates[goog.getUid(layer)];
|
||||
if (!layerState.visible) {
|
||||
return;
|
||||
} else if (!layerState.ready) {
|
||||
frameState.animate = true;
|
||||
return;
|
||||
}
|
||||
var layerRenderer = this.getLayerRenderer(layer);
|
||||
layerRenderer.renderFrame(frameState, layerState);
|
||||
|
||||
var transform = layerRenderer.getTransform();
|
||||
context.setTransform(
|
||||
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));
|
||||
|
||||
context.globalAlpha = layerState.opacity;
|
||||
context.drawImage(layerRenderer.getImage(), 0, 0);
|
||||
|
||||
}, this);
|
||||
|
||||
if (!this.renderedVisible_) {
|
||||
goog.style.showElement(this.canvas_, true);
|
||||
this.renderedVisible_ = true;
|
||||
}
|
||||
|
||||
this.calculateMatrices2D(frameState);
|
||||
|
||||
};
|
||||
@@ -1,8 +1,10 @@
|
||||
goog.provide('ol.renderer.canvas');
|
||||
goog.provide('ol.renderer.canvas.CanvasRenderer');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.Pixel');
|
||||
goog.require('ol.canvas');
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.renderer.Layer');
|
||||
@@ -12,6 +14,12 @@ goog.require('ol.style.LiteralStroke');
|
||||
goog.require('ol.style.LiteralSymbolizer');
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Is supported.
|
||||
*/
|
||||
ol.renderer.canvas.isSupported = ol.canvas.isSupported;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
@@ -81,7 +89,8 @@ ol.renderer.canvas.CanvasRenderer.prototype.setTarget = function(canvas) {
|
||||
/**
|
||||
* Render a geometry.
|
||||
* @param {ol.geom.Geometry} geometry The geometry to render.
|
||||
* @param {Array.<ol.style.LiteralSymbolizer>} symbolizers Symbolizers to render with.
|
||||
* @param {Array.<ol.style.LiteralSymbolizer>} symbolizers Symbolizers to render
|
||||
* with.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.canvas.CanvasRenderer.prototype.renderGeometry_ =
|
||||
|
||||
236
src/ol/renderer/canvas/canvastilelayerrenderer.js
Normal file
236
src/ol/renderer/canvas/canvastilelayerrenderer.js
Normal file
@@ -0,0 +1,236 @@
|
||||
// FIXME don't redraw tiles if not needed
|
||||
// FIXME find correct globalCompositeOperation
|
||||
// FIXME optimize :-)
|
||||
|
||||
goog.provide('ol.renderer.canvas.TileLayer');
|
||||
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.style');
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.Size');
|
||||
goog.require('ol.TileRange');
|
||||
goog.require('ol.layer.TileLayer');
|
||||
goog.require('ol.renderer.Map');
|
||||
goog.require('ol.renderer.canvas.Layer');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.renderer.canvas.Layer}
|
||||
* @param {ol.renderer.Map} mapRenderer Map renderer.
|
||||
* @param {ol.layer.TileLayer} tileLayer Tile layer.
|
||||
*/
|
||||
ol.renderer.canvas.TileLayer = function(mapRenderer, tileLayer) {
|
||||
|
||||
goog.base(this, mapRenderer, tileLayer);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {HTMLCanvasElement}
|
||||
*/
|
||||
this.canvas_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Size}
|
||||
*/
|
||||
this.canvasSize_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {CanvasRenderingContext2D}
|
||||
*/
|
||||
this.context_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!goog.vec.Mat4.Number}
|
||||
*/
|
||||
this.transform_ = goog.vec.Mat4.createNumber();
|
||||
|
||||
};
|
||||
goog.inherits(ol.renderer.canvas.TileLayer, ol.renderer.canvas.Layer);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.canvas.TileLayer.prototype.getImage = function() {
|
||||
return this.canvas_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.layer.TileLayer} Tile layer.
|
||||
*/
|
||||
ol.renderer.canvas.TileLayer.prototype.getTileLayer = function() {
|
||||
return /** @type {ol.layer.TileLayer} */ (this.getLayer());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.canvas.TileLayer.prototype.getTransform = function() {
|
||||
return this.transform_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.canvas.TileLayer.prototype.renderFrame =
|
||||
function(frameState, layerState) {
|
||||
|
||||
var view2DState = frameState.view2DState;
|
||||
|
||||
var tileLayer = this.getTileLayer();
|
||||
var tileSource = tileLayer.getTileSource();
|
||||
var tileGrid = tileSource.getTileGrid();
|
||||
var tileSize = tileGrid.getTileSize();
|
||||
var z = tileGrid.getZForResolution(view2DState.resolution);
|
||||
var tileResolution = tileGrid.getResolution(z);
|
||||
var tileRange = tileGrid.getTileRangeForExtentAndResolution(
|
||||
frameState.extent, tileResolution);
|
||||
|
||||
var canvasSize = new ol.Size(
|
||||
tileSize.width * tileRange.getWidth(),
|
||||
tileSize.height * tileRange.getHeight());
|
||||
|
||||
var canvas, context;
|
||||
if (goog.isNull(this.canvas_)) {
|
||||
canvas = /** @type {HTMLCanvasElement} */
|
||||
(goog.dom.createElement(goog.dom.TagName.CANVAS));
|
||||
canvas.width = canvasSize.width;
|
||||
canvas.height = canvasSize.height;
|
||||
context = /** @type {CanvasRenderingContext2D} */ (canvas.getContext('2d'));
|
||||
this.canvas_ = canvas;
|
||||
this.canvasSize_ = canvasSize;
|
||||
this.context_ = context;
|
||||
} else {
|
||||
canvas = this.canvas_;
|
||||
context = this.context_;
|
||||
if (!this.canvasSize_.equals(canvasSize)) {
|
||||
canvas.width = canvasSize.width;
|
||||
canvas.height = canvasSize.height;
|
||||
this.canvasSize_ = canvasSize;
|
||||
}
|
||||
}
|
||||
|
||||
context.clearRect(0, 0, canvasSize.width, canvasSize.height);
|
||||
|
||||
/**
|
||||
* @type {Object.<number, Object.<string, ol.Tile>>}
|
||||
*/
|
||||
var tilesToDrawByZ = {};
|
||||
tilesToDrawByZ[z] = {};
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {Array.<number>} */
|
||||
var zs = goog.array.map(goog.object.getKeys(tilesToDrawByZ), Number);
|
||||
goog.array.sort(zs);
|
||||
var origin = tileGrid.getTileCoordExtent(
|
||||
new ol.TileCoord(z, tileRange.minX, tileRange.maxY)).getTopLeft();
|
||||
var currentZ, i, scale, tileCoordKey, tileExtent, tilesToDraw;
|
||||
for (i = 0; i < zs.length; ++i) {
|
||||
currentZ = zs[i];
|
||||
tilesToDraw = tilesToDrawByZ[currentZ];
|
||||
if (currentZ == z) {
|
||||
for (tileCoordKey in tilesToDraw) {
|
||||
tile = tilesToDraw[tileCoordKey];
|
||||
context.drawImage(
|
||||
tile.getImage(),
|
||||
tileSize.width * (tile.tileCoord.x - tileRange.minX),
|
||||
tileSize.height * (tileRange.maxY - tile.tileCoord.y));
|
||||
}
|
||||
} else {
|
||||
scale = tileGrid.getResolution(currentZ) / tileResolution;
|
||||
for (tileCoordKey in tilesToDraw) {
|
||||
tile = tilesToDraw[tileCoordKey];
|
||||
tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord);
|
||||
context.drawImage(
|
||||
tile.getImage(),
|
||||
(tileExtent.minX - origin.x) / tileResolution,
|
||||
(origin.y - tileExtent.maxY) / tileResolution,
|
||||
scale * tileSize.width,
|
||||
scale * tileSize.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!allTilesLoaded) {
|
||||
frameState.animate = true;
|
||||
}
|
||||
|
||||
this.updateTileUsage(frameState.tileUsage, tileSource, z, tileRange);
|
||||
|
||||
var transform = this.transform_;
|
||||
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,
|
||||
tileResolution / view2DState.resolution,
|
||||
tileResolution / view2DState.resolution,
|
||||
1);
|
||||
goog.vec.Mat4.translate(
|
||||
transform,
|
||||
(origin.x - view2DState.center.x) / tileResolution,
|
||||
(view2DState.center.y - origin.y) / tileResolution,
|
||||
0);
|
||||
|
||||
};
|
||||
@@ -29,6 +29,15 @@ ol.renderer.dom.Layer = function(mapRenderer, layer, target) {
|
||||
goog.inherits(ol.renderer.dom.Layer, ol.renderer.Layer);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.Layer.prototype.disposeInternal = function() {
|
||||
goog.dom.removeNode(this.target);
|
||||
goog.base(this, 'disposeInternal');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!Element} Target.
|
||||
*/
|
||||
|
||||
@@ -71,15 +71,6 @@ ol.renderer.dom.Map.prototype.createLayerRenderer = function(layer) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.Map.prototype.removeLayer = function(layer) {
|
||||
goog.base(this, 'removeLayer', layer);
|
||||
this.getMap().render();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
||||
@@ -236,6 +236,8 @@ ol.renderer.dom.TileLayer.prototype.renderFrame =
|
||||
frameState.animate = true;
|
||||
}
|
||||
|
||||
this.updateTileUsage(frameState.tileUsage, tileSource, z, tileRange);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ goog.provide('ol.renderer.Layer');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('ol.Object');
|
||||
goog.require('ol.TileRange');
|
||||
goog.require('ol.layer.Layer');
|
||||
goog.require('ol.layer.LayerProperty');
|
||||
|
||||
@@ -125,3 +126,28 @@ ol.renderer.Layer.prototype.handleLayerSaturationChange = goog.nullFunction;
|
||||
* @protected
|
||||
*/
|
||||
ol.renderer.Layer.prototype.handleLayerVisibleChange = goog.nullFunction;
|
||||
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @param {Object.<string, Object.<string, ol.TileRange>>} tileUsage Tile usage.
|
||||
* @param {ol.source.Source} source Source.
|
||||
* @param {number} z Z.
|
||||
* @param {ol.TileRange} tileRange Tile range.
|
||||
*/
|
||||
ol.renderer.Layer.prototype.updateTileUsage =
|
||||
function(tileUsage, source, z, tileRange) {
|
||||
// FIXME should we use tilesToDrawByZ instead?
|
||||
var sourceKey = goog.getUid(source).toString();
|
||||
var zKey = z.toString();
|
||||
if (sourceKey in tileUsage) {
|
||||
if (z in tileUsage[sourceKey]) {
|
||||
tileUsage[sourceKey][zKey].extend(tileRange);
|
||||
} else {
|
||||
tileUsage[sourceKey][zKey] = tileRange;
|
||||
}
|
||||
} else {
|
||||
tileUsage[sourceKey] = {};
|
||||
tileUsage[sourceKey][zKey] = tileRange;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -490,7 +490,8 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) {
|
||||
gl.bindFramebuffer(goog.webgl.FRAMEBUFFER, null);
|
||||
|
||||
var clearColor = frameState.backgroundColor;
|
||||
gl.clearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
|
||||
gl.clearColor(clearColor.r / 255, clearColor.g / 255,
|
||||
clearColor.b / 255, clearColor.a);
|
||||
gl.clear(goog.webgl.COLOR_BUFFER_BIT);
|
||||
gl.enable(goog.webgl.BLEND);
|
||||
gl.viewport(0, 0, size.width, size.height);
|
||||
|
||||
@@ -277,7 +277,6 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame =
|
||||
frameState.extent, tileResolution);
|
||||
|
||||
var framebufferExtent;
|
||||
|
||||
if (!goog.isNull(this.renderedTileRange_) &&
|
||||
this.renderedTileRange_.equals(tileRange)) {
|
||||
framebufferExtent = this.renderedFramebufferExtent_;
|
||||
@@ -460,6 +459,8 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame =
|
||||
|
||||
}
|
||||
|
||||
this.updateTileUsage(frameState.tileUsage, tileSource, z, tileRange);
|
||||
|
||||
goog.vec.Mat4.makeIdentity(this.matrix_);
|
||||
goog.vec.Mat4.translate(this.matrix_,
|
||||
(view2DState.center.x - framebufferExtent.minX) /
|
||||
|
||||
@@ -5,7 +5,7 @@ goog.require('goog.Uri');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.net.Jsonp');
|
||||
goog.require('ol.TileCoverageArea');
|
||||
goog.require('ol.TileRange');
|
||||
goog.require('ol.source.ImageTileSource');
|
||||
goog.require('ol.tilegrid.XYZ');
|
||||
|
||||
@@ -118,21 +118,35 @@ ol.source.BingMaps.prototype.handleImageryMetadataResponse =
|
||||
};
|
||||
})));
|
||||
|
||||
var projection = ol.Projection.getFromCode('EPSG:4326');
|
||||
var transform = ol.Projection.getTransform(
|
||||
ol.Projection.getFromCode('EPSG:4326'), this.getProjection());
|
||||
var attributions = goog.array.map(
|
||||
resource.imageryProviders,
|
||||
function(imageryProvider) {
|
||||
var html = imageryProvider.attribution;
|
||||
var coverageAreas = goog.array.map(
|
||||
/** @type {Object.<string, Array.<ol.TileRange>>} */
|
||||
var tileRanges = {};
|
||||
goog.array.forEach(
|
||||
imageryProvider.coverageAreas,
|
||||
function(coverageArea) {
|
||||
var bbox = coverageArea.bbox;
|
||||
var extent = new ol.Extent(bbox[1], bbox[0], bbox[3], bbox[2]);
|
||||
var minZ = coverageArea.zoomMin;
|
||||
var maxZ = coverageArea.zoomMax;
|
||||
return new ol.TileCoverageArea(tileGrid, extent, minZ, maxZ);
|
||||
var bbox = coverageArea.bbox;
|
||||
var epsg4326Extent =
|
||||
new ol.Extent(bbox[1], bbox[0], bbox[3], bbox[2]);
|
||||
var extent = epsg4326Extent.transform(transform);
|
||||
var tileRange, z, zKey;
|
||||
for (z = minZ; z <= maxZ; ++z) {
|
||||
zKey = z.toString();
|
||||
tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);
|
||||
if (zKey in tileRanges) {
|
||||
tileRanges[zKey].push(tileRange);
|
||||
} else {
|
||||
tileRanges[zKey] = [tileRange];
|
||||
}
|
||||
}
|
||||
});
|
||||
return new ol.Attribution(html, coverageAreas, projection);
|
||||
return new ol.Attribution(html, tileRanges);
|
||||
});
|
||||
this.setAttributions(attributions);
|
||||
|
||||
|
||||
@@ -1,2 +1,21 @@
|
||||
@exportSymbol ol.source.Stamen
|
||||
|
||||
@exportSymbol ol.source.StamenFlavor
|
||||
@exportProperty ol.source.StamenFlavor.TERRAIN_BACKGROUND
|
||||
@exportProperty ol.source.StamenFlavor.TERRAIN_LABELS
|
||||
@exportProperty ol.source.StamenFlavor.TERRAIN_LINES
|
||||
@exportProperty ol.source.StamenFlavor.TONER_2010
|
||||
@exportProperty ol.source.StamenFlavor.TONER_2011
|
||||
@exportProperty ol.source.StamenFlavor.TONER_2011_LABELS
|
||||
@exportProperty ol.source.StamenFlavor.TONER_2011_LINES
|
||||
@exportProperty ol.source.StamenFlavor.TONER_2011_LITE
|
||||
@exportProperty ol.source.StamenFlavor.TONER_BACKGROUND
|
||||
@exportProperty ol.source.StamenFlavor.TONER_HYBRID
|
||||
@exportProperty ol.source.StamenFlavor.TONER_LABELS
|
||||
@exportProperty ol.source.StamenFlavor.TONER_LINES
|
||||
@exportProperty ol.source.StamenFlavor.TONER_LITE
|
||||
|
||||
@exportSymbol ol.source.StamenProvider
|
||||
@exportProperty ol.source.StamenProvider.TERRAIN
|
||||
@exportProperty ol.source.StamenProvider.TONER
|
||||
@exportProperty ol.source.StamenProvider.WATERCOLOR
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// FIXME Configure minZoom when supported by TileGrid
|
||||
|
||||
goog.provide('ol.source.Stamen');
|
||||
goog.provide('ol.source.StamenFlavor');
|
||||
goog.provide('ol.source.StamenProvider');
|
||||
|
||||
goog.require('ol.source.XYZ');
|
||||
|
||||
@@ -25,13 +27,6 @@ ol.source.StamenFlavor = {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{flavor: (ol.source.StamenFlavor|undefined),
|
||||
* provider: ol.source.StamenProvider}}
|
||||
*/
|
||||
ol.source.StamenOptions;
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
@@ -43,8 +38,7 @@ ol.source.StamenProvider = {
|
||||
|
||||
|
||||
/**
|
||||
* @type {Object.<ol.source.StamenProvider,
|
||||
* {type: string, minZoom: number, maxZoom: number}>}
|
||||
* @type {Object.<string, {type: string, minZoom: number, maxZoom: number}>}
|
||||
*/
|
||||
ol.source.StamenProviderConfig = {};
|
||||
ol.source.StamenProviderConfig[ol.source.StamenProvider.TERRAIN] = {
|
||||
|
||||
@@ -14,7 +14,6 @@ goog.require('goog.events.EventType');
|
||||
goog.require('goog.net.jsloader');
|
||||
goog.require('goog.string');
|
||||
goog.require('ol.Projection');
|
||||
goog.require('ol.TileCoverageArea');
|
||||
goog.require('ol.TileUrlFunction');
|
||||
goog.require('ol.source.ImageTileSource');
|
||||
goog.require('ol.tilegrid.XYZ');
|
||||
@@ -98,17 +97,17 @@ ol.source.TileJSON.prototype.handleTileJSONResponse = function() {
|
||||
if (goog.isDef(tileJSON.scheme)) {
|
||||
goog.asserts.assert(tileJSON.scheme == 'xyz');
|
||||
}
|
||||
var minzoom = tileJSON.minzoom || 0;
|
||||
goog.asserts.assert(minzoom === 0); // FIXME
|
||||
var maxzoom = tileJSON.maxzoom || 22;
|
||||
var minZoom = tileJSON.minzoom || 0;
|
||||
goog.asserts.assert(minZoom === 0); // FIXME
|
||||
var maxZoom = tileJSON.maxzoom || 22;
|
||||
var tileGrid = new ol.tilegrid.XYZ({
|
||||
maxZoom: maxzoom
|
||||
maxZoom: maxZoom
|
||||
});
|
||||
this.tileGrid = tileGrid;
|
||||
|
||||
this.tileUrlFunction = ol.TileUrlFunction.withTileCoordTransform(
|
||||
function(tileCoord) {
|
||||
if (tileCoord.z < minzoom || maxzoom < tileCoord.z) {
|
||||
if (tileCoord.z < minZoom || maxZoom < tileCoord.z) {
|
||||
return null;
|
||||
}
|
||||
var n = 1 << tileCoord.z;
|
||||
@@ -129,13 +128,18 @@ ol.source.TileJSON.prototype.handleTileJSONResponse = function() {
|
||||
ol.TileUrlFunction.createFromTemplates(tileJSON.tiles));
|
||||
|
||||
if (goog.isDef(tileJSON.attribution)) {
|
||||
var coverageAreas = [
|
||||
new ol.TileCoverageArea(tileGrid, epsg4326Extent, minzoom, maxzoom)
|
||||
];
|
||||
var coverageAreaProjection = epsg4326Projection;
|
||||
var attributionExtent = goog.isNull(extent) ?
|
||||
epsg4326Projection.getExtent() : extent;
|
||||
/** @type {Object.<string, Array.<ol.TileRange>>} */
|
||||
var tileRanges = {};
|
||||
var z, zKey;
|
||||
for (z = minZoom; z <= maxZoom; ++z) {
|
||||
zKey = z.toString();
|
||||
tileRanges[zKey] =
|
||||
[tileGrid.getTileRangeForExtentAndZ(attributionExtent, z)];
|
||||
}
|
||||
this.setAttributions([
|
||||
new ol.Attribution(
|
||||
tileJSON.attribution, coverageAreas, coverageAreaProjection)
|
||||
new ol.Attribution(tileJSON.attribution, tileRanges)
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
goog.provide('ol.TileCoverageArea');
|
||||
|
||||
goog.require('ol.CoverageArea');
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.tilegrid.TileGrid');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.CoverageArea}
|
||||
* @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {number} minZ Minimum Z.
|
||||
* @param {number} maxZ Maximum Z.
|
||||
*/
|
||||
ol.TileCoverageArea = function(tileGrid, extent, minZ, maxZ) {
|
||||
|
||||
goog.base(this, extent);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.tilegrid.TileGrid}
|
||||
*/
|
||||
this.tileGrid_ = tileGrid;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.minZ_ = minZ;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.maxZ_ = maxZ;
|
||||
|
||||
};
|
||||
goog.inherits(ol.TileCoverageArea, ol.CoverageArea);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.TileCoverageArea.prototype.intersectsExtentAndResolution =
|
||||
function(extent, resolution) {
|
||||
var z = this.tileGrid_.getZForResolution(resolution);
|
||||
return this.intersectsExtentAndZ(extent, z);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.TileCoverageArea.prototype.intersectsExtentAndZ = function(extent, z) {
|
||||
return this.minZ_ <= z && z <= this.maxZ_ && this.intersectsExtent(extent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.TransformFunction} transformFn Transform.
|
||||
* @return {ol.TileCoverageArea} Transformed tile coverage area.
|
||||
*/
|
||||
ol.TileCoverageArea.prototype.transform = function(transformFn) {
|
||||
var extent = this.extent.transform(transformFn);
|
||||
return new ol.TileCoverageArea(
|
||||
this.tileGrid_, extent, this.minZ_, this.maxZ_);
|
||||
};
|
||||
1
src/ol/tilegrid/tilegrid.exports
Normal file
1
src/ol/tilegrid/tilegrid.exports
Normal file
@@ -0,0 +1 @@
|
||||
@exportClass ol.tilegrid.TileGrid ol.tilegrid.TileGridOptions
|
||||
@@ -1,7 +1,6 @@
|
||||
// FIXME cope with tile grids whose minium zoom is not zero
|
||||
|
||||
goog.provide('ol.tilegrid.TileGrid');
|
||||
goog.provide('ol.tilegrid.TileGridOptions');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
@@ -15,13 +14,9 @@ goog.require('ol.array');
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{extent: (ol.Extent|undefined),
|
||||
* origin: (ol.Coordinate|undefined),
|
||||
* origins: (Array.<ol.Coordinate>|undefined),
|
||||
* resolutions: !Array.<number>,
|
||||
* tileSize: (ol.Size|undefined)}}
|
||||
* @define {number} Default tile size.
|
||||
*/
|
||||
ol.tilegrid.TileGridOptions;
|
||||
ol.DEFAULT_TILE_SIZE = 256;
|
||||
|
||||
|
||||
|
||||
@@ -75,7 +70,8 @@ ol.tilegrid.TileGrid = function(tileGridOptions) {
|
||||
* @type {ol.Size}
|
||||
*/
|
||||
this.tileSize_ = goog.isDef(tileGridOptions.tileSize) ?
|
||||
tileGridOptions.tileSize : new ol.Size(256, 256);
|
||||
tileGridOptions.tileSize :
|
||||
new ol.Size(ol.DEFAULT_TILE_SIZE, ol.DEFAULT_TILE_SIZE);
|
||||
|
||||
};
|
||||
|
||||
@@ -321,21 +317,27 @@ ol.tilegrid.TileGrid.prototype.getZForResolution = function(resolution) {
|
||||
/**
|
||||
* @param {ol.Projection} projection Projection.
|
||||
* @param {number=} opt_maxZoom Maximum zoom level (optional). Default is 18.
|
||||
* @param {ol.Size=} opt_tileSize Tile size.
|
||||
* @return {ol.tilegrid.TileGrid} TileGrid instance.
|
||||
*/
|
||||
ol.tilegrid.createForProjection = function(projection, opt_maxZoom) {
|
||||
ol.tilegrid.createForProjection =
|
||||
function(projection, opt_maxZoom, opt_tileSize) {
|
||||
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 tileSize = goog.isDef(opt_tileSize) ?
|
||||
opt_tileSize : new ol.Size(ol.DEFAULT_TILE_SIZE, ol.DEFAULT_TILE_SIZE);
|
||||
var resolutions = new Array(maxZoom + 1);
|
||||
goog.asserts.assert(tileSize.width == tileSize.height);
|
||||
for (var z = 0, zz = resolutions.length; z < zz; ++z) {
|
||||
resolutions[z] = size / (256 << z);
|
||||
resolutions[z] = size / (tileSize.width << z);
|
||||
}
|
||||
return new ol.tilegrid.TileGrid({
|
||||
origin: projectionExtent.getTopLeft(),
|
||||
resolutions: resolutions
|
||||
resolutions: resolutions,
|
||||
tileSize: tileSize
|
||||
});
|
||||
};
|
||||
|
||||
1
src/ol/tilegrid/xyztilegrid.exports
Normal file
1
src/ol/tilegrid/xyztilegrid.exports
Normal file
@@ -0,0 +1 @@
|
||||
@exportClass ol.tilegrid.XYZ ol.tilegrid.XYZOptions
|
||||
@@ -1,5 +1,4 @@
|
||||
goog.provide('ol.tilegrid.XYZ');
|
||||
goog.provide('ol.tilegrid.XYZOptions');
|
||||
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.Projection');
|
||||
@@ -8,12 +7,6 @@ goog.require('ol.TileRange');
|
||||
goog.require('ol.tilegrid.TileGrid');
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{maxZoom: number}}
|
||||
*/
|
||||
ol.tilegrid.XYZOptions;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
@@ -25,7 +18,8 @@ ol.tilegrid.XYZ = function(xyzOptions) {
|
||||
var resolutions = new Array(xyzOptions.maxZoom + 1);
|
||||
var z;
|
||||
for (z = 0; z <= xyzOptions.maxZoom; ++z) {
|
||||
resolutions[z] = ol.Projection.EPSG_3857_HALF_SIZE / (128 << z);
|
||||
resolutions[z] =
|
||||
2 * ol.Projection.EPSG_3857_HALF_SIZE / (ol.DEFAULT_TILE_SIZE << z);
|
||||
}
|
||||
|
||||
goog.base(this, {
|
||||
@@ -33,7 +27,7 @@ ol.tilegrid.XYZ = function(xyzOptions) {
|
||||
origin: new ol.Coordinate(-ol.Projection.EPSG_3857_HALF_SIZE,
|
||||
ol.Projection.EPSG_3857_HALF_SIZE),
|
||||
resolutions: resolutions,
|
||||
tileSize: new ol.Size(256, 256)
|
||||
tileSize: new ol.Size(ol.DEFAULT_TILE_SIZE, ol.DEFAULT_TILE_SIZE)
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
1
src/ol/view2d.exports
Normal file
1
src/ol/view2d.exports
Normal file
@@ -0,0 +1 @@
|
||||
@exportClass ol.View2D ol.View2DOptions
|
||||
@@ -12,6 +12,7 @@ goog.require('ol.Projection');
|
||||
goog.require('ol.ResolutionConstraint');
|
||||
goog.require('ol.RotationConstraint');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.animation');
|
||||
|
||||
|
||||
/**
|
||||
@@ -52,7 +53,8 @@ ol.View2D = function(opt_view2DOptions) {
|
||||
var size = Math.max(
|
||||
projectionExtent.maxX - projectionExtent.minX,
|
||||
projectionExtent.maxY - projectionExtent.minY);
|
||||
values[ol.View2DProperty.RESOLUTION] = size / (256 << view2DOptions.zoom);
|
||||
values[ol.View2DProperty.RESOLUTION] =
|
||||
size / (ol.DEFAULT_TILE_SIZE << view2DOptions.zoom);
|
||||
}
|
||||
values[ol.View2DProperty.ROTATION] = view2DOptions.rotation;
|
||||
this.setValues(values);
|
||||
@@ -288,9 +290,16 @@ ol.View2D.prototype.zoom_ = function(map, resolution, opt_anchor) {
|
||||
* @param {ol.Map} map Map.
|
||||
* @param {number} delta Delta from previous zoom level.
|
||||
* @param {ol.Coordinate=} opt_anchor Anchor coordinate.
|
||||
* @param {number=} opt_duration Duration.
|
||||
*/
|
||||
ol.View2D.prototype.zoom = function(map, delta, opt_anchor) {
|
||||
var resolution = this.constraints_.resolution(this.getResolution(), delta);
|
||||
ol.View2D.prototype.zoom = function(map, delta, opt_anchor, opt_duration) {
|
||||
var currentResolution = this.getResolution();
|
||||
if (goog.isDef(currentResolution) && goog.isDef(opt_duration)) {
|
||||
map.requestRenderFrame();
|
||||
map.addPreRenderFunction(ol.animation.createZoomFrom(
|
||||
currentResolution, opt_duration));
|
||||
}
|
||||
var resolution = this.constraints_.resolution(currentResolution, delta);
|
||||
this.zoom_(map, resolution, opt_anchor);
|
||||
};
|
||||
|
||||
@@ -329,7 +338,7 @@ ol.View2D.createConstraints_ = function(view2DOptions) {
|
||||
view2DOptions.projection, 'EPSG:3857').getExtent();
|
||||
maxResolution = Math.max(
|
||||
projectionExtent.maxX - projectionExtent.minX,
|
||||
projectionExtent.maxY - projectionExtent.minY) / 256;
|
||||
projectionExtent.maxY - projectionExtent.minY) / ol.DEFAULT_TILE_SIZE;
|
||||
// number of steps we want between two data resolutions
|
||||
var numSteps = 4;
|
||||
numZoomLevels = 29 * numSteps;
|
||||
|
||||
Reference in New Issue
Block a user