This commit is contained in:
Éric Lemoine
2013-03-11 13:35:17 +01:00
parent 849774dceb
commit f150259eee
1189 changed files with 341774 additions and 2001 deletions
+7
View File
@@ -0,0 +1,7 @@
@exportClass ol.AnchoredElement ol.AnchoredElementOptions
@exportSymbol ol.AnchoredElementPositioning
@exportProperty ol.AnchoredElementPositioning.BOTTOM_LEFT
@exportProperty ol.AnchoredElementPositioning.BOTTOM_RIGHT
@exportProperty ol.AnchoredElementPositioning.TOP_LEFT
@exportProperty ol.AnchoredElementPositioning.TOP_RIGHT
+318
View File
@@ -0,0 +1,318 @@
goog.provide('ol.AnchoredElement');
goog.provide('ol.AnchoredElementPositioning');
goog.provide('ol.AnchoredElementProperty');
goog.require('goog.dom');
goog.require('goog.events');
goog.require('goog.style');
goog.require('ol.Coordinate');
goog.require('ol.Map');
goog.require('ol.MapEventType');
goog.require('ol.Object');
/**
* @enum {string}
*/
ol.AnchoredElementProperty = {
ELEMENT: 'element',
MAP: 'map',
POSITION: 'position',
POSITIONING: 'positioning'
};
/**
* @enum {string}
*/
ol.AnchoredElementPositioning = {
BOTTOM_LEFT: 'bottom-left',
BOTTOM_RIGHT: 'bottom-right',
TOP_LEFT: 'top-left',
TOP_RIGHT: 'top-right'
};
/**
* @constructor
* @extends {ol.Object}
* @param {ol.AnchoredElementOptions} anchoredElementOptions Anchored element
* options.
*/
ol.AnchoredElement = function(anchoredElementOptions) {
goog.base(this);
/**
* @private
* @type {Element}
*/
this.element_ = goog.dom.createElement(goog.dom.TagName.DIV);
this.element_.style.position = 'absolute';
/**
* @private
* @type {{bottom_: string,
* left_: string,
* right_: string,
* top_: string,
* visible: boolean}}
*/
this.rendered_ = {
bottom_: '',
left_: '',
right_: '',
top_: '',
visible: true
};
goog.events.listen(
this, ol.Object.getChangedEventType(ol.AnchoredElementProperty.ELEMENT),
this.handleElementChanged, false, this);
goog.events.listen(
this, ol.Object.getChangedEventType(ol.AnchoredElementProperty.MAP),
this.handleMapChanged, false, this);
goog.events.listen(
this, ol.Object.getChangedEventType(ol.AnchoredElementProperty.POSITION),
this.handlePositionChanged, false, this);
goog.events.listen(
this,
ol.Object.getChangedEventType(ol.AnchoredElementProperty.POSITIONING),
this.handlePositioningChanged, false, this);
if (goog.isDef(anchoredElementOptions.element)) {
this.setElement(anchoredElementOptions.element);
}
if (goog.isDef(anchoredElementOptions.position)) {
this.setPosition(anchoredElementOptions.position);
}
if (goog.isDef(anchoredElementOptions.positioning)) {
this.setPositioning(anchoredElementOptions.positioning);
}
if (goog.isDef(anchoredElementOptions.map)) {
this.setMap(anchoredElementOptions.map);
}
};
goog.inherits(ol.AnchoredElement, ol.Object);
/**
* @return {Element|undefined} Element.
*/
ol.AnchoredElement.prototype.getElement = function() {
return /** @type {Element|undefined} */ (
this.get(ol.AnchoredElementProperty.ELEMENT));
};
goog.exportProperty(
ol.AnchoredElement.prototype,
'getElement',
ol.AnchoredElement.prototype.getElement);
/**
* @return {ol.Map|undefined} Map.
*/
ol.AnchoredElement.prototype.getMap = function() {
return /** @type {ol.Map|undefined} */ (
this.get(ol.AnchoredElementProperty.MAP));
};
goog.exportProperty(
ol.AnchoredElement.prototype,
'getMap',
ol.AnchoredElement.prototype.getMap);
/**
* @return {ol.Coordinate|undefined} Position.
*/
ol.AnchoredElement.prototype.getPosition = function() {
return /** @type {ol.Coordinate|undefined} */ (
this.get(ol.AnchoredElementProperty.POSITION));
};
goog.exportProperty(
ol.AnchoredElement.prototype,
'getPosition',
ol.AnchoredElement.prototype.getPosition);
/**
* @return {ol.AnchoredElementPositioning|undefined} Positioning.
*/
ol.AnchoredElement.prototype.getPositioning = function() {
return /** @type {ol.AnchoredElementPositioning|undefined} */ (
this.get(ol.AnchoredElementProperty.POSITIONING));
};
goog.exportProperty(
ol.AnchoredElement.prototype,
'getPositioning',
ol.AnchoredElement.prototype.getPositioning);
/**
* @protected
*/
ol.AnchoredElement.prototype.handleElementChanged = function() {
goog.dom.removeChildren(this.element_);
var element = this.getElement();
if (goog.isDefAndNotNull(element)) {
goog.dom.append(/** @type {!Node} */ (this.element_), element);
}
};
/**
* @protected
*/
ol.AnchoredElement.prototype.handleMapChanged = function() {
if (!goog.isNull(this.mapPostrenderListenerKey_)) {
goog.dom.removeNode(this.element_);
goog.events.unlistenByKey(this.mapPostrenderListenerKey_);
this.mapPostrenderListenerKey_ = null;
}
var map = this.getMap();
if (goog.isDefAndNotNull(map)) {
this.mapPostrenderListenerKey_ = goog.events.listen(map,
ol.MapEventType.POSTRENDER, this.handleMapPostrender, false, this);
this.updatePixelPosition_();
goog.dom.append(
/** @type {!Node} */ (map.getOverlayContainer()), this.element_);
}
};
/**
* @protected
*/
ol.AnchoredElement.prototype.handleMapPostrender = function() {
this.updatePixelPosition_();
};
/**
* @protected
*/
ol.AnchoredElement.prototype.handlePositionChanged = function() {
this.updatePixelPosition_();
};
/**
* @protected
*/
ol.AnchoredElement.prototype.handlePositioningChanged = function() {
this.updatePixelPosition_();
};
/**
* @param {Element|undefined} element Element.
*/
ol.AnchoredElement.prototype.setElement = function(element) {
this.set(ol.AnchoredElementProperty.ELEMENT, element);
};
goog.exportProperty(
ol.AnchoredElement.prototype,
'setElement',
ol.AnchoredElement.prototype.setElement);
/**
* @param {ol.Map|undefined} map Map.
*/
ol.AnchoredElement.prototype.setMap = function(map) {
this.set(ol.AnchoredElementProperty.MAP, map);
};
goog.exportProperty(
ol.AnchoredElement.prototype,
'setMap',
ol.AnchoredElement.prototype.setMap);
/**
* @param {ol.Coordinate|undefined} position Position.
*/
ol.AnchoredElement.prototype.setPosition = function(position) {
this.set(ol.AnchoredElementProperty.POSITION, position);
};
goog.exportProperty(
ol.AnchoredElement.prototype,
'setPosition',
ol.AnchoredElement.prototype.setPosition);
/**
* @param {ol.AnchoredElementPositioning|undefined} positioning Positioning.
*/
ol.AnchoredElement.prototype.setPositioning = function(positioning) {
this.set(ol.AnchoredElementProperty.POSITIONING, positioning);
};
/**
* @private
*/
ol.AnchoredElement.prototype.updatePixelPosition_ = function() {
var map = this.getMap();
var position = this.getPosition();
if (!goog.isDef(map) || !map.isDef() || !goog.isDef(position)) {
if (this.rendered_.visible) {
goog.style.showElement(this.element_, false);
this.rendered_.visible = false;
}
return;
}
var pixel = map.getPixelFromCoordinate(position);
var mapSize = map.getSize();
goog.asserts.assert(goog.isDef(mapSize));
var style = this.element_.style;
var positioning = this.getPositioning();
if (positioning == ol.AnchoredElementPositioning.BOTTOM_RIGHT ||
positioning == ol.AnchoredElementPositioning.TOP_RIGHT) {
if (this.rendered_.left_ !== '') {
this.rendered_.left_ = style.left = '';
}
var right = Math.round(mapSize.width - pixel.x) + 'px';
if (this.rendered_.right_ != right) {
this.rendered_.right_ = style.right = right;
}
} else {
if (this.rendered_.right_ !== '') {
this.rendered_.right_ = style.right = '';
}
var left = Math.round(pixel.x) + 'px';
if (this.rendered_.left_ != left) {
this.rendered_.left_ = style.left = left;
}
}
if (positioning == ol.AnchoredElementPositioning.TOP_LEFT ||
positioning == ol.AnchoredElementPositioning.TOP_RIGHT) {
if (this.rendered_.bottom_ !== '') {
this.rendered_.bottom_ = style.bottom = '';
}
var top = Math.round(pixel.y) + 'px';
if (this.rendered_.top_ != top) {
this.rendered_.top_ = style.top = top;
}
} else {
if (this.rendered_.top_ !== '') {
this.rendered_.top_ = style.top = '';
}
var bottom = Math.round(mapSize.height - pixel.y) + 'px';
if (this.rendered_.bottom_ != bottom) {
this.rendered_.bottom_ = style.bottom = bottom;
}
}
if (!this.rendered_.visible) {
goog.style.showElement(this.element_, true);
this.rendered_.visible = true;
}
};
+5
View File
@@ -0,0 +1,5 @@
@exportSymbol ol.animation
@exportProperty ol.animation.bounce
@exportProperty ol.animation.pan
@exportProperty ol.animation.rotate
@exportProperty ol.animation.zoom
+130
View File
@@ -0,0 +1,130 @@
// FIXME works for View2D only
goog.provide('ol.animation');
goog.require('ol.PreRenderFunction');
goog.require('ol.ViewHint');
goog.require('ol.easing');
/**
* @param {ol.animation.BounceOptions} options Options.
* @return {ol.PreRenderFunction} Pre-render function.
*/
ol.animation.bounce = function(options) {
var resolution = options.resolution;
var start = goog.isDef(options.start) ? options.start : goog.now();
var duration = goog.isDef(options.duration) ? options.duration : 1000;
var easing = goog.isDef(options.easing) ?
options.easing : 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 = easing((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.animation.PanOptions} options Options.
* @return {ol.PreRenderFunction} Pre-render function.
*/
ol.animation.pan = function(options) {
var source = options.source;
var start = goog.isDef(options.start) ? options.start : goog.now();
var sourceX = source.x;
var sourceY = source.y;
var duration = goog.isDef(options.duration) ? options.duration : 1000;
var easing = goog.isDef(options.easing) ?
options.easing : ol.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 - easing((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 {ol.animation.RotateOptions} options Options.
* @return {ol.PreRenderFunction} Pre-render function.
*/
ol.animation.rotate = function(options) {
var sourceRotation = options.rotation;
var start = goog.isDef(options.start) ? options.start : goog.now();
var duration = goog.isDef(options.duration) ? options.duration : 1000;
var easing = goog.isDef(options.easing) ?
options.easing : ol.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 - easing((frameState.time - start) / duration);
var deltaRotation =
sourceRotation - frameState.view2DState.rotation;
frameState.animate = true;
frameState.view2DState.rotation += delta * deltaRotation;
frameState.viewHints[ol.ViewHint.ANIMATING] += 1;
return true;
} else {
return false;
}
};
};
/**
* @param {ol.animation.ZoomOptions} options Options.
* @return {ol.PreRenderFunction} Pre-render function.
*/
ol.animation.zoom = function(options) {
var sourceResolution = options.resolution;
var start = goog.isDef(options.start) ? options.start : goog.now();
var duration = goog.isDef(options.duration) ? options.duration : 1000;
var easing = goog.isDef(options.easing) ?
options.easing : ol.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 - easing((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;
}
};
};
+59
View File
@@ -0,0 +1,59 @@
goog.provide('ol.array');
goog.require('goog.array');
/**
* @param {Array.<number>} arr Array.
* @param {number} target Target.
* @return {number} Index.
*/
ol.array.binaryFindNearest = function(arr, target) {
var index = goog.array.binarySearch(arr, target, function(a, b) {
return b - a;
});
if (index >= 0) {
return index;
} else if (index == -1) {
return 0;
} else if (index == -arr.length - 1) {
return arr.length - 1;
} else {
var left = -index - 2;
var right = -index - 1;
if (arr[left] - target < target - arr[right]) {
return left;
} else {
return right;
}
}
};
/**
* @param {Array.<number>} arr Array.
* @param {number} target Target.
* @return {number} Index.
*/
ol.array.linearFindNearest = function(arr, target) {
var n = arr.length;
if (arr[0] <= target) {
return 0;
} else if (target <= arr[n - 1]) {
return n - 1;
} else {
var i;
for (i = 1; i < n; ++i) {
if (arr[i] == target) {
return i;
} else if (arr[i] < target) {
if (arr[i - 1] - target < target - arr[i]) {
return i - 1;
} else {
return i;
}
}
}
return n - 1;
}
};
+1
View File
@@ -0,0 +1 @@
@exportSymbol ol.Attribution
+58
View File
@@ -0,0 +1,58 @@
goog.provide('ol.Attribution');
goog.require('ol.TileRange');
/**
* @constructor
* @param {string} html HTML.
* @param {Object.<string, Array.<ol.TileRange>>=} opt_tileRanges Tile ranges.
*/
ol.Attribution = function(html, opt_tileRanges) {
/**
* @private
* @type {string}
*/
this.html_ = html;
/**
* @private
* @type {Object.<string, Array.<ol.TileRange>>}
*/
this.tileRanges_ = opt_tileRanges || null;
};
/**
* @return {string} HTML.
*/
ol.Attribution.prototype.getHTML = function() {
return this.html_;
};
/**
* @param {Object.<string, ol.TileRange>} tileRanges Tile ranges.
* @return {boolean} Intersects any tile range.
*/
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;
};
+20
View File
@@ -0,0 +1,20 @@
goog.provide('ol.BrowserFeature');
/**
* @define {boolean} Assume touch.
*/
ol.ASSUME_TOUCH = false;
/**
* @type {Object}
*/
ol.BrowserFeature = {
/**
* @type {boolean} True if browser supports touch events
*/
HAS_TOUCH: ol.ASSUME_TOUCH ||
(document && 'ontouchstart' in document.documentElement) ||
!!(window.navigator.msPointerEnabled)
};
+22
View File
@@ -0,0 +1,22 @@
goog.provide('ol.canvas');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
/**
* @const
* @type {boolean} Is supported.
*/
ol.canvas.SUPPORTED = (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;
}
})();
+11
View File
@@ -0,0 +1,11 @@
@exportSymbol ol.Collection
@exportProperty ol.Collection.prototype.clear
@exportProperty ol.Collection.prototype.forEach
@exportProperty ol.Collection.prototype.getAt
@exportProperty ol.Collection.prototype.getLength
@exportProperty ol.Collection.prototype.insertAt
@exportProperty ol.Collection.prototype.pop
@exportProperty ol.Collection.prototype.push
@exportProperty ol.Collection.prototype.remove
@exportProperty ol.Collection.prototype.removeAt
@exportProperty ol.Collection.prototype.setAt
+220
View File
@@ -0,0 +1,220 @@
/**
* An implementation of Google Maps' MVCArray.
* @see https://developers.google.com/maps/documentation/javascript/reference
*/
goog.provide('ol.Collection');
goog.provide('ol.CollectionEvent');
goog.provide('ol.CollectionEventType');
goog.require('goog.array');
goog.require('goog.events.Event');
goog.require('ol.Object');
/**
* @enum {string}
*/
ol.CollectionEventType = {
ADD: 'add',
REMOVE: 'remove'
};
/**
* @constructor
* @extends {goog.events.Event}
* @param {ol.CollectionEventType} type Type.
* @param {*=} opt_elem Element.
* @param {Object=} opt_target Target.
*/
ol.CollectionEvent = function(type, opt_elem, opt_target) {
goog.base(this, type, opt_target);
/**
* @type {*}
*/
this.elem = opt_elem;
};
goog.inherits(ol.CollectionEvent, goog.events.Event);
/**
* @enum {string}
*/
ol.CollectionProperty = {
LENGTH: 'length'
};
/**
* @constructor
* @extends {ol.Object}
* @param {Array=} opt_array Array.
*/
ol.Collection = function(opt_array) {
goog.base(this);
/**
* @private
* @type {Array}
*/
this.array_ = opt_array || [];
this.updateLength_();
};
goog.inherits(ol.Collection, ol.Object);
/**
* Remove all elements from the collection.
*/
ol.Collection.prototype.clear = function() {
while (this.getLength() > 0) {
this.pop();
}
};
/**
* @param {Array} arr Array.
*/
ol.Collection.prototype.extend = function(arr) {
var i;
for (i = 0; i < arr.length; ++i) {
this.push(arr[i]);
}
};
/**
* @param {Function} f Function.
* @param {Object=} opt_obj Object.
*/
ol.Collection.prototype.forEach = function(f, opt_obj) {
goog.array.forEach(this.array_, f, opt_obj);
};
/**
* @return {Array} Array.
*/
ol.Collection.prototype.getArray = function() {
return this.array_;
};
/**
* @param {number} index Index.
* @return {*} Element.
*/
ol.Collection.prototype.getAt = function(index) {
return this.array_[index];
};
/**
* @return {number} Length.
*/
ol.Collection.prototype.getLength = function() {
return /** @type {number} */ (this.get(ol.CollectionProperty.LENGTH));
};
/**
* @param {number} index Index.
* @param {*} elem Element.
*/
ol.Collection.prototype.insertAt = function(index, elem) {
goog.array.insertAt(this.array_, elem, index);
this.updateLength_();
this.dispatchEvent(
new ol.CollectionEvent(ol.CollectionEventType.ADD, elem, this));
};
/**
* @return {*} Element.
*/
ol.Collection.prototype.pop = function() {
return this.removeAt(this.getLength() - 1);
};
/**
* @param {*} elem Element.
* @return {number} Length.
*/
ol.Collection.prototype.push = function(elem) {
var n = this.array_.length;
this.insertAt(n, elem);
return n;
};
/**
* Removes the first occurence of elem from the collection.
* @param {*} elem Element.
* @return {*} The removed element or undefined if elem was not found.
*/
ol.Collection.prototype.remove = function(elem) {
var i;
for (i = 0; i < this.array_.length; ++i) {
if (this.array_[i] === elem) {
return this.removeAt(i);
}
}
return undefined;
};
/**
* @param {number} index Index.
* @return {*} Value.
*/
ol.Collection.prototype.removeAt = function(index) {
var prev = this.array_[index];
goog.array.removeAt(this.array_, index);
this.updateLength_();
this.dispatchEvent(
new ol.CollectionEvent(ol.CollectionEventType.REMOVE, prev, this));
return prev;
};
/**
* @param {number} index Index.
* @param {*} elem Element.
*/
ol.Collection.prototype.setAt = function(index, elem) {
var n = this.getLength();
if (index < n) {
var prev = this.array_[index];
this.array_[index] = elem;
this.dispatchEvent(
new ol.CollectionEvent(ol.CollectionEventType.REMOVE, prev, this));
this.dispatchEvent(
new ol.CollectionEvent(ol.CollectionEventType.ADD, elem, this));
} else {
var j;
for (j = n; j < index; ++j) {
this.insertAt(j, undefined);
}
this.insertAt(index, elem);
}
};
/**
* @private
*/
ol.Collection.prototype.updateLength_ = function() {
this.set(ol.CollectionProperty.LENGTH, this.array_.length);
};
+62
View File
@@ -0,0 +1,62 @@
goog.provide('ol.Color');
goog.require('goog.color');
goog.require('goog.math');
/**
* @constructor
* @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 1 (fully opaque).
*/
ol.Color = function(r, g, b, a) {
/**
* @type {number}
*/
this.r = goog.math.clamp(r, 0, 255);
/**
* @type {number}
*/
this.g = goog.math.clamp(g, 0, 255);
/**
* @type {number}
*/
this.b = goog.math.clamp(b, 0, 255);
/**
* @type {number}
*/
this.a = goog.math.clamp(a, 0, 1);
};
/**
* @param {string} str String.
* @param {number=} opt_a Alpha.
* @return {ol.Color} Color.
*/
ol.Color.createFromString = function(str, opt_a) {
var rgb = goog.color.hexToRgb(goog.color.parse(str).hex);
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);
};
+27
View File
@@ -0,0 +1,27 @@
goog.provide('ol.Constraints');
goog.require('ol.ResolutionConstraintType');
goog.require('ol.RotationConstraintType');
/**
* @constructor
* @param {ol.ResolutionConstraintType} resolutionConstraint
* Resolution constraint.
* @param {ol.RotationConstraintType} rotationConstraint
* Rotation constraint.
*/
ol.Constraints = function(resolutionConstraint, rotationConstraint) {
/**
* @type {ol.ResolutionConstraintType}
*/
this.resolution = resolutionConstraint;
/**
* @type {ol.RotationConstraintType}
*/
this.rotation = rotationConstraint;
};
+3
View File
@@ -0,0 +1,3 @@
@exportClass ol.control.Attribution ol.control.AttributionOptions
@exportProperty ol.control.Attribution.prototype.setMap
+208
View File
@@ -0,0 +1,208 @@
// FIXME handle date line wrap
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.object');
goog.require('goog.style');
goog.require('ol.Attribution');
goog.require('ol.FrameState');
goog.require('ol.MapEvent');
goog.require('ol.MapEventType');
goog.require('ol.TileRange');
goog.require('ol.control.Control');
goog.require('ol.source.Source');
/**
* @constructor
* @extends {ol.control.Control}
* @param {ol.control.AttributionOptions=} opt_options Options.
*/
ol.control.Attribution = function(opt_options) {
var options = goog.isDef(opt_options) ? opt_options : {};
this.ulElement_ = goog.dom.createElement(goog.dom.TagName.UL);
var element = goog.dom.createDom(goog.dom.TagName.DIV, {
'class': 'ol-attribution ol-unselectable'
}, this.ulElement_);
goog.base(this, {
element: element,
map: options.map,
target: options.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 {?Object.<string, Object.<string, ol.TileRange>>} usedTiles Used
* tiles.
* @param {Object.<string, ol.source.Source>} sources Sources.
* @return {Object.<string, ol.Attribution>} Attributions.
*/
ol.control.Attribution.prototype.getTileSourceAttributions =
function(usedTiles, sources) {
/** @type {Object.<string, ol.Attribution>} */
var attributions = {};
var i, tileRanges, tileSource, tileSourceAttribution,
tileSourceAttributionKey, tileSourceAttributions, tileSourceKey, z;
for (tileSourceKey in usedTiles) {
goog.asserts.assert(tileSourceKey in sources);
tileSource = sources[tileSourceKey];
tileSourceAttributions = tileSource.getAttributions();
if (goog.isNull(tileSourceAttributions)) {
continue;
}
tileRanges = usedTiles[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;
}
}
}
return attributions;
};
/**
* @param {ol.MapEvent} mapEvent Map event.
*/
ol.control.Attribution.prototype.handleMapPostrender = function(mapEvent) {
this.updateElement_(mapEvent.frameState);
};
/**
* @inheritDoc
*/
ol.control.Attribution.prototype.setMap = function(map) {
if (!goog.isNull(this.listenerKeys_)) {
goog.array.forEach(this.listenerKeys_, goog.events.unlistenByKey);
this.listenerKeys_ = null;
}
goog.base(this, 'setMap', map);
if (!goog.isNull(map)) {
this.listenerKeys_ = [
goog.events.listen(map, ol.MapEventType.POSTRENDER,
this.handleMapPostrender, false, this)
];
}
};
/**
* @private
* @param {?ol.FrameState} frameState Frame state.
*/
ol.control.Attribution.prototype.updateElement_ = function(frameState) {
if (goog.isNull(frameState)) {
if (this.renderedVisible_) {
goog.style.showElement(this.element, false);
this.renderedVisible_ = false;
}
return;
}
var map = this.getMap();
/** @type {Object.<string, boolean>} */
var attributionsToRemove = {};
/** @type {Object.<string, ol.source.Source>} */
var sources = {};
var layers = map.getLayers();
if (goog.isDef(layers)) {
layers.forEach(function(layer) {
var source = layer.getSource();
sources[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 = goog.object.clone(frameState.attributions);
var tileSourceAttributions = this.getTileSourceAttributions(
frameState.usedTiles, sources);
goog.object.extend(attributions, tileSourceAttributions);
/** @type {Array.<number>} */
var attributionKeys =
goog.array.map(goog.object.getKeys(attributions), Number);
goog.array.sort(attributionKeys);
var i, 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;
}
};
+89
View File
@@ -0,0 +1,89 @@
goog.provide('ol.control.Control');
goog.provide('ol.control.ControlOptions');
goog.require('goog.Disposable');
/**
* @typedef {{element: (Element|undefined),
* map: (ol.Map|undefined),
* target: (Element|undefined)}}
*/
ol.control.ControlOptions;
/**
* A thing which is painted over the map to provide a means for interaction
* (buttons) of show annotations (status bars).
*
* @constructor
* @extends {goog.Disposable}
* @param {ol.control.ControlOptions} controlOptions Control options.
*/
ol.control.Control = function(controlOptions) {
goog.base(this);
/**
* @protected
* @type {Element}
*/
this.element = goog.isDef(controlOptions.element) ?
controlOptions.element : null;
/**
* @private
* @type {Element|undefined}
*/
this.target_ = controlOptions.target;
/**
* @private
* @type {ol.Map}
*/
this.map_ = null;
if (goog.isDef(controlOptions.map)) {
this.setMap(controlOptions.map);
}
};
goog.inherits(ol.control.Control, goog.Disposable);
/**
* @inheritDoc
*/
ol.control.Control.prototype.disposeInternal = function() {
goog.dom.removeNode(this.element);
goog.base(this, 'disposeInternal');
};
/**
* @return {ol.Map} Map.
*/
ol.control.Control.prototype.getMap = function() {
return this.map_;
};
/**
* Removes the control from its current map and attaches it to the new map.
* Subtypes might also wish set up event handlers to get notified about changes
* to the map here.
*
* @param {ol.Map} map Map.
*/
ol.control.Control.prototype.setMap = function(map) {
if (!goog.isNull(this.map_)) {
goog.dom.removeNode(this.element);
}
this.map_ = map;
if (!goog.isNull(this.map_)) {
var target = goog.isDef(this.target_) ?
this.target_ : map.getOverlayContainer();
goog.dom.appendChild(target, this.element);
}
};
+1
View File
@@ -0,0 +1 @@
@exportSymbol ol.control.defaults ol.control.defaults
+42
View File
@@ -0,0 +1,42 @@
goog.provide('ol.control.defaults');
goog.require('goog.array');
goog.require('ol.control.Attribution');
goog.require('ol.control.Zoom');
/**
* @param {ol.control.DefaultsOptions=} opt_options Options.
* @param {Array.<ol.control.Control>=} opt_controls Additional controls.
* @return {Array.<ol.control.Control>} Controls.
*/
ol.control.defaults = function(opt_options, opt_controls) {
var options = goog.isDef(opt_options) ? opt_options : {};
/** @type {Array.<ol.control.Control>} */
var controls = [];
var attributionControl = goog.isDef(options.attribution) ?
options.attribution : true;
if (attributionControl) {
var attributionControlOptions = goog.isDef(options.attributionOptions) ?
options.attributionOptions : undefined;
controls.push(new ol.control.Attribution(attributionControlOptions));
}
var zoomControl = goog.isDef(options.zoom) ?
options.zoom : true;
if (zoomControl) {
var zoomControlOptions = goog.isDef(options.zoomControlOptions) ?
options.zoomControlOptions : undefined;
controls.push(new ol.control.Zoom(zoomControlOptions));
}
if (goog.isDef(opt_controls)) {
goog.array.extend(controls, opt_controls);
}
return controls;
};
+95
View File
@@ -0,0 +1,95 @@
goog.provide('ol.control.DragBox');
goog.require('goog.asserts');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
goog.require('goog.events');
goog.require('goog.style');
goog.require('ol.Coordinate');
goog.require('ol.MapBrowserEvent');
goog.require('ol.MapBrowserEvent.EventType');
goog.require('ol.Pixel');
goog.require('ol.Size');
goog.require('ol.control.Control');
/**
* @typedef {{map: (ol.Map|undefined),
* startCoordinate: ol.Coordinate}}
*/
ol.control.DragBoxOptions;
/**
* @constructor
* @extends {ol.control.Control}
* @param {ol.control.DragBoxOptions} dragBoxOptions Drag box options.
*/
ol.control.DragBox = function(dragBoxOptions) {
var element = goog.dom.createDom(goog.dom.TagName.DIV, 'ol-dragbox');
/**
* @type {ol.Pixel|undefined}
* @private
*/
this.startPixel_ = null;
/**
* @private
* @type {ol.Coordinate}
*/
this.startCoordinate_ = dragBoxOptions.startCoordinate;
/**
* @private
* @type {?number}
*/
this.dragListenKey_ = null;
goog.base(this, {
element: element,
map: dragBoxOptions.map
});
};
goog.inherits(ol.control.DragBox, ol.control.Control);
/**
* @inheritDoc
*/
ol.control.DragBox.prototype.setMap = function(map) {
if (!goog.isNull(this.dragListenKey_)) {
goog.events.unlistenByKey(this.dragListenKey_);
this.dragListenKey_ = null;
}
if (!goog.isNull(map)) {
this.startPixel_ = map.getPixelFromCoordinate(this.startCoordinate_);
goog.asserts.assert(goog.isDef(this.startPixel_));
goog.style.setPosition(this.element, this.startPixel_);
goog.style.setBorderBoxSize(this.element, new ol.Size(0, 0));
this.dragListenKey_ = goog.events.listen(
map, ol.MapBrowserEvent.EventType.DRAG, this.updateBox_, false, this);
}
goog.base(this, 'setMap', map);
};
/**
* @param {ol.MapBrowserEvent} mapBrowserEvent The event to handle.
* @private
*/
ol.control.DragBox.prototype.updateBox_ = function(mapBrowserEvent) {
var map = this.getMap();
var coordinate = mapBrowserEvent.getCoordinate();
goog.asserts.assert(goog.isDef(coordinate));
var currentPixel = map.getPixelFromCoordinate(coordinate);
goog.style.setPosition(this.element, new ol.Pixel(
Math.min(currentPixel.x, this.startPixel_.x),
Math.min(currentPixel.y, this.startPixel_.y)));
goog.style.setBorderBoxSize(this.element, new ol.Size(
Math.abs(currentPixel.x - this.startPixel_.x),
Math.abs(currentPixel.y - this.startPixel_.y)));
};
@@ -0,0 +1,3 @@
@exportClass ol.control.MousePosition ol.control.MousePositionOptions
@exportProperty ol.control.MousePosition.prototype.setMap
@@ -0,0 +1,196 @@
// FIXME should listen on appropriate pane, once it is defined
// FIXME works for View2D only
goog.provide('ol.control.MousePosition');
goog.require('goog.array');
goog.require('goog.dom');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('goog.style');
goog.require('ol.Coordinate');
goog.require('ol.CoordinateFormatType');
goog.require('ol.MapEvent');
goog.require('ol.MapEventType');
goog.require('ol.Pixel');
goog.require('ol.Projection');
goog.require('ol.TransformFunction');
goog.require('ol.control.Control');
goog.require('ol.projection');
/**
* @constructor
* @extends {ol.control.Control}
* @param {ol.control.MousePositionOptions=} opt_options Options.
*/
ol.control.MousePosition = function(opt_options) {
var options = goog.isDef(opt_options) ? opt_options : {};
var element = goog.dom.createDom(goog.dom.TagName.DIV, {
'class': 'ol-mouse-position'
});
goog.base(this, {
element: element,
map: options.map,
target: options.target
});
/**
* @private
* @type {ol.Projection}
*/
this.projection_ = ol.projection.get(options.projection);
/**
* @private
* @type {ol.CoordinateFormatType|undefined}
*/
this.coordinateFormat_ = options.coordinateFormat;
/**
* @private
* @type {string}
*/
this.undefinedHTML_ = goog.isDef(options.undefinedHTML) ?
options.undefinedHTML : '';
/**
* @private
* @type {string}
*/
this.renderedHTML_ = element.innerHTML;
/**
* @private
* @type {ol.Projection}
*/
this.mapProjection_ = null;
/**
* @private
* @type {ol.TransformFunction}
*/
this.transform_ = ol.projection.identityTransform;
/**
* @private
* @type {ol.Projection}
*/
this.renderedProjection_ = null;
/**
* @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.handleMapPostrender = function(mapEvent) {
var frameState = mapEvent.frameState;
if (goog.isNull(frameState)) {
this.mapProjection_ = null;
} else {
this.mapProjection_ = frameState.view2DState.projection;
}
this.updateHTML_(this.lastMouseMovePixel_);
};
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @protected
*/
ol.control.MousePosition.prototype.handleMouseMove = function(browserEvent) {
var map = this.getMap();
var eventPosition = goog.style.getRelativePosition(
browserEvent, map.getViewport());
var pixel = new ol.Pixel(eventPosition.x, eventPosition.y);
this.updateHTML_(pixel);
this.lastMouseMovePixel_ = pixel;
};
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @protected
*/
ol.control.MousePosition.prototype.handleMouseOut = function(browserEvent) {
this.updateHTML_(null);
this.lastMouseMovePixel_ = null;
};
/**
* @inheritDoc
*/
ol.control.MousePosition.prototype.setMap = function(map) {
if (!goog.isNull(this.listenerKeys_)) {
goog.array.forEach(this.listenerKeys_, goog.events.unlistenByKey);
this.listenerKeys_ = null;
}
goog.base(this, 'setMap', map);
if (!goog.isNull(map)) {
var viewport = map.getViewport();
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),
goog.events.listen(map, ol.MapEventType.POSTRENDER,
this.handleMapPostrender, false, this)
];
}
};
/**
* @param {?ol.Pixel} pixel Pixel.
* @private
*/
ol.control.MousePosition.prototype.updateHTML_ = function(pixel) {
var html = this.undefinedHTML_;
if (!goog.isNull(pixel)) {
if (this.renderedProjection_ != this.mapProjection_) {
if (!goog.isNull(this.projection_)) {
this.transform_ = ol.projection.getTransformFromProjections(
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)) {
var vertex = [coordinate.x, coordinate.y];
vertex = this.transform_(vertex, vertex);
coordinate = new ol.Coordinate(vertex[0], vertex[1]);
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;
}
};
+9
View File
@@ -0,0 +1,9 @@
@exportClass ol.control.ScaleLine ol.control.ScaleLineOptions
@exportProperty ol.control.ScaleLine.prototype.setMap
@exportSymbol ol.control.ScaleLineUnits
@exportProperty ol.control.ScaleLineUnits.DEGREES
@exportProperty ol.control.ScaleLineUnits.IMPERIAL
@exportProperty ol.control.ScaleLineUnits.NAUTICAL
@exportProperty ol.control.ScaleLineUnits.METRIC
@exportProperty ol.control.ScaleLineUnits.US
+285
View File
@@ -0,0 +1,285 @@
goog.provide('ol.control.ScaleLine');
goog.provide('ol.control.ScaleLineUnits');
goog.require('goog.dom');
goog.require('goog.style');
goog.require('ol.FrameState');
goog.require('ol.MapEvent');
goog.require('ol.MapEventType');
goog.require('ol.ProjectionUnits');
goog.require('ol.TransformFunction');
goog.require('ol.control.Control');
goog.require('ol.projection');
goog.require('ol.sphere.NORMAL');
/**
* @enum {string}
*/
ol.control.ScaleLineUnits = {
DEGREES: 'degrees',
IMPERIAL: 'imperial',
NAUTICAL: 'nautical',
METRIC: 'metric',
US: 'us'
};
/**
* @constructor
* @extends {ol.control.Control}
* @param {ol.control.ScaleLineOptions=} opt_options Options.
*/
ol.control.ScaleLine = function(opt_options) {
var options = opt_options || {};
/**
* @private
* @type {Element}
*/
this.innerElement_ = goog.dom.createDom(goog.dom.TagName.DIV, {
'class': 'ol-scale-line-inner'
});
/**
* @private
* @type {Element}
*/
this.element_ = goog.dom.createDom(goog.dom.TagName.DIV, {
'class': 'ol-scale-line ol-unselectable'
}, this.innerElement_);
/**
* @private
* @type {number}
*/
this.minWidth_ = goog.isDef(options.minWidth) ? options.minWidth : 64;
/**
* @private
* @type {ol.control.ScaleLineUnits}
*/
this.units_ = goog.isDef(options.units) ?
options.units : ol.control.ScaleLineUnits.METRIC;
/**
* @private
* @type {Array.<?number>}
*/
this.listenerKeys_ = null;
/**
* @private
* @type {boolean}
*/
this.renderedVisible_ = false;
/**
* @private
* @type {number|undefined}
*/
this.renderedWidth_;
/**
* @private
* @type {string}
*/
this.renderedHTML_ = '';
/**
* @private
* @type {?ol.TransformFunction}
*/
this.toEPSG4326_ = null;
goog.base(this, {
element: this.element_,
map: options.map,
target: options.target
});
};
goog.inherits(ol.control.ScaleLine, ol.control.Control);
/**
* @const
* @type {Array.<number>}
*/
ol.control.ScaleLine.LEADING_DIGITS = [1, 2, 5];
/**
* @param {ol.MapEvent} mapEvent Map event.
*/
ol.control.ScaleLine.prototype.handleMapPostrender = function(mapEvent) {
var frameState = mapEvent.frameState;
this.updateElement_(mapEvent.frameState);
};
/**
* @inheritDoc
*/
ol.control.ScaleLine.prototype.setMap = function(map) {
if (!goog.isNull(this.listenerKeys_)) {
goog.array.forEach(this.listenerKeys_, goog.events.unlistenByKey);
this.listenerKeys_ = null;
}
goog.base(this, 'setMap', map);
if (!goog.isNull(map)) {
this.listenerKeys_ = [
goog.events.listen(map, ol.MapEventType.POSTRENDER,
this.handleMapPostrender, false, this)
];
}
};
/**
* @param {?ol.FrameState} frameState Frame state.
* @private
*/
ol.control.ScaleLine.prototype.updateElement_ = function(frameState) {
if (goog.isNull(frameState)) {
if (this.renderedVisible_) {
goog.style.showElement(this.element_, false);
this.renderedVisible_ = false;
}
return;
}
var view2DState = frameState.view2DState;
var center = view2DState.center;
var projection = view2DState.projection;
var pointResolution =
projection.getPointResolution(view2DState.resolution, center);
var projectionUnits = projection.getUnits();
var cosLatitude;
if (projectionUnits == ol.ProjectionUnits.DEGREES &&
(this.units_ == ol.control.ScaleLineUnits.METRIC ||
this.units_ == ol.control.ScaleLineUnits.IMPERIAL)) {
// Convert pointResolution from degrees to meters
this.toEPSG4326_ = null;
cosLatitude = Math.cos(goog.math.toRadians(center.y));
pointResolution *= Math.PI * cosLatitude * ol.sphere.NORMAL.radius / 180;
projectionUnits = ol.ProjectionUnits.METERS;
} else if ((projectionUnits == ol.ProjectionUnits.FEET ||
projectionUnits == ol.ProjectionUnits.METERS) &&
this.units_ == ol.control.ScaleLineUnits.DEGREES) {
// Convert pointResolution from meters or feet to degrees
if (goog.isNull(this.toEPSG4326_)) {
this.toEPSG4326_ = ol.projection.getTransformFromProjections(
projection, ol.projection.get('EPSG:4326'));
}
var vertex = [center.x, center.y];
vertex = this.toEPSG4326_(vertex, vertex, 2);
cosLatitude = Math.cos(goog.math.toRadians(vertex[1]));
var radius = ol.sphere.NORMAL.radius;
if (projectionUnits == ol.ProjectionUnits.FEET) {
radius /= 0.3048;
}
pointResolution *= 180 / (Math.PI * cosLatitude * radius);
projectionUnits = ol.ProjectionUnits.DEGREES;
} else {
this.toEPSG4326_ = null;
}
goog.asserts.assert(
((this.units_ == ol.control.ScaleLineUnits.METRIC ||
this.units_ == ol.control.ScaleLineUnits.IMPERIAL) &&
projectionUnits == ol.ProjectionUnits.METERS) ||
(this.units_ == ol.control.ScaleLineUnits.DEGREES &&
projectionUnits == ol.ProjectionUnits.DEGREES));
var nominalCount = this.minWidth_ * pointResolution;
var suffix = '';
if (this.units_ == ol.control.ScaleLineUnits.DEGREES) {
if (nominalCount < 1 / 60) {
suffix = '\u2033'; // seconds
pointResolution *= 3600;
} else if (nominalCount < 1) {
suffix = '\u2032'; // minutes
pointResolution *= 60;
} else {
suffix = '\u00b0'; // degrees
}
} else if (this.units_ == ol.control.ScaleLineUnits.IMPERIAL) {
if (nominalCount < 0.9144) {
suffix = 'in';
pointResolution /= 0.0254;
} else if (nominalCount < 1609.344) {
suffix = 'ft';
pointResolution /= 0.3048;
} else {
suffix = 'mi';
pointResolution /= 1609.344;
}
} else if (this.units_ == ol.control.ScaleLineUnits.NAUTICAL) {
pointResolution /= 1852;
suffix = 'nm';
} else if (this.units_ == ol.control.ScaleLineUnits.METRIC) {
if (nominalCount < 1) {
suffix = 'mm';
pointResolution *= 1000;
} else if (nominalCount < 1000) {
suffix = 'm';
} else {
suffix = 'km';
pointResolution /= 1000;
}
} else if (this.units_ == ol.control.ScaleLineUnits.US) {
if (nominalCount < 0.9144) {
suffix = 'in';
pointResolution *= 39.37;
} else if (nominalCount < 1609.344) {
suffix = 'ft';
pointResolution /= 0.30480061;
} else {
suffix = 'mi';
pointResolution /= 1609.3472;
}
} else {
goog.asserts.assert(false);
}
var i = 3 * Math.floor(
Math.log(this.minWidth_ * pointResolution) / Math.log(10));
var count, width;
while (true) {
count = ol.control.ScaleLine.LEADING_DIGITS[i % 3] *
Math.pow(10, Math.floor(i / 3));
width = Math.round(count / pointResolution);
if (width >= this.minWidth_) {
break;
}
++i;
}
var html = count + suffix;
if (this.renderedHTML_ != html) {
this.innerElement_.innerHTML = html;
this.renderedHTML_ = html;
}
if (this.renderedWidth_ != width) {
this.innerElement_.style.width = width + 'px';
this.renderedWidth_ = width;
}
if (!this.renderedVisible_) {
goog.style.showElement(this.element_, true);
this.renderedVisible_ = true;
}
};
+2
View File
@@ -0,0 +1,2 @@
@exportClass ol.control.Zoom ol.control.ZoomOptions
@exportProperty ol.control.Zoom.prototype.setMap
+92
View File
@@ -0,0 +1,92 @@
// FIXME works for View2D only
goog.provide('ol.control.Zoom');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('ol.control.Control');
/**
* @define {number} Zoom duration.
*/
ol.control.ZOOM_DURATION = 250;
/**
* @constructor
* @extends {ol.control.Control}
* @param {ol.control.ZoomOptions=} opt_options Options.
*/
ol.control.Zoom = function(opt_options) {
var options = goog.isDef(opt_options) ? opt_options : {};
var inElement = goog.dom.createDom(goog.dom.TagName.A, {
'href': '#zoomIn',
'class': 'ol-zoom-in'
});
goog.events.listen(inElement, [
goog.events.EventType.TOUCHEND,
goog.events.EventType.CLICK
], this.handleIn_, false, this);
var outElement = goog.dom.createDom(goog.dom.TagName.A, {
'href': '#zoomOut',
'class': 'ol-zoom-out'
});
goog.events.listen(outElement, [
goog.events.EventType.TOUCHEND,
goog.events.EventType.CLICK
], this.handleOut_, false, this);
var element = goog.dom.createDom(
goog.dom.TagName.DIV, 'ol-zoom ol-unselectable', inElement, outElement);
goog.base(this, {
element: element,
map: options.map,
target: options.target
});
/**
* @type {number}
* @private
*/
this.delta_ = goog.isDef(options.delta) ? options.delta : 1;
};
goog.inherits(ol.control.Zoom, ol.control.Control);
/**
* @param {goog.events.BrowserEvent} browserEvent The browser event to handle.
* @private
*/
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().zoomByDelta(map, this.delta_, undefined,
ol.control.ZOOM_DURATION);
};
/**
* @param {goog.events.BrowserEvent} browserEvent The browser event to handle.
* @private
*/
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().zoomByDelta(map, -this.delta_, undefined,
ol.control.ZOOM_DURATION);
};
+2
View File
@@ -0,0 +1,2 @@
@exportSymbol ol.Coordinate
@exportProperty ol.Coordinate.toStringHDMS
+106
View File
@@ -0,0 +1,106 @@
goog.provide('ol.Coordinate');
goog.provide('ol.CoordinateFormatType');
goog.require('goog.math');
goog.require('goog.math.Vec2');
/**
* @typedef {function((ol.Coordinate|undefined)): string}
*/
ol.CoordinateFormatType;
/**
* Two dimensional coordinate which does not know its projection.
*
* @constructor
* @extends {goog.math.Vec2}
* @param {number} x X.
* @param {number} y Y.
*/
ol.Coordinate = function(x, y) {
goog.base(this, x, y);
};
goog.inherits(ol.Coordinate, goog.math.Vec2);
/**
* @const
* @type {ol.Coordinate}
*/
ol.Coordinate.ZERO = new ol.Coordinate(0, 0);
/**
* @param {number=} opt_precision Precision.
* @return {ol.CoordinateFormatType} Coordinate format.
*/
ol.Coordinate.createStringXY = function(opt_precision) {
return function(coordinate) {
return ol.Coordinate.toStringXY(coordinate, opt_precision);
};
};
/**
* @private
* @param {number} degrees Degrees.
* @param {string} hemispheres Hemispheres.
* @return {string} String.
*/
ol.Coordinate.degreesToStringHDMS_ = function(degrees, hemispheres) {
var normalizedDegrees = goog.math.modulo(degrees + 180, 360) - 180;
var x = Math.abs(Math.round(3600 * normalizedDegrees));
return Math.floor(x / 3600) + '\u00b0 ' +
Math.floor((x / 60) % 60) + '\u2032 ' +
Math.floor(x % 60) + '\u2033 ' +
hemispheres.charAt(normalizedDegrees < 0 ? 1 : 0);
};
/**
* @param {ol.Coordinate|undefined} coordinate Coordinate.
* @return {string} Hemisphere, degrees, minutes and seconds.
*/
ol.Coordinate.toStringHDMS = function(coordinate) {
if (goog.isDef(coordinate)) {
return ol.Coordinate.degreesToStringHDMS_(coordinate.y, 'NS') + ' ' +
ol.Coordinate.degreesToStringHDMS_(coordinate.x, 'EW');
} else {
return '';
}
};
/**
* @param {ol.Coordinate|undefined} coordinate Coordinate.
* @param {number=} opt_precision Precision.
* @return {string} XY.
*/
ol.Coordinate.toStringXY = function(coordinate, opt_precision) {
if (goog.isDef(coordinate)) {
var precision = opt_precision || 0;
return coordinate.x.toFixed(precision) + ', ' +
coordinate.y.toFixed(precision);
} else {
return '';
}
};
/**
* Create an ol.Coordinate from an Array and take into account axis order.
* @param {Array} array The array with coordinates.
* @param {string} axis the axis info.
* @return {ol.Coordinate} The coordinate created.
*/
ol.Coordinate.fromProjectedArray = function(array, axis) {
var firstAxis = axis.charAt(0);
if (firstAxis === 'n' || firstAxis === 's') {
return new ol.Coordinate(array[1], array[0]);
} else {
return new ol.Coordinate(array[0], array[1]);
}
};
+86
View 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';
}
};
+8
View File
@@ -0,0 +1,8 @@
@exportSymbol ol.easing
@exportProperty ol.easing.bounce
@exportProperty ol.easing.easeIn
@exportProperty ol.easing.easeOut
@exportProperty ol.easing.elastic
@exportProperty ol.easing.inAndOut
@exportProperty ol.easing.linear
@exportProperty ol.easing.upAndDown
+83
View File
@@ -0,0 +1,83 @@
goog.provide('ol.easing');
goog.require('goog.fx.easing');
/**
* from https://raw.github.com/DmitryBaranovskiy/raphael/master/raphael.js
* @param {number} t Input between 0 and 1.
* @return {number} Output between 0 and 1.
*/
ol.easing.bounce = function(t) {
var s = 7.5625, p = 2.75, l;
if (t < (1 / p)) {
l = s * t * t;
} else {
if (t < (2 / p)) {
t -= (1.5 / p);
l = s * t * t + 0.75;
} else {
if (t < (2.5 / p)) {
t -= (2.25 / p);
l = s * t * t + 0.9375;
} else {
t -= (2.625 / p);
l = s * t * t + 0.984375;
}
}
}
return l;
};
/**
* @param {number} t Input between 0 and 1.
* @return {number} Output between 0 and 1.
*/
ol.easing.easeIn = goog.fx.easing.easeIn;
/**
* @param {number} t Input between 0 and 1.
* @return {number} Output between 0 and 1.
*/
ol.easing.easeOut = goog.fx.easing.easeOut;
/**
* from https://raw.github.com/DmitryBaranovskiy/raphael/master/raphael.js
* @param {number} t Input between 0 and 1.
* @return {number} Output between 0 and 1.
*/
ol.easing.elastic = function(t) {
return Math.pow(2, -10 * t) * Math.sin((t - 0.075) * (2 * Math.PI) / 0.3) + 1;
};
/**
* @param {number} t Input between 0 and 1.
* @return {number} Output between 0 and 1.
*/
ol.easing.inAndOut = goog.fx.easing.inAndOut;
/**
* @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.
*/
ol.easing.upAndDown = function(t) {
if (t < 0.5) {
return ol.easing.inAndOut(2 * t);
} else {
return 1 - ol.easing.inAndOut(2 * (t - 0.5));
}
};
+170
View File
@@ -0,0 +1,170 @@
goog.provide('ol.Ellipsoid');
goog.require('goog.math');
goog.require('ol.Coordinate');
/**
* @constructor
* @param {number} a Major radius.
* @param {number} flattening Flattening.
*/
ol.Ellipsoid = function(a, flattening) {
/**
* @type {number}
*/
this.a = a;
/**
* @type {number}
*/
this.flattening = flattening;
/**
* @type {number}
*/
this.b = this.a * (1 - this.flattening);
};
/**
* @param {ol.Coordinate} c1 Coordinate 1.
* @param {ol.Coordinate} c2 Coordinate 1.
* @param {number=} opt_minDeltaLambda Minimum delta lambda for convergence.
* @param {number=} opt_maxIterations Maximum iterations.
* @return {{distance: number, initialBearing: number, finalBearing: number}}
* Vincenty.
*/
ol.Ellipsoid.prototype.vincenty =
function(c1, c2, opt_minDeltaLambda, opt_maxIterations) {
var minDeltaLambda = goog.isDef(opt_minDeltaLambda) ?
opt_minDeltaLambda : 1e-12;
var maxIterations = goog.isDef(opt_maxIterations) ?
opt_maxIterations : 100;
var f = this.flattening;
var lat1 = goog.math.toRadians(c1.y);
var lat2 = goog.math.toRadians(c2.y);
var deltaLon = goog.math.toRadians(c2.x - c1.x);
var U1 = Math.atan((1 - f) * Math.tan(lat1));
var cosU1 = Math.cos(U1);
var sinU1 = Math.sin(U1);
var U2 = Math.atan((1 - f) * Math.tan(lat2));
var cosU2 = Math.cos(U2);
var sinU2 = Math.sin(U2);
var lambda = deltaLon;
var cosSquaredAlpha, sinAlpha;
var cosLambda, deltaLambda = Infinity, sinLambda;
var cos2SigmaM, cosSigma, sigma, sinSigma;
var i;
for (i = maxIterations; i > 0; --i) {
cosLambda = Math.cos(lambda);
sinLambda = Math.sin(lambda);
var x = cosU2 * sinLambda;
var y = cosU1 * sinU2 - sinU1 * cosU2 * cosLambda;
sinSigma = Math.sqrt(x * x + y * y);
if (sinSigma === 0) {
return {
distance: 0,
initialBearing: 0,
finalBearing: 0
};
}
cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
sigma = Math.atan2(sinSigma, cosSigma);
sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
cosSquaredAlpha = 1 - sinAlpha * sinAlpha;
cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSquaredAlpha;
if (isNaN(cos2SigmaM)) {
cos2SigmaM = 0;
}
var C = f / 16 * cosSquaredAlpha * (4 + f * (4 - 3 * cosSquaredAlpha));
var lambdaPrime = deltaLon + (1 - C) * f * sinAlpha * (sigma +
C * sinSigma * (cos2SigmaM +
C * cosSigma * (2 * cos2SigmaM * cos2SigmaM - 1)));
deltaLambda = Math.abs(lambdaPrime - lambda);
lambda = lambdaPrime;
if (deltaLambda < minDeltaLambda) {
break;
}
}
if (i === 0) {
return {
distance: NaN,
finalBearing: NaN,
initialBearing: NaN
};
}
var aSquared = this.a * this.a;
var bSquared = this.b * this.b;
var uSquared = cosSquaredAlpha * (aSquared - bSquared) / bSquared;
var A = 1 + uSquared / 16384 *
(4096 + uSquared * (uSquared * (320 - 175 * uSquared) - 768));
var B = uSquared / 1024 *
(256 + uSquared * (uSquared * (74 - 47 * uSquared) - 128));
var deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 *
(cosSigma * (2 * cos2SigmaM * cos2SigmaM - 1) -
B / 6 * cos2SigmaM * (4 * sinSigma * sinSigma - 3) *
(4 * cos2SigmaM * cos2SigmaM - 3)));
cosLambda = Math.cos(lambda);
sinLambda = Math.sin(lambda);
var alpha1 = Math.atan2(cosU2 * sinLambda,
cosU1 * sinU2 - sinU1 * cosU2 * cosLambda);
var alpha2 = Math.atan2(cosU1 * sinLambda,
cosU1 * sinU2 * cosLambda - sinU1 * cosU2);
return {
distance: this.b * A * (sigma - deltaSigma),
initialBearing: goog.math.toDegrees(alpha1),
finalBearing: goog.math.toDegrees(alpha2)
};
};
/**
* Returns the distance from c1 to c2 using Vincenty.
*
* @param {ol.Coordinate} c1 Coordinate 1.
* @param {ol.Coordinate} c2 Coordinate 1.
* @param {number=} opt_minDeltaLambda Minimum delta lambda for convergence.
* @param {number=} opt_maxIterations Maximum iterations.
* @return {number} Vincenty distance.
*/
ol.Ellipsoid.prototype.vincentyDistance =
function(c1, c2, opt_minDeltaLambda, opt_maxIterations) {
var vincenty = this.vincenty(c1, c2, opt_minDeltaLambda, opt_maxIterations);
return vincenty.distance;
};
/**
* Returns the final bearing from c1 to c2 using Vincenty.
*
* @param {ol.Coordinate} c1 Coordinate 1.
* @param {ol.Coordinate} c2 Coordinate 1.
* @param {number=} opt_minDeltaLambda Minimum delta lambda for convergence.
* @param {number=} opt_maxIterations Maximum iterations.
* @return {number} Initial bearing.
*/
ol.Ellipsoid.prototype.vincentyFinalBearing =
function(c1, c2, opt_minDeltaLambda, opt_maxIterations) {
var vincenty = this.vincenty(c1, c2, opt_minDeltaLambda, opt_maxIterations);
return vincenty.finalBearing;
};
/**
* Returns the initial bearing from c1 to c2 using Vincenty.
*
* @param {ol.Coordinate} c1 Coordinate 1.
* @param {ol.Coordinate} c2 Coordinate 1.
* @param {number=} opt_minDeltaLambda Minimum delta lambda for convergence.
* @param {number=} opt_maxIterations Maximum iterations.
* @return {number} Initial bearing.
*/
ol.Ellipsoid.prototype.vincentyInitialBearing =
function(c1, c2, opt_minDeltaLambda, opt_maxIterations) {
var vincenty = this.vincenty(c1, c2, opt_minDeltaLambda, opt_maxIterations);
return vincenty.initialBearing;
};
+10
View File
@@ -0,0 +1,10 @@
goog.provide('ol.ellipsoid.WGS84');
goog.require('ol.Ellipsoid');
/**
* @const
* @type {ol.Ellipsoid}
*/
ol.ellipsoid.WGS84 = new ol.Ellipsoid(6378137, 1 / 298.257223563);
+3
View File
@@ -0,0 +1,3 @@
@exportSymbol ol.Extent
@exportProperty ol.Extent.prototype.getHeight
@exportProperty ol.Extent.prototype.getWidth
+117
View File
@@ -0,0 +1,117 @@
goog.provide('ol.Extent');
goog.require('ol.Coordinate');
goog.require('ol.Rectangle');
goog.require('ol.TransformFunction');
/**
* Rectangular extent which is not rotated. An extent does not know its
* projection.
*
* @constructor
* @extends {ol.Rectangle}
* @param {number} minX Minimum X.
* @param {number} minY Minimum Y.
* @param {number} maxX Maximum X.
* @param {number} maxY Maximum Y.
*/
ol.Extent = function(minX, minY, maxX, maxY) {
goog.base(this, minX, minY, maxX, maxY);
};
goog.inherits(ol.Extent, ol.Rectangle);
/**
* Builds an extent that includes all given coordinates.
*
* @param {...ol.Coordinate} var_args Coordinates.
* @return {!ol.Extent} Bounding extent.
*/
ol.Extent.boundingExtent = function(var_args) {
var coordinate0 = arguments[0];
var extent = new ol.Extent(coordinate0.x, coordinate0.y,
coordinate0.x, coordinate0.y);
var i;
for (i = 1; i < arguments.length; ++i) {
var coordinate = arguments[i];
extent.minX = Math.min(extent.minX, coordinate.x);
extent.minY = Math.min(extent.minY, coordinate.y);
extent.maxX = Math.max(extent.maxX, coordinate.x);
extent.maxY = Math.max(extent.maxY, coordinate.y);
}
return extent;
};
/**
* Checks if the passed coordinate is contained or on the edge
* of the extent.
*
* @param {ol.Coordinate} coordinate Coordinate.
* @return {boolean} Contains.
*/
ol.Extent.prototype.containsCoordinate = function(coordinate) {
return this.minX <= coordinate.x && coordinate.x <= this.maxX &&
this.minY <= coordinate.y && coordinate.y <= this.maxY;
};
/**
* Checks if the passed extent is contained or on the edge of the
* extent.
*
* @param {ol.Extent} extent Extent.
* @return {boolean} Contains.
*/
ol.Extent.prototype.containsExtent = function(extent) {
return this.minX <= extent.minX && extent.maxX <= this.maxX &&
this.minY <= extent.minY && extent.maxY <= this.maxY;
};
/**
* @return {ol.Coordinate} Bottom left coordinate.
*/
ol.Extent.prototype.getBottomLeft = function() {
return new ol.Coordinate(this.minX, this.minY);
};
/**
* @return {ol.Coordinate} Bottom right coordinate.
*/
ol.Extent.prototype.getBottomRight = function() {
return new ol.Coordinate(this.maxX, this.minY);
};
/**
* @return {ol.Coordinate} Top left coordinate.
*/
ol.Extent.prototype.getTopLeft = function() {
return new ol.Coordinate(this.minX, this.maxY);
};
/**
* @return {ol.Coordinate} Top right coordinate.
*/
ol.Extent.prototype.getTopRight = function() {
return new ol.Coordinate(this.maxX, this.maxY);
};
/**
* @param {ol.TransformFunction} transformFn Transform function.
* @return {ol.Extent} Extent.
*/
ol.Extent.prototype.transform = function(transformFn) {
var input = [this.minX, this.minY, this.maxX, this.maxY];
input = transformFn(input, input, 2);
return new ol.Extent(Math.min(input[0], input[2]),
Math.min(input[1], input[3]),
Math.max(input[0], input[2]),
Math.max(input[1], input[3]));
};
+50
View File
@@ -0,0 +1,50 @@
// FIXME add view3DState
// FIXME factor out common code between usedTiles and wantedTiles
goog.provide('ol.FrameState');
goog.provide('ol.PostRenderFunction');
goog.provide('ol.PreRenderFunction');
goog.require('goog.vec.Mat4');
goog.require('ol.Attribution');
goog.require('ol.Color');
goog.require('ol.Extent');
goog.require('ol.Size');
goog.require('ol.TileQueue');
goog.require('ol.TileRange');
goog.require('ol.View2DState');
goog.require('ol.layer.Layer');
goog.require('ol.layer.LayerState');
/**
* @typedef {{animate: boolean,
* attributions: Object.<string, ol.Attribution>,
* 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,
* usedTiles: Object.<string, Object.<string, ol.TileRange>>,
* view2DState: ol.View2DState,
* viewHints: Array.<number>,
* wantedTiles: Object.<string, Object.<string, boolean>>}}
*/
ol.FrameState;
/**
* @typedef {function(ol.Map, ?ol.FrameState): boolean}
*/
ol.PostRenderFunction;
/**
* @typedef {function(ol.Map, ?ol.FrameState): boolean}
*/
ol.PreRenderFunction;
+1
View File
@@ -0,0 +1 @@
@exportSymbol ol.Geolocation
+312
View File
@@ -0,0 +1,312 @@
// FIXME handle geolocation not supported
// FIXME handle geolocation errors
goog.provide('ol.Geolocation');
goog.provide('ol.GeolocationProperty');
goog.require('goog.functions');
goog.require('goog.math');
goog.require('ol.Coordinate');
goog.require('ol.Object');
goog.require('ol.Projection');
goog.require('ol.projection');
/**
* @enum {string}
*/
ol.GeolocationProperty = {
ACCURACY: 'accuracy',
ALTITUDE: 'altitude',
ALTITUDE_ACCURACY: 'altitudeAccuracy',
HEADING: 'heading',
POSITION: 'position',
PROJECTION: 'projection',
SPEED: 'speed',
TRACKING: 'tracking',
TRACKING_OPTIONS: 'trackingOptions'
};
/**
* @constructor
* @extends {ol.Object}
*/
ol.Geolocation = function() {
goog.base(this);
/**
* The unprojected (EPSG:4326) device position.
* @private
* @type {ol.Coordinate}
*/
this.position_ = null;
/**
* @private
* @type {number|undefined}
*/
this.watchId_;
this.setTracking(false);
goog.events.listen(
this, ol.Object.getChangedEventType(ol.GeolocationProperty.PROJECTION),
this.handleProjectionChanged_, false, this);
goog.events.listen(
this, ol.Object.getChangedEventType(ol.GeolocationProperty.TRACKING),
this.handleTrackingChanged_, false, this);
};
goog.inherits(ol.Geolocation, ol.Object);
/**
* @inheritDoc
*/
ol.Geolocation.prototype.disposeInternal = function() {
this.setTracking(false);
goog.base(this, 'disposeInternal');
};
/**
* @private
*/
ol.Geolocation.prototype.handleProjectionChanged_ = function() {
var projection = this.getProjection();
if (goog.isDefAndNotNull(projection)) {
this.transformFn_ = ol.projection.getTransformFromProjections(
ol.projection.get('EPSG:4326'), projection);
if (!goog.isNull(this.position_)) {
var vertex = [this.position_.x, this.position_.y];
vertex = this.transformFn_(vertex, vertex, 2);
this.set(ol.GeolocationProperty.POSITION,
new ol.Coordinate(vertex[0], vertex[1]));
}
}
};
/**
* @private
*/
ol.Geolocation.prototype.handleTrackingChanged_ = function() {
if (ol.Geolocation.SUPPORTED) {
var tracking = this.getTracking();
if (tracking && !goog.isDef(this.watchId_)) {
this.watchId_ = navigator.geolocation.watchPosition(
goog.bind(this.positionChange_, this),
goog.bind(this.positionError_, this),
this.getTrackingOptions());
} else if (!tracking && goog.isDef(this.watchId_)) {
navigator.geolocation.clearWatch(this.watchId_);
this.watchId_ = undefined;
}
}
};
/**
* @const
* @type {boolean} Is supported.
*/
ol.Geolocation.SUPPORTED = 'geolocation' in navigator;
/**
* @private
* @param {GeolocationPosition} position position event.
*/
ol.Geolocation.prototype.positionChange_ = function(position) {
var coords = position.coords;
this.set(ol.GeolocationProperty.ACCURACY, coords.accuracy);
this.set(ol.GeolocationProperty.ALTITUDE,
goog.isNull(coords.altitude) ? undefined : coords.altitude);
this.set(ol.GeolocationProperty.ALTITUDE_ACCURACY,
goog.isNull(coords.altitudeAccuracy) ?
undefined : coords.altitudeAccuracy);
this.set(ol.GeolocationProperty.HEADING, goog.isNull(coords.heading) ?
undefined : goog.math.toRadians(coords.heading));
this.position_ = new ol.Coordinate(coords.longitude, coords.latitude);
var vertex = [coords.longitude, coords.latitude];
vertex = this.transformFn_(vertex, vertex, 2);
this.set(ol.GeolocationProperty.POSITION,
new ol.Coordinate(vertex[0], vertex[1]));
this.set(ol.GeolocationProperty.SPEED,
goog.isNull(coords.speed) ? undefined : coords.speed);
};
/**
* @private
* @param {GeolocationPositionError} error error object.
*/
ol.Geolocation.prototype.positionError_ = function(error) {
};
/**
* The accuracy of the position in meters.
* @return {number|undefined} accuracy.
*/
ol.Geolocation.prototype.getAccuracy = function() {
return /** @type {number} */ (
this.get(ol.GeolocationProperty.ACCURACY));
};
goog.exportProperty(
ol.Geolocation.prototype,
'getAccuracy',
ol.Geolocation.prototype.getAccuracy);
/**
* @return {number|undefined} Altitude.
*/
ol.Geolocation.prototype.getAltitude = function() {
return /** @type {number|undefined} */ (
this.get(ol.GeolocationProperty.ALTITUDE));
};
goog.exportProperty(
ol.Geolocation.prototype,
'getAltitude',
ol.Geolocation.prototype.getAltitude);
/**
* @return {number|undefined} Altitude accuracy.
*/
ol.Geolocation.prototype.getAltitudeAccuracy = function() {
return /** @type {number|undefined} */ (
this.get(ol.GeolocationProperty.ALTITUDE_ACCURACY));
};
goog.exportProperty(
ol.Geolocation.prototype,
'getAltitudeAccuracy',
ol.Geolocation.prototype.getAltitudeAccuracy);
/**
* @return {number|undefined} Heading.
*/
ol.Geolocation.prototype.getHeading = function() {
return /** @type {number|undefined} */ (
this.get(ol.GeolocationProperty.HEADING));
};
goog.exportProperty(
ol.Geolocation.prototype,
'getHeading',
ol.Geolocation.prototype.getHeading);
/**
* The position of the device.
* @return {ol.Coordinate|undefined} position.
*/
ol.Geolocation.prototype.getPosition = function() {
return /** @type {ol.Coordinate} */ (
this.get(ol.GeolocationProperty.POSITION));
};
goog.exportProperty(
ol.Geolocation.prototype,
'getPosition',
ol.Geolocation.prototype.getPosition);
/**
* @return {ol.Projection|undefined} projection.
*/
ol.Geolocation.prototype.getProjection = function() {
return /** @type {ol.Projection} */ (
this.get(ol.GeolocationProperty.PROJECTION));
};
goog.exportProperty(
ol.Geolocation.prototype,
'getProjection',
ol.Geolocation.prototype.getProjection);
/**
* @return {number|undefined} Speed.
*/
ol.Geolocation.prototype.getSpeed = function() {
return /** @type {number|undefined} */ (
this.get(ol.GeolocationProperty.SPEED));
};
goog.exportProperty(
ol.Geolocation.prototype,
'getSpeed',
ol.Geolocation.prototype.getSpeed);
/**
* @return {boolean|undefined} tracking.
*/
ol.Geolocation.prototype.getTracking = function() {
return /** @type {boolean} */ (
this.get(ol.GeolocationProperty.TRACKING));
};
goog.exportProperty(
ol.Geolocation.prototype,
'getTracking',
ol.Geolocation.prototype.getTracking);
/**
* @return {GeolocationPositionOptions|undefined} tracking options.
*/
ol.Geolocation.prototype.getTrackingOptions = function() {
return /** @type {GeolocationPositionOptions} */ (
this.get(ol.GeolocationProperty.TRACKING_OPTIONS));
};
goog.exportProperty(
ol.Geolocation.prototype,
'getTrackingOptions',
ol.Geolocation.prototype.getTrackingOptions);
/**
* @param {ol.Projection} projection Projection.
*/
ol.Geolocation.prototype.setProjection = function(projection) {
this.set(ol.GeolocationProperty.PROJECTION, projection);
};
goog.exportProperty(
ol.Geolocation.prototype,
'setProjection',
ol.Geolocation.prototype.setProjection);
/**
* @param {boolean} tracking Enable or disable tracking.
*/
ol.Geolocation.prototype.setTracking = function(tracking) {
this.set(ol.GeolocationProperty.TRACKING, tracking);
};
goog.exportProperty(
ol.Geolocation.prototype,
'setTracking',
ol.Geolocation.prototype.setTracking);
/**
* @param {GeolocationPositionOptions} options Tracking options.
*/
ol.Geolocation.prototype.setTrackingOptions = function(options) {
this.set(ol.GeolocationProperty.TRACKING_OPTIONS, options);
};
goog.exportProperty(
ol.Geolocation.prototype,
'setTrackingOptions',
ol.Geolocation.prototype.setTrackingOptions);
/**
* @private
* @param {Array.<number>} input Input coordinate values.
* @param {Array.<number>=} opt_output Output array of coordinate values.
* @param {number=} opt_dimension Dimension (default is 2).
* @return {Array.<number>} Output coordinate values.
*/
ol.Geolocation.prototype.transformFn_ = goog.functions.identity;
+203
View File
@@ -0,0 +1,203 @@
goog.provide('ol.Image');
goog.provide('ol.ImageState');
goog.require('goog.array');
goog.require('goog.events');
goog.require('goog.events.EventTarget');
goog.require('goog.events.EventType');
goog.require('ol.Attribution');
goog.require('ol.Extent');
/**
* @enum {number}
*/
ol.ImageState = {
IDLE: 0,
LOADING: 1,
LOADED: 2,
ERROR: 3
};
/**
* @constructor
* @extends {goog.events.EventTarget}
* @param {ol.Extent} extent Extent.
* @param {number} resolution Resolution.
* @param {string} src Image source URI.
* @param {?string} crossOrigin Cross origin.
* @param {Array.<ol.Attribution>} attributions Attributions.
*/
ol.Image = function(extent, resolution, src, crossOrigin, attributions) {
/**
* @private
* @type {Array.<ol.Attribution>}
*/
this.attributions_ = attributions;
/**
* @private
* @type {ol.Extent}
*/
this.extent_ = extent;
/**
* @private
* @type {string}
*/
this.src_ = src;
/**
* @private
* @type {number}
*/
this.resolution_ = resolution;
/**
* @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;
/**
* @protected
* @type {ol.ImageState}
*/
this.state = ol.ImageState.IDLE;
};
goog.inherits(ol.Image, goog.events.EventTarget);
/**
* @protected
*/
ol.Image.prototype.dispatchChangeEvent = function() {
this.dispatchEvent(goog.events.EventType.CHANGE);
};
/**
* @return {Array.<ol.Attribution>} Attributions.
*/
ol.Image.prototype.getAttributions = function() {
return this.attributions_;
};
/**
* @return {ol.Extent} Extent.
*/
ol.Image.prototype.getExtent = function() {
return this.extent_;
};
/**
* @param {Object=} opt_context Object.
* @return {HTMLCanvasElement|Image|HTMLVideoElement} Image.
*/
ol.Image.prototype.getImageElement = 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_;
}
};
/**
* @return {number} Resolution.
*/
ol.Image.prototype.getResolution = function() {
return this.resolution_;
};
/**
* @return {ol.ImageState} State.
*/
ol.Image.prototype.getState = function() {
return this.state;
};
/**
* Tracks loading or read errors.
*
* @private
*/
ol.Image.prototype.handleImageError_ = function() {
this.state = ol.ImageState.ERROR;
this.unlistenImage_();
this.dispatchChangeEvent();
};
/**
* Tracks successful image load.
*
* @private
*/
ol.Image.prototype.handleImageLoad_ = function() {
this.state = ol.ImageState.LOADED;
this.unlistenImage_();
this.dispatchChangeEvent();
};
/**
* Load not yet loaded URI.
*/
ol.Image.prototype.load = function() {
if (this.state == ol.ImageState.IDLE) {
this.state = ol.ImageState.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.Image.prototype.unlistenImage_ = function() {
goog.asserts.assert(!goog.isNull(this.imageListenerKeys_));
goog.array.forEach(this.imageListenerKeys_, goog.events.unlistenByKey);
this.imageListenerKeys_ = null;
};
+138
View File
@@ -0,0 +1,138 @@
goog.provide('ol.ImageTile');
goog.require('goog.array');
goog.require('goog.events');
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 {ol.TileState} state State.
* @param {string} src Image source URI.
* @param {?string} crossOrigin Cross origin.
*/
ol.ImageTile = function(tileCoord, state, src, crossOrigin) {
goog.base(this, tileCoord, state);
/**
* 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;
};
+37
View File
@@ -0,0 +1,37 @@
goog.provide('ol.ImageUrlFunction');
goog.provide('ol.ImageUrlFunctionType');
goog.require('ol.Extent');
goog.require('ol.Size');
goog.require('ol.source.wms');
/**
* @typedef {function(ol.Extent, ol.Size, ol.Projection): (string|undefined)}
*/
ol.ImageUrlFunctionType;
/**
* @param {string} baseUrl Base URL (may have query data).
* @param {Object.<string, string|number>} params WMS parameters.
* @return {ol.ImageUrlFunctionType} Image URL function.
*/
ol.ImageUrlFunction.createWMSParams =
function(baseUrl, params) {
return function(extent, size, projection) {
return ol.source.wms.getUrl(
baseUrl, params, extent, size, projection);
};
};
/**
* @param {ol.Extent} extent Extent.
* @param {ol.Size} size Size.
* @return {string|undefined} Image URL.
*/
ol.ImageUrlFunction.nullImageUrlFunction =
function(extent, size) {
return undefined;
};
+68
View File
@@ -0,0 +1,68 @@
goog.provide('ol.interaction.ConditionType');
goog.provide('ol.interaction.condition');
/**
* @typedef {function(goog.events.BrowserEvent): boolean}
*/
ol.interaction.ConditionType;
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @return {boolean} True if only the alt key is pressed.
*/
ol.interaction.condition.altKeyOnly = function(browserEvent) {
return (
browserEvent.altKey &&
!browserEvent.platformModifierKey &&
!browserEvent.shiftKey);
};
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @return {boolean} True if only the alt and shift keys are pressed.
*/
ol.interaction.condition.altShiftKeysOnly = function(browserEvent) {
return (
browserEvent.altKey &&
!browserEvent.platformModifierKey &&
browserEvent.shiftKey);
};
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @return {boolean} True if only the no modifier keys are pressed.
*/
ol.interaction.condition.noModifierKeys = function(browserEvent) {
return (
!browserEvent.altKey &&
!browserEvent.platformModifierKey &&
!browserEvent.shiftKey);
};
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @return {boolean} True if only the platform modifier key is pressed.
*/
ol.interaction.condition.platformModifierKeyOnly = function(browserEvent) {
return (
!browserEvent.altKey &&
browserEvent.platformModifierKey &&
!browserEvent.shiftKey);
};
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @return {boolean} True if only the shift key is pressed.
*/
ol.interaction.condition.shiftKeyOnly = function(browserEvent) {
return (
!browserEvent.altKey &&
!browserEvent.platformModifierKey &&
browserEvent.shiftKey);
};
@@ -0,0 +1,55 @@
// 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');
/**
* @define {number} Animation duration.
*/
ol.interaction.DBLCLICKZOOM_ANIMATION_DURATION = 250;
/**
* @constructor
* @extends {ol.interaction.Interaction}
* @param {number} delta The zoom delta applied on each double click.
*/
ol.interaction.DblClickZoom = function(delta) {
/**
* @private
* @type {number}
*/
this.delta_ = delta;
goog.base(this);
};
goog.inherits(ol.interaction.DblClickZoom, ol.interaction.Interaction);
/**
* @inheritDoc
*/
ol.interaction.DblClickZoom.prototype.handleMapBrowserEvent =
function(mapBrowserEvent) {
var browserEvent = mapBrowserEvent.browserEvent;
if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.DBLCLICK &&
mapBrowserEvent.isMouseActionButton()) {
var map = mapBrowserEvent.map;
var anchor = mapBrowserEvent.getCoordinate();
var delta = mapBrowserEvent.browserEvent.shiftKey ?
-this.delta_ : this.delta_;
// FIXME works for View2D only
var view = map.getView();
goog.asserts.assert(view instanceof ol.View2D);
view.zoomByDelta(map, delta, anchor,
ol.interaction.DBLCLICKZOOM_ANIMATION_DURATION);
mapBrowserEvent.preventDefault();
browserEvent.preventDefault();
}
};
@@ -0,0 +1 @@
@exportSymbol ol.interaction.defaults ol.interaction.defaults
+99
View File
@@ -0,0 +1,99 @@
goog.provide('ol.interaction.defaults');
goog.require('ol.Collection');
goog.require('ol.Kinetic');
goog.require('ol.interaction.DblClickZoom');
goog.require('ol.interaction.DragPan');
goog.require('ol.interaction.DragRotate');
goog.require('ol.interaction.DragZoom');
goog.require('ol.interaction.Interaction');
goog.require('ol.interaction.KeyboardPan');
goog.require('ol.interaction.KeyboardZoom');
goog.require('ol.interaction.MouseWheelZoom');
goog.require('ol.interaction.TouchPan');
goog.require('ol.interaction.TouchRotate');
goog.require('ol.interaction.TouchZoom');
goog.require('ol.interaction.condition');
/**
* @param {ol.interaction.DefaultOptions=} opt_options Options.
* @param {Array.<ol.interaction.Interaction>=} opt_interactions Additional
* interactions.
* @return {ol.Collection} Interactions.
*/
ol.interaction.defaults = function(opt_options, opt_interactions) {
var options = goog.isDef(opt_options) ? opt_options : {};
var interactions = new ol.Collection();
var rotate = goog.isDef(options.rotate) ?
options.rotate : true;
if (rotate) {
interactions.push(new ol.interaction.DragRotate(
ol.interaction.condition.altShiftKeysOnly));
}
var doubleClickZoom = goog.isDef(options.doubleClickZoom) ?
options.doubleClickZoom : true;
if (doubleClickZoom) {
var zoomDelta = goog.isDef(options.zoomDelta) ?
options.zoomDelta : 1;
interactions.push(new ol.interaction.DblClickZoom(zoomDelta));
}
var touchPan = goog.isDef(options.touchPan) ?
options.touchPan : true;
if (touchPan) {
interactions.push(new ol.interaction.TouchPan(
new ol.Kinetic(-0.005, 0.05, 100)));
}
var touchRotate = goog.isDef(options.touchRotate) ?
options.touchRotate : true;
if (touchRotate) {
interactions.push(new ol.interaction.TouchRotate());
}
var touchZoom = goog.isDef(options.touchZoom) ?
options.touchZoom : true;
if (touchZoom) {
interactions.push(new ol.interaction.TouchZoom());
}
var dragPan = goog.isDef(options.dragPan) ?
options.dragPan : true;
if (dragPan) {
interactions.push(
new ol.interaction.DragPan(ol.interaction.condition.noModifierKeys,
new ol.Kinetic(-0.005, 0.05, 100)));
}
var keyboard = goog.isDef(options.keyboard) ?
options.keyboard : true;
if (keyboard) {
interactions.push(new ol.interaction.KeyboardPan());
interactions.push(new ol.interaction.KeyboardZoom());
}
var mouseWheelZoom = goog.isDef(options.mouseWheelZoom) ?
options.mouseWheelZoom : true;
if (mouseWheelZoom) {
interactions.push(new ol.interaction.MouseWheelZoom());
}
var shiftDragZoom = goog.isDef(options.shiftDragZoom) ?
options.shiftDragZoom : true;
if (shiftDragZoom) {
interactions.push(
new ol.interaction.DragZoom(ol.interaction.condition.shiftKeyOnly));
}
if (goog.isDef(opt_interactions)) {
interactions.extend(opt_interactions);
}
return interactions;
};
+132
View File
@@ -0,0 +1,132 @@
goog.provide('ol.interaction.Drag');
goog.require('goog.asserts');
goog.require('goog.functions');
goog.require('ol.Coordinate');
goog.require('ol.MapBrowserEvent');
goog.require('ol.MapBrowserEvent.EventType');
goog.require('ol.interaction.Interaction');
/**
* @constructor
* @extends {ol.interaction.Interaction}
*/
ol.interaction.Drag = function() {
goog.base(this);
/**
* @private
* @type {boolean}
*/
this.dragging_ = false;
/**
* @type {number}
*/
this.startX = 0;
/**
* @type {number}
*/
this.startY = 0;
/**
* @type {number}
*/
this.offsetX = 0;
/**
* @type {number}
*/
this.offsetY = 0;
/**
* @type {ol.Coordinate}
*/
this.startCenter = null;
/**
* @type {ol.Coordinate}
*/
this.startCoordinate = null;
};
goog.inherits(ol.interaction.Drag, ol.interaction.Interaction);
/**
* @param {ol.MapBrowserEvent} mapBrowserEvent Event.
* @protected
*/
ol.interaction.Drag.prototype.handleDrag = goog.nullFunction;
/**
* @param {ol.MapBrowserEvent} mapBrowserEvent Event.
* @protected
*/
ol.interaction.Drag.prototype.handleDragEnd = goog.nullFunction;
/**
* @param {ol.MapBrowserEvent} mapBrowserEvent Event.
* @protected
* @return {boolean} Capture dragging.
*/
ol.interaction.Drag.prototype.handleDragStart = goog.functions.FALSE;
/**
* @param {ol.MapBrowserEvent} mapBrowserEvent Event.
* @protected
*/
ol.interaction.Drag.prototype.handleDown = goog.nullFunction;
/**
* @inheritDoc
*/
ol.interaction.Drag.prototype.handleMapBrowserEvent =
function(mapBrowserEvent) {
var map = mapBrowserEvent.map;
if (!map.isDef()) {
return;
}
var view = map.getView();
var browserEvent = mapBrowserEvent.browserEvent;
if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.DOWN) {
goog.asserts.assert(browserEvent instanceof goog.events.BrowserEvent);
this.handleDown(mapBrowserEvent);
}
if (this.dragging_) {
if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.DRAG) {
goog.asserts.assert(browserEvent instanceof goog.events.BrowserEvent);
this.deltaX = browserEvent.clientX - this.startX;
this.deltaY = browserEvent.clientY - this.startY;
this.handleDrag(mapBrowserEvent);
} else if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.DRAGEND) {
goog.asserts.assert(browserEvent instanceof goog.events.BrowserEvent);
this.deltaX = browserEvent.clientX - this.startX;
this.deltaY = browserEvent.clientY - this.startY;
this.handleDragEnd(mapBrowserEvent);
this.dragging_ = false;
}
} else if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.DRAGSTART) {
goog.asserts.assert(browserEvent instanceof goog.events.BrowserEvent);
this.startX = browserEvent.clientX;
this.startY = browserEvent.clientY;
this.deltaX = 0;
this.deltaY = 0;
this.startCenter = /** @type {!ol.Coordinate} */ (view.getCenter());
this.startCoordinate = /** @type {ol.Coordinate} */
(mapBrowserEvent.getCoordinate());
var handled = this.handleDragStart(mapBrowserEvent);
if (handled) {
this.dragging_ = true;
mapBrowserEvent.preventDefault();
}
}
};
@@ -0,0 +1,137 @@
// FIXME works for View2D only
goog.provide('ol.interaction.DragPan');
goog.require('goog.asserts');
goog.require('ol.Coordinate');
goog.require('ol.Kinetic');
goog.require('ol.Pixel');
goog.require('ol.PreRenderFunction');
goog.require('ol.View2D');
goog.require('ol.ViewHint');
goog.require('ol.interaction.ConditionType');
goog.require('ol.interaction.Drag');
/**
* @constructor
* @extends {ol.interaction.Drag}
* @param {ol.interaction.ConditionType} condition Condition.
* @param {ol.Kinetic=} opt_kinetic Kinetic object.
*/
ol.interaction.DragPan = function(condition, opt_kinetic) {
goog.base(this);
/**
* @private
* @type {ol.interaction.ConditionType}
*/
this.condition_ = condition;
/**
* @private
* @type {ol.Kinetic|undefined}
*/
this.kinetic_ = opt_kinetic;
/**
* @private
* @type {?ol.PreRenderFunction}
*/
this.kineticPreRenderFn_ = null;
};
goog.inherits(ol.interaction.DragPan, ol.interaction.Drag);
/**
* @inheritDoc
*/
ol.interaction.DragPan.prototype.handleDrag = function(mapBrowserEvent) {
if (this.kinetic_) {
this.kinetic_.update(
mapBrowserEvent.browserEvent.clientX,
mapBrowserEvent.browserEvent.clientY);
}
var map = mapBrowserEvent.map;
// 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);
delta.rotate(rotation);
var newCenter = new ol.Coordinate(
this.startCenter.x + delta.x, this.startCenter.y + delta.y);
map.requestRenderFrame();
view.setCenter(newCenter);
};
/**
* @inheritDoc
*/
ol.interaction.DragPan.prototype.handleDragEnd = function(mapBrowserEvent) {
// FIXME works for View2D only
var map = mapBrowserEvent.map;
var view = map.getView();
view.setHint(ol.ViewHint.INTERACTING, -1);
if (this.kinetic_ && this.kinetic_.end()) {
var distance = this.kinetic_.getDistance();
var angle = this.kinetic_.getAngle();
var center = view.getCenter();
this.kineticPreRenderFn_ = this.kinetic_.pan(center);
map.addPreRenderFunction(this.kineticPreRenderFn_);
var centerpx = map.getPixelFromCoordinate(center);
var destpx = new ol.Pixel(
centerpx.x - distance * Math.cos(angle),
centerpx.y - distance * Math.sin(angle));
var dest = map.getCoordinateFromPixel(destpx);
view.setCenter(dest);
}
};
/**
* @inheritDoc
*/
ol.interaction.DragPan.prototype.handleDragStart = function(mapBrowserEvent) {
var browserEvent = mapBrowserEvent.browserEvent;
if (this.condition_(browserEvent)) {
if (this.kinetic_) {
this.kinetic_.begin();
this.kinetic_.update(browserEvent.clientX, browserEvent.clientY);
}
var map = mapBrowserEvent.map;
map.requestRenderFrame();
map.getView().setHint(ol.ViewHint.INTERACTING, 1);
return true;
} else {
return false;
}
};
/**
* @inheritDoc
*/
ol.interaction.DragPan.prototype.handleDown = function(mapBrowserEvent) {
var map = mapBrowserEvent.map;
// FIXME works for View2D only
var view = map.getView();
goog.asserts.assert(view instanceof ol.View2D);
goog.asserts.assert(!goog.isNull(mapBrowserEvent.frameState));
if (!goog.isNull(this.kineticPreRenderFn_) &&
map.removePreRenderFunction(this.kineticPreRenderFn_)) {
map.requestRenderFrame();
view.setCenter(mapBrowserEvent.frameState.view2DState.center);
this.kineticPreRenderFn_ = null;
}
};
@@ -0,0 +1,88 @@
// FIXME works for View2D only
goog.provide('ol.interaction.DragRotateAndZoom');
goog.require('goog.math.Vec2');
goog.require('ol.View2D');
goog.require('ol.interaction.ConditionType');
goog.require('ol.interaction.Drag');
/**
* @constructor
* @extends {ol.interaction.Drag}
* @param {ol.interaction.ConditionType} condition Condition.
*/
ol.interaction.DragRotateAndZoom = function(condition) {
goog.base(this);
/**
* @private
* @type {ol.interaction.ConditionType}
*/
this.condition_ = condition;
/**
* @private
* @type {number|undefined}
*/
this.lastAngle_;
/**
* @private
* @type {number|undefined}
*/
this.lastMagnitude_;
};
goog.inherits(ol.interaction.DragRotateAndZoom, ol.interaction.Drag);
/**
* @inheritDoc
*/
ol.interaction.DragRotateAndZoom.prototype.handleDrag =
function(mapBrowserEvent) {
var browserEvent = mapBrowserEvent.browserEvent;
var map = mapBrowserEvent.map;
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);
var magnitude = 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 :-(
if (goog.isDef(this.lastAngle_)) {
var angleDelta = theta - this.lastAngle_;
view.rotate(map, view.getRotation() - angleDelta);
}
this.lastAngle_ = theta;
if (goog.isDef(this.lastMagnitude_)) {
var resolution = this.lastMagnitude_ * (view.getResolution() / magnitude);
view.zoom(map, resolution);
}
this.lastMagnitude_ = magnitude;
};
/**
* @inheritDoc
*/
ol.interaction.DragRotateAndZoom.prototype.handleDragStart =
function(mapBrowserEvent) {
var browserEvent = mapBrowserEvent.browserEvent;
if (this.condition_(browserEvent)) {
this.lastAngle_ = undefined;
this.lastMagnitude_ = undefined;
return true;
} else {
return false;
}
};
@@ -0,0 +1,95 @@
goog.provide('ol.interaction.DragRotate');
goog.require('ol.View2D');
goog.require('ol.ViewHint');
goog.require('ol.interaction.ConditionType');
goog.require('ol.interaction.Drag');
/**
* @define {number} Animation duration.
*/
ol.interaction.DRAGROTATE_ANIMATION_DURATION = 250;
/**
* @constructor
* @extends {ol.interaction.Drag}
* @param {ol.interaction.ConditionType} condition Condition.
*/
ol.interaction.DragRotate = function(condition) {
goog.base(this);
/**
* @private
* @type {ol.interaction.ConditionType}
*/
this.condition_ = condition;
/**
* @private
* @type {number|undefined}
*/
this.lastAngle_;
};
goog.inherits(ol.interaction.DragRotate, ol.interaction.Drag);
/**
* @inheritDoc
*/
ol.interaction.DragRotate.prototype.handleDrag = function(mapBrowserEvent) {
var browserEvent = mapBrowserEvent.browserEvent;
var map = mapBrowserEvent.map;
var size = map.getSize();
var offset = mapBrowserEvent.getPixel();
var theta = Math.atan2(size.height / 2 - offset.y, offset.x - size.width / 2);
if (goog.isDef(this.lastAngle_)) {
var delta = theta - this.lastAngle_;
var view = map.getView();
// FIXME supports View2D only
goog.asserts.assert(view instanceof ol.View2D);
map.requestRenderFrame();
view.rotateWithoutConstraints(map, view.getRotation() - delta);
}
this.lastAngle_ = theta;
};
/**
* @inheritDoc
*/
ol.interaction.DragRotate.prototype.handleDragEnd = function(mapBrowserEvent) {
var browserEvent = mapBrowserEvent.browserEvent;
var map = mapBrowserEvent.map;
// FIXME supports View2D only
var view = map.getView();
goog.asserts.assert(view instanceof ol.View2D);
view.rotate(map, view.getRotation(), undefined,
ol.interaction.DRAGROTATE_ANIMATION_DURATION);
view.setHint(ol.ViewHint.INTERACTING, -1);
};
/**
* @inheritDoc
*/
ol.interaction.DragRotate.prototype.handleDragStart =
function(mapBrowserEvent) {
var browserEvent = mapBrowserEvent.browserEvent;
if (browserEvent.isMouseActionButton() && this.condition_(browserEvent)) {
var map = mapBrowserEvent.map;
// FIXME supports View2D only
var view = map.getView();
goog.asserts.assert(view instanceof ol.View2D);
map.requestRenderFrame();
this.lastAngle_ = undefined;
view.setHint(ol.ViewHint.INTERACTING, 1);
return true;
} else {
return false;
}
};
@@ -0,0 +1,96 @@
// FIXME draw drag box
// FIXME works for View2D only
goog.provide('ol.interaction.DragZoom');
goog.require('ol.Extent');
goog.require('ol.Size');
goog.require('ol.View2D');
goog.require('ol.control.DragBox');
goog.require('ol.interaction.ConditionType');
goog.require('ol.interaction.Drag');
/**
* @define {number} Hysterisis pixels.
*/
ol.SHIFT_DRAG_ZOOM_HYSTERESIS_PIXELS = 8;
/**
* @const {number}
*/
ol.SHIFT_DRAG_ZOOM_HYSTERESIS_PIXELS_SQUARED =
ol.SHIFT_DRAG_ZOOM_HYSTERESIS_PIXELS *
ol.SHIFT_DRAG_ZOOM_HYSTERESIS_PIXELS;
/**
* @constructor
* @extends {ol.interaction.Drag}
* @param {ol.interaction.ConditionType} condition Condition.
*/
ol.interaction.DragZoom = function(condition) {
goog.base(this);
/**
* @private
* @type {ol.interaction.ConditionType}
*/
this.condition_ = condition;
/**
* @type {ol.control.DragBox}
* @private
*/
this.dragBox_ = null;
};
goog.inherits(ol.interaction.DragZoom, ol.interaction.Drag);
/**
* @inheritDoc
*/
ol.interaction.DragZoom.prototype.handleDragEnd =
function(mapBrowserEvent) {
this.dragBox_.setMap(null);
this.dragBox_ = null;
if (this.deltaX * this.deltaX + this.deltaY * this.deltaY >=
ol.SHIFT_DRAG_ZOOM_HYSTERESIS_PIXELS_SQUARED) {
var map = mapBrowserEvent.map;
var extent = ol.Extent.boundingExtent(
this.startCoordinate,
mapBrowserEvent.getCoordinate());
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);
});
}
};
/**
* @inheritDoc
*/
ol.interaction.DragZoom.prototype.handleDragStart =
function(mapBrowserEvent) {
var browserEvent = mapBrowserEvent.browserEvent;
if (browserEvent.isMouseActionButton() && this.condition_(browserEvent)) {
this.dragBox_ = new ol.control.DragBox({
map: mapBrowserEvent.map,
startCoordinate: this.startCoordinate
});
return true;
} else {
return false;
}
};
+20
View File
@@ -0,0 +1,20 @@
// FIXME factor out key precondition (shift et. al)
goog.provide('ol.interaction.Interaction');
goog.require('ol.MapBrowserEvent');
/**
* @constructor
*/
ol.interaction.Interaction = function() {
};
/**
* @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
*/
ol.interaction.Interaction.prototype.handleMapBrowserEvent =
goog.abstractMethod;
@@ -0,0 +1,3 @@
@exportSymbol ol.interaction.Keyboard
@exportProperty ol.interaction.Keyboard.prototype.addCallback
@@ -0,0 +1,53 @@
// FIXME this class is ugly and should be removed
goog.provide('ol.interaction.Keyboard');
goog.require('ol.interaction.Interaction');
/**
* @constructor
* @extends {ol.interaction.Interaction}
*/
ol.interaction.Keyboard = function() {
goog.base(this);
/**
* @private
* @type {Object.<number, Function>}
*/
this.charCodeCallbacks_ = {};
};
goog.inherits(ol.interaction.Keyboard, ol.interaction.Interaction);
/**
* @param {string} s String.
* @param {Function} callback Callback.
*/
ol.interaction.Keyboard.prototype.addCallback = function(s, callback) {
var i;
for (i = 0; i < s.length; ++i) {
this.charCodeCallbacks_[s.charCodeAt(i)] = callback;
}
};
/**
* @inheritDoc
*/
ol.interaction.Keyboard.prototype.handleMapBrowserEvent =
function(mapBrowserEvent) {
if (mapBrowserEvent.type == goog.events.KeyHandler.EventType.KEY) {
var keyEvent = /** @type {goog.events.KeyEvent} */
(mapBrowserEvent.browserEvent);
var callback = this.charCodeCallbacks_[keyEvent.charCode];
if (callback) {
callback();
mapBrowserEvent.preventDefault();
}
}
};
@@ -0,0 +1,77 @@
// FIXME works for View2D only
goog.provide('ol.interaction.KeyboardPan');
goog.require('goog.events.KeyCodes');
goog.require('goog.events.KeyHandler.EventType');
goog.require('ol.Coordinate');
goog.require('ol.View2D');
goog.require('ol.interaction.Interaction');
/**
* @define {number} Pan duration.
*/
ol.interaction.KEYBOARD_PAN_DURATION = 100;
/**
* @constructor
* @extends {ol.interaction.Interaction}
* @param {ol.interaction.KeyboardPanOptions=} opt_options Options.
*/
ol.interaction.KeyboardPan = function(opt_options) {
goog.base(this);
var options = goog.isDef(opt_options) ? opt_options : {};
/**
* @private
* @type {number}
*/
this.delta_ = goog.isDef(options.delta) ? options.delta : 128;
};
goog.inherits(ol.interaction.KeyboardPan, ol.interaction.Interaction);
/**
* @inheritDoc
*/
ol.interaction.KeyboardPan.prototype.handleMapBrowserEvent =
function(mapBrowserEvent) {
if (mapBrowserEvent.type == goog.events.KeyHandler.EventType.KEY) {
var keyEvent = /** @type {goog.events.KeyEvent} */
(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;
// 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 mapUnitsDelta = resolution * this.delta_;
var deltaX = 0, deltaY = 0;
if (keyCode == goog.events.KeyCodes.DOWN) {
deltaY = -mapUnitsDelta;
} else if (keyCode == goog.events.KeyCodes.LEFT) {
deltaX = -mapUnitsDelta;
} else if (keyCode == goog.events.KeyCodes.RIGHT) {
deltaX = mapUnitsDelta;
} else {
deltaY = mapUnitsDelta;
}
var delta = new ol.Coordinate(deltaX, deltaY);
delta.rotate(rotation);
view.pan(map, delta, ol.interaction.KEYBOARD_PAN_DURATION);
keyEvent.preventDefault();
mapBrowserEvent.preventDefault();
}
}
};
@@ -0,0 +1,60 @@
// FIXME works for View2D only
goog.provide('ol.interaction.KeyboardZoom');
goog.require('goog.events.KeyHandler.EventType');
goog.require('ol.View2D');
goog.require('ol.interaction.Interaction');
/**
* @define {number} Zoom duration.
*/
ol.interaction.KEYBOARD_ZOOM_DURATION = 100;
/**
* @constructor
* @param {ol.interaction.KeyboardZoomOptions=} opt_options Options.
* @extends {ol.interaction.Interaction}
*/
ol.interaction.KeyboardZoom = function(opt_options) {
goog.base(this);
var options = goog.isDef(opt_options) ? opt_options : {};
/**
* @private
* @type {number}
*/
this.delta_ = goog.isDef(options.delta) ? options.delta : 1;
};
goog.inherits(ol.interaction.KeyboardZoom, ol.interaction.Interaction);
/**
* @inheritDoc
*/
ol.interaction.KeyboardZoom.prototype.handleMapBrowserEvent =
function(mapBrowserEvent) {
if (mapBrowserEvent.type == goog.events.KeyHandler.EventType.KEY) {
var keyEvent = /** @type {goog.events.KeyEvent} */
(mapBrowserEvent.browserEvent);
var charCode = keyEvent.charCode;
if (charCode == '+'.charCodeAt(0) || charCode == '-'.charCodeAt(0)) {
var map = mapBrowserEvent.map;
var delta = (charCode == '+'.charCodeAt(0)) ? this.delta_ : -this.delta_;
map.requestRenderFrame();
// FIXME works for View2D only
var view = map.getView();
goog.asserts.assert(view instanceof ol.View2D);
view.zoomByDelta(map, delta, undefined,
ol.interaction.KEYBOARD_ZOOM_DURATION);
keyEvent.preventDefault();
mapBrowserEvent.preventDefault();
}
}
};
@@ -0,0 +1,121 @@
// FIXME works for View2D only
goog.provide('ol.interaction.MouseWheelZoom');
goog.require('goog.events.MouseWheelEvent');
goog.require('goog.events.MouseWheelHandler.EventType');
goog.require('goog.math');
goog.require('ol.Coordinate');
goog.require('ol.View2D');
goog.require('ol.interaction.Interaction');
/**
* @define {number} Animation duration.
*/
ol.interaction.MOUSEWHEELZOOM_ANIMATION_DURATION = 250;
/**
* @define {number} Maximum delta.
*/
ol.interaction.MOUSEWHEELZOOM_MAXDELTA = 1;
/**
* @define {number} Timeout duration.
*/
ol.interaction.MOUSEWHEELZOOM_TIMEOUT_DURATION = 80;
/**
* @constructor
* @extends {ol.interaction.Interaction}
*/
ol.interaction.MouseWheelZoom = function() {
goog.base(this);
/**
* @private
* @type {number}
*/
this.delta_ = 0;
/**
* @private
* @type {?ol.Coordinate}
*/
this.lastAnchor_ = null;
/**
* @private
* @type {number|undefined}
*/
this.startTime_ = undefined;
/**
* @private
* @type {number|undefined}
*/
this.timeoutId_ = undefined;
};
goog.inherits(ol.interaction.MouseWheelZoom, ol.interaction.Interaction);
/**
* @inheritDoc
*/
ol.interaction.MouseWheelZoom.prototype.handleMapBrowserEvent =
function(mapBrowserEvent) {
if (mapBrowserEvent.type ==
goog.events.MouseWheelHandler.EventType.MOUSEWHEEL) {
var map = mapBrowserEvent.map;
var mouseWheelEvent = /** @type {goog.events.MouseWheelEvent} */
(mapBrowserEvent.browserEvent);
goog.asserts.assert(mouseWheelEvent instanceof goog.events.MouseWheelEvent);
this.lastAnchor_ = mapBrowserEvent.getCoordinate();
this.delta_ += mouseWheelEvent.deltaY / 3;
if (!goog.isDef(this.startTime_)) {
this.startTime_ = goog.now();
}
var duration = ol.interaction.MOUSEWHEELZOOM_TIMEOUT_DURATION;
var timeLeft = Math.max(duration - (goog.now() - this.startTime_), 0);
goog.global.clearTimeout(this.timeoutId_);
this.timeoutId_ = goog.global.setTimeout(
goog.bind(this.doZoom_, this, map), timeLeft);
mapBrowserEvent.preventDefault();
mouseWheelEvent.preventDefault();
}
};
/**
* @private
* @param {ol.Map} map Map.
*/
ol.interaction.MouseWheelZoom.prototype.doZoom_ = function(map) {
var maxDelta = ol.interaction.MOUSEWHEELZOOM_MAXDELTA;
var delta = goog.math.clamp(this.delta_, -maxDelta, maxDelta);
// FIXME works for View2D only
var view = map.getView();
goog.asserts.assert(view instanceof ol.View2D);
map.requestRenderFrame();
view.zoomByDelta(map, -delta, this.lastAnchor_,
ol.interaction.MOUSEWHEELZOOM_ANIMATION_DURATION);
this.delta_ = 0;
this.lastAnchor_ = null;
this.startTime_ = undefined;
this.timeoutId_ = undefined;
};
@@ -0,0 +1,120 @@
goog.provide('ol.interaction.Touch');
goog.require('goog.functions');
goog.require('ol.MapBrowserEvent');
goog.require('ol.MapBrowserEvent.EventType');
goog.require('ol.Pixel');
goog.require('ol.interaction.Interaction');
/**
* @constructor
* @extends {ol.interaction.Interaction}
*/
ol.interaction.Touch = function() {
goog.base(this);
/**
* @type {boolean}
* @private
*/
this.handled_ = false;
/**
* @type {Object}
* @private
*/
this.trackedTouches_ = {};
/**
* @type {Array.<Object>}
* @protected
*/
this.targetTouches = [];
};
goog.inherits(ol.interaction.Touch, ol.interaction.Interaction);
/**
* @param {Array.<Object>} touches TouchEvents.
* @return {ol.Pixel} Centroid pixel.
*/
ol.interaction.Touch.centroid = function(touches) {
var length = touches.length;
var clientX = 0;
var clientY = 0;
for (var i = 0; i < length; i++) {
clientX += touches[i].clientX;
clientY += touches[i].clientY;
}
return new ol.Pixel(clientX / length, clientY / length);
};
/**
* @param {ol.MapBrowserEvent} mapBrowserEvent Event.
* @private
*/
ol.interaction.Touch.prototype.updateTrackedTouches_ =
function(mapBrowserEvent) {
var event = mapBrowserEvent.browserEvent.getBrowserEvent();
if (goog.isDef(event.targetTouches)) {
// W3C touch events
this.targetTouches = event.targetTouches;
} else {
// IE pointer event
if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.TOUCHEND) {
delete this.trackedTouches_[event.pointerId];
} else {
this.trackedTouches_[event.pointerId] = event;
}
this.targetTouches = goog.object.getValues(this.trackedTouches_);
}
};
/**
* @param {ol.MapBrowserEvent} mapBrowserEvent Event.
* @protected
*/
ol.interaction.Touch.prototype.handleTouchMove = goog.nullFunction;
/**
* @param {ol.MapBrowserEvent} mapBrowserEvent Event.
* @protected
* @return {boolean} Capture dragging.
*/
ol.interaction.Touch.prototype.handleTouchEnd = goog.functions.FALSE;
/**
* @param {ol.MapBrowserEvent} mapBrowserEvent Event.
* @protected
* @return {boolean} Capture dragging.
*/
ol.interaction.Touch.prototype.handleTouchStart = goog.functions.FALSE;
/**
* @inheritDoc
*/
ol.interaction.Touch.prototype.handleMapBrowserEvent =
function(mapBrowserEvent) {
var browserEvent = mapBrowserEvent.browserEvent.getBrowserEvent();
this.updateTrackedTouches_(mapBrowserEvent);
if (this.handled_) {
if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.TOUCHMOVE) {
this.handleTouchMove(mapBrowserEvent);
} else if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.TOUCHEND) {
this.handled_ = this.handleTouchEnd(mapBrowserEvent);
}
}
if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.TOUCHSTART) {
this.handled_ = this.handleTouchStart(mapBrowserEvent);
}
};
@@ -0,0 +1,121 @@
// FIXME works for View2D only
goog.provide('ol.interaction.TouchPan');
goog.require('goog.asserts');
goog.require('ol.Coordinate');
goog.require('ol.Kinetic');
goog.require('ol.Pixel');
goog.require('ol.PreRenderFunction');
goog.require('ol.View');
goog.require('ol.ViewHint');
goog.require('ol.interaction.Touch');
/**
* @constructor
* @extends {ol.interaction.Touch}
* @param {ol.Kinetic=} opt_kinetic Kinetic object.
*/
ol.interaction.TouchPan = function(opt_kinetic) {
goog.base(this);
/**
* @private
* @type {ol.Kinetic|undefined}
*/
this.kinetic_ = opt_kinetic;
/**
* @private
* @type {?ol.PreRenderFunction}
*/
this.kineticPreRenderFn_ = null;
/**
* @type {ol.Pixel}
*/
this.lastCentroid = null;
};
goog.inherits(ol.interaction.TouchPan, ol.interaction.Touch);
/**
* @inheritDoc
*/
ol.interaction.TouchPan.prototype.handleTouchMove = function(mapBrowserEvent) {
goog.asserts.assert(this.targetTouches.length >= 1);
var centroid = ol.interaction.Touch.centroid(this.targetTouches);
if (!goog.isNull(this.lastCentroid)) {
if (this.kinetic_) {
this.kinetic_.update(centroid.x, centroid.y);
}
var deltaX = this.lastCentroid.x - centroid.x;
var deltaY = centroid.y - this.lastCentroid.y;
var view = mapBrowserEvent.map.getView();
var center = new ol.Coordinate(deltaX, deltaY)
.scale(view.getResolution())
.rotate(view.getRotation())
.add(view.getCenter());
view.setCenter(center);
}
this.lastCentroid = centroid;
};
/**
* @inheritDoc
*/
ol.interaction.TouchPan.prototype.handleTouchEnd =
function(mapBrowserEvent) {
var map = mapBrowserEvent.map;
var view = map.getView();
if (this.targetTouches.length == 0) {
view.setHint(ol.ViewHint.INTERACTING, -1);
if (this.kinetic_ && this.kinetic_.end()) {
var distance = this.kinetic_.getDistance();
var angle = this.kinetic_.getAngle();
var center = view.getCenter();
this.kineticPreRenderFn_ = this.kinetic_.pan(center);
map.addPreRenderFunction(this.kineticPreRenderFn_);
var centerpx = map.getPixelFromCoordinate(center);
var destpx = new ol.Pixel(
centerpx.x - distance * Math.cos(angle),
centerpx.y - distance * Math.sin(angle));
var dest = map.getCoordinateFromPixel(destpx);
view.setCenter(dest);
}
return false;
} else {
this.lastCentroid = null;
return true;
}
};
/**
* @inheritDoc
*/
ol.interaction.TouchPan.prototype.handleTouchStart =
function(mapBrowserEvent) {
if (this.targetTouches.length >= 1) {
var map = mapBrowserEvent.map;
var view = map.getView();
this.lastCentroid = null;
if (!goog.isNull(this.kineticPreRenderFn_) &&
map.removePreRenderFunction(this.kineticPreRenderFn_)) {
map.requestRenderFrame();
view.setCenter(mapBrowserEvent.frameState.view2DState.center);
this.kineticPreRenderFn_ = null;
}
if (this.kinetic_) {
this.kinetic_.begin();
}
view.setHint(ol.ViewHint.INTERACTING, 1);
return true;
} else {
return false;
}
};
@@ -0,0 +1,142 @@
// FIXME works for View2D only
goog.provide('ol.interaction.TouchRotate');
goog.require('goog.asserts');
goog.require('ol.View');
goog.require('ol.ViewHint');
goog.require('ol.interaction.Touch');
/**
* @define {number} Animation duration.
*/
ol.interaction.TOUCHROTATE_ANIMATION_DURATION = 250;
/**
/**
* @constructor
* @extends {ol.interaction.Touch}
* @param {number=} opt_threshold Minimal angle to start a rotation.
* Default to 0.3 (radian).
*/
ol.interaction.TouchRotate = function(opt_threshold) {
goog.base(this);
/**
* @private
* @type {number|undefined}
*/
this.lastAngle_;
/**
* @private
* @type {boolean}
*/
this.rotating_ = false;
/**
* @private
* @type {number}
*/
this.rotationDelta_ = 0.0;
/**
* @private
* @type {number}
*/
this.threshold_ = goog.isDef(opt_threshold) ? opt_threshold : 0.3;
};
goog.inherits(ol.interaction.TouchRotate, ol.interaction.Touch);
/**
* @inheritDoc
*/
ol.interaction.TouchRotate.prototype.handleTouchMove =
function(mapBrowserEvent) {
goog.asserts.assert(this.targetTouches.length >= 2);
var rotationDelta = 0.0;
var touch0 = this.targetTouches[0];
var touch1 = this.targetTouches[1];
var dx = touch0.clientX - touch1.clientX;
var dy = touch0.clientY - touch1.clientY;
// angle between touches
var angle = Math.atan2(
touch1.clientY - touch0.clientY,
touch1.clientX - touch0.clientX);
if (goog.isDef(this.lastAngle_)) {
var delta = angle - this.lastAngle_;
this.rotationDelta_ += delta;
if (!this.rotating_ &&
Math.abs(this.rotationDelta_) > this.threshold_) {
this.rotating_ = true;
}
rotationDelta = delta;
}
this.lastAngle_ = angle;
var map = mapBrowserEvent.map;
var view = map.getView();
// rotate anchor point.
// FIXME: should be the intersection point between the lines:
// touch0,touch1 and previousTouch0,previousTouch1
var viewportPosition = goog.style.getClientPosition(map.getViewport());
var centroid = ol.interaction.Touch.centroid(this.targetTouches);
centroid.x -= viewportPosition.x;
centroid.y -= viewportPosition.y;
var anchor = map.getCoordinateFromPixel(centroid);
// rotate
if (this.rotating_) {
view.rotateWithoutConstraints(map, view.getRotation() + rotationDelta,
anchor);
}
};
/**
* @inheritDoc
*/
ol.interaction.TouchRotate.prototype.handleTouchEnd =
function(mapBrowserEvent) {
if (this.targetTouches.length < 2) {
var map = mapBrowserEvent.map;
var view = map.getView();
if (this.rotating_) {
view.rotate(map, view.getRotation(), undefined,
ol.interaction.TOUCHROTATE_ANIMATION_DURATION);
}
view.setHint(ol.ViewHint.INTERACTING, -1);
return false;
} else {
return true;
}
};
/**
* @inheritDoc
*/
ol.interaction.TouchRotate.prototype.handleTouchStart =
function(mapBrowserEvent) {
if (this.targetTouches.length >= 2) {
var view = mapBrowserEvent.map.getView();
this.lastAngle_ = undefined;
this.rotating_ = false;
this.rotationDelta_ = 0.0;
view.setHint(ol.ViewHint.INTERACTING, 1);
return true;
} else {
return false;
}
};
@@ -0,0 +1,105 @@
// FIXME works for View2D only
goog.provide('ol.interaction.TouchZoom');
goog.require('goog.asserts');
goog.require('ol.View');
goog.require('ol.ViewHint');
goog.require('ol.interaction.Touch');
/**
* @define {number} Animation duration.
*/
ol.interaction.TOUCHZOOM_ANIMATION_DURATION = 250;
/**
* @constructor
* @extends {ol.interaction.Touch}
*/
ol.interaction.TouchZoom = function() {
goog.base(this);
/**
* @private
* @type {number|undefined}
*/
this.lastDistance_;
};
goog.inherits(ol.interaction.TouchZoom, ol.interaction.Touch);
/**
* @inheritDoc
*/
ol.interaction.TouchZoom.prototype.handleTouchMove =
function(mapBrowserEvent) {
goog.asserts.assert(this.targetTouches.length >= 2);
var scaleDelta = 1.0;
var touch0 = this.targetTouches[0];
var touch1 = this.targetTouches[1];
var dx = touch0.clientX - touch1.clientX;
var dy = touch0.clientY - touch1.clientY;
// distance between touches
var distance = Math.sqrt(dx * dx + dy * dy);
if (goog.isDef(this.lastDistance_)) {
scaleDelta = this.lastDistance_ / distance;
}
this.lastDistance_ = distance;
var map = mapBrowserEvent.map;
var view = map.getView();
// scale anchor point.
var viewportPosition = goog.style.getClientPosition(map.getViewport());
var centroid = ol.interaction.Touch.centroid(this.targetTouches);
centroid.x -= viewportPosition.x;
centroid.y -= viewportPosition.y;
var anchor = map.getCoordinateFromPixel(centroid);
// scale, bypass the resolution constraint
view.zoomWithoutConstraints(map, view.getResolution() * scaleDelta, anchor);
};
/**
* @inheritDoc
*/
ol.interaction.TouchZoom.prototype.handleTouchEnd =
function(mapBrowserEvent) {
if (this.targetTouches.length < 2) {
var map = mapBrowserEvent.map;
var view = map.getView();
// take the resolution constraint into account
view.zoom(map, view.getResolution(), undefined,
ol.interaction.TOUCHZOOM_ANIMATION_DURATION);
view.setHint(ol.ViewHint.INTERACTING, -1);
return false;
} else {
return true;
}
};
/**
* @inheritDoc
*/
ol.interaction.TouchZoom.prototype.handleTouchStart =
function(mapBrowserEvent) {
if (this.targetTouches.length >= 2) {
var view = mapBrowserEvent.map.getView();
this.lastDistance_ = undefined;
view.setHint(ol.ViewHint.INTERACTING, 1);
return true;
} else {
return false;
}
};
+27
View 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() {
};
+58
View File
@@ -0,0 +1,58 @@
goog.provide('ol.IView2D');
goog.provide('ol.View2DState');
goog.require('ol.Coordinate');
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
View File
@@ -0,0 +1,12 @@
goog.provide('ol.IView3D');
/**
* Interface for views.
* @interface
*/
ol.IView3D = function() {
};
+154
View File
@@ -0,0 +1,154 @@
goog.provide('ol.Kinetic');
goog.require('ol.Coordinate');
goog.require('ol.PreRenderFunction');
goog.require('ol.animation');
/**
* @typedef {{x: number,
* y: number,
* t: number}}
*/
ol.KineticPoint;
/**
* @constructor
* @param {number} decay Rate of decay (must be negative).
* @param {number} minVelocity Minimum velocity (pixels/millisecond).
* @param {number} delay Delay to consider to calculate the kinetic
* initial values (milliseconds).
*/
ol.Kinetic = function(decay, minVelocity, delay) {
/**
* @private
* @type {number}
*/
this.decay_ = decay;
/**
* @private
* @type {number}
*/
this.minVelocity_ = minVelocity;
/**
* @private
* @type {number}
*/
this.delay_ = delay;
/**
* @private
* @type {Array.<ol.KineticPoint>}
*/
this.points_ = [];
/**
* @private
* @type {number}
*/
this.angle_ = 0;
/**
* @private
* @type {number}
*/
this.initialVelocity_ = 0;
};
/**
* FIXME empty description for jsdoc
*/
ol.Kinetic.prototype.begin = function() {
this.points_.length = 0;
this.angle_ = 0;
this.initialVelocity_ = 0;
};
/**
* @param {number} x X.
* @param {number} y Y.
*/
ol.Kinetic.prototype.update = function(x, y) {
this.points_.push({
x: x,
y: y,
t: goog.now()
});
};
/**
* @return {boolean} Whether we should do kinetic animation.
*/
ol.Kinetic.prototype.end = function() {
var now = goog.now();
var lastIndex = this.points_.length - 1;
var firstIndex = lastIndex - 1;
while (firstIndex >= 0 && this.points_[firstIndex].t > now - this.delay_) {
firstIndex--;
}
if (firstIndex >= 0) {
var first = this.points_[firstIndex];
var last = this.points_[lastIndex];
var dx = last.x - first.x;
var dy = last.y - first.y;
this.angle_ = Math.atan2(dy, dx);
this.initialVelocity_ = Math.sqrt(dx * dx + dy * dy) / (last.t - first.t);
return this.initialVelocity_ > this.minVelocity_;
}
return false;
};
/**
* @param {ol.Coordinate} source Source coordinate for the animation.
* @return {ol.PreRenderFunction} Pre-render function for kinetic animation.
*/
ol.Kinetic.prototype.pan = function(source) {
var decay = this.decay_;
var initialVelocity = this.initialVelocity_;
var minVelocity = this.minVelocity_;
var duration = this.getDuration_();
var easingFunction = function(t) {
return initialVelocity * (Math.exp((decay * t) * duration) - 1) /
(minVelocity - initialVelocity);
};
return ol.animation.pan({
source: source,
duration: duration,
easing: easingFunction
});
};
/**
* @private
* @return {number} Duration of animation (milliseconds).
*/
ol.Kinetic.prototype.getDuration_ = function() {
return Math.log(this.minVelocity_ / this.initialVelocity_) / this.decay_;
};
/**
* @return {number} Total distance travelled (pixels).
*/
ol.Kinetic.prototype.getDistance = function() {
return (this.minVelocity_ - this.initialVelocity_) / this.decay_;
};
/**
* @return {number} Angle of the kinetic panning animation (radians).
*/
ol.Kinetic.prototype.getAngle = function() {
return this.angle_;
};
+1
View File
@@ -0,0 +1 @@
@exportClass ol.layer.ImageLayer ol.layer.LayerOptions
+24
View File
@@ -0,0 +1,24 @@
goog.provide('ol.layer.ImageLayer');
goog.require('ol.layer.Layer');
goog.require('ol.source.ImageSource');
/**
* @constructor
* @extends {ol.layer.Layer}
* @param {ol.layer.LayerOptions} layerOptions Layer options.
*/
ol.layer.ImageLayer = function(layerOptions) {
goog.base(this, layerOptions);
};
goog.inherits(ol.layer.ImageLayer, ol.layer.Layer);
/**
* @return {ol.source.ImageSource} Single image source.
*/
ol.layer.ImageLayer.prototype.getImageSource = function() {
return /** @type {ol.source.ImageSource} */ (this.getSource());
};
+316
View File
@@ -0,0 +1,316 @@
goog.provide('ol.layer.Layer');
goog.provide('ol.layer.LayerProperty');
goog.provide('ol.layer.LayerState');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('goog.math');
goog.require('ol.Object');
goog.require('ol.source.Source');
/**
* @enum {string}
*/
ol.layer.LayerProperty = {
BRIGHTNESS: 'brightness',
CONTRAST: 'contrast',
HUE: 'hue',
OPACITY: 'opacity',
SATURATION: 'saturation',
VISIBLE: 'visible'
};
/**
* @typedef {{brightness: number,
* contrast: number,
* hue: number,
* opacity: number,
* ready: boolean,
* saturation: number,
* visible: boolean}}
*/
ol.layer.LayerState;
/**
* @constructor
* @extends {ol.Object}
* @param {ol.layer.LayerOptions} layerOptions LayerOptions.
*/
ol.layer.Layer = function(layerOptions) {
goog.base(this);
/**
* @private
* @type {ol.source.Source}
*/
this.source_ = layerOptions.source;
this.setBrightness(
goog.isDef(layerOptions.brightness) ? layerOptions.brightness : 0);
this.setContrast(
goog.isDef(layerOptions.contrast) ? layerOptions.contrast : 1);
this.setHue(
goog.isDef(layerOptions.hue) ? layerOptions.hue : 0);
this.setOpacity(
goog.isDef(layerOptions.opacity) ? layerOptions.opacity : 1);
this.setSaturation(
goog.isDef(layerOptions.saturation) ? layerOptions.saturation : 1);
this.setVisible(
goog.isDef(layerOptions.visible) ? layerOptions.visible : true);
if (!this.source_.isReady()) {
goog.events.listenOnce(this.source_, goog.events.EventType.LOAD,
this.handleSourceLoad_, false, this);
}
};
goog.inherits(ol.layer.Layer, ol.Object);
/**
* @private
*/
ol.layer.Layer.prototype.dispatchLoadEvent_ = function() {
this.dispatchEvent(goog.events.EventType.LOAD);
};
/**
* @return {number} Brightness.
*/
ol.layer.Layer.prototype.getBrightness = function() {
return /** @type {number} */ (this.get(ol.layer.LayerProperty.BRIGHTNESS));
};
goog.exportProperty(
ol.layer.Layer.prototype,
'getBrightness',
ol.layer.Layer.prototype.getBrightness);
/**
* @return {number} Contrast.
*/
ol.layer.Layer.prototype.getContrast = function() {
return /** @type {number} */ (this.get(ol.layer.LayerProperty.CONTRAST));
};
goog.exportProperty(
ol.layer.Layer.prototype,
'getContrast',
ol.layer.Layer.prototype.getContrast);
/**
* @return {number} Hue.
*/
ol.layer.Layer.prototype.getHue = function() {
return /** @type {number} */ (this.get(ol.layer.LayerProperty.HUE));
};
goog.exportProperty(
ol.layer.Layer.prototype,
'getHue',
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));
};
goog.exportProperty(
ol.layer.Layer.prototype,
'getOpacity',
ol.layer.Layer.prototype.getOpacity);
/**
* @return {number} Saturation.
*/
ol.layer.Layer.prototype.getSaturation = function() {
return /** @type {number} */ (this.get(ol.layer.LayerProperty.SATURATION));
};
goog.exportProperty(
ol.layer.Layer.prototype,
'getSaturation',
ol.layer.Layer.prototype.getSaturation);
/**
* @return {ol.source.Source} Source.
*/
ol.layer.Layer.prototype.getSource = function() {
return this.source_;
};
/**
* @return {boolean} Visible.
*/
ol.layer.Layer.prototype.getVisible = function() {
return /** @type {boolean} */ (this.get(ol.layer.LayerProperty.VISIBLE));
};
goog.exportProperty(
ol.layer.Layer.prototype,
'getVisible',
ol.layer.Layer.prototype.getVisible);
/**
* @private
*/
ol.layer.Layer.prototype.handleSourceLoad_ = function() {
this.dispatchLoadEvent_();
};
/**
* @return {boolean} Is ready.
*/
ol.layer.Layer.prototype.isReady = function() {
return this.getSource().isReady();
};
/**
* Adjust the layer brightness. A value of -1 will render the layer completely
* black. A value of 0 will leave the brightness unchanged. A value of 1 will
* render the layer completely white. Other values are linear multipliers on
* the effect (values are clamped between -1 and 1).
*
* The filter effects draft [1] says the brightness function is supposed to
* render 0 black, 1 unchanged, and all other values as a linear multiplier.
*
* The current WebKit implementation clamps values between -1 (black) and 1
* (white) [2]. There is a bug open to change the filter effect spec [3].
*
* TODO: revisit this if the spec is still unmodified before we release
*
* [1] https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html
* [2] https://github.com/WebKit/webkit/commit/8f4765e569
* [3] https://www.w3.org/Bugs/Public/show_bug.cgi?id=15647
*
* @param {number} brightness Brightness.
*/
ol.layer.Layer.prototype.setBrightness = function(brightness) {
brightness = goog.math.clamp(brightness, -1, 1);
if (brightness != this.getBrightness()) {
this.set(ol.layer.LayerProperty.BRIGHTNESS, brightness);
}
};
goog.exportProperty(
ol.layer.Layer.prototype,
'setBrightness',
ol.layer.Layer.prototype.setBrightness);
/**
* Adjust the layer contrast. A value of 0 will render the layer completely
* grey. A value of 1 will leave the contrast unchanged. Other values are
* linear multipliers on the effect (and values over 1 are permitted).
*
* @param {number} contrast Contrast.
*/
ol.layer.Layer.prototype.setContrast = function(contrast) {
contrast = Math.max(0, contrast);
if (contrast != this.getContrast()) {
this.set(ol.layer.LayerProperty.CONTRAST, contrast);
}
};
goog.exportProperty(
ol.layer.Layer.prototype,
'setContrast',
ol.layer.Layer.prototype.setContrast);
/**
* Apply a hue-rotation to the layer. A value of 0 will leave the hue
* unchanged. Other values are radians around the color circle.
* @param {number} hue Hue.
*/
ol.layer.Layer.prototype.setHue = function(hue) {
if (hue != this.getHue()) {
this.set(ol.layer.LayerProperty.HUE, hue);
}
};
goog.exportProperty(
ol.layer.Layer.prototype,
'setHue',
ol.layer.Layer.prototype.setHue);
/**
* @param {number} opacity Opacity.
*/
ol.layer.Layer.prototype.setOpacity = function(opacity) {
opacity = goog.math.clamp(opacity, 0, 1);
if (opacity != this.getOpacity()) {
this.set(ol.layer.LayerProperty.OPACITY, opacity);
}
};
goog.exportProperty(
ol.layer.Layer.prototype,
'setOpacity',
ol.layer.Layer.prototype.setOpacity);
/**
* Adjust layer saturation. A value of 0 will render the layer completely
* unsaturated. A value of 1 will leave the saturation unchanged. Other
* values are linear multipliers of the effect (and values over 1 are
* permitted).
*
* @param {number} saturation Saturation.
*/
ol.layer.Layer.prototype.setSaturation = function(saturation) {
saturation = Math.max(0, saturation);
if (saturation != this.getSaturation()) {
this.set(ol.layer.LayerProperty.SATURATION, saturation);
}
};
goog.exportProperty(
ol.layer.Layer.prototype,
'setSaturation',
ol.layer.Layer.prototype.setSaturation);
/**
* @param {boolean} visible Visible.
*/
ol.layer.Layer.prototype.setVisible = function(visible) {
visible = !!visible;
if (visible != this.getVisible()) {
this.set(ol.layer.LayerProperty.VISIBLE, visible);
}
};
goog.exportProperty(
ol.layer.Layer.prototype,
'setVisible',
ol.layer.Layer.prototype.setVisible);
+1
View File
@@ -0,0 +1 @@
@exportClass ol.layer.TileLayer ol.layer.LayerOptions
+24
View File
@@ -0,0 +1,24 @@
goog.provide('ol.layer.TileLayer');
goog.require('ol.layer.Layer');
goog.require('ol.source.TileSource');
/**
* @constructor
* @extends {ol.layer.Layer}
* @param {ol.layer.LayerOptions} layerOptions Layer options.
*/
ol.layer.TileLayer = function(layerOptions) {
goog.base(this, layerOptions);
};
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());
};
+15
View File
@@ -0,0 +1,15 @@
@exportClass ol.Map ol.MapOptions
@exportProperty ol.Map.prototype.addLayer
@exportProperty ol.Map.prototype.addPreRenderFunction
@exportProperty ol.Map.prototype.addPreRenderFunctions
@exportProperty ol.Map.prototype.getInteractions
@exportProperty ol.Map.prototype.getRenderer
@exportProperty ol.Map.prototype.removeLayer
@exportSymbol ol.RendererHint
@exportProperty ol.RendererHint.CANVAS
@exportProperty ol.RendererHint.DOM
@exportProperty ol.RendererHint.WEBGL
@exportSymbol ol.RendererHints
@exportProperty ol.RendererHints.createFromQueryData
+961
View File
@@ -0,0 +1,961 @@
// FIXME recheck layer/map projection compatability when projection changes
// FIXME layer renderers should skip when they can't reproject
// FIXME add tilt and height?
goog.provide('ol.Map');
goog.provide('ol.MapProperty');
goog.provide('ol.RendererHint');
goog.provide('ol.RendererHints');
goog.require('goog.Uri.QueryData');
goog.require('goog.async.AnimationDelay');
goog.require('goog.debug.Logger');
goog.require('goog.dom');
goog.require('goog.dom.ViewportSizeMonitor');
goog.require('goog.events');
goog.require('goog.events.BrowserEvent');
goog.require('goog.events.Event');
goog.require('goog.events.EventType');
goog.require('goog.events.KeyHandler');
goog.require('goog.events.KeyHandler.EventType');
goog.require('goog.events.MouseWheelHandler');
goog.require('goog.events.MouseWheelHandler.EventType');
goog.require('goog.style');
goog.require('ol.BrowserFeature');
goog.require('ol.Collection');
goog.require('ol.Color');
goog.require('ol.Coordinate');
goog.require('ol.Extent');
goog.require('ol.FrameState');
goog.require('ol.IView');
goog.require('ol.MapBrowserEvent');
goog.require('ol.MapBrowserEvent.EventType');
goog.require('ol.MapBrowserEventHandler');
goog.require('ol.MapEvent');
goog.require('ol.MapEventType');
goog.require('ol.Object');
goog.require('ol.ObjectEventType');
goog.require('ol.Pixel');
goog.require('ol.PostRenderFunction');
goog.require('ol.PreRenderFunction');
goog.require('ol.Size');
goog.require('ol.Tile');
goog.require('ol.TileQueue');
goog.require('ol.View');
goog.require('ol.View2D');
goog.require('ol.control.defaults');
goog.require('ol.interaction.defaults');
goog.require('ol.layer.Layer');
goog.require('ol.projection');
goog.require('ol.projection.addCommonProjections');
goog.require('ol.renderer.Map');
goog.require('ol.renderer.canvas.Map');
goog.require('ol.renderer.canvas.SUPPORTED');
goog.require('ol.renderer.dom.Map');
goog.require('ol.renderer.dom.SUPPORTED');
goog.require('ol.renderer.webgl.Map');
goog.require('ol.renderer.webgl.SUPPORTED');
/**
* @define {boolean} Whether to enable canvas.
*/
ol.ENABLE_CANVAS = true;
/**
* @define {boolean} Whether to enable DOM.
*/
ol.ENABLE_DOM = true;
/**
* @define {boolean} Whether to enable WebGL.
*/
ol.ENABLE_WEBGL = true;
/**
* @enum {string}
*/
ol.RendererHint = {
CANVAS: 'canvas',
DOM: 'dom',
WEBGL: 'webgl'
};
/**
* @type {Array.<ol.RendererHint>}
*/
ol.DEFAULT_RENDERER_HINTS = [
ol.RendererHint.WEBGL,
ol.RendererHint.CANVAS,
ol.RendererHint.DOM
];
/**
* @enum {string}
*/
ol.MapProperty = {
BACKGROUND_COLOR: 'backgroundColor',
LAYERS: 'layers',
SIZE: 'size',
VIEW: 'view'
};
/**
* @constructor
* @extends {ol.Object}
* @param {ol.MapOptions} mapOptions Map options.
*/
ol.Map = function(mapOptions) {
goog.base(this);
if (goog.DEBUG) {
/**
* @protected
* @type {goog.debug.Logger}
*/
this.logger = goog.debug.Logger.getLogger('ol.map.' + goog.getUid(this));
}
var mapOptionsInternal = ol.Map.createOptionsInternal(mapOptions);
/**
* @private
* @type {goog.async.AnimationDelay}
*/
this.animationDelay_ =
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}
*/
this.freezeRenderingCount_ = 0;
/**
* @private
* @type {boolean}
*/
this.dirty_ = false;
/**
* @private
* @type {Element}
*/
this.target_ = mapOptionsInternal.target;
/**
* @private
* @type {?number}
*/
this.viewPropertyListenerKey_ = null;
/**
* @private
* @type {Element}
*/
this.viewport_ = goog.dom.createDom(goog.dom.TagName.DIV, 'ol-viewport');
this.viewport_.style.position = 'relative';
this.viewport_.style.overflow = 'hidden';
this.viewport_.style.width = '100%';
this.viewport_.style.height = '100%';
// prevent page zoom on IE >= 10 browsers
this.viewport_.style.msTouchAction = 'none';
goog.dom.appendChild(this.target_, this.viewport_);
/**
* @private
* @type {Element}
*/
this.overlayContainer_ = goog.dom.createDom(goog.dom.TagName.DIV,
'ol-overlaycontainer');
goog.events.listen(this.overlayContainer_, [
goog.events.EventType.CLICK,
ol.BrowserFeature.HAS_TOUCH ?
goog.events.EventType.TOUCHSTART : goog.events.EventType.MOUSEDOWN
], goog.events.Event.stopPropagation);
goog.dom.appendChild(this.viewport_, this.overlayContainer_);
var mapBrowserEventHandler = new ol.MapBrowserEventHandler(this);
goog.events.listen(mapBrowserEventHandler,
goog.object.getValues(ol.MapBrowserEvent.EventType),
this.handleMapBrowserEvent, false, this);
this.registerDisposable(mapBrowserEventHandler);
// FIXME we probably shouldn't listen on document...
var keyHandler = new goog.events.KeyHandler(document);
goog.events.listen(keyHandler, goog.events.KeyHandler.EventType.KEY,
this.handleBrowserEvent, false, this);
this.registerDisposable(keyHandler);
var mouseWheelHandler = new goog.events.MouseWheelHandler(this.viewport_);
goog.events.listen(mouseWheelHandler,
goog.events.MouseWheelHandler.EventType.MOUSEWHEEL,
this.handleBrowserEvent, false, this);
this.registerDisposable(mouseWheelHandler);
/**
* @type {ol.Collection}
* @private
*/
this.interactions_ = mapOptionsInternal.interactions;
/**
* @type {ol.renderer.Map}
* @private
*/
this.renderer_ =
new mapOptionsInternal.rendererConstructor(this.viewport_, this);
this.registerDisposable(this.renderer_);
/**
* @private
*/
this.viewportSizeMonitor_ = new goog.dom.ViewportSizeMonitor();
goog.events.listen(this.viewportSizeMonitor_, goog.events.EventType.RESIZE,
this.handleBrowserWindowResize, false, this);
/**
* @private
* @type {ol.Coordinate}
*/
this.focus_ = null;
/**
* @private
* @type {Array.<ol.PreRenderFunction>}
*/
this.preRenderFunctions_ = [];
/**
* @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));
goog.events.listen(this, ol.Object.getChangedEventType(ol.MapProperty.VIEW),
this.handleViewChanged_, false, this);
goog.events.listen(this, ol.Object.getChangedEventType(ol.MapProperty.SIZE),
this.handleSizeChanged_, false, this);
goog.events.listen(
this, ol.Object.getChangedEventType(ol.MapProperty.BACKGROUND_COLOR),
this.handleBackgroundColorChanged_, false, this);
this.setValues(mapOptionsInternal.values);
// this gives the map an initial size
this.handleBrowserWindowResize();
if (goog.isDef(mapOptionsInternal.controls)) {
goog.array.forEach(mapOptionsInternal.controls,
/**
* @param {ol.control.Control} control Control.
*/
function(control) {
control.setMap(this);
}, this);
}
};
goog.inherits(ol.Map, ol.Object);
/**
* @param {ol.layer.Layer} layer Layer.
*/
ol.Map.prototype.addLayer = function(layer) {
var layers = this.getLayers();
goog.asserts.assert(goog.isDef(layers));
layers.push(layer);
};
/**
* @param {ol.PreRenderFunction} preRenderFunction Pre-render function.
*/
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);
};
/**
* @param {ol.PreRenderFunction} preRenderFunction Pre-render function.
* @return {boolean} Whether the preRenderFunction has been found and removed.
*/
ol.Map.prototype.removePreRenderFunction = function(preRenderFunction) {
return goog.array.remove(this.preRenderFunctions_, preRenderFunction);
};
/**
*
* @inheritDoc
*/
ol.Map.prototype.disposeInternal = function() {
goog.dom.removeNode(this.viewport_);
goog.base(this, 'disposeInternal');
};
/**
* Freeze rendering.
*/
ol.Map.prototype.freezeRendering = function() {
++this.freezeRenderingCount_;
};
/**
* @return {ol.Color|undefined} Background color.
*/
ol.Map.prototype.getBackgroundColor = function() {
return /** @type {ol.Color|undefined} */ (
this.get(ol.MapProperty.BACKGROUND_COLOR));
};
goog.exportProperty(
ol.Map.prototype,
'getBackgroundColor',
ol.Map.prototype.getBackgroundColor);
/**
* @return {ol.renderer.Map} Renderer.
*/
ol.Map.prototype.getRenderer = function() {
return this.renderer_;
};
/**
* @return {Element} Container.
*/
ol.Map.prototype.getTarget = function() {
return this.target_;
};
/**
* @param {ol.Pixel} pixel Pixel.
* @return {ol.Coordinate} Coordinate.
*/
ol.Map.prototype.getCoordinateFromPixel = function(pixel) {
var frameState = this.frameState_;
if (goog.isNull(frameState)) {
return null;
} else {
var vec3 = [pixel.x, pixel.y, 0];
goog.vec.Mat4.multVec3(frameState.pixelToCoordinateMatrix, vec3, vec3);
return new ol.Coordinate(vec3[0], vec3[1]);
}
};
/**
* @return {ol.Collection} Interactions.
*/
ol.Map.prototype.getInteractions = function() {
return this.interactions_;
};
/**
* @return {ol.Collection} Layers.
*/
ol.Map.prototype.getLayers = function() {
return /** @type {ol.Collection} */ (this.get(ol.MapProperty.LAYERS));
};
goog.exportProperty(
ol.Map.prototype,
'getLayers',
ol.Map.prototype.getLayers);
/**
* @param {ol.Coordinate} coordinate Coordinate.
* @return {ol.Pixel} Pixel.
*/
ol.Map.prototype.getPixelFromCoordinate = function(coordinate) {
var frameState = this.frameState_;
if (goog.isNull(frameState)) {
return null;
} else {
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.Size|undefined} Size.
*/
ol.Map.prototype.getSize = function() {
return /** @type {ol.Size|undefined} */ (this.get(ol.MapProperty.SIZE));
};
goog.exportProperty(
ol.Map.prototype,
'getSize',
ol.Map.prototype.getSize);
/**
* @return {ol.View} View.
*/
ol.Map.prototype.getView = function() {
return /** @type {ol.View} */ (this.get(ol.MapProperty.VIEW));
};
goog.exportProperty(
ol.Map.prototype,
'getView',
ol.Map.prototype.getView);
/**
* @return {Element} Viewport.
*/
ol.Map.prototype.getViewport = function() {
return this.viewport_;
};
/**
* @return {Element} The map's overlay container. Elements added to this
* container won't let mousedown and touchstart events through to the map, so
* clicks and gestures on an overlay don't trigger any MapBrowserEvent.
*/
ol.Map.prototype.getOverlayContainer = function() {
return this.overlayContainer_;
};
/**
* @param {ol.Tile} tile Tile.
* @param {string} tileSourceKey Tile source key.
* @param {ol.Coordinate} tileCenter Tile center.
* @return {number} Tile priority.
*/
ol.Map.prototype.getTilePriority = function(tile, tileSourceKey, tileCenter) {
var frameState = this.frameState_;
if (goog.isNull(frameState) || !(tileSourceKey in frameState.wantedTiles)) {
return ol.TileQueue.DROP;
}
var coordKey = tile.tileCoord.toString();
if (!frameState.wantedTiles[tileSourceKey][coordKey]) {
return ol.TileQueue.DROP;
}
var focus = goog.isNull(this.focus_) ?
frameState.view2DState.center : this.focus_;
var deltaX = tileCenter.x - focus.x;
var deltaY = tileCenter.y - focus.y;
return deltaX * deltaX + deltaY * deltaY;
};
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @param {string=} opt_type Type.
*/
ol.Map.prototype.handleBrowserEvent = function(browserEvent, opt_type) {
var type = opt_type || browserEvent.type;
var mapBrowserEvent = new ol.MapBrowserEvent(type, this, browserEvent);
this.handleMapBrowserEvent(mapBrowserEvent);
if (type == goog.events.EventType.MOUSEOUT) {
this.focus_ = null;
} else {
this.focus_ = mapBrowserEvent.getCoordinate();
}
};
/**
* @param {ol.MapBrowserEvent} mapBrowserEvent The event to handle.
*/
ol.Map.prototype.handleMapBrowserEvent = function(mapBrowserEvent) {
mapBrowserEvent.frameState = this.frameState_;
var interactions = this.getInteractions();
var interactionsArray = /** @type {Array.<ol.interaction.Interaction>} */
(interactions.getArray());
if (this.dispatchEvent(mapBrowserEvent) !== false) {
for (var i = interactionsArray.length - 1; i >= 0; i--) {
var interaction = interactionsArray[i];
interaction.handleMapBrowserEvent(mapBrowserEvent);
if (mapBrowserEvent.defaultPrevented) {
break;
}
}
}
};
/**
* @protected
*/
ol.Map.prototype.handlePostRender = function() {
this.tileQueue_.reprioritize(); // FIXME only call if needed
var moreLoadingTiles = this.tileQueue_.loadMoreTiles();
if (moreLoadingTiles) {
// The tile layer renderers need to know when tiles change
// to the LOADING state (to register the change listener
// on the tile).
this.requestRenderFrame();
}
var postRenderFunctions = this.postRenderFunctions_;
var i;
for (i = 0; i < postRenderFunctions.length; ++i) {
postRenderFunctions[i](this, this.frameState_);
}
postRenderFunctions.length = 0;
};
/**
* @private
*/
ol.Map.prototype.handleBackgroundColorChanged_ = function() {
this.render();
};
/**
* @protected
*/
ol.Map.prototype.handleBrowserWindowResize = function() {
var size = goog.style.getSize(this.target_);
this.setSize(new ol.Size(size.width, size.height));
};
/**
* @private
*/
ol.Map.prototype.handleSizeChanged_ = function() {
this.render();
};
/**
* @private
*/
ol.Map.prototype.handleViewPropertyChanged_ = function() {
this.render();
};
/**
* @private
*/
ol.Map.prototype.handleViewChanged_ = function() {
if (!goog.isNull(this.viewPropertyListenerKey_)) {
goog.events.unlistenByKey(this.viewPropertyListenerKey_);
this.viewPropertyListenerKey_ = null;
}
var view = this.getView();
if (goog.isDefAndNotNull(view)) {
this.viewPropertyListenerKey_ = goog.events.listen(
view, ol.ObjectEventType.CHANGED,
this.handleViewPropertyChanged_, false, this);
}
this.render();
};
/**
* @return {boolean} Is defined.
*/
ol.Map.prototype.isDef = function() {
var view = this.getView();
return goog.isDef(view) && view.isDef() &&
goog.isDefAndNotNull(this.getSize());
};
/**
* Render.
*/
ol.Map.prototype.render = function() {
if (this.animationDelay_.isActive()) {
// pass
} else if (this.freezeRenderingCount_ === 0) {
this.animationDelay_.fire();
} else {
this.dirty_ = true;
}
};
/**
* Request that renderFrame_ be called some time in the future.
*/
ol.Map.prototype.requestRenderFrame = function() {
if (this.freezeRenderingCount_ === 0) {
if (!this.animationDelay_.isActive()) {
this.animationDelay_.start();
}
} else {
this.dirty_ = true;
}
};
/**
* @param {ol.layer.Layer} layer Layer.
* @return {ol.layer.Layer|undefined} The removed layer or undefined if the
* layer was not found.
*/
ol.Map.prototype.removeLayer = function(layer) {
var layers = this.getLayers();
goog.asserts.assert(goog.isDef(layers));
return /** @type {ol.layer.Layer|undefined} */ (layers.remove(layer));
};
/**
* @param {number} time Time.
* @private
*/
ol.Map.prototype.renderFrame_ = function(time) {
var i;
if (this.freezeRenderingCount_ != 0) {
return;
}
if (goog.DEBUG) {
this.logger.info('renderFrame_');
}
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 = {};
var layer;
for (i = 0; i < layersArray.length; ++i) {
layer = layersArray[i];
layerStates[goog.getUid(layer)] = layer.getLayerState();
}
var view2DState = view2D.getView2DState();
frameState = {
animate: false,
attributions: {},
backgroundColor: goog.isDef(backgroundColor) ?
backgroundColor : new ol.Color(255, 255, 255, 1),
coordinateToPixelMatrix: this.coordinateToPixelMatrix_,
extent: null,
layersArray: layersArray,
layerStates: layerStates,
pixelToCoordinateMatrix: this.pixelToCoordinateMatrix_,
postRenderFunctions: [],
size: size,
tileQueue: this.tileQueue_,
time: time,
usedTiles: {},
view2DState: view2DState,
viewHints: viewHints,
wantedTiles: {}
};
}
var preRenderFunctions = this.preRenderFunctions_;
var n = 0, preRenderFunction;
for (i = 0; i < preRenderFunctions.length; ++i) {
preRenderFunction = preRenderFunctions[i];
if (preRenderFunction(this, frameState)) {
preRenderFunctions[n++] = preRenderFunction;
}
}
preRenderFunctions.length = n;
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.frameState_ = frameState;
this.renderer_.renderFrame(frameState);
this.dirty_ = false;
if (!goog.isNull(frameState)) {
if (frameState.animate) {
this.requestRenderFrame();
}
Array.prototype.push.apply(
this.postRenderFunctions_, frameState.postRenderFunctions);
}
this.dispatchEvent(
new ol.MapEvent(ol.MapEventType.POSTRENDER, this, frameState));
goog.global.setTimeout(this.handlePostRender_, 0);
};
/**
* @param {ol.Color} backgroundColor Background color.
*/
ol.Map.prototype.setBackgroundColor = function(backgroundColor) {
this.set(ol.MapProperty.BACKGROUND_COLOR, backgroundColor);
};
goog.exportProperty(
ol.Map.prototype,
'setBackgroundColor',
ol.Map.prototype.setBackgroundColor);
/**
* @param {ol.Collection} layers Layers.
*/
ol.Map.prototype.setLayers = function(layers) {
this.set(ol.MapProperty.LAYERS, layers);
};
goog.exportProperty(
ol.Map.prototype,
'setLayers',
ol.Map.prototype.setLayers);
/**
* @param {ol.Size} size Size.
*/
ol.Map.prototype.setSize = function(size) {
this.set(ol.MapProperty.SIZE, size);
};
goog.exportProperty(
ol.Map.prototype,
'setSize',
ol.Map.prototype.setSize);
/**
* @param {ol.IView} view View.
*/
ol.Map.prototype.setView = function(view) {
this.set(ol.MapProperty.VIEW, view);
};
goog.exportProperty(
ol.Map.prototype,
'setView',
ol.Map.prototype.setView);
/**
* Unfreeze rendering.
*/
ol.Map.prototype.unfreezeRendering = function() {
goog.asserts.assert(this.freezeRenderingCount_ > 0);
if (--this.freezeRenderingCount_ === 0 && this.dirty_) {
this.animationDelay_.fire();
}
};
/**
* @param {function(this: T)} f Function.
* @param {T=} opt_obj Object.
* @template T
*/
ol.Map.prototype.withFrozenRendering = function(f, opt_obj) {
this.freezeRendering();
try {
f.call(opt_obj);
} finally {
this.unfreezeRendering();
}
};
/**
* @typedef {{controls: Array.<ol.control.Control>,
* interactions: ol.Collection,
* rendererConstructor:
* function(new: ol.renderer.Map, Element, ol.Map),
* target: Element,
* values: Object.<string, *>}}
*/
ol.MapOptionsInternal;
/**
* @param {ol.MapOptions} mapOptions Map options.
* @return {ol.MapOptionsInternal} Map options.
*/
ol.Map.createOptionsInternal = function(mapOptions) {
/**
* @type {Object.<string, *>}
*/
var values = {};
var layers;
if (goog.isDef(mapOptions.layers)) {
if (goog.isArray(mapOptions.layers)) {
layers = new ol.Collection(goog.array.clone(mapOptions.layers));
} else {
goog.asserts.assert(mapOptions.layers instanceof ol.Collection);
layers = mapOptions.layers;
}
} else {
layers = new ol.Collection();
}
values[ol.MapProperty.LAYERS] = layers;
values[ol.MapProperty.VIEW] = goog.isDef(mapOptions.view) ?
mapOptions.view : new ol.View2D();
/**
* @type {function(new: ol.renderer.Map, Element, ol.Map)}
*/
var rendererConstructor = ol.renderer.Map;
/**
* @type {Array.<ol.RendererHint>}
*/
var rendererHints;
if (goog.isDef(mapOptions.renderers)) {
rendererHints = mapOptions.renderers;
} else if (goog.isDef(mapOptions.renderer)) {
rendererHints = [mapOptions.renderer];
} else {
rendererHints = ol.DEFAULT_RENDERER_HINTS;
}
var i, rendererHint;
for (i = 0; i < rendererHints.length; ++i) {
rendererHint = rendererHints[i];
if (rendererHint == ol.RendererHint.CANVAS) {
if (ol.ENABLE_CANVAS && ol.renderer.canvas.SUPPORTED) {
rendererConstructor = ol.renderer.canvas.Map;
break;
}
} else if (rendererHint == ol.RendererHint.DOM) {
if (ol.ENABLE_DOM && ol.renderer.dom.SUPPORTED) {
rendererConstructor = ol.renderer.dom.Map;
break;
}
} else if (rendererHint == ol.RendererHint.WEBGL) {
if (ol.ENABLE_WEBGL && ol.renderer.webgl.SUPPORTED) {
rendererConstructor = ol.renderer.webgl.Map;
break;
}
}
}
var controls = goog.isDef(mapOptions.controls) ?
mapOptions.controls : ol.control.defaults();
var interactions = goog.isDef(mapOptions.interactions) ?
mapOptions.interactions : ol.interaction.defaults();
/**
* @type {Element}
*/
var target = goog.dom.getElement(mapOptions.target);
return {
controls: controls,
interactions: interactions,
rendererConstructor: rendererConstructor,
target: target,
values: values
};
};
/**
* @param {goog.Uri.QueryData=} opt_queryData Query data.
* @return {Array.<ol.RendererHint>} Renderer hints.
*/
ol.RendererHints.createFromQueryData = function(opt_queryData) {
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')) {
return [queryData.get('renderer')];
} else {
return ol.DEFAULT_RENDERER_HINTS;
}
};
ol.projection.addCommonProjections();
+2
View File
@@ -0,0 +1,2 @@
@exportProperty ol.MapBrowserEvent.prototype.getCoordinate
+361
View File
@@ -0,0 +1,361 @@
goog.provide('ol.MapBrowserEvent');
goog.provide('ol.MapBrowserEvent.EventType');
goog.provide('ol.MapBrowserEventHandler');
goog.require('goog.array');
goog.require('goog.events.BrowserEvent');
goog.require('goog.events.EventTarget');
goog.require('goog.events.EventType');
goog.require('goog.style');
goog.require('ol.BrowserFeature');
goog.require('ol.Coordinate');
goog.require('ol.FrameState');
goog.require('ol.MapEvent');
goog.require('ol.Pixel');
/**
* @constructor
* @extends {ol.MapEvent}
* @param {string} type Event type.
* @param {ol.Map} map Map.
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @param {?ol.FrameState=} opt_frameState Frame state.
*/
ol.MapBrowserEvent = function(type, map, browserEvent, opt_frameState) {
goog.base(this, type, map, opt_frameState);
/**
* @type {goog.events.BrowserEvent}
*/
this.browserEvent = browserEvent;
/**
* @private
* @type {ol.Coordinate}
*/
this.coordinate_ = null;
/**
* @private
* @type {ol.Pixel}
*/
this.pixel_ = null;
};
goog.inherits(ol.MapBrowserEvent, ol.MapEvent);
/**
* IE specific events.
* See http://msdn.microsoft.com/en-us/library/ie/hh673557(v=vs.85).aspx
* FIXME: replace with goog.events.EventType enum once we use
* goog/events/eventtype.js above r2211
* @enum {string}
*/
ol.MapBrowserEvent.IEEventType = {
MSPOINTERDOWN: 'MSPointerDown',
MSPOINTERMOVE: 'MSPointerMove',
MSPOINTERUP: 'MSPointerUp'
};
/**
* @return {ol.Coordinate} Coordinate.
*/
ol.MapBrowserEvent.prototype.getCoordinate = function() {
if (goog.isNull(this.coordinate_)) {
this.coordinate_ = this.map.getCoordinateFromPixel(this.getPixel());
}
return this.coordinate_;
};
/**
* Get pixel offset of the event from the top-left corner of the map viewport.
* @return {ol.Pixel} Pixel offset.
*/
ol.MapBrowserEvent.prototype.getPixel = function() {
if (goog.isNull(this.pixel_)) {
var eventPosition = goog.style.getRelativePosition(
this.browserEvent, this.map.getViewport());
this.pixel_ = new ol.Pixel(eventPosition.x, eventPosition.y);
}
return this.pixel_;
};
/**
* @return {boolean} Do we have a left click?
*/
ol.MapBrowserEvent.prototype.isMouseActionButton = function() {
// always assume a left-click on touch devices
return ol.BrowserFeature.HAS_TOUCH ||
this.browserEvent.isMouseActionButton();
};
/**
* @param {ol.Map} map The map with the viewport to listen to events on.
* @constructor
* @extends {goog.events.EventTarget}
*/
ol.MapBrowserEventHandler = function(map) {
/**
* This is the element that we will listen to the real events on.
* @type {ol.Map}
* @private
*/
this.map_ = map;
/**
* @type {Object}
* @private
*/
this.previous_ = null;
/**
* @type {boolean}
* @private
*/
this.dragged_ = false;
/**
* Timestamp for the first click of a double click. Will be set back to 0
* as soon as a double click is detected.
* @type {?number}
* @private
*/
this.timestamp_ = null;
/**
* @type {?number}
* @private
*/
this.clickListenerKey_ = null;
/**
* @type {?number}
* @private
*/
this.downListenerKey_ = null;
/**
* @type {Array.<number>}
* @private
*/
this.dragListenerKeys_ = null;
/**
* @type {Array.<number>}
* @private
*/
this.touchListenerKeys_ = null;
/**
* @type {goog.events.BrowserEvent}
* @private
*/
this.down_ = null;
var element = this.map_.getViewport();
this.clickListenerKey_ = goog.events.listen(element,
[goog.events.EventType.CLICK, goog.events.EventType.DBLCLICK],
this.click_, false, this);
this.downListenerKey_ = goog.events.listen(element,
goog.events.EventType.MOUSEDOWN,
this.handleMouseDown_, false, this);
// touch events
this.touchListenerKeys_ = [
goog.events.listen(element, [
goog.events.EventType.TOUCHSTART,
ol.MapBrowserEvent.IEEventType.MSPOINTERDOWN
], this.handleTouchStart_, false, this),
goog.events.listen(element, [
goog.events.EventType.TOUCHMOVE,
ol.MapBrowserEvent.IEEventType.MSPOINTERMOVE
], this.handleTouchMove_, false, this),
goog.events.listen(element, [
goog.events.EventType.TOUCHEND,
ol.MapBrowserEvent.IEEventType.MSPOINTERUP
], this.handleTouchEnd_, false, this)
];
};
goog.inherits(ol.MapBrowserEventHandler, goog.events.EventTarget);
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @private
*/
ol.MapBrowserEventHandler.prototype.click_ = function(browserEvent) {
if (!this.dragged_) {
var newEvent;
var type = browserEvent.type;
if (this.timestamp_ == 0 || type == goog.events.EventType.DBLCLICK) {
newEvent = new ol.MapBrowserEvent(
ol.MapBrowserEvent.EventType.DBLCLICK, this.map_, browserEvent);
this.dispatchEvent(newEvent);
} else {
newEvent = new ol.MapBrowserEvent(
ol.MapBrowserEvent.EventType.CLICK, this.map_, browserEvent);
this.dispatchEvent(newEvent);
}
}
};
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @private
*/
ol.MapBrowserEventHandler.prototype.handleMouseUp_ = function(browserEvent) {
if (this.previous_) {
this.down_ = null;
goog.array.forEach(this.dragListenerKeys_, goog.events.unlistenByKey);
this.dragListenerKeys_ = null;
this.previous_ = null;
if (this.dragged_) {
var newEvent = new ol.MapBrowserEvent(
ol.MapBrowserEvent.EventType.DRAGEND, this.map_, browserEvent);
this.dispatchEvent(newEvent);
}
}
};
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @private
*/
ol.MapBrowserEventHandler.prototype.handleMouseDown_ = function(browserEvent) {
var newEvent = new ol.MapBrowserEvent(
ol.MapBrowserEvent.EventType.DOWN, this.map_, browserEvent);
this.dispatchEvent(newEvent);
if (!this.previous_) {
this.down_ = browserEvent;
this.previous_ = {
clientX: browserEvent.clientX,
clientY: browserEvent.clientY
};
this.dragged_ = false;
this.dragListenerKeys_ = [
goog.events.listen(document, goog.events.EventType.MOUSEMOVE,
this.handleMouseMove_, false, this),
goog.events.listen(document, goog.events.EventType.MOUSEUP,
this.handleMouseUp_, false, this)
];
// prevent browser image dragging with the dom renderer
browserEvent.preventDefault();
}
};
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @private
*/
ol.MapBrowserEventHandler.prototype.handleMouseMove_ = function(browserEvent) {
var newEvent;
if (!this.dragged_) {
this.dragged_ = true;
newEvent = new ol.MapBrowserEvent(
ol.MapBrowserEvent.EventType.DRAGSTART, this.map_, this.down_);
this.dispatchEvent(newEvent);
}
this.previous_ = {
clientX: browserEvent.clientX,
clientY: browserEvent.clientY
};
newEvent = new ol.MapBrowserEvent(
ol.MapBrowserEvent.EventType.DRAG, this.map_, browserEvent);
this.dispatchEvent(newEvent);
};
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @private
*/
ol.MapBrowserEventHandler.prototype.handleTouchStart_ = function(browserEvent) {
// prevent context menu
browserEvent.preventDefault();
this.down_ = browserEvent;
this.dragged_ = false;
var newEvent = new ol.MapBrowserEvent(
ol.MapBrowserEvent.EventType.TOUCHSTART, this.map_, browserEvent);
this.dispatchEvent(newEvent);
};
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @private
*/
ol.MapBrowserEventHandler.prototype.handleTouchMove_ = function(browserEvent) {
this.dragged_ = true;
var newEvent = new ol.MapBrowserEvent(
ol.MapBrowserEvent.EventType.TOUCHMOVE, this.map_, browserEvent);
this.dispatchEvent(newEvent);
};
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @private
*/
ol.MapBrowserEventHandler.prototype.handleTouchEnd_ = function(browserEvent) {
var newEvent = new ol.MapBrowserEvent(
ol.MapBrowserEvent.EventType.TOUCHEND, this.map_, browserEvent);
this.dispatchEvent(newEvent);
if (!this.dragged_) {
var now = goog.now();
if (!this.timestamp_ || now - this.timestamp_ > 250) {
this.timestamp_ = now;
} else {
this.timestamp_ = 0;
}
this.click_(this.down_);
}
this.down_ = null;
};
/**
* FIXME empty description for jsdoc
*/
ol.MapBrowserEventHandler.prototype.disposeInternal = function() {
goog.events.unlistenByKey(this.clickListenerKey_);
goog.events.unlistenByKey(this.downListenerKey_);
if (!goog.isNull(this.dragListenerKeys_)) {
goog.array.forEach(this.dragListenerKeys_, goog.events.unlistenByKey);
this.dragListenerKeys_ = null;
}
if (!goog.isNull(this.touchListenerKeys_)) {
goog.array.forEach(this.touchListenerKeys_, goog.events.unlistenByKey);
this.touchListenerKeys_ = null;
}
goog.base(this, 'disposeInternal');
};
/**
* Constants for event names.
* @enum {string}
*/
ol.MapBrowserEvent.EventType = {
CLICK: goog.events.EventType.CLICK,
DBLCLICK: goog.events.EventType.DBLCLICK,
DOWN: 'down',
DRAGSTART: 'dragstart',
DRAG: 'drag',
DRAGEND: 'dragend',
TOUCHSTART: goog.events.EventType.TOUCHSTART,
TOUCHMOVE: goog.events.EventType.TOUCHMOVE,
TOUCHEND: goog.events.EventType.TOUCHEND
};
+53
View File
@@ -0,0 +1,53 @@
goog.provide('ol.MapEvent');
goog.provide('ol.MapEventType');
goog.require('goog.events.Event');
goog.require('ol.FrameState');
/**
* @enum {string}
*/
ol.MapEventType = {
POSTRENDER: 'postrender'
};
/**
* @constructor
* @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, opt_frameState) {
goog.base(this, type);
/**
* @type {ol.Map}
*/
this.map = map;
/**
* @type {boolean}
*/
this.defaultPrevented = false;
/**
* @type {?ol.FrameState}
*/
this.frameState = goog.isDef(opt_frameState) ? opt_frameState : null;
};
goog.inherits(ol.MapEvent, goog.events.Event);
/**
* Prevents the default action.
*/
ol.MapEvent.prototype.preventDefault = function() {
goog.base(this, 'preventDefault');
this.defaultPrevented = true;
};
+57
View File
@@ -0,0 +1,57 @@
goog.provide('ol.math');
/**
* @param {number} x X.
* @return {number} Hyperbolic cosine of x.
*/
ol.math.cosh = function(x) {
return (Math.exp(x) + Math.exp(-x)) / 2;
};
/**
* @param {number} x X.
* @return {number} Hyperbolic cotangent of x.
*/
ol.math.coth = function(x) {
var expMinusTwoX = Math.exp(-2 * x);
return (1 + expMinusTwoX) / (1 - expMinusTwoX);
};
/**
* @param {number} x X.
* @return {number} Hyperbolic cosecant of x.
*/
ol.math.csch = function(x) {
return 2 / (Math.exp(x) - Math.exp(-x));
};
/**
* @param {number} x X.
* @return {number} Hyperbolic secant of x.
*/
ol.math.sech = function(x) {
return 2 / (Math.exp(x) + Math.exp(-x));
};
/**
* @param {number} x X.
* @return {number} Hyperbolic sine of x.
*/
ol.math.sinh = function(x) {
return (Math.exp(x) - Math.exp(-x)) / 2;
};
/**
* @param {number} x X.
* @return {number} Hyperbolic tangent of x.
*/
ol.math.tanh = function(x) {
var expMinusTwoX = Math.exp(-2 * x);
return (1 - expMinusTwoX) / (1 + expMinusTwoX);
};
+10
View File
@@ -0,0 +1,10 @@
@exportSymbol ol.Object
@exportProperty ol.Object.prototype.bindTo
@exportProperty ol.Object.prototype.changed
@exportProperty ol.Object.prototype.get
@exportProperty ol.Object.prototype.notify
@exportProperty ol.Object.prototype.set
@exportProperty ol.Object.prototype.setOptions
@exportProperty ol.Object.prototype.setValues
@exportProperty ol.Object.prototype.unbind
@exportProperty ol.Object.prototype.unbindAll
+302
View File
@@ -0,0 +1,302 @@
/**
* An implementation of Google Maps' MVCObject.
* @see https://developers.google.com/maps/articles/mvcfun
* @see https://developers.google.com/maps/documentation/javascript/reference
*/
goog.provide('ol.Object');
goog.provide('ol.ObjectEventType');
goog.require('goog.array');
goog.require('goog.events');
goog.require('goog.events.EventTarget');
goog.require('goog.object');
/**
* @enum {string}
*/
ol.ObjectEventType = {
CHANGED: 'changed'
};
/**
* @enum {string}
*/
ol.ObjectProperty = {
ACCESSORS: 'ol_accessors_',
BINDINGS: 'ol_bindings_'
};
/**
* @constructor
* @extends {goog.events.EventTarget}
* @param {Object.<string, *>=} opt_values Values.
*/
ol.Object = function(opt_values) {
goog.base(this);
/**
* @private
* @type {Object.<string, *>}
*/
this.values_ = {};
if (goog.isDef(opt_values)) {
this.setValues(opt_values);
}
};
goog.inherits(ol.Object, goog.events.EventTarget);
/**
* @private
* @type {Object.<string, string>}
*/
ol.Object.changedEventTypeCache_ = {};
/**
* @private
* @type {Object.<string, string>}
*/
ol.Object.getterNameCache_ = {};
/**
* @private
* @type {Object.<string, string>}
*/
ol.Object.setterNameCache_ = {};
/**
* @param {string} str String.
* @return {string} Capitalized string.
*/
ol.Object.capitalize = function(str) {
return str.substr(0, 1).toUpperCase() + str.substr(1);
};
/**
* @param {ol.Object} obj Object.
* @return {Object.<string, {target: ol.Object, key: string}>} Accessors.
*/
ol.Object.getAccessors = function(obj) {
return obj[ol.ObjectProperty.ACCESSORS] ||
(obj[ol.ObjectProperty.ACCESSORS] = {});
};
/**
* @param {string} key Key.
* @return {string} Changed name.
*/
ol.Object.getChangedEventType = function(key) {
return ol.Object.changedEventTypeCache_.hasOwnProperty(key) ?
ol.Object.changedEventTypeCache_[key] :
(ol.Object.changedEventTypeCache_[key] = key.toLowerCase() + '_changed');
};
/**
* @param {string} key String.
* @return {string} Getter name.
*/
ol.Object.getGetterName = function(key) {
return ol.Object.getterNameCache_.hasOwnProperty(key) ?
ol.Object.getterNameCache_[key] :
(ol.Object.getterNameCache_[key] = 'get' + ol.Object.capitalize(key));
};
/**
* @param {ol.Object} obj Object.
* @return {Object.<string, ?number>} Listeners.
*/
ol.Object.getListeners = function(obj) {
return obj[ol.ObjectProperty.BINDINGS] ||
(obj[ol.ObjectProperty.BINDINGS] = {});
};
/**
* @param {string} key String.
* @return {string} Setter name.
*/
ol.Object.getSetterName = function(key) {
return ol.Object.setterNameCache_.hasOwnProperty(key) ?
ol.Object.setterNameCache_[key] :
(ol.Object.setterNameCache_[key] = 'set' + ol.Object.capitalize(key));
};
/**
* @param {string} key Key.
* @param {ol.Object} target Target.
* @param {string=} opt_targetKey Target key.
* @param {boolean=} opt_noNotify No notify.
*/
ol.Object.prototype.bindTo =
function(key, target, opt_targetKey, opt_noNotify) {
var targetKey = opt_targetKey || key;
this.unbind(key);
var eventType = ol.Object.getChangedEventType(targetKey);
var listeners = ol.Object.getListeners(this);
listeners[key] = goog.events.listen(target, eventType, function() {
this.notifyInternal_(key);
}, undefined, this);
var accessors = ol.Object.getAccessors(this);
accessors[key] = {target: target, key: targetKey};
var noNotify = opt_noNotify || false;
if (!noNotify) {
this.notifyInternal_(key);
}
};
/**
* @param {string} key Key.
*/
ol.Object.prototype.changed = goog.nullFunction;
/**
* @param {string} key Key.
* @return {*} Value.
*/
ol.Object.prototype.get = function(key) {
var value;
var accessors = ol.Object.getAccessors(this);
if (accessors.hasOwnProperty(key)) {
var accessor = accessors[key];
var target = accessor.target;
var targetKey = accessor.key;
var getterName = ol.Object.getGetterName(targetKey);
if (target[getterName]) {
value = target[getterName]();
} else {
value = target.get(targetKey);
}
} else if (this.values_.hasOwnProperty(key)) {
value = this.values_[key];
}
return value;
};
/**
* Get a list of object property names.
* @return {Array.<string>} List of property names.
*/
ol.Object.prototype.getKeys = function() {
var keys = goog.object.getKeys(ol.Object.getAccessors(this)).concat(
goog.object.getKeys(this.values_));
goog.array.removeDuplicates(keys);
return keys;
};
/**
* @param {string} key Key.
*/
ol.Object.prototype.notify = function(key) {
var accessors = ol.Object.getAccessors(this);
if (accessors.hasOwnProperty(key)) {
var accessor = accessors[key];
var target = accessor.target;
var targetKey = accessor.key;
target.notify(targetKey);
} else {
this.notifyInternal_(key);
}
};
/**
* @param {string} key Key.
* @private
*/
ol.Object.prototype.notifyInternal_ = function(key) {
var eventType = ol.Object.getChangedEventType(key);
this.dispatchEvent(eventType);
this.dispatchEvent(ol.ObjectEventType.CHANGED);
};
/**
* @param {string} key Key.
* @param {*} value Value.
*/
ol.Object.prototype.set = function(key, value) {
var accessors = ol.Object.getAccessors(this);
if (accessors.hasOwnProperty(key)) {
var accessor = accessors[key];
var target = accessor.target;
var targetKey = accessor.key;
var setterName = ol.Object.getSetterName(targetKey);
if (target[setterName]) {
target[setterName](value);
} else {
target.set(targetKey, value);
}
} else {
this.values_[key] = value;
this.notifyInternal_(key);
}
};
/**
* @param {Object.<string, *>} options Options.
*/
ol.Object.prototype.setOptions = function(options) {
var key, value, setterName;
for (key in options) {
value = options[key];
setterName = ol.Object.getSetterName(key);
if (this[setterName]) {
this[setterName](value);
} else {
this.set(key, value);
}
}
};
/**
* @param {Object.<string, *>} values Values.
*/
ol.Object.prototype.setValues = ol.Object.prototype.setOptions;
/**
* @param {string} key Key.
*/
ol.Object.prototype.unbind = function(key) {
var listeners = ol.Object.getListeners(this);
var listener = listeners[key];
if (listener) {
delete listeners[key];
goog.events.unlistenByKey(listener);
var value = this.get(key);
var accessors = ol.Object.getAccessors(this);
delete accessors[key];
this.values_[key] = value;
}
};
/**
* Removes all bindings.
*/
ol.Object.prototype.unbindAll = function() {
for (var key in ol.Object.getListeners(this)) {
this.unbind(key);
}
};
+9
View File
@@ -0,0 +1,9 @@
goog.provide('ol');
goog.require('goog.debug.Logger');
if (goog.DEBUG) {
var logger = goog.debug.Logger.getLogger('ol');
logger.setLevel(goog.debug.Logger.Level.FINEST);
}
@@ -0,0 +1,96 @@
goog.provide('ol.parser.ogc.ExceptionReport');
goog.require('goog.dom.xml');
goog.require('ol.parser.XML');
/**
* @constructor
* @extends {ol.parser.XML}
*/
ol.parser.ogc.ExceptionReport = function() {
var exceptionReader = function(node, exceptionReport) {
var exception = {
code: node.getAttribute('exceptionCode'),
locator: node.getAttribute('locator'),
texts: []
};
exceptionReport.exceptions.push(exception);
this.readChildNodes(node, exception);
};
var exceptionTextReader = function(node, exception) {
var text = this.getChildValue(node);
exception.texts.push(text);
};
this.readers = {
'http://www.opengis.net/ogc': {
'ServiceExceptionReport': function(node, obj) {
obj['exceptionReport'] = {};
obj['exceptionReport']['exceptions'] = [];
this.readChildNodes(node, obj['exceptionReport']);
},
'ServiceException': function(node, exceptionReport) {
var exception = {};
exception['code'] = node.getAttribute('code');
exception['locator'] = node.getAttribute('locator');
exception['text'] = this.getChildValue(node);
exceptionReport['exceptions'].push(exception);
}
},
'http://www.opengis.net/ows': {
'ExceptionReport': function(node, obj) {
obj.success = false;
obj.exceptionReport = {
version: node.getAttribute('version'),
language: node.getAttribute('language'),
exceptions: []
};
this.readChildNodes(node, obj.exceptionReport);
},
'Exception': function(node, exceptionReport) {
exceptionReader.apply(this, arguments);
},
'ExceptionText': function(node, exception) {
exceptionTextReader.apply(this, arguments);
}
},
'http://www.opengis.net/ows/1.1': {
'ExceptionReport': function(node, obj) {
obj.exceptionReport = {
version: node.getAttribute('version'),
language: node.getAttribute('xml:lang'),
exceptions: []
};
this.readChildNodes(node, obj.exceptionReport);
},
'Exception': function(node, exceptionReport) {
exceptionReader.apply(this, arguments);
},
'ExceptionText': function(node, exception) {
exceptionTextReader.apply(this, arguments);
}
}
};
goog.base(this);
};
goog.inherits(ol.parser.ogc.ExceptionReport, ol.parser.XML);
/**
* Read OGC exception report data from a string, and return an object with
* information about the exceptions.
*
* @param {string|Document} data to read/parse.
* @return {Object} Information about the exceptions that occurred.
*/
ol.parser.ogc.ExceptionReport.prototype.read = function(data) {
if (typeof data == 'string') {
data = goog.dom.xml.loadXml(data);
}
var exceptionInfo = {};
exceptionInfo['exceptionReport'] = null;
if (data) {
this.readChildNodes(data, exceptionInfo);
}
return exceptionInfo;
};
+214
View File
@@ -0,0 +1,214 @@
goog.provide('ol.parser.ogc.OWSCommon_v1');
goog.require('ol.Extent');
goog.require('ol.parser.XML');
/**
* @constructor
* @extends {ol.parser.XML}
*/
ol.parser.ogc.OWSCommon_v1 = function() {
this.readers = {
'http://www.opengis.net/ows': {
'ServiceIdentification': function(node, obj) {
obj['serviceIdentification'] = {};
this.readChildNodes(node, obj['serviceIdentification']);
},
'Title': function(node, obj) {
obj['title'] = this.getChildValue(node);
},
'Abstract': function(node, serviceIdentification) {
serviceIdentification['abstract'] = this.getChildValue(node);
},
'Keywords': function(node, serviceIdentification) {
serviceIdentification['keywords'] = {};
this.readChildNodes(node, serviceIdentification['keywords']);
},
'Keyword': function(node, keywords) {
keywords[this.getChildValue(node)] = true;
},
'ServiceType': function(node, serviceIdentification) {
serviceIdentification['serviceType'] = {
'codeSpace': node.getAttribute('codeSpace'),
'value': this.getChildValue(node)};
},
'ServiceTypeVersion': function(node, serviceIdentification) {
serviceIdentification['serviceTypeVersion'] = this.getChildValue(node);
},
'Fees': function(node, serviceIdentification) {
serviceIdentification['fees'] = this.getChildValue(node);
},
'AccessConstraints': function(node, serviceIdentification) {
serviceIdentification['accessConstraints'] =
this.getChildValue(node);
},
'ServiceProvider': function(node, obj) {
obj['serviceProvider'] = {};
this.readChildNodes(node, obj['serviceProvider']);
},
'ProviderName': function(node, serviceProvider) {
serviceProvider['providerName'] = this.getChildValue(node);
},
'ProviderSite': function(node, serviceProvider) {
serviceProvider['providerSite'] = this.getAttributeNS(node,
'http://www.w3.org/1999/xlink', 'href');
},
'ServiceContact': function(node, serviceProvider) {
serviceProvider['serviceContact'] = {};
this.readChildNodes(node, serviceProvider['serviceContact']);
},
'IndividualName': function(node, serviceContact) {
serviceContact['individualName'] = this.getChildValue(node);
},
'PositionName': function(node, serviceContact) {
serviceContact['positionName'] = this.getChildValue(node);
},
'ContactInfo': function(node, serviceContact) {
serviceContact['contactInfo'] = {};
this.readChildNodes(node, serviceContact['contactInfo']);
},
'Phone': function(node, contactInfo) {
contactInfo['phone'] = {};
this.readChildNodes(node, contactInfo['phone']);
},
'Voice': function(node, phone) {
phone['voice'] = this.getChildValue(node);
},
'Address': function(node, contactInfo) {
contactInfo['address'] = {};
this.readChildNodes(node, contactInfo['address']);
},
'DeliveryPoint': function(node, address) {
address['deliveryPoint'] = this.getChildValue(node);
},
'City': function(node, address) {
address['city'] = this.getChildValue(node);
},
'AdministrativeArea': function(node, address) {
address['administrativeArea'] = this.getChildValue(node);
},
'PostalCode': function(node, address) {
address['postalCode'] = this.getChildValue(node);
},
'Country': function(node, address) {
address['country'] = this.getChildValue(node);
},
'ElectronicMailAddress': function(node, address) {
address['electronicMailAddress'] = this.getChildValue(node);
},
'Role': function(node, serviceContact) {
serviceContact['role'] = this.getChildValue(node);
},
'OperationsMetadata': function(node, obj) {
obj['operationsMetadata'] = {};
this.readChildNodes(node, obj['operationsMetadata']);
},
'Operation': function(node, operationsMetadata) {
var name = node.getAttribute('name');
operationsMetadata[name] = {};
this.readChildNodes(node, operationsMetadata[name]);
},
'DCP': function(node, operation) {
operation['dcp'] = {};
this.readChildNodes(node, operation['dcp']);
},
'HTTP': function(node, dcp) {
dcp['http'] = {};
this.readChildNodes(node, dcp['http']);
},
'Get': function(node, http) {
if (!http['get']) {
http['get'] = [];
}
var obj = {
'url': this.getAttributeNS(node, 'http://www.w3.org/1999/xlink',
'href')
};
this.readChildNodes(node, obj);
http['get'].push(obj);
},
'Post': function(node, http) {
if (!http['post']) {
http['post'] = [];
}
var obj = {
'url': this.getAttributeNS(node, 'http://www.w3.org/1999/xlink',
'href')
};
this.readChildNodes(node, obj);
http['post'].push(obj);
},
'Parameter': function(node, operation) {
if (!operation['parameters']) {
operation['parameters'] = {};
}
var name = node.getAttribute('name');
operation['parameters'][name] = {};
this.readChildNodes(node, operation['parameters'][name]);
},
'Constraint': function(node, obj) {
if (!obj['constraints']) {
obj['constraints'] = {};
}
var name = node.getAttribute('name');
obj['constraints'][name] = {};
this.readChildNodes(node, obj['constraints'][name]);
},
'Value': function(node, allowedValues) {
allowedValues[this.getChildValue(node)] = true;
},
'OutputFormat': function(node, obj) {
obj['formats'].push({'value': this.getChildValue(node)});
this.readChildNodes(node, obj);
},
'WGS84BoundingBox': function(node, obj) {
var boundingBox = {};
boundingBox['crs'] = node.getAttribute('crs');
if (obj['BoundingBox']) {
obj['BoundingBox'].push(boundingBox);
} else {
obj['projection'] = boundingBox['crs'];
boundingBox = obj;
}
this.readChildNodes(node, boundingBox);
},
'BoundingBox': function(node, obj) {
// FIXME: We consider that BoundingBox is the same as WGS84BoundingBox
// LowerCorner = "min_x min_y"
// UpperCorner = "max_x max_y"
// It should normally depend on the projection
var readers = this.readers['http://www.opengis.net/ows'];
readers['WGS84BoundingBox'].apply(this, [node, obj]);
},
'LowerCorner': function(node, obj) {
var str = this.getChildValue(node).replace(
this.regExes.trimSpace, '');
str = str.replace(this.regExes.trimComma, ',');
var pointList = str.split(this.regExes.splitSpace);
obj['left'] = pointList[0];
obj['bottom'] = pointList[1];
},
'UpperCorner': function(node, obj) {
var str = this.getChildValue(node).replace(
this.regExes.trimSpace, '');
str = str.replace(this.regExes.trimComma, ',');
var pointList = str.split(this.regExes.splitSpace);
obj['right'] = pointList[0];
obj['top'] = pointList[1];
obj['bounds'] = new ol.Extent(parseFloat(obj['left']),
parseFloat(obj['bottom']), parseFloat(obj['right']),
parseFloat(obj['top']));
delete obj['left'];
delete obj['bottom'];
delete obj['right'];
delete obj['top'];
},
'Language': function(node, obj) {
obj['language'] = this.getChildValue(node);
}
}
};
goog.base(this);
};
goog.inherits(ol.parser.ogc.OWSCommon_v1, ol.parser.XML);
@@ -0,0 +1,45 @@
goog.provide('ol.parser.ogc.OWSCommon_v1_1_0');
goog.require('goog.object');
goog.require('ol.parser.ogc.OWSCommon_v1');
/**
* @constructor
* @extends {ol.parser.ogc.OWSCommon_v1}
*/
ol.parser.ogc.OWSCommon_v1_1_0 = function() {
goog.base(this);
this.readers['http://www.opengis.net/ows/1.1'] =
this.readers['http://www.opengis.net/ows'];
goog.object.extend(this.readers['http://www.opengis.net/ows/1.1'], {
'AllowedValues': function(node, parameter) {
parameter['allowedValues'] = {};
this.readChildNodes(node, parameter['allowedValues']);
},
'AnyValue': function(node, parameter) {
parameter['anyValue'] = true;
},
'DataType': function(node, parameter) {
parameter['dataType'] = this.getChildValue(node);
},
'Range': function(node, allowedValues) {
allowedValues['range'] = {};
this.readChildNodes(node, allowedValues['range']);
},
'MinimumValue': function(node, range) {
range['minValue'] = this.getChildValue(node);
},
'MaximumValue': function(node, range) {
range['maxValue'] = this.getChildValue(node);
},
'Identifier': function(node, obj) {
obj['identifier'] = this.getChildValue(node);
},
'SupportedCRS': function(node, obj) {
obj['supportedCRS'] = this.getChildValue(node);
}
});
};
goog.inherits(ol.parser.ogc.OWSCommon_v1_1_0,
ol.parser.ogc.OWSCommon_v1);
+121
View File
@@ -0,0 +1,121 @@
goog.provide('ol.parser.ogc.Versioned');
goog.require('goog.dom.xml');
goog.require('ol.parser.ogc.ExceptionReport');
/**
* @constructor
* @param {Object} formatOptions Options which will be set on this object.
*/
ol.parser.ogc.Versioned = function(formatOptions) {
formatOptions = formatOptions || {};
this.options = formatOptions;
this.defaultVersion = formatOptions.defaultVersion || null;
this.version = formatOptions.version;
this.profile = formatOptions.profile;
if (formatOptions.allowFallback !== undefined) {
this.allowFallback = formatOptions.allowFallback;
} else {
this.allowFallback = false;
}
if (formatOptions.stringifyOutput !== undefined) {
this.stringifyOutput = formatOptions.stringifyOutput;
} else {
this.stringifyOutput = false;
}
};
/**
* @param {Element} root root element.
* @param {Object=} opt_options optional configuration object.
* @return {string} the version to use.
*/
ol.parser.ogc.Versioned.prototype.getVersion = function(root, opt_options) {
var version;
// read
if (root) {
version = this.version;
if (!version) {
version = root.getAttribute('version');
if (!version) {
version = this.defaultVersion;
}
}
} else {
// write
version = (opt_options && opt_options.version) ||
this.version || this.defaultVersion;
}
return version;
};
/**
* @param {string} version the version to use.
* @return {Object} the parser to use.
*/
ol.parser.ogc.Versioned.prototype.getParser = function(version) {
version = version || this.defaultVersion;
var profile = this.profile ? '_' + this.profile : '';
if (!this.parser || this.parser.VERSION != version) {
var format = this.parsers['v' + version.replace(/\./g, '_') + profile];
if (!format) {
if (profile !== '' && this.allowFallback) {
// fallback to the non-profiled version of the parser
profile = '';
format = this.parsers['v' + version.replace(/\./g, '_') + profile];
}
if (!format) {
throw 'Can\'t find a parser for version ' +
version + profile;
}
}
this.parser = new format(this.options);
}
return this.parser;
};
/**
* Write a document.
*
* @param {Object} obj An object representing the document.
* @param {Object=} opt_options Optional configuration object.
* @return {Element|string} the XML created.
*/
ol.parser.ogc.Versioned.prototype.write = function(obj, opt_options) {
var version = this.getVersion(null, opt_options);
this.parser = this.getParser(version);
var root = this.parser.write(obj, opt_options);
if (this.stringifyOutput === false) {
return root;
} else {
return goog.dom.xml.serialize(root);
}
};
/**
* @param {string|Document} data Data to read.
* @param {Object=} opt_options Options for the reader.
* @return {Object} An object representing the document.
*/
ol.parser.ogc.Versioned.prototype.read = function(data, opt_options) {
if (typeof data == 'string') {
data = goog.dom.xml.loadXml(data);
}
var root = data.documentElement;
var version = this.getVersion(root);
this.parser = this.getParser(version);
var obj = this.parser.read(data, opt_options);
var errorProperty = this.parser.errorProperty || null;
if (errorProperty !== null && obj[errorProperty] === undefined) {
// an error must have happened, so parse it and report back
var format = new ol.parser.ogc.ExceptionReport();
obj.error = format.read(data);
}
obj.version = version;
return obj;
};
@@ -0,0 +1,2 @@
@exportSymbol ol.parser.ogc.WMSCapabilities
@exportProperty ol.parser.ogc.WMSCapabilities.prototype.read
@@ -0,0 +1,68 @@
goog.provide('ol.parser.ogc.WMSCapabilities');
goog.require('ol.parser.ogc.Versioned');
goog.require('ol.parser.ogc.WMSCapabilities_v1_0_0');
goog.require('ol.parser.ogc.WMSCapabilities_v1_1_0');
goog.require('ol.parser.ogc.WMSCapabilities_v1_1_1');
goog.require('ol.parser.ogc.WMSCapabilities_v1_1_1_WMSC');
goog.require('ol.parser.ogc.WMSCapabilities_v1_3_0');
/**
* @define {boolean} Whether to enable WMS Capabilities version 1.0.0.
*/
ol.ENABLE_WMSCAPS_1_0_0 = false;
/**
* @define {boolean} Whether to enable WMS Capabilities version 1.1.0.
*/
ol.ENABLE_WMSCAPS_1_1_0 = true;
/**
* @define {boolean} Whether to enable WMS Capabilities version 1.1.1.
*/
ol.ENABLE_WMSCAPS_1_1_1 = true;
/**
* @define {boolean} Whether to enable WMS Capabilities version 1.3.0.
*/
ol.ENABLE_WMSCAPS_1_3_0 = true;
/**
* @define {boolean} Whether to enable WMS Capabilities version 1.1.1.
* WMSC profile.
*/
ol.ENABLE_WMSCAPS_1_1_1_WMSC = true;
/**
* @constructor
* @param {Object=} opt_options Options which will be set on this object.
* @extends {ol.parser.ogc.Versioned}
*/
ol.parser.ogc.WMSCapabilities = function(opt_options) {
opt_options = opt_options || {};
opt_options['defaultVersion'] = '1.1.1';
this.parsers = {};
if (ol.ENABLE_WMSCAPS_1_0_0) {
this.parsers['v1_0_0'] = ol.parser.ogc.WMSCapabilities_v1_0_0;
}
if (ol.ENABLE_WMSCAPS_1_1_0) {
this.parsers['v1_1_0'] = ol.parser.ogc.WMSCapabilities_v1_1_0;
}
if (ol.ENABLE_WMSCAPS_1_1_1) {
this.parsers['v1_1_1'] = ol.parser.ogc.WMSCapabilities_v1_1_1;
}
if (ol.ENABLE_WMSCAPS_1_1_1_WMSC) {
this.parsers['v1_1_1_WMSC'] = ol.parser.ogc.WMSCapabilities_v1_1_1_WMSC;
}
if (ol.ENABLE_WMSCAPS_1_3_0) {
this.parsers['v1_3_0'] = ol.parser.ogc.WMSCapabilities_v1_3_0;
}
goog.base(this, opt_options);
};
goog.inherits(ol.parser.ogc.WMSCapabilities, ol.parser.ogc.Versioned);
@@ -0,0 +1,315 @@
goog.provide('ol.parser.ogc.WMSCapabilities_v1');
goog.require('goog.dom.xml');
goog.require('goog.object');
goog.require('ol.parser.XML');
/**
* @constructor
* @extends {ol.parser.XML}
*/
ol.parser.ogc.WMSCapabilities_v1 = function() {
this.defaultNamespaceURI = 'http://www.opengis.net/wms';
this.errorProperty = 'service';
this.readers = {
'http://www.opengis.net/wms': {
'Service': function(node, obj) {
obj['service'] = {};
this.readChildNodes(node, obj['service']);
},
'Name': function(node, obj) {
obj['name'] = this.getChildValue(node);
},
'Title': function(node, obj) {
obj['title'] = this.getChildValue(node);
},
'Abstract': function(node, obj) {
obj['abstract'] = this.getChildValue(node);
},
'BoundingBox': function(node, obj) {
var bbox = {};
bbox['bbox'] = [
parseFloat(node.getAttribute('minx')),
parseFloat(node.getAttribute('miny')),
parseFloat(node.getAttribute('maxx')),
parseFloat(node.getAttribute('maxy'))
];
var res = {
x: parseFloat(node.getAttribute('resx')),
y: parseFloat(node.getAttribute('resy'))
};
if (! (isNaN(res.x) && isNaN(res.y))) {
bbox['res'] = res;
}
// return the bbox so that descendant classes can set the
// CRS and SRS and add it to the obj
return bbox;
},
'OnlineResource': function(node, obj) {
obj['href'] = this.getAttributeNS(node, 'http://www.w3.org/1999/xlink',
'href');
},
'ContactInformation': function(node, obj) {
obj['contactInformation'] = {};
this.readChildNodes(node, obj['contactInformation']);
},
'ContactPersonPrimary': function(node, obj) {
obj['personPrimary'] = {};
this.readChildNodes(node, obj['personPrimary']);
},
'ContactPerson': function(node, obj) {
obj['person'] = this.getChildValue(node);
},
'ContactOrganization': function(node, obj) {
obj['organization'] = this.getChildValue(node);
},
'ContactPosition': function(node, obj) {
obj['position'] = this.getChildValue(node);
},
'ContactAddress': function(node, obj) {
obj['contactAddress'] = {};
this.readChildNodes(node, obj['contactAddress']);
},
'AddressType': function(node, obj) {
obj['type'] = this.getChildValue(node);
},
'Address': function(node, obj) {
obj['address'] = this.getChildValue(node);
},
'City': function(node, obj) {
obj['city'] = this.getChildValue(node);
},
'StateOrProvince': function(node, obj) {
obj['stateOrProvince'] = this.getChildValue(node);
},
'PostCode': function(node, obj) {
obj['postcode'] = this.getChildValue(node);
},
'Country': function(node, obj) {
obj['country'] = this.getChildValue(node);
},
'ContactVoiceTelephone': function(node, obj) {
obj['phone'] = this.getChildValue(node);
},
'ContactFacsimileTelephone': function(node, obj) {
obj['fax'] = this.getChildValue(node);
},
'ContactElectronicMailAddress': function(node, obj) {
obj['email'] = this.getChildValue(node);
},
'Fees': function(node, obj) {
var fees = this.getChildValue(node);
if (fees && fees.toLowerCase() != 'none') {
obj['fees'] = fees;
}
},
'AccessConstraints': function(node, obj) {
var constraints = this.getChildValue(node);
if (constraints && constraints.toLowerCase() != 'none') {
obj['accessConstraints'] = constraints;
}
},
'Capability': function(node, obj) {
obj['capability'] = {};
obj['capability']['nestedLayers'] = [];
obj['capability']['layers'] = [];
this.readChildNodes(node, obj['capability']);
},
'Request': function(node, obj) {
obj['request'] = {};
this.readChildNodes(node, obj['request']);
},
'GetCapabilities': function(node, obj) {
obj['getcapabilities'] = {};
obj['getcapabilities']['formats'] = [];
this.readChildNodes(node, obj['getcapabilities']);
},
'Format': function(node, obj) {
if (goog.isArray(obj['formats'])) {
obj['formats'].push(this.getChildValue(node));
} else {
obj['format'] = this.getChildValue(node);
}
},
'DCPType': function(node, obj) {
this.readChildNodes(node, obj);
},
'HTTP': function(node, obj) {
this.readChildNodes(node, obj);
},
'Get': function(node, obj) {
obj['get'] = {};
this.readChildNodes(node, obj['get']);
},
'Post': function(node, obj) {
obj['post'] = {};
this.readChildNodes(node, obj['post']);
},
'GetMap': function(node, obj) {
obj['getmap'] = {};
obj['getmap']['formats'] = [];
this.readChildNodes(node, obj['getmap']);
},
'GetFeatureInfo': function(node, obj) {
obj['getfeatureinfo'] = {};
obj['getfeatureinfo']['formats'] = [];
this.readChildNodes(node, obj['getfeatureinfo']);
},
'Exception': function(node, obj) {
obj['exception'] = {};
obj['exception']['formats'] = [];
this.readChildNodes(node, obj['exception']);
},
'Layer': function(node, obj) {
var parentLayer, capability;
if (obj['capability']) {
capability = obj['capability'];
parentLayer = obj;
} else {
capability = obj;
}
var attrNode = node.getAttributeNode('queryable');
var queryable = (attrNode && attrNode.specified) ?
node.getAttribute('queryable') : null;
attrNode = node.getAttributeNode('cascaded');
var cascaded = (attrNode && attrNode.specified) ?
node.getAttribute('cascaded') : null;
attrNode = node.getAttributeNode('opaque');
var opaque = (attrNode && attrNode.specified) ?
node.getAttribute('opaque') : null;
var noSubsets = node.getAttribute('noSubsets');
var fixedWidth = node.getAttribute('fixedWidth');
var fixedHeight = node.getAttribute('fixedHeight');
var parent = parentLayer || {};
var layer = {
'nestedLayers': [],
'styles': parentLayer ? [].concat(parentLayer['styles']) : [],
'srs': {},
'metadataURLs': [],
'bbox': {},
'llbbox': parent['llbbox'],
'dimensions': {},
'authorityURLs': {},
'identifiers': {},
'keywords': [],
'queryable': (queryable && queryable !== '') ?
(queryable === '1' || queryable === 'true') :
(parent['queryable'] || false),
'cascaded': (cascaded !== null) ? parseInt(cascaded, 10) :
(parent['cascaded'] || 0),
'opaque': opaque ?
(opaque === '1' || opaque === 'true') :
(parent['opaque'] || false),
'noSubsets': (noSubsets !== null) ?
(noSubsets === '1' || noSubsets === 'true') :
(parent['noSubsets'] || false),
'fixedWidth': (fixedWidth !== null) ?
parseInt(fixedWidth, 10) : (parent['fixedWidth'] || 0),
'fixedHeight': (fixedHeight !== null) ?
parseInt(fixedHeight, 10) : (parent['fixedHeight'] || 0),
'minScale': parent['minScale'],
'maxScale': parent['maxScale'],
'attribution': parent['attribution']
};
if (parentLayer) {
goog.object.extend(layer['srs'], parent['srs']);
goog.object.extend(layer['bbox'], parent['bbox']);
goog.object.extend(layer['dimensions'], parent['dimensions']);
goog.object.extend(layer['authorityURLs'], parent['authorityURLs']);
}
obj['nestedLayers'].push(layer);
layer['capability'] = capability;
this.readChildNodes(node, layer);
delete layer['capability'];
if (layer['name']) {
var parts = layer['name'].split(':'),
request = capability['request'],
gfi = request['getfeatureinfo'];
if (parts.length > 0) {
layer['prefix'] = parts[0];
}
capability['layers'].push(layer);
if (layer['formats'] === undefined) {
layer['formats'] = request['getmap']['formats'];
}
if (layer['infoFormats'] === undefined && gfi) {
layer['infoFormats'] = gfi['formats'];
}
}
},
'Attribution': function(node, obj) {
obj['attribution'] = {};
this.readChildNodes(node, obj['attribution']);
},
'LogoURL': function(node, obj) {
obj['logo'] = {
'width': node.getAttribute('width'),
'height': node.getAttribute('height')
};
this.readChildNodes(node, obj['logo']);
},
'Style': function(node, obj) {
var style = {};
obj['styles'].push(style);
this.readChildNodes(node, style);
},
'LegendURL': function(node, obj) {
var legend = {
'width': node.getAttribute('width'),
'height': node.getAttribute('height')
};
obj['legend'] = legend;
this.readChildNodes(node, legend);
},
'MetadataURL': function(node, obj) {
var metadataURL = {'type': node.getAttribute('type')};
obj['metadataURLs'].push(metadataURL);
this.readChildNodes(node, metadataURL);
},
'DataURL': function(node, obj) {
obj['dataURL'] = {};
this.readChildNodes(node, obj['dataURL']);
},
'FeatureListURL': function(node, obj) {
obj['featureListURL'] = {};
this.readChildNodes(node, obj['featureListURL']);
},
'AuthorityURL': function(node, obj) {
var name = node.getAttribute('name');
var authority = {};
this.readChildNodes(node, authority);
obj['authorityURLs'][name] = authority['href'];
},
'Identifier': function(node, obj) {
var authority = node.getAttribute('authority');
obj['identifiers'][authority] = this.getChildValue(node);
},
'KeywordList': function(node, obj) {
this.readChildNodes(node, obj);
},
'SRS': function(node, obj) {
obj['srs'][this.getChildValue(node)] = true;
}
}
};
goog.base(this);
};
goog.inherits(ol.parser.ogc.WMSCapabilities_v1, ol.parser.XML);
/**
* @param {string|Document|Element} data Data to read.
* @return {Object} An object representing the document.
*/
ol.parser.ogc.WMSCapabilities_v1.prototype.read = function(data) {
if (typeof data == 'string') {
data = goog.dom.xml.loadXml(data);
}
if (data && data.nodeType == 9) {
data = data.documentElement;
}
var obj = {};
this.readNode(data, obj);
return obj;
};
@@ -0,0 +1,62 @@
goog.provide('ol.parser.ogc.WMSCapabilities_v1_0_0');
goog.require('goog.string');
goog.require('ol.parser.ogc.WMSCapabilities_v1_1_0');
/**
* @constructor
* @extends {ol.parser.ogc.WMSCapabilities_v1_1_0}
*/
ol.parser.ogc.WMSCapabilities_v1_0_0 = function() {
goog.base(this);
this.version = '1.0.0';
goog.object.extend(this.readers['http://www.opengis.net/wms'], {
'Format': function(node, obj) {
for (var i = 0, ii = node.childNodes.length; i < ii; i++) {
var child = node.childNodes[i];
var local = child.localName || child.nodeName.split(':').pop();
if (goog.isArray(obj['formats'])) {
obj['formats'].push(local);
} else {
obj['format'] = local;
}
}
},
'Keywords': function(node, obj) {
if (!goog.isDef(obj['keywords'])) {
obj['keywords'] = [];
}
var keywords = this.getChildValue(node).split(/ +/);
for (var i = 0, ii = keywords.length; i < ii; ++i) {
if (!goog.string.isEmpty(keywords[i])) {
obj['keywords'].push({'value': keywords[i]});
}
}
},
'OnlineResource': function(node, obj) {
obj['href'] = this.getChildValue(node);
},
'Get': function(node, obj) {
obj['get'] = {'href': node.getAttribute('onlineResource')};
},
'Post': function(node, obj) {
obj['post'] = {'href': node.getAttribute('onlineResource')};
},
'Map': function(node, obj) {
var reader = this.readers[this.defaultNamespaceURI]['GetMap'];
reader.apply(this, arguments);
},
'Capabilities': function(node, obj) {
var reader = this.readers[this.defaultNamespaceURI]['GetCapabilities'];
reader.apply(this, arguments);
},
'FeatureInfo': function(node, obj) {
var reader = this.readers[this.defaultNamespaceURI]['GetFeatureInfo'];
reader.apply(this, arguments);
}
});
};
goog.inherits(ol.parser.ogc.WMSCapabilities_v1_0_0,
ol.parser.ogc.WMSCapabilities_v1_1_0);
@@ -0,0 +1,99 @@
goog.provide('ol.parser.ogc.WMSCapabilities_v1_1');
goog.require('ol.parser.ogc.WMSCapabilities_v1');
/**
* @constructor
* @extends {ol.parser.ogc.WMSCapabilities_v1}
*/
ol.parser.ogc.WMSCapabilities_v1_1 = function() {
goog.base(this);
var bboxreader = this.readers['http://www.opengis.net/wms']['BoundingBox'];
goog.object.extend(this.readers['http://www.opengis.net/wms'], {
'WMT_MS_Capabilities': function(node, obj) {
this.readChildNodes(node, obj);
},
'Keyword': function(node, obj) {
if (obj['keywords']) {
obj['keywords'].push({'value': this.getChildValue(node)});
}
},
'DescribeLayer': function(node, obj) {
obj['describelayer'] = {'formats': []};
this.readChildNodes(node, obj['describelayer']);
},
'GetLegendGraphic': function(node, obj) {
obj['getlegendgraphic'] = {'formats': []};
this.readChildNodes(node, obj['getlegendgraphic']);
},
'GetStyles': function(node, obj) {
obj['getstyles'] = {'formats': []};
this.readChildNodes(node, obj['getstyles']);
},
'PutStyles': function(node, obj) {
obj['putstyles'] = {'formats': []};
this.readChildNodes(node, obj['putstyles']);
},
'UserDefinedSymbolization': function(node, obj) {
var userSymbols = {
'supportSLD': parseInt(node.getAttribute('SupportSLD'), 10) == 1,
'userLayer': parseInt(node.getAttribute('UserLayer'), 10) == 1,
'userStyle': parseInt(node.getAttribute('UserStyle'), 10) == 1,
'remoteWFS': parseInt(node.getAttribute('RemoteWFS'), 10) == 1
};
obj['userSymbols'] = userSymbols;
},
'LatLonBoundingBox': function(node, obj) {
obj['llbbox'] = [
parseFloat(node.getAttribute('minx')),
parseFloat(node.getAttribute('miny')),
parseFloat(node.getAttribute('maxx')),
parseFloat(node.getAttribute('maxy'))
];
},
'BoundingBox': function(node, obj) {
var bbox = bboxreader.apply(this, arguments);
bbox['srs'] = node.getAttribute('SRS');
obj['bbox'][bbox['srs']] = bbox;
},
'ScaleHint': function(node, obj) {
var min = parseFloat(node.getAttribute('min'));
var max = parseFloat(node.getAttribute('max'));
var rad2 = Math.pow(2, 0.5);
var dpi = (25.4 / 0.28);
var ipm = 39.37;
if (min !== 0) {
obj['maxScale'] = parseFloat((min / rad2) * ipm * dpi);
}
if (max != Number.POSITIVE_INFINITY) {
obj['minScale'] = parseFloat((max / rad2) * ipm * dpi);
}
},
'Dimension': function(node, obj) {
var name = node.getAttribute('name').toLowerCase();
var dim = {
'name': name,
'units': node.getAttribute('units'),
'unitsymbol': node.getAttribute('unitSymbol')
};
obj['dimensions'][dim.name] = dim;
},
'Extent': function(node, obj) {
var name = node.getAttribute('name').toLowerCase();
if (name in obj['dimensions']) {
var extent = obj['dimensions'][name];
extent['nearestVal'] =
node.getAttribute('nearestValue') === '1';
extent['multipleVal'] =
node.getAttribute('multipleValues') === '1';
extent['current'] = node.getAttribute('current') === '1';
extent['default'] = node.getAttribute('default') || '';
var values = this.getChildValue(node);
extent['values'] = values.split(',');
}
}
});
};
goog.inherits(ol.parser.ogc.WMSCapabilities_v1_1,
ol.parser.ogc.WMSCapabilities_v1);
@@ -0,0 +1,25 @@
goog.provide('ol.parser.ogc.WMSCapabilities_v1_1_0');
goog.require('ol.parser.ogc.WMSCapabilities_v1_1');
/**
* @constructor
* @extends {ol.parser.ogc.WMSCapabilities_v1_1}
*/
ol.parser.ogc.WMSCapabilities_v1_1_0 = function() {
goog.base(this);
this.version = '1.1.0';
goog.object.extend(this.readers['http://www.opengis.net/wms'], {
'SRS': function(node, obj) {
var srs = this.getChildValue(node);
var values = srs.split(/ +/);
for (var i = 0, len = values.length; i < len; i++) {
obj['srs'][values[i]] = true;
}
}
});
};
goog.inherits(ol.parser.ogc.WMSCapabilities_v1_1_0,
ol.parser.ogc.WMSCapabilities_v1_1);
@@ -0,0 +1,21 @@
goog.provide('ol.parser.ogc.WMSCapabilities_v1_1_1');
goog.require('ol.parser.ogc.WMSCapabilities_v1_1');
/**
* @constructor
* @extends {ol.parser.ogc.WMSCapabilities_v1_1}
*/
ol.parser.ogc.WMSCapabilities_v1_1_1 = function() {
goog.base(this);
this.version = '1.1.1';
goog.object.extend(this.readers['http://www.opengis.net/wms'], {
'SRS': function(node, obj) {
obj['srs'][this.getChildValue(node)] = true;
}
});
};
goog.inherits(ol.parser.ogc.WMSCapabilities_v1_1_1,
ol.parser.ogc.WMSCapabilities_v1_1);
@@ -0,0 +1,46 @@
goog.provide('ol.parser.ogc.WMSCapabilities_v1_1_1_WMSC');
goog.require('ol.parser.ogc.WMSCapabilities_v1_1_1');
/**
* @constructor
* @extends {ol.parser.ogc.WMSCapabilities_v1_1_1}
*/
ol.parser.ogc.WMSCapabilities_v1_1_1_WMSC = function() {
goog.base(this);
this.profile = 'WMSC';
goog.object.extend(this.readers['http://www.opengis.net/wms'], {
'VendorSpecificCapabilities': function(node, obj) {
obj['vendorSpecific'] = {'tileSets': []};
this.readChildNodes(node, obj['vendorSpecific']);
},
'TileSet': function(node, vendorSpecific) {
var tileset = {'srs': {}, 'bbox': {}, 'resolutions': []};
this.readChildNodes(node, tileset);
vendorSpecific.tileSets.push(tileset);
},
'Resolutions': function(node, tileset) {
var res = this.getChildValue(node).split(' ');
for (var i = 0, len = res.length; i < len; i++) {
if (res[i] !== '') {
tileset['resolutions'].push(parseFloat(res[i]));
}
}
},
'Width': function(node, tileset) {
tileset['width'] = parseInt(this.getChildValue(node), 10);
},
'Height': function(node, tileset) {
tileset['height'] = parseInt(this.getChildValue(node), 10);
},
'Layers': function(node, tileset) {
tileset['layers'] = this.getChildValue(node);
},
'Styles': function(node, tileset) {
tileset['styles'] = this.getChildValue(node);
}
});
};
goog.inherits(ol.parser.ogc.WMSCapabilities_v1_1_1_WMSC,
ol.parser.ogc.WMSCapabilities_v1_1_1);
@@ -0,0 +1,109 @@
goog.provide('ol.parser.ogc.WMSCapabilities_v1_3_0');
goog.require('ol.parser.ogc.WMSCapabilities_v1');
/**
* @constructor
* @extends {ol.parser.ogc.WMSCapabilities_v1}
*/
ol.parser.ogc.WMSCapabilities_v1_3_0 = function() {
goog.base(this);
var bboxreader = this.readers['http://www.opengis.net/wms']['BoundingBox'];
goog.object.extend(this.readers['http://www.opengis.net/wms'], {
'WMS_Capabilities': function(node, obj) {
this.readChildNodes(node, obj);
},
'LayerLimit': function(node, obj) {
obj['layerLimit'] = parseInt(this.getChildValue(node), 10);
},
'MaxWidth': function(node, obj) {
obj['maxWidth'] = parseInt(this.getChildValue(node), 10);
},
'MaxHeight': function(node, obj) {
obj['maxHeight'] = parseInt(this.getChildValue(node), 10);
},
'BoundingBox': function(node, obj) {
var bbox = bboxreader.apply(this, arguments);
bbox['srs'] = node.getAttribute('CRS');
obj['bbox'][bbox['srs']] = bbox;
},
'CRS': function(node, obj) {
// CRS is the synonym of SRS
this.readers['http://www.opengis.net/wms']['SRS'].apply(this, arguments);
},
'EX_GeographicBoundingBox': function(node, obj) {
// replacement of LatLonBoundingBox
obj['llbbox'] = [];
this.readChildNodes(node, obj['llbbox']);
},
'westBoundLongitude': function(node, obj) {
obj[0] = this.getChildValue(node);
},
'eastBoundLongitude': function(node, obj) {
obj[2] = this.getChildValue(node);
},
'southBoundLatitude': function(node, obj) {
obj[1] = this.getChildValue(node);
},
'northBoundLatitude': function(node, obj) {
obj[3] = this.getChildValue(node);
},
'MinScaleDenominator': function(node, obj) {
obj['maxScale'] = parseFloat(this.getChildValue(node)).toPrecision(16);
},
'MaxScaleDenominator': function(node, obj) {
obj['minScale'] = parseFloat(this.getChildValue(node)).toPrecision(16);
},
'Dimension': function(node, obj) {
// dimension has extra attributes: default, multipleValues,
// nearestValue, current which used to be part of Extent. It now
// also contains the values.
var name = node.getAttribute('name').toLowerCase();
var dim = {
'name': name,
'units': node.getAttribute('units'),
'unitsymbol': node.getAttribute('unitSymbol'),
'nearestVal': node.getAttribute('nearestValue') === '1',
'multipleVal': node.getAttribute('multipleValues') === '1',
'default': node.getAttribute('default') || '',
'current': node.getAttribute('current') === '1',
'values': this.getChildValue(node).split(',')
};
// Theoretically there can be more dimensions with the same
// name, but with a different unit. Until we meet such a case,
// let's just keep the same structure as the WMS 1.1
// GetCapabilities parser uses. We will store the last
// one encountered.
obj['dimensions'][dim['name']] = dim;
},
'Keyword': function(node, obj) {
var keyword = {'value': this.getChildValue(node),
'vocabulary': node.getAttribute('vocabulary')};
if (obj['keywords']) {
obj['keywords'].push(keyword);
}
}
});
this.readers['sld'] = {
'UserDefinedSymbolization': function(node, obj) {
var readers = this.readers['http://www.opengis.net/wms'];
readers.UserDefinedSymbolization.apply(this, arguments);
// add the two extra attributes
var value = node.getAttribute('InlineFeature');
obj['userSymbols']['inlineFeature'] = parseInt(value, 10) == 1;
value = node.getAttribute('RemoteWCS');
obj['userSymbols']['remoteWCS'] = parseInt(value, 10) == 1;
},
'DescribeLayer': function(node, obj) {
var readers = this.readers['http://www.opengis.net/wms'];
readers.DescribeLayer.apply(this, arguments);
},
'GetLegendGraphic': function(node, obj) {
var readers = this.readers['http://www.opengis.net/wms'];
readers.GetLegendGraphic.apply(this, arguments);
}
};
};
goog.inherits(ol.parser.ogc.WMSCapabilities_v1_3_0,
ol.parser.ogc.WMSCapabilities_v1);
@@ -0,0 +1,2 @@
@exportSymbol ol.parser.ogc.WMTSCapabilities
@exportProperty ol.parser.ogc.WMTSCapabilities.prototype.read
@@ -0,0 +1,19 @@
goog.provide('ol.parser.ogc.WMTSCapabilities');
goog.require('ol.parser.ogc.Versioned');
goog.require('ol.parser.ogc.WMTSCapabilities_v1_0_0');
/**
* @constructor
* @param {Object=} opt_options Options which will be set on this object.
* @extends {ol.parser.ogc.Versioned}
*/
ol.parser.ogc.WMTSCapabilities = function(opt_options) {
opt_options = opt_options || {};
opt_options['defaultVersion'] = '1.0.0';
this.parsers = {};
this.parsers['v1_0_0'] = ol.parser.ogc.WMTSCapabilities_v1_0_0;
goog.base(this, opt_options);
};
goog.inherits(ol.parser.ogc.WMTSCapabilities, ol.parser.ogc.Versioned);
@@ -0,0 +1,166 @@
goog.provide('ol.parser.ogc.WMTSCapabilities_v1_0_0');
goog.require('goog.dom.xml');
goog.require('ol.Coordinate');
goog.require('ol.parser.XML');
goog.require('ol.parser.ogc.OWSCommon_v1_1_0');
goog.require('ol.projection');
/**
* @constructor
* @extends {ol.parser.XML}
*/
ol.parser.ogc.WMTSCapabilities_v1_0_0 = function() {
this.defaultNamespaceURI = 'http://www.opengis.net/wtms/1.0';
this.errorProperty = 'serviceIdentification';
this.readers = {
'http://www.opengis.net/wmts/1.0': {
'Capabilities': function(node, obj) {
this.readChildNodes(node, obj);
},
'Contents': function(node, obj) {
obj['contents'] = {};
obj['contents']['layers'] = [];
obj['contents']['tileMatrixSets'] = {};
this.readChildNodes(node, obj['contents']);
},
'Layer': function(node, obj) {
var layer = {
'styles': [],
'formats': [],
'dimensions': [],
'tileMatrixSetLinks': []
};
layer['layers'] = [];
this.readChildNodes(node, layer);
obj['layers'].push(layer);
},
'Style': function(node, obj) {
var style = {};
style['isDefault'] = (node.getAttribute('isDefault') === 'true');
this.readChildNodes(node, style);
obj['styles'].push(style);
},
'Format': function(node, obj) {
obj['formats'].push(this.getChildValue(node));
},
'TileMatrixSetLink': function(node, obj) {
var tileMatrixSetLink = {};
this.readChildNodes(node, tileMatrixSetLink);
obj['tileMatrixSetLinks'].push(tileMatrixSetLink);
},
'TileMatrixSet': function(node, obj) {
// node could be child of wmts:Contents or wmts:TileMatrixSetLink
// duck type wmts:Contents by looking for layers
if (obj['layers']) {
// TileMatrixSet as object type in schema
var tileMatrixSet = {
'matrixIds': []
};
this.readChildNodes(node, tileMatrixSet);
obj['tileMatrixSets'][tileMatrixSet['identifier']] = tileMatrixSet;
} else {
// TileMatrixSet as string type in schema
obj['tileMatrixSet'] = this.getChildValue(node);
}
},
'TileMatrix': function(node, obj) {
var tileMatrix = {
'supportedCRS': obj.supportedCRS
};
this.readChildNodes(node, tileMatrix);
obj['matrixIds'].push(tileMatrix);
},
'ScaleDenominator': function(node, obj) {
obj['scaleDenominator'] = parseFloat(this.getChildValue(node));
},
'TopLeftCorner': function(node, obj) {
var topLeftCorner = this.getChildValue(node);
var coords = topLeftCorner.split(' ');
var axisOrientation =
ol.projection.get(obj['supportedCRS']).getAxisOrientation();
obj['topLeftCorner'] = ol.Coordinate.fromProjectedArray(
[parseFloat(coords[0]), parseFloat(coords[1])], axisOrientation);
},
'TileWidth': function(node, obj) {
obj['tileWidth'] = parseInt(this.getChildValue(node), 10);
},
'TileHeight': function(node, obj) {
obj['tileHeight'] = parseInt(this.getChildValue(node), 10);
},
'MatrixWidth': function(node, obj) {
obj['matrixWidth'] = parseInt(this.getChildValue(node), 10);
},
'MatrixHeight': function(node, obj) {
obj['matrixHeight'] = parseInt(this.getChildValue(node), 10);
},
'ResourceURL': function(node, obj) {
var resourceType = node.getAttribute('resourceType');
var format = node.getAttribute('format');
var template = node.getAttribute('template');
if (!obj['resourceUrls']) {
obj['resourceUrls'] = {};
}
if (!obj['resourceUrls'][resourceType]) {
obj['resourceUrls'][resourceType] = {};
}
if (!obj['resourceUrls'][resourceType][format]) {
obj['resourceUrls'][resourceType][format] = [];
}
obj['resourceUrls'][resourceType][format].push(template);
},
'WSDL': function(node, obj) {
obj['wsdl'] = {};
obj['wsdl']['href'] = this.getAttributeNS(node,
'http://www.w3.org/1999/xlink', 'href');
// TODO: other attributes of <WSDL> element
},
'ServiceMetadataURL': function(node, obj) {
obj['serviceMetadataUrl'] = {};
obj['serviceMetadataUrl']['href'] =
this.getAttributeNS(node, 'http://www.w3.org/1999/xlink', 'href');
// TODO: other attributes of <ServiceMetadataURL> element
},
'LegendURL': function(node, obj) {
obj['legend'] = {};
obj['legend']['href'] = this.getAttributeNS(node,
'http://www.w3.org/1999/xlink', 'href');
obj['legend']['format'] = node.getAttribute('format');
},
'Dimension': function(node, obj) {
var dimension = {'values': []};
this.readChildNodes(node, dimension);
obj['dimensions'].push(dimension);
},
'Default': function(node, obj) {
obj['default'] = this.getChildValue(node);
},
'Value': function(node, obj) {
obj['values'].push(this.getChildValue(node));
}
}
};
var ows = new ol.parser.ogc.OWSCommon_v1_1_0();
this.readers['http://www.opengis.net/ows/1.1'] =
ows.readers['http://www.opengis.net/ows/1.1'];
goog.base(this);
};
goog.inherits(ol.parser.ogc.WMTSCapabilities_v1_0_0, ol.parser.XML);
/**
* @param {string|Document|Element} data Data to read.
* @return {Object} An object representing the document.
*/
ol.parser.ogc.WMTSCapabilities_v1_0_0.prototype.read = function(data) {
if (typeof data == 'string') {
data = goog.dom.xml.loadXml(data);
}
if (data && data.nodeType == 9) {
data = data.documentElement;
}
var obj = {};
this.readNode(data, obj);
return obj;
};
+147
View File
@@ -0,0 +1,147 @@
goog.provide('ol.parser.XML');
/**
* @constructor
*/
ol.parser.XML = function() {
this.regExes = {
trimSpace: (/^\s*|\s*$/g),
removeSpace: (/\s*/g),
splitSpace: (/\s+/),
trimComma: (/\s*,\s*/g)
};
};
/**
* Shorthand for applying one of the named readers given the node
* namespace and local name. Readers take two args (node, obj) and
* generally extend or modify the second.
*
* @param {Element|Document} node The node to be read (required).
* @param {Object} obj The object to be modified (optional).
* @return {Object} The input object, modified (or a new one if none was
* provided).
*/
ol.parser.XML.prototype.readNode = function(node, obj) {
if (!obj) {
obj = {};
}
var group = this.readers[node.namespaceURI] ||
this.readers[this.defaultNamespaceURI];
if (group) {
var local = node.localName || node.nodeName.split(':').pop();
var reader = group[local] || group['*'];
if (reader) {
reader.apply(this, [node, obj]);
}
}
return obj;
};
/**
* Shorthand for applying the named readers to all children of a node.
* For each child of type 1 (element), <readSelf> is called.
*
* @param {Element|Document} node The node to be read (required).
* @param {Object} obj The object to be modified (optional).
* @return {Object} The input object, modified.
*/
ol.parser.XML.prototype.readChildNodes = function(node, obj) {
if (!obj) {
obj = {};
}
var children = node.childNodes;
var child;
for (var i = 0, len = children.length; i < len; ++i) {
child = children[i];
if (child.nodeType == 1) {
this.readNode(child, obj);
}
}
return obj;
};
/**
* Get the textual value of the node if it exists, or return an
* optional default string. Returns an empty string if no first child
* exists and no default value is supplied.
*
* @param {Element} node The element used to look for a first child value.
* @param {string} def Optional string to return in the event that no
* first child value exists.
* @return {string} The value of the first child of the given node.
*/
ol.parser.XML.prototype.getChildValue = function(node, def) {
var value = def || '';
if (node) {
for (var child = node.firstChild; child; child = child.nextSibling) {
switch (child.nodeType) {
case 3: // text node
case 4: // cdata section
value += child.nodeValue;
break;
default:
break;
}
}
}
return value;
};
/**
* Get an attribute node given the namespace URI and local name.
*
* @param {Element} node Node on which to search for attribute nodes.
* @param {string} uri Namespace URI.
* @param {string} name Local name of the attribute (without the prefix).
* @return {?Element} An attribute node or null if none found.
*/
ol.parser.XML.prototype.getAttributeNodeNS = function(node, uri, name) {
var attributeNode = null;
if (node.getAttributeNodeNS) {
attributeNode = node.getAttributeNodeNS(uri, name);
} else {
var attributes = node.attributes;
var potentialNode, fullName;
for (var i = 0, len = attributes.length; i < len; ++i) {
potentialNode = attributes[i];
if (potentialNode.namespaceURI == uri) {
fullName = (potentialNode.prefix) ?
(potentialNode.prefix + ':' + name) : name;
if (fullName == potentialNode.nodeName) {
attributeNode = potentialNode;
break;
}
}
}
}
return attributeNode;
};
/**
* Get an attribute value given the namespace URI and local name.
*
* @param {Element} node Node on which to search for an attribute.
* @param {string} uri Namespace URI.
* @param {string} name Local name of the attribute (without the prefix).
* @return {string} An attribute value or and empty string if none found.
*/
ol.parser.XML.prototype.getAttributeNS = function(node, uri, name) {
var attributeValue = '';
if (node.getAttributeNS) {
attributeValue = node.getAttributeNS(uri, name) || '';
} else {
var attributeNode = this.getAttributeNodeNS(node, uri, name);
if (attributeNode) {
attributeValue = attributeNode.nodeValue;
}
}
return attributeValue;
};
+16
View File
@@ -0,0 +1,16 @@
goog.provide('ol.Pixel');
goog.require('goog.math.Coordinate');
/**
* @constructor
* @extends {goog.math.Coordinate}
* @param {number} x X.
* @param {number} y Y.
*/
ol.Pixel = function(x, y) {
goog.base(this, x, y);
};
goog.inherits(ol.Pixel, goog.math.Coordinate);
+18
View File
@@ -0,0 +1,18 @@
goog.provide('ol.PixelBounds');
goog.require('ol.Rectangle');
/**
* @constructor
* @extends {ol.Rectangle}
* @param {number} minX Minimum X.
* @param {number} minY Minimum Y.
* @param {number} maxX Maximum X.
* @param {number} maxY Maximum Y.
*/
ol.PixelBounds = function(minX, minY, maxX, maxY) {
goog.base(this, minX, minY, maxX, maxY);
};
goog.inherits(ol.PixelBounds, ol.Rectangle);
+21
View File
@@ -0,0 +1,21 @@
@exportClass ol.Projection ol.ProjectionOptions
@exportProperty ol.Projection.prototype.getAxisOrientation
@exportProperty ol.Projection.prototype.getCode
@exportProperty ol.Projection.prototype.getExtent
@exportProperty ol.Projection.prototype.getPointResolution
@exportProperty ol.Projection.prototype.getUnits
@exportProperty ol.Projection.prototype.getMetersPerUnit
@exportProperty ol.Projection.prototype.isGlobal
@exportSymbol ol.ProjectionUnits
@exportProperty ol.ProjectionUnits.DEGREES
@exportProperty ol.ProjectionUnits.FEET
@exportProperty ol.ProjectionUnits.METERS
@exportSymbol ol.projection.addProjection
@exportSymbol ol.projection.get
@exportSymbol ol.projection.getTransform
@exportSymbol ol.projection.getTransformFromProjections
@exportSymbol ol.projection.transform
@exportSymbol ol.projection.transformWithProjections
@exportSymbol ol.projection.configureProj4jsProjection
+688
View File
@@ -0,0 +1,688 @@
goog.provide('ol.Projection');
goog.provide('ol.ProjectionLike');
goog.provide('ol.ProjectionUnits');
goog.provide('ol.projection');
goog.require('goog.array');
goog.require('goog.asserts');
goog.require('goog.object');
goog.require('ol.Coordinate');
goog.require('ol.Extent');
goog.require('ol.TransformFunction');
goog.require('ol.sphere.NORMAL');
/**
* @define {boolean} Enable Proj4js.
*/
ol.ENABLE_PROJ4JS = true;
/**
* @const {boolean} Have Proj4js.
*/
ol.HAVE_PROJ4JS = ol.ENABLE_PROJ4JS && typeof Proj4js == 'object';
/**
* @typedef {ol.Projection|string|undefined}
*/
ol.ProjectionLike;
/**
* @enum {string}
*/
ol.ProjectionUnits = {
DEGREES: 'degrees',
FEET: 'ft',
METERS: 'm'
};
/**
* @const {Object.<ol.ProjectionUnits, number>} Meters per unit lookup table.
*/
ol.METERS_PER_UNIT = {};
ol.METERS_PER_UNIT[ol.ProjectionUnits.DEGREES] =
2 * Math.PI * ol.sphere.NORMAL.radius / 360;
ol.METERS_PER_UNIT[ol.ProjectionUnits.FEET] = 0.3048;
ol.METERS_PER_UNIT[ol.ProjectionUnits.METERS] = 1;
/**
* @constructor
* @param {ol.ProjectionOptions} options Options object.
*/
ol.Projection = function(options) {
/**
* @private
* @type {string}
*/
this.code_ = options.code;
/**
* @private
* @type {ol.ProjectionUnits}
*/
this.units_ = options.units;
/**
* @private
* @type {ol.Extent}
*/
this.extent_ = options.extent;
/**
* @private
* @type {string}
*/
this.axisOrientation_ = goog.isDef(options.axisOrientation) ?
options.axisOrientation : 'enu';
/**
* @private
* @type {boolean}
*/
this.global_ = goog.isDef(options.global) ?
options.global : false;
/**
* @private
* @type {ol.tilegrid.TileGrid}
*/
this.defaultTileGrid_ = null;
};
/**
* @return {string} Code.
*/
ol.Projection.prototype.getCode = function() {
return this.code_;
};
/**
* @return {ol.Extent} Extent.
*/
ol.Projection.prototype.getExtent = function() {
return this.extent_;
};
/**
* @param {number} resolution Resolution.
* @param {ol.Coordinate} point Point.
* @return {number} Point resolution.
*/
ol.Projection.prototype.getPointResolution = goog.abstractMethod;
/**
* @return {ol.ProjectionUnits} Units.
*/
ol.Projection.prototype.getUnits = function() {
return this.units_;
};
/**
* @return {number} Meters.
*/
ol.Projection.prototype.getMetersPerUnit = function() {
return ol.METERS_PER_UNIT[this.units_];
};
/**
* @return {string} Axis orientation.
*/
ol.Projection.prototype.getAxisOrientation = function() {
return this.axisOrientation_;
};
/**
* @return {boolean} Wether the projection is global.
*/
ol.Projection.prototype.isGlobal = function() {
return this.global_;
};
/**
* @return {ol.tilegrid.TileGrid} The default tile grid.
*/
ol.Projection.prototype.getDefaultTileGrid = function() {
return this.defaultTileGrid_;
};
/**
* @param {ol.tilegrid.TileGrid} tileGrid The default tile grid.
*/
ol.Projection.prototype.setDefaultTileGrid = function(tileGrid) {
this.defaultTileGrid_ = tileGrid;
};
/**
* @constructor
* @extends {ol.Projection}
* @param {Proj4js.Proj} proj4jsProj Proj4js projection.
* @param {ol.Proj4jsProjectionOptions} options Projection config options.
* @private
*/
ol.Proj4jsProjection_ = function(proj4jsProj, options) {
var units = /** @type {ol.ProjectionUnits} */ (proj4jsProj.units);
var config = /** @type {ol.ProjectionOptions} */ ({
units: units,
axisOrientation: proj4jsProj.axis
});
goog.object.extend(config, options);
goog.base(this, config);
/**
* @private
* @type {Proj4js.Proj}
*/
this.proj4jsProj_ = proj4jsProj;
/**
* @private
* @type {?ol.TransformFunction}
*/
this.toEPSG4326_ = null;
};
goog.inherits(ol.Proj4jsProjection_, ol.Projection);
/**
* @inheritDoc
*/
ol.Proj4jsProjection_.prototype.getPointResolution =
function(resolution, point) {
if (this.getUnits() == ol.ProjectionUnits.DEGREES) {
return resolution;
} else {
// Estimate point resolution by transforming the center pixel to EPSG:4326,
// measuring its width and height on the normal sphere, and taking the
// average of the width and height.
if (goog.isNull(this.toEPSG4326_)) {
this.toEPSG4326_ = ol.projection.getTransformFromProjections(
this, ol.projection.getProj4jsProjectionFromCode_({
code: 'EPSG:4326',
extent: null
}));
}
var vertices = [
point.x - resolution / 2, point.y,
point.x + resolution / 2, point.y,
point.x, point.y - resolution / 2,
point.x, point.y + resolution / 2
];
vertices = this.toEPSG4326_(vertices, vertices, 2);
var width = ol.sphere.NORMAL.haversineDistance(
new ol.Coordinate(vertices[0], vertices[1]),
new ol.Coordinate(vertices[2], vertices[3]));
var height = ol.sphere.NORMAL.haversineDistance(
new ol.Coordinate(vertices[4], vertices[5]),
new ol.Coordinate(vertices[6], vertices[7]));
var pointResolution = (width + height) / 2;
if (this.getUnits() == ol.ProjectionUnits.FEET) {
// The radius of the normal sphere is defined in meters, so we must
// convert back to feet.
pointResolution /= 0.3048;
}
return pointResolution;
}
};
/**
* @return {Proj4js.Proj} Proj4js projection.
*/
ol.Proj4jsProjection_.prototype.getProj4jsProj = function() {
return this.proj4jsProj_;
};
/**
* @private
* @type {Object.<string, ol.Proj4jsProjection_>}
*/
ol.projection.proj4jsProjections_ = {};
/**
* @private
* @type {Object.<string, ol.Projection>}
*/
ol.projection.projections_ = {};
/**
* @private
* @type {Object.<string, Object.<string, ol.TransformFunction>>}
*/
ol.projection.transforms_ = {};
/**
* Registers transformation functions that don't alter coordinates. Those allow
* to transform between projections with equal meaning.
*
* @param {Array.<ol.Projection>} projections Projections.
*/
ol.projection.addEquivalentProjections = function(projections) {
ol.projection.addProjections(projections);
goog.array.forEach(projections, function(source) {
goog.array.forEach(projections, function(destination) {
if (source !== destination) {
ol.projection.addTransform(
source, destination, ol.projection.cloneTransform);
}
});
});
};
/**
* Registers transformation functions to convert coordinates in any projection
* in projection1 to any projection in projection2.
*
* @param {Array.<ol.Projection>} projections1 Projections with equal meaning.
* @param {Array.<ol.Projection>} projections2 Projections with equal meaning.
* @param {ol.TransformFunction} forwardTransform Transformation from any
* projection in projection1 to any projection in projection2.
* @param {ol.TransformFunction} inverseTransform Transform from any projection
* in projection2 to any projection in projection1..
*/
ol.projection.addEquivalentTransforms =
function(projections1, projections2, forwardTransform, inverseTransform) {
goog.array.forEach(projections1, function(projection1) {
goog.array.forEach(projections2, function(projection2) {
ol.projection.addTransform(projection1, projection2, forwardTransform);
ol.projection.addTransform(projection2, projection1, inverseTransform);
});
});
};
/**
* @param {ol.Proj4jsProjection_} proj4jsProjection Proj4js projection.
* @private
*/
ol.projection.addProj4jsProjection_ = function(proj4jsProjection) {
var proj4jsProjections = ol.projection.proj4jsProjections_;
var code = proj4jsProjection.getCode();
goog.asserts.assert(!goog.object.containsKey(proj4jsProjections, code));
proj4jsProjections[code] = proj4jsProjection;
};
/**
* @param {ol.Projection} projection Projection.
*/
ol.projection.addProjection = function(projection) {
var projections = ol.projection.projections_;
var code = projection.getCode();
goog.asserts.assert(!goog.object.containsKey(projections, code));
projections[code] = projection;
ol.projection.addTransform(
projection, projection, ol.projection.cloneTransform);
};
/**
* @param {Array.<ol.Projection>} projections Projections.
*/
ol.projection.addProjections = function(projections) {
goog.array.forEach(projections, function(projection) {
ol.projection.addProjection(projection);
});
};
/**
* FIXME empty description for jsdoc
*/
ol.projection.clearAllProjections = function() {
if (ol.ENABLE_PROJ4JS) {
ol.projection.proj4jsProjections_ = {};
}
ol.projection.projections_ = {};
ol.projection.transforms_ = {};
};
/**
* @param {ol.Projection|string|undefined} projection Projection.
* @param {string} defaultCode Default code.
* @return {ol.Projection} Projection.
*/
ol.projection.createProjection = function(projection, defaultCode) {
if (!goog.isDefAndNotNull(projection)) {
return ol.projection.get(defaultCode);
} else if (goog.isString(projection)) {
return ol.projection.get(projection);
} else {
goog.asserts.assert(projection instanceof ol.Projection);
return projection;
}
};
/**
* Registers a conversion function to convert coordinates from the source
* projection to the destination projection.
*
* @param {ol.Projection} source Source.
* @param {ol.Projection} destination Destination.
* @param {ol.TransformFunction} transformFn Transform.
*/
ol.projection.addTransform = function(source, destination, transformFn) {
var sourceCode = source.getCode();
var destinationCode = destination.getCode();
var transforms = ol.projection.transforms_;
if (!goog.object.containsKey(transforms, sourceCode)) {
transforms[sourceCode] = {};
}
goog.asserts.assert(
!goog.object.containsKey(transforms[sourceCode], destinationCode));
transforms[sourceCode][destinationCode] = transformFn;
};
/**
* Unregisters the conversion function to convert coordinates from the source
* projection to the destination projection. This method is used to clean up
* cached transforms during testing.
*
* @param {ol.Projection} source Source projection.
* @param {ol.Projection} destination Destination projection.
* @return {ol.TransformFunction} transformFn The unregistered transform.
*/
ol.projection.removeTransform = function(source, destination) {
var sourceCode = source.getCode();
var destinationCode = destination.getCode();
var transforms = ol.projection.transforms_;
goog.asserts.assert(sourceCode in transforms);
goog.asserts.assert(destinationCode in transforms[sourceCode]);
var transform = transforms[sourceCode][destinationCode];
delete transforms[sourceCode][destinationCode];
var keys = goog.object.getKeys(transforms[sourceCode]);
if (keys.length == 0) {
delete transforms[sourceCode];
}
return transform;
};
/**
* @param {ol.ProjectionLike} projectionLike Either a code string which is a
* combination of authority and identifier such as "EPSG:4326", or an
* existing projection object, or undefined.
* @return {ol.Projection} Projection.
*/
ol.projection.get = function(projectionLike) {
var projection;
if (projectionLike instanceof ol.Projection) {
projection = projectionLike;
} else if (goog.isString(projectionLike)) {
var code = projectionLike;
projection = ol.projection.projections_[code];
if (ol.HAVE_PROJ4JS && !goog.isDef(projection)) {
projection = ol.projection.getProj4jsProjectionFromCode_({
code: code,
extent: null
});
}
if (!goog.isDef(projection)) {
goog.asserts.assert(goog.isDef(projection));
projection = null;
}
} else {
projection = null;
}
return projection;
};
/**
* @param {ol.Proj4jsProjectionOptions} options Projection config options.
* @private
* @return {ol.Proj4jsProjection_} Proj4js projection.
*/
ol.projection.getProj4jsProjectionFromCode_ = function(options) {
var code = options.code;
var proj4jsProjections = ol.projection.proj4jsProjections_;
var proj4jsProjection = proj4jsProjections[code];
if (!goog.isDef(proj4jsProjection)) {
var proj4jsProj = new Proj4js.Proj(code);
var srsCode = proj4jsProj.srsCode;
proj4jsProjection = proj4jsProjections[srsCode];
if (!goog.isDef(proj4jsProjection)) {
var config = /** @type {ol.Proj4jsProjectionOptions} */
(goog.object.clone(options));
config.code = srsCode;
proj4jsProjection = new ol.Proj4jsProjection_(proj4jsProj, config);
proj4jsProjections[srsCode] = proj4jsProjection;
}
proj4jsProjections[code] = proj4jsProjection;
}
return proj4jsProjection;
};
/**
* Checks if two projections are the same, that is every coordinate in one
* projection does represent the same geographic point as the same coordinate in
* the other projection.
*
* @param {ol.Projection} projection1 Projection 1.
* @param {ol.Projection} projection2 Projection 2.
* @return {boolean} Equivalent.
*/
ol.projection.equivalent = function(projection1, projection2) {
if (projection1 === projection2) {
return true;
} else if (projection1.getUnits() != projection2.getUnits()) {
return false;
} else {
var transformFn = ol.projection.getTransformFromProjections(
projection1, projection2);
return transformFn === ol.projection.cloneTransform;
}
};
/**
* Given the projection-like objects this method searches for a transformation
* function to convert a coordinates array from the source projection to the
* destination projection.
*
* @param {ol.ProjectionLike} source Source.
* @param {ol.ProjectionLike} destination Destination.
* @return {ol.TransformFunction} Transform.
*/
ol.projection.getTransform = function(source, destination) {
var sourceProjection = ol.projection.get(source);
var destinationProjection = ol.projection.get(destination);
return ol.projection.getTransformFromProjections(
sourceProjection, destinationProjection);
};
/**
* Searches a function that can be used to convert coordinates from the source
* projection to the destination projection.
*
* @param {ol.Projection} sourceProjection Source projection.
* @param {ol.Projection} destinationProjection Destination projection.
* @return {ol.TransformFunction} Transform.
*/
ol.projection.getTransformFromProjections =
function(sourceProjection, destinationProjection) {
var transforms = ol.projection.transforms_;
var sourceCode = sourceProjection.getCode();
var destinationCode = destinationProjection.getCode();
var transform;
if (goog.object.containsKey(transforms, sourceCode) &&
goog.object.containsKey(transforms[sourceCode], destinationCode)) {
transform = transforms[sourceCode][destinationCode];
}
if (ol.HAVE_PROJ4JS && !goog.isDef(transform)) {
var proj4jsSource;
if (sourceProjection instanceof ol.Proj4jsProjection_) {
proj4jsSource = sourceProjection;
} else {
proj4jsSource =
ol.projection.getProj4jsProjectionFromCode_({
code: sourceCode,
extent: null
});
}
var sourceProj4jsProj = proj4jsSource.getProj4jsProj();
var proj4jsDestination;
if (destinationProjection instanceof ol.Proj4jsProjection_) {
proj4jsDestination = destinationProjection;
} else {
proj4jsDestination =
ol.projection.getProj4jsProjectionFromCode_({
code: destinationCode,
extent: null
});
}
var destinationProj4jsProj = proj4jsDestination.getProj4jsProj();
transform =
/**
* @param {Array.<number>} input Input coordinate values.
* @param {Array.<number>=} opt_output Output array of coordinates.
* @param {number=} opt_dimension Dimension.
* @return {Array.<number>} Output coordinate values.
*/
function(input, opt_output, opt_dimension) {
var length = input.length,
dimension = opt_dimension > 1 ? opt_dimension : 2,
output = opt_output;
if (!goog.isDef(output)) {
if (dimension > 2) {
// preserve values beyond second dimension
output = input.slice();
} else {
output = new Array(length);
}
}
goog.asserts.assert(output.length % dimension === 0);
var proj4jsPoint;
for (var i = 0; i < length; i += dimension) {
proj4jsPoint = new Proj4js.Point(input[i], input[i + 1]);
proj4jsPoint = Proj4js.transform(
sourceProj4jsProj, destinationProj4jsProj, proj4jsPoint);
output[i] = proj4jsPoint.x;
output[i + 1] = proj4jsPoint.y;
}
return output;
};
ol.projection.addTransform(
sourceProjection, destinationProjection, transform);
}
if (!goog.isDef(transform)) {
goog.asserts.assert(goog.isDef(transform));
transform = ol.projection.identityTransform;
}
return transform;
};
/**
* @param {Array.<number>} input Input coordinate array.
* @param {Array.<number>=} opt_output Output array of coordinate values.
* @param {number=} opt_dimension Dimension.
* @return {Array.<number>} Input coordinate array (same array as input).
*/
ol.projection.identityTransform = function(input, opt_output, opt_dimension) {
if (goog.isDef(opt_output) && input !== opt_output) {
// TODO: consider making this a warning instead
goog.asserts.assert(false, 'This should not be used internally.');
for (var i = 0, ii = input.length; i < ii; ++i) {
opt_output[i] = input[i];
}
input = opt_output;
}
return input;
};
/**
* @param {Array.<number>} input Input coordinate array.
* @param {Array.<number>=} opt_output Output array of coordinate values.
* @param {number=} opt_dimension Dimension.
* @return {Array.<number>} Output coordinate array (new array, same coordinate
* values).
*/
ol.projection.cloneTransform = function(input, opt_output, opt_dimension) {
var output;
if (goog.isDef(opt_output)) {
for (var i = 0, ii = input.length; i < ii; ++i) {
opt_output[i] = input[i];
}
output = opt_output;
} else {
output = input.slice();
}
return output;
};
/**
* @param {ol.Coordinate} point Point.
* @param {ol.ProjectionLike} source Source.
* @param {ol.ProjectionLike} destination Destination.
* @return {ol.Coordinate} Point.
*/
ol.projection.transform = function(point, source, destination) {
var transformFn = ol.projection.getTransform(source, destination);
var vertex = [point.x, point.y];
vertex = transformFn(vertex, vertex, 2);
return new ol.Coordinate(vertex[0], vertex[1]);
};
/**
* Transforms the given point to the destination projection.
*
* @param {ol.Coordinate} point Point.
* @param {ol.Projection} sourceProjection Source projection.
* @param {ol.Projection} destinationProjection Destination projection.
* @return {ol.Coordinate} Point.
*/
ol.projection.transformWithProjections =
function(point, sourceProjection, destinationProjection) {
var transformFn = ol.projection.getTransformFromProjections(
sourceProjection, destinationProjection);
var vertex = [point.x, point.y];
vertex = transformFn(vertex, vertex, 2);
return new ol.Coordinate(vertex[0], vertex[1]);
};
/**
* @param {ol.Proj4jsProjectionOptions} options Projection config options.
* @return {ol.Proj4jsProjection_} Proj4js projection.
*/
ol.projection.configureProj4jsProjection = function(options) {
goog.asserts.assert(!goog.object.containsKey(
ol.projection.proj4jsProjections_, options.code));
return ol.projection.getProj4jsProjectionFromCode_(options);
};
+23
View File
@@ -0,0 +1,23 @@
goog.provide('ol.projection.addCommonProjections');
goog.require('ol.projection');
goog.require('ol.projection.EPSG3857');
goog.require('ol.projection.EPSG4326');
/**
* FIXME empty description for jsdoc
*/
ol.projection.addCommonProjections = function() {
// Add transformations that don't alter coordinates to convert within set of
// projections with equal meaning.
ol.projection.addEquivalentProjections(ol.projection.EPSG3857.PROJECTIONS);
ol.projection.addEquivalentProjections(ol.projection.EPSG4326.PROJECTIONS);
// Add transformations to convert EPSG:4326 like coordinates to EPSG:3857 like
// coordinates and back.
ol.projection.addEquivalentTransforms(
ol.projection.EPSG4326.PROJECTIONS,
ol.projection.EPSG3857.PROJECTIONS,
ol.projection.EPSG3857.fromEPSG4326,
ol.projection.EPSG3857.toEPSG4326);
};
+144
View File
@@ -0,0 +1,144 @@
goog.provide('ol.projection.EPSG3857');
goog.require('goog.array');
goog.require('ol.Extent');
goog.require('ol.Projection');
goog.require('ol.ProjectionUnits');
goog.require('ol.math');
goog.require('ol.projection');
/**
* @constructor
* @extends {ol.Projection}
* @param {string} code Code.
*/
ol.projection.EPSG3857 = function(code) {
goog.base(this, {
code: code,
units: ol.ProjectionUnits.METERS,
extent: ol.projection.EPSG3857.EXTENT,
global: true
});
};
goog.inherits(ol.projection.EPSG3857, ol.Projection);
/**
* @const
* @type {number}
*/
ol.projection.EPSG3857.RADIUS = 6378137;
/**
* @const
* @type {number}
*/
ol.projection.EPSG3857.HALF_SIZE = Math.PI * ol.projection.EPSG3857.RADIUS;
/**
* @const
* @type {ol.Extent}
*/
ol.projection.EPSG3857.EXTENT = new ol.Extent(
-ol.projection.EPSG3857.HALF_SIZE, -ol.projection.EPSG3857.HALF_SIZE,
ol.projection.EPSG3857.HALF_SIZE, ol.projection.EPSG3857.HALF_SIZE);
/**
* Lists several projection codes with the same meaning as EPSG:3857.
*
* @type {Array.<string>}
*/
ol.projection.EPSG3857.CODES = [
'EPSG:3857',
'EPSG:102100',
'EPSG:102113',
'EPSG:900913'
];
/**
* Projections equal to EPSG:3857.
*
* @const
* @type {Array.<ol.Projection>}
*/
ol.projection.EPSG3857.PROJECTIONS = goog.array.map(
ol.projection.EPSG3857.CODES,
function(code) {
return new ol.projection.EPSG3857(code);
});
/**
* Transformation from EPSG:4326 to EPSG:3857.
*
* @param {Array.<number>} input Input array of coordinate values.
* @param {Array.<number>=} opt_output Output array of coordinate values.
* @param {number=} opt_dimension Dimension (default is 2).
* @return {Array.<number>} Output array of coordinate values.
*/
ol.projection.EPSG3857.fromEPSG4326 = function(
input, opt_output, opt_dimension) {
var length = input.length,
dimension = opt_dimension > 1 ? opt_dimension : 2,
output = opt_output;
if (!goog.isDef(output)) {
if (dimension > 2) {
// preserve values beyond second dimension
output = input.slice();
} else {
output = new Array(length);
}
}
goog.asserts.assert(output.length % dimension === 0);
for (var i = 0; i < length; i += dimension) {
output[i] = ol.projection.EPSG3857.RADIUS * Math.PI * input[i] / 180;
output[i + 1] = ol.projection.EPSG3857.RADIUS *
Math.log(Math.tan(Math.PI * (input[i + 1] + 90) / 360));
}
return output;
};
/**
* Transformation from EPSG:3857 to EPSG:4326.
*
* @param {Array.<number>} input Input array of coordinate values.
* @param {Array.<number>=} opt_output Output array of coordinate values.
* @param {number=} opt_dimension Dimension (default is 2).
* @return {Array.<number>} Output array of coordinate values.
*/
ol.projection.EPSG3857.toEPSG4326 = function(input, opt_output, opt_dimension) {
var length = input.length,
dimension = opt_dimension > 1 ? opt_dimension : 2,
output = opt_output;
if (!goog.isDef(output)) {
if (dimension > 2) {
// preserve values beyond second dimension
output = input.slice();
} else {
output = new Array(length);
}
}
goog.asserts.assert(output.length % dimension === 0);
for (var i = 0; i < length; i += dimension) {
output[i] = 180 * input[i] / (ol.projection.EPSG3857.RADIUS * Math.PI);
output[i + 1] = 360 * Math.atan(
Math.exp(input[i + 1] / ol.projection.EPSG3857.RADIUS)) / Math.PI - 90;
}
return output;
};
/**
* @inheritDoc
*/
ol.projection.EPSG3857.prototype.getPointResolution =
function(resolution, point) {
return resolution / ol.math.cosh(point.y / ol.projection.EPSG3857.RADIUS);
};

Some files were not shown because too many files have changed in this diff Show More