--- /srv/reproducible-results/rbuild-debian/r-b-build.DRwMgvt8/b1/openlayers_2.13.1+ds2-10_armhf.changes
+++ /srv/reproducible-results/rbuild-debian/r-b-build.DRwMgvt8/b2/openlayers_2.13.1+ds2-10_armhf.changes
├── Files
│ @@ -1,2 +1,2 @@
│
│ - c5b7e5c200b9cd4991cea7757a73d3c3 715764 javascript optional libjs-openlayers_2.13.1+ds2-10_all.deb
│ + cf0c9dfa4e437587b088729c65476571 718104 javascript optional libjs-openlayers_2.13.1+ds2-10_all.deb
├── libjs-openlayers_2.13.1+ds2-10_all.deb
│ ├── file list
│ │ @@ -1,3 +1,3 @@
│ │ -rw-r--r-- 0 0 0 4 2023-01-14 13:27:41.000000 debian-binary
│ │ -rw-r--r-- 0 0 0 3680 2023-01-14 13:27:41.000000 control.tar.xz
│ │ --rw-r--r-- 0 0 0 711892 2023-01-14 13:27:41.000000 data.tar.xz
│ │ +-rw-r--r-- 0 0 0 714232 2023-01-14 13:27:41.000000 data.tar.xz
│ ├── control.tar.xz
│ │ ├── control.tar
│ │ │ ├── ./md5sums
│ │ │ │ ├── ./md5sums
│ │ │ │ │┄ Files differ
│ ├── data.tar.xz
│ │ ├── data.tar
│ │ │ ├── ./usr/share/javascript/openlayers/OpenLayers.js
│ │ │ │ ├── js-beautify {}
│ │ │ │ │ @@ -136,14 +136,141 @@
│ │ │ │ │ * (code)
│ │ │ │ │ *
│ │ │ │ │ * (end code)
│ │ │ │ │ */
│ │ │ │ │ ImgPath: ''
│ │ │ │ │ };
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ + OpenLayers/BaseTypes/Class.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
│ │ │ │ │ + */
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Constructor: OpenLayers.Class
│ │ │ │ │ + * Base class used to construct all other classes. Includes support for
│ │ │ │ │ + * multiple inheritance.
│ │ │ │ │ + *
│ │ │ │ │ + * This constructor is new in OpenLayers 2.5. At OpenLayers 3.0, the old
│ │ │ │ │ + * syntax for creating classes and dealing with inheritance
│ │ │ │ │ + * will be removed.
│ │ │ │ │ + *
│ │ │ │ │ + * To create a new OpenLayers-style class, use the following syntax:
│ │ │ │ │ + * (code)
│ │ │ │ │ + * var MyClass = OpenLayers.Class(prototype);
│ │ │ │ │ + * (end)
│ │ │ │ │ + *
│ │ │ │ │ + * To create a new OpenLayers-style class with multiple inheritance, use the
│ │ │ │ │ + * following syntax:
│ │ │ │ │ + * (code)
│ │ │ │ │ + * var MyClass = OpenLayers.Class(Class1, Class2, prototype);
│ │ │ │ │ + * (end)
│ │ │ │ │ + *
│ │ │ │ │ + * Note that instanceof reflection will only reveal Class1 as superclass.
│ │ │ │ │ + *
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Class = function() {
│ │ │ │ │ + var len = arguments.length;
│ │ │ │ │ + var P = arguments[0];
│ │ │ │ │ + var F = arguments[len - 1];
│ │ │ │ │ +
│ │ │ │ │ + var C = typeof F.initialize == "function" ?
│ │ │ │ │ + F.initialize :
│ │ │ │ │ + function() {
│ │ │ │ │ + P.prototype.initialize.apply(this, arguments);
│ │ │ │ │ + };
│ │ │ │ │ +
│ │ │ │ │ + if (len > 1) {
│ │ │ │ │ + var newArgs = [C, P].concat(
│ │ │ │ │ + Array.prototype.slice.call(arguments).slice(1, len - 1), F);
│ │ │ │ │ + OpenLayers.inherit.apply(null, newArgs);
│ │ │ │ │ + } else {
│ │ │ │ │ + C.prototype = F;
│ │ │ │ │ + }
│ │ │ │ │ + return C;
│ │ │ │ │ +};
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Function: OpenLayers.inherit
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * C - {Object} the class that inherits
│ │ │ │ │ + * P - {Object} the superclass to inherit from
│ │ │ │ │ + *
│ │ │ │ │ + * In addition to the mandatory C and P parameters, an arbitrary number of
│ │ │ │ │ + * objects can be passed, which will extend C.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.inherit = function(C, P) {
│ │ │ │ │ + var F = function() {};
│ │ │ │ │ + F.prototype = P.prototype;
│ │ │ │ │ + C.prototype = new F;
│ │ │ │ │ + var i, l, o;
│ │ │ │ │ + for (i = 2, l = arguments.length; i < l; i++) {
│ │ │ │ │ + o = arguments[i];
│ │ │ │ │ + if (typeof o === "function") {
│ │ │ │ │ + o = o.prototype;
│ │ │ │ │ + }
│ │ │ │ │ + OpenLayers.Util.extend(C.prototype, o);
│ │ │ │ │ + }
│ │ │ │ │ +};
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * APIFunction: extend
│ │ │ │ │ + * Copy all properties of a source object to a destination object. Modifies
│ │ │ │ │ + * the passed in destination object. Any properties on the source object
│ │ │ │ │ + * that are set to undefined will not be (re)set on the destination object.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * destination - {Object} The object that will be modified
│ │ │ │ │ + * source - {Object} The object with properties to be set on the destination
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Object} The destination object.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Util = OpenLayers.Util || {};
│ │ │ │ │ +OpenLayers.Util.extend = function(destination, source) {
│ │ │ │ │ + destination = destination || {};
│ │ │ │ │ + if (source) {
│ │ │ │ │ + for (var property in source) {
│ │ │ │ │ + var value = source[property];
│ │ │ │ │ + if (value !== undefined) {
│ │ │ │ │ + destination[property] = value;
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * IE doesn't include the toString property when iterating over an object's
│ │ │ │ │ + * properties with the for(property in object) syntax. Explicitly check if
│ │ │ │ │ + * the source has its own toString property.
│ │ │ │ │ + */
│ │ │ │ │ +
│ │ │ │ │ + /*
│ │ │ │ │ + * FF/Windows < 2.0.0.13 reports "Illegal operation on WrappedNative
│ │ │ │ │ + * prototype object" when calling hawOwnProperty if the source object
│ │ │ │ │ + * is an instance of window.Event.
│ │ │ │ │ + */
│ │ │ │ │ +
│ │ │ │ │ + var sourceIsEvt = typeof window.Event == "function" &&
│ │ │ │ │ + source instanceof window.Event;
│ │ │ │ │ +
│ │ │ │ │ + if (!sourceIsEvt &&
│ │ │ │ │ + source.hasOwnProperty && source.hasOwnProperty("toString")) {
│ │ │ │ │ + destination.toString = source.toString;
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + return destination;
│ │ │ │ │ +};
│ │ │ │ │ +/* ======================================================================
│ │ │ │ │ OpenLayers/BaseTypes.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. */
│ │ │ │ │ @@ -603,141 +730,14 @@
│ │ │ │ │ }
│ │ │ │ │ }
│ │ │ │ │ return selected;
│ │ │ │ │ }
│ │ │ │ │
│ │ │ │ │ };
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/BaseTypes/Class.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
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Constructor: OpenLayers.Class
│ │ │ │ │ - * Base class used to construct all other classes. Includes support for
│ │ │ │ │ - * multiple inheritance.
│ │ │ │ │ - *
│ │ │ │ │ - * This constructor is new in OpenLayers 2.5. At OpenLayers 3.0, the old
│ │ │ │ │ - * syntax for creating classes and dealing with inheritance
│ │ │ │ │ - * will be removed.
│ │ │ │ │ - *
│ │ │ │ │ - * To create a new OpenLayers-style class, use the following syntax:
│ │ │ │ │ - * (code)
│ │ │ │ │ - * var MyClass = OpenLayers.Class(prototype);
│ │ │ │ │ - * (end)
│ │ │ │ │ - *
│ │ │ │ │ - * To create a new OpenLayers-style class with multiple inheritance, use the
│ │ │ │ │ - * following syntax:
│ │ │ │ │ - * (code)
│ │ │ │ │ - * var MyClass = OpenLayers.Class(Class1, Class2, prototype);
│ │ │ │ │ - * (end)
│ │ │ │ │ - *
│ │ │ │ │ - * Note that instanceof reflection will only reveal Class1 as superclass.
│ │ │ │ │ - *
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Class = function() {
│ │ │ │ │ - var len = arguments.length;
│ │ │ │ │ - var P = arguments[0];
│ │ │ │ │ - var F = arguments[len - 1];
│ │ │ │ │ -
│ │ │ │ │ - var C = typeof F.initialize == "function" ?
│ │ │ │ │ - F.initialize :
│ │ │ │ │ - function() {
│ │ │ │ │ - P.prototype.initialize.apply(this, arguments);
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - if (len > 1) {
│ │ │ │ │ - var newArgs = [C, P].concat(
│ │ │ │ │ - Array.prototype.slice.call(arguments).slice(1, len - 1), F);
│ │ │ │ │ - OpenLayers.inherit.apply(null, newArgs);
│ │ │ │ │ - } else {
│ │ │ │ │ - C.prototype = F;
│ │ │ │ │ - }
│ │ │ │ │ - return C;
│ │ │ │ │ -};
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Function: OpenLayers.inherit
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * C - {Object} the class that inherits
│ │ │ │ │ - * P - {Object} the superclass to inherit from
│ │ │ │ │ - *
│ │ │ │ │ - * In addition to the mandatory C and P parameters, an arbitrary number of
│ │ │ │ │ - * objects can be passed, which will extend C.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.inherit = function(C, P) {
│ │ │ │ │ - var F = function() {};
│ │ │ │ │ - F.prototype = P.prototype;
│ │ │ │ │ - C.prototype = new F;
│ │ │ │ │ - var i, l, o;
│ │ │ │ │ - for (i = 2, l = arguments.length; i < l; i++) {
│ │ │ │ │ - o = arguments[i];
│ │ │ │ │ - if (typeof o === "function") {
│ │ │ │ │ - o = o.prototype;
│ │ │ │ │ - }
│ │ │ │ │ - OpenLayers.Util.extend(C.prototype, o);
│ │ │ │ │ - }
│ │ │ │ │ -};
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * APIFunction: extend
│ │ │ │ │ - * Copy all properties of a source object to a destination object. Modifies
│ │ │ │ │ - * the passed in destination object. Any properties on the source object
│ │ │ │ │ - * that are set to undefined will not be (re)set on the destination object.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * destination - {Object} The object that will be modified
│ │ │ │ │ - * source - {Object} The object with properties to be set on the destination
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Object} The destination object.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Util = OpenLayers.Util || {};
│ │ │ │ │ -OpenLayers.Util.extend = function(destination, source) {
│ │ │ │ │ - destination = destination || {};
│ │ │ │ │ - if (source) {
│ │ │ │ │ - for (var property in source) {
│ │ │ │ │ - var value = source[property];
│ │ │ │ │ - if (value !== undefined) {
│ │ │ │ │ - destination[property] = value;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * IE doesn't include the toString property when iterating over an object's
│ │ │ │ │ - * properties with the for(property in object) syntax. Explicitly check if
│ │ │ │ │ - * the source has its own toString property.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /*
│ │ │ │ │ - * FF/Windows < 2.0.0.13 reports "Illegal operation on WrappedNative
│ │ │ │ │ - * prototype object" when calling hawOwnProperty if the source object
│ │ │ │ │ - * is an instance of window.Event.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - var sourceIsEvt = typeof window.Event == "function" &&
│ │ │ │ │ - source instanceof window.Event;
│ │ │ │ │ -
│ │ │ │ │ - if (!sourceIsEvt &&
│ │ │ │ │ - source.hasOwnProperty && source.hasOwnProperty("toString")) {
│ │ │ │ │ - destination.toString = source.toString;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return destination;
│ │ │ │ │ -};
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ OpenLayers/BaseTypes/Bounds.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. */
│ │ │ │ │ @@ -4426,813 +4426,1673 @@
│ │ │ │ │ } else {
│ │ │ │ │ str += coordinate < 0 ? OpenLayers.i18n("S") : OpenLayers.i18n("N");
│ │ │ │ │ }
│ │ │ │ │ return str;
│ │ │ │ │ };
│ │ │ │ │
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Util/vendorPrefix.js
│ │ │ │ │ + OpenLayers/Feature.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/BaseTypes/Class.js
│ │ │ │ │ + * @requires OpenLayers/Util.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ -OpenLayers.Util = OpenLayers.Util || {};
│ │ │ │ │ /**
│ │ │ │ │ - * Namespace: OpenLayers.Util.vendorPrefix
│ │ │ │ │ - * A collection of utility functions to detect vendor prefixed features
│ │ │ │ │ + * Class: OpenLayers.Feature
│ │ │ │ │ + * Features are combinations of geography and attributes. The OpenLayers.Feature
│ │ │ │ │ + * class specifically combines a marker and a lonlat.
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Util.vendorPrefix = (function() {
│ │ │ │ │ - "use strict";
│ │ │ │ │ +OpenLayers.Feature = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ - var VENDOR_PREFIXES = ["", "O", "ms", "Moz", "Webkit"],
│ │ │ │ │ - divStyle = document.createElement("div").style,
│ │ │ │ │ - cssCache = {},
│ │ │ │ │ - jsCache = {};
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: layer
│ │ │ │ │ + * {}
│ │ │ │ │ + */
│ │ │ │ │ + layer: null,
│ │ │ │ │
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: id
│ │ │ │ │ + * {String}
│ │ │ │ │ + */
│ │ │ │ │ + id: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * 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
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: lonlat
│ │ │ │ │ + * {}
│ │ │ │ │ */
│ │ │ │ │ - function domToCss(prefixedDom) {
│ │ │ │ │ - if (!prefixedDom) {
│ │ │ │ │ - return null;
│ │ │ │ │ - }
│ │ │ │ │ - return prefixedDom.
│ │ │ │ │ - replace(/([A-Z])/g, function(c) {
│ │ │ │ │ - return "-" + c.toLowerCase();
│ │ │ │ │ - }).
│ │ │ │ │ - replace(/^ms-/, "-ms-");
│ │ │ │ │ - }
│ │ │ │ │ + lonlat: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * 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
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: data
│ │ │ │ │ + * {Object}
│ │ │ │ │ */
│ │ │ │ │ - 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];
│ │ │ │ │ - }
│ │ │ │ │ + data: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: marker
│ │ │ │ │ + * {}
│ │ │ │ │ + */
│ │ │ │ │ + marker: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: js
│ │ │ │ │ - * Detect which property is used for a JS property/method
│ │ │ │ │ + * APIProperty: popupClass
│ │ │ │ │ + * {} The class which will be used to instantiate
│ │ │ │ │ + * a new Popup. Default is .
│ │ │ │ │ + */
│ │ │ │ │ + popupClass: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: popup
│ │ │ │ │ + * {}
│ │ │ │ │ + */
│ │ │ │ │ + popup: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Constructor: OpenLayers.Feature
│ │ │ │ │ + * Constructor for features.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * obj - {Object} The object to test on
│ │ │ │ │ - * property - {String} The standard (unprefixed) JS property name
│ │ │ │ │ - *
│ │ │ │ │ + * layer - {}
│ │ │ │ │ + * lonlat - {}
│ │ │ │ │ + * data - {Object}
│ │ │ │ │ + *
│ │ │ │ │ * 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");
│ │ │ │ │ + initialize: function(layer, lonlat, data) {
│ │ │ │ │ + this.layer = layer;
│ │ │ │ │ + this.lonlat = lonlat;
│ │ │ │ │ + this.data = (data != null) ? data : {};
│ │ │ │ │ + this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - 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;
│ │ │ │ │ - }
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: destroy
│ │ │ │ │ + * nullify references to prevent circular references and memory leaks
│ │ │ │ │ + */
│ │ │ │ │ + destroy: function() {
│ │ │ │ │
│ │ │ │ │ - if (obj[tmpProp] !== undefined) {
│ │ │ │ │ - jsCache[property] = tmpProp;
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ + //remove the popup from the map
│ │ │ │ │ + if ((this.layer != null) && (this.layer.map != null)) {
│ │ │ │ │ + if (this.popup != null) {
│ │ │ │ │ + this.layer.map.removePopup(this.popup);
│ │ │ │ │ }
│ │ │ │ │ }
│ │ │ │ │ - return jsCache[property];
│ │ │ │ │ - }
│ │ │ │ │ + // remove the marker from the layer
│ │ │ │ │ + if (this.layer != null && this.marker != null) {
│ │ │ │ │ + this.layer.removeMarker(this.marker);
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + this.layer = null;
│ │ │ │ │ + this.id = null;
│ │ │ │ │ + this.lonlat = null;
│ │ │ │ │ + this.data = null;
│ │ │ │ │ + if (this.marker != null) {
│ │ │ │ │ + this.destroyMarker(this.marker);
│ │ │ │ │ + this.marker = null;
│ │ │ │ │ + }
│ │ │ │ │ + if (this.popup != null) {
│ │ │ │ │ + this.destroyPopup(this.popup);
│ │ │ │ │ + this.popup = null;
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: style
│ │ │ │ │ - * Detect which property is used for a DOM style property
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * property - {String} The standard (unprefixed) style property name
│ │ │ │ │ - *
│ │ │ │ │ + * Method: onScreen
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {String} The standard style property, prefixed property or null if not
│ │ │ │ │ - * supported
│ │ │ │ │ + * {Boolean} Whether or not the feature is currently visible on screen
│ │ │ │ │ + * (based on its 'lonlat' property)
│ │ │ │ │ */
│ │ │ │ │ - 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. */
│ │ │ │ │ + onScreen: function() {
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/SingleFile.js
│ │ │ │ │ - * @requires OpenLayers/Util/vendorPrefix.js
│ │ │ │ │ - */
│ │ │ │ │ + var onScreen = false;
│ │ │ │ │ + if ((this.layer != null) && (this.layer.map != null)) {
│ │ │ │ │ + var screenBounds = this.layer.map.getExtent();
│ │ │ │ │ + onScreen = screenBounds.containsLonLat(this.lonlat);
│ │ │ │ │ + }
│ │ │ │ │ + return onScreen;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * 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
│ │ │ │ │ + * Method: createMarker
│ │ │ │ │ + * Based on the data associated with the Feature, create and return a marker object.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {} A Marker Object created from the 'lonlat' and 'icon' properties
│ │ │ │ │ + * set in this.data. If no 'lonlat' is set, returns null. If no
│ │ │ │ │ + * 'icon' is set, OpenLayers.Marker() will load the default image.
│ │ │ │ │ + *
│ │ │ │ │ + * Note - this.marker is set to return value
│ │ │ │ │ + *
│ │ │ │ │ */
│ │ │ │ │ - var requestAnimationFrame = OpenLayers.Util.vendorPrefix.js(window, "requestAnimationFrame");
│ │ │ │ │ - var isNative = !!(requestAnimationFrame);
│ │ │ │ │ + createMarker: function() {
│ │ │ │ │ +
│ │ │ │ │ + if (this.lonlat != null) {
│ │ │ │ │ + this.marker = new OpenLayers.Marker(this.lonlat, this.data.icon);
│ │ │ │ │ + }
│ │ │ │ │ + return this.marker;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * 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.
│ │ │ │ │ + * Method: destroyMarker
│ │ │ │ │ + * Destroys marker.
│ │ │ │ │ + * If user overrides the createMarker() function, s/he should be able
│ │ │ │ │ + * to also specify an alternative function for destroying it
│ │ │ │ │ */
│ │ │ │ │ - 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 = {};
│ │ │ │ │ + destroyMarker: function() {
│ │ │ │ │ + this.marker.destroy();
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * 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.
│ │ │ │ │ + * Method: createPopup
│ │ │ │ │ + * Creates a popup object created from the 'lonlat', 'popupSize',
│ │ │ │ │ + * and 'popupContentHTML' properties set in this.data. It uses
│ │ │ │ │ + * this.marker.icon as default anchor.
│ │ │ │ │ + *
│ │ │ │ │ + * If no 'lonlat' is set, returns null.
│ │ │ │ │ + * If no this.marker has been created, no anchor is sent.
│ │ │ │ │ *
│ │ │ │ │ + * Note - the returned popup object is 'owned' by the feature, so you
│ │ │ │ │ + * cannot use the popup's destroy method to discard the popup.
│ │ │ │ │ + * Instead, you must use the feature's destroyPopup
│ │ │ │ │ + *
│ │ │ │ │ + * Note - this.popup is set to return value
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * closeBox - {Boolean} create popup with closebox or not
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Number} Identifier for the animation loop. Used to stop animations with
│ │ │ │ │ - * .
│ │ │ │ │ + * {} Returns the created popup, which is also set
│ │ │ │ │ + * as 'popup' property of this feature. Will be of whatever type
│ │ │ │ │ + * specified by this feature's 'popupClass' property, but must be
│ │ │ │ │ + * of type .
│ │ │ │ │ + *
│ │ │ │ │ */
│ │ │ │ │ - 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];
│ │ │ │ │ + createPopup: function(closeBox) {
│ │ │ │ │ +
│ │ │ │ │ + if (this.lonlat != null) {
│ │ │ │ │ + if (!this.popup) {
│ │ │ │ │ + var anchor = (this.marker) ? this.marker.icon : null;
│ │ │ │ │ + var popupClass = this.popupClass ?
│ │ │ │ │ + this.popupClass : OpenLayers.Popup.Anchored;
│ │ │ │ │ + this.popup = new popupClass(this.id + "_popup",
│ │ │ │ │ + this.lonlat,
│ │ │ │ │ + this.data.popupSize,
│ │ │ │ │ + this.data.popupContentHTML,
│ │ │ │ │ + anchor,
│ │ │ │ │ + closeBox);
│ │ │ │ │ + }
│ │ │ │ │ + if (this.data.overflow != null) {
│ │ │ │ │ + this.popup.contentDiv.style.overflow = this.data.overflow;
│ │ │ │ │ }
│ │ │ │ │ - };
│ │ │ │ │ - requestFrame(loops[id], element);
│ │ │ │ │ - return id;
│ │ │ │ │ - }
│ │ │ │ │ +
│ │ │ │ │ + this.popup.feature = this;
│ │ │ │ │ + }
│ │ │ │ │ + return this.popup;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Function: stop
│ │ │ │ │ - * Terminates an animation loop started with .
│ │ │ │ │ + * Method: destroyPopup
│ │ │ │ │ + * Destroys the popup created via createPopup.
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * id - {Number} Identifier returned from .
│ │ │ │ │ + * As with the marker, if user overrides the createPopup() function, s/he
│ │ │ │ │ + * should also be able to override the destruction
│ │ │ │ │ */
│ │ │ │ │ - function stop(id) {
│ │ │ │ │ - delete loops[id];
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - return {
│ │ │ │ │ - isNative: isNative,
│ │ │ │ │ - requestFrame: requestFrame,
│ │ │ │ │ - start: start,
│ │ │ │ │ - stop: stop
│ │ │ │ │ - };
│ │ │ │ │ + destroyPopup: function() {
│ │ │ │ │ + if (this.popup) {
│ │ │ │ │ + this.popup.feature = null;
│ │ │ │ │ + this.popup.destroy();
│ │ │ │ │ + this.popup = null;
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ -})(window);
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Feature"
│ │ │ │ │ +});
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Kinetic.js
│ │ │ │ │ + OpenLayers/Feature/Vector.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. */
│ │ │ │ │
│ │ │ │ │ +// TRASH THIS
│ │ │ │ │ +OpenLayers.State = {
│ │ │ │ │ + /** states */
│ │ │ │ │ + UNKNOWN: 'Unknown',
│ │ │ │ │ + INSERT: 'Insert',
│ │ │ │ │ + UPDATE: 'Update',
│ │ │ │ │ + DELETE: 'Delete'
│ │ │ │ │ +};
│ │ │ │ │ +
│ │ │ │ │ /**
│ │ │ │ │ - * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ - * @requires OpenLayers/Animation.js
│ │ │ │ │ + * @requires OpenLayers/Feature.js
│ │ │ │ │ + * @requires OpenLayers/Util.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ -OpenLayers.Kinetic = OpenLayers.Class({
│ │ │ │ │ +/**
│ │ │ │ │ + * Class: OpenLayers.Feature.Vector
│ │ │ │ │ + * Vector features use the OpenLayers.Geometry classes as geometry description.
│ │ │ │ │ + * They have an 'attributes' property, which is the data object, and a 'style'
│ │ │ │ │ + * property, the default values of which are defined in the
│ │ │ │ │ + * objects.
│ │ │ │ │ + *
│ │ │ │ │ + * Inherits from:
│ │ │ │ │ + * -
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Feature.Vector = OpenLayers.Class(OpenLayers.Feature, {
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: threshold
│ │ │ │ │ - * In most cases changing the threshold isn't needed.
│ │ │ │ │ - * In px/ms, default to 0.
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: fid
│ │ │ │ │ + * {String}
│ │ │ │ │ */
│ │ │ │ │ - threshold: 0,
│ │ │ │ │ + fid: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: deceleration
│ │ │ │ │ - * {Float} the deseleration in px/ms², default to 0.0035.
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: geometry
│ │ │ │ │ + * {}
│ │ │ │ │ */
│ │ │ │ │ - deceleration: 0.0035,
│ │ │ │ │ + geometry: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: nbPoints
│ │ │ │ │ - * {Integer} the number of points we use to calculate the kinetic
│ │ │ │ │ - * initial values.
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: attributes
│ │ │ │ │ + * {Object} This object holds arbitrary, serializable properties that
│ │ │ │ │ + * describe the feature.
│ │ │ │ │ */
│ │ │ │ │ - nbPoints: 100,
│ │ │ │ │ + attributes: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: delay
│ │ │ │ │ - * {Float} time to consider to calculate the kinetic initial values.
│ │ │ │ │ - * In ms, default to 200.
│ │ │ │ │ + * Property: bounds
│ │ │ │ │ + * {} The box bounding that feature's geometry, that
│ │ │ │ │ + * property can be set by an object when
│ │ │ │ │ + * deserializing the feature, so in most cases it represents an
│ │ │ │ │ + * information set by the server.
│ │ │ │ │ */
│ │ │ │ │ - delay: 200,
│ │ │ │ │ + bounds: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: state
│ │ │ │ │ + * {String}
│ │ │ │ │ + */
│ │ │ │ │ + state: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: style
│ │ │ │ │ + * {Object}
│ │ │ │ │ + */
│ │ │ │ │ + style: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: points
│ │ │ │ │ - * List of points use to calculate the kinetic initial values.
│ │ │ │ │ + * APIProperty: url
│ │ │ │ │ + * {String} If this property is set it will be taken into account by
│ │ │ │ │ + * {} when upadting or deleting the feature.
│ │ │ │ │ */
│ │ │ │ │ - points: undefined,
│ │ │ │ │ + url: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: timerId
│ │ │ │ │ - * ID of the timer.
│ │ │ │ │ + * Property: renderIntent
│ │ │ │ │ + * {String} rendering intent currently being used
│ │ │ │ │ */
│ │ │ │ │ - timerId: undefined,
│ │ │ │ │ + renderIntent: "default",
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constructor: OpenLayers.Kinetic
│ │ │ │ │ + * APIProperty: modified
│ │ │ │ │ + * {Object} An object with the originals of the geometry and attributes of
│ │ │ │ │ + * the feature, if they were changed. Currently this property is only read
│ │ │ │ │ + * by , and written by
│ │ │ │ │ + * , which sets the geometry property.
│ │ │ │ │ + * Applications can set the originals of modified attributes in the
│ │ │ │ │ + * attributes property. Note that applications have to check if this
│ │ │ │ │ + * object and the attributes property is already created before using it.
│ │ │ │ │ + * After a change made with ModifyFeature, this object could look like
│ │ │ │ │ + *
│ │ │ │ │ + * (code)
│ │ │ │ │ + * {
│ │ │ │ │ + * geometry: >Object
│ │ │ │ │ + * }
│ │ │ │ │ + * (end)
│ │ │ │ │ + *
│ │ │ │ │ + * When an application has made changes to feature attributes, it could
│ │ │ │ │ + * have set the attributes to something like this:
│ │ │ │ │ + *
│ │ │ │ │ + * (code)
│ │ │ │ │ + * {
│ │ │ │ │ + * attributes: {
│ │ │ │ │ + * myAttribute: "original"
│ │ │ │ │ + * }
│ │ │ │ │ + * }
│ │ │ │ │ + * (end)
│ │ │ │ │ *
│ │ │ │ │ + * Note that only checks for truthy values in
│ │ │ │ │ + * *modified.geometry* and the attribute names in *modified.attributes*,
│ │ │ │ │ + * but it is recommended to set the original values (and not just true) as
│ │ │ │ │ + * attribute value, so applications could use this information to undo
│ │ │ │ │ + * changes.
│ │ │ │ │ + */
│ │ │ │ │ + modified: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Constructor: OpenLayers.Feature.Vector
│ │ │ │ │ + * Create a vector feature.
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * options - {Object}
│ │ │ │ │ + * geometry - {} The geometry that this feature
│ │ │ │ │ + * represents.
│ │ │ │ │ + * attributes - {Object} An optional object that will be mapped to the
│ │ │ │ │ + * property.
│ │ │ │ │ + * style - {Object} An optional style object.
│ │ │ │ │ */
│ │ │ │ │ - initialize: function(options) {
│ │ │ │ │ - OpenLayers.Util.extend(this, options);
│ │ │ │ │ + initialize: function(geometry, attributes, style) {
│ │ │ │ │ + OpenLayers.Feature.prototype.initialize.apply(this,
│ │ │ │ │ + [null, null, attributes]);
│ │ │ │ │ + this.lonlat = null;
│ │ │ │ │ + this.geometry = geometry ? geometry : null;
│ │ │ │ │ + this.state = null;
│ │ │ │ │ + this.attributes = {};
│ │ │ │ │ + if (attributes) {
│ │ │ │ │ + this.attributes = OpenLayers.Util.extend(this.attributes,
│ │ │ │ │ + attributes);
│ │ │ │ │ + }
│ │ │ │ │ + this.style = style ? style : null;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: begin
│ │ │ │ │ - * Begins the dragging.
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: destroy
│ │ │ │ │ + * nullify references to prevent circular references and memory leaks
│ │ │ │ │ */
│ │ │ │ │ - begin: function() {
│ │ │ │ │ - OpenLayers.Animation.stop(this.timerId);
│ │ │ │ │ - this.timerId = undefined;
│ │ │ │ │ - this.points = [];
│ │ │ │ │ + destroy: function() {
│ │ │ │ │ + if (this.layer) {
│ │ │ │ │ + this.layer.removeFeatures(this);
│ │ │ │ │ + this.layer = null;
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + this.geometry = null;
│ │ │ │ │ + this.modified = null;
│ │ │ │ │ + OpenLayers.Feature.prototype.destroy.apply(this, arguments);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: update
│ │ │ │ │ - * Updates during the dragging.
│ │ │ │ │ + * Method: clone
│ │ │ │ │ + * Create a clone of this vector feature. Does not set any non-standard
│ │ │ │ │ + * properties.
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * xy - {} The new position.
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {} An exact clone of this vector feature.
│ │ │ │ │ */
│ │ │ │ │ - update: function(xy) {
│ │ │ │ │ - this.points.unshift({
│ │ │ │ │ - xy: xy,
│ │ │ │ │ - tick: new Date().getTime()
│ │ │ │ │ - });
│ │ │ │ │ - if (this.points.length > this.nbPoints) {
│ │ │ │ │ - this.points.pop();
│ │ │ │ │ - }
│ │ │ │ │ + clone: function() {
│ │ │ │ │ + return new OpenLayers.Feature.Vector(
│ │ │ │ │ + this.geometry ? this.geometry.clone() : null,
│ │ │ │ │ + this.attributes,
│ │ │ │ │ + this.style);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: end
│ │ │ │ │ - * Ends the dragging, start the kinetic.
│ │ │ │ │ + * Method: onScreen
│ │ │ │ │ + * Determine whether the feature is within the map viewport. This method
│ │ │ │ │ + * tests for an intersection between the geometry and the viewport
│ │ │ │ │ + * bounds. If a more effecient but less precise geometry bounds
│ │ │ │ │ + * intersection is desired, call the method with the boundsOnly
│ │ │ │ │ + * parameter true.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * xy - {} The last position.
│ │ │ │ │ - *
│ │ │ │ │ + * boundsOnly - {Boolean} Only test whether a feature's bounds intersects
│ │ │ │ │ + * the viewport bounds. Default is false. If false, the feature's
│ │ │ │ │ + * geometry must intersect the viewport for onScreen to return true.
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Object} An object with two properties: "speed", and "theta". The
│ │ │ │ │ - * "speed" and "theta" values are to be passed to the move
│ │ │ │ │ - * function when starting the animation.
│ │ │ │ │ + * {Boolean} The feature is currently visible on screen (optionally
│ │ │ │ │ + * based on its bounds if boundsOnly is true).
│ │ │ │ │ */
│ │ │ │ │ - end: function(xy) {
│ │ │ │ │ - var last, now = new Date().getTime();
│ │ │ │ │ - for (var i = 0, l = this.points.length, point; i < l; i++) {
│ │ │ │ │ - point = this.points[i];
│ │ │ │ │ - if (now - point.tick > this.delay) {
│ │ │ │ │ - break;
│ │ │ │ │ + onScreen: function(boundsOnly) {
│ │ │ │ │ + var onScreen = false;
│ │ │ │ │ + if (this.layer && this.layer.map) {
│ │ │ │ │ + var screenBounds = this.layer.map.getExtent();
│ │ │ │ │ + if (boundsOnly) {
│ │ │ │ │ + var featureBounds = this.geometry.getBounds();
│ │ │ │ │ + onScreen = screenBounds.intersectsBounds(featureBounds);
│ │ │ │ │ + } else {
│ │ │ │ │ + var screenPoly = screenBounds.toGeometry();
│ │ │ │ │ + onScreen = screenPoly.intersects(this.geometry);
│ │ │ │ │ }
│ │ │ │ │ - last = point;
│ │ │ │ │ - }
│ │ │ │ │ - if (!last) {
│ │ │ │ │ - return;
│ │ │ │ │ - }
│ │ │ │ │ - var time = new Date().getTime() - last.tick;
│ │ │ │ │ - var dist = Math.sqrt(Math.pow(xy.x - last.xy.x, 2) +
│ │ │ │ │ - Math.pow(xy.y - last.xy.y, 2));
│ │ │ │ │ - var speed = dist / time;
│ │ │ │ │ - if (speed == 0 || speed < this.threshold) {
│ │ │ │ │ - return;
│ │ │ │ │ }
│ │ │ │ │ - var theta = Math.asin((xy.y - last.xy.y) / dist);
│ │ │ │ │ - if (last.xy.x <= xy.x) {
│ │ │ │ │ - theta = Math.PI - theta;
│ │ │ │ │ + return onScreen;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: getVisibility
│ │ │ │ │ + * Determine whether the feature is displayed or not. It may not displayed
│ │ │ │ │ + * because:
│ │ │ │ │ + * - its style display property is set to 'none',
│ │ │ │ │ + * - it doesn't belong to any layer,
│ │ │ │ │ + * - the styleMap creates a symbolizer with display property set to 'none'
│ │ │ │ │ + * for it,
│ │ │ │ │ + * - the layer which it belongs to is not visible.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean} The feature is currently displayed.
│ │ │ │ │ + */
│ │ │ │ │ + getVisibility: function() {
│ │ │ │ │ + return !(this.style && this.style.display == 'none' ||
│ │ │ │ │ + !this.layer ||
│ │ │ │ │ + this.layer && this.layer.styleMap &&
│ │ │ │ │ + this.layer.styleMap.createSymbolizer(this, this.renderIntent).display == 'none' ||
│ │ │ │ │ + this.layer && !this.layer.getVisibility());
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: createMarker
│ │ │ │ │ + * HACK - we need to decide if all vector features should be able to
│ │ │ │ │ + * create markers
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {} For now just returns null
│ │ │ │ │ + */
│ │ │ │ │ + createMarker: function() {
│ │ │ │ │ + return null;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: destroyMarker
│ │ │ │ │ + * HACK - we need to decide if all vector features should be able to
│ │ │ │ │ + * delete markers
│ │ │ │ │ + *
│ │ │ │ │ + * If user overrides the createMarker() function, s/he should be able
│ │ │ │ │ + * to also specify an alternative function for destroying it
│ │ │ │ │ + */
│ │ │ │ │ + destroyMarker: function() {
│ │ │ │ │ + // pass
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: createPopup
│ │ │ │ │ + * HACK - we need to decide if all vector features should be able to
│ │ │ │ │ + * create popups
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {} For now just returns null
│ │ │ │ │ + */
│ │ │ │ │ + createPopup: function() {
│ │ │ │ │ + return null;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: atPoint
│ │ │ │ │ + * Determins whether the feature intersects with the specified location.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * lonlat - {|Object} OpenLayers.LonLat or an
│ │ │ │ │ + * object with a 'lon' and 'lat' properties.
│ │ │ │ │ + * toleranceLon - {float} Optional tolerance in Geometric Coords
│ │ │ │ │ + * toleranceLat - {float} Optional tolerance in Geographic Coords
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean} Whether or not the feature is at the specified location
│ │ │ │ │ + */
│ │ │ │ │ + atPoint: function(lonlat, toleranceLon, toleranceLat) {
│ │ │ │ │ + var atPoint = false;
│ │ │ │ │ + if (this.geometry) {
│ │ │ │ │ + atPoint = this.geometry.atPoint(lonlat, toleranceLon,
│ │ │ │ │ + toleranceLat);
│ │ │ │ │ }
│ │ │ │ │ - return {
│ │ │ │ │ - speed: speed,
│ │ │ │ │ - theta: theta
│ │ │ │ │ - };
│ │ │ │ │ + return atPoint;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: destroyPopup
│ │ │ │ │ + * HACK - we need to decide if all vector features should be able to
│ │ │ │ │ + * delete popups
│ │ │ │ │ + */
│ │ │ │ │ + destroyPopup: function() {
│ │ │ │ │ + // pass
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ * Method: move
│ │ │ │ │ - * Launch the kinetic move pan.
│ │ │ │ │ + * Moves the feature and redraws it at its new location
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * info - {Object} An object with two properties, "speed", and "theta".
│ │ │ │ │ - * These values are those returned from the "end" call.
│ │ │ │ │ - * callback - {Function} Function called on every step of the animation,
│ │ │ │ │ - * receives x, y (values to pan), end (is the last point).
│ │ │ │ │ + * location - { or } the
│ │ │ │ │ + * location to which to move the feature.
│ │ │ │ │ */
│ │ │ │ │ - move: function(info, callback) {
│ │ │ │ │ - var v0 = info.speed;
│ │ │ │ │ - var fx = Math.cos(info.theta);
│ │ │ │ │ - var fy = -Math.sin(info.theta);
│ │ │ │ │ -
│ │ │ │ │ - var initialTime = new Date().getTime();
│ │ │ │ │ + move: function(location) {
│ │ │ │ │
│ │ │ │ │ - var lastX = 0;
│ │ │ │ │ - var lastY = 0;
│ │ │ │ │ + if (!this.layer || !this.geometry.move) {
│ │ │ │ │ + //do nothing if no layer or immoveable geometry
│ │ │ │ │ + return undefined;
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - var timerCallback = function() {
│ │ │ │ │ - if (this.timerId == null) {
│ │ │ │ │ - return;
│ │ │ │ │ - }
│ │ │ │ │ + var pixel;
│ │ │ │ │ + if (location.CLASS_NAME == "OpenLayers.LonLat") {
│ │ │ │ │ + pixel = this.layer.getViewPortPxFromLonLat(location);
│ │ │ │ │ + } else {
│ │ │ │ │ + pixel = location;
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - var t = new Date().getTime() - initialTime;
│ │ │ │ │ + var lastPixel = this.layer.getViewPortPxFromLonLat(this.geometry.getBounds().getCenterLonLat());
│ │ │ │ │ + var res = this.layer.map.getResolution();
│ │ │ │ │ + this.geometry.move(res * (pixel.x - lastPixel.x),
│ │ │ │ │ + res * (lastPixel.y - pixel.y));
│ │ │ │ │ + this.layer.drawFeature(this);
│ │ │ │ │ + return lastPixel;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - var p = (-this.deceleration * Math.pow(t, 2)) / 2.0 + v0 * t;
│ │ │ │ │ - var x = p * fx;
│ │ │ │ │ - var y = p * fy;
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: toState
│ │ │ │ │ + * Sets the new state
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * state - {String}
│ │ │ │ │ + */
│ │ │ │ │ + toState: function(state) {
│ │ │ │ │ + if (state == OpenLayers.State.UPDATE) {
│ │ │ │ │ + switch (this.state) {
│ │ │ │ │ + case OpenLayers.State.UNKNOWN:
│ │ │ │ │ + case OpenLayers.State.DELETE:
│ │ │ │ │ + this.state = state;
│ │ │ │ │ + break;
│ │ │ │ │ + case OpenLayers.State.UPDATE:
│ │ │ │ │ + case OpenLayers.State.INSERT:
│ │ │ │ │ + break;
│ │ │ │ │ + }
│ │ │ │ │ + } else if (state == OpenLayers.State.INSERT) {
│ │ │ │ │ + switch (this.state) {
│ │ │ │ │ + case OpenLayers.State.UNKNOWN:
│ │ │ │ │ + break;
│ │ │ │ │ + default:
│ │ │ │ │ + this.state = state;
│ │ │ │ │ + break;
│ │ │ │ │ + }
│ │ │ │ │ + } else if (state == OpenLayers.State.DELETE) {
│ │ │ │ │ + switch (this.state) {
│ │ │ │ │ + case OpenLayers.State.INSERT:
│ │ │ │ │ + // the feature should be destroyed
│ │ │ │ │ + break;
│ │ │ │ │ + case OpenLayers.State.DELETE:
│ │ │ │ │ + break;
│ │ │ │ │ + case OpenLayers.State.UNKNOWN:
│ │ │ │ │ + case OpenLayers.State.UPDATE:
│ │ │ │ │ + this.state = state;
│ │ │ │ │ + break;
│ │ │ │ │ + }
│ │ │ │ │ + } else if (state == OpenLayers.State.UNKNOWN) {
│ │ │ │ │ + this.state = state;
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - var args = {};
│ │ │ │ │ - args.end = false;
│ │ │ │ │ - var v = -this.deceleration * t + v0;
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Feature.Vector"
│ │ │ │ │ +});
│ │ │ │ │
│ │ │ │ │ - if (v <= 0) {
│ │ │ │ │ - OpenLayers.Animation.stop(this.timerId);
│ │ │ │ │ - this.timerId = null;
│ │ │ │ │ - args.end = true;
│ │ │ │ │ - }
│ │ │ │ │
│ │ │ │ │ - args.x = x - lastX;
│ │ │ │ │ - args.y = y - lastY;
│ │ │ │ │ - lastX = x;
│ │ │ │ │ - lastY = y;
│ │ │ │ │ - callback(args.x, args.y, args.end);
│ │ │ │ │ - };
│ │ │ │ │ +/**
│ │ │ │ │ + * Constant: OpenLayers.Feature.Vector.style
│ │ │ │ │ + * OpenLayers features can have a number of style attributes. The 'default'
│ │ │ │ │ + * style will typically be used if no other style is specified. These
│ │ │ │ │ + * styles correspond for the most part, to the styling properties defined
│ │ │ │ │ + * by the SVG standard.
│ │ │ │ │ + * Information on fill properties: http://www.w3.org/TR/SVG/painting.html#FillProperties
│ │ │ │ │ + * Information on stroke properties: http://www.w3.org/TR/SVG/painting.html#StrokeProperties
│ │ │ │ │ + *
│ │ │ │ │ + * Symbolizer properties:
│ │ │ │ │ + * fill - {Boolean} Set to false if no fill is desired.
│ │ │ │ │ + * fillColor - {String} Hex fill color. Default is "#ee9900".
│ │ │ │ │ + * fillOpacity - {Number} Fill opacity (0-1). Default is 0.4
│ │ │ │ │ + * stroke - {Boolean} Set to false if no stroke is desired.
│ │ │ │ │ + * strokeColor - {String} Hex stroke color. Default is "#ee9900".
│ │ │ │ │ + * strokeOpacity - {Number} Stroke opacity (0-1). Default is 1.
│ │ │ │ │ + * strokeWidth - {Number} Pixel stroke width. Default is 1.
│ │ │ │ │ + * strokeLinecap - {String} Stroke cap type. Default is "round". [butt | round | square]
│ │ │ │ │ + * strokeDashstyle - {String} Stroke dash style. Default is "solid". [dot | dash | dashdot | longdash | longdashdot | solid]
│ │ │ │ │ + * graphic - {Boolean} Set to false if no graphic is desired.
│ │ │ │ │ + * pointRadius - {Number} Pixel point radius. Default is 6.
│ │ │ │ │ + * pointerEvents - {String} Default is "visiblePainted".
│ │ │ │ │ + * cursor - {String} Default is "".
│ │ │ │ │ + * externalGraphic - {String} Url to an external graphic that will be used for rendering points.
│ │ │ │ │ + * graphicWidth - {Number} Pixel width for sizing an external graphic.
│ │ │ │ │ + * graphicHeight - {Number} Pixel height for sizing an external graphic.
│ │ │ │ │ + * graphicOpacity - {Number} Opacity (0-1) for an external graphic.
│ │ │ │ │ + * graphicXOffset - {Number} Pixel offset along the positive x axis for displacing an external graphic.
│ │ │ │ │ + * graphicYOffset - {Number} Pixel offset along the positive y axis for displacing an external graphic.
│ │ │ │ │ + * rotation - {Number} For point symbolizers, this is the rotation of a graphic in the clockwise direction about its center point (or any point off center as specified by graphicXOffset and graphicYOffset).
│ │ │ │ │ + * graphicZIndex - {Number} The integer z-index value to use in rendering.
│ │ │ │ │ + * graphicName - {String} Named graphic to use when rendering points. Supported values include "circle" (default),
│ │ │ │ │ + * "square", "star", "x", "cross", "triangle".
│ │ │ │ │ + * graphicTitle - {String} Tooltip when hovering over a feature. *deprecated*, use title instead
│ │ │ │ │ + * title - {String} Tooltip when hovering over a feature. Not supported by the canvas renderer.
│ │ │ │ │ + * backgroundGraphic - {String} Url to a graphic to be used as the background under an externalGraphic.
│ │ │ │ │ + * backgroundGraphicZIndex - {Number} The integer z-index value to use in rendering the background graphic.
│ │ │ │ │ + * backgroundXOffset - {Number} The x offset (in pixels) for the background graphic.
│ │ │ │ │ + * backgroundYOffset - {Number} The y offset (in pixels) for the background graphic.
│ │ │ │ │ + * backgroundHeight - {Number} The height of the background graphic. If not provided, the graphicHeight will be used.
│ │ │ │ │ + * backgroundWidth - {Number} The width of the background width. If not provided, the graphicWidth will be used.
│ │ │ │ │ + * label - {String} The text for an optional label. For browsers that use the canvas renderer, this requires either
│ │ │ │ │ + * fillText or mozDrawText to be available.
│ │ │ │ │ + * labelAlign - {String} Label alignment. This specifies the insertion point relative to the text. It is a string
│ │ │ │ │ + * composed of two characters. The first character is for the horizontal alignment, the second for the vertical
│ │ │ │ │ + * alignment. Valid values for horizontal alignment: "l"=left, "c"=center, "r"=right. Valid values for vertical
│ │ │ │ │ + * alignment: "t"=top, "m"=middle, "b"=bottom. Example values: "lt", "cm", "rb". Default is "cm".
│ │ │ │ │ + * labelXOffset - {Number} Pixel offset along the positive x axis for displacing the label. Not supported by the canvas renderer.
│ │ │ │ │ + * labelYOffset - {Number} Pixel offset along the positive y axis for displacing the label. Not supported by the canvas renderer.
│ │ │ │ │ + * labelSelect - {Boolean} If set to true, labels will be selectable using SelectFeature or similar controls.
│ │ │ │ │ + * Default is false.
│ │ │ │ │ + * labelOutlineColor - {String} The color of the label outline. Default is 'white'. Only supported by the canvas & SVG renderers.
│ │ │ │ │ + * labelOutlineWidth - {Number} The width of the label outline. Default is 3, set to 0 or null to disable. Only supported by the SVG renderers.
│ │ │ │ │ + * labelOutlineOpacity - {Number} The opacity (0-1) of the label outline. Default is fontOpacity. Only supported by the canvas & SVG renderers.
│ │ │ │ │ + * fontColor - {String} The font color for the label, to be provided like CSS.
│ │ │ │ │ + * fontOpacity - {Number} Opacity (0-1) for the label
│ │ │ │ │ + * fontFamily - {String} The font family for the label, to be provided like in CSS.
│ │ │ │ │ + * fontSize - {String} The font size for the label, to be provided like in CSS.
│ │ │ │ │ + * fontStyle - {String} The font style for the label, to be provided like in CSS.
│ │ │ │ │ + * fontWeight - {String} The font weight for the label, to be provided like in CSS.
│ │ │ │ │ + * display - {String} Symbolizers will have no effect if display is set to "none". All other values have no effect.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Feature.Vector.style = {
│ │ │ │ │ + 'default': {
│ │ │ │ │ + fillColor: "#ee9900",
│ │ │ │ │ + fillOpacity: 0.4,
│ │ │ │ │ + hoverFillColor: "white",
│ │ │ │ │ + hoverFillOpacity: 0.8,
│ │ │ │ │ + strokeColor: "#ee9900",
│ │ │ │ │ + strokeOpacity: 1,
│ │ │ │ │ + strokeWidth: 1,
│ │ │ │ │ + strokeLinecap: "round",
│ │ │ │ │ + strokeDashstyle: "solid",
│ │ │ │ │ + hoverStrokeColor: "red",
│ │ │ │ │ + hoverStrokeOpacity: 1,
│ │ │ │ │ + hoverStrokeWidth: 0.2,
│ │ │ │ │ + pointRadius: 6,
│ │ │ │ │ + hoverPointRadius: 1,
│ │ │ │ │ + hoverPointUnit: "%",
│ │ │ │ │ + pointerEvents: "visiblePainted",
│ │ │ │ │ + cursor: "inherit",
│ │ │ │ │ + fontColor: "#000000",
│ │ │ │ │ + labelAlign: "cm",
│ │ │ │ │ + labelOutlineColor: "white",
│ │ │ │ │ + labelOutlineWidth: 3
│ │ │ │ │ + },
│ │ │ │ │ + 'select': {
│ │ │ │ │ + fillColor: "blue",
│ │ │ │ │ + fillOpacity: 0.4,
│ │ │ │ │ + hoverFillColor: "white",
│ │ │ │ │ + hoverFillOpacity: 0.8,
│ │ │ │ │ + strokeColor: "blue",
│ │ │ │ │ + strokeOpacity: 1,
│ │ │ │ │ + strokeWidth: 2,
│ │ │ │ │ + strokeLinecap: "round",
│ │ │ │ │ + strokeDashstyle: "solid",
│ │ │ │ │ + hoverStrokeColor: "red",
│ │ │ │ │ + hoverStrokeOpacity: 1,
│ │ │ │ │ + hoverStrokeWidth: 0.2,
│ │ │ │ │ + pointRadius: 6,
│ │ │ │ │ + hoverPointRadius: 1,
│ │ │ │ │ + hoverPointUnit: "%",
│ │ │ │ │ + pointerEvents: "visiblePainted",
│ │ │ │ │ + cursor: "pointer",
│ │ │ │ │ + fontColor: "#000000",
│ │ │ │ │ + labelAlign: "cm",
│ │ │ │ │ + labelOutlineColor: "white",
│ │ │ │ │ + labelOutlineWidth: 3
│ │ │ │ │
│ │ │ │ │ - this.timerId = OpenLayers.Animation.start(
│ │ │ │ │ - OpenLayers.Function.bind(timerCallback, this)
│ │ │ │ │ - );
│ │ │ │ │ },
│ │ │ │ │ + 'temporary': {
│ │ │ │ │ + fillColor: "#66cccc",
│ │ │ │ │ + fillOpacity: 0.2,
│ │ │ │ │ + hoverFillColor: "white",
│ │ │ │ │ + hoverFillOpacity: 0.8,
│ │ │ │ │ + strokeColor: "#66cccc",
│ │ │ │ │ + strokeOpacity: 1,
│ │ │ │ │ + strokeLinecap: "round",
│ │ │ │ │ + strokeWidth: 2,
│ │ │ │ │ + strokeDashstyle: "solid",
│ │ │ │ │ + hoverStrokeColor: "red",
│ │ │ │ │ + hoverStrokeOpacity: 1,
│ │ │ │ │ + hoverStrokeWidth: 0.2,
│ │ │ │ │ + pointRadius: 6,
│ │ │ │ │ + hoverPointRadius: 1,
│ │ │ │ │ + hoverPointUnit: "%",
│ │ │ │ │ + pointerEvents: "visiblePainted",
│ │ │ │ │ + cursor: "inherit",
│ │ │ │ │ + fontColor: "#000000",
│ │ │ │ │ + labelAlign: "cm",
│ │ │ │ │ + labelOutlineColor: "white",
│ │ │ │ │ + labelOutlineWidth: 3
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Kinetic"
│ │ │ │ │ -});
│ │ │ │ │ + },
│ │ │ │ │ + 'delete': {
│ │ │ │ │ + display: "none"
│ │ │ │ │ + }
│ │ │ │ │ +};
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Tween.js
│ │ │ │ │ + OpenLayers/Style.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
│ │ │ │ │ + * @requires OpenLayers/Util.js
│ │ │ │ │ + * @requires OpenLayers/Feature/Vector.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Namespace: OpenLayers.Tween
│ │ │ │ │ + * Class: OpenLayers.Style
│ │ │ │ │ + * This class represents a UserStyle obtained
│ │ │ │ │ + * from a SLD, containing styling rules.
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Tween = OpenLayers.Class({
│ │ │ │ │ +OpenLayers.Style = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: easing
│ │ │ │ │ - * {(Function)} Easing equation used for the animation
│ │ │ │ │ - * Defaultly set to OpenLayers.Easing.Expo.easeOut
│ │ │ │ │ + * Property: id
│ │ │ │ │ + * {String} A unique id for this session.
│ │ │ │ │ */
│ │ │ │ │ - easing: null,
│ │ │ │ │ + id: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: begin
│ │ │ │ │ - * {Object} Values to start the animation with
│ │ │ │ │ + * APIProperty: name
│ │ │ │ │ + * {String}
│ │ │ │ │ */
│ │ │ │ │ - begin: null,
│ │ │ │ │ + name: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: finish
│ │ │ │ │ - * {Object} Values to finish the animation with
│ │ │ │ │ + * Property: title
│ │ │ │ │ + * {String} Title of this style (set if included in SLD)
│ │ │ │ │ */
│ │ │ │ │ - finish: null,
│ │ │ │ │ + title: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: duration
│ │ │ │ │ - * {int} duration of the tween (number of steps)
│ │ │ │ │ + * Property: description
│ │ │ │ │ + * {String} Description of this style (set if abstract is included in SLD)
│ │ │ │ │ */
│ │ │ │ │ - duration: null,
│ │ │ │ │ + description: 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.
│ │ │ │ │ + * APIProperty: layerName
│ │ │ │ │ + * {} name of the layer that this style belongs to, usually
│ │ │ │ │ + * according to the NamedLayer attribute of an SLD document.
│ │ │ │ │ */
│ │ │ │ │ - callbacks: null,
│ │ │ │ │ + layerName: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: time
│ │ │ │ │ - * {int} Step counter
│ │ │ │ │ + * APIProperty: isDefault
│ │ │ │ │ + * {Boolean}
│ │ │ │ │ */
│ │ │ │ │ - time: null,
│ │ │ │ │ + isDefault: false,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: rules
│ │ │ │ │ + * {Array()}
│ │ │ │ │ + */
│ │ │ │ │ + rules: 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.
│ │ │ │ │ + * APIProperty: 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
│ │ │ │ │ */
│ │ │ │ │ - minFrameRate: null,
│ │ │ │ │ + context: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: startTime
│ │ │ │ │ - * {Number} The timestamp of the first execution step. Used for skipping
│ │ │ │ │ - * frames
│ │ │ │ │ + * Property: defaultStyle
│ │ │ │ │ + * {Object} hash of style properties to use as default for merging
│ │ │ │ │ + * rule-based style symbolizers onto. If no rules are defined,
│ │ │ │ │ + * createSymbolizer will return this style. If is set to
│ │ │ │ │ + * true, the defaultStyle will only be taken into account if there are
│ │ │ │ │ + * rules defined.
│ │ │ │ │ */
│ │ │ │ │ - startTime: null,
│ │ │ │ │ + defaultStyle: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: animationId
│ │ │ │ │ - * {int} Loop id returned by OpenLayers.Animation.start
│ │ │ │ │ + * Property: defaultsPerSymbolizer
│ │ │ │ │ + * {Boolean} If set to true, the will extend the symbolizer
│ │ │ │ │ + * of every rule. Properties of the will also be used to set
│ │ │ │ │ + * missing symbolizer properties if the symbolizer has stroke, fill or
│ │ │ │ │ + * graphic set to true. Default is false.
│ │ │ │ │ */
│ │ │ │ │ - animationId: null,
│ │ │ │ │ + defaultsPerSymbolizer: false,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: playing
│ │ │ │ │ - * {Boolean} Tells if the easing is currently playing
│ │ │ │ │ + * Property: propertyStyles
│ │ │ │ │ + * {Hash of Boolean} cache of style properties that need to be parsed for
│ │ │ │ │ + * propertyNames. Property names are keys, values won't be used.
│ │ │ │ │ */
│ │ │ │ │ - playing: false,
│ │ │ │ │ + propertyStyles: null,
│ │ │ │ │ +
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constructor: OpenLayers.Tween
│ │ │ │ │ - * Creates a Tween.
│ │ │ │ │ + * Constructor: OpenLayers.Style
│ │ │ │ │ + * Creates a UserStyle.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * easing - {(Function)} easing function method to use
│ │ │ │ │ + * style - {Object} Optional hash of style properties that will be
│ │ │ │ │ + * used as default style for this style object. This style
│ │ │ │ │ + * applies if no rules are specified. Symbolizers defined in
│ │ │ │ │ + * rules will extend this default style.
│ │ │ │ │ + * options - {Object} An optional object with properties to set on the
│ │ │ │ │ + * style.
│ │ │ │ │ + *
│ │ │ │ │ + * Valid options:
│ │ │ │ │ + * rules - {Array()} List of rules to be added to the
│ │ │ │ │ + * style.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {}
│ │ │ │ │ */
│ │ │ │ │ - initialize: function(easing) {
│ │ │ │ │ - this.easing = (easing) ? easing : OpenLayers.Easing.Expo.easeOut;
│ │ │ │ │ + initialize: function(style, options) {
│ │ │ │ │ +
│ │ │ │ │ + OpenLayers.Util.extend(this, options);
│ │ │ │ │ + this.rules = [];
│ │ │ │ │ + if (options && options.rules) {
│ │ │ │ │ + this.addRules(options.rules);
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + // use the default style from OpenLayers.Feature.Vector if no style
│ │ │ │ │ + // was given in the constructor
│ │ │ │ │ + this.setDefaultStyle(style ||
│ │ │ │ │ + OpenLayers.Feature.Vector.style["default"]);
│ │ │ │ │ +
│ │ │ │ │ + this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * 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)
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: destroy
│ │ │ │ │ + * nullify references to prevent circular references and memory leaks
│ │ │ │ │ */
│ │ │ │ │ - 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);
│ │ │ │ │ + destroy: function() {
│ │ │ │ │ + for (var i = 0, len = this.rules.length; i < len; i++) {
│ │ │ │ │ + this.rules[i].destroy();
│ │ │ │ │ + this.rules[i] = null;
│ │ │ │ │ }
│ │ │ │ │ - this.animationId = OpenLayers.Animation.start(
│ │ │ │ │ - OpenLayers.Function.bind(this.play, this)
│ │ │ │ │ - );
│ │ │ │ │ + this.rules = null;
│ │ │ │ │ + this.defaultStyle = null;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: stop
│ │ │ │ │ - * Stops the Tween, and calls the done callback
│ │ │ │ │ - * Doesn't do anything if animation is already finished
│ │ │ │ │ + * 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
│ │ │ │ │ */
│ │ │ │ │ - stop: function() {
│ │ │ │ │ - if (!this.playing) {
│ │ │ │ │ - return;
│ │ │ │ │ + createSymbolizer: function(feature) {
│ │ │ │ │ + var style = this.defaultsPerSymbolizer ? {} : this.createLiterals(
│ │ │ │ │ + OpenLayers.Util.extend({}, this.defaultStyle), feature);
│ │ │ │ │ +
│ │ │ │ │ + var rules = this.rules;
│ │ │ │ │ +
│ │ │ │ │ + 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);
│ │ │ │ │ +
│ │ │ │ │ + if (applies) {
│ │ │ │ │ + if (rule instanceof OpenLayers.Rule && rule.elseFilter) {
│ │ │ │ │ + elseRules.push(rule);
│ │ │ │ │ + } else {
│ │ │ │ │ + appliedRules = true;
│ │ │ │ │ + this.applySymbolizer(rule, style, feature);
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │
│ │ │ │ │ - if (this.callbacks && this.callbacks.done) {
│ │ │ │ │ - this.callbacks.done.call(this, this.finish);
│ │ │ │ │ + // 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);
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ - OpenLayers.Animation.stop(this.animationId);
│ │ │ │ │ - this.animationId = null;
│ │ │ │ │ - this.playing = false;
│ │ │ │ │ +
│ │ │ │ │ + // don't display if there were rules but none applied
│ │ │ │ │ + if (rules.length > 0 && appliedRules == false) {
│ │ │ │ │ + style.display = "none";
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + if (style.label != null && typeof style.label !== "string") {
│ │ │ │ │ + style.label = String(style.label);
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + return style;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: play
│ │ │ │ │ - * Calls the appropriate easing method
│ │ │ │ │ + * Method: applySymbolizer
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * rule - {}
│ │ │ │ │ + * style - {Object}
│ │ │ │ │ + * feature - {}
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Object} A style with new symbolizer applied.
│ │ │ │ │ */
│ │ │ │ │ - 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');
│ │ │ │ │ - }
│ │ │ │ │ + applySymbolizer: function(rule, style, feature) {
│ │ │ │ │ + var symbolizerPrefix = feature.geometry ?
│ │ │ │ │ + this.getSymbolizerPrefix(feature.geometry) :
│ │ │ │ │ + OpenLayers.Style.SYMBOLIZER_PREFIXES[0];
│ │ │ │ │
│ │ │ │ │ - var c = f - b;
│ │ │ │ │ - value[i] = this.easing.apply(this, [this.time, b, c, this.duration]);
│ │ │ │ │ - }
│ │ │ │ │ - this.time++;
│ │ │ │ │ + var symbolizer = rule.symbolizer[symbolizerPrefix] || rule.symbolizer;
│ │ │ │ │
│ │ │ │ │ - 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.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
│ │ │ │ │ + });
│ │ │ │ │ + }
│ │ │ │ │ + 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
│ │ │ │ │ + });
│ │ │ │ │ }
│ │ │ │ │ }
│ │ │ │ │
│ │ │ │ │ - if (this.time > this.duration) {
│ │ │ │ │ - this.stop();
│ │ │ │ │ - }
│ │ │ │ │ + // merge the style with the current style
│ │ │ │ │ + return this.createLiterals(
│ │ │ │ │ + OpenLayers.Util.extend(style, symbolizer), feature);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Create empty functions for all easing methods.
│ │ │ │ │ + * Method: createLiterals
│ │ │ │ │ + * creates literals for all style properties that have an entry in
│ │ │ │ │ + * .
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * style - {Object} style to create literals for. Will be modified
│ │ │ │ │ + * inline.
│ │ │ │ │ + * feature - {Object}
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Object} the modified style
│ │ │ │ │ */
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Tween"
│ │ │ │ │ -});
│ │ │ │ │ + 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;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * Namespace: OpenLayers.Easing
│ │ │ │ │ - *
│ │ │ │ │ - * Credits:
│ │ │ │ │ - * Easing Equations by Robert Penner,
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Easing = {
│ │ │ │ │ /**
│ │ │ │ │ - * Create empty functions for all easing methods.
│ │ │ │ │ + * 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.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Object} hash of property names that need createLiteral parsing. The
│ │ │ │ │ + * name of the property is the key, and the value is true;
│ │ │ │ │ */
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Easing"
│ │ │ │ │ -};
│ │ │ │ │ + findPropertyStyles: function() {
│ │ │ │ │ + var propertyStyles = {};
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * Namespace: OpenLayers.Easing.Linear
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Easing.Linear = {
│ │ │ │ │ + // 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;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Function: easeIn
│ │ │ │ │ + * Method: addPropertyStyles
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * t - {Float} time
│ │ │ │ │ - * b - {Float} beginning position
│ │ │ │ │ - * c - {Float} total change
│ │ │ │ │ - * d - {Float} duration of the transition
│ │ │ │ │ - *
│ │ │ │ │ + * propertyStyles - {Object} hash to add new property styles to. Will be
│ │ │ │ │ + * modified inline
│ │ │ │ │ + * symbolizer - {Object} search this symbolizer for property styles
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Float}
│ │ │ │ │ + * {Object} propertyStyles hash
│ │ │ │ │ */
│ │ │ │ │ - easeIn: function(t, b, c, d) {
│ │ │ │ │ - return c * t / d + b;
│ │ │ │ │ + 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;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Function: easeOut
│ │ │ │ │ + * APIMethod: addRules
│ │ │ │ │ + * Adds rules to this style.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * t - {Float} time
│ │ │ │ │ - * b - {Float} beginning position
│ │ │ │ │ - * c - {Float} total change
│ │ │ │ │ - * d - {Float} duration of the transition
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Float}
│ │ │ │ │ + * rules - {Array()}
│ │ │ │ │ */
│ │ │ │ │ - easeOut: function(t, b, c, d) {
│ │ │ │ │ - return c * t / d + b;
│ │ │ │ │ + addRules: function(rules) {
│ │ │ │ │ + Array.prototype.push.apply(this.rules, rules);
│ │ │ │ │ + this.propertyStyles = this.findPropertyStyles();
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Function: easeInOut
│ │ │ │ │ + * APIMethod: setDefaultStyle
│ │ │ │ │ + * Sets the default style for this style object.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * t - {Float} time
│ │ │ │ │ - * b - {Float} beginning position
│ │ │ │ │ - * c - {Float} total change
│ │ │ │ │ - * d - {Float} duration of the transition
│ │ │ │ │ - *
│ │ │ │ │ + * style - {Object} Hash of style properties
│ │ │ │ │ + */
│ │ │ │ │ + setDefaultStyle: function(style) {
│ │ │ │ │ + this.defaultStyle = style;
│ │ │ │ │ + this.propertyStyles = this.findPropertyStyles();
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: getSymbolizerPrefix
│ │ │ │ │ + * Returns the correct symbolizer prefix according to the
│ │ │ │ │ + * geometry type of the passed geometry
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * geometry - {}
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Float}
│ │ │ │ │ + * {String} key of the according symbolizer
│ │ │ │ │ */
│ │ │ │ │ - easeInOut: function(t, b, c, d) {
│ │ │ │ │ - return c * t / d + b;
│ │ │ │ │ + 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];
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Easing.Linear"
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: clone
│ │ │ │ │ + * Clones this style.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {} Clone of this style.
│ │ │ │ │ + */
│ │ │ │ │ + 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);
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + 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;
│ │ │ │ │ };
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Namespace: OpenLayers.Easing.Expo
│ │ │ │ │ + * Constant: OpenLayers.Style.SYMBOLIZER_PREFIXES
│ │ │ │ │ + * {Array} prefixes of the sld symbolizers. These are the
│ │ │ │ │ + * same as the main geometry types
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Easing.Expo = {
│ │ │ │ │ +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({
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Function: easeIn
│ │ │ │ │ + * Property: styles
│ │ │ │ │ + * {Object} Hash of {}, keyed by names of well known
│ │ │ │ │ + * rendering intents (e.g. "default", "temporary", "select", "delete").
│ │ │ │ │ + */
│ │ │ │ │ + styles: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * 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.
│ │ │ │ │ + */
│ │ │ │ │ + extendDefault: true,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Constructor: OpenLayers.StyleMap
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * t - {Float} time
│ │ │ │ │ - * b - {Float} beginning position
│ │ │ │ │ - * c - {Float} total change
│ │ │ │ │ - * d - {Float} duration of the transition
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Float}
│ │ │ │ │ + * 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
│ │ │ │ │ */
│ │ │ │ │ - easeIn: function(t, b, c, d) {
│ │ │ │ │ - return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
│ │ │ │ │ + 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);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Function: easeOut
│ │ │ │ │ + * Method: destroy
│ │ │ │ │ + */
│ │ │ │ │ + destroy: function() {
│ │ │ │ │ + for (var key in this.styles) {
│ │ │ │ │ + this.styles[key].destroy();
│ │ │ │ │ + }
│ │ │ │ │ + this.styles = null;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: createSymbolizer
│ │ │ │ │ + * Creates the symbolizer for a feature for a render intent.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * t - {Float} time
│ │ │ │ │ - * b - {Float} beginning position
│ │ │ │ │ - * c - {Float} total change
│ │ │ │ │ - * d - {Float} duration of the transition
│ │ │ │ │ - *
│ │ │ │ │ + * 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).
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Float}
│ │ │ │ │ + * {Object} symbolizer hash
│ │ │ │ │ */
│ │ │ │ │ - easeOut: function(t, b, c, d) {
│ │ │ │ │ - return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
│ │ │ │ │ + createSymbolizer: function(feature, intent) {
│ │ │ │ │ + if (!feature) {
│ │ │ │ │ + feature = new OpenLayers.Feature.Vector();
│ │ │ │ │ + }
│ │ │ │ │ + if (!this.styles[intent]) {
│ │ │ │ │ + intent = "default";
│ │ │ │ │ + }
│ │ │ │ │ + feature.renderIntent = intent;
│ │ │ │ │ + var defaultSymbolizer = {};
│ │ │ │ │ + if (this.extendDefault && intent != "default") {
│ │ │ │ │ + defaultSymbolizer = this.styles["default"].createSymbolizer(feature);
│ │ │ │ │ + }
│ │ │ │ │ + return OpenLayers.Util.extend(defaultSymbolizer,
│ │ │ │ │ + this.styles[intent].createSymbolizer(feature));
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Function: easeInOut
│ │ │ │ │ + * 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
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * t - {Float} time
│ │ │ │ │ - * b - {Float} beginning position
│ │ │ │ │ - * c - {Float} total change
│ │ │ │ │ - * d - {Float} duration of the transition
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Float}
│ │ │ │ │ + * 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
│ │ │ │ │ */
│ │ │ │ │ - easeInOut: function(t, b, c, d) {
│ │ │ │ │ - if (t == 0) return b;
│ │ │ │ │ - if (t == d) return b + c;
│ │ │ │ │ - if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
│ │ │ │ │ - return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
│ │ │ │ │ + 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
│ │ │ │ │ + })
│ │ │ │ │ + }));
│ │ │ │ │ + }
│ │ │ │ │ + this.styles[renderIntent].addRules(rules);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Easing.Expo"
│ │ │ │ │ -};
│ │ │ │ │ + CLASS_NAME: "OpenLayers.StyleMap"
│ │ │ │ │ +});
│ │ │ │ │ +/* ======================================================================
│ │ │ │ │ + OpenLayers/Tile.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. */
│ │ │ │ │ +
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Namespace: OpenLayers.Easing.Quad
│ │ │ │ │ + * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ + * @requires OpenLayers/Util.js
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Easing.Quad = {
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Class: OpenLayers.Tile
│ │ │ │ │ + * This is a class designed to designate a single tile, however
│ │ │ │ │ + * it is explicitly designed to do relatively little. Tiles store
│ │ │ │ │ + * information about themselves -- such as the URL that they are related
│ │ │ │ │ + * to, and their size - but do not add themselves to the layer div
│ │ │ │ │ + * automatically, for example. Create a new tile with the
│ │ │ │ │ + * constructor, or a subclass.
│ │ │ │ │ + *
│ │ │ │ │ + * TBD 3.0 - remove reference to url in above paragraph
│ │ │ │ │ + *
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Tile = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Function: easeIn
│ │ │ │ │ + * APIProperty: events
│ │ │ │ │ + * {} An events object that handles all
│ │ │ │ │ + * events on the tile.
│ │ │ │ │ + *
│ │ │ │ │ + * Register a listener for a particular event with the following syntax:
│ │ │ │ │ + * (code)
│ │ │ │ │ + * tile.events.register(type, obj, listener);
│ │ │ │ │ + * (end)
│ │ │ │ │ + *
│ │ │ │ │ + * Supported event types:
│ │ │ │ │ + * beforedraw - Triggered before the tile is drawn. Used to defer
│ │ │ │ │ + * drawing to an animation queue. To defer drawing, listeners need
│ │ │ │ │ + * to return false, which will abort drawing. The queue handler needs
│ │ │ │ │ + * to call (true) to actually draw the tile.
│ │ │ │ │ + * loadstart - Triggered when tile loading starts.
│ │ │ │ │ + * loadend - Triggered when tile loading ends.
│ │ │ │ │ + * loaderror - Triggered before the loadend event (i.e. when the tile is
│ │ │ │ │ + * still hidden) if the tile could not be loaded.
│ │ │ │ │ + * reload - Triggered when an already loading tile is reloaded.
│ │ │ │ │ + * unload - Triggered before a tile is unloaded.
│ │ │ │ │ + */
│ │ │ │ │ + events: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: eventListeners
│ │ │ │ │ + * {Object} If set as an option at construction, the eventListeners
│ │ │ │ │ + * object will be registered with . Object
│ │ │ │ │ + * structure must be a listeners object as shown in the example for
│ │ │ │ │ + * the events.on method.
│ │ │ │ │ + *
│ │ │ │ │ + * This options can be set in the ``tileOptions`` option from
│ │ │ │ │ + * . For example, to be notified of the
│ │ │ │ │ + * ``loadend`` event of each tiles:
│ │ │ │ │ + * (code)
│ │ │ │ │ + * new OpenLayers.Layer.OSM('osm', 'http://tile.openstreetmap.org/${z}/${x}/${y}.png', {
│ │ │ │ │ + * tileOptions: {
│ │ │ │ │ + * eventListeners: {
│ │ │ │ │ + * 'loadend': function(evt) {
│ │ │ │ │ + * // do something on loadend
│ │ │ │ │ + * }
│ │ │ │ │ + * }
│ │ │ │ │ + * }
│ │ │ │ │ + * });
│ │ │ │ │ + * (end)
│ │ │ │ │ + */
│ │ │ │ │ + eventListeners: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: id
│ │ │ │ │ + * {String} null
│ │ │ │ │ + */
│ │ │ │ │ + id: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: layer
│ │ │ │ │ + * {} layer the tile is attached to
│ │ │ │ │ + */
│ │ │ │ │ + layer: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: url
│ │ │ │ │ + * {String} url of the request.
│ │ │ │ │ + *
│ │ │ │ │ + * TBD 3.0
│ │ │ │ │ + * Deprecated. The base tile class does not need an url. This should be
│ │ │ │ │ + * handled in subclasses. Does not belong here.
│ │ │ │ │ + */
│ │ │ │ │ + url: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: bounds
│ │ │ │ │ + * {} null
│ │ │ │ │ + */
│ │ │ │ │ + bounds: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: size
│ │ │ │ │ + * {} null
│ │ │ │ │ + */
│ │ │ │ │ + size: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: position
│ │ │ │ │ + * {} Top Left pixel of the tile
│ │ │ │ │ + */
│ │ │ │ │ + position: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: isLoading
│ │ │ │ │ + * {Boolean} Is the tile loading?
│ │ │ │ │ + */
│ │ │ │ │ + isLoading: false,
│ │ │ │ │ +
│ │ │ │ │ + /** TBD 3.0 -- remove 'url' from the list of parameters to the constructor.
│ │ │ │ │ + * there is no need for the base tile class to have a url.
│ │ │ │ │ + */
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Constructor: OpenLayers.Tile
│ │ │ │ │ + * Constructor for a new instance.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * t - {Float} time
│ │ │ │ │ - * b - {Float} beginning position
│ │ │ │ │ - * c - {Float} total change
│ │ │ │ │ - * d - {Float} duration of the transition
│ │ │ │ │ + * layer - {} layer that the tile will go in.
│ │ │ │ │ + * position - {}
│ │ │ │ │ + * bounds - {}
│ │ │ │ │ + * url - {}
│ │ │ │ │ + * size - {}
│ │ │ │ │ + * options - {Object}
│ │ │ │ │ + */
│ │ │ │ │ + initialize: function(layer, position, bounds, url, size, options) {
│ │ │ │ │ + this.layer = layer;
│ │ │ │ │ + this.position = position.clone();
│ │ │ │ │ + this.setBounds(bounds);
│ │ │ │ │ + this.url = url;
│ │ │ │ │ + if (size) {
│ │ │ │ │ + this.size = size.clone();
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + //give the tile a unique id based on its BBOX.
│ │ │ │ │ + this.id = OpenLayers.Util.createUniqueID("Tile_");
│ │ │ │ │ +
│ │ │ │ │ + OpenLayers.Util.extend(this, options);
│ │ │ │ │ +
│ │ │ │ │ + this.events = new OpenLayers.Events(this);
│ │ │ │ │ + if (this.eventListeners instanceof Object) {
│ │ │ │ │ + this.events.on(this.eventListeners);
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: unload
│ │ │ │ │ + * Call immediately before destroying if you are listening to tile
│ │ │ │ │ + * events, so that counters are properly handled if tile is still
│ │ │ │ │ + * loading at destroy-time. Will only fire an event if the tile is
│ │ │ │ │ + * still loading.
│ │ │ │ │ + */
│ │ │ │ │ + unload: function() {
│ │ │ │ │ + if (this.isLoading) {
│ │ │ │ │ + this.isLoading = false;
│ │ │ │ │ + this.events.triggerEvent("unload");
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: destroy
│ │ │ │ │ + * Nullify references to prevent circular references and memory leaks.
│ │ │ │ │ + */
│ │ │ │ │ + destroy: function() {
│ │ │ │ │ + this.layer = null;
│ │ │ │ │ + this.bounds = null;
│ │ │ │ │ + this.size = null;
│ │ │ │ │ + this.position = null;
│ │ │ │ │ +
│ │ │ │ │ + if (this.eventListeners) {
│ │ │ │ │ + this.events.un(this.eventListeners);
│ │ │ │ │ + }
│ │ │ │ │ + this.events.destroy();
│ │ │ │ │ + this.eventListeners = null;
│ │ │ │ │ + this.events = null;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: draw
│ │ │ │ │ + * Clear whatever is currently in the tile, then return whether or not
│ │ │ │ │ + * it should actually be re-drawn. This is an example implementation
│ │ │ │ │ + * that can be overridden by subclasses. The minimum thing to do here
│ │ │ │ │ + * is to call and return the result from .
│ │ │ │ │ *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * force - {Boolean} If true, the tile will not be cleared and no beforedraw
│ │ │ │ │ + * event will be fired. This is used for drawing tiles asynchronously
│ │ │ │ │ + * after drawing has been cancelled by returning false from a beforedraw
│ │ │ │ │ + * listener.
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Float}
│ │ │ │ │ + * {Boolean} Whether or not the tile should actually be drawn. Returns null
│ │ │ │ │ + * if a beforedraw listener returned false.
│ │ │ │ │ */
│ │ │ │ │ - easeIn: function(t, b, c, d) {
│ │ │ │ │ - return c * (t /= d) * t + b;
│ │ │ │ │ + draw: function(force) {
│ │ │ │ │ + if (!force) {
│ │ │ │ │ + //clear tile's contents and mark as not drawn
│ │ │ │ │ + this.clear();
│ │ │ │ │ + }
│ │ │ │ │ + var draw = this.shouldDraw();
│ │ │ │ │ + if (draw && !force && this.events.triggerEvent("beforedraw") === false) {
│ │ │ │ │ + draw = null;
│ │ │ │ │ + }
│ │ │ │ │ + return draw;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Function: easeOut
│ │ │ │ │ + * Method: shouldDraw
│ │ │ │ │ + * Return whether or not the tile should actually be (re-)drawn. The only
│ │ │ │ │ + * case where we *wouldn't* want to draw the tile is if the tile is outside
│ │ │ │ │ + * its layer's maxExtent
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * t - {Float} time
│ │ │ │ │ - * b - {Float} beginning position
│ │ │ │ │ - * c - {Float} total change
│ │ │ │ │ - * d - {Float} duration of the transition
│ │ │ │ │ - *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Float}
│ │ │ │ │ + * {Boolean} Whether or not the tile should actually be drawn.
│ │ │ │ │ */
│ │ │ │ │ - easeOut: function(t, b, c, d) {
│ │ │ │ │ - return -c * (t /= d) * (t - 2) + b;
│ │ │ │ │ + shouldDraw: function() {
│ │ │ │ │ + var withinMaxExtent = false,
│ │ │ │ │ + maxExtent = this.layer.maxExtent;
│ │ │ │ │ + if (maxExtent) {
│ │ │ │ │ + var map = this.layer.map;
│ │ │ │ │ + var worldBounds = map.baseLayer.wrapDateLine && map.getMaxExtent();
│ │ │ │ │ + if (this.bounds.intersectsBounds(maxExtent, {
│ │ │ │ │ + inclusive: false,
│ │ │ │ │ + worldBounds: worldBounds
│ │ │ │ │ + })) {
│ │ │ │ │ + withinMaxExtent = true;
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + return withinMaxExtent || this.layer.displayOutsideMaxExtent;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Function: easeInOut
│ │ │ │ │ - *
│ │ │ │ │ + * Method: setBounds
│ │ │ │ │ + * Sets the bounds on this instance
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * t - {Float} time
│ │ │ │ │ - * b - {Float} beginning position
│ │ │ │ │ - * c - {Float} total change
│ │ │ │ │ - * d - {Float} duration of the transition
│ │ │ │ │ + * bounds {}
│ │ │ │ │ + */
│ │ │ │ │ + setBounds: function(bounds) {
│ │ │ │ │ + bounds = bounds.clone();
│ │ │ │ │ + if (this.layer.map.baseLayer.wrapDateLine) {
│ │ │ │ │ + var worldExtent = this.layer.map.getMaxExtent(),
│ │ │ │ │ + tolerance = this.layer.map.getResolution();
│ │ │ │ │ + bounds = bounds.wrapDateLine(worldExtent, {
│ │ │ │ │ + leftTolerance: tolerance,
│ │ │ │ │ + rightTolerance: tolerance
│ │ │ │ │ + });
│ │ │ │ │ + }
│ │ │ │ │ + this.bounds = bounds;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: moveTo
│ │ │ │ │ + * Reposition the tile.
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Float}
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * bounds - {}
│ │ │ │ │ + * position - {}
│ │ │ │ │ + * redraw - {Boolean} Call draw method on tile after moving.
│ │ │ │ │ + * Default is true
│ │ │ │ │ */
│ │ │ │ │ - easeInOut: function(t, b, c, d) {
│ │ │ │ │ - if ((t /= d / 2) < 1) return c / 2 * t * t + b;
│ │ │ │ │ - return -c / 2 * ((--t) * (t - 2) - 1) + b;
│ │ │ │ │ + moveTo: function(bounds, position, redraw) {
│ │ │ │ │ + if (redraw == null) {
│ │ │ │ │ + redraw = true;
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + this.setBounds(bounds);
│ │ │ │ │ + this.position = position.clone();
│ │ │ │ │ + if (redraw) {
│ │ │ │ │ + this.draw();
│ │ │ │ │ + }
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Easing.Quad"
│ │ │ │ │ -};
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: clear
│ │ │ │ │ + * Clear the tile of any bounds/position-related data so that it can
│ │ │ │ │ + * be reused in a new location.
│ │ │ │ │ + */
│ │ │ │ │ + clear: function(draw) {
│ │ │ │ │ + // to be extended by subclasses
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Tile"
│ │ │ │ │ +});
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ OpenLayers/Events.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
│ │ │ │ │ @@ -6402,14 +7262,1549 @@
│ │ │ │ │
│ │ │ │ │ OpenLayers.Event.observe(element, 'MSPointerUp', cb);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ CLASS_NAME: "OpenLayers.Events"
│ │ │ │ │ });
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ + 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/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/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,
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Easing = {
│ │ │ │ │ + /**
│ │ │ │ │ + * Create empty functions for all easing methods.
│ │ │ │ │ + */
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Easing"
│ │ │ │ │ +};
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Namespace: OpenLayers.Easing.Linear
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Easing.Linear = {
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Function: easeIn
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Float}
│ │ │ │ │ + */
│ │ │ │ │ + easeIn: function(t, b, c, d) {
│ │ │ │ │ + return c * t / d + b;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Function: easeOut
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Float}
│ │ │ │ │ + */
│ │ │ │ │ + easeOut: function(t, b, c, d) {
│ │ │ │ │ + return c * t / d + b;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Function: easeInOut
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Float}
│ │ │ │ │ + */
│ │ │ │ │ + easeInOut: function(t, b, c, d) {
│ │ │ │ │ + return c * t / d + b;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Easing.Linear"
│ │ │ │ │ +};
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Namespace: OpenLayers.Easing.Expo
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Easing.Expo = {
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Function: easeIn
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Float}
│ │ │ │ │ + */
│ │ │ │ │ + easeIn: function(t, b, c, d) {
│ │ │ │ │ + return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Function: easeOut
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Float}
│ │ │ │ │ + */
│ │ │ │ │ + easeOut: function(t, b, c, d) {
│ │ │ │ │ + return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Function: easeInOut
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Float}
│ │ │ │ │ + */
│ │ │ │ │ + easeInOut: function(t, b, c, d) {
│ │ │ │ │ + if (t == 0) return b;
│ │ │ │ │ + if (t == d) return b + c;
│ │ │ │ │ + if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
│ │ │ │ │ + return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Easing.Expo"
│ │ │ │ │ +};
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Namespace: OpenLayers.Easing.Quad
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Easing.Quad = {
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Function: easeIn
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Float}
│ │ │ │ │ + */
│ │ │ │ │ + easeIn: function(t, b, c, d) {
│ │ │ │ │ + return c * (t /= d) * t + b;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Function: easeOut
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Float}
│ │ │ │ │ + */
│ │ │ │ │ + easeOut: function(t, b, c, d) {
│ │ │ │ │ + return -c * (t /= d) * (t - 2) + b;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Function: easeInOut
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Float}
│ │ │ │ │ + */
│ │ │ │ │ + easeInOut: function(t, b, c, d) {
│ │ │ │ │ + if ((t /= d / 2) < 1) return c / 2 * t * t + b;
│ │ │ │ │ + return -c / 2 * ((--t) * (t - 2) - 1) + b;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Easing.Quad"
│ │ │ │ │ +};
│ │ │ │ │ +/* ======================================================================
│ │ │ │ │ OpenLayers/Projection.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. */
│ │ │ │ │ @@ -9645,1311 +12040,1396 @@
│ │ │ │ │ OpenLayers.Map.TILE_WIDTH = 256;
│ │ │ │ │ /**
│ │ │ │ │ * Constant: TILE_HEIGHT
│ │ │ │ │ * {Integer} 256 Default tile height (unless otherwise specified)
│ │ │ │ │ */
│ │ │ │ │ OpenLayers.Map.TILE_HEIGHT = 256;
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Request/XMLHttpRequest.js
│ │ │ │ │ + OpenLayers/Layer.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.
│ │ │ │ │ +/* 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/Request.js
│ │ │ │ │ + * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ + * @requires OpenLayers/Map.js
│ │ │ │ │ + * @requires OpenLayers/Projection.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ -(function() {
│ │ │ │ │ +/**
│ │ │ │ │ + * Class: OpenLayers.Layer
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Layer = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ - // Save reference to earlier defined object implementation (if any)
│ │ │ │ │ - var oXMLHttpRequest = window.XMLHttpRequest;
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: id
│ │ │ │ │ + * {String}
│ │ │ │ │ + */
│ │ │ │ │ + id: null,
│ │ │ │ │
│ │ │ │ │ - // Define on browser type
│ │ │ │ │ - var bGecko = !!window.controllers,
│ │ │ │ │ - bIE = window.document.all && !window.opera,
│ │ │ │ │ - bIE7 = bIE && window.navigator.userAgent.match(/MSIE 7.0/);
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: name
│ │ │ │ │ + * {String}
│ │ │ │ │ + */
│ │ │ │ │ + name: null,
│ │ │ │ │
│ │ │ │ │ - // Enables "XMLHttpRequest()" call next to "new XMLHttpReques()"
│ │ │ │ │ - function fXMLHttpRequest() {
│ │ │ │ │ - this._object = oXMLHttpRequest && !bIE7 ? new oXMLHttpRequest : new window.ActiveXObject("Microsoft.XMLHTTP");
│ │ │ │ │ - this._listeners = [];
│ │ │ │ │ - };
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: div
│ │ │ │ │ + * {DOMElement}
│ │ │ │ │ + */
│ │ │ │ │ + div: null,
│ │ │ │ │
│ │ │ │ │ - // Constructor
│ │ │ │ │ - function cXMLHttpRequest() {
│ │ │ │ │ - return new fXMLHttpRequest;
│ │ │ │ │ - };
│ │ │ │ │ - cXMLHttpRequest.prototype = fXMLHttpRequest.prototype;
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: opacity
│ │ │ │ │ + * {Float} The layer's opacity. Float number between 0.0 and 1.0. Default
│ │ │ │ │ + * is 1.
│ │ │ │ │ + */
│ │ │ │ │ + opacity: 1,
│ │ │ │ │
│ │ │ │ │ - // BUGFIX: Firefox with Firebug installed would break pages if not executed
│ │ │ │ │ - if (bGecko && oXMLHttpRequest.wrapped)
│ │ │ │ │ - cXMLHttpRequest.wrapped = oXMLHttpRequest.wrapped;
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: alwaysInRange
│ │ │ │ │ + * {Boolean} If a layer's display should not be scale-based, this should
│ │ │ │ │ + * be set to true. This will cause the layer, as an overlay, to always
│ │ │ │ │ + * be 'active', by always returning true from the calculateInRange()
│ │ │ │ │ + * function.
│ │ │ │ │ + *
│ │ │ │ │ + * If not explicitly specified for a layer, its value will be
│ │ │ │ │ + * determined on startup in initResolutions() based on whether or not
│ │ │ │ │ + * any scale-specific properties have been set as options on the
│ │ │ │ │ + * layer. If no scale-specific options have been set on the layer, we
│ │ │ │ │ + * assume that it should always be in range.
│ │ │ │ │ + *
│ │ │ │ │ + * See #987 for more info.
│ │ │ │ │ + */
│ │ │ │ │ + alwaysInRange: null,
│ │ │ │ │
│ │ │ │ │ - // Constants
│ │ │ │ │ - cXMLHttpRequest.UNSENT = 0;
│ │ │ │ │ - cXMLHttpRequest.OPENED = 1;
│ │ │ │ │ - cXMLHttpRequest.HEADERS_RECEIVED = 2;
│ │ │ │ │ - cXMLHttpRequest.LOADING = 3;
│ │ │ │ │ - cXMLHttpRequest.DONE = 4;
│ │ │ │ │ + /**
│ │ │ │ │ + * Constant: RESOLUTION_PROPERTIES
│ │ │ │ │ + * {Array} The properties that are used for calculating resolutions
│ │ │ │ │ + * information.
│ │ │ │ │ + */
│ │ │ │ │ + RESOLUTION_PROPERTIES: [
│ │ │ │ │ + 'scales', 'resolutions',
│ │ │ │ │ + 'maxScale', 'minScale',
│ │ │ │ │ + 'maxResolution', 'minResolution',
│ │ │ │ │ + 'numZoomLevels', 'maxZoomLevel'
│ │ │ │ │ + ],
│ │ │ │ │
│ │ │ │ │ - // Public Properties
│ │ │ │ │ - cXMLHttpRequest.prototype.readyState = cXMLHttpRequest.UNSENT;
│ │ │ │ │ - cXMLHttpRequest.prototype.responseText = '';
│ │ │ │ │ - cXMLHttpRequest.prototype.responseXML = null;
│ │ │ │ │ - cXMLHttpRequest.prototype.status = 0;
│ │ │ │ │ - cXMLHttpRequest.prototype.statusText = '';
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: events
│ │ │ │ │ + * {}
│ │ │ │ │ + *
│ │ │ │ │ + * Register a listener for a particular event with the following syntax:
│ │ │ │ │ + * (code)
│ │ │ │ │ + * layer.events.register(type, obj, listener);
│ │ │ │ │ + * (end)
│ │ │ │ │ + *
│ │ │ │ │ + * Listeners will be called with a reference to an event object. The
│ │ │ │ │ + * properties of this event depends on exactly what happened.
│ │ │ │ │ + *
│ │ │ │ │ + * All event objects have at least the following properties:
│ │ │ │ │ + * object - {Object} A reference to layer.events.object.
│ │ │ │ │ + * element - {DOMElement} A reference to layer.events.element.
│ │ │ │ │ + *
│ │ │ │ │ + * Supported map event types:
│ │ │ │ │ + * loadstart - Triggered when layer loading starts. When using a Vector
│ │ │ │ │ + * layer with a Fixed or BBOX strategy, the event object includes
│ │ │ │ │ + * a *filter* property holding the OpenLayers.Filter used when
│ │ │ │ │ + * calling read on the protocol.
│ │ │ │ │ + * loadend - Triggered when layer loading ends. When using a Vector layer
│ │ │ │ │ + * with a Fixed or BBOX strategy, the event object includes a
│ │ │ │ │ + * *response* property holding an OpenLayers.Protocol.Response object.
│ │ │ │ │ + * visibilitychanged - Triggered when the layer's visibility property is
│ │ │ │ │ + * changed, e.g. by turning the layer on or off in the layer switcher.
│ │ │ │ │ + * Note that the actual visibility of the layer can also change if it
│ │ │ │ │ + * gets out of range (see ). If you also want to catch
│ │ │ │ │ + * these cases, register for the map's 'changelayer' event instead.
│ │ │ │ │ + * move - Triggered when layer moves (triggered with every mousemove
│ │ │ │ │ + * during a drag).
│ │ │ │ │ + * moveend - Triggered when layer is done moving, object passed as
│ │ │ │ │ + * argument has a zoomChanged boolean property which tells that the
│ │ │ │ │ + * zoom has changed.
│ │ │ │ │ + * added - Triggered after the layer is added to a map. Listeners will
│ │ │ │ │ + * receive an object with a *map* property referencing the map and a
│ │ │ │ │ + * *layer* property referencing the layer.
│ │ │ │ │ + * removed - Triggered after the layer is removed from the map. Listeners
│ │ │ │ │ + * will receive an object with a *map* property referencing the map and
│ │ │ │ │ + * a *layer* property referencing the layer.
│ │ │ │ │ + */
│ │ │ │ │ + events: null,
│ │ │ │ │
│ │ │ │ │ - // Priority proposal
│ │ │ │ │ - cXMLHttpRequest.prototype.priority = "NORMAL";
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: map
│ │ │ │ │ + * {} This variable is set when the layer is added to
│ │ │ │ │ + * the map, via the accessor function setMap().
│ │ │ │ │ + */
│ │ │ │ │ + map: null,
│ │ │ │ │
│ │ │ │ │ - // Instance-level Events Handlers
│ │ │ │ │ - cXMLHttpRequest.prototype.onreadystatechange = null;
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: isBaseLayer
│ │ │ │ │ + * {Boolean} Whether or not the layer is a base layer. This should be set
│ │ │ │ │ + * individually by all subclasses. Default is false
│ │ │ │ │ + */
│ │ │ │ │ + isBaseLayer: false,
│ │ │ │ │
│ │ │ │ │ - // Class-level Events Handlers
│ │ │ │ │ - cXMLHttpRequest.onreadystatechange = null;
│ │ │ │ │ - cXMLHttpRequest.onopen = null;
│ │ │ │ │ - cXMLHttpRequest.onsend = null;
│ │ │ │ │ - cXMLHttpRequest.onabort = null;
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: alpha
│ │ │ │ │ + * {Boolean} The layer's images have an alpha channel. Default is false.
│ │ │ │ │ + */
│ │ │ │ │ + alpha: false,
│ │ │ │ │
│ │ │ │ │ - // Public Methods
│ │ │ │ │ - cXMLHttpRequest.prototype.open = function(sMethod, sUrl, bAsync, sUser, sPassword) {
│ │ │ │ │ - // Delete headers, required when object is reused
│ │ │ │ │ - delete this._headers;
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: displayInLayerSwitcher
│ │ │ │ │ + * {Boolean} Display the layer's name in the layer switcher. Default is
│ │ │ │ │ + * true.
│ │ │ │ │ + */
│ │ │ │ │ + displayInLayerSwitcher: true,
│ │ │ │ │
│ │ │ │ │ - // When bAsync parameter value is omitted, use true as default
│ │ │ │ │ - if (arguments.length < 3)
│ │ │ │ │ - bAsync = true;
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: visibility
│ │ │ │ │ + * {Boolean} The layer should be displayed in the map. Default is true.
│ │ │ │ │ + */
│ │ │ │ │ + visibility: true,
│ │ │ │ │
│ │ │ │ │ - // Save async parameter for fixing Gecko bug with missing readystatechange in synchronous requests
│ │ │ │ │ - this._async = bAsync;
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: attribution
│ │ │ │ │ + * {String} Attribution string, displayed when an
│ │ │ │ │ + * has been added to the map.
│ │ │ │ │ + */
│ │ │ │ │ + attribution: null,
│ │ │ │ │
│ │ │ │ │ - // Set the onreadystatechange handler
│ │ │ │ │ - var oRequest = this,
│ │ │ │ │ - nState = this.readyState,
│ │ │ │ │ - fOnUnload;
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: inRange
│ │ │ │ │ + * {Boolean} The current map resolution is within the layer's min/max
│ │ │ │ │ + * range. This is set in whenever the zoom
│ │ │ │ │ + * changes.
│ │ │ │ │ + */
│ │ │ │ │ + inRange: false,
│ │ │ │ │
│ │ │ │ │ - // 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);
│ │ │ │ │ - }
│ │ │ │ │ + /**
│ │ │ │ │ + * Propery: imageSize
│ │ │ │ │ + * {} For layers with a gutter, the image is larger than
│ │ │ │ │ + * the tile by twice the gutter in each dimension.
│ │ │ │ │ + */
│ │ │ │ │ + imageSize: null,
│ │ │ │ │
│ │ │ │ │ - // Add method sniffer
│ │ │ │ │ - if (cXMLHttpRequest.onopen)
│ │ │ │ │ - cXMLHttpRequest.onopen.apply(this, arguments);
│ │ │ │ │ + // OPTIONS
│ │ │ │ │
│ │ │ │ │ - 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);
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: options
│ │ │ │ │ + * {Object} An optional object whose properties will be set on the layer.
│ │ │ │ │ + * Any of the layer properties can be set as a property of the options
│ │ │ │ │ + * object and sent to the constructor when the layer is created.
│ │ │ │ │ + */
│ │ │ │ │ + options: null,
│ │ │ │ │
│ │ │ │ │ - this.readyState = cXMLHttpRequest.OPENED;
│ │ │ │ │ - fReadyStateChange(this);
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: eventListeners
│ │ │ │ │ + * {Object} If set as an option at construction, the eventListeners
│ │ │ │ │ + * object will be registered with . Object
│ │ │ │ │ + * structure must be a listeners object as shown in the example for
│ │ │ │ │ + * the events.on method.
│ │ │ │ │ + */
│ │ │ │ │ + eventListeners: null,
│ │ │ │ │
│ │ │ │ │ - this._object.onreadystatechange = function() {
│ │ │ │ │ - if (bGecko && !bAsync)
│ │ │ │ │ - return;
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: gutter
│ │ │ │ │ + * {Integer} Determines the width (in pixels) of the gutter around image
│ │ │ │ │ + * tiles to ignore. By setting this property to a non-zero value,
│ │ │ │ │ + * images will be requested that are wider and taller than the tile
│ │ │ │ │ + * size by a value of 2 x gutter. This allows artifacts of rendering
│ │ │ │ │ + * at tile edges to be ignored. Set a gutter value that is equal to
│ │ │ │ │ + * half the size of the widest symbol that needs to be displayed.
│ │ │ │ │ + * Defaults to zero. Non-tiled layers always have zero gutter.
│ │ │ │ │ + */
│ │ │ │ │ + gutter: 0,
│ │ │ │ │
│ │ │ │ │ - // Synchronize state
│ │ │ │ │ - oRequest.readyState = oRequest._object.readyState;
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: projection
│ │ │ │ │ + * {} or {} Specifies the projection of the layer.
│ │ │ │ │ + * Can be set in the layer options. If not specified in the layer options,
│ │ │ │ │ + * it is set to the default projection specified in the map,
│ │ │ │ │ + * when the layer is added to the map.
│ │ │ │ │ + * Projection along with default maxExtent and resolutions
│ │ │ │ │ + * are set automatically with commercial baselayers in EPSG:3857,
│ │ │ │ │ + * such as Google, Bing and OpenStreetMap, and do not need to be specified.
│ │ │ │ │ + * Otherwise, if specifying projection, also set maxExtent,
│ │ │ │ │ + * maxResolution or resolutions as appropriate.
│ │ │ │ │ + * When using vector layers with strategies, layer projection should be set
│ │ │ │ │ + * to the projection of the source data if that is different from the map default.
│ │ │ │ │ + *
│ │ │ │ │ + * Can be either a string or an object;
│ │ │ │ │ + * if a string is passed, will be converted to an object when
│ │ │ │ │ + * the layer is added to the map.
│ │ │ │ │ + *
│ │ │ │ │ + */
│ │ │ │ │ + projection: null,
│ │ │ │ │
│ │ │ │ │ - //
│ │ │ │ │ - fSynchronizeValues(oRequest);
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: units
│ │ │ │ │ + * {String} The layer map units. Defaults to null. Possible values
│ │ │ │ │ + * are 'degrees' (or 'dd'), 'm', 'ft', 'km', 'mi', 'inches'.
│ │ │ │ │ + * Normally taken from the projection.
│ │ │ │ │ + * Only required if both map and layers do not define a projection,
│ │ │ │ │ + * or if they define a projection which does not define units.
│ │ │ │ │ + */
│ │ │ │ │ + units: null,
│ │ │ │ │
│ │ │ │ │ - // BUGFIX: Firefox fires unnecessary DONE when aborting
│ │ │ │ │ - if (oRequest._aborted) {
│ │ │ │ │ - // Reset readyState to UNSENT
│ │ │ │ │ - oRequest.readyState = cXMLHttpRequest.UNSENT;
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: scales
│ │ │ │ │ + * {Array} An array of map scales in descending order. The values in the
│ │ │ │ │ + * array correspond to the map scale denominator. Note that these
│ │ │ │ │ + * values only make sense if the display (monitor) resolution of the
│ │ │ │ │ + * client is correctly guessed by whomever is configuring the
│ │ │ │ │ + * application. In addition, the units property must also be set.
│ │ │ │ │ + * Use instead wherever possible.
│ │ │ │ │ + */
│ │ │ │ │ + scales: null,
│ │ │ │ │
│ │ │ │ │ - // Return now
│ │ │ │ │ - return;
│ │ │ │ │ - }
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: resolutions
│ │ │ │ │ + * {Array} A list of map resolutions (map units per pixel) in descending
│ │ │ │ │ + * order. If this is not set in the layer constructor, it will be set
│ │ │ │ │ + * based on other resolution related properties (maxExtent,
│ │ │ │ │ + * maxResolution, maxScale, etc.).
│ │ │ │ │ + */
│ │ │ │ │ + resolutions: null,
│ │ │ │ │
│ │ │ │ │ - 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;
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: maxExtent
│ │ │ │ │ + * {|Array} If provided as an array, the array
│ │ │ │ │ + * should consist of four values (left, bottom, right, top).
│ │ │ │ │ + * The maximum extent for the layer. Defaults to null.
│ │ │ │ │ + *
│ │ │ │ │ + * The center of these bounds will not stray outside
│ │ │ │ │ + * of the viewport extent during panning. In addition, if
│ │ │ │ │ + * is set to false, data will not be
│ │ │ │ │ + * requested that falls completely outside of these bounds.
│ │ │ │ │ + */
│ │ │ │ │ + maxExtent: null,
│ │ │ │ │
│ │ │ │ │ - // Instantiate a new transport object
│ │ │ │ │ - cXMLHttpRequest.call(oRequest);
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: minExtent
│ │ │ │ │ + * {|Array} If provided as an array, the array
│ │ │ │ │ + * should consist of four values (left, bottom, right, top).
│ │ │ │ │ + * The minimum extent for the layer. Defaults to null.
│ │ │ │ │ + */
│ │ │ │ │ + minExtent: null,
│ │ │ │ │
│ │ │ │ │ - // 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;
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: maxResolution
│ │ │ │ │ + * {Float} Default max is 360 deg / 256 px, which corresponds to
│ │ │ │ │ + * zoom level 0 on gmaps. Specify a different value in the layer
│ │ │ │ │ + * options if you are not using the default
│ │ │ │ │ + * and displaying the whole world.
│ │ │ │ │ + */
│ │ │ │ │ + maxResolution: null,
│ │ │ │ │
│ │ │ │ │ - // Return
│ │ │ │ │ - return;
│ │ │ │ │ - }
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: minResolution
│ │ │ │ │ + * {Float}
│ │ │ │ │ + */
│ │ │ │ │ + minResolution: null,
│ │ │ │ │
│ │ │ │ │ - if (oRequest.readyState == cXMLHttpRequest.DONE) {
│ │ │ │ │ - // Clean Object
│ │ │ │ │ - fCleanTransport(oRequest);
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: numZoomLevels
│ │ │ │ │ + * {Integer}
│ │ │ │ │ + */
│ │ │ │ │ + numZoomLevels: null,
│ │ │ │ │
│ │ │ │ │ - // get cached request
│ │ │ │ │ - if (oRequest.status == 304)
│ │ │ │ │ - oRequest._object = oRequest._cached;
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: minScale
│ │ │ │ │ + * {Float}
│ │ │ │ │ + */
│ │ │ │ │ + minScale: null,
│ │ │ │ │
│ │ │ │ │ - //
│ │ │ │ │ - delete oRequest._cached;
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: maxScale
│ │ │ │ │ + * {Float}
│ │ │ │ │ + */
│ │ │ │ │ + maxScale: null,
│ │ │ │ │
│ │ │ │ │ - //
│ │ │ │ │ - fSynchronizeValues(oRequest);
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: displayOutsideMaxExtent
│ │ │ │ │ + * {Boolean} Request map tiles that are completely outside of the max
│ │ │ │ │ + * extent for this layer. Defaults to false.
│ │ │ │ │ + */
│ │ │ │ │ + displayOutsideMaxExtent: false,
│ │ │ │ │
│ │ │ │ │ - //
│ │ │ │ │ - fReadyStateChange(oRequest);
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: wrapDateLine
│ │ │ │ │ + * {Boolean} Wraps the world at the international dateline, so the map can
│ │ │ │ │ + * be panned infinitely in longitudinal direction. Only use this on the
│ │ │ │ │ + * base layer, and only if the layer's maxExtent equals the world bounds.
│ │ │ │ │ + * #487 for more info.
│ │ │ │ │ + */
│ │ │ │ │ + wrapDateLine: false,
│ │ │ │ │
│ │ │ │ │ - // BUGFIX: IE - memory leak in interrupted
│ │ │ │ │ - if (bIE && bAsync)
│ │ │ │ │ - window.detachEvent("onunload", fOnUnload);
│ │ │ │ │ - }
│ │ │ │ │ - };
│ │ │ │ │ - oRequest._object.send(null);
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: metadata
│ │ │ │ │ + * {Object} This object can be used to store additional information on a
│ │ │ │ │ + * layer object.
│ │ │ │ │ + */
│ │ │ │ │ + metadata: null,
│ │ │ │ │
│ │ │ │ │ - // Return now - wait until re-sent request is finished
│ │ │ │ │ - return;
│ │ │ │ │ - };
│ │ │ │ │ - */
│ │ │ │ │ - // BUGFIX: IE - memory leak in interrupted
│ │ │ │ │ - if (bIE && bAsync)
│ │ │ │ │ - window.detachEvent("onunload", fOnUnload);
│ │ │ │ │ - }
│ │ │ │ │ + /**
│ │ │ │ │ + * Constructor: OpenLayers.Layer
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * name - {String} The layer name
│ │ │ │ │ + * options - {Object} Hashtable of extra options to tag onto the layer
│ │ │ │ │ + */
│ │ │ │ │ + initialize: function(name, options) {
│ │ │ │ │
│ │ │ │ │ - // BUGFIX: Some browsers (Internet Explorer, Gecko) fire OPEN readystate twice
│ │ │ │ │ - if (nState != oRequest.readyState)
│ │ │ │ │ - fReadyStateChange(oRequest);
│ │ │ │ │ + this.metadata = {};
│ │ │ │ │
│ │ │ │ │ - nState = oRequest.readyState;
│ │ │ │ │ + options = OpenLayers.Util.extend({}, options);
│ │ │ │ │ + // make sure we respect alwaysInRange if set on the prototype
│ │ │ │ │ + if (this.alwaysInRange != null) {
│ │ │ │ │ + options.alwaysInRange = this.alwaysInRange;
│ │ │ │ │ }
│ │ │ │ │ - };
│ │ │ │ │ + this.addOptions(options);
│ │ │ │ │
│ │ │ │ │ - function fXMLHttpRequest_send(oRequest) {
│ │ │ │ │ - oRequest._object.send(oRequest._data);
│ │ │ │ │ + this.name = name;
│ │ │ │ │
│ │ │ │ │ - // BUGFIX: Gecko - missing readystatechange calls in synchronous requests
│ │ │ │ │ - if (bGecko && !oRequest._async) {
│ │ │ │ │ - oRequest.readyState = cXMLHttpRequest.OPENED;
│ │ │ │ │ + if (this.id == null) {
│ │ │ │ │
│ │ │ │ │ - // Synchronize state
│ │ │ │ │ - fSynchronizeValues(oRequest);
│ │ │ │ │ + this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
│ │ │ │ │
│ │ │ │ │ - // 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);
│ │ │ │ │ + this.div = OpenLayers.Util.createDiv(this.id);
│ │ │ │ │ + this.div.style.width = "100%";
│ │ │ │ │ + this.div.style.height = "100%";
│ │ │ │ │ + this.div.dir = "ltr";
│ │ │ │ │
│ │ │ │ │ - if (!arguments.length)
│ │ │ │ │ - vData = null;
│ │ │ │ │ + this.events = new OpenLayers.Events(this, this.div);
│ │ │ │ │ + if (this.eventListeners instanceof Object) {
│ │ │ │ │ + this.events.on(this.eventListeners);
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - // 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);
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: destroy
│ │ │ │ │ + * Destroy is a destructor: this is to alleviate cyclic references which
│ │ │ │ │ + * the Javascript garbage cleaner can not take care of on its own.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * setNewBaseLayer - {Boolean} Set a new base layer when this layer has
│ │ │ │ │ + * been destroyed. Default is true.
│ │ │ │ │ + */
│ │ │ │ │ + destroy: function(setNewBaseLayer) {
│ │ │ │ │ + if (setNewBaseLayer == null) {
│ │ │ │ │ + setNewBaseLayer = true;
│ │ │ │ │ }
│ │ │ │ │ - // 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);
│ │ │ │ │ - };
│ │ │ │ │ + if (this.map != null) {
│ │ │ │ │ + this.map.removeLayer(this, setNewBaseLayer);
│ │ │ │ │ + }
│ │ │ │ │ + this.projection = null;
│ │ │ │ │ + this.map = null;
│ │ │ │ │ + this.name = null;
│ │ │ │ │ + this.div = null;
│ │ │ │ │ + this.options = null;
│ │ │ │ │
│ │ │ │ │ - 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;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ + if (this.events) {
│ │ │ │ │ + if (this.eventListeners) {
│ │ │ │ │ + this.events.un(this.eventListeners);
│ │ │ │ │ }
│ │ │ │ │ - };
│ │ │ │ │ - */
│ │ │ │ │ - // 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;
│ │ │ │ │ - };
│ │ │ │ │ - };
│ │ │ │ │ + this.events.destroy();
│ │ │ │ │ + }
│ │ │ │ │ + this.eventListeners = null;
│ │ │ │ │ + this.events = null;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - // 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/.
│ │ │ │ │ + * Method: clone
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * obj - {} The layer to be cloned
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {} An exact clone of this
│ │ │ │ │ */
│ │ │ │ │ - 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. */
│ │ │ │ │ + clone: function(obj) {
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/Events.js
│ │ │ │ │ - * @requires OpenLayers/Request/XMLHttpRequest.js
│ │ │ │ │ - */
│ │ │ │ │ + if (obj == null) {
│ │ │ │ │ + obj = new OpenLayers.Layer(this.name, this.getOptions());
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * TODO: deprecate me
│ │ │ │ │ - * Use OpenLayers.Request.proxy instead.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.ProxyHost = "";
│ │ │ │ │ + // catch any randomly tagged-on properties
│ │ │ │ │ + OpenLayers.Util.applyDefaults(obj, this);
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * 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, {
│ │ │ │ │ + // a cloned layer should never have its map property set
│ │ │ │ │ + // because it has not been added to a map yet.
│ │ │ │ │ + obj.map = null;
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * 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
│ │ │ │ │ + return obj;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * 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.
│ │ │ │ │ + * Method: getOptions
│ │ │ │ │ + * Extracts an object from the layer with the properties that were set as
│ │ │ │ │ + * options, but updates them with the values currently set on the
│ │ │ │ │ + * instance.
│ │ │ │ │ *
│ │ │ │ │ - * 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.
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Object} the of the layer, representing the current state.
│ │ │ │ │ */
│ │ │ │ │ - events: new OpenLayers.Events(this),
│ │ │ │ │ + getOptions: function() {
│ │ │ │ │ + var options = {};
│ │ │ │ │ + for (var o in this.options) {
│ │ │ │ │ + options[o] = this[o];
│ │ │ │ │ + }
│ │ │ │ │ + return options;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: makeSameOrigin
│ │ │ │ │ - * Using the specified proxy, returns a same origin url of the provided url.
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: setName
│ │ │ │ │ + * Sets the new layer name for this layer. Can trigger a changelayer event
│ │ │ │ │ + * on the map.
│ │ │ │ │ *
│ │ │ │ │ * 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.
│ │ │ │ │ + * newName - {String} The new name.
│ │ │ │ │ */
│ │ │ │ │ - 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);
│ │ │ │ │ - }
│ │ │ │ │ + setName: function(newName) {
│ │ │ │ │ + if (newName != this.name) {
│ │ │ │ │ + this.name = newName;
│ │ │ │ │ + if (this.map != null) {
│ │ │ │ │ + this.map.events.triggerEvent("changelayer", {
│ │ │ │ │ + layer: this,
│ │ │ │ │ + property: "name"
│ │ │ │ │ + });
│ │ │ │ │ }
│ │ │ │ │ }
│ │ │ │ │ - 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.
│ │ │ │ │ - *
│ │ │ │ │ + * APIMethod: addOptions
│ │ │ │ │ + *
│ │ │ │ │ * 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.
│ │ │ │ │ + * newOptions - {Object}
│ │ │ │ │ + * reinitialize - {Boolean} If set to true, and if resolution options of the
│ │ │ │ │ + * current baseLayer were changed, the map will be recentered to make
│ │ │ │ │ + * sure that it is displayed with a valid resolution, and a
│ │ │ │ │ + * changebaselayer event will be triggered.
│ │ │ │ │ */
│ │ │ │ │ - issue: function(config) {
│ │ │ │ │ - // apply default config - proxy host may have changed
│ │ │ │ │ - var defaultConfig = OpenLayers.Util.extend(
│ │ │ │ │ - this.DEFAULT_CONFIG, {
│ │ │ │ │ - proxy: OpenLayers.ProxyHost
│ │ │ │ │ + addOptions: function(newOptions, reinitialize) {
│ │ │ │ │ +
│ │ │ │ │ + if (this.options == null) {
│ │ │ │ │ + this.options = {};
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + if (newOptions) {
│ │ │ │ │ + // make sure this.projection references a projection object
│ │ │ │ │ + if (typeof newOptions.projection == "string") {
│ │ │ │ │ + newOptions.projection = new OpenLayers.Projection(newOptions.projection);
│ │ │ │ │ }
│ │ │ │ │ - );
│ │ │ │ │ - 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 (newOptions.projection) {
│ │ │ │ │ + // get maxResolution, units and maxExtent from projection defaults if
│ │ │ │ │ + // they are not defined already
│ │ │ │ │ + OpenLayers.Util.applyDefaults(newOptions,
│ │ │ │ │ + OpenLayers.Projection.defaults[newOptions.projection.getCode()]);
│ │ │ │ │ + }
│ │ │ │ │ + // allow array for extents
│ │ │ │ │ + if (newOptions.maxExtent && !(newOptions.maxExtent instanceof OpenLayers.Bounds)) {
│ │ │ │ │ + newOptions.maxExtent = new OpenLayers.Bounds(newOptions.maxExtent);
│ │ │ │ │ + }
│ │ │ │ │ + if (newOptions.minExtent && !(newOptions.minExtent instanceof OpenLayers.Bounds)) {
│ │ │ │ │ + newOptions.minExtent = new OpenLayers.Bounds(newOptions.minExtent);
│ │ │ │ │ }
│ │ │ │ │ - }
│ │ │ │ │ - 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]);
│ │ │ │ │ - }
│ │ │ │ │ + // update our copy for clone
│ │ │ │ │ + OpenLayers.Util.extend(this.options, newOptions);
│ │ │ │ │
│ │ │ │ │ - var events = this.events;
│ │ │ │ │ + // add new options to this
│ │ │ │ │ + OpenLayers.Util.extend(this, newOptions);
│ │ │ │ │
│ │ │ │ │ - // we want to execute runCallbacks with "this" as the
│ │ │ │ │ - // execution scope
│ │ │ │ │ - var self = this;
│ │ │ │ │ + // get the units from the projection, if we have a projection
│ │ │ │ │ + // and it it has units
│ │ │ │ │ + if (this.projection && this.projection.getUnits()) {
│ │ │ │ │ + this.units = this.projection.getUnits();
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - request.onreadystatechange = function() {
│ │ │ │ │ - if (request.readyState == OpenLayers.Request.XMLHttpRequest.DONE) {
│ │ │ │ │ - var proceed = events.triggerEvent(
│ │ │ │ │ - "complete", {
│ │ │ │ │ - request: request,
│ │ │ │ │ - config: config,
│ │ │ │ │ - requestUrl: url
│ │ │ │ │ + // re-initialize resolutions if necessary, i.e. if any of the
│ │ │ │ │ + // properties of the "properties" array defined below is set
│ │ │ │ │ + // in the new options
│ │ │ │ │ + if (this.map) {
│ │ │ │ │ + // store current resolution so we can try to restore it later
│ │ │ │ │ + var resolution = this.map.getResolution();
│ │ │ │ │ + var properties = this.RESOLUTION_PROPERTIES.concat(
│ │ │ │ │ + ["projection", "units", "minExtent", "maxExtent"]
│ │ │ │ │ + );
│ │ │ │ │ + for (var o in newOptions) {
│ │ │ │ │ + if (newOptions.hasOwnProperty(o) &&
│ │ │ │ │ + OpenLayers.Util.indexOf(properties, o) >= 0) {
│ │ │ │ │ +
│ │ │ │ │ + this.initResolutions();
│ │ │ │ │ + if (reinitialize && this.map.baseLayer === this) {
│ │ │ │ │ + // update map position, and restore previous resolution
│ │ │ │ │ + this.map.setCenter(this.map.getCenter(),
│ │ │ │ │ + this.map.getZoomForResolution(resolution),
│ │ │ │ │ + false, true
│ │ │ │ │ + );
│ │ │ │ │ + // trigger a changebaselayer event to make sure that
│ │ │ │ │ + // all controls (especially
│ │ │ │ │ + // OpenLayers.Control.PanZoomBar) get notified of the
│ │ │ │ │ + // new options
│ │ │ │ │ + this.map.events.triggerEvent("changebaselayer", {
│ │ │ │ │ + layer: this
│ │ │ │ │ + });
│ │ │ │ │ }
│ │ │ │ │ - );
│ │ │ │ │ - if (proceed !== false) {
│ │ │ │ │ - self.runCallbacks({
│ │ │ │ │ - request: request,
│ │ │ │ │ - config: config,
│ │ │ │ │ - requestUrl: url
│ │ │ │ │ - });
│ │ │ │ │ + break;
│ │ │ │ │ }
│ │ │ │ │ }
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - // 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
│ │ │ │ │ + * APIMethod: onMapResize
│ │ │ │ │ + * This function can be implemented by subclasses
│ │ │ │ │ */
│ │ │ │ │ - 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;
│ │ │ │ │ + onMapResize: function() {
│ │ │ │ │ + //this function can be implemented by subclasses
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - // optional success callback
│ │ │ │ │ - var success;
│ │ │ │ │ - if (config.success) {
│ │ │ │ │ - success = (config.scope) ?
│ │ │ │ │ - OpenLayers.Function.bind(config.success, config.scope) :
│ │ │ │ │ - config.success;
│ │ │ │ │ - }
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: redraw
│ │ │ │ │ + * Redraws the layer. Returns true if the layer was redrawn, false if not.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean} The layer was redrawn.
│ │ │ │ │ + */
│ │ │ │ │ + redraw: function() {
│ │ │ │ │ + var redrawn = false;
│ │ │ │ │ + if (this.map) {
│ │ │ │ │
│ │ │ │ │ - // optional failure callback
│ │ │ │ │ - var failure;
│ │ │ │ │ - if (config.failure) {
│ │ │ │ │ - failure = (config.scope) ?
│ │ │ │ │ - OpenLayers.Function.bind(config.failure, config.scope) :
│ │ │ │ │ - config.failure;
│ │ │ │ │ - }
│ │ │ │ │ + // min/max Range may have changed
│ │ │ │ │ + this.inRange = this.calculateInRange();
│ │ │ │ │
│ │ │ │ │ - if (OpenLayers.Util.createUrlObject(config.url).protocol == "file:" &&
│ │ │ │ │ - request.responseText) {
│ │ │ │ │ - request.status = 200;
│ │ │ │ │ - }
│ │ │ │ │ - complete(request);
│ │ │ │ │ + // map's center might not yet be set
│ │ │ │ │ + var extent = this.getExtent();
│ │ │ │ │
│ │ │ │ │ - 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);
│ │ │ │ │ + if (extent && this.inRange && this.visibility) {
│ │ │ │ │ + var zoomChanged = true;
│ │ │ │ │ + this.moveTo(extent, zoomChanged, false);
│ │ │ │ │ + this.events.triggerEvent("moveend", {
│ │ │ │ │ + "zoomChanged": zoomChanged
│ │ │ │ │ + });
│ │ │ │ │ + redrawn = true;
│ │ │ │ │ }
│ │ │ │ │ }
│ │ │ │ │ + return redrawn;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * 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.
│ │ │ │ │ + * Method: moveTo
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {XMLHttpRequest} Request object.
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * bounds - {}
│ │ │ │ │ + * zoomChanged - {Boolean} Tells when zoom has changed, as layers have to
│ │ │ │ │ + * do some init work in that case.
│ │ │ │ │ + * dragging - {Boolean}
│ │ │ │ │ */
│ │ │ │ │ - GET: function(config) {
│ │ │ │ │ - config = OpenLayers.Util.extend(config, {
│ │ │ │ │ - method: "GET"
│ │ │ │ │ - });
│ │ │ │ │ - return OpenLayers.Request.issue(config);
│ │ │ │ │ + moveTo: function(bounds, zoomChanged, dragging) {
│ │ │ │ │ + var display = this.visibility;
│ │ │ │ │ + if (!this.isBaseLayer) {
│ │ │ │ │ + display = display && this.inRange;
│ │ │ │ │ + }
│ │ │ │ │ + this.display(display);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * 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".
│ │ │ │ │ + * Method: moveByPx
│ │ │ │ │ + * Move the layer based on pixel vector. To be implemented by subclasses.
│ │ │ │ │ *
│ │ │ │ │ * 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.
│ │ │ │ │ + * dx - {Number} The x coord of the displacement vector.
│ │ │ │ │ + * dy - {Number} The y coord of the displacement vector.
│ │ │ │ │ + */
│ │ │ │ │ + moveByPx: function(dx, dy) {},
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: setMap
│ │ │ │ │ + * Set the map property for the layer. This is done through an accessor
│ │ │ │ │ + * so that subclasses can override this and take special action once
│ │ │ │ │ + * they have their map variable set.
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {XMLHttpRequest} Request object.
│ │ │ │ │ + * Here we take care to bring over any of the necessary default
│ │ │ │ │ + * properties from the map.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * map - {}
│ │ │ │ │ */
│ │ │ │ │ - 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";
│ │ │ │ │ + setMap: function(map) {
│ │ │ │ │ + if (this.map == null) {
│ │ │ │ │ +
│ │ │ │ │ + this.map = map;
│ │ │ │ │ +
│ │ │ │ │ + // grab some essential layer data from the map if it hasn't already
│ │ │ │ │ + // been set
│ │ │ │ │ + this.maxExtent = this.maxExtent || this.map.maxExtent;
│ │ │ │ │ + this.minExtent = this.minExtent || this.map.minExtent;
│ │ │ │ │ +
│ │ │ │ │ + this.projection = this.projection || this.map.projection;
│ │ │ │ │ + if (typeof this.projection == "string") {
│ │ │ │ │ + this.projection = new OpenLayers.Projection(this.projection);
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + // Check the projection to see if we can get units -- if not, refer
│ │ │ │ │ + // to properties.
│ │ │ │ │ + this.units = this.projection.getUnits() ||
│ │ │ │ │ + this.units || this.map.units;
│ │ │ │ │ +
│ │ │ │ │ + this.initResolutions();
│ │ │ │ │ +
│ │ │ │ │ + if (!this.isBaseLayer) {
│ │ │ │ │ + this.inRange = this.calculateInRange();
│ │ │ │ │ + var show = ((this.visibility) && (this.inRange));
│ │ │ │ │ + this.div.style.display = show ? "" : "none";
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + // deal with gutters
│ │ │ │ │ + this.setTileSize();
│ │ │ │ │ }
│ │ │ │ │ - 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.
│ │ │ │ │ + * Method: afterAdd
│ │ │ │ │ + * Called at the end of the map.addLayer sequence. At this point, the map
│ │ │ │ │ + * will have a base layer. To be overridden by subclasses.
│ │ │ │ │ + */
│ │ │ │ │ + afterAdd: function() {},
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: removeMap
│ │ │ │ │ + * Just as setMap() allows each layer the possibility to take a
│ │ │ │ │ + * personalized action on being added to the map, removeMap() allows
│ │ │ │ │ + * each layer to take a personalized action on being removed from it.
│ │ │ │ │ + * For now, this will be mostly unused, except for the EventPane layer,
│ │ │ │ │ + * which needs this hook so that it can remove the special invisible
│ │ │ │ │ + * pane.
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {XMLHttpRequest} Request object.
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * map - {}
│ │ │ │ │ */
│ │ │ │ │ - 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);
│ │ │ │ │ + removeMap: function(map) {
│ │ │ │ │ + //to be overridden by subclasses
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: DELETE
│ │ │ │ │ - * Send an HTTP DELETE request. Additional configuration properties are
│ │ │ │ │ - * documented in the method, with the method property set
│ │ │ │ │ - * to DELETE.
│ │ │ │ │ + * APIMethod: getImageSize
│ │ │ │ │ *
│ │ │ │ │ * 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.
│ │ │ │ │ + * bounds - {} optional tile bounds, can be used
│ │ │ │ │ + * by subclasses that have to deal with different tile sizes at the
│ │ │ │ │ + * layer extent edges (e.g. Zoomify)
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {XMLHttpRequest} Request object.
│ │ │ │ │ + * {} The size that the image should be, taking into
│ │ │ │ │ + * account gutters.
│ │ │ │ │ */
│ │ │ │ │ - DELETE: function(config) {
│ │ │ │ │ - config = OpenLayers.Util.extend(config, {
│ │ │ │ │ - method: "DELETE"
│ │ │ │ │ - });
│ │ │ │ │ - return OpenLayers.Request.issue(config);
│ │ │ │ │ + getImageSize: function(bounds) {
│ │ │ │ │ + return (this.imageSize || this.tileSize);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * 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.
│ │ │ │ │ + * APIMethod: setTileSize
│ │ │ │ │ + * Set the tile size based on the map size. This also sets layer.imageSize
│ │ │ │ │ + * or use by Tile.Image.
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {XMLHttpRequest} Request object.
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * size - {}
│ │ │ │ │ */
│ │ │ │ │ - HEAD: function(config) {
│ │ │ │ │ - config = OpenLayers.Util.extend(config, {
│ │ │ │ │ - method: "HEAD"
│ │ │ │ │ - });
│ │ │ │ │ - return OpenLayers.Request.issue(config);
│ │ │ │ │ + setTileSize: function(size) {
│ │ │ │ │ + var tileSize = (size) ? size :
│ │ │ │ │ + ((this.tileSize) ? this.tileSize :
│ │ │ │ │ + this.map.getTileSize());
│ │ │ │ │ + this.tileSize = tileSize;
│ │ │ │ │ + if (this.gutter) {
│ │ │ │ │ + // layers with gutters need non-null tile sizes
│ │ │ │ │ + //if(tileSize == null) {
│ │ │ │ │ + // OpenLayers.console.error("Error in layer.setMap() for " +
│ │ │ │ │ + // this.name + ": layers with " +
│ │ │ │ │ + // "gutters need non-null tile sizes");
│ │ │ │ │ + //}
│ │ │ │ │ + this.imageSize = new OpenLayers.Size(tileSize.w + (2 * this.gutter),
│ │ │ │ │ + tileSize.h + (2 * this.gutter));
│ │ │ │ │ + }
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * 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.
│ │ │ │ │ + * APIMethod: getVisibility
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {XMLHttpRequest} Request object.
│ │ │ │ │ + * {Boolean} The layer should be displayed (if in range).
│ │ │ │ │ */
│ │ │ │ │ - OPTIONS: function(config) {
│ │ │ │ │ - config = OpenLayers.Util.extend(config, {
│ │ │ │ │ - method: "OPTIONS"
│ │ │ │ │ - });
│ │ │ │ │ - return OpenLayers.Request.issue(config);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ -});
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Control.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.Control
│ │ │ │ │ - * Controls affect the display or behavior of the map. They allow everything
│ │ │ │ │ - * from panning and zooming to displaying a scale indicator. Controls by
│ │ │ │ │ - * default are added to the map they are contained within however it is
│ │ │ │ │ - * possible to add a control to an external div by passing the div in the
│ │ │ │ │ - * options parameter.
│ │ │ │ │ - *
│ │ │ │ │ - * Example:
│ │ │ │ │ - * The following example shows how to add many of the common controls
│ │ │ │ │ - * to a map.
│ │ │ │ │ - *
│ │ │ │ │ - * > var map = new OpenLayers.Map('map', { controls: [] });
│ │ │ │ │ - * >
│ │ │ │ │ - * > map.addControl(new OpenLayers.Control.PanZoomBar());
│ │ │ │ │ - * > map.addControl(new OpenLayers.Control.LayerSwitcher({'ascending':false}));
│ │ │ │ │ - * > map.addControl(new OpenLayers.Control.Permalink());
│ │ │ │ │ - * > map.addControl(new OpenLayers.Control.Permalink('permalink'));
│ │ │ │ │ - * > map.addControl(new OpenLayers.Control.MousePosition());
│ │ │ │ │ - * > map.addControl(new OpenLayers.Control.OverviewMap());
│ │ │ │ │ - * > map.addControl(new OpenLayers.Control.KeyboardDefaults());
│ │ │ │ │ - *
│ │ │ │ │ - * The next code fragment is a quick example of how to intercept
│ │ │ │ │ - * shift-mouse click to display the extent of the bounding box
│ │ │ │ │ - * dragged out by the user. Usually controls are not created
│ │ │ │ │ - * in exactly this manner. See the source for a more complete
│ │ │ │ │ - * example:
│ │ │ │ │ - *
│ │ │ │ │ - * > var control = new OpenLayers.Control();
│ │ │ │ │ - * > OpenLayers.Util.extend(control, {
│ │ │ │ │ - * > draw: function () {
│ │ │ │ │ - * > // this Handler.Box will intercept the shift-mousedown
│ │ │ │ │ - * > // before Control.MouseDefault gets to see it
│ │ │ │ │ - * > this.box = new OpenLayers.Handler.Box( control,
│ │ │ │ │ - * > {"done": this.notice},
│ │ │ │ │ - * > {keyMask: OpenLayers.Handler.MOD_SHIFT});
│ │ │ │ │ - * > this.box.activate();
│ │ │ │ │ - * > },
│ │ │ │ │ - * >
│ │ │ │ │ - * > notice: function (bounds) {
│ │ │ │ │ - * > OpenLayers.Console.userError(bounds);
│ │ │ │ │ - * > }
│ │ │ │ │ - * > });
│ │ │ │ │ - * > map.addControl(control);
│ │ │ │ │ - *
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Control = OpenLayers.Class({
│ │ │ │ │ + getVisibility: function() {
│ │ │ │ │ + return this.visibility;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: id
│ │ │ │ │ - * {String}
│ │ │ │ │ + * APIMethod: setVisibility
│ │ │ │ │ + * Set the visibility flag for the layer and hide/show & redraw
│ │ │ │ │ + * accordingly. Fire event unless otherwise specified
│ │ │ │ │ + *
│ │ │ │ │ + * Note that visibility is no longer simply whether or not the layer's
│ │ │ │ │ + * style.display is set to "block". Now we store a 'visibility' state
│ │ │ │ │ + * property on the layer class, this allows us to remember whether or
│ │ │ │ │ + * not we *desire* for a layer to be visible. In the case where the
│ │ │ │ │ + * map's resolution is out of the layer's range, this desire may be
│ │ │ │ │ + * subverted.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * visibility - {Boolean} Whether or not to display the layer (if in range)
│ │ │ │ │ */
│ │ │ │ │ - id: null,
│ │ │ │ │ + setVisibility: function(visibility) {
│ │ │ │ │ + if (visibility != this.visibility) {
│ │ │ │ │ + this.visibility = visibility;
│ │ │ │ │ + this.display(visibility);
│ │ │ │ │ + this.redraw();
│ │ │ │ │ + if (this.map != null) {
│ │ │ │ │ + this.map.events.triggerEvent("changelayer", {
│ │ │ │ │ + layer: this,
│ │ │ │ │ + property: "visibility"
│ │ │ │ │ + });
│ │ │ │ │ + }
│ │ │ │ │ + this.events.triggerEvent("visibilitychanged");
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: map
│ │ │ │ │ - * {} this gets set in the addControl() function in
│ │ │ │ │ - * OpenLayers.Map
│ │ │ │ │ + * APIMethod: display
│ │ │ │ │ + * Hide or show the Layer. This is designed to be used internally, and
│ │ │ │ │ + * is not generally the way to enable or disable the layer. For that,
│ │ │ │ │ + * use the setVisibility function instead..
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * display - {Boolean}
│ │ │ │ │ */
│ │ │ │ │ - map: null,
│ │ │ │ │ + display: function(display) {
│ │ │ │ │ + if (display != (this.div.style.display != "none")) {
│ │ │ │ │ + this.div.style.display = (display && this.calculateInRange()) ? "block" : "none";
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: div
│ │ │ │ │ - * {DOMElement} The element that contains the control, if not present the
│ │ │ │ │ - * control is placed inside the map.
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: calculateInRange
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean} The layer is displayable at the current map's current
│ │ │ │ │ + * resolution. Note that if 'alwaysInRange' is true for the layer,
│ │ │ │ │ + * this function will always return true.
│ │ │ │ │ */
│ │ │ │ │ - div: null,
│ │ │ │ │ + calculateInRange: function() {
│ │ │ │ │ + var inRange = false;
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: type
│ │ │ │ │ - * {Number} Controls can have a 'type'. The type determines the type of
│ │ │ │ │ - * interactions which are possible with them when they are placed in an
│ │ │ │ │ - * .
│ │ │ │ │ - */
│ │ │ │ │ - type: null,
│ │ │ │ │ + if (this.alwaysInRange) {
│ │ │ │ │ + inRange = true;
│ │ │ │ │ + } else {
│ │ │ │ │ + if (this.map) {
│ │ │ │ │ + var resolution = this.map.getResolution();
│ │ │ │ │ + inRange = ((resolution >= this.minResolution) &&
│ │ │ │ │ + (resolution <= this.maxResolution));
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + return inRange;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: allowSelection
│ │ │ │ │ - * {Boolean} By default, controls do not allow selection, because
│ │ │ │ │ - * it may interfere with map dragging. If this is true, OpenLayers
│ │ │ │ │ - * will not prevent selection of the control.
│ │ │ │ │ - * Default is false.
│ │ │ │ │ + * APIMethod: setIsBaseLayer
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * isBaseLayer - {Boolean}
│ │ │ │ │ */
│ │ │ │ │ - allowSelection: false,
│ │ │ │ │ + setIsBaseLayer: function(isBaseLayer) {
│ │ │ │ │ + if (isBaseLayer != this.isBaseLayer) {
│ │ │ │ │ + this.isBaseLayer = isBaseLayer;
│ │ │ │ │ + if (this.map != null) {
│ │ │ │ │ + this.map.events.triggerEvent("changebaselayer", {
│ │ │ │ │ + layer: this
│ │ │ │ │ + });
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /********************************************************/
│ │ │ │ │ + /* */
│ │ │ │ │ + /* Baselayer Functions */
│ │ │ │ │ + /* */
│ │ │ │ │ + /********************************************************/
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: displayClass
│ │ │ │ │ - * {string} This property is used for CSS related to the drawing of the
│ │ │ │ │ - * Control.
│ │ │ │ │ + * Method: initResolutions
│ │ │ │ │ + * This method's responsibility is to set up the 'resolutions' array
│ │ │ │ │ + * for the layer -- this array is what the layer will use to interface
│ │ │ │ │ + * between the zoom levels of the map and the resolution display
│ │ │ │ │ + * of the layer.
│ │ │ │ │ + *
│ │ │ │ │ + * The user has several options that determine how the array is set up.
│ │ │ │ │ + *
│ │ │ │ │ + * For a detailed explanation, see the following wiki from the
│ │ │ │ │ + * openlayers.org homepage:
│ │ │ │ │ + * http://trac.openlayers.org/wiki/SettingZoomLevels
│ │ │ │ │ */
│ │ │ │ │ - displayClass: "",
│ │ │ │ │ + initResolutions: function() {
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: title
│ │ │ │ │ - * {string} This property is used for showing a tooltip over the
│ │ │ │ │ - * Control.
│ │ │ │ │ - */
│ │ │ │ │ - title: "",
│ │ │ │ │ + // ok we want resolutions, here's our strategy:
│ │ │ │ │ + //
│ │ │ │ │ + // 1. if resolutions are defined in the layer config, use them
│ │ │ │ │ + // 2. else, if scales are defined in the layer config then derive
│ │ │ │ │ + // resolutions from these scales
│ │ │ │ │ + // 3. else, attempt to calculate resolutions from maxResolution,
│ │ │ │ │ + // minResolution, numZoomLevels, maxZoomLevel set in the
│ │ │ │ │ + // layer config
│ │ │ │ │ + // 4. if we still don't have resolutions, and if resolutions
│ │ │ │ │ + // are defined in the same, use them
│ │ │ │ │ + // 5. else, if scales are defined in the map then derive
│ │ │ │ │ + // resolutions from these scales
│ │ │ │ │ + // 6. else, attempt to calculate resolutions from maxResolution,
│ │ │ │ │ + // minResolution, numZoomLevels, maxZoomLevel set in the
│ │ │ │ │ + // map
│ │ │ │ │ + // 7. hope for the best!
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: autoActivate
│ │ │ │ │ - * {Boolean} Activate the control when it is added to a map. Default is
│ │ │ │ │ - * false.
│ │ │ │ │ - */
│ │ │ │ │ - autoActivate: false,
│ │ │ │ │ + var i, len, p;
│ │ │ │ │ + var props = {},
│ │ │ │ │ + alwaysInRange = true;
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: active
│ │ │ │ │ - * {Boolean} The control is active (read-only). Use and
│ │ │ │ │ - * to change control state.
│ │ │ │ │ - */
│ │ │ │ │ - active: null,
│ │ │ │ │ + // get resolution data from layer config
│ │ │ │ │ + // (we also set alwaysInRange in the layer as appropriate)
│ │ │ │ │ + for (i = 0, len = this.RESOLUTION_PROPERTIES.length; i < len; i++) {
│ │ │ │ │ + p = this.RESOLUTION_PROPERTIES[i];
│ │ │ │ │ + props[p] = this.options[p];
│ │ │ │ │ + if (alwaysInRange && this.options[p]) {
│ │ │ │ │ + alwaysInRange = false;
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + if (this.options.alwaysInRange == null) {
│ │ │ │ │ + this.alwaysInRange = alwaysInRange;
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: handlerOptions
│ │ │ │ │ - * {Object} Used to set non-default properties on the control's handler
│ │ │ │ │ - */
│ │ │ │ │ - handlerOptions: null,
│ │ │ │ │ + // if we don't have resolutions then attempt to derive them from scales
│ │ │ │ │ + if (props.resolutions == null) {
│ │ │ │ │ + props.resolutions = this.resolutionsFromScales(props.scales);
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: handler
│ │ │ │ │ - * {} null
│ │ │ │ │ - */
│ │ │ │ │ - handler: null,
│ │ │ │ │ + // if we still don't have resolutions then attempt to calculate them
│ │ │ │ │ + if (props.resolutions == null) {
│ │ │ │ │ + props.resolutions = this.calculateResolutions(props);
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: eventListeners
│ │ │ │ │ - * {Object} If set as an option at construction, the eventListeners
│ │ │ │ │ - * object will be registered with . Object
│ │ │ │ │ - * structure must be a listeners object as shown in the example for
│ │ │ │ │ - * the events.on method.
│ │ │ │ │ - */
│ │ │ │ │ - eventListeners: null,
│ │ │ │ │ + // if we couldn't calculate resolutions then we look at we have
│ │ │ │ │ + // in the map
│ │ │ │ │ + if (props.resolutions == null) {
│ │ │ │ │ + for (i = 0, len = this.RESOLUTION_PROPERTIES.length; i < len; i++) {
│ │ │ │ │ + p = this.RESOLUTION_PROPERTIES[i];
│ │ │ │ │ + props[p] = this.options[p] != null ?
│ │ │ │ │ + this.options[p] : this.map[p];
│ │ │ │ │ + }
│ │ │ │ │ + if (props.resolutions == null) {
│ │ │ │ │ + props.resolutions = this.resolutionsFromScales(props.scales);
│ │ │ │ │ + }
│ │ │ │ │ + if (props.resolutions == null) {
│ │ │ │ │ + props.resolutions = this.calculateResolutions(props);
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: events
│ │ │ │ │ - * {} Events instance for listeners and triggering
│ │ │ │ │ - * control specific events.
│ │ │ │ │ - *
│ │ │ │ │ - * Register a listener for a particular event with the following syntax:
│ │ │ │ │ - * (code)
│ │ │ │ │ - * control.events.register(type, obj, listener);
│ │ │ │ │ - * (end)
│ │ │ │ │ - *
│ │ │ │ │ - * Listeners will be called with a reference to an event object. The
│ │ │ │ │ - * properties of this event depends on exactly what happened.
│ │ │ │ │ + // ok, we new need to set properties in the instance
│ │ │ │ │ +
│ │ │ │ │ + // get maxResolution from the config if it's defined there
│ │ │ │ │ + var maxResolution;
│ │ │ │ │ + if (this.options.maxResolution &&
│ │ │ │ │ + this.options.maxResolution !== "auto") {
│ │ │ │ │ + maxResolution = this.options.maxResolution;
│ │ │ │ │ + }
│ │ │ │ │ + if (this.options.minScale) {
│ │ │ │ │ + maxResolution = OpenLayers.Util.getResolutionFromScale(
│ │ │ │ │ + this.options.minScale, this.units);
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + // get minResolution from the config if it's defined there
│ │ │ │ │ + var minResolution;
│ │ │ │ │ + if (this.options.minResolution &&
│ │ │ │ │ + this.options.minResolution !== "auto") {
│ │ │ │ │ + minResolution = this.options.minResolution;
│ │ │ │ │ + }
│ │ │ │ │ + if (this.options.maxScale) {
│ │ │ │ │ + minResolution = OpenLayers.Util.getResolutionFromScale(
│ │ │ │ │ + this.options.maxScale, this.units);
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + if (props.resolutions) {
│ │ │ │ │ +
│ │ │ │ │ + //sort resolutions array descendingly
│ │ │ │ │ + props.resolutions.sort(function(a, b) {
│ │ │ │ │ + return (b - a);
│ │ │ │ │ + });
│ │ │ │ │ +
│ │ │ │ │ + // if we still don't have a maxResolution get it from the
│ │ │ │ │ + // resolutions array
│ │ │ │ │ + if (!maxResolution) {
│ │ │ │ │ + maxResolution = props.resolutions[0];
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + // if we still don't have a minResolution get it from the
│ │ │ │ │ + // resolutions array
│ │ │ │ │ + if (!minResolution) {
│ │ │ │ │ + var lastIdx = props.resolutions.length - 1;
│ │ │ │ │ + minResolution = props.resolutions[lastIdx];
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + this.resolutions = props.resolutions;
│ │ │ │ │ + if (this.resolutions) {
│ │ │ │ │ + len = this.resolutions.length;
│ │ │ │ │ + this.scales = new Array(len);
│ │ │ │ │ + for (i = 0; i < len; i++) {
│ │ │ │ │ + this.scales[i] = OpenLayers.Util.getScaleFromResolution(
│ │ │ │ │ + this.resolutions[i], this.units);
│ │ │ │ │ + }
│ │ │ │ │ + this.numZoomLevels = len;
│ │ │ │ │ + }
│ │ │ │ │ + this.minResolution = minResolution;
│ │ │ │ │ + if (minResolution) {
│ │ │ │ │ + this.maxScale = OpenLayers.Util.getScaleFromResolution(
│ │ │ │ │ + minResolution, this.units);
│ │ │ │ │ + }
│ │ │ │ │ + this.maxResolution = maxResolution;
│ │ │ │ │ + if (maxResolution) {
│ │ │ │ │ + this.minScale = OpenLayers.Util.getScaleFromResolution(
│ │ │ │ │ + maxResolution, this.units);
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: resolutionsFromScales
│ │ │ │ │ + * Derive resolutions from scales.
│ │ │ │ │ *
│ │ │ │ │ - * All event objects have at least the following properties:
│ │ │ │ │ - * object - {Object} A reference to control.events.object (a reference
│ │ │ │ │ - * to the control).
│ │ │ │ │ - * element - {DOMElement} A reference to control.events.element (which
│ │ │ │ │ - * will be null unless documented otherwise).
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * scales - {Array(Number)} Scales
│ │ │ │ │ *
│ │ │ │ │ - * Supported map event types:
│ │ │ │ │ - * activate - Triggered when activated.
│ │ │ │ │ - * deactivate - Triggered when deactivated.
│ │ │ │ │ + * Returns
│ │ │ │ │ + * {Array(Number)} Resolutions
│ │ │ │ │ */
│ │ │ │ │ - events: null,
│ │ │ │ │ + resolutionsFromScales: function(scales) {
│ │ │ │ │ + if (scales == null) {
│ │ │ │ │ + return;
│ │ │ │ │ + }
│ │ │ │ │ + var resolutions, i, len;
│ │ │ │ │ + len = scales.length;
│ │ │ │ │ + resolutions = new Array(len);
│ │ │ │ │ + for (i = 0; i < len; i++) {
│ │ │ │ │ + resolutions[i] = OpenLayers.Util.getResolutionFromScale(
│ │ │ │ │ + scales[i], this.units);
│ │ │ │ │ + }
│ │ │ │ │ + return resolutions;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constructor: OpenLayers.Control
│ │ │ │ │ - * Create an OpenLayers Control. The options passed as a parameter
│ │ │ │ │ - * directly extend the control. For example passing the following:
│ │ │ │ │ - *
│ │ │ │ │ - * > var control = new OpenLayers.Control({div: myDiv});
│ │ │ │ │ + * Method: calculateResolutions
│ │ │ │ │ + * Calculate resolutions based on the provided properties.
│ │ │ │ │ *
│ │ │ │ │ - * Overrides the default div attribute value of null.
│ │ │ │ │ - *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * options - {Object}
│ │ │ │ │ + * props - {Object} Properties
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Array({Number})} Array of resolutions.
│ │ │ │ │ */
│ │ │ │ │ - initialize: function(options) {
│ │ │ │ │ - // We do this before the extend so that instances can override
│ │ │ │ │ - // className in options.
│ │ │ │ │ - this.displayClass =
│ │ │ │ │ - this.CLASS_NAME.replace("OpenLayers.", "ol").replace(/\./g, "");
│ │ │ │ │ + calculateResolutions: function(props) {
│ │ │ │ │
│ │ │ │ │ - OpenLayers.Util.extend(this, options);
│ │ │ │ │ + var viewSize, wRes, hRes;
│ │ │ │ │
│ │ │ │ │ - this.events = new OpenLayers.Events(this);
│ │ │ │ │ - if (this.eventListeners instanceof Object) {
│ │ │ │ │ - this.events.on(this.eventListeners);
│ │ │ │ │ + // determine maxResolution
│ │ │ │ │ + var maxResolution = props.maxResolution;
│ │ │ │ │ + if (props.minScale != null) {
│ │ │ │ │ + maxResolution =
│ │ │ │ │ + OpenLayers.Util.getResolutionFromScale(props.minScale,
│ │ │ │ │ + this.units);
│ │ │ │ │ + } else if (maxResolution == "auto" && this.maxExtent != null) {
│ │ │ │ │ + viewSize = this.map.getSize();
│ │ │ │ │ + wRes = this.maxExtent.getWidth() / viewSize.w;
│ │ │ │ │ + hRes = this.maxExtent.getHeight() / viewSize.h;
│ │ │ │ │ + maxResolution = Math.max(wRes, hRes);
│ │ │ │ │ }
│ │ │ │ │ - if (this.id == null) {
│ │ │ │ │ - this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
│ │ │ │ │ +
│ │ │ │ │ + // determine minResolution
│ │ │ │ │ + var minResolution = props.minResolution;
│ │ │ │ │ + if (props.maxScale != null) {
│ │ │ │ │ + minResolution =
│ │ │ │ │ + OpenLayers.Util.getResolutionFromScale(props.maxScale,
│ │ │ │ │ + this.units);
│ │ │ │ │ + } else if (props.minResolution == "auto" && this.minExtent != null) {
│ │ │ │ │ + viewSize = this.map.getSize();
│ │ │ │ │ + wRes = this.minExtent.getWidth() / viewSize.w;
│ │ │ │ │ + hRes = this.minExtent.getHeight() / viewSize.h;
│ │ │ │ │ + minResolution = Math.max(wRes, hRes);
│ │ │ │ │ }
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: destroy
│ │ │ │ │ - * The destroy method is used to perform any clean up before the control
│ │ │ │ │ - * is dereferenced. Typically this is where event listeners are removed
│ │ │ │ │ - * to prevent memory leaks.
│ │ │ │ │ - */
│ │ │ │ │ - destroy: function() {
│ │ │ │ │ - if (this.events) {
│ │ │ │ │ - if (this.eventListeners) {
│ │ │ │ │ - this.events.un(this.eventListeners);
│ │ │ │ │ - }
│ │ │ │ │ - this.events.destroy();
│ │ │ │ │ - this.events = null;
│ │ │ │ │ + if (typeof maxResolution !== "number" &&
│ │ │ │ │ + typeof minResolution !== "number" &&
│ │ │ │ │ + this.maxExtent != null) {
│ │ │ │ │ + // maxResolution for default grid sets assumes that at zoom
│ │ │ │ │ + // level zero, the whole world fits on one tile.
│ │ │ │ │ + var tileSize = this.map.getTileSize();
│ │ │ │ │ + maxResolution = Math.max(
│ │ │ │ │ + this.maxExtent.getWidth() / tileSize.w,
│ │ │ │ │ + this.maxExtent.getHeight() / tileSize.h
│ │ │ │ │ + );
│ │ │ │ │ }
│ │ │ │ │ - this.eventListeners = null;
│ │ │ │ │
│ │ │ │ │ - // eliminate circular references
│ │ │ │ │ - if (this.handler) {
│ │ │ │ │ - this.handler.destroy();
│ │ │ │ │ - this.handler = null;
│ │ │ │ │ + // determine numZoomLevels
│ │ │ │ │ + var maxZoomLevel = props.maxZoomLevel;
│ │ │ │ │ + var numZoomLevels = props.numZoomLevels;
│ │ │ │ │ + if (typeof minResolution === "number" &&
│ │ │ │ │ + typeof maxResolution === "number" && numZoomLevels === undefined) {
│ │ │ │ │ + var ratio = maxResolution / minResolution;
│ │ │ │ │ + numZoomLevels = Math.floor(Math.log(ratio) / Math.log(2)) + 1;
│ │ │ │ │ + } else if (numZoomLevels === undefined && maxZoomLevel != null) {
│ │ │ │ │ + numZoomLevels = maxZoomLevel + 1;
│ │ │ │ │ }
│ │ │ │ │ - if (this.handlers) {
│ │ │ │ │ - for (var key in this.handlers) {
│ │ │ │ │ - if (this.handlers.hasOwnProperty(key) &&
│ │ │ │ │ - typeof this.handlers[key].destroy == "function") {
│ │ │ │ │ - this.handlers[key].destroy();
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - this.handlers = null;
│ │ │ │ │ +
│ │ │ │ │ + // are we able to calculate resolutions?
│ │ │ │ │ + if (typeof numZoomLevels !== "number" || numZoomLevels <= 0 ||
│ │ │ │ │ + (typeof maxResolution !== "number" &&
│ │ │ │ │ + typeof minResolution !== "number")) {
│ │ │ │ │ + return;
│ │ │ │ │ }
│ │ │ │ │ - if (this.map) {
│ │ │ │ │ - this.map.removeControl(this);
│ │ │ │ │ - this.map = null;
│ │ │ │ │ +
│ │ │ │ │ + // now we have numZoomLevels and at least one of maxResolution
│ │ │ │ │ + // or minResolution, we can populate the resolutions array
│ │ │ │ │ +
│ │ │ │ │ + var resolutions = new Array(numZoomLevels);
│ │ │ │ │ + var base = 2;
│ │ │ │ │ + if (typeof minResolution == "number" &&
│ │ │ │ │ + typeof maxResolution == "number") {
│ │ │ │ │ + // if maxResolution and minResolution are set, we calculate
│ │ │ │ │ + // the base for exponential scaling that starts at
│ │ │ │ │ + // maxResolution and ends at minResolution in numZoomLevels
│ │ │ │ │ + // steps.
│ │ │ │ │ + base = Math.pow(
│ │ │ │ │ + (maxResolution / minResolution),
│ │ │ │ │ + (1 / (numZoomLevels - 1))
│ │ │ │ │ + );
│ │ │ │ │ }
│ │ │ │ │ - this.div = null;
│ │ │ │ │ +
│ │ │ │ │ + var i;
│ │ │ │ │ + if (typeof maxResolution === "number") {
│ │ │ │ │ + for (i = 0; i < numZoomLevels; i++) {
│ │ │ │ │ + resolutions[i] = maxResolution / Math.pow(base, i);
│ │ │ │ │ + }
│ │ │ │ │ + } else {
│ │ │ │ │ + for (i = 0; i < numZoomLevels; i++) {
│ │ │ │ │ + resolutions[numZoomLevels - 1 - i] =
│ │ │ │ │ + minResolution * Math.pow(base, i);
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + return resolutions;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: getResolution
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Float} The currently selected resolution of the map, taken from the
│ │ │ │ │ + * resolutions array, indexed by current zoom level.
│ │ │ │ │ + */
│ │ │ │ │ + getResolution: function() {
│ │ │ │ │ + var zoom = this.map.getZoom();
│ │ │ │ │ + return this.getResolutionForZoom(zoom);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: setMap
│ │ │ │ │ - * Set the map property for the control. This is done through an accessor
│ │ │ │ │ - * so that subclasses can override this and take special action once
│ │ │ │ │ - * they have their map variable set.
│ │ │ │ │ + * APIMethod: getExtent
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {} A Bounds object which represents the lon/lat
│ │ │ │ │ + * bounds of the current viewPort.
│ │ │ │ │ + */
│ │ │ │ │ + getExtent: function() {
│ │ │ │ │ + // just use stock map calculateBounds function -- passing no arguments
│ │ │ │ │ + // means it will user map's current center & resolution
│ │ │ │ │ + //
│ │ │ │ │ + return this.map.calculateBounds();
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: getZoomForExtent
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * extent - {}
│ │ │ │ │ + * closest - {Boolean} Find the zoom level that most closely fits the
│ │ │ │ │ + * specified bounds. Note that this may result in a zoom that does
│ │ │ │ │ + * not exactly contain the entire extent.
│ │ │ │ │ + * Default is false.
│ │ │ │ │ *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Integer} The index of the zoomLevel (entry in the resolutions array)
│ │ │ │ │ + * for the passed-in extent. We do this by calculating the ideal
│ │ │ │ │ + * resolution for the given extent (based on the map size) and then
│ │ │ │ │ + * calling getZoomForResolution(), passing along the 'closest'
│ │ │ │ │ + * parameter.
│ │ │ │ │ + */
│ │ │ │ │ + getZoomForExtent: function(extent, closest) {
│ │ │ │ │ + var viewSize = this.map.getSize();
│ │ │ │ │ + var idealResolution = Math.max(extent.getWidth() / viewSize.w,
│ │ │ │ │ + extent.getHeight() / viewSize.h);
│ │ │ │ │ +
│ │ │ │ │ + return this.getZoomForResolution(idealResolution, closest);
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: getDataExtent
│ │ │ │ │ + * Calculates the max extent which includes all of the data for the layer.
│ │ │ │ │ + * This function is to be implemented by subclasses.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {}
│ │ │ │ │ + */
│ │ │ │ │ + getDataExtent: function() {
│ │ │ │ │ + //to be implemented by subclasses
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: getResolutionForZoom
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * map - {}
│ │ │ │ │ + * zoom - {Float}
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Float} A suitable resolution for the specified zoom.
│ │ │ │ │ */
│ │ │ │ │ - setMap: function(map) {
│ │ │ │ │ - this.map = map;
│ │ │ │ │ - if (this.handler) {
│ │ │ │ │ - this.handler.setMap(map);
│ │ │ │ │ + getResolutionForZoom: function(zoom) {
│ │ │ │ │ + zoom = Math.max(0, Math.min(zoom, this.resolutions.length - 1));
│ │ │ │ │ + var resolution;
│ │ │ │ │ + if (this.map.fractionalZoom) {
│ │ │ │ │ + var low = Math.floor(zoom);
│ │ │ │ │ + var high = Math.ceil(zoom);
│ │ │ │ │ + resolution = this.resolutions[low] -
│ │ │ │ │ + ((zoom - low) * (this.resolutions[low] - this.resolutions[high]));
│ │ │ │ │ + } else {
│ │ │ │ │ + resolution = this.resolutions[Math.round(zoom)];
│ │ │ │ │ }
│ │ │ │ │ + return resolution;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: draw
│ │ │ │ │ - * The draw method is called when the control is ready to be displayed
│ │ │ │ │ - * on the page. If a div has not been created one is created. Controls
│ │ │ │ │ - * with a visual component will almost always want to override this method
│ │ │ │ │ - * to customize the look of control.
│ │ │ │ │ - *
│ │ │ │ │ + * APIMethod: getZoomForResolution
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * px - {} The top-left pixel position of the control
│ │ │ │ │ - * or null.
│ │ │ │ │ - *
│ │ │ │ │ + * resolution - {Float}
│ │ │ │ │ + * closest - {Boolean} Find the zoom level that corresponds to the absolute
│ │ │ │ │ + * closest resolution, which may result in a zoom whose corresponding
│ │ │ │ │ + * resolution is actually smaller than we would have desired (if this
│ │ │ │ │ + * is being called from a getZoomForExtent() call, then this means that
│ │ │ │ │ + * the returned zoom index might not actually contain the entire
│ │ │ │ │ + * extent specified... but it'll be close).
│ │ │ │ │ + * Default is false.
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {DOMElement} A reference to the DIV DOMElement containing the control
│ │ │ │ │ + * {Integer} The index of the zoomLevel (entry in the resolutions array)
│ │ │ │ │ + * that corresponds to the best fit resolution given the passed in
│ │ │ │ │ + * value and the 'closest' specification.
│ │ │ │ │ */
│ │ │ │ │ - draw: function(px) {
│ │ │ │ │ - if (this.div == null) {
│ │ │ │ │ - this.div = OpenLayers.Util.createDiv(this.id);
│ │ │ │ │ - this.div.className = this.displayClass;
│ │ │ │ │ - if (!this.allowSelection) {
│ │ │ │ │ - this.div.className += " olControlNoSelect";
│ │ │ │ │ - this.div.setAttribute("unselectable", "on", 0);
│ │ │ │ │ - this.div.onselectstart = OpenLayers.Function.False;
│ │ │ │ │ + getZoomForResolution: function(resolution, closest) {
│ │ │ │ │ + var zoom, i, len;
│ │ │ │ │ + if (this.map.fractionalZoom) {
│ │ │ │ │ + var lowZoom = 0;
│ │ │ │ │ + var highZoom = this.resolutions.length - 1;
│ │ │ │ │ + var highRes = this.resolutions[lowZoom];
│ │ │ │ │ + var lowRes = this.resolutions[highZoom];
│ │ │ │ │ + var res;
│ │ │ │ │ + for (i = 0, len = this.resolutions.length; i < len; ++i) {
│ │ │ │ │ + res = this.resolutions[i];
│ │ │ │ │ + if (res >= resolution) {
│ │ │ │ │ + highRes = res;
│ │ │ │ │ + lowZoom = i;
│ │ │ │ │ + }
│ │ │ │ │ + if (res <= resolution) {
│ │ │ │ │ + lowRes = res;
│ │ │ │ │ + highZoom = i;
│ │ │ │ │ + break;
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ - if (this.title != "") {
│ │ │ │ │ - this.div.title = this.title;
│ │ │ │ │ + var dRes = highRes - lowRes;
│ │ │ │ │ + if (dRes > 0) {
│ │ │ │ │ + zoom = lowZoom + ((highRes - resolution) / dRes);
│ │ │ │ │ + } else {
│ │ │ │ │ + zoom = lowZoom;
│ │ │ │ │ }
│ │ │ │ │ + } else {
│ │ │ │ │ + var diff;
│ │ │ │ │ + var minDiff = Number.POSITIVE_INFINITY;
│ │ │ │ │ + for (i = 0, len = this.resolutions.length; i < len; i++) {
│ │ │ │ │ + if (closest) {
│ │ │ │ │ + diff = Math.abs(this.resolutions[i] - resolution);
│ │ │ │ │ + if (diff > minDiff) {
│ │ │ │ │ + break;
│ │ │ │ │ + }
│ │ │ │ │ + minDiff = diff;
│ │ │ │ │ + } else {
│ │ │ │ │ + if (this.resolutions[i] < resolution) {
│ │ │ │ │ + break;
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + zoom = Math.max(0, i - 1);
│ │ │ │ │ }
│ │ │ │ │ - if (px != null) {
│ │ │ │ │ - this.position = px.clone();
│ │ │ │ │ - }
│ │ │ │ │ - this.moveTo(this.position);
│ │ │ │ │ - return this.div;
│ │ │ │ │ + return zoom;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: moveTo
│ │ │ │ │ - * Sets the left and top style attributes to the passed in pixel
│ │ │ │ │ - * coordinates.
│ │ │ │ │ - *
│ │ │ │ │ + * APIMethod: getLonLatFromViewPortPx
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * px - {}
│ │ │ │ │ + * viewPortPx - {|Object} An OpenLayers.Pixel or
│ │ │ │ │ + * an object with a 'x'
│ │ │ │ │ + * and 'y' properties.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {} An OpenLayers.LonLat which is the passed-in
│ │ │ │ │ + * view port , translated into lon/lat by the layer.
│ │ │ │ │ */
│ │ │ │ │ - moveTo: function(px) {
│ │ │ │ │ - if ((px != null) && (this.div != null)) {
│ │ │ │ │ - this.div.style.left = px.x + "px";
│ │ │ │ │ - this.div.style.top = px.y + "px";
│ │ │ │ │ + getLonLatFromViewPortPx: function(viewPortPx) {
│ │ │ │ │ + var lonlat = null;
│ │ │ │ │ + var map = this.map;
│ │ │ │ │ + if (viewPortPx != null && map.minPx) {
│ │ │ │ │ + var res = map.getResolution();
│ │ │ │ │ + var maxExtent = map.getMaxExtent({
│ │ │ │ │ + restricted: true
│ │ │ │ │ + });
│ │ │ │ │ + var lon = (viewPortPx.x - map.minPx.x) * res + maxExtent.left;
│ │ │ │ │ + var lat = (map.minPx.y - viewPortPx.y) * res + maxExtent.top;
│ │ │ │ │ + lonlat = new OpenLayers.LonLat(lon, lat);
│ │ │ │ │ +
│ │ │ │ │ + if (this.wrapDateLine) {
│ │ │ │ │ + lonlat = lonlat.wrapDateLine(this.maxExtent);
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ + return lonlat;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: activate
│ │ │ │ │ - * Explicitly activates a control and it's associated
│ │ │ │ │ - * handler if one has been set. Controls can be
│ │ │ │ │ - * deactivated by calling the deactivate() method.
│ │ │ │ │ + * APIMethod: getViewPortPxFromLonLat
│ │ │ │ │ + * Returns a pixel location given a map location. This method will return
│ │ │ │ │ + * fractional pixel values.
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} True if the control was successfully activated or
│ │ │ │ │ - * false if the control was already active.
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * lonlat - {|Object} An OpenLayers.LonLat or
│ │ │ │ │ + * an object with a 'lon'
│ │ │ │ │ + * and 'lat' properties.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {} An which is the passed-in
│ │ │ │ │ + * lonlat translated into view port pixels.
│ │ │ │ │ */
│ │ │ │ │ - activate: function() {
│ │ │ │ │ - if (this.active) {
│ │ │ │ │ - return false;
│ │ │ │ │ - }
│ │ │ │ │ - if (this.handler) {
│ │ │ │ │ - this.handler.activate();
│ │ │ │ │ - }
│ │ │ │ │ - this.active = true;
│ │ │ │ │ - if (this.map) {
│ │ │ │ │ - OpenLayers.Element.addClass(
│ │ │ │ │ - this.map.viewPortDiv,
│ │ │ │ │ - this.displayClass.replace(/ /g, "") + "Active"
│ │ │ │ │ + getViewPortPxFromLonLat: function(lonlat, resolution) {
│ │ │ │ │ + var px = null;
│ │ │ │ │ + if (lonlat != null) {
│ │ │ │ │ + resolution = resolution || this.map.getResolution();
│ │ │ │ │ + var extent = this.map.calculateBounds(null, resolution);
│ │ │ │ │ + px = new OpenLayers.Pixel(
│ │ │ │ │ + (1 / resolution * (lonlat.lon - extent.left)),
│ │ │ │ │ + (1 / resolution * (extent.top - lonlat.lat))
│ │ │ │ │ );
│ │ │ │ │ }
│ │ │ │ │ - this.events.triggerEvent("activate");
│ │ │ │ │ - return true;
│ │ │ │ │ + return px;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: deactivate
│ │ │ │ │ - * Deactivates a control and it's associated handler if any. The exact
│ │ │ │ │ - * effect of this depends on the control itself.
│ │ │ │ │ + * APIMethod: setOpacity
│ │ │ │ │ + * Sets the opacity for the entire layer (all images)
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} True if the control was effectively deactivated or false
│ │ │ │ │ - * if the control was already inactive.
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * opacity - {Float}
│ │ │ │ │ */
│ │ │ │ │ - deactivate: function() {
│ │ │ │ │ - if (this.active) {
│ │ │ │ │ - if (this.handler) {
│ │ │ │ │ - this.handler.deactivate();
│ │ │ │ │ + setOpacity: function(opacity) {
│ │ │ │ │ + if (opacity != this.opacity) {
│ │ │ │ │ + this.opacity = opacity;
│ │ │ │ │ + var childNodes = this.div.childNodes;
│ │ │ │ │ + for (var i = 0, len = childNodes.length; i < len; ++i) {
│ │ │ │ │ + var element = childNodes[i].firstChild || childNodes[i];
│ │ │ │ │ + var lastChild = childNodes[i].lastChild;
│ │ │ │ │ + //TODO de-uglify this
│ │ │ │ │ + if (lastChild && lastChild.nodeName.toLowerCase() === "iframe") {
│ │ │ │ │ + element = lastChild.parentNode;
│ │ │ │ │ + }
│ │ │ │ │ + OpenLayers.Util.modifyDOMElement(element, null, null, null,
│ │ │ │ │ + null, null, null, opacity);
│ │ │ │ │ }
│ │ │ │ │ - this.active = false;
│ │ │ │ │ - if (this.map) {
│ │ │ │ │ - OpenLayers.Element.removeClass(
│ │ │ │ │ - this.map.viewPortDiv,
│ │ │ │ │ - this.displayClass.replace(/ /g, "") + "Active"
│ │ │ │ │ - );
│ │ │ │ │ + if (this.map != null) {
│ │ │ │ │ + this.map.events.triggerEvent("changelayer", {
│ │ │ │ │ + layer: this,
│ │ │ │ │ + property: "opacity"
│ │ │ │ │ + });
│ │ │ │ │ }
│ │ │ │ │ - this.events.triggerEvent("deactivate");
│ │ │ │ │ - return true;
│ │ │ │ │ }
│ │ │ │ │ - return false;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Control"
│ │ │ │ │ -});
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: getZIndex
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Integer} the z-index of this layer
│ │ │ │ │ + */
│ │ │ │ │ + getZIndex: function() {
│ │ │ │ │ + return this.div.style.zIndex;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * Constant: OpenLayers.Control.TYPE_BUTTON
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Control.TYPE_BUTTON = 1;
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: setZIndex
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * zIndex - {Integer}
│ │ │ │ │ + */
│ │ │ │ │ + setZIndex: function(zIndex) {
│ │ │ │ │ + this.div.style.zIndex = zIndex;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * Constant: OpenLayers.Control.TYPE_TOGGLE
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Control.TYPE_TOGGLE = 2;
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: adjustBounds
│ │ │ │ │ + * This function will take a bounds, and if wrapDateLine option is set
│ │ │ │ │ + * on the layer, it will return a bounds which is wrapped around the
│ │ │ │ │ + * world. We do not wrap for bounds which *cross* the
│ │ │ │ │ + * maxExtent.left/right, only bounds which are entirely to the left
│ │ │ │ │ + * or entirely to the right.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * bounds - {}
│ │ │ │ │ + */
│ │ │ │ │ + adjustBounds: function(bounds) {
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * Constant: OpenLayers.Control.TYPE_TOOL
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Control.TYPE_TOOL = 3;
│ │ │ │ │ + if (this.gutter) {
│ │ │ │ │ + // Adjust the extent of a bounds in map units by the
│ │ │ │ │ + // layer's gutter in pixels.
│ │ │ │ │ + var mapGutter = this.gutter * this.map.getResolution();
│ │ │ │ │ + bounds = new OpenLayers.Bounds(bounds.left - mapGutter,
│ │ │ │ │ + bounds.bottom - mapGutter,
│ │ │ │ │ + bounds.right + mapGutter,
│ │ │ │ │ + bounds.top + mapGutter);
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + if (this.wrapDateLine) {
│ │ │ │ │ + // wrap around the date line, within the limits of rounding error
│ │ │ │ │ + var wrappingOptions = {
│ │ │ │ │ + 'rightTolerance': this.getResolution(),
│ │ │ │ │ + 'leftTolerance': this.getResolution()
│ │ │ │ │ + };
│ │ │ │ │ + bounds = bounds.wrapDateLine(this.maxExtent, wrappingOptions);
│ │ │ │ │ +
│ │ │ │ │ + }
│ │ │ │ │ + return bounds;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Layer"
│ │ │ │ │ +});
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ OpenLayers/Geometry.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
│ │ │ │ │ @@ -11449,757 +13929,14 @@
│ │ │ │ │ distance: Math.pow(x - x0, 2) + Math.pow(y - y0, 2),
│ │ │ │ │ x: x,
│ │ │ │ │ y: y,
│ │ │ │ │ along: along
│ │ │ │ │ };
│ │ │ │ │ };
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Feature.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.Feature
│ │ │ │ │ - * Features are combinations of geography and attributes. The OpenLayers.Feature
│ │ │ │ │ - * class specifically combines a marker and a lonlat.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Feature = OpenLayers.Class({
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: layer
│ │ │ │ │ - * {}
│ │ │ │ │ - */
│ │ │ │ │ - layer: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: id
│ │ │ │ │ - * {String}
│ │ │ │ │ - */
│ │ │ │ │ - id: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: lonlat
│ │ │ │ │ - * {}
│ │ │ │ │ - */
│ │ │ │ │ - lonlat: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: data
│ │ │ │ │ - * {Object}
│ │ │ │ │ - */
│ │ │ │ │ - data: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: marker
│ │ │ │ │ - * {}
│ │ │ │ │ - */
│ │ │ │ │ - marker: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: popupClass
│ │ │ │ │ - * {} The class which will be used to instantiate
│ │ │ │ │ - * a new Popup. Default is .
│ │ │ │ │ - */
│ │ │ │ │ - popupClass: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: popup
│ │ │ │ │ - * {}
│ │ │ │ │ - */
│ │ │ │ │ - popup: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Feature
│ │ │ │ │ - * Constructor for features.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * layer - {}
│ │ │ │ │ - * lonlat - {}
│ │ │ │ │ - * data - {Object}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {}
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(layer, lonlat, data) {
│ │ │ │ │ - this.layer = layer;
│ │ │ │ │ - this.lonlat = lonlat;
│ │ │ │ │ - this.data = (data != null) ? data : {};
│ │ │ │ │ - this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: destroy
│ │ │ │ │ - * nullify references to prevent circular references and memory leaks
│ │ │ │ │ - */
│ │ │ │ │ - destroy: function() {
│ │ │ │ │ -
│ │ │ │ │ - //remove the popup from the map
│ │ │ │ │ - if ((this.layer != null) && (this.layer.map != null)) {
│ │ │ │ │ - if (this.popup != null) {
│ │ │ │ │ - this.layer.map.removePopup(this.popup);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - // remove the marker from the layer
│ │ │ │ │ - if (this.layer != null && this.marker != null) {
│ │ │ │ │ - this.layer.removeMarker(this.marker);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - this.layer = null;
│ │ │ │ │ - this.id = null;
│ │ │ │ │ - this.lonlat = null;
│ │ │ │ │ - this.data = null;
│ │ │ │ │ - if (this.marker != null) {
│ │ │ │ │ - this.destroyMarker(this.marker);
│ │ │ │ │ - this.marker = null;
│ │ │ │ │ - }
│ │ │ │ │ - if (this.popup != null) {
│ │ │ │ │ - this.destroyPopup(this.popup);
│ │ │ │ │ - this.popup = null;
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: onScreen
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} Whether or not the feature is currently visible on screen
│ │ │ │ │ - * (based on its 'lonlat' property)
│ │ │ │ │ - */
│ │ │ │ │ - onScreen: function() {
│ │ │ │ │ -
│ │ │ │ │ - var onScreen = false;
│ │ │ │ │ - if ((this.layer != null) && (this.layer.map != null)) {
│ │ │ │ │ - var screenBounds = this.layer.map.getExtent();
│ │ │ │ │ - onScreen = screenBounds.containsLonLat(this.lonlat);
│ │ │ │ │ - }
│ │ │ │ │ - return onScreen;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: createMarker
│ │ │ │ │ - * Based on the data associated with the Feature, create and return a marker object.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} A Marker Object created from the 'lonlat' and 'icon' properties
│ │ │ │ │ - * set in this.data. If no 'lonlat' is set, returns null. If no
│ │ │ │ │ - * 'icon' is set, OpenLayers.Marker() will load the default image.
│ │ │ │ │ - *
│ │ │ │ │ - * Note - this.marker is set to return value
│ │ │ │ │ - *
│ │ │ │ │ - */
│ │ │ │ │ - createMarker: function() {
│ │ │ │ │ -
│ │ │ │ │ - if (this.lonlat != null) {
│ │ │ │ │ - this.marker = new OpenLayers.Marker(this.lonlat, this.data.icon);
│ │ │ │ │ - }
│ │ │ │ │ - return this.marker;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: destroyMarker
│ │ │ │ │ - * Destroys marker.
│ │ │ │ │ - * If user overrides the createMarker() function, s/he should be able
│ │ │ │ │ - * to also specify an alternative function for destroying it
│ │ │ │ │ - */
│ │ │ │ │ - destroyMarker: function() {
│ │ │ │ │ - this.marker.destroy();
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: createPopup
│ │ │ │ │ - * Creates a popup object created from the 'lonlat', 'popupSize',
│ │ │ │ │ - * and 'popupContentHTML' properties set in this.data. It uses
│ │ │ │ │ - * this.marker.icon as default anchor.
│ │ │ │ │ - *
│ │ │ │ │ - * If no 'lonlat' is set, returns null.
│ │ │ │ │ - * If no this.marker has been created, no anchor is sent.
│ │ │ │ │ - *
│ │ │ │ │ - * Note - the returned popup object is 'owned' by the feature, so you
│ │ │ │ │ - * cannot use the popup's destroy method to discard the popup.
│ │ │ │ │ - * Instead, you must use the feature's destroyPopup
│ │ │ │ │ - *
│ │ │ │ │ - * Note - this.popup is set to return value
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * closeBox - {Boolean} create popup with closebox or not
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} Returns the created popup, which is also set
│ │ │ │ │ - * as 'popup' property of this feature. Will be of whatever type
│ │ │ │ │ - * specified by this feature's 'popupClass' property, but must be
│ │ │ │ │ - * of type .
│ │ │ │ │ - *
│ │ │ │ │ - */
│ │ │ │ │ - createPopup: function(closeBox) {
│ │ │ │ │ -
│ │ │ │ │ - if (this.lonlat != null) {
│ │ │ │ │ - if (!this.popup) {
│ │ │ │ │ - var anchor = (this.marker) ? this.marker.icon : null;
│ │ │ │ │ - var popupClass = this.popupClass ?
│ │ │ │ │ - this.popupClass : OpenLayers.Popup.Anchored;
│ │ │ │ │ - this.popup = new popupClass(this.id + "_popup",
│ │ │ │ │ - this.lonlat,
│ │ │ │ │ - this.data.popupSize,
│ │ │ │ │ - this.data.popupContentHTML,
│ │ │ │ │ - anchor,
│ │ │ │ │ - closeBox);
│ │ │ │ │ - }
│ │ │ │ │ - if (this.data.overflow != null) {
│ │ │ │ │ - this.popup.contentDiv.style.overflow = this.data.overflow;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - this.popup.feature = this;
│ │ │ │ │ - }
│ │ │ │ │ - return this.popup;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: destroyPopup
│ │ │ │ │ - * Destroys the popup created via createPopup.
│ │ │ │ │ - *
│ │ │ │ │ - * As with the marker, if user overrides the createPopup() function, s/he
│ │ │ │ │ - * should also be able to override the destruction
│ │ │ │ │ - */
│ │ │ │ │ - destroyPopup: function() {
│ │ │ │ │ - if (this.popup) {
│ │ │ │ │ - this.popup.feature = null;
│ │ │ │ │ - this.popup.destroy();
│ │ │ │ │ - this.popup = null;
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Feature"
│ │ │ │ │ -});
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Feature/Vector.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. */
│ │ │ │ │ -
│ │ │ │ │ -// TRASH THIS
│ │ │ │ │ -OpenLayers.State = {
│ │ │ │ │ - /** states */
│ │ │ │ │ - UNKNOWN: 'Unknown',
│ │ │ │ │ - INSERT: 'Insert',
│ │ │ │ │ - UPDATE: 'Update',
│ │ │ │ │ - DELETE: 'Delete'
│ │ │ │ │ -};
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/Feature.js
│ │ │ │ │ - * @requires OpenLayers/Util.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Feature.Vector
│ │ │ │ │ - * Vector features use the OpenLayers.Geometry classes as geometry description.
│ │ │ │ │ - * They have an 'attributes' property, which is the data object, and a 'style'
│ │ │ │ │ - * property, the default values of which are defined in the
│ │ │ │ │ - * objects.
│ │ │ │ │ - *
│ │ │ │ │ - * Inherits from:
│ │ │ │ │ - * -
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Feature.Vector = OpenLayers.Class(OpenLayers.Feature, {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: fid
│ │ │ │ │ - * {String}
│ │ │ │ │ - */
│ │ │ │ │ - fid: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: geometry
│ │ │ │ │ - * {}
│ │ │ │ │ - */
│ │ │ │ │ - geometry: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: attributes
│ │ │ │ │ - * {Object} This object holds arbitrary, serializable properties that
│ │ │ │ │ - * describe the feature.
│ │ │ │ │ - */
│ │ │ │ │ - attributes: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: bounds
│ │ │ │ │ - * {} The box bounding that feature's geometry, that
│ │ │ │ │ - * property can be set by an object when
│ │ │ │ │ - * deserializing the feature, so in most cases it represents an
│ │ │ │ │ - * information set by the server.
│ │ │ │ │ - */
│ │ │ │ │ - bounds: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: state
│ │ │ │ │ - * {String}
│ │ │ │ │ - */
│ │ │ │ │ - state: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: style
│ │ │ │ │ - * {Object}
│ │ │ │ │ - */
│ │ │ │ │ - style: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: url
│ │ │ │ │ - * {String} If this property is set it will be taken into account by
│ │ │ │ │ - * {} when upadting or deleting the feature.
│ │ │ │ │ - */
│ │ │ │ │ - url: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: renderIntent
│ │ │ │ │ - * {String} rendering intent currently being used
│ │ │ │ │ - */
│ │ │ │ │ - renderIntent: "default",
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: modified
│ │ │ │ │ - * {Object} An object with the originals of the geometry and attributes of
│ │ │ │ │ - * the feature, if they were changed. Currently this property is only read
│ │ │ │ │ - * by , and written by
│ │ │ │ │ - * , which sets the geometry property.
│ │ │ │ │ - * Applications can set the originals of modified attributes in the
│ │ │ │ │ - * attributes property. Note that applications have to check if this
│ │ │ │ │ - * object and the attributes property is already created before using it.
│ │ │ │ │ - * After a change made with ModifyFeature, this object could look like
│ │ │ │ │ - *
│ │ │ │ │ - * (code)
│ │ │ │ │ - * {
│ │ │ │ │ - * geometry: >Object
│ │ │ │ │ - * }
│ │ │ │ │ - * (end)
│ │ │ │ │ - *
│ │ │ │ │ - * When an application has made changes to feature attributes, it could
│ │ │ │ │ - * have set the attributes to something like this:
│ │ │ │ │ - *
│ │ │ │ │ - * (code)
│ │ │ │ │ - * {
│ │ │ │ │ - * attributes: {
│ │ │ │ │ - * myAttribute: "original"
│ │ │ │ │ - * }
│ │ │ │ │ - * }
│ │ │ │ │ - * (end)
│ │ │ │ │ - *
│ │ │ │ │ - * Note that only checks for truthy values in
│ │ │ │ │ - * *modified.geometry* and the attribute names in *modified.attributes*,
│ │ │ │ │ - * but it is recommended to set the original values (and not just true) as
│ │ │ │ │ - * attribute value, so applications could use this information to undo
│ │ │ │ │ - * changes.
│ │ │ │ │ - */
│ │ │ │ │ - modified: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Feature.Vector
│ │ │ │ │ - * Create a vector feature.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * geometry - {} The geometry that this feature
│ │ │ │ │ - * represents.
│ │ │ │ │ - * attributes - {Object} An optional object that will be mapped to the
│ │ │ │ │ - * property.
│ │ │ │ │ - * style - {Object} An optional style object.
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(geometry, attributes, style) {
│ │ │ │ │ - OpenLayers.Feature.prototype.initialize.apply(this,
│ │ │ │ │ - [null, null, attributes]);
│ │ │ │ │ - this.lonlat = null;
│ │ │ │ │ - this.geometry = geometry ? geometry : null;
│ │ │ │ │ - this.state = null;
│ │ │ │ │ - this.attributes = {};
│ │ │ │ │ - if (attributes) {
│ │ │ │ │ - this.attributes = OpenLayers.Util.extend(this.attributes,
│ │ │ │ │ - attributes);
│ │ │ │ │ - }
│ │ │ │ │ - this.style = style ? style : null;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: destroy
│ │ │ │ │ - * nullify references to prevent circular references and memory leaks
│ │ │ │ │ - */
│ │ │ │ │ - destroy: function() {
│ │ │ │ │ - if (this.layer) {
│ │ │ │ │ - this.layer.removeFeatures(this);
│ │ │ │ │ - this.layer = null;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - this.geometry = null;
│ │ │ │ │ - this.modified = null;
│ │ │ │ │ - OpenLayers.Feature.prototype.destroy.apply(this, arguments);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: clone
│ │ │ │ │ - * Create a clone of this vector feature. Does not set any non-standard
│ │ │ │ │ - * properties.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} An exact clone of this vector feature.
│ │ │ │ │ - */
│ │ │ │ │ - clone: function() {
│ │ │ │ │ - return new OpenLayers.Feature.Vector(
│ │ │ │ │ - this.geometry ? this.geometry.clone() : null,
│ │ │ │ │ - this.attributes,
│ │ │ │ │ - this.style);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: onScreen
│ │ │ │ │ - * Determine whether the feature is within the map viewport. This method
│ │ │ │ │ - * tests for an intersection between the geometry and the viewport
│ │ │ │ │ - * bounds. If a more effecient but less precise geometry bounds
│ │ │ │ │ - * intersection is desired, call the method with the boundsOnly
│ │ │ │ │ - * parameter true.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * boundsOnly - {Boolean} Only test whether a feature's bounds intersects
│ │ │ │ │ - * the viewport bounds. Default is false. If false, the feature's
│ │ │ │ │ - * geometry must intersect the viewport for onScreen to return true.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} The feature is currently visible on screen (optionally
│ │ │ │ │ - * based on its bounds if boundsOnly is true).
│ │ │ │ │ - */
│ │ │ │ │ - onScreen: function(boundsOnly) {
│ │ │ │ │ - var onScreen = false;
│ │ │ │ │ - if (this.layer && this.layer.map) {
│ │ │ │ │ - var screenBounds = this.layer.map.getExtent();
│ │ │ │ │ - if (boundsOnly) {
│ │ │ │ │ - var featureBounds = this.geometry.getBounds();
│ │ │ │ │ - onScreen = screenBounds.intersectsBounds(featureBounds);
│ │ │ │ │ - } else {
│ │ │ │ │ - var screenPoly = screenBounds.toGeometry();
│ │ │ │ │ - onScreen = screenPoly.intersects(this.geometry);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return onScreen;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: getVisibility
│ │ │ │ │ - * Determine whether the feature is displayed or not. It may not displayed
│ │ │ │ │ - * because:
│ │ │ │ │ - * - its style display property is set to 'none',
│ │ │ │ │ - * - it doesn't belong to any layer,
│ │ │ │ │ - * - the styleMap creates a symbolizer with display property set to 'none'
│ │ │ │ │ - * for it,
│ │ │ │ │ - * - the layer which it belongs to is not visible.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} The feature is currently displayed.
│ │ │ │ │ - */
│ │ │ │ │ - getVisibility: function() {
│ │ │ │ │ - return !(this.style && this.style.display == 'none' ||
│ │ │ │ │ - !this.layer ||
│ │ │ │ │ - this.layer && this.layer.styleMap &&
│ │ │ │ │ - this.layer.styleMap.createSymbolizer(this, this.renderIntent).display == 'none' ||
│ │ │ │ │ - this.layer && !this.layer.getVisibility());
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: createMarker
│ │ │ │ │ - * HACK - we need to decide if all vector features should be able to
│ │ │ │ │ - * create markers
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} For now just returns null
│ │ │ │ │ - */
│ │ │ │ │ - createMarker: function() {
│ │ │ │ │ - return null;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: destroyMarker
│ │ │ │ │ - * HACK - we need to decide if all vector features should be able to
│ │ │ │ │ - * delete markers
│ │ │ │ │ - *
│ │ │ │ │ - * If user overrides the createMarker() function, s/he should be able
│ │ │ │ │ - * to also specify an alternative function for destroying it
│ │ │ │ │ - */
│ │ │ │ │ - destroyMarker: function() {
│ │ │ │ │ - // pass
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: createPopup
│ │ │ │ │ - * HACK - we need to decide if all vector features should be able to
│ │ │ │ │ - * create popups
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} For now just returns null
│ │ │ │ │ - */
│ │ │ │ │ - createPopup: function() {
│ │ │ │ │ - return null;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: atPoint
│ │ │ │ │ - * Determins whether the feature intersects with the specified location.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * lonlat - {|Object} OpenLayers.LonLat or an
│ │ │ │ │ - * object with a 'lon' and 'lat' properties.
│ │ │ │ │ - * toleranceLon - {float} Optional tolerance in Geometric Coords
│ │ │ │ │ - * toleranceLat - {float} Optional tolerance in Geographic Coords
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} Whether or not the feature is at the specified location
│ │ │ │ │ - */
│ │ │ │ │ - atPoint: function(lonlat, toleranceLon, toleranceLat) {
│ │ │ │ │ - var atPoint = false;
│ │ │ │ │ - if (this.geometry) {
│ │ │ │ │ - atPoint = this.geometry.atPoint(lonlat, toleranceLon,
│ │ │ │ │ - toleranceLat);
│ │ │ │ │ - }
│ │ │ │ │ - return atPoint;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: destroyPopup
│ │ │ │ │ - * HACK - we need to decide if all vector features should be able to
│ │ │ │ │ - * delete popups
│ │ │ │ │ - */
│ │ │ │ │ - destroyPopup: function() {
│ │ │ │ │ - // pass
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: move
│ │ │ │ │ - * Moves the feature and redraws it at its new location
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * location - { or } the
│ │ │ │ │ - * location to which to move the feature.
│ │ │ │ │ - */
│ │ │ │ │ - move: function(location) {
│ │ │ │ │ -
│ │ │ │ │ - if (!this.layer || !this.geometry.move) {
│ │ │ │ │ - //do nothing if no layer or immoveable geometry
│ │ │ │ │ - return undefined;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - var pixel;
│ │ │ │ │ - if (location.CLASS_NAME == "OpenLayers.LonLat") {
│ │ │ │ │ - pixel = this.layer.getViewPortPxFromLonLat(location);
│ │ │ │ │ - } else {
│ │ │ │ │ - pixel = location;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - var lastPixel = this.layer.getViewPortPxFromLonLat(this.geometry.getBounds().getCenterLonLat());
│ │ │ │ │ - var res = this.layer.map.getResolution();
│ │ │ │ │ - this.geometry.move(res * (pixel.x - lastPixel.x),
│ │ │ │ │ - res * (lastPixel.y - pixel.y));
│ │ │ │ │ - this.layer.drawFeature(this);
│ │ │ │ │ - return lastPixel;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: toState
│ │ │ │ │ - * Sets the new state
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * state - {String}
│ │ │ │ │ - */
│ │ │ │ │ - toState: function(state) {
│ │ │ │ │ - if (state == OpenLayers.State.UPDATE) {
│ │ │ │ │ - switch (this.state) {
│ │ │ │ │ - case OpenLayers.State.UNKNOWN:
│ │ │ │ │ - case OpenLayers.State.DELETE:
│ │ │ │ │ - this.state = state;
│ │ │ │ │ - break;
│ │ │ │ │ - case OpenLayers.State.UPDATE:
│ │ │ │ │ - case OpenLayers.State.INSERT:
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - } else if (state == OpenLayers.State.INSERT) {
│ │ │ │ │ - switch (this.state) {
│ │ │ │ │ - case OpenLayers.State.UNKNOWN:
│ │ │ │ │ - break;
│ │ │ │ │ - default:
│ │ │ │ │ - this.state = state;
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - } else if (state == OpenLayers.State.DELETE) {
│ │ │ │ │ - switch (this.state) {
│ │ │ │ │ - case OpenLayers.State.INSERT:
│ │ │ │ │ - // the feature should be destroyed
│ │ │ │ │ - break;
│ │ │ │ │ - case OpenLayers.State.DELETE:
│ │ │ │ │ - break;
│ │ │ │ │ - case OpenLayers.State.UNKNOWN:
│ │ │ │ │ - case OpenLayers.State.UPDATE:
│ │ │ │ │ - this.state = state;
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - } else if (state == OpenLayers.State.UNKNOWN) {
│ │ │ │ │ - this.state = state;
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Feature.Vector"
│ │ │ │ │ -});
│ │ │ │ │ -
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Constant: OpenLayers.Feature.Vector.style
│ │ │ │ │ - * OpenLayers features can have a number of style attributes. The 'default'
│ │ │ │ │ - * style will typically be used if no other style is specified. These
│ │ │ │ │ - * styles correspond for the most part, to the styling properties defined
│ │ │ │ │ - * by the SVG standard.
│ │ │ │ │ - * Information on fill properties: http://www.w3.org/TR/SVG/painting.html#FillProperties
│ │ │ │ │ - * Information on stroke properties: http://www.w3.org/TR/SVG/painting.html#StrokeProperties
│ │ │ │ │ - *
│ │ │ │ │ - * Symbolizer properties:
│ │ │ │ │ - * fill - {Boolean} Set to false if no fill is desired.
│ │ │ │ │ - * fillColor - {String} Hex fill color. Default is "#ee9900".
│ │ │ │ │ - * fillOpacity - {Number} Fill opacity (0-1). Default is 0.4
│ │ │ │ │ - * stroke - {Boolean} Set to false if no stroke is desired.
│ │ │ │ │ - * strokeColor - {String} Hex stroke color. Default is "#ee9900".
│ │ │ │ │ - * strokeOpacity - {Number} Stroke opacity (0-1). Default is 1.
│ │ │ │ │ - * strokeWidth - {Number} Pixel stroke width. Default is 1.
│ │ │ │ │ - * strokeLinecap - {String} Stroke cap type. Default is "round". [butt | round | square]
│ │ │ │ │ - * strokeDashstyle - {String} Stroke dash style. Default is "solid". [dot | dash | dashdot | longdash | longdashdot | solid]
│ │ │ │ │ - * graphic - {Boolean} Set to false if no graphic is desired.
│ │ │ │ │ - * pointRadius - {Number} Pixel point radius. Default is 6.
│ │ │ │ │ - * pointerEvents - {String} Default is "visiblePainted".
│ │ │ │ │ - * cursor - {String} Default is "".
│ │ │ │ │ - * externalGraphic - {String} Url to an external graphic that will be used for rendering points.
│ │ │ │ │ - * graphicWidth - {Number} Pixel width for sizing an external graphic.
│ │ │ │ │ - * graphicHeight - {Number} Pixel height for sizing an external graphic.
│ │ │ │ │ - * graphicOpacity - {Number} Opacity (0-1) for an external graphic.
│ │ │ │ │ - * graphicXOffset - {Number} Pixel offset along the positive x axis for displacing an external graphic.
│ │ │ │ │ - * graphicYOffset - {Number} Pixel offset along the positive y axis for displacing an external graphic.
│ │ │ │ │ - * rotation - {Number} For point symbolizers, this is the rotation of a graphic in the clockwise direction about its center point (or any point off center as specified by graphicXOffset and graphicYOffset).
│ │ │ │ │ - * graphicZIndex - {Number} The integer z-index value to use in rendering.
│ │ │ │ │ - * graphicName - {String} Named graphic to use when rendering points. Supported values include "circle" (default),
│ │ │ │ │ - * "square", "star", "x", "cross", "triangle".
│ │ │ │ │ - * graphicTitle - {String} Tooltip when hovering over a feature. *deprecated*, use title instead
│ │ │ │ │ - * title - {String} Tooltip when hovering over a feature. Not supported by the canvas renderer.
│ │ │ │ │ - * backgroundGraphic - {String} Url to a graphic to be used as the background under an externalGraphic.
│ │ │ │ │ - * backgroundGraphicZIndex - {Number} The integer z-index value to use in rendering the background graphic.
│ │ │ │ │ - * backgroundXOffset - {Number} The x offset (in pixels) for the background graphic.
│ │ │ │ │ - * backgroundYOffset - {Number} The y offset (in pixels) for the background graphic.
│ │ │ │ │ - * backgroundHeight - {Number} The height of the background graphic. If not provided, the graphicHeight will be used.
│ │ │ │ │ - * backgroundWidth - {Number} The width of the background width. If not provided, the graphicWidth will be used.
│ │ │ │ │ - * label - {String} The text for an optional label. For browsers that use the canvas renderer, this requires either
│ │ │ │ │ - * fillText or mozDrawText to be available.
│ │ │ │ │ - * labelAlign - {String} Label alignment. This specifies the insertion point relative to the text. It is a string
│ │ │ │ │ - * composed of two characters. The first character is for the horizontal alignment, the second for the vertical
│ │ │ │ │ - * alignment. Valid values for horizontal alignment: "l"=left, "c"=center, "r"=right. Valid values for vertical
│ │ │ │ │ - * alignment: "t"=top, "m"=middle, "b"=bottom. Example values: "lt", "cm", "rb". Default is "cm".
│ │ │ │ │ - * labelXOffset - {Number} Pixel offset along the positive x axis for displacing the label. Not supported by the canvas renderer.
│ │ │ │ │ - * labelYOffset - {Number} Pixel offset along the positive y axis for displacing the label. Not supported by the canvas renderer.
│ │ │ │ │ - * labelSelect - {Boolean} If set to true, labels will be selectable using SelectFeature or similar controls.
│ │ │ │ │ - * Default is false.
│ │ │ │ │ - * labelOutlineColor - {String} The color of the label outline. Default is 'white'. Only supported by the canvas & SVG renderers.
│ │ │ │ │ - * labelOutlineWidth - {Number} The width of the label outline. Default is 3, set to 0 or null to disable. Only supported by the SVG renderers.
│ │ │ │ │ - * labelOutlineOpacity - {Number} The opacity (0-1) of the label outline. Default is fontOpacity. Only supported by the canvas & SVG renderers.
│ │ │ │ │ - * fontColor - {String} The font color for the label, to be provided like CSS.
│ │ │ │ │ - * fontOpacity - {Number} Opacity (0-1) for the label
│ │ │ │ │ - * fontFamily - {String} The font family for the label, to be provided like in CSS.
│ │ │ │ │ - * fontSize - {String} The font size for the label, to be provided like in CSS.
│ │ │ │ │ - * fontStyle - {String} The font style for the label, to be provided like in CSS.
│ │ │ │ │ - * fontWeight - {String} The font weight for the label, to be provided like in CSS.
│ │ │ │ │ - * display - {String} Symbolizers will have no effect if display is set to "none". All other values have no effect.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Feature.Vector.style = {
│ │ │ │ │ - 'default': {
│ │ │ │ │ - fillColor: "#ee9900",
│ │ │ │ │ - fillOpacity: 0.4,
│ │ │ │ │ - hoverFillColor: "white",
│ │ │ │ │ - hoverFillOpacity: 0.8,
│ │ │ │ │ - strokeColor: "#ee9900",
│ │ │ │ │ - strokeOpacity: 1,
│ │ │ │ │ - strokeWidth: 1,
│ │ │ │ │ - strokeLinecap: "round",
│ │ │ │ │ - strokeDashstyle: "solid",
│ │ │ │ │ - hoverStrokeColor: "red",
│ │ │ │ │ - hoverStrokeOpacity: 1,
│ │ │ │ │ - hoverStrokeWidth: 0.2,
│ │ │ │ │ - pointRadius: 6,
│ │ │ │ │ - hoverPointRadius: 1,
│ │ │ │ │ - hoverPointUnit: "%",
│ │ │ │ │ - pointerEvents: "visiblePainted",
│ │ │ │ │ - cursor: "inherit",
│ │ │ │ │ - fontColor: "#000000",
│ │ │ │ │ - labelAlign: "cm",
│ │ │ │ │ - labelOutlineColor: "white",
│ │ │ │ │ - labelOutlineWidth: 3
│ │ │ │ │ - },
│ │ │ │ │ - 'select': {
│ │ │ │ │ - fillColor: "blue",
│ │ │ │ │ - fillOpacity: 0.4,
│ │ │ │ │ - hoverFillColor: "white",
│ │ │ │ │ - hoverFillOpacity: 0.8,
│ │ │ │ │ - strokeColor: "blue",
│ │ │ │ │ - strokeOpacity: 1,
│ │ │ │ │ - strokeWidth: 2,
│ │ │ │ │ - strokeLinecap: "round",
│ │ │ │ │ - strokeDashstyle: "solid",
│ │ │ │ │ - hoverStrokeColor: "red",
│ │ │ │ │ - hoverStrokeOpacity: 1,
│ │ │ │ │ - hoverStrokeWidth: 0.2,
│ │ │ │ │ - pointRadius: 6,
│ │ │ │ │ - hoverPointRadius: 1,
│ │ │ │ │ - hoverPointUnit: "%",
│ │ │ │ │ - pointerEvents: "visiblePainted",
│ │ │ │ │ - cursor: "pointer",
│ │ │ │ │ - fontColor: "#000000",
│ │ │ │ │ - labelAlign: "cm",
│ │ │ │ │ - labelOutlineColor: "white",
│ │ │ │ │ - labelOutlineWidth: 3
│ │ │ │ │ -
│ │ │ │ │ - },
│ │ │ │ │ - 'temporary': {
│ │ │ │ │ - fillColor: "#66cccc",
│ │ │ │ │ - fillOpacity: 0.2,
│ │ │ │ │ - hoverFillColor: "white",
│ │ │ │ │ - hoverFillOpacity: 0.8,
│ │ │ │ │ - strokeColor: "#66cccc",
│ │ │ │ │ - strokeOpacity: 1,
│ │ │ │ │ - strokeLinecap: "round",
│ │ │ │ │ - strokeWidth: 2,
│ │ │ │ │ - strokeDashstyle: "solid",
│ │ │ │ │ - hoverStrokeColor: "red",
│ │ │ │ │ - hoverStrokeOpacity: 1,
│ │ │ │ │ - hoverStrokeWidth: 0.2,
│ │ │ │ │ - pointRadius: 6,
│ │ │ │ │ - hoverPointRadius: 1,
│ │ │ │ │ - hoverPointUnit: "%",
│ │ │ │ │ - pointerEvents: "visiblePainted",
│ │ │ │ │ - cursor: "inherit",
│ │ │ │ │ - fontColor: "#000000",
│ │ │ │ │ - labelAlign: "cm",
│ │ │ │ │ - labelOutlineColor: "white",
│ │ │ │ │ - labelOutlineWidth: 3
│ │ │ │ │ -
│ │ │ │ │ - },
│ │ │ │ │ - 'delete': {
│ │ │ │ │ - display: "none"
│ │ │ │ │ - }
│ │ │ │ │ -};
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ 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. */
│ │ │ │ │ @@ -18560,467 +20297,14 @@
│ │ │ │ │ * Constant: OpenLayers.Format.WFST.DEFAULTS
│ │ │ │ │ * {Object} Default properties for the WFST format.
│ │ │ │ │ */
│ │ │ │ │ OpenLayers.Format.WFST.DEFAULTS = {
│ │ │ │ │ "version": "1.0.0"
│ │ │ │ │ };
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Style.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
│ │ │ │ │ - * @requires OpenLayers/Feature/Vector.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Style
│ │ │ │ │ - * This class represents a UserStyle obtained
│ │ │ │ │ - * from a SLD, containing styling rules.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Style = OpenLayers.Class({
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: id
│ │ │ │ │ - * {String} A unique id for this session.
│ │ │ │ │ - */
│ │ │ │ │ - id: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: name
│ │ │ │ │ - * {String}
│ │ │ │ │ - */
│ │ │ │ │ - name: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: title
│ │ │ │ │ - * {String} Title of this style (set if included in SLD)
│ │ │ │ │ - */
│ │ │ │ │ - title: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: description
│ │ │ │ │ - * {String} Description of this style (set if abstract is included in SLD)
│ │ │ │ │ - */
│ │ │ │ │ - description: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: layerName
│ │ │ │ │ - * {} name of the layer that this style belongs to, usually
│ │ │ │ │ - * according to the NamedLayer attribute of an SLD document.
│ │ │ │ │ - */
│ │ │ │ │ - layerName: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: isDefault
│ │ │ │ │ - * {Boolean}
│ │ │ │ │ - */
│ │ │ │ │ - isDefault: false,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: rules
│ │ │ │ │ - * {Array()}
│ │ │ │ │ - */
│ │ │ │ │ - rules: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: 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
│ │ │ │ │ - */
│ │ │ │ │ - context: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: defaultStyle
│ │ │ │ │ - * {Object} hash of style properties to use as default for merging
│ │ │ │ │ - * rule-based style symbolizers onto. If no rules are defined,
│ │ │ │ │ - * createSymbolizer will return this style. If is set to
│ │ │ │ │ - * true, the defaultStyle will only be taken into account if there are
│ │ │ │ │ - * rules defined.
│ │ │ │ │ - */
│ │ │ │ │ - defaultStyle: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: defaultsPerSymbolizer
│ │ │ │ │ - * {Boolean} If set to true, the will extend the symbolizer
│ │ │ │ │ - * of every rule. Properties of the will also be used to set
│ │ │ │ │ - * missing symbolizer properties if the symbolizer has stroke, fill or
│ │ │ │ │ - * graphic set to true. Default is false.
│ │ │ │ │ - */
│ │ │ │ │ - defaultsPerSymbolizer: false,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: propertyStyles
│ │ │ │ │ - * {Hash of Boolean} cache of style properties that need to be parsed for
│ │ │ │ │ - * propertyNames. Property names are keys, values won't be used.
│ │ │ │ │ - */
│ │ │ │ │ - propertyStyles: null,
│ │ │ │ │ -
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Style
│ │ │ │ │ - * Creates a UserStyle.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * style - {Object} Optional hash of style properties that will be
│ │ │ │ │ - * used as default style for this style object. This style
│ │ │ │ │ - * applies if no rules are specified. Symbolizers defined in
│ │ │ │ │ - * rules will extend this default style.
│ │ │ │ │ - * options - {Object} An optional object with properties to set on the
│ │ │ │ │ - * style.
│ │ │ │ │ - *
│ │ │ │ │ - * Valid options:
│ │ │ │ │ - * rules - {Array()} List of rules to be added to the
│ │ │ │ │ - * style.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {}
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(style, options) {
│ │ │ │ │ -
│ │ │ │ │ - OpenLayers.Util.extend(this, options);
│ │ │ │ │ - this.rules = [];
│ │ │ │ │ - if (options && options.rules) {
│ │ │ │ │ - this.addRules(options.rules);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // use the default style from OpenLayers.Feature.Vector if no style
│ │ │ │ │ - // was given in the constructor
│ │ │ │ │ - this.setDefaultStyle(style ||
│ │ │ │ │ - OpenLayers.Feature.Vector.style["default"]);
│ │ │ │ │ -
│ │ │ │ │ - this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * 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.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);
│ │ │ │ │ -
│ │ │ │ │ - var rules = this.rules;
│ │ │ │ │ -
│ │ │ │ │ - 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);
│ │ │ │ │ -
│ │ │ │ │ - if (applies) {
│ │ │ │ │ - if (rule instanceof OpenLayers.Rule && rule.elseFilter) {
│ │ │ │ │ - elseRules.push(rule);
│ │ │ │ │ - } else {
│ │ │ │ │ - appliedRules = true;
│ │ │ │ │ - this.applySymbolizer(rule, style, feature);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // 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);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // don't display if there were rules but none applied
│ │ │ │ │ - if (rules.length > 0 && appliedRules == false) {
│ │ │ │ │ - style.display = "none";
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - if (style.label != null && typeof style.label !== "string") {
│ │ │ │ │ - style.label = String(style.label);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - return style;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: applySymbolizer
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * rule - {}
│ │ │ │ │ - * style - {Object}
│ │ │ │ │ - * feature - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Object} A style with new symbolizer applied.
│ │ │ │ │ - */
│ │ │ │ │ - applySymbolizer: function(rule, style, feature) {
│ │ │ │ │ - var symbolizerPrefix = feature.geometry ?
│ │ │ │ │ - this.getSymbolizerPrefix(feature.geometry) :
│ │ │ │ │ - OpenLayers.Style.SYMBOLIZER_PREFIXES[0];
│ │ │ │ │ -
│ │ │ │ │ - var symbolizer = rule.symbolizer[symbolizerPrefix] || rule.symbolizer;
│ │ │ │ │ -
│ │ │ │ │ - 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
│ │ │ │ │ - });
│ │ │ │ │ - }
│ │ │ │ │ - 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
│ │ │ │ │ - });
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // merge the style with the current style
│ │ │ │ │ - return this.createLiterals(
│ │ │ │ │ - OpenLayers.Util.extend(style, symbolizer), feature);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: createLiterals
│ │ │ │ │ - * creates literals for all style properties that have an entry in
│ │ │ │ │ - * .
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * style - {Object} style to create literals for. Will be modified
│ │ │ │ │ - * inline.
│ │ │ │ │ - * feature - {Object}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Object} the modified style
│ │ │ │ │ - */
│ │ │ │ │ - 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;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * 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.
│ │ │ │ │ - *
│ │ │ │ │ - * 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;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: addPropertyStyles
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * propertyStyles - {Object} hash to add new property styles to. Will be
│ │ │ │ │ - * modified inline
│ │ │ │ │ - * symbolizer - {Object} search this symbolizer for property styles
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Object} propertyStyles hash
│ │ │ │ │ - */
│ │ │ │ │ - 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;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: addRules
│ │ │ │ │ - * Adds rules to this style.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * rules - {Array()}
│ │ │ │ │ - */
│ │ │ │ │ - addRules: function(rules) {
│ │ │ │ │ - Array.prototype.push.apply(this.rules, rules);
│ │ │ │ │ - this.propertyStyles = this.findPropertyStyles();
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: setDefaultStyle
│ │ │ │ │ - * Sets the default style for this style object.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * style - {Object} Hash of style properties
│ │ │ │ │ - */
│ │ │ │ │ - setDefaultStyle: function(style) {
│ │ │ │ │ - this.defaultStyle = style;
│ │ │ │ │ - this.propertyStyles = this.findPropertyStyles();
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: getSymbolizerPrefix
│ │ │ │ │ - * Returns the correct symbolizer prefix according to the
│ │ │ │ │ - * geometry type of the passed geometry
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * geometry - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} key of the according symbolizer
│ │ │ │ │ - */
│ │ │ │ │ - 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];
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: clone
│ │ │ │ │ - * Clones this style.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} Clone of this style.
│ │ │ │ │ - */
│ │ │ │ │ - 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);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - 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/Filter.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. */
│ │ │ │ │ @@ -24416,429 +25700,784 @@
│ │ │ │ │ OpenLayers.Util.extend(this, options);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ CLASS_NAME: "OpenLayers.WPSProcess.ChainLink"
│ │ │ │ │
│ │ │ │ │ });
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Format/WPSDescribeProcess.js
│ │ │ │ │ + OpenLayers/Handler.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/Format/XML.js
│ │ │ │ │ - * @requires OpenLayers/Format/OWSCommon/v1_1_0.js
│ │ │ │ │ + * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ + * @requires OpenLayers/Events.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Class: OpenLayers.Format.WPSDescribeProcess
│ │ │ │ │ - * Read WPS DescribeProcess responses.
│ │ │ │ │ + * Class: OpenLayers.Handler
│ │ │ │ │ + * Base class to construct a higher-level handler for event sequences. All
│ │ │ │ │ + * handlers have activate and deactivate methods. In addition, they have
│ │ │ │ │ + * methods named like browser events. When a handler is activated, any
│ │ │ │ │ + * additional methods named like a browser event is registered as a
│ │ │ │ │ + * listener for the corresponding event. When a handler is deactivated,
│ │ │ │ │ + * those same methods are unregistered as event listeners.
│ │ │ │ │ *
│ │ │ │ │ - * Inherits from:
│ │ │ │ │ - * -
│ │ │ │ │ + * Handlers also typically have a callbacks object with keys named like
│ │ │ │ │ + * the abstracted events or event sequences that they are in charge of
│ │ │ │ │ + * handling. The controls that wrap handlers define the methods that
│ │ │ │ │ + * correspond to these abstract events - so instead of listening for
│ │ │ │ │ + * individual browser events, they only listen for the abstract events
│ │ │ │ │ + * defined by the handler.
│ │ │ │ │ + *
│ │ │ │ │ + * Handlers are created by controls, which ultimately have the responsibility
│ │ │ │ │ + * of making changes to the the state of the application. Handlers
│ │ │ │ │ + * themselves may make temporary changes, but in general are expected to
│ │ │ │ │ + * return the application in the same state that they found it.
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Format.WPSDescribeProcess = OpenLayers.Class(
│ │ │ │ │ - OpenLayers.Format.XML, {
│ │ │ │ │ +OpenLayers.Handler = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Constant: VERSION
│ │ │ │ │ - * {String} 1.0.0
│ │ │ │ │ - */
│ │ │ │ │ - VERSION: "1.0.0",
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: id
│ │ │ │ │ + * {String}
│ │ │ │ │ + */
│ │ │ │ │ + id: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: namespaces
│ │ │ │ │ - * {Object} Mapping of namespace aliases to namespace URIs.
│ │ │ │ │ - */
│ │ │ │ │ - namespaces: {
│ │ │ │ │ - wps: "http://www.opengis.net/wps/1.0.0",
│ │ │ │ │ - ows: "http://www.opengis.net/ows/1.1",
│ │ │ │ │ - xsi: "http://www.w3.org/2001/XMLSchema-instance"
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: control
│ │ │ │ │ + * {}. The control that initialized this handler. The
│ │ │ │ │ + * control is assumed to have a valid map property - that map is used
│ │ │ │ │ + * in the handler's own setMap method.
│ │ │ │ │ + */
│ │ │ │ │ + control: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: schemaLocation
│ │ │ │ │ - * {String} Schema location
│ │ │ │ │ - */
│ │ │ │ │ - schemaLocation: "http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd",
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: map
│ │ │ │ │ + * {}
│ │ │ │ │ + */
│ │ │ │ │ + map: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: defaultPrefix
│ │ │ │ │ - */
│ │ │ │ │ - defaultPrefix: "wps",
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: keyMask
│ │ │ │ │ + * {Integer} Use bitwise operators and one or more of the OpenLayers.Handler
│ │ │ │ │ + * constants to construct a keyMask. The keyMask is used by
│ │ │ │ │ + * . If the keyMask matches the combination of keys
│ │ │ │ │ + * down on an event, checkModifiers returns true.
│ │ │ │ │ + *
│ │ │ │ │ + * Example:
│ │ │ │ │ + * (code)
│ │ │ │ │ + * // handler only responds if the Shift key is down
│ │ │ │ │ + * handler.keyMask = OpenLayers.Handler.MOD_SHIFT;
│ │ │ │ │ + *
│ │ │ │ │ + * // handler only responds if Ctrl-Shift is down
│ │ │ │ │ + * handler.keyMask = OpenLayers.Handler.MOD_SHIFT |
│ │ │ │ │ + * OpenLayers.Handler.MOD_CTRL;
│ │ │ │ │ + * (end)
│ │ │ │ │ + */
│ │ │ │ │ + keyMask: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: regExes
│ │ │ │ │ - * Compiled regular expressions for manipulating strings.
│ │ │ │ │ - */
│ │ │ │ │ - regExes: {
│ │ │ │ │ - trimSpace: (/^\s*|\s*$/g),
│ │ │ │ │ - removeSpace: (/\s*/g),
│ │ │ │ │ - splitSpace: (/\s+/),
│ │ │ │ │ - trimComma: (/\s*,\s*/g)
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: active
│ │ │ │ │ + * {Boolean}
│ │ │ │ │ + */
│ │ │ │ │ + active: false,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Format.WPSDescribeProcess
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * options - {Object} An optional object whose properties will be set on
│ │ │ │ │ - * this instance.
│ │ │ │ │ - */
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: evt
│ │ │ │ │ + * {Event} This property references the last event handled by the handler.
│ │ │ │ │ + * Note that this property is not part of the stable API. Use of the
│ │ │ │ │ + * evt property should be restricted to controls in the library
│ │ │ │ │ + * or other applications that are willing to update with changes to
│ │ │ │ │ + * the OpenLayers code.
│ │ │ │ │ + */
│ │ │ │ │ + evt: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: read
│ │ │ │ │ - * Parse a WPS DescribeProcess and return an object with its information.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * data - {String} or {DOMElement} data to read/parse.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Object}
│ │ │ │ │ - */
│ │ │ │ │ - read: function(data) {
│ │ │ │ │ - if (typeof data == "string") {
│ │ │ │ │ - data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: touch
│ │ │ │ │ + * {Boolean} Indicates the support of touch events. When touch events are
│ │ │ │ │ + * started touch will be true and all mouse related listeners will do
│ │ │ │ │ + * nothing.
│ │ │ │ │ + */
│ │ │ │ │ + touch: false,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Constructor: OpenLayers.Handler
│ │ │ │ │ + * Construct a handler.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * control - {} The control that initialized this
│ │ │ │ │ + * handler. The control is assumed to have a valid map property; that
│ │ │ │ │ + * map is used in the handler's own setMap method. If a map property
│ │ │ │ │ + * is present in the options argument it will be used instead.
│ │ │ │ │ + * callbacks - {Object} An object whose properties correspond to abstracted
│ │ │ │ │ + * events or sequences of browser events. The values for these
│ │ │ │ │ + * properties are functions defined by the control that get called by
│ │ │ │ │ + * the handler.
│ │ │ │ │ + * options - {Object} An optional object whose properties will be set on
│ │ │ │ │ + * the handler.
│ │ │ │ │ + */
│ │ │ │ │ + initialize: function(control, callbacks, options) {
│ │ │ │ │ + OpenLayers.Util.extend(this, options);
│ │ │ │ │ + this.control = control;
│ │ │ │ │ + this.callbacks = callbacks;
│ │ │ │ │ +
│ │ │ │ │ + var map = this.map || control.map;
│ │ │ │ │ + if (map) {
│ │ │ │ │ + this.setMap(map);
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: setMap
│ │ │ │ │ + */
│ │ │ │ │ + setMap: function(map) {
│ │ │ │ │ + this.map = map;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: checkModifiers
│ │ │ │ │ + * Check the keyMask on the handler. If no is set, this always
│ │ │ │ │ + * returns true. If a is set and it matches the combination
│ │ │ │ │ + * of keys down on an event, this returns true.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean} The keyMask matches the keys down on an event.
│ │ │ │ │ + */
│ │ │ │ │ + checkModifiers: function(evt) {
│ │ │ │ │ + if (this.keyMask == null) {
│ │ │ │ │ + return true;
│ │ │ │ │ + }
│ │ │ │ │ + /* calculate the keyboard modifier mask for this event */
│ │ │ │ │ + var keyModifiers =
│ │ │ │ │ + (evt.shiftKey ? OpenLayers.Handler.MOD_SHIFT : 0) |
│ │ │ │ │ + (evt.ctrlKey ? OpenLayers.Handler.MOD_CTRL : 0) |
│ │ │ │ │ + (evt.altKey ? OpenLayers.Handler.MOD_ALT : 0) |
│ │ │ │ │ + (evt.metaKey ? OpenLayers.Handler.MOD_META : 0);
│ │ │ │ │ +
│ │ │ │ │ + /* if it differs from the handler object's key mask,
│ │ │ │ │ + bail out of the event handler */
│ │ │ │ │ + return (keyModifiers == this.keyMask);
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: activate
│ │ │ │ │ + * Turn on the handler. Returns false if the handler was already active.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean} The handler was activated.
│ │ │ │ │ + */
│ │ │ │ │ + activate: function() {
│ │ │ │ │ + if (this.active) {
│ │ │ │ │ + return false;
│ │ │ │ │ + }
│ │ │ │ │ + // register for event handlers defined on this class.
│ │ │ │ │ + var events = OpenLayers.Events.prototype.BROWSER_EVENTS;
│ │ │ │ │ + for (var i = 0, len = events.length; i < len; i++) {
│ │ │ │ │ + if (this[events[i]]) {
│ │ │ │ │ + this.register(events[i], this[events[i]]);
│ │ │ │ │ }
│ │ │ │ │ - if (data && data.nodeType == 9) {
│ │ │ │ │ - data = data.documentElement;
│ │ │ │ │ + }
│ │ │ │ │ + this.active = true;
│ │ │ │ │ + return true;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: deactivate
│ │ │ │ │ + * Turn off the handler. Returns false if the handler was already inactive.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean} The handler was deactivated.
│ │ │ │ │ + */
│ │ │ │ │ + deactivate: function() {
│ │ │ │ │ + if (!this.active) {
│ │ │ │ │ + return false;
│ │ │ │ │ + }
│ │ │ │ │ + // unregister event handlers defined on this class.
│ │ │ │ │ + var events = OpenLayers.Events.prototype.BROWSER_EVENTS;
│ │ │ │ │ + for (var i = 0, len = events.length; i < len; i++) {
│ │ │ │ │ + if (this[events[i]]) {
│ │ │ │ │ + this.unregister(events[i], this[events[i]]);
│ │ │ │ │ }
│ │ │ │ │ - var info = {};
│ │ │ │ │ - this.readNode(data, info);
│ │ │ │ │ - return info;
│ │ │ │ │ - },
│ │ │ │ │ + }
│ │ │ │ │ + this.touch = false;
│ │ │ │ │ + this.active = false;
│ │ │ │ │ + return true;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: readers
│ │ │ │ │ - * Contains public functions, grouped by namespace prefix, that will
│ │ │ │ │ - * be applied when a namespaced node is found matching the function
│ │ │ │ │ - * name. The function will be applied in the scope of this parser
│ │ │ │ │ - * with two arguments: the node being read and a context object passed
│ │ │ │ │ - * from the parent.
│ │ │ │ │ - */
│ │ │ │ │ - readers: {
│ │ │ │ │ - "wps": {
│ │ │ │ │ - "ProcessDescriptions": function(node, obj) {
│ │ │ │ │ - obj.processDescriptions = {};
│ │ │ │ │ - this.readChildNodes(node, obj.processDescriptions);
│ │ │ │ │ - },
│ │ │ │ │ - "ProcessDescription": function(node, processDescriptions) {
│ │ │ │ │ - var processVersion = this.getAttributeNS(node, this.namespaces.wps, "processVersion");
│ │ │ │ │ - var processDescription = {
│ │ │ │ │ - processVersion: processVersion,
│ │ │ │ │ - statusSupported: (node.getAttribute("statusSupported") === "true"),
│ │ │ │ │ - storeSupported: (node.getAttribute("storeSupported") === "true")
│ │ │ │ │ - };
│ │ │ │ │ - this.readChildNodes(node, processDescription);
│ │ │ │ │ - processDescriptions[processDescription.identifier] = processDescription;
│ │ │ │ │ - },
│ │ │ │ │ - "DataInputs": function(node, processDescription) {
│ │ │ │ │ - processDescription.dataInputs = [];
│ │ │ │ │ - this.readChildNodes(node, processDescription.dataInputs);
│ │ │ │ │ - },
│ │ │ │ │ - "ProcessOutputs": function(node, processDescription) {
│ │ │ │ │ - processDescription.processOutputs = [];
│ │ │ │ │ - this.readChildNodes(node, processDescription.processOutputs);
│ │ │ │ │ - },
│ │ │ │ │ - "Output": function(node, processOutputs) {
│ │ │ │ │ - var output = {};
│ │ │ │ │ - this.readChildNodes(node, output);
│ │ │ │ │ - processOutputs.push(output);
│ │ │ │ │ - },
│ │ │ │ │ - "ComplexOutput": function(node, output) {
│ │ │ │ │ - output.complexOutput = {};
│ │ │ │ │ - this.readChildNodes(node, output.complexOutput);
│ │ │ │ │ - },
│ │ │ │ │ - "LiteralOutput": function(node, output) {
│ │ │ │ │ - output.literalOutput = {};
│ │ │ │ │ - this.readChildNodes(node, output.literalOutput);
│ │ │ │ │ - },
│ │ │ │ │ - "Input": function(node, dataInputs) {
│ │ │ │ │ - var input = {
│ │ │ │ │ - maxOccurs: parseInt(node.getAttribute("maxOccurs")),
│ │ │ │ │ - minOccurs: parseInt(node.getAttribute("minOccurs"))
│ │ │ │ │ - };
│ │ │ │ │ - this.readChildNodes(node, input);
│ │ │ │ │ - dataInputs.push(input);
│ │ │ │ │ - },
│ │ │ │ │ - "BoundingBoxData": function(node, input) {
│ │ │ │ │ - input.boundingBoxData = {};
│ │ │ │ │ - this.readChildNodes(node, input.boundingBoxData);
│ │ │ │ │ - },
│ │ │ │ │ - "CRS": function(node, obj) {
│ │ │ │ │ - if (!obj.CRSs) {
│ │ │ │ │ - obj.CRSs = {};
│ │ │ │ │ - }
│ │ │ │ │ - obj.CRSs[this.getChildValue(node)] = true;
│ │ │ │ │ - },
│ │ │ │ │ - "LiteralData": function(node, input) {
│ │ │ │ │ - input.literalData = {};
│ │ │ │ │ - this.readChildNodes(node, input.literalData);
│ │ │ │ │ - },
│ │ │ │ │ - "ComplexData": function(node, input) {
│ │ │ │ │ - input.complexData = {};
│ │ │ │ │ - this.readChildNodes(node, input.complexData);
│ │ │ │ │ - },
│ │ │ │ │ - "Default": function(node, complexData) {
│ │ │ │ │ - complexData["default"] = {};
│ │ │ │ │ - this.readChildNodes(node, complexData["default"]);
│ │ │ │ │ - },
│ │ │ │ │ - "Supported": function(node, complexData) {
│ │ │ │ │ - complexData["supported"] = {};
│ │ │ │ │ - this.readChildNodes(node, complexData["supported"]);
│ │ │ │ │ - },
│ │ │ │ │ - "Format": function(node, obj) {
│ │ │ │ │ - var format = {};
│ │ │ │ │ - this.readChildNodes(node, format);
│ │ │ │ │ - if (!obj.formats) {
│ │ │ │ │ - obj.formats = {};
│ │ │ │ │ - }
│ │ │ │ │ - obj.formats[format.mimeType] = true;
│ │ │ │ │ - },
│ │ │ │ │ - "MimeType": function(node, format) {
│ │ │ │ │ - format.mimeType = this.getChildValue(node);
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: startTouch
│ │ │ │ │ + * Start touch events, this method must be called by subclasses in
│ │ │ │ │ + * "touchstart" method. When touch events are started will be
│ │ │ │ │ + * true and all mouse related listeners will do nothing.
│ │ │ │ │ + */
│ │ │ │ │ + startTouch: function() {
│ │ │ │ │ + if (!this.touch) {
│ │ │ │ │ + this.touch = true;
│ │ │ │ │ + var events = [
│ │ │ │ │ + "mousedown", "mouseup", "mousemove", "click", "dblclick",
│ │ │ │ │ + "mouseout"
│ │ │ │ │ + ];
│ │ │ │ │ + for (var i = 0, len = events.length; i < len; i++) {
│ │ │ │ │ + if (this[events[i]]) {
│ │ │ │ │ + this.unregister(events[i], this[events[i]]);
│ │ │ │ │ }
│ │ │ │ │ - },
│ │ │ │ │ - "ows": OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers["ows"]
│ │ │ │ │ - },
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: callback
│ │ │ │ │ + * Trigger the control's named callback with the given arguments
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * name - {String} The key for the callback that is one of the properties
│ │ │ │ │ + * of the handler's callbacks object.
│ │ │ │ │ + * args - {Array(*)} An array of arguments (any type) with which to call
│ │ │ │ │ + * the callback (defined by the control).
│ │ │ │ │ + */
│ │ │ │ │ + callback: function(name, args) {
│ │ │ │ │ + if (name && this.callbacks[name]) {
│ │ │ │ │ + this.callbacks[name].apply(this.control, args);
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: register
│ │ │ │ │ + * register an event on the map
│ │ │ │ │ + */
│ │ │ │ │ + register: function(name, method) {
│ │ │ │ │ + // TODO: deal with registerPriority in 3.0
│ │ │ │ │ + this.map.events.registerPriority(name, this, method);
│ │ │ │ │ + this.map.events.registerPriority(name, this, this.setEvent);
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: unregister
│ │ │ │ │ + * unregister an event from the map
│ │ │ │ │ + */
│ │ │ │ │ + unregister: function(name, method) {
│ │ │ │ │ + this.map.events.unregister(name, this, method);
│ │ │ │ │ + this.map.events.unregister(name, this, this.setEvent);
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: setEvent
│ │ │ │ │ + * With each registered browser event, the handler sets its own evt
│ │ │ │ │ + * property. This property can be accessed by controls if needed
│ │ │ │ │ + * to get more information about the event that the handler is
│ │ │ │ │ + * processing.
│ │ │ │ │ + *
│ │ │ │ │ + * This allows modifier keys on the event to be checked (alt, shift, ctrl,
│ │ │ │ │ + * and meta cannot be checked with the keyboard handler). For a
│ │ │ │ │ + * control to determine which modifier keys are associated with the
│ │ │ │ │ + * event that a handler is currently processing, it should access
│ │ │ │ │ + * (code)handler.evt.altKey || handler.evt.shiftKey ||
│ │ │ │ │ + * handler.evt.ctrlKey || handler.evt.metaKey(end).
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * evt - {Event} The browser event.
│ │ │ │ │ + */
│ │ │ │ │ + setEvent: function(evt) {
│ │ │ │ │ + this.evt = evt;
│ │ │ │ │ + return true;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: destroy
│ │ │ │ │ + * Deconstruct the handler.
│ │ │ │ │ + */
│ │ │ │ │ + destroy: function() {
│ │ │ │ │ + // unregister event listeners
│ │ │ │ │ + this.deactivate();
│ │ │ │ │ + // eliminate circular references
│ │ │ │ │ + this.control = this.map = null;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Handler"
│ │ │ │ │ +});
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Constant: OpenLayers.Handler.MOD_NONE
│ │ │ │ │ + * If set as the , returns false if any key is down.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Handler.MOD_NONE = 0;
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Constant: OpenLayers.Handler.MOD_SHIFT
│ │ │ │ │ + * If set as the , returns false if Shift is down.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Handler.MOD_SHIFT = 1;
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Constant: OpenLayers.Handler.MOD_CTRL
│ │ │ │ │ + * If set as the , returns false if Ctrl is down.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Handler.MOD_CTRL = 2;
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Constant: OpenLayers.Handler.MOD_ALT
│ │ │ │ │ + * If set as the , returns false if Alt is down.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Handler.MOD_ALT = 4;
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Constant: OpenLayers.Handler.MOD_META
│ │ │ │ │ + * If set as the , returns false if Cmd is down.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Handler.MOD_META = 8;
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Format.WPSDescribeProcess"
│ │ │ │ │
│ │ │ │ │ - });
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/WPSClient.js
│ │ │ │ │ + OpenLayers/Renderer.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/BaseTypes/Class.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * @requires OpenLayers/Events.js
│ │ │ │ │ - * @requires OpenLayers/WPSProcess.js
│ │ │ │ │ - * @requires OpenLayers/Format/WPSDescribeProcess.js
│ │ │ │ │ - * @requires OpenLayers/Request.js
│ │ │ │ │ + * Class: OpenLayers.Renderer
│ │ │ │ │ + * This is the base class for all renderers.
│ │ │ │ │ + *
│ │ │ │ │ + * This is based on a merger code written by Paul Spencer and Bertil Chapuis.
│ │ │ │ │ + * It is largely composed of virtual functions that are to be implemented
│ │ │ │ │ + * in technology-specific subclasses, but there is some generic code too.
│ │ │ │ │ + *
│ │ │ │ │ + * The functions that *are* implemented here merely deal with the maintenance
│ │ │ │ │ + * of the size and extent variables, as well as the cached 'resolution'
│ │ │ │ │ + * value.
│ │ │ │ │ + *
│ │ │ │ │ + * A note to the user that all subclasses should use getResolution() instead
│ │ │ │ │ + * of directly accessing this.resolution in order to correctly use the
│ │ │ │ │ + * cacheing system.
│ │ │ │ │ + *
│ │ │ │ │ */
│ │ │ │ │ +OpenLayers.Renderer = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.WPSClient
│ │ │ │ │ - * High level API for interaction with Web Processing Services (WPS).
│ │ │ │ │ - * An instance is used to create
│ │ │ │ │ - * instances for servers known to the WPSClient. The WPSClient also caches
│ │ │ │ │ - * DescribeProcess responses to reduce the number of requests sent to servers
│ │ │ │ │ - * when processes are created.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.WPSClient = OpenLayers.Class({
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: container
│ │ │ │ │ + * {DOMElement}
│ │ │ │ │ + */
│ │ │ │ │ + container: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: servers
│ │ │ │ │ - * {Object} Service metadata, keyed by a local identifier.
│ │ │ │ │ - *
│ │ │ │ │ - * Properties:
│ │ │ │ │ - * url - {String} the url of the server
│ │ │ │ │ - * version - {String} WPS version of the server
│ │ │ │ │ - * processDescription - {Object} Cache of raw DescribeProcess
│ │ │ │ │ - * responses, keyed by process identifier.
│ │ │ │ │ + * Property: root
│ │ │ │ │ + * {DOMElement}
│ │ │ │ │ */
│ │ │ │ │ - servers: null,
│ │ │ │ │ + root: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: extent
│ │ │ │ │ + * {}
│ │ │ │ │ + */
│ │ │ │ │ + extent: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: version
│ │ │ │ │ - * {String} The default WPS version to use if none is configured. Default
│ │ │ │ │ - * is '1.0.0'.
│ │ │ │ │ + * Property: locked
│ │ │ │ │ + * {Boolean} If the renderer is currently in a state where many things
│ │ │ │ │ + * are changing, the 'locked' property is set to true. This means
│ │ │ │ │ + * that renderers can expect at least one more drawFeature event to be
│ │ │ │ │ + * called with the 'locked' property set to 'true': In some renderers,
│ │ │ │ │ + * this might make sense to use as a 'only update local information'
│ │ │ │ │ + * flag.
│ │ │ │ │ */
│ │ │ │ │ - version: '1.0.0',
│ │ │ │ │ + locked: false,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: size
│ │ │ │ │ + * {}
│ │ │ │ │ + */
│ │ │ │ │ + size: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: lazy
│ │ │ │ │ - * {Boolean} Should the DescribeProcess be deferred until a process is
│ │ │ │ │ - * fully configured? Default is false.
│ │ │ │ │ + * Property: resolution
│ │ │ │ │ + * {Float} cache of current map resolution
│ │ │ │ │ */
│ │ │ │ │ - lazy: false,
│ │ │ │ │ + resolution: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: events
│ │ │ │ │ - * {}
│ │ │ │ │ - *
│ │ │ │ │ - * Supported event types:
│ │ │ │ │ - * describeprocess - Fires when the process description is available.
│ │ │ │ │ - * Listeners receive an object with a 'raw' property holding the raw
│ │ │ │ │ - * DescribeProcess response, and an 'identifier' property holding the
│ │ │ │ │ - * process identifier of the described process.
│ │ │ │ │ + * Property: map
│ │ │ │ │ + * {} Reference to the map -- this is set in Vector's setMap()
│ │ │ │ │ */
│ │ │ │ │ - events: null,
│ │ │ │ │ + map: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constructor: OpenLayers.WPSClient
│ │ │ │ │ + * Property: featureDx
│ │ │ │ │ + * {Number} Feature offset in x direction. Will be calculated for and
│ │ │ │ │ + * applied to the current feature while rendering (see
│ │ │ │ │ + * ).
│ │ │ │ │ + */
│ │ │ │ │ + featureDx: 0,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Constructor: OpenLayers.Renderer
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * options - {Object} Object whose properties will be set on the instance.
│ │ │ │ │ + * containerID - {}
│ │ │ │ │ + * options - {Object} options for this renderer. See sublcasses for
│ │ │ │ │ + * supported options.
│ │ │ │ │ + */
│ │ │ │ │ + initialize: function(containerID, options) {
│ │ │ │ │ + this.container = OpenLayers.Util.getElement(containerID);
│ │ │ │ │ + OpenLayers.Util.extend(this, options);
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: destroy
│ │ │ │ │ + */
│ │ │ │ │ + destroy: function() {
│ │ │ │ │ + this.container = null;
│ │ │ │ │ + this.extent = null;
│ │ │ │ │ + this.size = null;
│ │ │ │ │ + this.resolution = null;
│ │ │ │ │ + this.map = null;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: supported
│ │ │ │ │ + * This should be overridden by specific subclasses
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean} Whether or not the browser supports the renderer class
│ │ │ │ │ + */
│ │ │ │ │ + supported: function() {
│ │ │ │ │ + return false;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: setExtent
│ │ │ │ │ + * Set the visible part of the layer.
│ │ │ │ │ *
│ │ │ │ │ - * Avaliable options:
│ │ │ │ │ - * servers - {Object} Mandatory. Service metadata, keyed by a local
│ │ │ │ │ - * identifier. Can either be a string with the service url or an
│ │ │ │ │ - * object literal with additional metadata:
│ │ │ │ │ + * Resolution has probably changed, so we nullify the resolution
│ │ │ │ │ + * cache (this.resolution) -- this way it will be re-computed when
│ │ │ │ │ + * next it is needed.
│ │ │ │ │ + * We nullify the resolution cache (this.resolution) if resolutionChanged
│ │ │ │ │ + * is set to true - this way it will be re-computed on the next
│ │ │ │ │ + * getResolution() request.
│ │ │ │ │ *
│ │ │ │ │ - * (code)
│ │ │ │ │ - * servers: {
│ │ │ │ │ - * local: '/geoserver/wps'
│ │ │ │ │ - * }, {
│ │ │ │ │ - * opengeo: {
│ │ │ │ │ - * url: 'http://demo.opengeo.org/geoserver/wps',
│ │ │ │ │ - * version: '1.0.0'
│ │ │ │ │ - * }
│ │ │ │ │ - * }
│ │ │ │ │ - * (end)
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * extent - {}
│ │ │ │ │ + * resolutionChanged - {Boolean}
│ │ │ │ │ *
│ │ │ │ │ - * lazy - {Boolean} Optional. Set to true if DescribeProcess should not be
│ │ │ │ │ - * requested until a process is fully configured. Default is false.
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean} true to notify the layer that the new extent does not exceed
│ │ │ │ │ + * the coordinate range, and the features will not need to be redrawn.
│ │ │ │ │ + * False otherwise.
│ │ │ │ │ */
│ │ │ │ │ - initialize: function(options) {
│ │ │ │ │ - OpenLayers.Util.extend(this, options);
│ │ │ │ │ - this.events = new OpenLayers.Events(this);
│ │ │ │ │ - this.servers = {};
│ │ │ │ │ - for (var s in options.servers) {
│ │ │ │ │ - this.servers[s] = typeof options.servers[s] == 'string' ? {
│ │ │ │ │ - url: options.servers[s],
│ │ │ │ │ - version: this.version,
│ │ │ │ │ - processDescription: {}
│ │ │ │ │ - } : options.servers[s];
│ │ │ │ │ + setExtent: function(extent, resolutionChanged) {
│ │ │ │ │ + this.extent = extent.clone();
│ │ │ │ │ + if (this.map.baseLayer && this.map.baseLayer.wrapDateLine) {
│ │ │ │ │ + var ratio = extent.getWidth() / this.map.getExtent().getWidth(),
│ │ │ │ │ + extent = extent.scale(1 / ratio);
│ │ │ │ │ + this.extent = extent.wrapDateLine(this.map.getMaxExtent()).scale(ratio);
│ │ │ │ │ + }
│ │ │ │ │ + if (resolutionChanged) {
│ │ │ │ │ + this.resolution = null;
│ │ │ │ │ }
│ │ │ │ │ + return true;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: execute
│ │ │ │ │ - * Shortcut to execute a process with a single function call. This is
│ │ │ │ │ - * equivalent to using