goog.provide('ol.Map'); goog.require('ol.Loc'); goog.require('ol.Bounds'); goog.require('ol.Projection'); goog.require('ol.control.Control'); goog.require('ol.renderer.MapRenderer'); goog.require('ol.handler.Drag'); goog.require('ol.handler.MouseWheel'); goog.require('ol.handler.Click'); goog.require('goog.dom'); goog.require('goog.math'); goog.require('goog.asserts'); goog.require('goog.events.EventTarget'); /** * @define {boolean} Whether to enable the drag handler. */ ol.ENABLE_DRAG_HANDLER = true; /** * @define {boolean} Whether to enable the mousewheel handler. */ ol.ENABLE_MOUSEWHEEL_HANDLER = true; /** * @define {boolean} Whether to enable the click handler. */ ol.ENABLE_CLICK_HANDLER = true; /** * @export * @constructor * @extends {goog.events.EventTarget} * * @event layeradd Fires when a layer is added to the map. The event object * contains a 'layer' property referencing the added layer. */ ol.Map = function() { goog.base(this); /** * @private * @type {ol.Projection} */ this.projection_ = null; /** * @private * @type {ol.Projection} */ this.userProjection_ = null; /** * @private * @type {ol.Loc} */ this.center_ = null; /** * @private * @type {number|undefined} */ this.zoom_ = undefined; /** * @private * @type {number} */ this.numZoomLevels_ = 22; /** * @private * @type {Array} */ this.resolutions_ = null; /** * @private * @type {Array} */ this.layers_ = null; /** * @private * @type {Array} */ this.controls_ = null; /** * @private * @type {ol.Bounds} */ this.maxExtent_ = null; /** * @private * @type {number|undefined} */ this.maxResolution_ = undefined; /** * @private * @type {Element} */ this.viewport_ = null; /** * @private * @type {goog.math.Size} */ this.viewportSize_ = null; /** * @private * @type {Node} */ this.mapOverlay_ = null; /** * @private * @type {Node} */ this.staticOverlay_ = null; /** * @private * @type {Element} */ this.container_ = null; }; goog.inherits(ol.Map, goog.events.EventTarget); /** @const @type {string} */ ol.Map.prototype.DEFAULT_PROJECTION = "EPSG:3857"; /** @const @type {string} */ ol.Map.prototype.DEFAULT_USER_PROJECTION = "EPSG:4326"; /** @const @type {number} */ ol.Map.ZOOM_FACTOR = 2; /** @const @type {number} */ ol.Map.DEFAULT_TILE_SIZE = 256; /** @const @type {Array.} */ ol.Map.DEFAULT_CONTROLS = ["attribution", "zoom"]; /** * @return {ol.Loc} Map center in map projection. */ ol.Map.prototype.getCenter = function() { return this.center_; }; /** * @return {!ol.Projection} Projection. */ ol.Map.prototype.getProjection = function() { if (goog.isNull(this.projection_)) { this.projection_ = new ol.Projection(this.DEFAULT_PROJECTION); } return this.projection_; }; /** * @return {!ol.Projection} User projection. */ ol.Map.prototype.getUserProjection = function() { if (goog.isNull(this.userProjection_)) { this.userProjection_ = new ol.Projection(this.DEFAULT_USER_PROJECTION); } return this.userProjection_; }; /** * @return {number|undefined} Zoom. */ ol.Map.prototype.getZoom = function() { return this.zoom_; }; /** * @return {number} number of zoom levels. */ ol.Map.prototype.getNumZoomLevels = function() { return this.numZoomLevels_; }; /** * @return {Array|undefined} array of resolutions available for this map */ ol.Map.prototype.getResolutions = function() { return this.resolutions_; }; /** * @return {Array|undefined} array of layers available for this map */ ol.Map.prototype.getLayers = function() { return this.layers_; }; /** * @return {Array.} */ ol.Map.prototype.getControls = function() { return this.controls_; }; /** * @return {ol.Bounds} the maxExtent for the map */ ol.Map.prototype.getMaxExtent = function() { if (goog.isDefAndNotNull(this.maxExtent_)) { return this.maxExtent_; } else { var projection = this.getProjection(); var extent = projection.getExtent(); if (goog.isDefAndNotNull(extent)) { extent = new ol.Bounds( extent.getMinX(), extent.getMinY(), extent.getMaxX(), extent.getMaxY()); extent.setProjection(projection); return extent; } else { throw('maxExtent must be defined either in the map or the projection'); } } }; /** * @return {number} the max resolution for the map */ ol.Map.prototype.getMaxResolution = function() { if (goog.isDefAndNotNull(this.maxResolution_)) { return this.maxResolution_; } else { var extent = this.getMaxExtent(); var dim = Math.max( (extent.getMaxX()-extent.getMinX()), (extent.getMaxY()-extent.getMinY()) ); return dim/ol.Map.DEFAULT_TILE_SIZE; } }; /** * @param {number} zoom the zoom level being requested * @return {number} the resolution for the map at the given zoom level */ ol.Map.prototype.getResolutionForZoom = function(zoom) { if (goog.isDefAndNotNull(this.resolutions_)) { return this.resolutions_[zoom]; } else { var maxResolution = this.getMaxResolution(); return maxResolution/Math.pow(ol.Map.ZOOM_FACTOR, zoom); } }; /** * @return {number} the resolution for the map at the given zoom level */ ol.Map.prototype.getResolution = function() { goog.asserts.assert(goog.isDef(this.renderer_)); return this.renderer_.getResolution(); }; /** * TODO: We'll have to ask the map overlay renderer for this. This method will * not work once map space is not aligned with pixel space. * * @param {goog.math.Coordinate|{x: number, y: number}} pixel * @return {ol.Loc} */ ol.Map.prototype.getLocForViewportPixel = function(pixel) { var size = this.getViewportSize(); var center = this.center_; var resolution = this.getResolution(); var x = center.getX() + (resolution * (pixel.x - (size.width / 2))); var y = center.getY() - (resolution * (pixel.y - (size.height / 2))); return new ol.Loc(x, y, undefined, this.getProjection()); }; /** * TODO: We'll have to ask the map overlay renderer for this. This method will * not work once map space is not aligned with pixel space. * * @param {ol.Loc} loc * @return {{x: number, y: number}} */ ol.Map.prototype.getViewportPixelForLoc = function(loc) { var size = this.getViewportSize(); var center = this.center_; var resolution = this.getResolution(); return { x: ((loc.getX() - center.getX()) / resolution) + (size.width / 2), y: ((center.getY() - loc.getY()) / resolution) + (size.height / 2) }; }; /** * @return {goog.math.Size} */ ol.Map.prototype.getViewportSize = function() { // TODO: listen for resize and set this.viewportSize_ null // https://github.com/openlayers/ol3/issues/2 if (goog.isNull(this.viewportSize_)) { this.viewportSize_ = goog.style.getSize(this.viewport_); } return this.viewportSize_; }; /** * @param {ol.Loc} center Center in map projection. */ ol.Map.prototype.setCenter = function(center) { goog.asserts.assert(!goog.isNull(center.getProjection())); this.center_ = center.doTransform(this.getProjection()); this.conditionallyRender(); }; /** * @param {ol.Loc} center * @param {number} zoom */ ol.Map.prototype.setCenterAndZoom = function(center, zoom) { goog.asserts.assert(!goog.isNull(center.getProjection())); this.center_ = center.doTransform(this.getProjection()); this.zoom_ = this.limitZoom(zoom); this.conditionallyRender(); }; /** * @param {number} zoom The zoom level to zoom to * @param {goog.math.Coordinate|{x: number, y: number}=} opt_anchor * Optional anchor pixel for the zoom origin. */ ol.Map.prototype.setZoom = function(zoom, opt_anchor) { var currentZoom = this.zoom_, newZoom = this.limitZoom(zoom), newCenter; if (newZoom === currentZoom) { return; } if (goog.isDef(opt_anchor)) { var size = this.getViewportSize(), anchorLoc = this.getLocForViewportPixel(opt_anchor), newRes = this.getResolutionForZoom(newZoom); newCenter = anchorLoc.add( (size.width/2 - opt_anchor.x) * newRes, (opt_anchor.y - size.height/2) * newRes ); } else { newCenter = this.center_; } this.setCenterAndZoom(newCenter, newZoom); }; /** * @param {ol.Projection} projection Projection. */ ol.Map.prototype.setProjection = function(projection) { this.projection_ = projection; }; /** * @param {ol.Projection} userProjection set the user projection. */ ol.Map.prototype.setUserProjection = function(userProjection) { this.userProjection_ = userProjection; }; /** * @param {number} zoom * @return {number} zoom clamped to the range of available zoom levels. */ ol.Map.prototype.limitZoom = function(zoom) { return goog.math.clamp(zoom, 0, this.getNumZoomLevels()-1); }; /** * @param {number} nZoom Zoom. */ ol.Map.prototype.setNumZoomLevels = function(nZoom) { this.numZoomLevels_ = nZoom; }; /** * @param {Array} resolutions the map resolutions if set on the map */ ol.Map.prototype.setResolutions = function(resolutions) { this.resolutions_ = resolutions; }; /** * @param {Array} layers the layers set on the map */ ol.Map.prototype.setLayers = function(layers) { //TODO remove layers properly if there are layers already this.layers_ = []; this.addLayers(layers); }; ol.Map.prototype.addLayers = function(layers) { var layer; for (var i=0, ii=layers.length; i|undefined} opt_controls */ ol.Map.prototype.setControls = function(opt_controls) { if (!this.controls_) { var control; for (var i=0, ii=opt_controls.length; i} */ ol.Map.preferredRenderers = ["webgl", "canvas"];