Updated
This commit is contained in:
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
@exportSymbol ol.animation
|
||||
@exportProperty ol.animation.bounce
|
||||
@exportProperty ol.animation.pan
|
||||
@exportProperty ol.animation.rotate
|
||||
@exportProperty ol.animation.zoom
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
@exportSymbol ol.Attribution
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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)
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
})();
|
||||
@@ -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
|
||||
@@ -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);
|
||||
};
|
||||
@@ -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);
|
||||
};
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
@exportClass ol.control.Attribution ol.control.AttributionOptions
|
||||
@exportProperty ol.control.Attribution.prototype.setMap
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
@exportSymbol ol.control.defaults ol.control.defaults
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
@exportClass ol.control.Zoom ol.control.ZoomOptions
|
||||
@exportProperty ol.control.Zoom.prototype.setMap
|
||||
@@ -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);
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
@exportSymbol ol.Coordinate
|
||||
@exportProperty ol.Coordinate.toStringHDMS
|
||||
@@ -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]);
|
||||
}
|
||||
};
|
||||
@@ -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';
|
||||
}
|
||||
};
|
||||
@@ -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
|
||||
@@ -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));
|
||||
}
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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);
|
||||
@@ -0,0 +1,3 @@
|
||||
@exportSymbol ol.Extent
|
||||
@exportProperty ol.Extent.prototype.getHeight
|
||||
@exportProperty ol.Extent.prototype.getWidth
|
||||
@@ -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]));
|
||||
};
|
||||
@@ -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;
|
||||
@@ -0,0 +1 @@
|
||||
@exportSymbol ol.Geolocation
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
@@ -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() {
|
||||
};
|
||||
@@ -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() {
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
goog.provide('ol.IView3D');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface for views.
|
||||
* @interface
|
||||
*/
|
||||
ol.IView3D = function() {
|
||||
};
|
||||
|
||||
|
||||
@@ -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_;
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
@exportClass ol.layer.ImageLayer ol.layer.LayerOptions
|
||||
@@ -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());
|
||||
};
|
||||
@@ -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);
|
||||
@@ -0,0 +1 @@
|
||||
@exportClass ol.layer.TileLayer ol.layer.LayerOptions
|
||||
@@ -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());
|
||||
};
|
||||
@@ -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
|
||||
@@ -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();
|
||||
@@ -0,0 +1,2 @@
|
||||
@exportProperty ol.MapBrowserEvent.prototype.getCoordinate
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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);
|
||||
};
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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
|
||||
@@ -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);
|
||||
};
|
||||
@@ -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);
|
||||
};
|
||||
@@ -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
Reference in New Issue
Block a user