option is
│ │ │ │ │ + * provided or if you intend to call the
method later.
│ │ │ │ │ + * options - {Object} Optional object with properties to tag onto the map.
│ │ │ │ │ *
│ │ │ │ │ - * Valid options:
│ │ │ │ │ - * rules - {Array()} List of rules to be added to the
│ │ │ │ │ - * style.
│ │ │ │ │ + * Valid options (in addition to the listed API properties):
│ │ │ │ │ + * center - {|Array} The default initial center of the map.
│ │ │ │ │ + * If provided as array, the first value is the x coordinate,
│ │ │ │ │ + * and the 2nd value is the y coordinate.
│ │ │ │ │ + * Only specify if is provided.
│ │ │ │ │ + * Note that if an ArgParser/Permalink control is present,
│ │ │ │ │ + * and the querystring contains coordinates, center will be set
│ │ │ │ │ + * by that, and this option will be ignored.
│ │ │ │ │ + * zoom - {Number} The initial zoom level for the map. Only specify if
│ │ │ │ │ + * is provided.
│ │ │ │ │ + * Note that if an ArgParser/Permalink control is present,
│ │ │ │ │ + * and the querystring contains a zoom level, zoom will be set
│ │ │ │ │ + * by that, and this option will be ignored.
│ │ │ │ │ + * extent - {|Array} The initial extent of the map.
│ │ │ │ │ + * If provided as an array, the array should consist of
│ │ │ │ │ + * four values (left, bottom, right, top).
│ │ │ │ │ + * Only specify if and are not provided.
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {}
│ │ │ │ │ + * Examples:
│ │ │ │ │ + * (code)
│ │ │ │ │ + * // create a map with default options in an element with the id "map1"
│ │ │ │ │ + * var map = new OpenLayers.Map("map1");
│ │ │ │ │ + *
│ │ │ │ │ + * // create a map with non-default options in an element with id "map2"
│ │ │ │ │ + * var options = {
│ │ │ │ │ + * projection: "EPSG:3857",
│ │ │ │ │ + * maxExtent: new OpenLayers.Bounds(-200000, -200000, 200000, 200000),
│ │ │ │ │ + * center: new OpenLayers.LonLat(-12356463.476333, 5621521.4854095)
│ │ │ │ │ + * };
│ │ │ │ │ + * var map = new OpenLayers.Map("map2", options);
│ │ │ │ │ + *
│ │ │ │ │ + * // map with non-default options - same as above but with a single argument,
│ │ │ │ │ + * // a restricted extent, and using arrays for bounds and center
│ │ │ │ │ + * var map = new OpenLayers.Map({
│ │ │ │ │ + * div: "map_id",
│ │ │ │ │ + * projection: "EPSG:3857",
│ │ │ │ │ + * maxExtent: [-18924313.432222, -15538711.094146, 18924313.432222, 15538711.094146],
│ │ │ │ │ + * restrictedExtent: [-13358338.893333, -9608371.5085962, 13358338.893333, 9608371.5085962],
│ │ │ │ │ + * center: [-12356463.476333, 5621521.4854095]
│ │ │ │ │ + * });
│ │ │ │ │ + *
│ │ │ │ │ + * // create a map without a reference to a container - call render later
│ │ │ │ │ + * var map = new OpenLayers.Map({
│ │ │ │ │ + * projection: "EPSG:3857",
│ │ │ │ │ + * maxExtent: new OpenLayers.Bounds(-200000, -200000, 200000, 200000)
│ │ │ │ │ + * });
│ │ │ │ │ + * (end)
│ │ │ │ │ */
│ │ │ │ │ - initialize: function(style, options) {
│ │ │ │ │ + initialize: function(div, options) {
│ │ │ │ │ +
│ │ │ │ │ + // If only one argument is provided, check if it is an object.
│ │ │ │ │ + if (arguments.length === 1 && typeof div === "object") {
│ │ │ │ │ + options = div;
│ │ │ │ │ + div = options && options.div;
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + // Simple-type defaults are set in class definition.
│ │ │ │ │ + // Now set complex-type defaults
│ │ │ │ │ + this.tileSize = new OpenLayers.Size(OpenLayers.Map.TILE_WIDTH,
│ │ │ │ │ + OpenLayers.Map.TILE_HEIGHT);
│ │ │ │ │ +
│ │ │ │ │ + this.paddingForPopups = new OpenLayers.Bounds(15, 15, 15, 15);
│ │ │ │ │ +
│ │ │ │ │ + this.theme = OpenLayers._getScriptLocation() +
│ │ │ │ │ + 'theme/default/style.css';
│ │ │ │ │
│ │ │ │ │ + // backup original options
│ │ │ │ │ + this.options = OpenLayers.Util.extend({}, options);
│ │ │ │ │ +
│ │ │ │ │ + // now override default options
│ │ │ │ │ OpenLayers.Util.extend(this, options);
│ │ │ │ │ - this.rules = [];
│ │ │ │ │ - if (options && options.rules) {
│ │ │ │ │ - this.addRules(options.rules);
│ │ │ │ │ +
│ │ │ │ │ + var projCode = this.projection instanceof OpenLayers.Projection ?
│ │ │ │ │ + this.projection.projCode : this.projection;
│ │ │ │ │ + OpenLayers.Util.applyDefaults(this, OpenLayers.Projection.defaults[projCode]);
│ │ │ │ │ +
│ │ │ │ │ + // allow extents and center to be arrays
│ │ │ │ │ + if (this.maxExtent && !(this.maxExtent instanceof OpenLayers.Bounds)) {
│ │ │ │ │ + this.maxExtent = new OpenLayers.Bounds(this.maxExtent);
│ │ │ │ │ + }
│ │ │ │ │ + if (this.minExtent && !(this.minExtent instanceof OpenLayers.Bounds)) {
│ │ │ │ │ + this.minExtent = new OpenLayers.Bounds(this.minExtent);
│ │ │ │ │ + }
│ │ │ │ │ + if (this.restrictedExtent && !(this.restrictedExtent instanceof OpenLayers.Bounds)) {
│ │ │ │ │ + this.restrictedExtent = new OpenLayers.Bounds(this.restrictedExtent);
│ │ │ │ │ + }
│ │ │ │ │ + if (this.center && !(this.center instanceof OpenLayers.LonLat)) {
│ │ │ │ │ + this.center = new OpenLayers.LonLat(this.center);
│ │ │ │ │ }
│ │ │ │ │
│ │ │ │ │ - // use the default style from OpenLayers.Feature.Vector if no style
│ │ │ │ │ - // was given in the constructor
│ │ │ │ │ - this.setDefaultStyle(style ||
│ │ │ │ │ - OpenLayers.Feature.Vector.style["default"]);
│ │ │ │ │ + // initialize layers array
│ │ │ │ │ + this.layers = [];
│ │ │ │ │
│ │ │ │ │ - this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
│ │ │ │ │ - },
│ │ │ │ │ + this.id = OpenLayers.Util.createUniqueID("OpenLayers.Map_");
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: destroy
│ │ │ │ │ - * nullify references to prevent circular references and memory leaks
│ │ │ │ │ - */
│ │ │ │ │ - destroy: function() {
│ │ │ │ │ - for (var i = 0, len = this.rules.length; i < len; i++) {
│ │ │ │ │ - this.rules[i].destroy();
│ │ │ │ │ - this.rules[i] = null;
│ │ │ │ │ + this.div = OpenLayers.Util.getElement(div);
│ │ │ │ │ + if (!this.div) {
│ │ │ │ │ + this.div = document.createElement("div");
│ │ │ │ │ + this.div.style.height = "1px";
│ │ │ │ │ + this.div.style.width = "1px";
│ │ │ │ │ }
│ │ │ │ │ - this.rules = null;
│ │ │ │ │ - this.defaultStyle = null;
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: createSymbolizer
│ │ │ │ │ - * creates a style by applying all feature-dependent rules to the base
│ │ │ │ │ - * style.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * feature - {} feature to evaluate rules for
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Object} symbolizer hash
│ │ │ │ │ - */
│ │ │ │ │ - createSymbolizer: function(feature) {
│ │ │ │ │ - var style = this.defaultsPerSymbolizer ? {} : this.createLiterals(
│ │ │ │ │ - OpenLayers.Util.extend({}, this.defaultStyle), feature);
│ │ │ │ │ + OpenLayers.Element.addClass(this.div, 'olMap');
│ │ │ │ │
│ │ │ │ │ - var rules = this.rules;
│ │ │ │ │ + // the viewPortDiv is the outermost div we modify
│ │ │ │ │ + var id = this.id + "_OpenLayers_ViewPort";
│ │ │ │ │ + this.viewPortDiv = OpenLayers.Util.createDiv(id, null, null, null,
│ │ │ │ │ + "relative", null,
│ │ │ │ │ + "hidden");
│ │ │ │ │ + this.viewPortDiv.style.width = "100%";
│ │ │ │ │ + this.viewPortDiv.style.height = "100%";
│ │ │ │ │ + this.viewPortDiv.className = "olMapViewport";
│ │ │ │ │ + this.div.appendChild(this.viewPortDiv);
│ │ │ │ │
│ │ │ │ │ - var rule, context;
│ │ │ │ │ - var elseRules = [];
│ │ │ │ │ - var appliedRules = false;
│ │ │ │ │ - for (var i = 0, len = rules.length; i < len; i++) {
│ │ │ │ │ - rule = rules[i];
│ │ │ │ │ - // does the rule apply?
│ │ │ │ │ - var applies = rule.evaluate(feature);
│ │ │ │ │ + this.events = new OpenLayers.Events(
│ │ │ │ │ + this, this.viewPortDiv, null, this.fallThrough, {
│ │ │ │ │ + includeXY: true
│ │ │ │ │ + }
│ │ │ │ │ + );
│ │ │ │ │
│ │ │ │ │ - if (applies) {
│ │ │ │ │ - if (rule instanceof OpenLayers.Rule && rule.elseFilter) {
│ │ │ │ │ - elseRules.push(rule);
│ │ │ │ │ - } else {
│ │ │ │ │ - appliedRules = true;
│ │ │ │ │ - this.applySymbolizer(rule, style, feature);
│ │ │ │ │ + if (OpenLayers.TileManager && this.tileManager !== null) {
│ │ │ │ │ + if (!(this.tileManager instanceof OpenLayers.TileManager)) {
│ │ │ │ │ + this.tileManager = new OpenLayers.TileManager(this.tileManager);
│ │ │ │ │ + }
│ │ │ │ │ + this.tileManager.addMap(this);
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + // the layerContainerDiv is the one that holds all the layers
│ │ │ │ │ + id = this.id + "_OpenLayers_Container";
│ │ │ │ │ + this.layerContainerDiv = OpenLayers.Util.createDiv(id);
│ │ │ │ │ + this.layerContainerDiv.style.zIndex = this.Z_INDEX_BASE['Popup'] - 1;
│ │ │ │ │ + this.layerContainerOriginPx = {
│ │ │ │ │ + x: 0,
│ │ │ │ │ + y: 0
│ │ │ │ │ + };
│ │ │ │ │ + this.applyTransform();
│ │ │ │ │ +
│ │ │ │ │ + this.viewPortDiv.appendChild(this.layerContainerDiv);
│ │ │ │ │ +
│ │ │ │ │ + this.updateSize();
│ │ │ │ │ + if (this.eventListeners instanceof Object) {
│ │ │ │ │ + this.events.on(this.eventListeners);
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + if (this.autoUpdateSize === true) {
│ │ │ │ │ + // updateSize on catching the window's resize
│ │ │ │ │ + // Note that this is ok, as updateSize() does nothing if the
│ │ │ │ │ + // map's size has not actually changed.
│ │ │ │ │ + this.updateSizeDestroy = OpenLayers.Function.bind(this.updateSize,
│ │ │ │ │ + this);
│ │ │ │ │ + OpenLayers.Event.observe(window, 'resize',
│ │ │ │ │ + this.updateSizeDestroy);
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + // only append link stylesheet if the theme property is set
│ │ │ │ │ + if (this.theme) {
│ │ │ │ │ + // check existing links for equivalent url
│ │ │ │ │ + var addNode = true;
│ │ │ │ │ + var nodes = document.getElementsByTagName('link');
│ │ │ │ │ + for (var i = 0, len = nodes.length; i < len; ++i) {
│ │ │ │ │ + if (OpenLayers.Util.isEquivalentUrl(nodes.item(i).href,
│ │ │ │ │ + this.theme)) {
│ │ │ │ │ + addNode = false;
│ │ │ │ │ + break;
│ │ │ │ │ }
│ │ │ │ │ }
│ │ │ │ │ + // only add a new node if one with an equivalent url hasn't already
│ │ │ │ │ + // been added
│ │ │ │ │ + if (addNode) {
│ │ │ │ │ + var cssNode = document.createElement('link');
│ │ │ │ │ + cssNode.setAttribute('rel', 'stylesheet');
│ │ │ │ │ + cssNode.setAttribute('type', 'text/css');
│ │ │ │ │ + cssNode.setAttribute('href', this.theme);
│ │ │ │ │ + document.getElementsByTagName('head')[0].appendChild(cssNode);
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │
│ │ │ │ │ - // if no other rules apply, apply the rules with else filters
│ │ │ │ │ - if (appliedRules == false && elseRules.length > 0) {
│ │ │ │ │ - appliedRules = true;
│ │ │ │ │ - for (var i = 0, len = elseRules.length; i < len; i++) {
│ │ │ │ │ - this.applySymbolizer(elseRules[i], style, feature);
│ │ │ │ │ + if (this.controls == null) { // default controls
│ │ │ │ │ + this.controls = [];
│ │ │ │ │ + if (OpenLayers.Control != null) { // running full or lite?
│ │ │ │ │ + // Navigation or TouchNavigation depending on what is in build
│ │ │ │ │ + if (OpenLayers.Control.Navigation) {
│ │ │ │ │ + this.controls.push(new OpenLayers.Control.Navigation());
│ │ │ │ │ + } else if (OpenLayers.Control.TouchNavigation) {
│ │ │ │ │ + this.controls.push(new OpenLayers.Control.TouchNavigation());
│ │ │ │ │ + }
│ │ │ │ │ + if (OpenLayers.Control.Zoom) {
│ │ │ │ │ + this.controls.push(new OpenLayers.Control.Zoom());
│ │ │ │ │ + } else if (OpenLayers.Control.PanZoom) {
│ │ │ │ │ + this.controls.push(new OpenLayers.Control.PanZoom());
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + if (OpenLayers.Control.ArgParser) {
│ │ │ │ │ + this.controls.push(new OpenLayers.Control.ArgParser());
│ │ │ │ │ + }
│ │ │ │ │ + if (OpenLayers.Control.Attribution) {
│ │ │ │ │ + this.controls.push(new OpenLayers.Control.Attribution());
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ }
│ │ │ │ │
│ │ │ │ │ - // don't display if there were rules but none applied
│ │ │ │ │ - if (rules.length > 0 && appliedRules == false) {
│ │ │ │ │ - style.display = "none";
│ │ │ │ │ + for (var i = 0, len = this.controls.length; i < len; i++) {
│ │ │ │ │ + this.addControlToMap(this.controls[i]);
│ │ │ │ │ }
│ │ │ │ │
│ │ │ │ │ - if (style.label != null && typeof style.label !== "string") {
│ │ │ │ │ - style.label = String(style.label);
│ │ │ │ │ + this.popups = [];
│ │ │ │ │ +
│ │ │ │ │ + this.unloadDestroy = OpenLayers.Function.bind(this.destroy, this);
│ │ │ │ │ +
│ │ │ │ │ +
│ │ │ │ │ + // always call map.destroy()
│ │ │ │ │ + OpenLayers.Event.observe(window, 'unload', this.unloadDestroy);
│ │ │ │ │ +
│ │ │ │ │ + // add any initial layers
│ │ │ │ │ + if (options && options.layers) {
│ │ │ │ │ + /**
│ │ │ │ │ + * If you have set options.center, the map center property will be
│ │ │ │ │ + * set at this point. However, since setCenter has not been called,
│ │ │ │ │ + * addLayers gets confused. So we delete the map center in this
│ │ │ │ │ + * case. Because the check below uses options.center, it will
│ │ │ │ │ + * be properly set below.
│ │ │ │ │ + */
│ │ │ │ │ + delete this.center;
│ │ │ │ │ + delete this.zoom;
│ │ │ │ │ + this.addLayers(options.layers);
│ │ │ │ │ + // set center (and optionally zoom)
│ │ │ │ │ + if (options.center && !this.getCenter()) {
│ │ │ │ │ + // zoom can be undefined here
│ │ │ │ │ + this.setCenter(options.center, options.zoom);
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │
│ │ │ │ │ - return style;
│ │ │ │ │ + if (this.panMethod) {
│ │ │ │ │ + this.panTween = new OpenLayers.Tween(this.panMethod);
│ │ │ │ │ + }
│ │ │ │ │ + if (this.zoomMethod && this.applyTransform.transform) {
│ │ │ │ │ + this.zoomTween = new OpenLayers.Tween(this.zoomMethod);
│ │ │ │ │ + }
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: applySymbolizer
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * rule - {}
│ │ │ │ │ - * style - {Object}
│ │ │ │ │ - * feature - {}
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: getViewport
│ │ │ │ │ + * Get the DOMElement representing the view port.
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Object} A style with new symbolizer applied.
│ │ │ │ │ + * {DOMElement}
│ │ │ │ │ */
│ │ │ │ │ - applySymbolizer: function(rule, style, feature) {
│ │ │ │ │ - var symbolizerPrefix = feature.geometry ?
│ │ │ │ │ - this.getSymbolizerPrefix(feature.geometry) :
│ │ │ │ │ - OpenLayers.Style.SYMBOLIZER_PREFIXES[0];
│ │ │ │ │ + getViewport: function() {
│ │ │ │ │ + return this.viewPortDiv;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - var symbolizer = rule.symbolizer[symbolizerPrefix] || rule.symbolizer;
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: render
│ │ │ │ │ + * Render the map to a specified container.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * div - {String|DOMElement} The container that the map should be rendered
│ │ │ │ │ + * to. If different than the current container, the map viewport
│ │ │ │ │ + * will be moved from the current to the new container.
│ │ │ │ │ + */
│ │ │ │ │ + render: function(div) {
│ │ │ │ │ + this.div = OpenLayers.Util.getElement(div);
│ │ │ │ │ + OpenLayers.Element.addClass(this.div, 'olMap');
│ │ │ │ │ + this.viewPortDiv.parentNode.removeChild(this.viewPortDiv);
│ │ │ │ │ + this.div.appendChild(this.viewPortDiv);
│ │ │ │ │ + this.updateSize();
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - if (this.defaultsPerSymbolizer === true) {
│ │ │ │ │ - var defaults = this.defaultStyle;
│ │ │ │ │ - OpenLayers.Util.applyDefaults(symbolizer, {
│ │ │ │ │ - pointRadius: defaults.pointRadius
│ │ │ │ │ - });
│ │ │ │ │ - if (symbolizer.stroke === true || symbolizer.graphic === true) {
│ │ │ │ │ - OpenLayers.Util.applyDefaults(symbolizer, {
│ │ │ │ │ - strokeWidth: defaults.strokeWidth,
│ │ │ │ │ - strokeColor: defaults.strokeColor,
│ │ │ │ │ - strokeOpacity: defaults.strokeOpacity,
│ │ │ │ │ - strokeDashstyle: defaults.strokeDashstyle,
│ │ │ │ │ - strokeLinecap: defaults.strokeLinecap
│ │ │ │ │ - });
│ │ │ │ │ - }
│ │ │ │ │ - if (symbolizer.fill === true || symbolizer.graphic === true) {
│ │ │ │ │ - OpenLayers.Util.applyDefaults(symbolizer, {
│ │ │ │ │ - fillColor: defaults.fillColor,
│ │ │ │ │ - fillOpacity: defaults.fillOpacity
│ │ │ │ │ - });
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: unloadDestroy
│ │ │ │ │ + * Function that is called to destroy the map on page unload. stored here
│ │ │ │ │ + * so that if map is manually destroyed, we can unregister this.
│ │ │ │ │ + */
│ │ │ │ │ + unloadDestroy: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: updateSizeDestroy
│ │ │ │ │ + * When the map is destroyed, we need to stop listening to updateSize
│ │ │ │ │ + * events: this method stores the function we need to unregister in
│ │ │ │ │ + * non-IE browsers.
│ │ │ │ │ + */
│ │ │ │ │ + updateSizeDestroy: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: destroy
│ │ │ │ │ + * Destroy this map.
│ │ │ │ │ + * Note that if you are using an application which removes a container
│ │ │ │ │ + * of the map from the DOM, you need to ensure that you destroy the
│ │ │ │ │ + * map *before* this happens; otherwise, the page unload handler
│ │ │ │ │ + * will fail because the DOM elements that map.destroy() wants
│ │ │ │ │ + * to clean up will be gone. (See
│ │ │ │ │ + * http://trac.osgeo.org/openlayers/ticket/2277 for more information).
│ │ │ │ │ + * This will apply to GeoExt and also to other applications which
│ │ │ │ │ + * modify the DOM of the container of the OpenLayers Map.
│ │ │ │ │ + */
│ │ │ │ │ + destroy: function() {
│ │ │ │ │ + // if unloadDestroy is null, we've already been destroyed
│ │ │ │ │ + if (!this.unloadDestroy) {
│ │ │ │ │ + return false;
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + // make sure panning doesn't continue after destruction
│ │ │ │ │ + if (this.panTween) {
│ │ │ │ │ + this.panTween.stop();
│ │ │ │ │ + this.panTween = null;
│ │ │ │ │ + }
│ │ │ │ │ + // make sure zooming doesn't continue after destruction
│ │ │ │ │ + if (this.zoomTween) {
│ │ │ │ │ + this.zoomTween.stop();
│ │ │ │ │ + this.zoomTween = null;
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + // map has been destroyed. dont do it again!
│ │ │ │ │ + OpenLayers.Event.stopObserving(window, 'unload', this.unloadDestroy);
│ │ │ │ │ + this.unloadDestroy = null;
│ │ │ │ │ +
│ │ │ │ │ + if (this.updateSizeDestroy) {
│ │ │ │ │ + OpenLayers.Event.stopObserving(window, 'resize',
│ │ │ │ │ + this.updateSizeDestroy);
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + this.paddingForPopups = null;
│ │ │ │ │ +
│ │ │ │ │ + if (this.controls != null) {
│ │ │ │ │ + for (var i = this.controls.length - 1; i >= 0; --i) {
│ │ │ │ │ + this.controls[i].destroy();
│ │ │ │ │ }
│ │ │ │ │ - if (symbolizer.graphic === true) {
│ │ │ │ │ - OpenLayers.Util.applyDefaults(symbolizer, {
│ │ │ │ │ - pointRadius: this.defaultStyle.pointRadius,
│ │ │ │ │ - externalGraphic: this.defaultStyle.externalGraphic,
│ │ │ │ │ - graphicName: this.defaultStyle.graphicName,
│ │ │ │ │ - graphicOpacity: this.defaultStyle.graphicOpacity,
│ │ │ │ │ - graphicWidth: this.defaultStyle.graphicWidth,
│ │ │ │ │ - graphicHeight: this.defaultStyle.graphicHeight,
│ │ │ │ │ - graphicXOffset: this.defaultStyle.graphicXOffset,
│ │ │ │ │ - graphicYOffset: this.defaultStyle.graphicYOffset
│ │ │ │ │ - });
│ │ │ │ │ + this.controls = null;
│ │ │ │ │ + }
│ │ │ │ │ + if (this.layers != null) {
│ │ │ │ │ + for (var i = this.layers.length - 1; i >= 0; --i) {
│ │ │ │ │ + //pass 'false' to destroy so that map wont try to set a new
│ │ │ │ │ + // baselayer after each baselayer is removed
│ │ │ │ │ + this.layers[i].destroy(false);
│ │ │ │ │ }
│ │ │ │ │ + this.layers = null;
│ │ │ │ │ + }
│ │ │ │ │ + if (this.viewPortDiv && this.viewPortDiv.parentNode) {
│ │ │ │ │ + this.viewPortDiv.parentNode.removeChild(this.viewPortDiv);
│ │ │ │ │ }
│ │ │ │ │ + this.viewPortDiv = null;
│ │ │ │ │
│ │ │ │ │ - // merge the style with the current style
│ │ │ │ │ - return this.createLiterals(
│ │ │ │ │ - OpenLayers.Util.extend(style, symbolizer), feature);
│ │ │ │ │ + if (this.tileManager) {
│ │ │ │ │ + this.tileManager.removeMap(this);
│ │ │ │ │ + this.tileManager = null;
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + if (this.eventListeners) {
│ │ │ │ │ + this.events.un(this.eventListeners);
│ │ │ │ │ + this.eventListeners = null;
│ │ │ │ │ + }
│ │ │ │ │ + this.events.destroy();
│ │ │ │ │ + this.events = null;
│ │ │ │ │ +
│ │ │ │ │ + this.options = null;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: createLiterals
│ │ │ │ │ - * creates literals for all style properties that have an entry in
│ │ │ │ │ - * .
│ │ │ │ │ - *
│ │ │ │ │ + * APIMethod: setOptions
│ │ │ │ │ + * Change the map options
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * style - {Object} style to create literals for. Will be modified
│ │ │ │ │ - * inline.
│ │ │ │ │ - * feature - {Object}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Object} the modified style
│ │ │ │ │ + * options - {Object} Hashtable of options to tag to the map
│ │ │ │ │ */
│ │ │ │ │ - createLiterals: function(style, feature) {
│ │ │ │ │ - var context = OpenLayers.Util.extend({}, feature.attributes || feature.data);
│ │ │ │ │ - OpenLayers.Util.extend(context, this.context);
│ │ │ │ │ -
│ │ │ │ │ - for (var i in this.propertyStyles) {
│ │ │ │ │ - style[i] = OpenLayers.Style.createLiteral(style[i], context, feature, i);
│ │ │ │ │ - }
│ │ │ │ │ - return style;
│ │ │ │ │ + setOptions: function(options) {
│ │ │ │ │ + var updatePxExtent = this.minPx &&
│ │ │ │ │ + options.restrictedExtent != this.restrictedExtent;
│ │ │ │ │ + OpenLayers.Util.extend(this, options);
│ │ │ │ │ + // force recalculation of minPx and maxPx
│ │ │ │ │ + updatePxExtent && this.moveTo(this.getCachedCenter(), this.zoom, {
│ │ │ │ │ + forceZoomChange: true
│ │ │ │ │ + });
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: findPropertyStyles
│ │ │ │ │ - * Looks into all rules for this style and the defaultStyle to collect
│ │ │ │ │ - * all the style hash property names containing ${...} strings that have
│ │ │ │ │ - * to be replaced using the createLiteral method before returning them.
│ │ │ │ │ - *
│ │ │ │ │ + * APIMethod: getTileSize
│ │ │ │ │ + * Get the tile size for the map
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Object} hash of property names that need createLiteral parsing. The
│ │ │ │ │ - * name of the property is the key, and the value is true;
│ │ │ │ │ + * {}
│ │ │ │ │ */
│ │ │ │ │ - findPropertyStyles: function() {
│ │ │ │ │ - var propertyStyles = {};
│ │ │ │ │ -
│ │ │ │ │ - // check the default style
│ │ │ │ │ - var style = this.defaultStyle;
│ │ │ │ │ - this.addPropertyStyles(propertyStyles, style);
│ │ │ │ │ -
│ │ │ │ │ - // walk through all rules to check for properties in their symbolizer
│ │ │ │ │ - var rules = this.rules;
│ │ │ │ │ - var symbolizer, value;
│ │ │ │ │ - for (var i = 0, len = rules.length; i < len; i++) {
│ │ │ │ │ - symbolizer = rules[i].symbolizer;
│ │ │ │ │ - for (var key in symbolizer) {
│ │ │ │ │ - value = symbolizer[key];
│ │ │ │ │ - if (typeof value == "object") {
│ │ │ │ │ - // symbolizer key is "Point", "Line" or "Polygon"
│ │ │ │ │ - this.addPropertyStyles(propertyStyles, value);
│ │ │ │ │ - } else {
│ │ │ │ │ - // symbolizer is a hash of style properties
│ │ │ │ │ - this.addPropertyStyles(propertyStyles, symbolizer);
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return propertyStyles;
│ │ │ │ │ + getTileSize: function() {
│ │ │ │ │ + return this.tileSize;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ +
│ │ │ │ │ /**
│ │ │ │ │ - * Method: addPropertyStyles
│ │ │ │ │ - *
│ │ │ │ │ + * APIMethod: getBy
│ │ │ │ │ + * Get a list of objects given a property and a match item.
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * propertyStyles - {Object} hash to add new property styles to. Will be
│ │ │ │ │ - * modified inline
│ │ │ │ │ - * symbolizer - {Object} search this symbolizer for property styles
│ │ │ │ │ - *
│ │ │ │ │ + * array - {String} A property on the map whose value is an array.
│ │ │ │ │ + * property - {String} A property on each item of the given array.
│ │ │ │ │ + * match - {String | Object} A string to match. Can also be a regular
│ │ │ │ │ + * expression literal or object. In addition, it can be any object
│ │ │ │ │ + * with a method named test. For reqular expressions or other, if
│ │ │ │ │ + * match.test(map[array][i][property]) evaluates to true, the item will
│ │ │ │ │ + * be included in the array returned. If no items are found, an empty
│ │ │ │ │ + * array is returned.
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Object} propertyStyles hash
│ │ │ │ │ + * {Array} An array of items where the given property matches the given
│ │ │ │ │ + * criteria.
│ │ │ │ │ */
│ │ │ │ │ - addPropertyStyles: function(propertyStyles, symbolizer) {
│ │ │ │ │ - var property;
│ │ │ │ │ - for (var key in symbolizer) {
│ │ │ │ │ - property = symbolizer[key];
│ │ │ │ │ - if (typeof property == "string" &&
│ │ │ │ │ - property.match(/\$\{\w+\}/)) {
│ │ │ │ │ - propertyStyles[key] = true;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return propertyStyles;
│ │ │ │ │ + getBy: function(array, property, match) {
│ │ │ │ │ + var test = (typeof match.test == "function");
│ │ │ │ │ + var found = OpenLayers.Array.filter(this[array], function(item) {
│ │ │ │ │ + return item[property] == match || (test && match.test(item[property]));
│ │ │ │ │ + });
│ │ │ │ │ + return found;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: addRules
│ │ │ │ │ - * Adds rules to this style.
│ │ │ │ │ - *
│ │ │ │ │ + * APIMethod: getLayersBy
│ │ │ │ │ + * Get a list of layers with properties matching the given criteria.
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * rules - {Array()}
│ │ │ │ │ + * property - {String} A layer property to be matched.
│ │ │ │ │ + * match - {String | Object} A string to match. Can also be a regular
│ │ │ │ │ + * expression literal or object. In addition, it can be any object
│ │ │ │ │ + * with a method named test. For reqular expressions or other, if
│ │ │ │ │ + * match.test(layer[property]) evaluates to true, the layer will be
│ │ │ │ │ + * included in the array returned. If no layers are found, an empty
│ │ │ │ │ + * array is returned.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Array()} A list of layers matching the given criteria.
│ │ │ │ │ + * An empty array is returned if no matches are found.
│ │ │ │ │ */
│ │ │ │ │ - addRules: function(rules) {
│ │ │ │ │ - Array.prototype.push.apply(this.rules, rules);
│ │ │ │ │ - this.propertyStyles = this.findPropertyStyles();
│ │ │ │ │ + getLayersBy: function(property, match) {
│ │ │ │ │ + return this.getBy("layers", property, match);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: setDefaultStyle
│ │ │ │ │ - * Sets the default style for this style object.
│ │ │ │ │ - *
│ │ │ │ │ + * APIMethod: getLayersByName
│ │ │ │ │ + * Get a list of layers with names matching the given name.
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * style - {Object} Hash of style properties
│ │ │ │ │ + * match - {String | Object} A layer name. The name can also be a regular
│ │ │ │ │ + * expression literal or object. In addition, it can be any object
│ │ │ │ │ + * with a method named test. For reqular expressions or other, if
│ │ │ │ │ + * name.test(layer.name) evaluates to true, the layer will be included
│ │ │ │ │ + * in the list of layers returned. If no layers are found, an empty
│ │ │ │ │ + * array is returned.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Array()} A list of layers matching the given name.
│ │ │ │ │ + * An empty array is returned if no matches are found.
│ │ │ │ │ */
│ │ │ │ │ - setDefaultStyle: function(style) {
│ │ │ │ │ - this.defaultStyle = style;
│ │ │ │ │ - this.propertyStyles = this.findPropertyStyles();
│ │ │ │ │ + getLayersByName: function(match) {
│ │ │ │ │ + return this.getLayersBy("name", match);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: getSymbolizerPrefix
│ │ │ │ │ - * Returns the correct symbolizer prefix according to the
│ │ │ │ │ - * geometry type of the passed geometry
│ │ │ │ │ - *
│ │ │ │ │ + * APIMethod: getLayersByClass
│ │ │ │ │ + * Get a list of layers of a given class (CLASS_NAME).
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * geometry - {}
│ │ │ │ │ - *
│ │ │ │ │ + * match - {String | Object} A layer class name. The match can also be a
│ │ │ │ │ + * regular expression literal or object. In addition, it can be any
│ │ │ │ │ + * object with a method named test. For reqular expressions or other,
│ │ │ │ │ + * if type.test(layer.CLASS_NAME) evaluates to true, the layer will
│ │ │ │ │ + * be included in the list of layers returned. If no layers are
│ │ │ │ │ + * found, an empty array is returned.
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {String} key of the according symbolizer
│ │ │ │ │ + * {Array()} A list of layers matching the given class.
│ │ │ │ │ + * An empty array is returned if no matches are found.
│ │ │ │ │ */
│ │ │ │ │ - getSymbolizerPrefix: function(geometry) {
│ │ │ │ │ - var prefixes = OpenLayers.Style.SYMBOLIZER_PREFIXES;
│ │ │ │ │ - for (var i = 0, len = prefixes.length; i < len; i++) {
│ │ │ │ │ - if (geometry.CLASS_NAME.indexOf(prefixes[i]) != -1) {
│ │ │ │ │ - return prefixes[i];
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ + getLayersByClass: function(match) {
│ │ │ │ │ + return this.getLayersBy("CLASS_NAME", match);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: clone
│ │ │ │ │ - * Clones this style.
│ │ │ │ │ - *
│ │ │ │ │ + * APIMethod: getControlsBy
│ │ │ │ │ + * Get a list of controls with properties matching the given criteria.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * property - {String} A control property to be matched.
│ │ │ │ │ + * match - {String | Object} A string to match. Can also be a regular
│ │ │ │ │ + * expression literal or object. In addition, it can be any object
│ │ │ │ │ + * with a method named test. For reqular expressions or other, if
│ │ │ │ │ + * match.test(layer[property]) evaluates to true, the layer will be
│ │ │ │ │ + * included in the array returned. If no layers are found, an empty
│ │ │ │ │ + * array is returned.
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {} Clone of this style.
│ │ │ │ │ + * {Array()} A list of controls matching the given
│ │ │ │ │ + * criteria. An empty array is returned if no matches are found.
│ │ │ │ │ */
│ │ │ │ │ - clone: function() {
│ │ │ │ │ - var options = OpenLayers.Util.extend({}, this);
│ │ │ │ │ - // clone rules
│ │ │ │ │ - if (this.rules) {
│ │ │ │ │ - options.rules = [];
│ │ │ │ │ - for (var i = 0, len = this.rules.length; i < len; ++i) {
│ │ │ │ │ - options.rules.push(this.rules[i].clone());
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - // clone context
│ │ │ │ │ - options.context = this.context && OpenLayers.Util.extend({}, this.context);
│ │ │ │ │ - //clone default style
│ │ │ │ │ - var defaultStyle = OpenLayers.Util.extend({}, this.defaultStyle);
│ │ │ │ │ - return new OpenLayers.Style(defaultStyle, options);
│ │ │ │ │ + getControlsBy: function(property, match) {
│ │ │ │ │ + return this.getBy("controls", property, match);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Style"
│ │ │ │ │ -});
│ │ │ │ │ -
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Function: createLiteral
│ │ │ │ │ - * converts a style value holding a combination of PropertyName and Literal
│ │ │ │ │ - * into a Literal, taking the property values from the passed features.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * value - {String} value to parse. If this string contains a construct like
│ │ │ │ │ - * "foo ${bar}", then "foo " will be taken as literal, and "${bar}"
│ │ │ │ │ - * will be replaced by the value of the "bar" attribute of the passed
│ │ │ │ │ - * feature.
│ │ │ │ │ - * context - {Object} context to take attribute values from
│ │ │ │ │ - * feature - {} optional feature to pass to
│ │ │ │ │ - * for evaluating functions in the
│ │ │ │ │ - * context.
│ │ │ │ │ - * property - {String} optional, name of the property for which the literal is
│ │ │ │ │ - * being created for evaluating functions in the context.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} the parsed value. In the example of the value parameter above, the
│ │ │ │ │ - * result would be "foo valueOfBar", assuming that the passed feature has an
│ │ │ │ │ - * attribute named "bar" with the value "valueOfBar".
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Style.createLiteral = function(value, context, feature, property) {
│ │ │ │ │ - if (typeof value == "string" && value.indexOf("${") != -1) {
│ │ │ │ │ - value = OpenLayers.String.format(value, context, [feature, property]);
│ │ │ │ │ - value = (isNaN(value) || !value) ? value : parseFloat(value);
│ │ │ │ │ - }
│ │ │ │ │ - return value;
│ │ │ │ │ -};
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Constant: OpenLayers.Style.SYMBOLIZER_PREFIXES
│ │ │ │ │ - * {Array} prefixes of the sld symbolizers. These are the
│ │ │ │ │ - * same as the main geometry types
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Style.SYMBOLIZER_PREFIXES = ['Point', 'Line', 'Polygon', 'Text',
│ │ │ │ │ - 'Raster'
│ │ │ │ │ -];
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/StyleMap.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ - * @requires OpenLayers/Style.js
│ │ │ │ │ - * @requires OpenLayers/Feature/Vector.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.StyleMap
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.StyleMap = OpenLayers.Class({
│ │ │ │ │ -
│ │ │ │ │ /**
│ │ │ │ │ - * Property: styles
│ │ │ │ │ - * {Object} Hash of {}, keyed by names of well known
│ │ │ │ │ - * rendering intents (e.g. "default", "temporary", "select", "delete").
│ │ │ │ │ + * APIMethod: getControlsByClass
│ │ │ │ │ + * Get a list of controls of a given class (CLASS_NAME).
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * match - {String | Object} A control class name. The match can also be a
│ │ │ │ │ + * regular expression literal or object. In addition, it can be any
│ │ │ │ │ + * object with a method named test. For reqular expressions or other,
│ │ │ │ │ + * if type.test(control.CLASS_NAME) evaluates to true, the control will
│ │ │ │ │ + * be included in the list of controls returned. If no controls are
│ │ │ │ │ + * found, an empty array is returned.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Array()} A list of controls matching the given class.
│ │ │ │ │ + * An empty array is returned if no matches are found.
│ │ │ │ │ */
│ │ │ │ │ - styles: null,
│ │ │ │ │ + getControlsByClass: function(match) {
│ │ │ │ │ + return this.getControlsBy("CLASS_NAME", match);
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /********************************************************/
│ │ │ │ │ + /* */
│ │ │ │ │ + /* Layer Functions */
│ │ │ │ │ + /* */
│ │ │ │ │ + /* The following functions deal with adding and */
│ │ │ │ │ + /* removing Layers to and from the Map */
│ │ │ │ │ + /* */
│ │ │ │ │ + /********************************************************/
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: extendDefault
│ │ │ │ │ - * {Boolean} if true, every render intent will extend the symbolizers
│ │ │ │ │ - * specified for the "default" intent at rendering time. Otherwise, every
│ │ │ │ │ - * rendering intent will be treated as a completely independent style.
│ │ │ │ │ + * APIMethod: getLayer
│ │ │ │ │ + * Get a layer based on its id
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * id - {String} A layer id
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {} The Layer with the corresponding id from the map's
│ │ │ │ │ + * layer collection, or null if not found.
│ │ │ │ │ */
│ │ │ │ │ - extendDefault: true,
│ │ │ │ │ + getLayer: function(id) {
│ │ │ │ │ + var foundLayer = null;
│ │ │ │ │ + for (var i = 0, len = this.layers.length; i < len; i++) {
│ │ │ │ │ + var layer = this.layers[i];
│ │ │ │ │ + if (layer.id == id) {
│ │ │ │ │ + foundLayer = layer;
│ │ │ │ │ + break;
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + return foundLayer;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constructor: OpenLayers.StyleMap
│ │ │ │ │ + * Method: setLayerZIndex
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * style - {Object} Optional. Either a style hash, or a style object, or
│ │ │ │ │ - * a hash of style objects (style hashes) keyed by rendering
│ │ │ │ │ - * intent. If just one style hash or style object is passed,
│ │ │ │ │ - * this will be used for all known render intents (default,
│ │ │ │ │ - * select, temporary)
│ │ │ │ │ - * options - {Object} optional hash of additional options for this
│ │ │ │ │ - * instance
│ │ │ │ │ + * layer - {}
│ │ │ │ │ + * zIdx - {int}
│ │ │ │ │ */
│ │ │ │ │ - initialize: function(style, options) {
│ │ │ │ │ - this.styles = {
│ │ │ │ │ - "default": new OpenLayers.Style(
│ │ │ │ │ - OpenLayers.Feature.Vector.style["default"]),
│ │ │ │ │ - "select": new OpenLayers.Style(
│ │ │ │ │ - OpenLayers.Feature.Vector.style["select"]),
│ │ │ │ │ - "temporary": new OpenLayers.Style(
│ │ │ │ │ - OpenLayers.Feature.Vector.style["temporary"]),
│ │ │ │ │ - "delete": new OpenLayers.Style(
│ │ │ │ │ - OpenLayers.Feature.Vector.style["delete"])
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - // take whatever the user passed as style parameter and convert it
│ │ │ │ │ - // into parts of stylemap.
│ │ │ │ │ - if (style instanceof OpenLayers.Style) {
│ │ │ │ │ - // user passed a style object
│ │ │ │ │ - this.styles["default"] = style;
│ │ │ │ │ - this.styles["select"] = style;
│ │ │ │ │ - this.styles["temporary"] = style;
│ │ │ │ │ - this.styles["delete"] = style;
│ │ │ │ │ - } else if (typeof style == "object") {
│ │ │ │ │ - for (var key in style) {
│ │ │ │ │ - if (style[key] instanceof OpenLayers.Style) {
│ │ │ │ │ - // user passed a hash of style objects
│ │ │ │ │ - this.styles[key] = style[key];
│ │ │ │ │ - } else if (typeof style[key] == "object") {
│ │ │ │ │ - // user passsed a hash of style hashes
│ │ │ │ │ - this.styles[key] = new OpenLayers.Style(style[key]);
│ │ │ │ │ - } else {
│ │ │ │ │ - // user passed a style hash (i.e. symbolizer)
│ │ │ │ │ - this.styles["default"] = new OpenLayers.Style(style);
│ │ │ │ │ - this.styles["select"] = new OpenLayers.Style(style);
│ │ │ │ │ - this.styles["temporary"] = new OpenLayers.Style(style);
│ │ │ │ │ - this.styles["delete"] = new OpenLayers.Style(style);
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - OpenLayers.Util.extend(this, options);
│ │ │ │ │ + setLayerZIndex: function(layer, zIdx) {
│ │ │ │ │ + layer.setZIndex(
│ │ │ │ │ + this.Z_INDEX_BASE[layer.isBaseLayer ? 'BaseLayer' : 'Overlay'] +
│ │ │ │ │ + zIdx * 5);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: destroy
│ │ │ │ │ + * Method: resetLayersZIndex
│ │ │ │ │ + * Reset each layer's z-index based on layer's array index
│ │ │ │ │ */
│ │ │ │ │ - destroy: function() {
│ │ │ │ │ - for (var key in this.styles) {
│ │ │ │ │ - this.styles[key].destroy();
│ │ │ │ │ + resetLayersZIndex: function() {
│ │ │ │ │ + for (var i = 0, len = this.layers.length; i < len; i++) {
│ │ │ │ │ + var layer = this.layers[i];
│ │ │ │ │ + this.setLayerZIndex(layer, i);
│ │ │ │ │ }
│ │ │ │ │ - this.styles = null;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: createSymbolizer
│ │ │ │ │ - * Creates the symbolizer for a feature for a render intent.
│ │ │ │ │ - *
│ │ │ │ │ + * APIMethod: addLayer
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * feature - {} The feature to evaluate the rules
│ │ │ │ │ - * of the intended style against.
│ │ │ │ │ - * intent - {String} The intent determines the symbolizer that will be
│ │ │ │ │ - * used to draw the feature. Well known intents are "default"
│ │ │ │ │ - * (for just drawing the features), "select" (for selected
│ │ │ │ │ - * features) and "temporary" (for drawing features).
│ │ │ │ │ - *
│ │ │ │ │ + * layer - {}
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Object} symbolizer hash
│ │ │ │ │ + * {Boolean} True if the layer has been added to the map.
│ │ │ │ │ */
│ │ │ │ │ - createSymbolizer: function(feature, intent) {
│ │ │ │ │ - if (!feature) {
│ │ │ │ │ - feature = new OpenLayers.Feature.Vector();
│ │ │ │ │ + addLayer: function(layer) {
│ │ │ │ │ + for (var i = 0, len = this.layers.length; i < len; i++) {
│ │ │ │ │ + if (this.layers[i] == layer) {
│ │ │ │ │ + return false;
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ - if (!this.styles[intent]) {
│ │ │ │ │ - intent = "default";
│ │ │ │ │ + if (this.events.triggerEvent("preaddlayer", {
│ │ │ │ │ + layer: layer
│ │ │ │ │ + }) === false) {
│ │ │ │ │ + return false;
│ │ │ │ │ }
│ │ │ │ │ - feature.renderIntent = intent;
│ │ │ │ │ - var defaultSymbolizer = {};
│ │ │ │ │ - if (this.extendDefault && intent != "default") {
│ │ │ │ │ - defaultSymbolizer = this.styles["default"].createSymbolizer(feature);
│ │ │ │ │ + if (this.allOverlays) {
│ │ │ │ │ + layer.isBaseLayer = false;
│ │ │ │ │ }
│ │ │ │ │ - return OpenLayers.Util.extend(defaultSymbolizer,
│ │ │ │ │ - this.styles[intent].createSymbolizer(feature));
│ │ │ │ │ +
│ │ │ │ │ + layer.div.className = "olLayerDiv";
│ │ │ │ │ + layer.div.style.overflow = "";
│ │ │ │ │ + this.setLayerZIndex(layer, this.layers.length);
│ │ │ │ │ +
│ │ │ │ │ + if (layer.isFixed) {
│ │ │ │ │ + this.viewPortDiv.appendChild(layer.div);
│ │ │ │ │ + } else {
│ │ │ │ │ + this.layerContainerDiv.appendChild(layer.div);
│ │ │ │ │ + }
│ │ │ │ │ + this.layers.push(layer);
│ │ │ │ │ + layer.setMap(this);
│ │ │ │ │ +
│ │ │ │ │ + if (layer.isBaseLayer || (this.allOverlays && !this.baseLayer)) {
│ │ │ │ │ + if (this.baseLayer == null) {
│ │ │ │ │ + // set the first baselaye we add as the baselayer
│ │ │ │ │ + this.setBaseLayer(layer);
│ │ │ │ │ + } else {
│ │ │ │ │ + layer.setVisibility(false);
│ │ │ │ │ + }
│ │ │ │ │ + } else {
│ │ │ │ │ + layer.redraw();
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + this.events.triggerEvent("addlayer", {
│ │ │ │ │ + layer: layer
│ │ │ │ │ + });
│ │ │ │ │ + layer.events.triggerEvent("added", {
│ │ │ │ │ + map: this,
│ │ │ │ │ + layer: layer
│ │ │ │ │ + });
│ │ │ │ │ + layer.afterAdd();
│ │ │ │ │ +
│ │ │ │ │ + return true;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: addUniqueValueRules
│ │ │ │ │ - * Convenience method to create comparison rules for unique values of a
│ │ │ │ │ - * property. The rules will be added to the style object for a specified
│ │ │ │ │ - * rendering intent. This method is a shortcut for creating something like
│ │ │ │ │ - * the "unique value legends" familiar from well known desktop GIS systems
│ │ │ │ │ - *
│ │ │ │ │ + * APIMethod: addLayers
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * renderIntent - {String} rendering intent to add the rules to
│ │ │ │ │ - * property - {String} values of feature attributes to create the
│ │ │ │ │ - * rules for
│ │ │ │ │ - * symbolizers - {Object} Hash of symbolizers, keyed by the desired
│ │ │ │ │ - * property values
│ │ │ │ │ - * context - {Object} An optional object with properties that
│ │ │ │ │ - * symbolizers' property values should be evaluated
│ │ │ │ │ - * against. If no context is specified, feature.attributes
│ │ │ │ │ - * will be used
│ │ │ │ │ + * layers - {Array()}
│ │ │ │ │ */
│ │ │ │ │ - addUniqueValueRules: function(renderIntent, property, symbolizers, context) {
│ │ │ │ │ - var rules = [];
│ │ │ │ │ - for (var value in symbolizers) {
│ │ │ │ │ - rules.push(new OpenLayers.Rule({
│ │ │ │ │ - symbolizer: symbolizers[value],
│ │ │ │ │ - context: context,
│ │ │ │ │ - filter: new OpenLayers.Filter.Comparison({
│ │ │ │ │ - type: OpenLayers.Filter.Comparison.EQUAL_TO,
│ │ │ │ │ - property: property,
│ │ │ │ │ - value: value
│ │ │ │ │ - })
│ │ │ │ │ - }));
│ │ │ │ │ + addLayers: function(layers) {
│ │ │ │ │ + for (var i = 0, len = layers.length; i < len; i++) {
│ │ │ │ │ + this.addLayer(layers[i]);
│ │ │ │ │ }
│ │ │ │ │ - this.styles[renderIntent].addRules(rules);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.StyleMap"
│ │ │ │ │ -});
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Icon.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: removeLayer
│ │ │ │ │ + * Removes a layer from the map by removing its visual element (the
│ │ │ │ │ + * layer.div property), then removing it from the map's internal list
│ │ │ │ │ + * of layers, setting the layer's map property to null.
│ │ │ │ │ + *
│ │ │ │ │ + * a "removelayer" event is triggered.
│ │ │ │ │ + *
│ │ │ │ │ + * very worthy of mention is that simply removing a layer from a map
│ │ │ │ │ + * will not cause the removal of any popups which may have been created
│ │ │ │ │ + * by the layer. this is due to the fact that it was decided at some
│ │ │ │ │ + * point that popups would not belong to layers. thus there is no way
│ │ │ │ │ + * for us to know here to which layer the popup belongs.
│ │ │ │ │ + *
│ │ │ │ │ + * A simple solution to this is simply to call destroy() on the layer.
│ │ │ │ │ + * the default OpenLayers.Layer class's destroy() function
│ │ │ │ │ + * automatically takes care to remove itself from whatever map it has
│ │ │ │ │ + * been attached to.
│ │ │ │ │ + *
│ │ │ │ │ + * The correct solution is for the layer itself to register an
│ │ │ │ │ + * event-handler on "removelayer" and when it is called, if it
│ │ │ │ │ + * recognizes itself as the layer being removed, then it cycles through
│ │ │ │ │ + * its own personal list of popups, removing them from the map.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * layer - {}
│ │ │ │ │ + * setNewBaseLayer - {Boolean} Default is true
│ │ │ │ │ + */
│ │ │ │ │ + removeLayer: function(layer, setNewBaseLayer) {
│ │ │ │ │ + if (this.events.triggerEvent("preremovelayer", {
│ │ │ │ │ + layer: layer
│ │ │ │ │ + }) === false) {
│ │ │ │ │ + return;
│ │ │ │ │ + }
│ │ │ │ │ + if (setNewBaseLayer == null) {
│ │ │ │ │ + setNewBaseLayer = true;
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ + if (layer.isFixed) {
│ │ │ │ │ + this.viewPortDiv.removeChild(layer.div);
│ │ │ │ │ + } else {
│ │ │ │ │ + this.layerContainerDiv.removeChild(layer.div);
│ │ │ │ │ + }
│ │ │ │ │ + OpenLayers.Util.removeItem(this.layers, layer);
│ │ │ │ │ + layer.removeMap(this);
│ │ │ │ │ + layer.map = null;
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ - */
│ │ │ │ │ + // if we removed the base layer, need to set a new one
│ │ │ │ │ + if (this.baseLayer == layer) {
│ │ │ │ │ + this.baseLayer = null;
│ │ │ │ │ + if (setNewBaseLayer) {
│ │ │ │ │ + for (var i = 0, len = this.layers.length; i < len; i++) {
│ │ │ │ │ + var iLayer = this.layers[i];
│ │ │ │ │ + if (iLayer.isBaseLayer || this.allOverlays) {
│ │ │ │ │ + this.setBaseLayer(iLayer);
│ │ │ │ │ + break;
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Icon
│ │ │ │ │ - *
│ │ │ │ │ - * The icon represents a graphical icon on the screen. Typically used in
│ │ │ │ │ - * conjunction with a to represent markers on a screen.
│ │ │ │ │ - *
│ │ │ │ │ - * An icon has a url, size and position. It also contains an offset which
│ │ │ │ │ - * allows the center point to be represented correctly. This can be
│ │ │ │ │ - * provided either as a fixed offset or a function provided to calculate
│ │ │ │ │ - * the desired offset.
│ │ │ │ │ - *
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Icon = OpenLayers.Class({
│ │ │ │ │ + this.resetLayersZIndex();
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: url
│ │ │ │ │ - * {String} image url
│ │ │ │ │ - */
│ │ │ │ │ - url: null,
│ │ │ │ │ + this.events.triggerEvent("removelayer", {
│ │ │ │ │ + layer: layer
│ │ │ │ │ + });
│ │ │ │ │ + layer.events.triggerEvent("removed", {
│ │ │ │ │ + map: this,
│ │ │ │ │ + layer: layer
│ │ │ │ │ + });
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: size
│ │ │ │ │ - * {|Object} An OpenLayers.Size or
│ │ │ │ │ - * an object with a 'w' and 'h' properties.
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: getNumLayers
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Int} The number of layers attached to the map.
│ │ │ │ │ */
│ │ │ │ │ - size: null,
│ │ │ │ │ + getNumLayers: function() {
│ │ │ │ │ + return this.layers.length;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: offset
│ │ │ │ │ - * {|Object} distance in pixels to offset the
│ │ │ │ │ - * image when being rendered. An OpenLayers.Pixel or an object
│ │ │ │ │ - * with a 'x' and 'y' properties.
│ │ │ │ │ + * APIMethod: getLayerIndex
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * layer - {}
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Integer} The current (zero-based) index of the given layer in the map's
│ │ │ │ │ + * layer stack. Returns -1 if the layer isn't on the map.
│ │ │ │ │ */
│ │ │ │ │ - offset: null,
│ │ │ │ │ + getLayerIndex: function(layer) {
│ │ │ │ │ + return OpenLayers.Util.indexOf(this.layers, layer);
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: calculateOffset
│ │ │ │ │ - * {Function} Function to calculate the offset (based on the size)
│ │ │ │ │ + * APIMethod: setLayerIndex
│ │ │ │ │ + * Move the given layer to the specified (zero-based) index in the layer
│ │ │ │ │ + * list, changing its z-index in the map display. Use
│ │ │ │ │ + * map.getLayerIndex() to find out the current index of a layer. Note
│ │ │ │ │ + * that this cannot (or at least should not) be effectively used to
│ │ │ │ │ + * raise base layers above overlays.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * layer - {}
│ │ │ │ │ + * idx - {int}
│ │ │ │ │ */
│ │ │ │ │ - calculateOffset: null,
│ │ │ │ │ + setLayerIndex: function(layer, idx) {
│ │ │ │ │ + var base = this.getLayerIndex(layer);
│ │ │ │ │ + if (idx < 0) {
│ │ │ │ │ + idx = 0;
│ │ │ │ │ + } else if (idx > this.layers.length) {
│ │ │ │ │ + idx = this.layers.length;
│ │ │ │ │ + }
│ │ │ │ │ + if (base != idx) {
│ │ │ │ │ + this.layers.splice(base, 1);
│ │ │ │ │ + this.layers.splice(idx, 0, layer);
│ │ │ │ │ + for (var i = 0, len = this.layers.length; i < len; i++) {
│ │ │ │ │ + this.setLayerZIndex(this.layers[i], i);
│ │ │ │ │ + }
│ │ │ │ │ + this.events.triggerEvent("changelayer", {
│ │ │ │ │ + layer: layer,
│ │ │ │ │ + property: "order"
│ │ │ │ │ + });
│ │ │ │ │ + if (this.allOverlays) {
│ │ │ │ │ + if (idx === 0) {
│ │ │ │ │ + this.setBaseLayer(layer);
│ │ │ │ │ + } else if (this.baseLayer !== this.layers[0]) {
│ │ │ │ │ + this.setBaseLayer(this.layers[0]);
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: imageDiv
│ │ │ │ │ - * {DOMElement}
│ │ │ │ │ + * APIMethod: raiseLayer
│ │ │ │ │ + * Change the index of the given layer by delta. If delta is positive,
│ │ │ │ │ + * the layer is moved up the map's layer stack; if delta is negative,
│ │ │ │ │ + * the layer is moved down. Again, note that this cannot (or at least
│ │ │ │ │ + * should not) be effectively used to raise base layers above overlays.
│ │ │ │ │ + *
│ │ │ │ │ + * Paremeters:
│ │ │ │ │ + * layer - {}
│ │ │ │ │ + * delta - {int}
│ │ │ │ │ */
│ │ │ │ │ - imageDiv: null,
│ │ │ │ │ + raiseLayer: function(layer, delta) {
│ │ │ │ │ + var idx = this.getLayerIndex(layer) + delta;
│ │ │ │ │ + this.setLayerIndex(layer, idx);
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: px
│ │ │ │ │ - * {|Object} An OpenLayers.Pixel or an object
│ │ │ │ │ - * with a 'x' and 'y' properties.
│ │ │ │ │ + * APIMethod: setBaseLayer
│ │ │ │ │ + * Allows user to specify one of the currently-loaded layers as the Map's
│ │ │ │ │ + * new base layer.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * newBaseLayer - {}
│ │ │ │ │ */
│ │ │ │ │ - px: null,
│ │ │ │ │ + setBaseLayer: function(newBaseLayer) {
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Icon
│ │ │ │ │ - * Creates an icon, which is an image tag in a div.
│ │ │ │ │ - *
│ │ │ │ │ - * url - {String}
│ │ │ │ │ - * size - {|Object} An OpenLayers.Size or an
│ │ │ │ │ - * object with a 'w' and 'h'
│ │ │ │ │ - * properties.
│ │ │ │ │ - * offset - {|Object} An OpenLayers.Pixel or an
│ │ │ │ │ - * object with a 'x' and 'y'
│ │ │ │ │ - * properties.
│ │ │ │ │ - * calculateOffset - {Function}
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(url, size, offset, calculateOffset) {
│ │ │ │ │ - this.url = url;
│ │ │ │ │ - this.size = size || {
│ │ │ │ │ - w: 20,
│ │ │ │ │ - h: 20
│ │ │ │ │ - };
│ │ │ │ │ - this.offset = offset || {
│ │ │ │ │ - x: -(this.size.w / 2),
│ │ │ │ │ - y: -(this.size.h / 2)
│ │ │ │ │ - };
│ │ │ │ │ - this.calculateOffset = calculateOffset;
│ │ │ │ │ + if (newBaseLayer != this.baseLayer) {
│ │ │ │ │
│ │ │ │ │ - var id = OpenLayers.Util.createUniqueID("OL_Icon_");
│ │ │ │ │ - this.imageDiv = OpenLayers.Util.createAlphaImageDiv(id);
│ │ │ │ │ - },
│ │ │ │ │ + // ensure newBaseLayer is already loaded
│ │ │ │ │ + if (OpenLayers.Util.indexOf(this.layers, newBaseLayer) != -1) {
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: destroy
│ │ │ │ │ - * Nullify references and remove event listeners to prevent circular
│ │ │ │ │ - * references and memory leaks
│ │ │ │ │ - */
│ │ │ │ │ - destroy: function() {
│ │ │ │ │ - // erase any drawn elements
│ │ │ │ │ - this.erase();
│ │ │ │ │ + // preserve center and scale when changing base layers
│ │ │ │ │ + var center = this.getCachedCenter();
│ │ │ │ │ + var newResolution = OpenLayers.Util.getResolutionFromScale(
│ │ │ │ │ + this.getScale(), newBaseLayer.units
│ │ │ │ │ + );
│ │ │ │ │
│ │ │ │ │ - OpenLayers.Event.stopObservingElement(this.imageDiv.firstChild);
│ │ │ │ │ - this.imageDiv.innerHTML = "";
│ │ │ │ │ - this.imageDiv = null;
│ │ │ │ │ + // make the old base layer invisible
│ │ │ │ │ + if (this.baseLayer != null && !this.allOverlays) {
│ │ │ │ │ + this.baseLayer.setVisibility(false);
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + // set new baselayer
│ │ │ │ │ + this.baseLayer = newBaseLayer;
│ │ │ │ │ +
│ │ │ │ │ + if (!this.allOverlays || this.baseLayer.visibility) {
│ │ │ │ │ + this.baseLayer.setVisibility(true);
│ │ │ │ │ + // Layer may previously have been visible but not in range.
│ │ │ │ │ + // In this case we need to redraw it to make it visible.
│ │ │ │ │ + if (this.baseLayer.inRange === false) {
│ │ │ │ │ + this.baseLayer.redraw();
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + // recenter the map
│ │ │ │ │ + if (center != null) {
│ │ │ │ │ + // new zoom level derived from old scale
│ │ │ │ │ + var newZoom = this.getZoomForResolution(
│ │ │ │ │ + newResolution || this.resolution, true
│ │ │ │ │ + );
│ │ │ │ │ + // zoom and force zoom change
│ │ │ │ │ + this.setCenter(center, newZoom, false, true);
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + this.events.triggerEvent("changebaselayer", {
│ │ │ │ │ + layer: this.baseLayer
│ │ │ │ │ + });
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: clone
│ │ │ │ │ +
│ │ │ │ │ + /********************************************************/
│ │ │ │ │ + /* */
│ │ │ │ │ + /* Control Functions */
│ │ │ │ │ + /* */
│ │ │ │ │ + /* The following functions deal with adding and */
│ │ │ │ │ + /* removing Controls to and from the Map */
│ │ │ │ │ + /* */
│ │ │ │ │ + /********************************************************/
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: addControl
│ │ │ │ │ + * Add the passed over control to the map. Optionally
│ │ │ │ │ + * position the control at the given pixel.
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} A fresh copy of the icon.
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * control - {}
│ │ │ │ │ + * px - {}
│ │ │ │ │ */
│ │ │ │ │ - clone: function() {
│ │ │ │ │ - return new OpenLayers.Icon(this.url,
│ │ │ │ │ - this.size,
│ │ │ │ │ - this.offset,
│ │ │ │ │ - this.calculateOffset);
│ │ │ │ │ + addControl: function(control, px) {
│ │ │ │ │ + this.controls.push(control);
│ │ │ │ │ + this.addControlToMap(control, px);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: setSize
│ │ │ │ │ - *
│ │ │ │ │ + * APIMethod: addControls
│ │ │ │ │ + * Add all of the passed over controls to the map.
│ │ │ │ │ + * You can pass over an optional second array
│ │ │ │ │ + * with pixel-objects to position the controls.
│ │ │ │ │ + * The indices of the two arrays should match and
│ │ │ │ │ + * you can add null as pixel for those controls
│ │ │ │ │ + * you want to be autopositioned.
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * size - {|Object} An OpenLayers.Size or
│ │ │ │ │ - * an object with a 'w' and 'h' properties.
│ │ │ │ │ + * controls - {Array()}
│ │ │ │ │ + * pixels - {Array()}
│ │ │ │ │ */
│ │ │ │ │ - setSize: function(size) {
│ │ │ │ │ - if (size != null) {
│ │ │ │ │ - this.size = size;
│ │ │ │ │ + addControls: function(controls, pixels) {
│ │ │ │ │ + var pxs = (arguments.length === 1) ? [] : pixels;
│ │ │ │ │ + for (var i = 0, len = controls.length; i < len; i++) {
│ │ │ │ │ + var ctrl = controls[i];
│ │ │ │ │ + var px = (pxs[i]) ? pxs[i] : null;
│ │ │ │ │ + this.addControl(ctrl, px);
│ │ │ │ │ }
│ │ │ │ │ - this.draw();
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: setUrl
│ │ │ │ │ + * Method: addControlToMap
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * url - {String}
│ │ │ │ │ + *
│ │ │ │ │ + * control - {}
│ │ │ │ │ + * px - {}
│ │ │ │ │ */
│ │ │ │ │ - setUrl: function(url) {
│ │ │ │ │ - if (url != null) {
│ │ │ │ │ - this.url = url;
│ │ │ │ │ + addControlToMap: function(control, px) {
│ │ │ │ │ + // If a control doesn't have a div at this point, it belongs in the
│ │ │ │ │ + // viewport.
│ │ │ │ │ + control.outsideViewport = (control.div != null);
│ │ │ │ │ +
│ │ │ │ │ + // If the map has a displayProjection, and the control doesn't, set
│ │ │ │ │ + // the display projection.
│ │ │ │ │ + if (this.displayProjection && !control.displayProjection) {
│ │ │ │ │ + control.displayProjection = this.displayProjection;
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + control.setMap(this);
│ │ │ │ │ + var div = control.draw(px);
│ │ │ │ │ + if (div) {
│ │ │ │ │ + if (!control.outsideViewport) {
│ │ │ │ │ + div.style.zIndex = this.Z_INDEX_BASE['Control'] +
│ │ │ │ │ + this.controls.length;
│ │ │ │ │ + this.viewPortDiv.appendChild(div);
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + if (control.autoActivate) {
│ │ │ │ │ + control.activate();
│ │ │ │ │ }
│ │ │ │ │ - this.draw();
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: draw
│ │ │ │ │ - * Move the div to the given pixel.
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: getControl
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * px - {|Object} An OpenLayers.Pixel or an
│ │ │ │ │ - * object with a 'x' and 'y' properties.
│ │ │ │ │ + * id - {String} ID of the control to return.
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {DOMElement} A new DOM Image of this icon set at the location passed-in
│ │ │ │ │ + * {} The control from the map's list of controls
│ │ │ │ │ + * which has a matching 'id'. If none found,
│ │ │ │ │ + * returns null.
│ │ │ │ │ */
│ │ │ │ │ - draw: function(px) {
│ │ │ │ │ - OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv,
│ │ │ │ │ - null,
│ │ │ │ │ - null,
│ │ │ │ │ - this.size,
│ │ │ │ │ - this.url,
│ │ │ │ │ - "absolute");
│ │ │ │ │ - this.moveTo(px);
│ │ │ │ │ - return this.imageDiv;
│ │ │ │ │ + getControl: function(id) {
│ │ │ │ │ + var returnControl = null;
│ │ │ │ │ + for (var i = 0, len = this.controls.length; i < len; i++) {
│ │ │ │ │ + var control = this.controls[i];
│ │ │ │ │ + if (control.id == id) {
│ │ │ │ │ + returnControl = control;
│ │ │ │ │ + break;
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + return returnControl;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: erase
│ │ │ │ │ - * Erase the underlying image element.
│ │ │ │ │ + * APIMethod: removeControl
│ │ │ │ │ + * Remove a control from the map. Removes the control both from the map
│ │ │ │ │ + * object's internal array of controls, as well as from the map's
│ │ │ │ │ + * viewPort (assuming the control was not added outsideViewport)
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * control - {} The control to remove.
│ │ │ │ │ */
│ │ │ │ │ - erase: function() {
│ │ │ │ │ - if (this.imageDiv != null && this.imageDiv.parentNode != null) {
│ │ │ │ │ - OpenLayers.Element.remove(this.imageDiv);
│ │ │ │ │ + removeControl: function(control) {
│ │ │ │ │ + //make sure control is non-null and actually part of our map
│ │ │ │ │ + if ((control) && (control == this.getControl(control.id))) {
│ │ │ │ │ + if (control.div && (control.div.parentNode == this.viewPortDiv)) {
│ │ │ │ │ + this.viewPortDiv.removeChild(control.div);
│ │ │ │ │ + }
│ │ │ │ │ + OpenLayers.Util.removeItem(this.controls, control);
│ │ │ │ │ }
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ + /********************************************************/
│ │ │ │ │ + /* */
│ │ │ │ │ + /* Popup Functions */
│ │ │ │ │ + /* */
│ │ │ │ │ + /* The following functions deal with adding and */
│ │ │ │ │ + /* removing Popups to and from the Map */
│ │ │ │ │ + /* */
│ │ │ │ │ + /********************************************************/
│ │ │ │ │ +
│ │ │ │ │ /**
│ │ │ │ │ - * Method: setOpacity
│ │ │ │ │ - * Change the icon's opacity
│ │ │ │ │ - *
│ │ │ │ │ + * APIMethod: addPopup
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * opacity - {float}
│ │ │ │ │ + * popup - {}
│ │ │ │ │ + * exclusive - {Boolean} If true, closes all other popups first
│ │ │ │ │ */
│ │ │ │ │ - setOpacity: function(opacity) {
│ │ │ │ │ - OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv, null, null, null,
│ │ │ │ │ - null, null, null, null, opacity);
│ │ │ │ │ -
│ │ │ │ │ - },
│ │ │ │ │ + addPopup: function(popup, exclusive) {
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: moveTo
│ │ │ │ │ - * move icon to passed in px.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * px - {|Object} the pixel position to move to.
│ │ │ │ │ - * An OpenLayers.Pixel or an object with a 'x' and 'y' properties.
│ │ │ │ │ - */
│ │ │ │ │ - moveTo: function(px) {
│ │ │ │ │ - //if no px passed in, use stored location
│ │ │ │ │ - if (px != null) {
│ │ │ │ │ - this.px = px;
│ │ │ │ │ + if (exclusive) {
│ │ │ │ │ + //remove all other popups from screen
│ │ │ │ │ + for (var i = this.popups.length - 1; i >= 0; --i) {
│ │ │ │ │ + this.removePopup(this.popups[i]);
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │
│ │ │ │ │ - if (this.imageDiv != null) {
│ │ │ │ │ - if (this.px == null) {
│ │ │ │ │ - this.display(false);
│ │ │ │ │ - } else {
│ │ │ │ │ - if (this.calculateOffset) {
│ │ │ │ │ - this.offset = this.calculateOffset(this.size);
│ │ │ │ │ - }
│ │ │ │ │ - OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv, null, {
│ │ │ │ │ - x: this.px.x + this.offset.x,
│ │ │ │ │ - y: this.px.y + this.offset.y
│ │ │ │ │ - });
│ │ │ │ │ - }
│ │ │ │ │ + popup.map = this;
│ │ │ │ │ + this.popups.push(popup);
│ │ │ │ │ + var popupDiv = popup.draw();
│ │ │ │ │ + if (popupDiv) {
│ │ │ │ │ + popupDiv.style.zIndex = this.Z_INDEX_BASE['Popup'] +
│ │ │ │ │ + this.popups.length;
│ │ │ │ │ + this.layerContainerDiv.appendChild(popupDiv);
│ │ │ │ │ }
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: display
│ │ │ │ │ - * Hide or show the icon
│ │ │ │ │ - *
│ │ │ │ │ + * APIMethod: removePopup
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * display - {Boolean}
│ │ │ │ │ + * popup - {}
│ │ │ │ │ */
│ │ │ │ │ - display: function(display) {
│ │ │ │ │ - this.imageDiv.style.display = (display) ? "" : "none";
│ │ │ │ │ + removePopup: function(popup) {
│ │ │ │ │ + OpenLayers.Util.removeItem(this.popups, popup);
│ │ │ │ │ + if (popup.div) {
│ │ │ │ │ + try {
│ │ │ │ │ + this.layerContainerDiv.removeChild(popup.div);
│ │ │ │ │ + } catch (e) {} // Popups sometimes apparently get disconnected
│ │ │ │ │ + // from the layerContainerDiv, and cause complaints.
│ │ │ │ │ + }
│ │ │ │ │ + popup.map = null;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ + /********************************************************/
│ │ │ │ │ + /* */
│ │ │ │ │ + /* Container Div Functions */
│ │ │ │ │ + /* */
│ │ │ │ │ + /* The following functions deal with the access to */
│ │ │ │ │ + /* and maintenance of the size of the container div */
│ │ │ │ │ + /* */
│ │ │ │ │ + /********************************************************/
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: isDrawn
│ │ │ │ │ + * APIMethod: getSize
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Boolean} Whether or not the icon is drawn.
│ │ │ │ │ + * {} An object that represents the
│ │ │ │ │ + * size, in pixels, of the div into which OpenLayers
│ │ │ │ │ + * has been loaded.
│ │ │ │ │ + * Note - A clone() of this locally cached variable is
│ │ │ │ │ + * returned, so as not to allow users to modify it.
│ │ │ │ │ */
│ │ │ │ │ - isDrawn: function() {
│ │ │ │ │ - // nodeType 11 for ie, whose nodes *always* have a parentNode
│ │ │ │ │ - // (of type document fragment)
│ │ │ │ │ - var isDrawn = (this.imageDiv && this.imageDiv.parentNode &&
│ │ │ │ │ - (this.imageDiv.parentNode.nodeType != 11));
│ │ │ │ │ -
│ │ │ │ │ - return isDrawn;
│ │ │ │ │ + getSize: function() {
│ │ │ │ │ + var size = null;
│ │ │ │ │ + if (this.size != null) {
│ │ │ │ │ + size = this.size.clone();
│ │ │ │ │ + }
│ │ │ │ │ + return size;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Icon"
│ │ │ │ │ -});
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Marker.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ - * @requires OpenLayers/Events.js
│ │ │ │ │ - * @requires OpenLayers/Icon.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Marker
│ │ │ │ │ - * Instances of OpenLayers.Marker are a combination of a
│ │ │ │ │ - * and an .
│ │ │ │ │ - *
│ │ │ │ │ - * Markers are generally added to a special layer called
│ │ │ │ │ - * .
│ │ │ │ │ - *
│ │ │ │ │ - * Example:
│ │ │ │ │ - * (code)
│ │ │ │ │ - * var markers = new OpenLayers.Layer.Markers( "Markers" );
│ │ │ │ │ - * map.addLayer(markers);
│ │ │ │ │ - *
│ │ │ │ │ - * var size = new OpenLayers.Size(21,25);
│ │ │ │ │ - * var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
│ │ │ │ │ - * var icon = new OpenLayers.Icon('http://www.openlayers.org/dev/img/marker.png', size, offset);
│ │ │ │ │ - * markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0,0),icon));
│ │ │ │ │ - * markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0,0),icon.clone()));
│ │ │ │ │ - *
│ │ │ │ │ - * (end)
│ │ │ │ │ - *
│ │ │ │ │ - * Note that if you pass an icon into the Marker constructor, it will take
│ │ │ │ │ - * that icon and use it. This means that you should not share icons between
│ │ │ │ │ - * markers -- you use them once, but you should clone() for any additional
│ │ │ │ │ - * markers using that same icon.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Marker = OpenLayers.Class({
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: icon
│ │ │ │ │ - * {} The icon used by this marker.
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: updateSize
│ │ │ │ │ + * This function should be called by any external code which dynamically
│ │ │ │ │ + * changes the size of the map div (because mozilla wont let us catch
│ │ │ │ │ + * the "onresize" for an element)
│ │ │ │ │ */
│ │ │ │ │ - icon: null,
│ │ │ │ │ + updateSize: function() {
│ │ │ │ │ + // the div might have moved on the page, also
│ │ │ │ │ + var newSize = this.getCurrentSize();
│ │ │ │ │ + if (newSize && !isNaN(newSize.h) && !isNaN(newSize.w)) {
│ │ │ │ │ + this.events.clearMouseCache();
│ │ │ │ │ + var oldSize = this.getSize();
│ │ │ │ │ + if (oldSize == null) {
│ │ │ │ │ + this.size = oldSize = newSize;
│ │ │ │ │ + }
│ │ │ │ │ + if (!newSize.equals(oldSize)) {
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: lonlat
│ │ │ │ │ - * {} location of object
│ │ │ │ │ - */
│ │ │ │ │ - lonlat: null,
│ │ │ │ │ + // store the new size
│ │ │ │ │ + this.size = newSize;
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: events
│ │ │ │ │ - * {} the event handler.
│ │ │ │ │ - */
│ │ │ │ │ - events: null,
│ │ │ │ │ + //notify layers of mapresize
│ │ │ │ │ + for (var i = 0, len = this.layers.length; i < len; i++) {
│ │ │ │ │ + this.layers[i].onMapResize();
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: map
│ │ │ │ │ - * {} the map this marker is attached to
│ │ │ │ │ - */
│ │ │ │ │ - map: null,
│ │ │ │ │ + var center = this.getCachedCenter();
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Marker
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * lonlat - {} the position of this marker
│ │ │ │ │ - * icon - {} the icon for this marker
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(lonlat, icon) {
│ │ │ │ │ - this.lonlat = lonlat;
│ │ │ │ │ + if (this.baseLayer != null && center != null) {
│ │ │ │ │ + var zoom = this.getZoom();
│ │ │ │ │ + this.zoom = null;
│ │ │ │ │ + this.setCenter(center, zoom);
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - var newIcon = (icon) ? icon : OpenLayers.Marker.defaultIcon();
│ │ │ │ │ - if (this.icon == null) {
│ │ │ │ │ - this.icon = newIcon;
│ │ │ │ │ - } else {
│ │ │ │ │ - this.icon.url = newIcon.url;
│ │ │ │ │ - this.icon.size = newIcon.size;
│ │ │ │ │ - this.icon.offset = newIcon.offset;
│ │ │ │ │ - this.icon.calculateOffset = newIcon.calculateOffset;
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ - this.events = new OpenLayers.Events(this, this.icon.imageDiv);
│ │ │ │ │ + this.events.triggerEvent("updatesize");
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: destroy
│ │ │ │ │ - * Destroy the marker. You must first remove the marker from any
│ │ │ │ │ - * layer which it has been added to, or you will get buggy behavior.
│ │ │ │ │ - * (This can not be done within the marker since the marker does not
│ │ │ │ │ - * know which layer it is attached to.)
│ │ │ │ │ + * Method: getCurrentSize
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {} A new object with the dimensions
│ │ │ │ │ + * of the map div
│ │ │ │ │ */
│ │ │ │ │ - destroy: function() {
│ │ │ │ │ - // erase any drawn features
│ │ │ │ │ - this.erase();
│ │ │ │ │ -
│ │ │ │ │ - this.map = null;
│ │ │ │ │ + getCurrentSize: function() {
│ │ │ │ │
│ │ │ │ │ - this.events.destroy();
│ │ │ │ │ - this.events = null;
│ │ │ │ │ + var size = new OpenLayers.Size(this.div.clientWidth,
│ │ │ │ │ + this.div.clientHeight);
│ │ │ │ │
│ │ │ │ │ - if (this.icon != null) {
│ │ │ │ │ - this.icon.destroy();
│ │ │ │ │ - this.icon = null;
│ │ │ │ │ + if (size.w == 0 && size.h == 0 || isNaN(size.w) && isNaN(size.h)) {
│ │ │ │ │ + size.w = this.div.offsetWidth;
│ │ │ │ │ + size.h = this.div.offsetHeight;
│ │ │ │ │ + }
│ │ │ │ │ + if (size.w == 0 && size.h == 0 || isNaN(size.w) && isNaN(size.h)) {
│ │ │ │ │ + size.w = parseInt(this.div.style.width);
│ │ │ │ │ + size.h = parseInt(this.div.style.height);
│ │ │ │ │ }
│ │ │ │ │ + return size;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: draw
│ │ │ │ │ - * Calls draw on the icon, and returns that output.
│ │ │ │ │ + * Method: calculateBounds
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * px - {}
│ │ │ │ │ + * center - {} Default is this.getCenter()
│ │ │ │ │ + * resolution - {float} Default is this.getResolution()
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {DOMElement} A new DOM Image with this marker's icon set at the
│ │ │ │ │ - * location passed-in
│ │ │ │ │ + * {} A bounds based on resolution, center, and
│ │ │ │ │ + * current mapsize.
│ │ │ │ │ */
│ │ │ │ │ - draw: function(px) {
│ │ │ │ │ - return this.icon.draw(px);
│ │ │ │ │ - },
│ │ │ │ │ + calculateBounds: function(center, resolution) {
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: erase
│ │ │ │ │ - * Erases any drawn elements for this marker.
│ │ │ │ │ - */
│ │ │ │ │ - erase: function() {
│ │ │ │ │ - if (this.icon != null) {
│ │ │ │ │ - this.icon.erase();
│ │ │ │ │ + var extent = null;
│ │ │ │ │ +
│ │ │ │ │ + if (center == null) {
│ │ │ │ │ + center = this.getCachedCenter();
│ │ │ │ │ + }
│ │ │ │ │ + if (resolution == null) {
│ │ │ │ │ + resolution = this.getResolution();
│ │ │ │ │ }
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: moveTo
│ │ │ │ │ - * Move the marker to the new location.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * px - {|Object} the pixel position to move to.
│ │ │ │ │ - * An OpenLayers.Pixel or an object with a 'x' and 'y' properties.
│ │ │ │ │ - */
│ │ │ │ │ - moveTo: function(px) {
│ │ │ │ │ - if ((px != null) && (this.icon != null)) {
│ │ │ │ │ - this.icon.moveTo(px);
│ │ │ │ │ + if ((center != null) && (resolution != null)) {
│ │ │ │ │ + var halfWDeg = (this.size.w * resolution) / 2;
│ │ │ │ │ + var halfHDeg = (this.size.h * resolution) / 2;
│ │ │ │ │ +
│ │ │ │ │ + extent = new OpenLayers.Bounds(center.lon - halfWDeg,
│ │ │ │ │ + center.lat - halfHDeg,
│ │ │ │ │ + center.lon + halfWDeg,
│ │ │ │ │ + center.lat + halfHDeg);
│ │ │ │ │ }
│ │ │ │ │ - this.lonlat = this.map.getLonLatFromLayerPx(px);
│ │ │ │ │ +
│ │ │ │ │ + return extent;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ +
│ │ │ │ │ + /********************************************************/
│ │ │ │ │ + /* */
│ │ │ │ │ + /* Zoom, Center, Pan Functions */
│ │ │ │ │ + /* */
│ │ │ │ │ + /* The following functions handle the validation, */
│ │ │ │ │ + /* getting and setting of the Zoom Level and Center */
│ │ │ │ │ + /* as well as the panning of the Map */
│ │ │ │ │ + /* */
│ │ │ │ │ + /********************************************************/
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: isDrawn
│ │ │ │ │ + * APIMethod: getCenter
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Boolean} Whether or not the marker is drawn.
│ │ │ │ │ + * {}
│ │ │ │ │ */
│ │ │ │ │ - isDrawn: function() {
│ │ │ │ │ - var isDrawn = (this.icon && this.icon.isDrawn());
│ │ │ │ │ - return isDrawn;
│ │ │ │ │ + getCenter: function() {
│ │ │ │ │ + var center = null;
│ │ │ │ │ + var cachedCenter = this.getCachedCenter();
│ │ │ │ │ + if (cachedCenter) {
│ │ │ │ │ + center = cachedCenter.clone();
│ │ │ │ │ + }
│ │ │ │ │ + return center;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: onScreen
│ │ │ │ │ + * Method: getCachedCenter
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Boolean} Whether or not the marker is currently visible on screen.
│ │ │ │ │ + * {}
│ │ │ │ │ */
│ │ │ │ │ - onScreen: function() {
│ │ │ │ │ -
│ │ │ │ │ - var onScreen = false;
│ │ │ │ │ - if (this.map) {
│ │ │ │ │ - var screenBounds = this.map.getExtent();
│ │ │ │ │ - onScreen = screenBounds.containsLonLat(this.lonlat);
│ │ │ │ │ + getCachedCenter: function() {
│ │ │ │ │ + if (!this.center && this.size) {
│ │ │ │ │ + this.center = this.getLonLatFromViewPortPx({
│ │ │ │ │ + x: this.size.w / 2,
│ │ │ │ │ + y: this.size.h / 2
│ │ │ │ │ + });
│ │ │ │ │ }
│ │ │ │ │ - return onScreen;
│ │ │ │ │ + return this.center;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: inflate
│ │ │ │ │ - * Englarges the markers icon by the specified ratio.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * inflate - {float} the ratio to enlarge the marker by (passing 2
│ │ │ │ │ - * will double the size).
│ │ │ │ │ - */
│ │ │ │ │ - inflate: function(inflate) {
│ │ │ │ │ - if (this.icon) {
│ │ │ │ │ - this.icon.setSize({
│ │ │ │ │ - w: this.icon.size.w * inflate,
│ │ │ │ │ - h: this.icon.size.h * inflate
│ │ │ │ │ - });
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: setOpacity
│ │ │ │ │ - * Change the opacity of the marker by changin the opacity of
│ │ │ │ │ - * its icon
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * opacity - {float} Specified as fraction (0.4, etc)
│ │ │ │ │ - */
│ │ │ │ │ - setOpacity: function(opacity) {
│ │ │ │ │ - this.icon.setOpacity(opacity);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: setUrl
│ │ │ │ │ - * Change URL of the Icon Image.
│ │ │ │ │ - *
│ │ │ │ │ - * url - {String}
│ │ │ │ │ - */
│ │ │ │ │ - setUrl: function(url) {
│ │ │ │ │ - this.icon.setUrl(url);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: display
│ │ │ │ │ - * Hide or show the icon
│ │ │ │ │ - *
│ │ │ │ │ - * display - {Boolean}
│ │ │ │ │ - */
│ │ │ │ │ - display: function(display) {
│ │ │ │ │ - this.icon.display(display);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Marker"
│ │ │ │ │ -});
│ │ │ │ │ -
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Function: defaultIcon
│ │ │ │ │ - * Creates a default .
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} A default OpenLayers.Icon to use for a marker
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Marker.defaultIcon = function() {
│ │ │ │ │ - return new OpenLayers.Icon(OpenLayers.Util.getImageLocation("marker.png"), {
│ │ │ │ │ - w: 21,
│ │ │ │ │ - h: 25
│ │ │ │ │ - }, {
│ │ │ │ │ - x: -10.5,
│ │ │ │ │ - y: -25
│ │ │ │ │ - });
│ │ │ │ │ -};
│ │ │ │ │ -
│ │ │ │ │ -
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Request/XMLHttpRequest.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -// XMLHttpRequest.js Copyright (C) 2010 Sergey Ilinsky (http://www.ilinsky.com)
│ │ │ │ │ -//
│ │ │ │ │ -// Licensed under the Apache License, Version 2.0 (the "License");
│ │ │ │ │ -// you may not use this file except in compliance with the License.
│ │ │ │ │ -// You may obtain a copy of the License at
│ │ │ │ │ -//
│ │ │ │ │ -// http://www.apache.org/licenses/LICENSE-2.0
│ │ │ │ │ -//
│ │ │ │ │ -// Unless required by applicable law or agreed to in writing, software
│ │ │ │ │ -// distributed under the License is distributed on an "AS IS" BASIS,
│ │ │ │ │ -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
│ │ │ │ │ -// See the License for the specific language governing permissions and
│ │ │ │ │ -// limitations under the License.
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/Request.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -(function() {
│ │ │ │ │ -
│ │ │ │ │ - // Save reference to earlier defined object implementation (if any)
│ │ │ │ │ - var oXMLHttpRequest = window.XMLHttpRequest;
│ │ │ │ │ -
│ │ │ │ │ - // Define on browser type
│ │ │ │ │ - var bGecko = !!window.controllers,
│ │ │ │ │ - bIE = window.document.all && !window.opera,
│ │ │ │ │ - bIE7 = bIE && window.navigator.userAgent.match(/MSIE 7.0/);
│ │ │ │ │ -
│ │ │ │ │ - // Enables "XMLHttpRequest()" call next to "new XMLHttpReques()"
│ │ │ │ │ - function fXMLHttpRequest() {
│ │ │ │ │ - this._object = oXMLHttpRequest && !bIE7 ? new oXMLHttpRequest : new window.ActiveXObject("Microsoft.XMLHTTP");
│ │ │ │ │ - this._listeners = [];
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - // Constructor
│ │ │ │ │ - function cXMLHttpRequest() {
│ │ │ │ │ - return new fXMLHttpRequest;
│ │ │ │ │ - };
│ │ │ │ │ - cXMLHttpRequest.prototype = fXMLHttpRequest.prototype;
│ │ │ │ │ -
│ │ │ │ │ - // BUGFIX: Firefox with Firebug installed would break pages if not executed
│ │ │ │ │ - if (bGecko && oXMLHttpRequest.wrapped)
│ │ │ │ │ - cXMLHttpRequest.wrapped = oXMLHttpRequest.wrapped;
│ │ │ │ │ -
│ │ │ │ │ - // Constants
│ │ │ │ │ - cXMLHttpRequest.UNSENT = 0;
│ │ │ │ │ - cXMLHttpRequest.OPENED = 1;
│ │ │ │ │ - cXMLHttpRequest.HEADERS_RECEIVED = 2;
│ │ │ │ │ - cXMLHttpRequest.LOADING = 3;
│ │ │ │ │ - cXMLHttpRequest.DONE = 4;
│ │ │ │ │ -
│ │ │ │ │ - // Public Properties
│ │ │ │ │ - cXMLHttpRequest.prototype.readyState = cXMLHttpRequest.UNSENT;
│ │ │ │ │ - cXMLHttpRequest.prototype.responseText = '';
│ │ │ │ │ - cXMLHttpRequest.prototype.responseXML = null;
│ │ │ │ │ - cXMLHttpRequest.prototype.status = 0;
│ │ │ │ │ - cXMLHttpRequest.prototype.statusText = '';
│ │ │ │ │ -
│ │ │ │ │ - // Priority proposal
│ │ │ │ │ - cXMLHttpRequest.prototype.priority = "NORMAL";
│ │ │ │ │ -
│ │ │ │ │ - // Instance-level Events Handlers
│ │ │ │ │ - cXMLHttpRequest.prototype.onreadystatechange = null;
│ │ │ │ │ -
│ │ │ │ │ - // Class-level Events Handlers
│ │ │ │ │ - cXMLHttpRequest.onreadystatechange = null;
│ │ │ │ │ - cXMLHttpRequest.onopen = null;
│ │ │ │ │ - cXMLHttpRequest.onsend = null;
│ │ │ │ │ - cXMLHttpRequest.onabort = null;
│ │ │ │ │ -
│ │ │ │ │ - // Public Methods
│ │ │ │ │ - cXMLHttpRequest.prototype.open = function(sMethod, sUrl, bAsync, sUser, sPassword) {
│ │ │ │ │ - // Delete headers, required when object is reused
│ │ │ │ │ - delete this._headers;
│ │ │ │ │ -
│ │ │ │ │ - // When bAsync parameter value is omitted, use true as default
│ │ │ │ │ - if (arguments.length < 3)
│ │ │ │ │ - bAsync = true;
│ │ │ │ │ -
│ │ │ │ │ - // Save async parameter for fixing Gecko bug with missing readystatechange in synchronous requests
│ │ │ │ │ - this._async = bAsync;
│ │ │ │ │ -
│ │ │ │ │ - // Set the onreadystatechange handler
│ │ │ │ │ - var oRequest = this,
│ │ │ │ │ - nState = this.readyState,
│ │ │ │ │ - fOnUnload;
│ │ │ │ │ -
│ │ │ │ │ - // BUGFIX: IE - memory leak on page unload (inter-page leak)
│ │ │ │ │ - if (bIE && bAsync) {
│ │ │ │ │ - fOnUnload = function() {
│ │ │ │ │ - if (nState != cXMLHttpRequest.DONE) {
│ │ │ │ │ - fCleanTransport(oRequest);
│ │ │ │ │ - // Safe to abort here since onreadystatechange handler removed
│ │ │ │ │ - oRequest.abort();
│ │ │ │ │ - }
│ │ │ │ │ - };
│ │ │ │ │ - window.attachEvent("onunload", fOnUnload);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // Add method sniffer
│ │ │ │ │ - if (cXMLHttpRequest.onopen)
│ │ │ │ │ - cXMLHttpRequest.onopen.apply(this, arguments);
│ │ │ │ │ -
│ │ │ │ │ - if (arguments.length > 4)
│ │ │ │ │ - this._object.open(sMethod, sUrl, bAsync, sUser, sPassword);
│ │ │ │ │ - else
│ │ │ │ │ - if (arguments.length > 3)
│ │ │ │ │ - this._object.open(sMethod, sUrl, bAsync, sUser);
│ │ │ │ │ - else
│ │ │ │ │ - this._object.open(sMethod, sUrl, bAsync);
│ │ │ │ │ -
│ │ │ │ │ - this.readyState = cXMLHttpRequest.OPENED;
│ │ │ │ │ - fReadyStateChange(this);
│ │ │ │ │ -
│ │ │ │ │ - this._object.onreadystatechange = function() {
│ │ │ │ │ - if (bGecko && !bAsync)
│ │ │ │ │ - return;
│ │ │ │ │ -
│ │ │ │ │ - // Synchronize state
│ │ │ │ │ - oRequest.readyState = oRequest._object.readyState;
│ │ │ │ │ -
│ │ │ │ │ - //
│ │ │ │ │ - fSynchronizeValues(oRequest);
│ │ │ │ │ -
│ │ │ │ │ - // BUGFIX: Firefox fires unnecessary DONE when aborting
│ │ │ │ │ - if (oRequest._aborted) {
│ │ │ │ │ - // Reset readyState to UNSENT
│ │ │ │ │ - oRequest.readyState = cXMLHttpRequest.UNSENT;
│ │ │ │ │ -
│ │ │ │ │ - // Return now
│ │ │ │ │ - return;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - if (oRequest.readyState == cXMLHttpRequest.DONE) {
│ │ │ │ │ - // Free up queue
│ │ │ │ │ - delete oRequest._data;
│ │ │ │ │ - /* if (bAsync)
│ │ │ │ │ - fQueue_remove(oRequest);*/
│ │ │ │ │ - //
│ │ │ │ │ - fCleanTransport(oRequest);
│ │ │ │ │ - // Uncomment this block if you need a fix for IE cache
│ │ │ │ │ - /*
│ │ │ │ │ - // BUGFIX: IE - cache issue
│ │ │ │ │ - if (!oRequest._object.getResponseHeader("Date")) {
│ │ │ │ │ - // Save object to cache
│ │ │ │ │ - oRequest._cached = oRequest._object;
│ │ │ │ │ -
│ │ │ │ │ - // Instantiate a new transport object
│ │ │ │ │ - cXMLHttpRequest.call(oRequest);
│ │ │ │ │ -
│ │ │ │ │ - // Re-send request
│ │ │ │ │ - if (sUser) {
│ │ │ │ │ - if (sPassword)
│ │ │ │ │ - oRequest._object.open(sMethod, sUrl, bAsync, sUser, sPassword);
│ │ │ │ │ - else
│ │ │ │ │ - oRequest._object.open(sMethod, sUrl, bAsync, sUser);
│ │ │ │ │ - }
│ │ │ │ │ - else
│ │ │ │ │ - oRequest._object.open(sMethod, sUrl, bAsync);
│ │ │ │ │ - oRequest._object.setRequestHeader("If-Modified-Since", oRequest._cached.getResponseHeader("Last-Modified") || new window.Date(0));
│ │ │ │ │ - // Copy headers set
│ │ │ │ │ - if (oRequest._headers)
│ │ │ │ │ - for (var sHeader in oRequest._headers)
│ │ │ │ │ - if (typeof oRequest._headers[sHeader] == "string") // Some frameworks prototype objects with functions
│ │ │ │ │ - oRequest._object.setRequestHeader(sHeader, oRequest._headers[sHeader]);
│ │ │ │ │ -
│ │ │ │ │ - oRequest._object.onreadystatechange = function() {
│ │ │ │ │ - // Synchronize state
│ │ │ │ │ - oRequest.readyState = oRequest._object.readyState;
│ │ │ │ │ -
│ │ │ │ │ - if (oRequest._aborted) {
│ │ │ │ │ - //
│ │ │ │ │ - oRequest.readyState = cXMLHttpRequest.UNSENT;
│ │ │ │ │ -
│ │ │ │ │ - // Return
│ │ │ │ │ - return;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - if (oRequest.readyState == cXMLHttpRequest.DONE) {
│ │ │ │ │ - // Clean Object
│ │ │ │ │ - fCleanTransport(oRequest);
│ │ │ │ │ -
│ │ │ │ │ - // get cached request
│ │ │ │ │ - if (oRequest.status == 304)
│ │ │ │ │ - oRequest._object = oRequest._cached;
│ │ │ │ │ -
│ │ │ │ │ - //
│ │ │ │ │ - delete oRequest._cached;
│ │ │ │ │ -
│ │ │ │ │ - //
│ │ │ │ │ - fSynchronizeValues(oRequest);
│ │ │ │ │ -
│ │ │ │ │ - //
│ │ │ │ │ - fReadyStateChange(oRequest);
│ │ │ │ │ -
│ │ │ │ │ - // BUGFIX: IE - memory leak in interrupted
│ │ │ │ │ - if (bIE && bAsync)
│ │ │ │ │ - window.detachEvent("onunload", fOnUnload);
│ │ │ │ │ - }
│ │ │ │ │ - };
│ │ │ │ │ - oRequest._object.send(null);
│ │ │ │ │ -
│ │ │ │ │ - // Return now - wait until re-sent request is finished
│ │ │ │ │ - return;
│ │ │ │ │ - };
│ │ │ │ │ - */
│ │ │ │ │ - // BUGFIX: IE - memory leak in interrupted
│ │ │ │ │ - if (bIE && bAsync)
│ │ │ │ │ - window.detachEvent("onunload", fOnUnload);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // BUGFIX: Some browsers (Internet Explorer, Gecko) fire OPEN readystate twice
│ │ │ │ │ - if (nState != oRequest.readyState)
│ │ │ │ │ - fReadyStateChange(oRequest);
│ │ │ │ │ -
│ │ │ │ │ - nState = oRequest.readyState;
│ │ │ │ │ - }
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - function fXMLHttpRequest_send(oRequest) {
│ │ │ │ │ - oRequest._object.send(oRequest._data);
│ │ │ │ │ -
│ │ │ │ │ - // BUGFIX: Gecko - missing readystatechange calls in synchronous requests
│ │ │ │ │ - if (bGecko && !oRequest._async) {
│ │ │ │ │ - oRequest.readyState = cXMLHttpRequest.OPENED;
│ │ │ │ │ -
│ │ │ │ │ - // Synchronize state
│ │ │ │ │ - fSynchronizeValues(oRequest);
│ │ │ │ │ -
│ │ │ │ │ - // Simulate missing states
│ │ │ │ │ - while (oRequest.readyState < cXMLHttpRequest.DONE) {
│ │ │ │ │ - oRequest.readyState++;
│ │ │ │ │ - fReadyStateChange(oRequest);
│ │ │ │ │ - // Check if we are aborted
│ │ │ │ │ - if (oRequest._aborted)
│ │ │ │ │ - return;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - };
│ │ │ │ │ - cXMLHttpRequest.prototype.send = function(vData) {
│ │ │ │ │ - // Add method sniffer
│ │ │ │ │ - if (cXMLHttpRequest.onsend)
│ │ │ │ │ - cXMLHttpRequest.onsend.apply(this, arguments);
│ │ │ │ │ -
│ │ │ │ │ - if (!arguments.length)
│ │ │ │ │ - vData = null;
│ │ │ │ │ -
│ │ │ │ │ - // BUGFIX: Safari - fails sending documents created/modified dynamically, so an explicit serialization required
│ │ │ │ │ - // BUGFIX: IE - rewrites any custom mime-type to "text/xml" in case an XMLNode is sent
│ │ │ │ │ - // BUGFIX: Gecko - fails sending Element (this is up to the implementation either to standard)
│ │ │ │ │ - if (vData && vData.nodeType) {
│ │ │ │ │ - vData = window.XMLSerializer ? new window.XMLSerializer().serializeToString(vData) : vData.xml;
│ │ │ │ │ - if (!this._headers["Content-Type"])
│ │ │ │ │ - this._object.setRequestHeader("Content-Type", "application/xml");
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - this._data = vData;
│ │ │ │ │ - /*
│ │ │ │ │ - // Add to queue
│ │ │ │ │ - if (this._async)
│ │ │ │ │ - fQueue_add(this);
│ │ │ │ │ - else*/
│ │ │ │ │ - fXMLHttpRequest_send(this);
│ │ │ │ │ - };
│ │ │ │ │ - cXMLHttpRequest.prototype.abort = function() {
│ │ │ │ │ - // Add method sniffer
│ │ │ │ │ - if (cXMLHttpRequest.onabort)
│ │ │ │ │ - cXMLHttpRequest.onabort.apply(this, arguments);
│ │ │ │ │ -
│ │ │ │ │ - // BUGFIX: Gecko - unnecessary DONE when aborting
│ │ │ │ │ - if (this.readyState > cXMLHttpRequest.UNSENT)
│ │ │ │ │ - this._aborted = true;
│ │ │ │ │ -
│ │ │ │ │ - this._object.abort();
│ │ │ │ │ -
│ │ │ │ │ - // BUGFIX: IE - memory leak
│ │ │ │ │ - fCleanTransport(this);
│ │ │ │ │ -
│ │ │ │ │ - this.readyState = cXMLHttpRequest.UNSENT;
│ │ │ │ │ -
│ │ │ │ │ - delete this._data;
│ │ │ │ │ - /* if (this._async)
│ │ │ │ │ - fQueue_remove(this);*/
│ │ │ │ │ - };
│ │ │ │ │ - cXMLHttpRequest.prototype.getAllResponseHeaders = function() {
│ │ │ │ │ - return this._object.getAllResponseHeaders();
│ │ │ │ │ - };
│ │ │ │ │ - cXMLHttpRequest.prototype.getResponseHeader = function(sName) {
│ │ │ │ │ - return this._object.getResponseHeader(sName);
│ │ │ │ │ - };
│ │ │ │ │ - cXMLHttpRequest.prototype.setRequestHeader = function(sName, sValue) {
│ │ │ │ │ - // BUGFIX: IE - cache issue
│ │ │ │ │ - if (!this._headers)
│ │ │ │ │ - this._headers = {};
│ │ │ │ │ - this._headers[sName] = sValue;
│ │ │ │ │ -
│ │ │ │ │ - return this._object.setRequestHeader(sName, sValue);
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - // EventTarget interface implementation
│ │ │ │ │ - cXMLHttpRequest.prototype.addEventListener = function(sName, fHandler, bUseCapture) {
│ │ │ │ │ - for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++)
│ │ │ │ │ - if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture)
│ │ │ │ │ - return;
│ │ │ │ │ - // Add listener
│ │ │ │ │ - this._listeners.push([sName, fHandler, bUseCapture]);
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - cXMLHttpRequest.prototype.removeEventListener = function(sName, fHandler, bUseCapture) {
│ │ │ │ │ - for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++)
│ │ │ │ │ - if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture)
│ │ │ │ │ - break;
│ │ │ │ │ - // Remove listener
│ │ │ │ │ - if (oListener)
│ │ │ │ │ - this._listeners.splice(nIndex, 1);
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - cXMLHttpRequest.prototype.dispatchEvent = function(oEvent) {
│ │ │ │ │ - var oEventPseudo = {
│ │ │ │ │ - 'type': oEvent.type,
│ │ │ │ │ - 'target': this,
│ │ │ │ │ - 'currentTarget': this,
│ │ │ │ │ - 'eventPhase': 2,
│ │ │ │ │ - 'bubbles': oEvent.bubbles,
│ │ │ │ │ - 'cancelable': oEvent.cancelable,
│ │ │ │ │ - 'timeStamp': oEvent.timeStamp,
│ │ │ │ │ - 'stopPropagation': function() {}, // There is no flow
│ │ │ │ │ - 'preventDefault': function() {}, // There is no default action
│ │ │ │ │ - 'initEvent': function() {} // Original event object should be initialized
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - // Execute onreadystatechange
│ │ │ │ │ - if (oEventPseudo.type == "readystatechange" && this.onreadystatechange)
│ │ │ │ │ - (this.onreadystatechange.handleEvent || this.onreadystatechange).apply(this, [oEventPseudo]);
│ │ │ │ │ -
│ │ │ │ │ - // Execute listeners
│ │ │ │ │ - for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++)
│ │ │ │ │ - if (oListener[0] == oEventPseudo.type && !oListener[2])
│ │ │ │ │ - (oListener[1].handleEvent || oListener[1]).apply(this, [oEventPseudo]);
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - //
│ │ │ │ │ - cXMLHttpRequest.prototype.toString = function() {
│ │ │ │ │ - return '[' + "object" + ' ' + "XMLHttpRequest" + ']';
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - cXMLHttpRequest.toString = function() {
│ │ │ │ │ - return '[' + "XMLHttpRequest" + ']';
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - // Helper function
│ │ │ │ │ - function fReadyStateChange(oRequest) {
│ │ │ │ │ - // Sniffing code
│ │ │ │ │ - if (cXMLHttpRequest.onreadystatechange)
│ │ │ │ │ - cXMLHttpRequest.onreadystatechange.apply(oRequest);
│ │ │ │ │ -
│ │ │ │ │ - // Fake event
│ │ │ │ │ - oRequest.dispatchEvent({
│ │ │ │ │ - 'type': "readystatechange",
│ │ │ │ │ - 'bubbles': false,
│ │ │ │ │ - 'cancelable': false,
│ │ │ │ │ - 'timeStamp': new Date + 0
│ │ │ │ │ - });
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - function fGetDocument(oRequest) {
│ │ │ │ │ - var oDocument = oRequest.responseXML,
│ │ │ │ │ - sResponse = oRequest.responseText;
│ │ │ │ │ - // Try parsing responseText
│ │ │ │ │ - if (bIE && sResponse && oDocument && !oDocument.documentElement && oRequest.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/)) {
│ │ │ │ │ - oDocument = new window.ActiveXObject("Microsoft.XMLDOM");
│ │ │ │ │ - oDocument.async = false;
│ │ │ │ │ - oDocument.validateOnParse = false;
│ │ │ │ │ - oDocument.loadXML(sResponse);
│ │ │ │ │ - }
│ │ │ │ │ - // Check if there is no error in document
│ │ │ │ │ - if (oDocument)
│ │ │ │ │ - if ((bIE && oDocument.parseError != 0) || !oDocument.documentElement || (oDocument.documentElement && oDocument.documentElement.tagName == "parsererror"))
│ │ │ │ │ - return null;
│ │ │ │ │ - return oDocument;
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - function fSynchronizeValues(oRequest) {
│ │ │ │ │ - try {
│ │ │ │ │ - oRequest.responseText = oRequest._object.responseText;
│ │ │ │ │ - } catch (e) {}
│ │ │ │ │ - try {
│ │ │ │ │ - oRequest.responseXML = fGetDocument(oRequest._object);
│ │ │ │ │ - } catch (e) {}
│ │ │ │ │ - try {
│ │ │ │ │ - oRequest.status = oRequest._object.status;
│ │ │ │ │ - } catch (e) {}
│ │ │ │ │ - try {
│ │ │ │ │ - oRequest.statusText = oRequest._object.statusText;
│ │ │ │ │ - } catch (e) {}
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - function fCleanTransport(oRequest) {
│ │ │ │ │ - // BUGFIX: IE - memory leak (on-page leak)
│ │ │ │ │ - oRequest._object.onreadystatechange = new window.Function;
│ │ │ │ │ - };
│ │ │ │ │ - /*
│ │ │ │ │ - // Queue manager
│ │ │ │ │ - var oQueuePending = {"CRITICAL":[],"HIGH":[],"NORMAL":[],"LOW":[],"LOWEST":[]},
│ │ │ │ │ - aQueueRunning = [];
│ │ │ │ │ - function fQueue_add(oRequest) {
│ │ │ │ │ - oQueuePending[oRequest.priority in oQueuePending ? oRequest.priority : "NORMAL"].push(oRequest);
│ │ │ │ │ - //
│ │ │ │ │ - setTimeout(fQueue_process);
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - function fQueue_remove(oRequest) {
│ │ │ │ │ - for (var nIndex = 0, bFound = false; nIndex < aQueueRunning.length; nIndex++)
│ │ │ │ │ - if (bFound)
│ │ │ │ │ - aQueueRunning[nIndex - 1] = aQueueRunning[nIndex];
│ │ │ │ │ - else
│ │ │ │ │ - if (aQueueRunning[nIndex] == oRequest)
│ │ │ │ │ - bFound = true;
│ │ │ │ │ - if (bFound)
│ │ │ │ │ - aQueueRunning.length--;
│ │ │ │ │ - //
│ │ │ │ │ - setTimeout(fQueue_process);
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - function fQueue_process() {
│ │ │ │ │ - if (aQueueRunning.length < 6) {
│ │ │ │ │ - for (var sPriority in oQueuePending) {
│ │ │ │ │ - if (oQueuePending[sPriority].length) {
│ │ │ │ │ - var oRequest = oQueuePending[sPriority][0];
│ │ │ │ │ - oQueuePending[sPriority] = oQueuePending[sPriority].slice(1);
│ │ │ │ │ - //
│ │ │ │ │ - aQueueRunning.push(oRequest);
│ │ │ │ │ - // Send request
│ │ │ │ │ - fXMLHttpRequest_send(oRequest);
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - };
│ │ │ │ │ - */
│ │ │ │ │ - // Internet Explorer 5.0 (missing apply)
│ │ │ │ │ - if (!window.Function.prototype.apply) {
│ │ │ │ │ - window.Function.prototype.apply = function(oRequest, oArguments) {
│ │ │ │ │ - if (!oArguments)
│ │ │ │ │ - oArguments = [];
│ │ │ │ │ - oRequest.__func = this;
│ │ │ │ │ - oRequest.__func(oArguments[0], oArguments[1], oArguments[2], oArguments[3], oArguments[4]);
│ │ │ │ │ - delete oRequest.__func;
│ │ │ │ │ - };
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - // Register new object with window
│ │ │ │ │ - /**
│ │ │ │ │ - * Class: OpenLayers.Request.XMLHttpRequest
│ │ │ │ │ - * Standard-compliant (W3C) cross-browser implementation of the
│ │ │ │ │ - * XMLHttpRequest object. From
│ │ │ │ │ - * http://code.google.com/p/xmlhttprequest/.
│ │ │ │ │ - */
│ │ │ │ │ - if (!OpenLayers.Request) {
│ │ │ │ │ - /**
│ │ │ │ │ - * This allows for OpenLayers/Request.js to be included
│ │ │ │ │ - * before or after this script.
│ │ │ │ │ - */
│ │ │ │ │ - OpenLayers.Request = {};
│ │ │ │ │ - }
│ │ │ │ │ - OpenLayers.Request.XMLHttpRequest = cXMLHttpRequest;
│ │ │ │ │ -})();
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Request.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/Events.js
│ │ │ │ │ - * @requires OpenLayers/Request/XMLHttpRequest.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * TODO: deprecate me
│ │ │ │ │ - * Use OpenLayers.Request.proxy instead.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.ProxyHost = "";
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Namespace: OpenLayers.Request
│ │ │ │ │ - * The OpenLayers.Request namespace contains convenience methods for working
│ │ │ │ │ - * with XMLHttpRequests. These methods work with a cross-browser
│ │ │ │ │ - * W3C compliant class.
│ │ │ │ │ - */
│ │ │ │ │ -if (!OpenLayers.Request) {
│ │ │ │ │ - /**
│ │ │ │ │ - * This allows for OpenLayers/Request/XMLHttpRequest.js to be included
│ │ │ │ │ - * before or after this script.
│ │ │ │ │ - */
│ │ │ │ │ - OpenLayers.Request = {};
│ │ │ │ │ -}
│ │ │ │ │ -OpenLayers.Util.extend(OpenLayers.Request, {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constant: DEFAULT_CONFIG
│ │ │ │ │ - * {Object} Default configuration for all requests.
│ │ │ │ │ - */
│ │ │ │ │ - DEFAULT_CONFIG: {
│ │ │ │ │ - method: "GET",
│ │ │ │ │ - url: window.location.href,
│ │ │ │ │ - async: true,
│ │ │ │ │ - user: undefined,
│ │ │ │ │ - password: undefined,
│ │ │ │ │ - params: null,
│ │ │ │ │ - proxy: OpenLayers.ProxyHost,
│ │ │ │ │ - headers: {},
│ │ │ │ │ - data: null,
│ │ │ │ │ - callback: function() {},
│ │ │ │ │ - success: null,
│ │ │ │ │ - failure: null,
│ │ │ │ │ - scope: null
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constant: URL_SPLIT_REGEX
│ │ │ │ │ - */
│ │ │ │ │ - URL_SPLIT_REGEX: /([^:]*:)\/\/([^:]*:?[^@]*@)?([^:\/\?]*):?([^\/\?]*)/,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: events
│ │ │ │ │ - * {} An events object that handles all
│ │ │ │ │ - * events on the {} object.
│ │ │ │ │ - *
│ │ │ │ │ - * All event listeners will receive an event object with three properties:
│ │ │ │ │ - * request - {} The request object.
│ │ │ │ │ - * config - {Object} The config object sent to the specific request method.
│ │ │ │ │ - * requestUrl - {String} The request url.
│ │ │ │ │ - *
│ │ │ │ │ - * Supported event types:
│ │ │ │ │ - * complete - Triggered when we have a response from the request, if a
│ │ │ │ │ - * listener returns false, no further response processing will take
│ │ │ │ │ - * place.
│ │ │ │ │ - * success - Triggered when the HTTP response has a success code (200-299).
│ │ │ │ │ - * failure - Triggered when the HTTP response does not have a success code.
│ │ │ │ │ - */
│ │ │ │ │ - events: new OpenLayers.Events(this),
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: makeSameOrigin
│ │ │ │ │ - * Using the specified proxy, returns a same origin url of the provided url.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * url - {String} An arbitrary url
│ │ │ │ │ - * proxy {String|Function} The proxy to use to make the provided url a
│ │ │ │ │ - * same origin url.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns
│ │ │ │ │ - * {String} the same origin url. If no proxy is provided, the returned url
│ │ │ │ │ - * will be the same as the provided url.
│ │ │ │ │ - */
│ │ │ │ │ - makeSameOrigin: function(url, proxy) {
│ │ │ │ │ - var sameOrigin = url.indexOf("http") !== 0;
│ │ │ │ │ - var urlParts = !sameOrigin && url.match(this.URL_SPLIT_REGEX);
│ │ │ │ │ - if (urlParts) {
│ │ │ │ │ - var location = window.location;
│ │ │ │ │ - sameOrigin =
│ │ │ │ │ - urlParts[1] == location.protocol &&
│ │ │ │ │ - urlParts[3] == location.hostname;
│ │ │ │ │ - var uPort = urlParts[4],
│ │ │ │ │ - lPort = location.port;
│ │ │ │ │ - if (uPort != 80 && uPort != "" || lPort != "80" && lPort != "") {
│ │ │ │ │ - sameOrigin = sameOrigin && uPort == lPort;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - if (!sameOrigin) {
│ │ │ │ │ - if (proxy) {
│ │ │ │ │ - if (typeof proxy == "function") {
│ │ │ │ │ - url = proxy(url);
│ │ │ │ │ - } else {
│ │ │ │ │ - url = proxy + encodeURIComponent(url);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return url;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: issue
│ │ │ │ │ - * Create a new XMLHttpRequest object, open it, set any headers, bind
│ │ │ │ │ - * a callback to done state, and send any data. It is recommended that
│ │ │ │ │ - * you use one , , , , , or .
│ │ │ │ │ - * This method is only documented to provide detail on the configuration
│ │ │ │ │ - * options available to all request methods.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * config - {Object} Object containing properties for configuring the
│ │ │ │ │ - * request. Allowed configuration properties are described below.
│ │ │ │ │ - * This object is modified and should not be reused.
│ │ │ │ │ - *
│ │ │ │ │ - * Allowed config properties:
│ │ │ │ │ - * method - {String} One of GET, POST, PUT, DELETE, HEAD, or
│ │ │ │ │ - * OPTIONS. Default is GET.
│ │ │ │ │ - * url - {String} URL for the request.
│ │ │ │ │ - * async - {Boolean} Open an asynchronous request. Default is true.
│ │ │ │ │ - * user - {String} User for relevant authentication scheme. Set
│ │ │ │ │ - * to null to clear current user.
│ │ │ │ │ - * password - {String} Password for relevant authentication scheme.
│ │ │ │ │ - * Set to null to clear current password.
│ │ │ │ │ - * proxy - {String} Optional proxy. Defaults to
│ │ │ │ │ - * .
│ │ │ │ │ - * params - {Object} Any key:value pairs to be appended to the
│ │ │ │ │ - * url as a query string. Assumes url doesn't already include a query
│ │ │ │ │ - * string or hash. Typically, this is only appropriate for
│ │ │ │ │ - * requests where the query string will be appended to the url.
│ │ │ │ │ - * Parameter values that are arrays will be
│ │ │ │ │ - * concatenated with a comma (note that this goes against form-encoding)
│ │ │ │ │ - * as is done with .
│ │ │ │ │ - * headers - {Object} Object with header:value pairs to be set on
│ │ │ │ │ - * the request.
│ │ │ │ │ - * data - {String | Document} Optional data to send with the request.
│ │ │ │ │ - * Typically, this is only used with and requests.
│ │ │ │ │ - * Make sure to provide the appropriate "Content-Type" header for your
│ │ │ │ │ - * data. For and requests, the content type defaults to
│ │ │ │ │ - * "application-xml". If your data is a different content type, or
│ │ │ │ │ - * if you are using a different HTTP method, set the "Content-Type"
│ │ │ │ │ - * header to match your data type.
│ │ │ │ │ - * callback - {Function} Function to call when request is done.
│ │ │ │ │ - * To determine if the request failed, check request.status (200
│ │ │ │ │ - * indicates success).
│ │ │ │ │ - * success - {Function} Optional function to call if request status is in
│ │ │ │ │ - * the 200s. This will be called in addition to callback above and
│ │ │ │ │ - * would typically only be used as an alternative.
│ │ │ │ │ - * failure - {Function} Optional function to call if request status is not
│ │ │ │ │ - * in the 200s. This will be called in addition to callback above and
│ │ │ │ │ - * would typically only be used as an alternative.
│ │ │ │ │ - * scope - {Object} If callback is a public method on some object,
│ │ │ │ │ - * set the scope to that object.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {XMLHttpRequest} Request object. To abort the request before a response
│ │ │ │ │ - * is received, call abort() on the request object.
│ │ │ │ │ - */
│ │ │ │ │ - issue: function(config) {
│ │ │ │ │ - // apply default config - proxy host may have changed
│ │ │ │ │ - var defaultConfig = OpenLayers.Util.extend(
│ │ │ │ │ - this.DEFAULT_CONFIG, {
│ │ │ │ │ - proxy: OpenLayers.ProxyHost
│ │ │ │ │ - }
│ │ │ │ │ - );
│ │ │ │ │ - config = config || {};
│ │ │ │ │ - config.headers = config.headers || {};
│ │ │ │ │ - config = OpenLayers.Util.applyDefaults(config, defaultConfig);
│ │ │ │ │ - config.headers = OpenLayers.Util.applyDefaults(config.headers, defaultConfig.headers);
│ │ │ │ │ - // Always set the "X-Requested-With" header to signal that this request
│ │ │ │ │ - // was issued through the XHR-object. Since header keys are case
│ │ │ │ │ - // insensitive and we want to allow overriding of the "X-Requested-With"
│ │ │ │ │ - // header through the user we cannot use applyDefaults, but have to
│ │ │ │ │ - // check manually whether we were called with a "X-Requested-With"
│ │ │ │ │ - // header.
│ │ │ │ │ - var customRequestedWithHeader = false,
│ │ │ │ │ - headerKey;
│ │ │ │ │ - for (headerKey in config.headers) {
│ │ │ │ │ - if (config.headers.hasOwnProperty(headerKey)) {
│ │ │ │ │ - if (headerKey.toLowerCase() === 'x-requested-with') {
│ │ │ │ │ - customRequestedWithHeader = true;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - if (customRequestedWithHeader === false) {
│ │ │ │ │ - // we did not have a custom "X-Requested-With" header
│ │ │ │ │ - config.headers['X-Requested-With'] = 'XMLHttpRequest';
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // create request, open, and set headers
│ │ │ │ │ - var request = new OpenLayers.Request.XMLHttpRequest();
│ │ │ │ │ - var url = OpenLayers.Util.urlAppend(config.url,
│ │ │ │ │ - OpenLayers.Util.getParameterString(config.params || {}));
│ │ │ │ │ - url = OpenLayers.Request.makeSameOrigin(url, config.proxy);
│ │ │ │ │ - request.open(
│ │ │ │ │ - config.method, url, config.async, config.user, config.password
│ │ │ │ │ - );
│ │ │ │ │ - for (var header in config.headers) {
│ │ │ │ │ - request.setRequestHeader(header, config.headers[header]);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - var events = this.events;
│ │ │ │ │ -
│ │ │ │ │ - // we want to execute runCallbacks with "this" as the
│ │ │ │ │ - // execution scope
│ │ │ │ │ - var self = this;
│ │ │ │ │ -
│ │ │ │ │ - request.onreadystatechange = function() {
│ │ │ │ │ - if (request.readyState == OpenLayers.Request.XMLHttpRequest.DONE) {
│ │ │ │ │ - var proceed = events.triggerEvent(
│ │ │ │ │ - "complete", {
│ │ │ │ │ - request: request,
│ │ │ │ │ - config: config,
│ │ │ │ │ - requestUrl: url
│ │ │ │ │ - }
│ │ │ │ │ - );
│ │ │ │ │ - if (proceed !== false) {
│ │ │ │ │ - self.runCallbacks({
│ │ │ │ │ - request: request,
│ │ │ │ │ - config: config,
│ │ │ │ │ - requestUrl: url
│ │ │ │ │ - });
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - // send request (optionally with data) and return
│ │ │ │ │ - // call in a timeout for asynchronous requests so the return is
│ │ │ │ │ - // available before readyState == 4 for cached docs
│ │ │ │ │ - if (config.async === false) {
│ │ │ │ │ - request.send(config.data);
│ │ │ │ │ - } else {
│ │ │ │ │ - window.setTimeout(function() {
│ │ │ │ │ - if (request.readyState !== 0) { // W3C: 0-UNSENT
│ │ │ │ │ - request.send(config.data);
│ │ │ │ │ - }
│ │ │ │ │ - }, 0);
│ │ │ │ │ - }
│ │ │ │ │ - return request;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: runCallbacks
│ │ │ │ │ - * Calls the complete, success and failure callbacks. Application
│ │ │ │ │ - * can listen to the "complete" event, have the listener
│ │ │ │ │ - * display a confirm window and always return false, and
│ │ │ │ │ - * execute OpenLayers.Request.runCallbacks if the user
│ │ │ │ │ - * hits "yes" in the confirm window.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * options - {Object} Hash containing request, config and requestUrl keys
│ │ │ │ │ - */
│ │ │ │ │ - runCallbacks: function(options) {
│ │ │ │ │ - var request = options.request;
│ │ │ │ │ - var config = options.config;
│ │ │ │ │ -
│ │ │ │ │ - // bind callbacks to readyState 4 (done)
│ │ │ │ │ - var complete = (config.scope) ?
│ │ │ │ │ - OpenLayers.Function.bind(config.callback, config.scope) :
│ │ │ │ │ - config.callback;
│ │ │ │ │ -
│ │ │ │ │ - // optional success callback
│ │ │ │ │ - var success;
│ │ │ │ │ - if (config.success) {
│ │ │ │ │ - success = (config.scope) ?
│ │ │ │ │ - OpenLayers.Function.bind(config.success, config.scope) :
│ │ │ │ │ - config.success;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // optional failure callback
│ │ │ │ │ - var failure;
│ │ │ │ │ - if (config.failure) {
│ │ │ │ │ - failure = (config.scope) ?
│ │ │ │ │ - OpenLayers.Function.bind(config.failure, config.scope) :
│ │ │ │ │ - config.failure;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - if (OpenLayers.Util.createUrlObject(config.url).protocol == "file:" &&
│ │ │ │ │ - request.responseText) {
│ │ │ │ │ - request.status = 200;
│ │ │ │ │ - }
│ │ │ │ │ - complete(request);
│ │ │ │ │ -
│ │ │ │ │ - if (!request.status || (request.status >= 200 && request.status < 300)) {
│ │ │ │ │ - this.events.triggerEvent("success", options);
│ │ │ │ │ - if (success) {
│ │ │ │ │ - success(request);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - if (request.status && (request.status < 200 || request.status >= 300)) {
│ │ │ │ │ - this.events.triggerEvent("failure", options);
│ │ │ │ │ - if (failure) {
│ │ │ │ │ - failure(request);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: GET
│ │ │ │ │ - * Send an HTTP GET request. Additional configuration properties are
│ │ │ │ │ - * documented in the method, with the method property set
│ │ │ │ │ - * to GET.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * config - {Object} Object with properties for configuring the request.
│ │ │ │ │ - * See the method for documentation of allowed properties.
│ │ │ │ │ - * This object is modified and should not be reused.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {XMLHttpRequest} Request object.
│ │ │ │ │ - */
│ │ │ │ │ - GET: function(config) {
│ │ │ │ │ - config = OpenLayers.Util.extend(config, {
│ │ │ │ │ - method: "GET"
│ │ │ │ │ - });
│ │ │ │ │ - return OpenLayers.Request.issue(config);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: POST
│ │ │ │ │ - * Send a POST request. Additional configuration properties are
│ │ │ │ │ - * documented in the method, with the method property set
│ │ │ │ │ - * to POST and "Content-Type" header set to "application/xml".
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * config - {Object} Object with properties for configuring the request.
│ │ │ │ │ - * See the method for documentation of allowed properties. The
│ │ │ │ │ - * default "Content-Type" header will be set to "application-xml" if
│ │ │ │ │ - * none is provided. This object is modified and should not be reused.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {XMLHttpRequest} Request object.
│ │ │ │ │ - */
│ │ │ │ │ - POST: function(config) {
│ │ │ │ │ - config = OpenLayers.Util.extend(config, {
│ │ │ │ │ - method: "POST"
│ │ │ │ │ - });
│ │ │ │ │ - // set content type to application/xml if it isn't already set
│ │ │ │ │ - config.headers = config.headers ? config.headers : {};
│ │ │ │ │ - if (!("CONTENT-TYPE" in OpenLayers.Util.upperCaseObject(config.headers))) {
│ │ │ │ │ - config.headers["Content-Type"] = "application/xml";
│ │ │ │ │ - }
│ │ │ │ │ - return OpenLayers.Request.issue(config);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: PUT
│ │ │ │ │ - * Send an HTTP PUT request. Additional configuration properties are
│ │ │ │ │ - * documented in the method, with the method property set
│ │ │ │ │ - * to PUT and "Content-Type" header set to "application/xml".
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * config - {Object} Object with properties for configuring the request.
│ │ │ │ │ - * See the method for documentation of allowed properties. The
│ │ │ │ │ - * default "Content-Type" header will be set to "application-xml" if
│ │ │ │ │ - * none is provided. This object is modified and should not be reused.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {XMLHttpRequest} Request object.
│ │ │ │ │ - */
│ │ │ │ │ - PUT: function(config) {
│ │ │ │ │ - config = OpenLayers.Util.extend(config, {
│ │ │ │ │ - method: "PUT"
│ │ │ │ │ - });
│ │ │ │ │ - // set content type to application/xml if it isn't already set
│ │ │ │ │ - config.headers = config.headers ? config.headers : {};
│ │ │ │ │ - if (!("CONTENT-TYPE" in OpenLayers.Util.upperCaseObject(config.headers))) {
│ │ │ │ │ - config.headers["Content-Type"] = "application/xml";
│ │ │ │ │ - }
│ │ │ │ │ - return OpenLayers.Request.issue(config);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: DELETE
│ │ │ │ │ - * Send an HTTP DELETE request. Additional configuration properties are
│ │ │ │ │ - * documented in the method, with the method property set
│ │ │ │ │ - * to DELETE.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * config - {Object} Object with properties for configuring the request.
│ │ │ │ │ - * See the method for documentation of allowed properties.
│ │ │ │ │ - * This object is modified and should not be reused.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {XMLHttpRequest} Request object.
│ │ │ │ │ - */
│ │ │ │ │ - DELETE: function(config) {
│ │ │ │ │ - config = OpenLayers.Util.extend(config, {
│ │ │ │ │ - method: "DELETE"
│ │ │ │ │ - });
│ │ │ │ │ - return OpenLayers.Request.issue(config);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: HEAD
│ │ │ │ │ - * Send an HTTP HEAD request. Additional configuration properties are
│ │ │ │ │ - * documented in the method, with the method property set
│ │ │ │ │ - * to HEAD.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * config - {Object} Object with properties for configuring the request.
│ │ │ │ │ - * See the method for documentation of allowed properties.
│ │ │ │ │ - * This object is modified and should not be reused.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {XMLHttpRequest} Request object.
│ │ │ │ │ - */
│ │ │ │ │ - HEAD: function(config) {
│ │ │ │ │ - config = OpenLayers.Util.extend(config, {
│ │ │ │ │ - method: "HEAD"
│ │ │ │ │ - });
│ │ │ │ │ - return OpenLayers.Request.issue(config);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: OPTIONS
│ │ │ │ │ - * Send an HTTP OPTIONS request. Additional configuration properties are
│ │ │ │ │ - * documented in the method, with the method property set
│ │ │ │ │ - * to OPTIONS.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * config - {Object} Object with properties for configuring the request.
│ │ │ │ │ - * See the method for documentation of allowed properties.
│ │ │ │ │ - * This object is modified and should not be reused.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {XMLHttpRequest} Request object.
│ │ │ │ │ - */
│ │ │ │ │ - OPTIONS: function(config) {
│ │ │ │ │ - config = OpenLayers.Util.extend(config, {
│ │ │ │ │ - method: "OPTIONS"
│ │ │ │ │ - });
│ │ │ │ │ - return OpenLayers.Request.issue(config);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ -});
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Format.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ - * @requires OpenLayers/Util.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Format
│ │ │ │ │ - * Base class for format reading/writing a variety of formats. Subclasses
│ │ │ │ │ - * of OpenLayers.Format are expected to have read and write methods.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Format = OpenLayers.Class({
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: options
│ │ │ │ │ - * {Object} A reference to options passed to the constructor.
│ │ │ │ │ - */
│ │ │ │ │ - options: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: externalProjection
│ │ │ │ │ - * {} When passed a externalProjection and
│ │ │ │ │ - * internalProjection, the format will reproject the geometries it
│ │ │ │ │ - * reads or writes. The externalProjection is the projection used by
│ │ │ │ │ - * the content which is passed into read or which comes out of write.
│ │ │ │ │ - * In order to reproject, a projection transformation function for the
│ │ │ │ │ - * specified projections must be available. This support may be
│ │ │ │ │ - * provided via proj4js or via a custom transformation function. See
│ │ │ │ │ - * {} for more information on
│ │ │ │ │ - * custom transformations.
│ │ │ │ │ - */
│ │ │ │ │ - externalProjection: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: internalProjection
│ │ │ │ │ - * {} When passed a externalProjection and
│ │ │ │ │ - * internalProjection, the format will reproject the geometries it
│ │ │ │ │ - * reads or writes. The internalProjection is the projection used by
│ │ │ │ │ - * the geometries which are returned by read or which are passed into
│ │ │ │ │ - * write. In order to reproject, a projection transformation function
│ │ │ │ │ - * for the specified projections must be available. This support may be
│ │ │ │ │ - * provided via proj4js or via a custom transformation function. See
│ │ │ │ │ - * {} for more information on
│ │ │ │ │ - * custom transformations.
│ │ │ │ │ - */
│ │ │ │ │ - internalProjection: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: data
│ │ │ │ │ - * {Object} When is true, this is the parsed string sent to
│ │ │ │ │ - * .
│ │ │ │ │ - */
│ │ │ │ │ - data: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: keepData
│ │ │ │ │ - * {Object} Maintain a reference () to the most recently read data.
│ │ │ │ │ - * Default is false.
│ │ │ │ │ - */
│ │ │ │ │ - keepData: false,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Format
│ │ │ │ │ - * Instances of this class are not useful. See one of the subclasses.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * options - {Object} An optional object with properties to set on the
│ │ │ │ │ - * format
│ │ │ │ │ - *
│ │ │ │ │ - * Valid options:
│ │ │ │ │ - * keepData - {Boolean} If true, upon , the data property will be
│ │ │ │ │ - * set to the parsed object (e.g. the json or xml object).
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * An instance of OpenLayers.Format
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(options) {
│ │ │ │ │ - OpenLayers.Util.extend(this, options);
│ │ │ │ │ - this.options = options;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: destroy
│ │ │ │ │ - * Clean up.
│ │ │ │ │ - */
│ │ │ │ │ - destroy: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: read
│ │ │ │ │ - * Read data from a string, and return an object whose type depends on the
│ │ │ │ │ - * subclass.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * data - {string} Data to read/parse.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * Depends on the subclass
│ │ │ │ │ - */
│ │ │ │ │ - read: function(data) {
│ │ │ │ │ - throw new Error('Read not implemented.');
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: write
│ │ │ │ │ - * Accept an object, and return a string.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * object - {Object} Object to be serialized
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} A string representation of the object.
│ │ │ │ │ - */
│ │ │ │ │ - write: function(object) {
│ │ │ │ │ - throw new Error('Write not implemented.');
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Format"
│ │ │ │ │ -});
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Util/vendorPrefix.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/SingleFile.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -OpenLayers.Util = OpenLayers.Util || {};
│ │ │ │ │ -/**
│ │ │ │ │ - * Namespace: OpenLayers.Util.vendorPrefix
│ │ │ │ │ - * A collection of utility functions to detect vendor prefixed features
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Util.vendorPrefix = (function() {
│ │ │ │ │ - "use strict";
│ │ │ │ │ -
│ │ │ │ │ - var VENDOR_PREFIXES = ["", "O", "ms", "Moz", "Webkit"],
│ │ │ │ │ - divStyle = document.createElement("div").style,
│ │ │ │ │ - cssCache = {},
│ │ │ │ │ - jsCache = {};
│ │ │ │ │ -
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Function: domToCss
│ │ │ │ │ - * Converts a upper camel case DOM style property name to a CSS property
│ │ │ │ │ - * i.e. transformOrigin -> transform-origin
│ │ │ │ │ - * or WebkitTransformOrigin -> -webkit-transform-origin
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * prefixedDom - {String} The property to convert
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} The CSS property
│ │ │ │ │ - */
│ │ │ │ │ - function domToCss(prefixedDom) {
│ │ │ │ │ - if (!prefixedDom) {
│ │ │ │ │ - return null;
│ │ │ │ │ - }
│ │ │ │ │ - return prefixedDom.
│ │ │ │ │ - replace(/([A-Z])/g, function(c) {
│ │ │ │ │ - return "-" + c.toLowerCase();
│ │ │ │ │ - }).
│ │ │ │ │ - replace(/^ms-/, "-ms-");
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: css
│ │ │ │ │ - * Detect which property is used for a CSS property
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * property - {String} The standard (unprefixed) CSS property name
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} The standard CSS property, prefixed property or null if not
│ │ │ │ │ - * supported
│ │ │ │ │ - */
│ │ │ │ │ - function css(property) {
│ │ │ │ │ - if (cssCache[property] === undefined) {
│ │ │ │ │ - var domProperty = property.
│ │ │ │ │ - replace(/(-[\s\S])/g, function(c) {
│ │ │ │ │ - return c.charAt(1).toUpperCase();
│ │ │ │ │ - });
│ │ │ │ │ - var prefixedDom = style(domProperty);
│ │ │ │ │ - cssCache[property] = domToCss(prefixedDom);
│ │ │ │ │ - }
│ │ │ │ │ - return cssCache[property];
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: js
│ │ │ │ │ - * Detect which property is used for a JS property/method
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * obj - {Object} The object to test on
│ │ │ │ │ - * property - {String} The standard (unprefixed) JS property name
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} The standard JS property, prefixed property or null if not
│ │ │ │ │ - * supported
│ │ │ │ │ - */
│ │ │ │ │ - function js(obj, property) {
│ │ │ │ │ - if (jsCache[property] === undefined) {
│ │ │ │ │ - var tmpProp,
│ │ │ │ │ - i = 0,
│ │ │ │ │ - l = VENDOR_PREFIXES.length,
│ │ │ │ │ - prefix,
│ │ │ │ │ - isStyleObj = (typeof obj.cssText !== "undefined");
│ │ │ │ │ -
│ │ │ │ │ - jsCache[property] = null;
│ │ │ │ │ - for (; i < l; i++) {
│ │ │ │ │ - prefix = VENDOR_PREFIXES[i];
│ │ │ │ │ - if (prefix) {
│ │ │ │ │ - if (!isStyleObj) {
│ │ │ │ │ - // js prefix should be lower-case, while style
│ │ │ │ │ - // properties have upper case on first character
│ │ │ │ │ - prefix = prefix.toLowerCase();
│ │ │ │ │ - }
│ │ │ │ │ - tmpProp = prefix + property.charAt(0).toUpperCase() + property.slice(1);
│ │ │ │ │ - } else {
│ │ │ │ │ - tmpProp = property;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - if (obj[tmpProp] !== undefined) {
│ │ │ │ │ - jsCache[property] = tmpProp;
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return jsCache[property];
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: style
│ │ │ │ │ - * Detect which property is used for a DOM style property
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * property - {String} The standard (unprefixed) style property name
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} The standard style property, prefixed property or null if not
│ │ │ │ │ - * supported
│ │ │ │ │ - */
│ │ │ │ │ - function style(property) {
│ │ │ │ │ - return js(divStyle, property);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - return {
│ │ │ │ │ - css: css,
│ │ │ │ │ - js: js,
│ │ │ │ │ - style: style,
│ │ │ │ │ -
│ │ │ │ │ - // used for testing
│ │ │ │ │ - cssCache: cssCache,
│ │ │ │ │ - jsCache: jsCache
│ │ │ │ │ - };
│ │ │ │ │ -}());
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Animation.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/SingleFile.js
│ │ │ │ │ - * @requires OpenLayers/Util/vendorPrefix.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Namespace: OpenLayers.Animation
│ │ │ │ │ - * A collection of utility functions for executing methods that repaint a
│ │ │ │ │ - * portion of the browser window. These methods take advantage of the
│ │ │ │ │ - * browser's scheduled repaints where requestAnimationFrame is available.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Animation = (function(window) {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: isNative
│ │ │ │ │ - * {Boolean} true if a native requestAnimationFrame function is available
│ │ │ │ │ - */
│ │ │ │ │ - var requestAnimationFrame = OpenLayers.Util.vendorPrefix.js(window, "requestAnimationFrame");
│ │ │ │ │ - var isNative = !!(requestAnimationFrame);
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Function: requestFrame
│ │ │ │ │ - * Schedule a function to be called at the next available animation frame.
│ │ │ │ │ - * Uses the native method where available. Where requestAnimationFrame is
│ │ │ │ │ - * not available, setTimeout will be called with a 16ms delay.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * callback - {Function} The function to be called at the next animation frame.
│ │ │ │ │ - * element - {DOMElement} Optional element that visually bounds the animation.
│ │ │ │ │ - */
│ │ │ │ │ - var requestFrame = (function() {
│ │ │ │ │ - var request = window[requestAnimationFrame] ||
│ │ │ │ │ - function(callback, element) {
│ │ │ │ │ - window.setTimeout(callback, 16);
│ │ │ │ │ - };
│ │ │ │ │ - // bind to window to avoid illegal invocation of native function
│ │ │ │ │ - return function(callback, element) {
│ │ │ │ │ - request.apply(window, [callback, element]);
│ │ │ │ │ - };
│ │ │ │ │ - })();
│ │ │ │ │ -
│ │ │ │ │ - // private variables for animation loops
│ │ │ │ │ - var counter = 0;
│ │ │ │ │ - var loops = {};
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Function: start
│ │ │ │ │ - * Executes a method with in series for some
│ │ │ │ │ - * duration.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * callback - {Function} The function to be called at the next animation frame.
│ │ │ │ │ - * duration - {Number} Optional duration for the loop. If not provided, the
│ │ │ │ │ - * animation loop will execute indefinitely.
│ │ │ │ │ - * element - {DOMElement} Optional element that visually bounds the animation.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Number} Identifier for the animation loop. Used to stop animations with
│ │ │ │ │ - * .
│ │ │ │ │ - */
│ │ │ │ │ - function start(callback, duration, element) {
│ │ │ │ │ - duration = duration > 0 ? duration : Number.POSITIVE_INFINITY;
│ │ │ │ │ - var id = ++counter;
│ │ │ │ │ - var start = +new Date;
│ │ │ │ │ - loops[id] = function() {
│ │ │ │ │ - if (loops[id] && +new Date - start <= duration) {
│ │ │ │ │ - callback();
│ │ │ │ │ - if (loops[id]) {
│ │ │ │ │ - requestFrame(loops[id], element);
│ │ │ │ │ - }
│ │ │ │ │ - } else {
│ │ │ │ │ - delete loops[id];
│ │ │ │ │ - }
│ │ │ │ │ - };
│ │ │ │ │ - requestFrame(loops[id], element);
│ │ │ │ │ - return id;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Function: stop
│ │ │ │ │ - * Terminates an animation loop started with .
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * id - {Number} Identifier returned from .
│ │ │ │ │ - */
│ │ │ │ │ - function stop(id) {
│ │ │ │ │ - delete loops[id];
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - return {
│ │ │ │ │ - isNative: isNative,
│ │ │ │ │ - requestFrame: requestFrame,
│ │ │ │ │ - start: start,
│ │ │ │ │ - stop: stop
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ -})(window);
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Protocol.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Protocol
│ │ │ │ │ - * Abstract vector layer protocol class. Not to be instantiated directly. Use
│ │ │ │ │ - * one of the protocol subclasses instead.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Protocol = OpenLayers.Class({
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: format
│ │ │ │ │ - * {} The format used by this protocol.
│ │ │ │ │ - */
│ │ │ │ │ - format: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: options
│ │ │ │ │ - * {Object} Any options sent to the constructor.
│ │ │ │ │ - */
│ │ │ │ │ - options: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: autoDestroy
│ │ │ │ │ - * {Boolean} The creator of the protocol can set autoDestroy to false
│ │ │ │ │ - * to fully control when the protocol is destroyed. Defaults to
│ │ │ │ │ - * true.
│ │ │ │ │ - */
│ │ │ │ │ - autoDestroy: true,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: defaultFilter
│ │ │ │ │ - * {} Optional default filter to read requests
│ │ │ │ │ - */
│ │ │ │ │ - defaultFilter: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Protocol
│ │ │ │ │ - * Abstract class for vector protocols. Create instances of a subclass.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * options - {Object} Optional object whose properties will be set on the
│ │ │ │ │ - * instance.
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(options) {
│ │ │ │ │ - options = options || {};
│ │ │ │ │ - OpenLayers.Util.extend(this, options);
│ │ │ │ │ - this.options = options;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: mergeWithDefaultFilter
│ │ │ │ │ - * Merge filter passed to the read method with the default one
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * filter - {}
│ │ │ │ │ - */
│ │ │ │ │ - mergeWithDefaultFilter: function(filter) {
│ │ │ │ │ - var merged;
│ │ │ │ │ - if (filter && this.defaultFilter) {
│ │ │ │ │ - merged = new OpenLayers.Filter.Logical({
│ │ │ │ │ - type: OpenLayers.Filter.Logical.AND,
│ │ │ │ │ - filters: [this.defaultFilter, filter]
│ │ │ │ │ - });
│ │ │ │ │ - } else {
│ │ │ │ │ - merged = filter || this.defaultFilter || undefined;
│ │ │ │ │ - }
│ │ │ │ │ - return merged;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: destroy
│ │ │ │ │ - * Clean up the protocol.
│ │ │ │ │ - */
│ │ │ │ │ - destroy: function() {
│ │ │ │ │ - this.options = null;
│ │ │ │ │ - this.format = null;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: read
│ │ │ │ │ - * Construct a request for reading new features.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * options - {Object} Optional object for configuring the request.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} An
│ │ │ │ │ - * object, the same object will be passed to the callback function passed
│ │ │ │ │ - * if one exists in the options object.
│ │ │ │ │ - */
│ │ │ │ │ - read: function(options) {
│ │ │ │ │ - options = options || {};
│ │ │ │ │ - options.filter = this.mergeWithDefaultFilter(options.filter);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: create
│ │ │ │ │ - * Construct a request for writing newly created features.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * features - {Array({})} or
│ │ │ │ │ - * {}
│ │ │ │ │ - * options - {Object} Optional object for configuring the request.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} An
│ │ │ │ │ - * object, the same object will be passed to the callback function passed
│ │ │ │ │ - * if one exists in the options object.
│ │ │ │ │ - */
│ │ │ │ │ - create: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: update
│ │ │ │ │ - * Construct a request updating modified features.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * features - {Array({})} or
│ │ │ │ │ - * {}
│ │ │ │ │ - * options - {Object} Optional object for configuring the request.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} An
│ │ │ │ │ - * object, the same object will be passed to the callback function passed
│ │ │ │ │ - * if one exists in the options object.
│ │ │ │ │ - */
│ │ │ │ │ - update: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: delete
│ │ │ │ │ - * Construct a request deleting a removed feature.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * feature - {}
│ │ │ │ │ - * options - {Object} Optional object for configuring the request.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} An
│ │ │ │ │ - * object, the same object will be passed to the callback function passed
│ │ │ │ │ - * if one exists in the options object.
│ │ │ │ │ - */
│ │ │ │ │ - "delete": function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: commit
│ │ │ │ │ - * Go over the features and for each take action
│ │ │ │ │ - * based on the feature state. Possible actions are create,
│ │ │ │ │ - * update and delete.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * features - {Array({})}
│ │ │ │ │ - * options - {Object} Object whose possible keys are "create", "update",
│ │ │ │ │ - * "delete", "callback" and "scope", the values referenced by the
│ │ │ │ │ - * first three are objects as passed to the "create", "update", and
│ │ │ │ │ - * "delete" methods, the value referenced by the "callback" key is
│ │ │ │ │ - * a function which is called when the commit operation is complete
│ │ │ │ │ - * using the scope referenced by the "scope" key.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Array({})} An array of
│ │ │ │ │ - * objects.
│ │ │ │ │ - */
│ │ │ │ │ - commit: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: abort
│ │ │ │ │ - * Abort an ongoing request.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * response - {}
│ │ │ │ │ - */
│ │ │ │ │ - abort: function(response) {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: createCallback
│ │ │ │ │ - * Returns a function that applies the given public method with resp and
│ │ │ │ │ - * options arguments.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * method - {Function} The method to be applied by the callback.
│ │ │ │ │ - * response - {} The protocol response object.
│ │ │ │ │ - * options - {Object} Options sent to the protocol method
│ │ │ │ │ - */
│ │ │ │ │ - createCallback: function(method, response, options) {
│ │ │ │ │ - return OpenLayers.Function.bind(function() {
│ │ │ │ │ - method.apply(this, [response, options]);
│ │ │ │ │ - }, this);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Protocol"
│ │ │ │ │ -});
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Protocol.Response
│ │ │ │ │ - * Protocols return Response objects to their users.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Protocol.Response = OpenLayers.Class({
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: code
│ │ │ │ │ - * {Number} - OpenLayers.Protocol.Response.SUCCESS or
│ │ │ │ │ - * OpenLayers.Protocol.Response.FAILURE
│ │ │ │ │ - */
│ │ │ │ │ - code: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: requestType
│ │ │ │ │ - * {String} The type of request this response corresponds to. Either
│ │ │ │ │ - * "create", "read", "update" or "delete".
│ │ │ │ │ - */
│ │ │ │ │ - requestType: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: last
│ │ │ │ │ - * {Boolean} - true if this is the last response expected in a commit,
│ │ │ │ │ - * false otherwise, defaults to true.
│ │ │ │ │ - */
│ │ │ │ │ - last: true,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: features
│ │ │ │ │ - * {Array({})} or {}
│ │ │ │ │ - * The features returned in the response by the server. Depending on the
│ │ │ │ │ - * protocol's read payload, either features or data will be populated.
│ │ │ │ │ - */
│ │ │ │ │ - features: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: data
│ │ │ │ │ - * {Object}
│ │ │ │ │ - * The data returned in the response by the server. Depending on the
│ │ │ │ │ - * protocol's read payload, either features or data will be populated.
│ │ │ │ │ - */
│ │ │ │ │ - data: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: reqFeatures
│ │ │ │ │ - * {Array({})} or {}
│ │ │ │ │ - * The features provided by the user and placed in the request by the
│ │ │ │ │ - * protocol.
│ │ │ │ │ - */
│ │ │ │ │ - reqFeatures: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: priv
│ │ │ │ │ - */
│ │ │ │ │ - priv: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: error
│ │ │ │ │ - * {Object} The error object in case a service exception was encountered.
│ │ │ │ │ - */
│ │ │ │ │ - error: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Protocol.Response
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * options - {Object} Optional object whose properties will be set on the
│ │ │ │ │ - * instance.
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(options) {
│ │ │ │ │ - OpenLayers.Util.extend(this, options);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: success
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} - true on success, false otherwise
│ │ │ │ │ - */
│ │ │ │ │ - success: function() {
│ │ │ │ │ - return this.code > 0;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Protocol.Response"
│ │ │ │ │ -});
│ │ │ │ │ -
│ │ │ │ │ -OpenLayers.Protocol.Response.SUCCESS = 1;
│ │ │ │ │ -OpenLayers.Protocol.Response.FAILURE = 0;
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Tween.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ - * @requires OpenLayers/Animation.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Namespace: OpenLayers.Tween
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Tween = OpenLayers.Class({
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: easing
│ │ │ │ │ - * {(Function)} Easing equation used for the animation
│ │ │ │ │ - * Defaultly set to OpenLayers.Easing.Expo.easeOut
│ │ │ │ │ - */
│ │ │ │ │ - easing: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: begin
│ │ │ │ │ - * {Object} Values to start the animation with
│ │ │ │ │ - */
│ │ │ │ │ - begin: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: finish
│ │ │ │ │ - * {Object} Values to finish the animation with
│ │ │ │ │ - */
│ │ │ │ │ - finish: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: duration
│ │ │ │ │ - * {int} duration of the tween (number of steps)
│ │ │ │ │ - */
│ │ │ │ │ - duration: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: callbacks
│ │ │ │ │ - * {Object} An object with start, eachStep and done properties whose values
│ │ │ │ │ - * are functions to be call during the animation. They are passed the
│ │ │ │ │ - * current computed value as argument.
│ │ │ │ │ - */
│ │ │ │ │ - callbacks: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: time
│ │ │ │ │ - * {int} Step counter
│ │ │ │ │ - */
│ │ │ │ │ - time: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: minFrameRate
│ │ │ │ │ - * {Number} The minimum framerate for animations in frames per second. After
│ │ │ │ │ - * each step, the time spent in the animation is compared to the calculated
│ │ │ │ │ - * time at this frame rate. If the animation runs longer than the calculated
│ │ │ │ │ - * time, the next step is skipped. Default is 30.
│ │ │ │ │ - */
│ │ │ │ │ - minFrameRate: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: startTime
│ │ │ │ │ - * {Number} The timestamp of the first execution step. Used for skipping
│ │ │ │ │ - * frames
│ │ │ │ │ - */
│ │ │ │ │ - startTime: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: animationId
│ │ │ │ │ - * {int} Loop id returned by OpenLayers.Animation.start
│ │ │ │ │ - */
│ │ │ │ │ - animationId: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: playing
│ │ │ │ │ - * {Boolean} Tells if the easing is currently playing
│ │ │ │ │ - */
│ │ │ │ │ - playing: false,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Tween
│ │ │ │ │ - * Creates a Tween.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * easing - {(Function)} easing function method to use
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(easing) {
│ │ │ │ │ - this.easing = (easing) ? easing : OpenLayers.Easing.Expo.easeOut;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: start
│ │ │ │ │ - * Plays the Tween, and calls the callback method on each step
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * begin - {Object} values to start the animation with
│ │ │ │ │ - * finish - {Object} values to finish the animation with
│ │ │ │ │ - * duration - {int} duration of the tween (number of steps)
│ │ │ │ │ - * options - {Object} hash of options (callbacks (start, eachStep, done),
│ │ │ │ │ - * minFrameRate)
│ │ │ │ │ - */
│ │ │ │ │ - start: function(begin, finish, duration, options) {
│ │ │ │ │ - this.playing = true;
│ │ │ │ │ - this.begin = begin;
│ │ │ │ │ - this.finish = finish;
│ │ │ │ │ - this.duration = duration;
│ │ │ │ │ - this.callbacks = options.callbacks;
│ │ │ │ │ - this.minFrameRate = options.minFrameRate || 30;
│ │ │ │ │ - this.time = 0;
│ │ │ │ │ - this.startTime = new Date().getTime();
│ │ │ │ │ - OpenLayers.Animation.stop(this.animationId);
│ │ │ │ │ - this.animationId = null;
│ │ │ │ │ - if (this.callbacks && this.callbacks.start) {
│ │ │ │ │ - this.callbacks.start.call(this, this.begin);
│ │ │ │ │ - }
│ │ │ │ │ - this.animationId = OpenLayers.Animation.start(
│ │ │ │ │ - OpenLayers.Function.bind(this.play, this)
│ │ │ │ │ - );
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: stop
│ │ │ │ │ - * Stops the Tween, and calls the done callback
│ │ │ │ │ - * Doesn't do anything if animation is already finished
│ │ │ │ │ - */
│ │ │ │ │ - stop: function() {
│ │ │ │ │ - if (!this.playing) {
│ │ │ │ │ - return;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - if (this.callbacks && this.callbacks.done) {
│ │ │ │ │ - this.callbacks.done.call(this, this.finish);
│ │ │ │ │ - }
│ │ │ │ │ - OpenLayers.Animation.stop(this.animationId);
│ │ │ │ │ - this.animationId = null;
│ │ │ │ │ - this.playing = false;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: play
│ │ │ │ │ - * Calls the appropriate easing method
│ │ │ │ │ - */
│ │ │ │ │ - play: function() {
│ │ │ │ │ - var value = {};
│ │ │ │ │ - for (var i in this.begin) {
│ │ │ │ │ - var b = this.begin[i];
│ │ │ │ │ - var f = this.finish[i];
│ │ │ │ │ - if (b == null || f == null || isNaN(b) || isNaN(f)) {
│ │ │ │ │ - throw new TypeError('invalid value for Tween');
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - var c = f - b;
│ │ │ │ │ - value[i] = this.easing.apply(this, [this.time, b, c, this.duration]);
│ │ │ │ │ - }
│ │ │ │ │ - this.time++;
│ │ │ │ │ -
│ │ │ │ │ - if (this.callbacks && this.callbacks.eachStep) {
│ │ │ │ │ - // skip frames if frame rate drops below threshold
│ │ │ │ │ - if ((new Date().getTime() - this.startTime) / this.time <= 1000 / this.minFrameRate) {
│ │ │ │ │ - this.callbacks.eachStep.call(this, value);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - if (this.time > this.duration) {
│ │ │ │ │ - this.stop();
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Create empty functions for all easing methods.
│ │ │ │ │ - */
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Tween"
│ │ │ │ │ -});
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Namespace: OpenLayers.Easing
│ │ │ │ │ - *
│ │ │ │ │ - * Credits:
│ │ │ │ │ - * Easing Equations by Robert Penner,