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