--- /srv/reproducible-results/rbuild-debian/r-b-build.NdPtmx6M/b1/openlayers_2.13.1+ds2-11_i386.changes
+++ /srv/reproducible-results/rbuild-debian/r-b-build.NdPtmx6M/b2/openlayers_2.13.1+ds2-11_i386.changes
├── Files
│ @@ -1,2 +1,2 @@
│
│ - f3a6badd141c6fb44590d90735067dc6 714000 javascript optional libjs-openlayers_2.13.1+ds2-11_all.deb
│ + a8b691201f10cf133bb27cf95f95c2dc 715616 javascript optional libjs-openlayers_2.13.1+ds2-11_all.deb
├── libjs-openlayers_2.13.1+ds2-11_all.deb
│ ├── file list
│ │ @@ -1,3 +1,3 @@
│ │ -rw-r--r-- 0 0 0 4 2025-03-06 18:35:30.000000 debian-binary
│ │ -rw-r--r-- 0 0 0 3684 2025-03-06 18:35:30.000000 control.tar.xz
│ │ --rw-r--r-- 0 0 0 710124 2025-03-06 18:35:30.000000 data.tar.xz
│ │ +-rw-r--r-- 0 0 0 711740 2025-03-06 18:35:30.000000 data.tar.xz
│ ├── control.tar.xz
│ │ ├── control.tar
│ │ │ ├── ./md5sums
│ │ │ │ ├── ./md5sums
│ │ │ │ │┄ Files differ
│ ├── data.tar.xz
│ │ ├── data.tar
│ │ │ ├── ./usr/share/javascript/openlayers/OpenLayers.js
│ │ │ │ ├── js-beautify {}
│ │ │ │ │ @@ -52,37 +52,14 @@
│ │ │ │ │ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
│ │ │ │ │ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
│ │ │ │ │ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
│ │ │ │ │ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
│ │ │ │ │ * POSSIBILITY OF SUCH DAMAGE.
│ │ │ │ │ */
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - Rico/license.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @license Apache 2
│ │ │ │ │ - *
│ │ │ │ │ - * Contains portions of Rico
│ │ │ │ │ - *
│ │ │ │ │ - * Copyright 2005 Sabre Airline Solutions
│ │ │ │ │ - *
│ │ │ │ │ - * Licensed under the Apache License, Version 2.0 (the "License"); you
│ │ │ │ │ - * may not use this file except in compliance with the License. You
│ │ │ │ │ - * may obtain a copy of the License at
│ │ │ │ │ - *
│ │ │ │ │ - * http://www.apache.org/licenses/LICENSE-2.0
│ │ │ │ │ - *
│ │ │ │ │ - * Unless required by applicable law or agreed to in writing, software
│ │ │ │ │ - * distributed under the License is distributed on an "AS IS" BASIS,
│ │ │ │ │ - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
│ │ │ │ │ - * implied. See the License for the specific language governing
│ │ │ │ │ - * permissions and limitations under the License.
│ │ │ │ │ - */
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ OpenLayers/SingleFile.js
│ │ │ │ │ ====================================================================== */
│ │ │ │ │
│ │ │ │ │ /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ * full text of the license. */
│ │ │ │ │ @@ -286,268 +263,14 @@
│ │ │ │ │ source.hasOwnProperty && source.hasOwnProperty("toString")) {
│ │ │ │ │ destination.toString = source.toString;
│ │ │ │ │ }
│ │ │ │ │ }
│ │ │ │ │ return destination;
│ │ │ │ │ };
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Console.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Namespace: OpenLayers.Console
│ │ │ │ │ - * The OpenLayers.Console namespace is used for debugging and error logging.
│ │ │ │ │ - * If the Firebug Lite (../Firebug/firebug.js) is included before this script,
│ │ │ │ │ - * calls to OpenLayers.Console methods will get redirected to window.console.
│ │ │ │ │ - * This makes use of the Firebug extension where available and allows for
│ │ │ │ │ - * cross-browser debugging Firebug style.
│ │ │ │ │ - *
│ │ │ │ │ - * Note:
│ │ │ │ │ - * Note that behavior will differ with the Firebug extention and Firebug Lite.
│ │ │ │ │ - * Most notably, the Firebug Lite console does not currently allow for
│ │ │ │ │ - * hyperlinks to code or for clicking on object to explore their properties.
│ │ │ │ │ - *
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Console = {
│ │ │ │ │ - /**
│ │ │ │ │ - * Create empty functions for all console methods. The real value of these
│ │ │ │ │ - * properties will be set if Firebug Lite (../Firebug/firebug.js script) is
│ │ │ │ │ - * included. We explicitly require the Firebug Lite script to trigger
│ │ │ │ │ - * functionality of the OpenLayers.Console methods.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: log
│ │ │ │ │ - * Log an object in the console. The Firebug Lite console logs string
│ │ │ │ │ - * representation of objects. Given multiple arguments, they will
│ │ │ │ │ - * be cast to strings and logged with a space delimiter. If the first
│ │ │ │ │ - * argument is a string with printf-like formatting, subsequent arguments
│ │ │ │ │ - * will be used in string substitution. Any additional arguments (beyond
│ │ │ │ │ - * the number substituted in a format string) will be appended in a space-
│ │ │ │ │ - * delimited line.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * object - {Object}
│ │ │ │ │ - */
│ │ │ │ │ - log: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: debug
│ │ │ │ │ - * Writes a message to the console, including a hyperlink to the line
│ │ │ │ │ - * where it was called.
│ │ │ │ │ - *
│ │ │ │ │ - * May be called with multiple arguments as with OpenLayers.Console.log().
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * object - {Object}
│ │ │ │ │ - */
│ │ │ │ │ - debug: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: info
│ │ │ │ │ - * Writes a message to the console with the visual "info" icon and color
│ │ │ │ │ - * coding and a hyperlink to the line where it was called.
│ │ │ │ │ - *
│ │ │ │ │ - * May be called with multiple arguments as with OpenLayers.Console.log().
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * object - {Object}
│ │ │ │ │ - */
│ │ │ │ │ - info: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: warn
│ │ │ │ │ - * Writes a message to the console with the visual "warning" icon and
│ │ │ │ │ - * color coding and a hyperlink to the line where it was called.
│ │ │ │ │ - *
│ │ │ │ │ - * May be called with multiple arguments as with OpenLayers.Console.log().
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * object - {Object}
│ │ │ │ │ - */
│ │ │ │ │ - warn: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: error
│ │ │ │ │ - * Writes a message to the console with the visual "error" icon and color
│ │ │ │ │ - * coding and a hyperlink to the line where it was called.
│ │ │ │ │ - *
│ │ │ │ │ - * May be called with multiple arguments as with OpenLayers.Console.log().
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * object - {Object}
│ │ │ │ │ - */
│ │ │ │ │ - error: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: userError
│ │ │ │ │ - * A single interface for showing error messages to the user. The default
│ │ │ │ │ - * behavior is a Javascript alert, though this can be overridden by
│ │ │ │ │ - * reassigning OpenLayers.Console.userError to a different function.
│ │ │ │ │ - *
│ │ │ │ │ - * Expects a single error message
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * error - {Object}
│ │ │ │ │ - */
│ │ │ │ │ - userError: function(error) {
│ │ │ │ │ - alert(error);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: assert
│ │ │ │ │ - * Tests that an expression is true. If not, it will write a message to
│ │ │ │ │ - * the console and throw an exception.
│ │ │ │ │ - *
│ │ │ │ │ - * May be called with multiple arguments as with OpenLayers.Console.log().
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * object - {Object}
│ │ │ │ │ - */
│ │ │ │ │ - assert: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: dir
│ │ │ │ │ - * Prints an interactive listing of all properties of the object. This
│ │ │ │ │ - * looks identical to the view that you would see in the DOM tab.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * object - {Object}
│ │ │ │ │ - */
│ │ │ │ │ - dir: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: dirxml
│ │ │ │ │ - * Prints the XML source tree of an HTML or XML element. This looks
│ │ │ │ │ - * identical to the view that you would see in the HTML tab. You can click
│ │ │ │ │ - * on any node to inspect it in the HTML tab.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * object - {Object}
│ │ │ │ │ - */
│ │ │ │ │ - dirxml: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: trace
│ │ │ │ │ - * Prints an interactive stack trace of JavaScript execution at the point
│ │ │ │ │ - * where it is called. The stack trace details the functions on the stack,
│ │ │ │ │ - * as well as the values that were passed as arguments to each function.
│ │ │ │ │ - * You can click each function to take you to its source in the Script tab,
│ │ │ │ │ - * and click each argument value to inspect it in the DOM or HTML tabs.
│ │ │ │ │ - *
│ │ │ │ │ - */
│ │ │ │ │ - trace: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: group
│ │ │ │ │ - * Writes a message to the console and opens a nested block to indent all
│ │ │ │ │ - * future messages sent to the console. Call OpenLayers.Console.groupEnd()
│ │ │ │ │ - * to close the block.
│ │ │ │ │ - *
│ │ │ │ │ - * May be called with multiple arguments as with OpenLayers.Console.log().
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * object - {Object}
│ │ │ │ │ - */
│ │ │ │ │ - group: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: groupEnd
│ │ │ │ │ - * Closes the most recently opened block created by a call to
│ │ │ │ │ - * OpenLayers.Console.group
│ │ │ │ │ - */
│ │ │ │ │ - groupEnd: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: time
│ │ │ │ │ - * Creates a new timer under the given name. Call
│ │ │ │ │ - * OpenLayers.Console.timeEnd(name)
│ │ │ │ │ - * with the same name to stop the timer and print the time elapsed.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * name - {String}
│ │ │ │ │ - */
│ │ │ │ │ - time: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: timeEnd
│ │ │ │ │ - * Stops a timer created by a call to OpenLayers.Console.time(name) and
│ │ │ │ │ - * writes the time elapsed.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * name - {String}
│ │ │ │ │ - */
│ │ │ │ │ - timeEnd: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: profile
│ │ │ │ │ - * Turns on the JavaScript profiler. The optional argument title would
│ │ │ │ │ - * contain the text to be printed in the header of the profile report.
│ │ │ │ │ - *
│ │ │ │ │ - * This function is not currently implemented in Firebug Lite.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * title - {String} Optional title for the profiler
│ │ │ │ │ - */
│ │ │ │ │ - profile: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: profileEnd
│ │ │ │ │ - * Turns off the JavaScript profiler and prints its report.
│ │ │ │ │ - *
│ │ │ │ │ - * This function is not currently implemented in Firebug Lite.
│ │ │ │ │ - */
│ │ │ │ │ - profileEnd: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: count
│ │ │ │ │ - * Writes the number of times that the line of code where count was called
│ │ │ │ │ - * was executed. The optional argument title will print a message in
│ │ │ │ │ - * addition to the number of the count.
│ │ │ │ │ - *
│ │ │ │ │ - * This function is not currently implemented in Firebug Lite.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * title - {String} Optional title to be printed with count
│ │ │ │ │ - */
│ │ │ │ │ - count: function() {},
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Console"
│ │ │ │ │ -};
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Execute an anonymous function to extend the OpenLayers.Console namespace
│ │ │ │ │ - * if the firebug.js script is included. This closure is used so that the
│ │ │ │ │ - * "scripts" and "i" variables don't pollute the global namespace.
│ │ │ │ │ - */
│ │ │ │ │ -(function() {
│ │ │ │ │ - /**
│ │ │ │ │ - * If Firebug Lite is included (before this script), re-route all
│ │ │ │ │ - * OpenLayers.Console calls to the console object.
│ │ │ │ │ - */
│ │ │ │ │ - var scripts = document.getElementsByTagName("script");
│ │ │ │ │ - for (var i = 0, len = scripts.length; i < len; ++i) {
│ │ │ │ │ - if (scripts[i].src.indexOf("firebug.js") != -1) {
│ │ │ │ │ - if (console) {
│ │ │ │ │ - OpenLayers.Util.extend(OpenLayers.Console, console);
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -})();
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ OpenLayers/BaseTypes.js
│ │ │ │ │ ====================================================================== */
│ │ │ │ │
│ │ │ │ │ /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ * full text of the license. */
│ │ │ │ │ @@ -1866,14 +1589,207 @@
│ │ │ │ │
│ │ │ │ │ opp += (quadrant.charAt(0) == 't') ? 'b' : 't';
│ │ │ │ │ opp += (quadrant.charAt(1) == 'l') ? 'r' : 'l';
│ │ │ │ │
│ │ │ │ │ return opp;
│ │ │ │ │ };
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ + OpenLayers/BaseTypes/Element.js
│ │ │ │ │ + ====================================================================== */
│ │ │ │ │ +
│ │ │ │ │ +/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ + * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ + * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ + * full text of the license. */
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * @requires OpenLayers/Util.js
│ │ │ │ │ + * @requires OpenLayers/BaseTypes.js
│ │ │ │ │ + */
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Namespace: OpenLayers.Element
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Element = {
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: visible
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * element - {DOMElement}
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean} Is the element visible?
│ │ │ │ │ + */
│ │ │ │ │ + visible: function(element) {
│ │ │ │ │ + return OpenLayers.Util.getElement(element).style.display != 'none';
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: toggle
│ │ │ │ │ + * Toggle the visibility of element(s) passed in
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * element - {DOMElement} Actually user can pass any number of elements
│ │ │ │ │ + */
│ │ │ │ │ + toggle: function() {
│ │ │ │ │ + for (var i = 0, len = arguments.length; i < len; i++) {
│ │ │ │ │ + var element = OpenLayers.Util.getElement(arguments[i]);
│ │ │ │ │ + var display = OpenLayers.Element.visible(element) ? 'none' :
│ │ │ │ │ + '';
│ │ │ │ │ + element.style.display = display;
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: remove
│ │ │ │ │ + * Remove the specified element from the DOM.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * element - {DOMElement}
│ │ │ │ │ + */
│ │ │ │ │ + remove: function(element) {
│ │ │ │ │ + element = OpenLayers.Util.getElement(element);
│ │ │ │ │ + element.parentNode.removeChild(element);
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: getHeight
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * element - {DOMElement}
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Integer} The offset height of the element passed in
│ │ │ │ │ + */
│ │ │ │ │ + getHeight: function(element) {
│ │ │ │ │ + element = OpenLayers.Util.getElement(element);
│ │ │ │ │ + return element.offsetHeight;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Function: hasClass
│ │ │ │ │ + * Tests if an element has the given CSS class name.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * element - {DOMElement} A DOM element node.
│ │ │ │ │ + * name - {String} The CSS class name to search for.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean} The element has the given class name.
│ │ │ │ │ + */
│ │ │ │ │ + hasClass: function(element, name) {
│ │ │ │ │ + var names = element.className;
│ │ │ │ │ + return (!!names && new RegExp("(^|\\s)" + name + "(\\s|$)").test(names));
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Function: addClass
│ │ │ │ │ + * Add a CSS class name to an element. Safe where element already has
│ │ │ │ │ + * the class name.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * element - {DOMElement} A DOM element node.
│ │ │ │ │ + * name - {String} The CSS class name to add.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {DOMElement} The element.
│ │ │ │ │ + */
│ │ │ │ │ + addClass: function(element, name) {
│ │ │ │ │ + if (!OpenLayers.Element.hasClass(element, name)) {
│ │ │ │ │ + element.className += (element.className ? " " : "") + name;
│ │ │ │ │ + }
│ │ │ │ │ + return element;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Function: removeClass
│ │ │ │ │ + * Remove a CSS class name from an element. Safe where element does not
│ │ │ │ │ + * have the class name.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * element - {DOMElement} A DOM element node.
│ │ │ │ │ + * name - {String} The CSS class name to remove.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {DOMElement} The element.
│ │ │ │ │ + */
│ │ │ │ │ + removeClass: function(element, name) {
│ │ │ │ │ + var names = element.className;
│ │ │ │ │ + if (names) {
│ │ │ │ │ + element.className = OpenLayers.String.trim(
│ │ │ │ │ + names.replace(
│ │ │ │ │ + new RegExp("(^|\\s+)" + name + "(\\s+|$)"), " "
│ │ │ │ │ + )
│ │ │ │ │ + );
│ │ │ │ │ + }
│ │ │ │ │ + return element;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Function: toggleClass
│ │ │ │ │ + * Remove a CSS class name from an element if it exists. Add the class name
│ │ │ │ │ + * if it doesn't exist.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * element - {DOMElement} A DOM element node.
│ │ │ │ │ + * name - {String} The CSS class name to toggle.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {DOMElement} The element.
│ │ │ │ │ + */
│ │ │ │ │ + toggleClass: function(element, name) {
│ │ │ │ │ + if (OpenLayers.Element.hasClass(element, name)) {
│ │ │ │ │ + OpenLayers.Element.removeClass(element, name);
│ │ │ │ │ + } else {
│ │ │ │ │ + OpenLayers.Element.addClass(element, name);
│ │ │ │ │ + }
│ │ │ │ │ + return element;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: getStyle
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * element - {DOMElement}
│ │ │ │ │ + * style - {?}
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {?}
│ │ │ │ │ + */
│ │ │ │ │ + getStyle: function(element, style) {
│ │ │ │ │ + element = OpenLayers.Util.getElement(element);
│ │ │ │ │ +
│ │ │ │ │ + var value = null;
│ │ │ │ │ + if (element && element.style) {
│ │ │ │ │ + value = element.style[OpenLayers.String.camelize(style)];
│ │ │ │ │ + if (!value) {
│ │ │ │ │ + if (document.defaultView &&
│ │ │ │ │ + document.defaultView.getComputedStyle) {
│ │ │ │ │ +
│ │ │ │ │ + var css = document.defaultView.getComputedStyle(element, null);
│ │ │ │ │ + value = css ? css.getPropertyValue(style) : null;
│ │ │ │ │ + } else if (element.currentStyle) {
│ │ │ │ │ + value = element.currentStyle[OpenLayers.String.camelize(style)];
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + var positions = ['left', 'top', 'right', 'bottom'];
│ │ │ │ │ + if (window.opera &&
│ │ │ │ │ + (OpenLayers.Util.indexOf(positions, style) != -1) &&
│ │ │ │ │ + (OpenLayers.Element.getStyle(element, 'position') == 'static')) {
│ │ │ │ │ + value = 'auto';
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + return value == 'auto' ? null : value;
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ +};
│ │ │ │ │ +/* ======================================================================
│ │ │ │ │ OpenLayers/BaseTypes/LonLat.js
│ │ │ │ │ ====================================================================== */
│ │ │ │ │
│ │ │ │ │ /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ * full text of the license. */
│ │ │ │ │ @@ -2327,14 +2243,268 @@
│ │ │ │ │ }
│ │ │ │ │ return equals;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ CLASS_NAME: "OpenLayers.Size"
│ │ │ │ │ });
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ + OpenLayers/Console.js
│ │ │ │ │ + ====================================================================== */
│ │ │ │ │ +
│ │ │ │ │ +/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ + * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ + * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ + * full text of the license. */
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ + */
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Namespace: OpenLayers.Console
│ │ │ │ │ + * The OpenLayers.Console namespace is used for debugging and error logging.
│ │ │ │ │ + * If the Firebug Lite (../Firebug/firebug.js) is included before this script,
│ │ │ │ │ + * calls to OpenLayers.Console methods will get redirected to window.console.
│ │ │ │ │ + * This makes use of the Firebug extension where available and allows for
│ │ │ │ │ + * cross-browser debugging Firebug style.
│ │ │ │ │ + *
│ │ │ │ │ + * Note:
│ │ │ │ │ + * Note that behavior will differ with the Firebug extention and Firebug Lite.
│ │ │ │ │ + * Most notably, the Firebug Lite console does not currently allow for
│ │ │ │ │ + * hyperlinks to code or for clicking on object to explore their properties.
│ │ │ │ │ + *
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Console = {
│ │ │ │ │ + /**
│ │ │ │ │ + * Create empty functions for all console methods. The real value of these
│ │ │ │ │ + * properties will be set if Firebug Lite (../Firebug/firebug.js script) is
│ │ │ │ │ + * included. We explicitly require the Firebug Lite script to trigger
│ │ │ │ │ + * functionality of the OpenLayers.Console methods.
│ │ │ │ │ + */
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: log
│ │ │ │ │ + * Log an object in the console. The Firebug Lite console logs string
│ │ │ │ │ + * representation of objects. Given multiple arguments, they will
│ │ │ │ │ + * be cast to strings and logged with a space delimiter. If the first
│ │ │ │ │ + * argument is a string with printf-like formatting, subsequent arguments
│ │ │ │ │ + * will be used in string substitution. Any additional arguments (beyond
│ │ │ │ │ + * the number substituted in a format string) will be appended in a space-
│ │ │ │ │ + * delimited line.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * object - {Object}
│ │ │ │ │ + */
│ │ │ │ │ + log: function() {},
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: debug
│ │ │ │ │ + * Writes a message to the console, including a hyperlink to the line
│ │ │ │ │ + * where it was called.
│ │ │ │ │ + *
│ │ │ │ │ + * May be called with multiple arguments as with OpenLayers.Console.log().
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * object - {Object}
│ │ │ │ │ + */
│ │ │ │ │ + debug: function() {},
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: info
│ │ │ │ │ + * Writes a message to the console with the visual "info" icon and color
│ │ │ │ │ + * coding and a hyperlink to the line where it was called.
│ │ │ │ │ + *
│ │ │ │ │ + * May be called with multiple arguments as with OpenLayers.Console.log().
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * object - {Object}
│ │ │ │ │ + */
│ │ │ │ │ + info: function() {},
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: warn
│ │ │ │ │ + * Writes a message to the console with the visual "warning" icon and
│ │ │ │ │ + * color coding and a hyperlink to the line where it was called.
│ │ │ │ │ + *
│ │ │ │ │ + * May be called with multiple arguments as with OpenLayers.Console.log().
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * object - {Object}
│ │ │ │ │ + */
│ │ │ │ │ + warn: function() {},
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: error
│ │ │ │ │ + * Writes a message to the console with the visual "error" icon and color
│ │ │ │ │ + * coding and a hyperlink to the line where it was called.
│ │ │ │ │ + *
│ │ │ │ │ + * May be called with multiple arguments as with OpenLayers.Console.log().
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * object - {Object}
│ │ │ │ │ + */
│ │ │ │ │ + error: function() {},
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: userError
│ │ │ │ │ + * A single interface for showing error messages to the user. The default
│ │ │ │ │ + * behavior is a Javascript alert, though this can be overridden by
│ │ │ │ │ + * reassigning OpenLayers.Console.userError to a different function.
│ │ │ │ │ + *
│ │ │ │ │ + * Expects a single error message
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * error - {Object}
│ │ │ │ │ + */
│ │ │ │ │ + userError: function(error) {
│ │ │ │ │ + alert(error);
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: assert
│ │ │ │ │ + * Tests that an expression is true. If not, it will write a message to
│ │ │ │ │ + * the console and throw an exception.
│ │ │ │ │ + *
│ │ │ │ │ + * May be called with multiple arguments as with OpenLayers.Console.log().
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * object - {Object}
│ │ │ │ │ + */
│ │ │ │ │ + assert: function() {},
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: dir
│ │ │ │ │ + * Prints an interactive listing of all properties of the object. This
│ │ │ │ │ + * looks identical to the view that you would see in the DOM tab.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * object - {Object}
│ │ │ │ │ + */
│ │ │ │ │ + dir: function() {},
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: dirxml
│ │ │ │ │ + * Prints the XML source tree of an HTML or XML element. This looks
│ │ │ │ │ + * identical to the view that you would see in the HTML tab. You can click
│ │ │ │ │ + * on any node to inspect it in the HTML tab.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * object - {Object}
│ │ │ │ │ + */
│ │ │ │ │ + dirxml: function() {},
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: trace
│ │ │ │ │ + * Prints an interactive stack trace of JavaScript execution at the point
│ │ │ │ │ + * where it is called. The stack trace details the functions on the stack,
│ │ │ │ │ + * as well as the values that were passed as arguments to each function.
│ │ │ │ │ + * You can click each function to take you to its source in the Script tab,
│ │ │ │ │ + * and click each argument value to inspect it in the DOM or HTML tabs.
│ │ │ │ │ + *
│ │ │ │ │ + */
│ │ │ │ │ + trace: function() {},
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: group
│ │ │ │ │ + * Writes a message to the console and opens a nested block to indent all
│ │ │ │ │ + * future messages sent to the console. Call OpenLayers.Console.groupEnd()
│ │ │ │ │ + * to close the block.
│ │ │ │ │ + *
│ │ │ │ │ + * May be called with multiple arguments as with OpenLayers.Console.log().
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * object - {Object}
│ │ │ │ │ + */
│ │ │ │ │ + group: function() {},
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: groupEnd
│ │ │ │ │ + * Closes the most recently opened block created by a call to
│ │ │ │ │ + * OpenLayers.Console.group
│ │ │ │ │ + */
│ │ │ │ │ + groupEnd: function() {},
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: time
│ │ │ │ │ + * Creates a new timer under the given name. Call
│ │ │ │ │ + * OpenLayers.Console.timeEnd(name)
│ │ │ │ │ + * with the same name to stop the timer and print the time elapsed.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * name - {String}
│ │ │ │ │ + */
│ │ │ │ │ + time: function() {},
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: timeEnd
│ │ │ │ │ + * Stops a timer created by a call to OpenLayers.Console.time(name) and
│ │ │ │ │ + * writes the time elapsed.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * name - {String}
│ │ │ │ │ + */
│ │ │ │ │ + timeEnd: function() {},
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: profile
│ │ │ │ │ + * Turns on the JavaScript profiler. The optional argument title would
│ │ │ │ │ + * contain the text to be printed in the header of the profile report.
│ │ │ │ │ + *
│ │ │ │ │ + * This function is not currently implemented in Firebug Lite.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * title - {String} Optional title for the profiler
│ │ │ │ │ + */
│ │ │ │ │ + profile: function() {},
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: profileEnd
│ │ │ │ │ + * Turns off the JavaScript profiler and prints its report.
│ │ │ │ │ + *
│ │ │ │ │ + * This function is not currently implemented in Firebug Lite.
│ │ │ │ │ + */
│ │ │ │ │ + profileEnd: function() {},
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIFunction: count
│ │ │ │ │ + * Writes the number of times that the line of code where count was called
│ │ │ │ │ + * was executed. The optional argument title will print a message in
│ │ │ │ │ + * addition to the number of the count.
│ │ │ │ │ + *
│ │ │ │ │ + * This function is not currently implemented in Firebug Lite.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * title - {String} Optional title to be printed with count
│ │ │ │ │ + */
│ │ │ │ │ + count: function() {},
│ │ │ │ │ +
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Console"
│ │ │ │ │ +};
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Execute an anonymous function to extend the OpenLayers.Console namespace
│ │ │ │ │ + * if the firebug.js script is included. This closure is used so that the
│ │ │ │ │ + * "scripts" and "i" variables don't pollute the global namespace.
│ │ │ │ │ + */
│ │ │ │ │ +(function() {
│ │ │ │ │ + /**
│ │ │ │ │ + * If Firebug Lite is included (before this script), re-route all
│ │ │ │ │ + * OpenLayers.Console calls to the console object.
│ │ │ │ │ + */
│ │ │ │ │ + var scripts = document.getElementsByTagName("script");
│ │ │ │ │ + for (var i = 0, len = scripts.length; i < len; ++i) {
│ │ │ │ │ + if (scripts[i].src.indexOf("firebug.js") != -1) {
│ │ │ │ │ + if (console) {
│ │ │ │ │ + OpenLayers.Util.extend(OpenLayers.Console, console);
│ │ │ │ │ + break;
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ +})();
│ │ │ │ │ +/* ======================================================================
│ │ │ │ │ OpenLayers/Lang.js
│ │ │ │ │ ====================================================================== */
│ │ │ │ │
│ │ │ │ │ /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ * full text of the license. */
│ │ │ │ │ @@ -4256,3198 +4426,1940 @@
│ │ │ │ │ } else {
│ │ │ │ │ str += coordinate < 0 ? OpenLayers.i18n("S") : OpenLayers.i18n("N");
│ │ │ │ │ }
│ │ │ │ │ return str;
│ │ │ │ │ };
│ │ │ │ │
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/BaseTypes/Element.js
│ │ │ │ │ + OpenLayers/Util/vendorPrefix.js
│ │ │ │ │ ====================================================================== */
│ │ │ │ │
│ │ │ │ │ /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ * full text of the license. */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * @requires OpenLayers/Util.js
│ │ │ │ │ - * @requires OpenLayers/BaseTypes.js
│ │ │ │ │ + * @requires OpenLayers/SingleFile.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ +OpenLayers.Util = OpenLayers.Util || {};
│ │ │ │ │ /**
│ │ │ │ │ - * Namespace: OpenLayers.Element
│ │ │ │ │ + * Namespace: OpenLayers.Util.vendorPrefix
│ │ │ │ │ + * A collection of utility functions to detect vendor prefixed features
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Element = {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: visible
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * element - {DOMElement}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} Is the element visible?
│ │ │ │ │ - */
│ │ │ │ │ - visible: function(element) {
│ │ │ │ │ - return OpenLayers.Util.getElement(element).style.display != 'none';
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: toggle
│ │ │ │ │ - * Toggle the visibility of element(s) passed in
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * element - {DOMElement} Actually user can pass any number of elements
│ │ │ │ │ - */
│ │ │ │ │ - toggle: function() {
│ │ │ │ │ - for (var i = 0, len = arguments.length; i < len; i++) {
│ │ │ │ │ - var element = OpenLayers.Util.getElement(arguments[i]);
│ │ │ │ │ - var display = OpenLayers.Element.visible(element) ? 'none' :
│ │ │ │ │ - '';
│ │ │ │ │ - element.style.display = display;
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ +OpenLayers.Util.vendorPrefix = (function() {
│ │ │ │ │ + "use strict";
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: remove
│ │ │ │ │ - * Remove the specified element from the DOM.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * element - {DOMElement}
│ │ │ │ │ - */
│ │ │ │ │ - remove: function(element) {
│ │ │ │ │ - element = OpenLayers.Util.getElement(element);
│ │ │ │ │ - element.parentNode.removeChild(element);
│ │ │ │ │ - },
│ │ │ │ │ + var VENDOR_PREFIXES = ["", "O", "ms", "Moz", "Webkit"],
│ │ │ │ │ + divStyle = document.createElement("div").style,
│ │ │ │ │ + cssCache = {},
│ │ │ │ │ + jsCache = {};
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: getHeight
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * element - {DOMElement}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Integer} The offset height of the element passed in
│ │ │ │ │ - */
│ │ │ │ │ - getHeight: function(element) {
│ │ │ │ │ - element = OpenLayers.Util.getElement(element);
│ │ │ │ │ - return element.offsetHeight;
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Function: hasClass
│ │ │ │ │ - * Tests if an element has the given CSS class name.
│ │ │ │ │ + * Function: domToCss
│ │ │ │ │ + * Converts a upper camel case DOM style property name to a CSS property
│ │ │ │ │ + * i.e. transformOrigin -> transform-origin
│ │ │ │ │ + * or WebkitTransformOrigin -> -webkit-transform-origin
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * element - {DOMElement} A DOM element node.
│ │ │ │ │ - * name - {String} The CSS class name to search for.
│ │ │ │ │ + * prefixedDom - {String} The property to convert
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Boolean} The element has the given class name.
│ │ │ │ │ + * {String} The CSS property
│ │ │ │ │ */
│ │ │ │ │ - hasClass: function(element, name) {
│ │ │ │ │ - var names = element.className;
│ │ │ │ │ - return (!!names && new RegExp("(^|\\s)" + name + "(\\s|$)").test(names));
│ │ │ │ │ - },
│ │ │ │ │ + function domToCss(prefixedDom) {
│ │ │ │ │ + if (!prefixedDom) {
│ │ │ │ │ + return null;
│ │ │ │ │ + }
│ │ │ │ │ + return prefixedDom.
│ │ │ │ │ + replace(/([A-Z])/g, function(c) {
│ │ │ │ │ + return "-" + c.toLowerCase();
│ │ │ │ │ + }).
│ │ │ │ │ + replace(/^ms-/, "-ms-");
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Function: addClass
│ │ │ │ │ - * Add a CSS class name to an element. Safe where element already has
│ │ │ │ │ - * the class name.
│ │ │ │ │ + * APIMethod: css
│ │ │ │ │ + * Detect which property is used for a CSS property
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * element - {DOMElement} A DOM element node.
│ │ │ │ │ - * name - {String} The CSS class name to add.
│ │ │ │ │ + * property - {String} The standard (unprefixed) CSS property name
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {DOMElement} The element.
│ │ │ │ │ + * {String} The standard CSS property, prefixed property or null if not
│ │ │ │ │ + * supported
│ │ │ │ │ */
│ │ │ │ │ - addClass: function(element, name) {
│ │ │ │ │ - if (!OpenLayers.Element.hasClass(element, name)) {
│ │ │ │ │ - element.className += (element.className ? " " : "") + name;
│ │ │ │ │ + function css(property) {
│ │ │ │ │ + if (cssCache[property] === undefined) {
│ │ │ │ │ + var domProperty = property.
│ │ │ │ │ + replace(/(-[\s\S])/g, function(c) {
│ │ │ │ │ + return c.charAt(1).toUpperCase();
│ │ │ │ │ + });
│ │ │ │ │ + var prefixedDom = style(domProperty);
│ │ │ │ │ + cssCache[property] = domToCss(prefixedDom);
│ │ │ │ │ }
│ │ │ │ │ - return element;
│ │ │ │ │ - },
│ │ │ │ │ + return cssCache[property];
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Function: removeClass
│ │ │ │ │ - * Remove a CSS class name from an element. Safe where element does not
│ │ │ │ │ - * have the class name.
│ │ │ │ │ + * APIMethod: js
│ │ │ │ │ + * Detect which property is used for a JS property/method
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * element - {DOMElement} A DOM element node.
│ │ │ │ │ - * name - {String} The CSS class name to remove.
│ │ │ │ │ + * obj - {Object} The object to test on
│ │ │ │ │ + * property - {String} The standard (unprefixed) JS property name
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {DOMElement} The element.
│ │ │ │ │ + * {String} The standard JS property, prefixed property or null if not
│ │ │ │ │ + * supported
│ │ │ │ │ */
│ │ │ │ │ - removeClass: function(element, name) {
│ │ │ │ │ - var names = element.className;
│ │ │ │ │ - if (names) {
│ │ │ │ │ - element.className = OpenLayers.String.trim(
│ │ │ │ │ - names.replace(
│ │ │ │ │ - new RegExp("(^|\\s+)" + name + "(\\s+|$)"), " "
│ │ │ │ │ - )
│ │ │ │ │ - );
│ │ │ │ │ + function js(obj, property) {
│ │ │ │ │ + if (jsCache[property] === undefined) {
│ │ │ │ │ + var tmpProp,
│ │ │ │ │ + i = 0,
│ │ │ │ │ + l = VENDOR_PREFIXES.length,
│ │ │ │ │ + prefix,
│ │ │ │ │ + isStyleObj = (typeof obj.cssText !== "undefined");
│ │ │ │ │ +
│ │ │ │ │ + jsCache[property] = null;
│ │ │ │ │ + for (; i < l; i++) {
│ │ │ │ │ + prefix = VENDOR_PREFIXES[i];
│ │ │ │ │ + if (prefix) {
│ │ │ │ │ + if (!isStyleObj) {
│ │ │ │ │ + // js prefix should be lower-case, while style
│ │ │ │ │ + // properties have upper case on first character
│ │ │ │ │ + prefix = prefix.toLowerCase();
│ │ │ │ │ + }
│ │ │ │ │ + tmpProp = prefix + property.charAt(0).toUpperCase() + property.slice(1);
│ │ │ │ │ + } else {
│ │ │ │ │ + tmpProp = property;
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + if (obj[tmpProp] !== undefined) {
│ │ │ │ │ + jsCache[property] = tmpProp;
│ │ │ │ │ + break;
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ - return element;
│ │ │ │ │ - },
│ │ │ │ │ + return jsCache[property];
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Function: toggleClass
│ │ │ │ │ - * Remove a CSS class name from an element if it exists. Add the class name
│ │ │ │ │ - * if it doesn't exist.
│ │ │ │ │ + * APIMethod: style
│ │ │ │ │ + * Detect which property is used for a DOM style property
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * element - {DOMElement} A DOM element node.
│ │ │ │ │ - * name - {String} The CSS class name to toggle.
│ │ │ │ │ + * property - {String} The standard (unprefixed) style property name
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {DOMElement} The element.
│ │ │ │ │ - */
│ │ │ │ │ - toggleClass: function(element, name) {
│ │ │ │ │ - if (OpenLayers.Element.hasClass(element, name)) {
│ │ │ │ │ - OpenLayers.Element.removeClass(element, name);
│ │ │ │ │ - } else {
│ │ │ │ │ - OpenLayers.Element.addClass(element, name);
│ │ │ │ │ - }
│ │ │ │ │ - return element;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIFunction: getStyle
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * element - {DOMElement}
│ │ │ │ │ - * style - {?}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {?}
│ │ │ │ │ + * {String} The standard style property, prefixed property or null if not
│ │ │ │ │ + * supported
│ │ │ │ │ */
│ │ │ │ │ - getStyle: function(element, style) {
│ │ │ │ │ - element = OpenLayers.Util.getElement(element);
│ │ │ │ │ -
│ │ │ │ │ - var value = null;
│ │ │ │ │ - if (element && element.style) {
│ │ │ │ │ - value = element.style[OpenLayers.String.camelize(style)];
│ │ │ │ │ - if (!value) {
│ │ │ │ │ - if (document.defaultView &&
│ │ │ │ │ - document.defaultView.getComputedStyle) {
│ │ │ │ │ -
│ │ │ │ │ - var css = document.defaultView.getComputedStyle(element, null);
│ │ │ │ │ - value = css ? css.getPropertyValue(style) : null;
│ │ │ │ │ - } else if (element.currentStyle) {
│ │ │ │ │ - value = element.currentStyle[OpenLayers.String.camelize(style)];
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - var positions = ['left', 'top', 'right', 'bottom'];
│ │ │ │ │ - if (window.opera &&
│ │ │ │ │ - (OpenLayers.Util.indexOf(positions, style) != -1) &&
│ │ │ │ │ - (OpenLayers.Element.getStyle(element, 'position') == 'static')) {
│ │ │ │ │ - value = 'auto';
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - return value == 'auto' ? null : value;
│ │ │ │ │ + function style(property) {
│ │ │ │ │ + return js(divStyle, property);
│ │ │ │ │ }
│ │ │ │ │
│ │ │ │ │ -};
│ │ │ │ │ + return {
│ │ │ │ │ + css: css,
│ │ │ │ │ + js: js,
│ │ │ │ │ + style: style,
│ │ │ │ │ +
│ │ │ │ │ + // used for testing
│ │ │ │ │ + cssCache: cssCache,
│ │ │ │ │ + jsCache: jsCache
│ │ │ │ │ + };
│ │ │ │ │ +}());
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - Rico/Color.js
│ │ │ │ │ + OpenLayers/Events.js
│ │ │ │ │ ====================================================================== */
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires Rico/license.js
│ │ │ │ │ - * @requires OpenLayers/Console.js
│ │ │ │ │ - * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ - * @requires OpenLayers/BaseTypes/Element.js
│ │ │ │ │ - */
│ │ │ │ │ +/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ + * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ + * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ + * full text of the license. */
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │ -/*
│ │ │ │ │ - * This file has been edited substantially from the Rico-released version by
│ │ │ │ │ - * the OpenLayers development team.
│ │ │ │ │ +/**
│ │ │ │ │ + * @requires OpenLayers/Util.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ -OpenLayers.Console.warn("OpenLayers.Rico is deprecated");
│ │ │ │ │ -
│ │ │ │ │ -OpenLayers.Rico = OpenLayers.Rico || {};
│ │ │ │ │ -OpenLayers.Rico.Color = OpenLayers.Class({
│ │ │ │ │ -
│ │ │ │ │ - initialize: function(red, green, blue) {
│ │ │ │ │ - this.rgb = {
│ │ │ │ │ - r: red,
│ │ │ │ │ - g: green,
│ │ │ │ │ - b: blue
│ │ │ │ │ - };
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - setRed: function(r) {
│ │ │ │ │ - this.rgb.r = r;
│ │ │ │ │ - },
│ │ │ │ │ +/**
│ │ │ │ │ + * Namespace: OpenLayers.Event
│ │ │ │ │ + * Utility functions for event handling.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Event = {
│ │ │ │ │
│ │ │ │ │ - setGreen: function(g) {
│ │ │ │ │ - this.rgb.g = g;
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: observers
│ │ │ │ │ + * {Object} A hashtable cache of the event observers. Keyed by
│ │ │ │ │ + * element._eventCacheID
│ │ │ │ │ + */
│ │ │ │ │ + observers: false,
│ │ │ │ │
│ │ │ │ │ - setBlue: function(b) {
│ │ │ │ │ - this.rgb.b = b;
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * Constant: KEY_SPACE
│ │ │ │ │ + * {int}
│ │ │ │ │ + */
│ │ │ │ │ + KEY_SPACE: 32,
│ │ │ │ │
│ │ │ │ │ - setHue: function(h) {
│ │ │ │ │ + /**
│ │ │ │ │ + * Constant: KEY_BACKSPACE
│ │ │ │ │ + * {int}
│ │ │ │ │ + */
│ │ │ │ │ + KEY_BACKSPACE: 8,
│ │ │ │ │
│ │ │ │ │ - // get an HSB model, and set the new hue...
│ │ │ │ │ - var hsb = this.asHSB();
│ │ │ │ │ - hsb.h = h;
│ │ │ │ │ + /**
│ │ │ │ │ + * Constant: KEY_TAB
│ │ │ │ │ + * {int}
│ │ │ │ │ + */
│ │ │ │ │ + KEY_TAB: 9,
│ │ │ │ │
│ │ │ │ │ - // convert back to RGB...
│ │ │ │ │ - this.rgb = OpenLayers.Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b);
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * Constant: KEY_RETURN
│ │ │ │ │ + * {int}
│ │ │ │ │ + */
│ │ │ │ │ + KEY_RETURN: 13,
│ │ │ │ │
│ │ │ │ │ - setSaturation: function(s) {
│ │ │ │ │ - // get an HSB model, and set the new hue...
│ │ │ │ │ - var hsb = this.asHSB();
│ │ │ │ │ - hsb.s = s;
│ │ │ │ │ + /**
│ │ │ │ │ + * Constant: KEY_ESC
│ │ │ │ │ + * {int}
│ │ │ │ │ + */
│ │ │ │ │ + KEY_ESC: 27,
│ │ │ │ │
│ │ │ │ │ - // convert back to RGB and set values...
│ │ │ │ │ - this.rgb = OpenLayers.Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b);
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * Constant: KEY_LEFT
│ │ │ │ │ + * {int}
│ │ │ │ │ + */
│ │ │ │ │ + KEY_LEFT: 37,
│ │ │ │ │
│ │ │ │ │ - setBrightness: function(b) {
│ │ │ │ │ - // get an HSB model, and set the new hue...
│ │ │ │ │ - var hsb = this.asHSB();
│ │ │ │ │ - hsb.b = b;
│ │ │ │ │ + /**
│ │ │ │ │ + * Constant: KEY_UP
│ │ │ │ │ + * {int}
│ │ │ │ │ + */
│ │ │ │ │ + KEY_UP: 38,
│ │ │ │ │
│ │ │ │ │ - // convert back to RGB and set values...
│ │ │ │ │ - this.rgb = OpenLayers.Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b);
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * Constant: KEY_RIGHT
│ │ │ │ │ + * {int}
│ │ │ │ │ + */
│ │ │ │ │ + KEY_RIGHT: 39,
│ │ │ │ │
│ │ │ │ │ - darken: function(percent) {
│ │ │ │ │ - var hsb = this.asHSB();
│ │ │ │ │ - this.rgb = OpenLayers.Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.max(hsb.b - percent, 0));
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * Constant: KEY_DOWN
│ │ │ │ │ + * {int}
│ │ │ │ │ + */
│ │ │ │ │ + KEY_DOWN: 40,
│ │ │ │ │
│ │ │ │ │ - brighten: function(percent) {
│ │ │ │ │ - var hsb = this.asHSB();
│ │ │ │ │ - this.rgb = OpenLayers.Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.min(hsb.b + percent, 1));
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * Constant: KEY_DELETE
│ │ │ │ │ + * {int}
│ │ │ │ │ + */
│ │ │ │ │ + KEY_DELETE: 46,
│ │ │ │ │
│ │ │ │ │ - blend: function(other) {
│ │ │ │ │ - this.rgb.r = Math.floor((this.rgb.r + other.rgb.r) / 2);
│ │ │ │ │ - this.rgb.g = Math.floor((this.rgb.g + other.rgb.g) / 2);
│ │ │ │ │ - this.rgb.b = Math.floor((this.rgb.b + other.rgb.b) / 2);
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ - isBright: function() {
│ │ │ │ │ - var hsb = this.asHSB();
│ │ │ │ │ - return this.asHSB().b > 0.5;
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: element
│ │ │ │ │ + * Cross browser event element detection.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * event - {Event}
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {DOMElement} The element that caused the event
│ │ │ │ │ + */
│ │ │ │ │ + element: function(event) {
│ │ │ │ │ + return event.target || event.srcElement;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - isDark: function() {
│ │ │ │ │ - return !this.isBright();
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: isSingleTouch
│ │ │ │ │ + * Determine whether event was caused by a single touch
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * event - {Event}
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean}
│ │ │ │ │ + */
│ │ │ │ │ + isSingleTouch: function(event) {
│ │ │ │ │ + return event.touches && event.touches.length == 1;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - asRGB: function() {
│ │ │ │ │ - return "rgb(" + this.rgb.r + "," + this.rgb.g + "," + this.rgb.b + ")";
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: isMultiTouch
│ │ │ │ │ + * Determine whether event was caused by a multi touch
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * event - {Event}
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean}
│ │ │ │ │ + */
│ │ │ │ │ + isMultiTouch: function(event) {
│ │ │ │ │ + return event.touches && event.touches.length > 1;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - asHex: function() {
│ │ │ │ │ - return "#" + this.rgb.r.toColorPart() + this.rgb.g.toColorPart() + this.rgb.b.toColorPart();
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: isLeftClick
│ │ │ │ │ + * Determine whether event was caused by a left click.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * event - {Event}
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean}
│ │ │ │ │ + */
│ │ │ │ │ + isLeftClick: function(event) {
│ │ │ │ │ + return (((event.which) && (event.which == 1)) ||
│ │ │ │ │ + ((event.button) && (event.button == 1)));
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - asHSB: function() {
│ │ │ │ │ - return OpenLayers.Rico.Color.RGBtoHSB(this.rgb.r, this.rgb.g, this.rgb.b);
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: isRightClick
│ │ │ │ │ + * Determine whether event was caused by a right mouse click.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * event - {Event}
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean}
│ │ │ │ │ + */
│ │ │ │ │ + isRightClick: function(event) {
│ │ │ │ │ + return (((event.which) && (event.which == 3)) ||
│ │ │ │ │ + ((event.button) && (event.button == 2)));
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - toString: function() {
│ │ │ │ │ - return this.asHex();
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ -});
│ │ │ │ │ -
│ │ │ │ │ -OpenLayers.Rico.Color.createFromHex = function(hexCode) {
│ │ │ │ │ - if (hexCode.length == 4) {
│ │ │ │ │ - var shortHexCode = hexCode;
│ │ │ │ │ - var hexCode = '#';
│ │ │ │ │ - for (var i = 1; i < 4; i++) {
│ │ │ │ │ - hexCode += (shortHexCode.charAt(i) +
│ │ │ │ │ - shortHexCode.charAt(i));
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - if (hexCode.indexOf('#') == 0) {
│ │ │ │ │ - hexCode = hexCode.substring(1);
│ │ │ │ │ - }
│ │ │ │ │ - var red = hexCode.substring(0, 2);
│ │ │ │ │ - var green = hexCode.substring(2, 4);
│ │ │ │ │ - var blue = hexCode.substring(4, 6);
│ │ │ │ │ - return new OpenLayers.Rico.Color(parseInt(red, 16), parseInt(green, 16), parseInt(blue, 16));
│ │ │ │ │ -};
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Factory method for creating a color from the background of
│ │ │ │ │ - * an HTML element.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Rico.Color.createColorFromBackground = function(elem) {
│ │ │ │ │ -
│ │ │ │ │ - var actualColor =
│ │ │ │ │ - OpenLayers.Element.getStyle(OpenLayers.Util.getElement(elem),
│ │ │ │ │ - "backgroundColor");
│ │ │ │ │ -
│ │ │ │ │ - if (actualColor == "transparent" && elem.parentNode) {
│ │ │ │ │ - return OpenLayers.Rico.Color.createColorFromBackground(elem.parentNode);
│ │ │ │ │ - }
│ │ │ │ │ - if (actualColor == null) {
│ │ │ │ │ - return new OpenLayers.Rico.Color(255, 255, 255);
│ │ │ │ │ - }
│ │ │ │ │ - if (actualColor.indexOf("rgb(") == 0) {
│ │ │ │ │ - var colors = actualColor.substring(4, actualColor.length - 1);
│ │ │ │ │ - var colorArray = colors.split(",");
│ │ │ │ │ - return new OpenLayers.Rico.Color(parseInt(colorArray[0]),
│ │ │ │ │ - parseInt(colorArray[1]),
│ │ │ │ │ - parseInt(colorArray[2]));
│ │ │ │ │ -
│ │ │ │ │ - } else if (actualColor.indexOf("#") == 0) {
│ │ │ │ │ - return OpenLayers.Rico.Color.createFromHex(actualColor);
│ │ │ │ │ - } else {
│ │ │ │ │ - return new OpenLayers.Rico.Color(255, 255, 255);
│ │ │ │ │ - }
│ │ │ │ │ -};
│ │ │ │ │ -
│ │ │ │ │ -OpenLayers.Rico.Color.HSBtoRGB = function(hue, saturation, brightness) {
│ │ │ │ │ -
│ │ │ │ │ - var red = 0;
│ │ │ │ │ - var green = 0;
│ │ │ │ │ - var blue = 0;
│ │ │ │ │ -
│ │ │ │ │ - if (saturation == 0) {
│ │ │ │ │ - red = parseInt(brightness * 255.0 + 0.5);
│ │ │ │ │ - green = red;
│ │ │ │ │ - blue = red;
│ │ │ │ │ - } else {
│ │ │ │ │ - var h = (hue - Math.floor(hue)) * 6.0;
│ │ │ │ │ - var f = h - Math.floor(h);
│ │ │ │ │ - var p = brightness * (1.0 - saturation);
│ │ │ │ │ - var q = brightness * (1.0 - saturation * f);
│ │ │ │ │ - var t = brightness * (1.0 - (saturation * (1.0 - f)));
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: stop
│ │ │ │ │ + * Stops an event from propagating.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * event - {Event}
│ │ │ │ │ + * allowDefault - {Boolean} If true, we stop the event chain but
│ │ │ │ │ + * still allow the default browser behaviour (text selection,
│ │ │ │ │ + * radio-button clicking, etc). Default is false.
│ │ │ │ │ + */
│ │ │ │ │ + stop: function(event, allowDefault) {
│ │ │ │ │
│ │ │ │ │ - switch (parseInt(h)) {
│ │ │ │ │ - case 0:
│ │ │ │ │ - red = (brightness * 255.0 + 0.5);
│ │ │ │ │ - green = (t * 255.0 + 0.5);
│ │ │ │ │ - blue = (p * 255.0 + 0.5);
│ │ │ │ │ - break;
│ │ │ │ │ - case 1:
│ │ │ │ │ - red = (q * 255.0 + 0.5);
│ │ │ │ │ - green = (brightness * 255.0 + 0.5);
│ │ │ │ │ - blue = (p * 255.0 + 0.5);
│ │ │ │ │ - break;
│ │ │ │ │ - case 2:
│ │ │ │ │ - red = (p * 255.0 + 0.5);
│ │ │ │ │ - green = (brightness * 255.0 + 0.5);
│ │ │ │ │ - blue = (t * 255.0 + 0.5);
│ │ │ │ │ - break;
│ │ │ │ │ - case 3:
│ │ │ │ │ - red = (p * 255.0 + 0.5);
│ │ │ │ │ - green = (q * 255.0 + 0.5);
│ │ │ │ │ - blue = (brightness * 255.0 + 0.5);
│ │ │ │ │ - break;
│ │ │ │ │ - case 4:
│ │ │ │ │ - red = (t * 255.0 + 0.5);
│ │ │ │ │ - green = (p * 255.0 + 0.5);
│ │ │ │ │ - blue = (brightness * 255.0 + 0.5);
│ │ │ │ │ - break;
│ │ │ │ │ - case 5:
│ │ │ │ │ - red = (brightness * 255.0 + 0.5);
│ │ │ │ │ - green = (p * 255.0 + 0.5);
│ │ │ │ │ - blue = (q * 255.0 + 0.5);
│ │ │ │ │ - break;
│ │ │ │ │ + if (!allowDefault) {
│ │ │ │ │ + OpenLayers.Event.preventDefault(event);
│ │ │ │ │ }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - return {
│ │ │ │ │ - r: parseInt(red),
│ │ │ │ │ - g: parseInt(green),
│ │ │ │ │ - b: parseInt(blue)
│ │ │ │ │ - };
│ │ │ │ │ -};
│ │ │ │ │ -
│ │ │ │ │ -OpenLayers.Rico.Color.RGBtoHSB = function(r, g, b) {
│ │ │ │ │ -
│ │ │ │ │ - var hue;
│ │ │ │ │ - var saturation;
│ │ │ │ │ - var brightness;
│ │ │ │ │ -
│ │ │ │ │ - var cmax = (r > g) ? r : g;
│ │ │ │ │ - if (b > cmax) {
│ │ │ │ │ - cmax = b;
│ │ │ │ │ - }
│ │ │ │ │ - var cmin = (r < g) ? r : g;
│ │ │ │ │ - if (b < cmin) {
│ │ │ │ │ - cmin = b;
│ │ │ │ │ - }
│ │ │ │ │ - brightness = cmax / 255.0;
│ │ │ │ │ - if (cmax != 0) {
│ │ │ │ │ - saturation = (cmax - cmin) / cmax;
│ │ │ │ │ - } else {
│ │ │ │ │ - saturation = 0;
│ │ │ │ │ - }
│ │ │ │ │ - if (saturation == 0) {
│ │ │ │ │ - hue = 0;
│ │ │ │ │ - } else {
│ │ │ │ │ - var redc = (cmax - r) / (cmax - cmin);
│ │ │ │ │ - var greenc = (cmax - g) / (cmax - cmin);
│ │ │ │ │ - var bluec = (cmax - b) / (cmax - cmin);
│ │ │ │ │
│ │ │ │ │ - if (r == cmax) {
│ │ │ │ │ - hue = bluec - greenc;
│ │ │ │ │ - } else if (g == cmax) {
│ │ │ │ │ - hue = 2.0 + redc - bluec;
│ │ │ │ │ + if (event.stopPropagation) {
│ │ │ │ │ + event.stopPropagation();
│ │ │ │ │ } else {
│ │ │ │ │ - hue = 4.0 + greenc - redc;
│ │ │ │ │ - }
│ │ │ │ │ - hue = hue / 6.0;
│ │ │ │ │ - if (hue < 0) {
│ │ │ │ │ - hue = hue + 1.0;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - return {
│ │ │ │ │ - h: hue,
│ │ │ │ │ - s: saturation,
│ │ │ │ │ - b: brightness
│ │ │ │ │ - };
│ │ │ │ │ -};
│ │ │ │ │ -
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - Rico/Corner.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/Console.js
│ │ │ │ │ - * @requires Rico/Color.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -
│ │ │ │ │ -/*
│ │ │ │ │ - * This file has been edited substantially from the Rico-released
│ │ │ │ │ - * version by the OpenLayers development team.
│ │ │ │ │ - *
│ │ │ │ │ - * Copyright 2005 Sabre Airline Solutions
│ │ │ │ │ - *
│ │ │ │ │ - * Licensed under the Apache License, Version 2.0 (the "License");
│ │ │ │ │ - * you may not use this file except in compliance with the
│ │ │ │ │ - * License. You may obtain a copy of the License at
│ │ │ │ │ - *
│ │ │ │ │ - * http://www.apache.org/licenses/LICENSE-2.0
│ │ │ │ │ - *
│ │ │ │ │ - * Unless required by applicable law or agreed to in writing, software
│ │ │ │ │ - * distributed under the * License is distributed on an "AS IS" BASIS,
│ │ │ │ │ - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or
│ │ │ │ │ - * implied. See the License for the specific language governing
│ │ │ │ │ - * permissions * and limitations under the License.
│ │ │ │ │ - *
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -OpenLayers.Console.warn("OpenLayers.Rico is deprecated");
│ │ │ │ │ -
│ │ │ │ │ -OpenLayers.Rico = OpenLayers.Rico || {};
│ │ │ │ │ -OpenLayers.Rico.Corner = {
│ │ │ │ │ -
│ │ │ │ │ - round: function(e, options) {
│ │ │ │ │ - e = OpenLayers.Util.getElement(e);
│ │ │ │ │ - this._setOptions(options);
│ │ │ │ │ -
│ │ │ │ │ - var color = this.options.color;
│ │ │ │ │ - if (this.options.color == "fromElement") {
│ │ │ │ │ - color = this._background(e);
│ │ │ │ │ - }
│ │ │ │ │ - var bgColor = this.options.bgColor;
│ │ │ │ │ - if (this.options.bgColor == "fromParent") {
│ │ │ │ │ - bgColor = this._background(e.offsetParent);
│ │ │ │ │ + event.cancelBubble = true;
│ │ │ │ │ }
│ │ │ │ │ - this._roundCornersImpl(e, color, bgColor);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - /** This is a helper function to change the background
│ │ │ │ │ - * color of
that has had Rico rounded corners added.
│ │ │ │ │ - *
│ │ │ │ │ - * It seems we cannot just set the background color for the
│ │ │ │ │ - * outer
so each
element used to create the
│ │ │ │ │ - * corners must have its background color set individually.
│ │ │ │ │ - *
│ │ │ │ │ - * @param {DOM} theDiv - A child of the outer that was
│ │ │ │ │ - * supplied to the `round` method.
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: preventDefault
│ │ │ │ │ + * Cancels the event if it is cancelable, without stopping further
│ │ │ │ │ + * propagation of the event.
│ │ │ │ │ *
│ │ │ │ │ - * @param {String} newColor - The new background color to use.
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * event - {Event}
│ │ │ │ │ */
│ │ │ │ │ - changeColor: function(theDiv, newColor) {
│ │ │ │ │ -
│ │ │ │ │ - theDiv.style.backgroundColor = newColor;
│ │ │ │ │ -
│ │ │ │ │ - var spanElements = theDiv.parentNode.getElementsByTagName("span");
│ │ │ │ │ -
│ │ │ │ │ - for (var currIdx = 0; currIdx < spanElements.length; currIdx++) {
│ │ │ │ │ - spanElements[currIdx].style.backgroundColor = newColor;
│ │ │ │ │ + preventDefault: function(event) {
│ │ │ │ │ + if (event.preventDefault) {
│ │ │ │ │ + event.preventDefault();
│ │ │ │ │ + } else {
│ │ │ │ │ + event.returnValue = false;
│ │ │ │ │ }
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ -
│ │ │ │ │ - /** This is a helper function to change the background
│ │ │ │ │ - * opacity of
that has had Rico rounded corners added.
│ │ │ │ │ - *
│ │ │ │ │ - * See changeColor (above) for algorithm explanation
│ │ │ │ │ - *
│ │ │ │ │ - * @param {DOM} theDiv A child of the outer
that was
│ │ │ │ │ - * supplied to the `round` method.
│ │ │ │ │ - *
│ │ │ │ │ - * @param {int} newOpacity The new opacity to use (0-1).
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: findElement
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * event - {Event}
│ │ │ │ │ + * tagName - {String}
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {DOMElement} The first node with the given tagName, starting from the
│ │ │ │ │ + * node the event was triggered on and traversing the DOM upwards
│ │ │ │ │ */
│ │ │ │ │ - changeOpacity: function(theDiv, newOpacity) {
│ │ │ │ │ -
│ │ │ │ │ - var mozillaOpacity = newOpacity;
│ │ │ │ │ - var ieOpacity = 'alpha(opacity=' + newOpacity * 100 + ')';
│ │ │ │ │ -
│ │ │ │ │ - theDiv.style.opacity = mozillaOpacity;
│ │ │ │ │ - theDiv.style.filter = ieOpacity;
│ │ │ │ │ -
│ │ │ │ │ - var spanElements = theDiv.parentNode.getElementsByTagName("span");
│ │ │ │ │ -
│ │ │ │ │ - for (var currIdx = 0; currIdx < spanElements.length; currIdx++) {
│ │ │ │ │ - spanElements[currIdx].style.opacity = mozillaOpacity;
│ │ │ │ │ - spanElements[currIdx].style.filter = ieOpacity;
│ │ │ │ │ + findElement: function(event, tagName) {
│ │ │ │ │ + var element = OpenLayers.Event.element(event);
│ │ │ │ │ + while (element.parentNode && (!element.tagName ||
│ │ │ │ │ + (element.tagName.toUpperCase() != tagName.toUpperCase()))) {
│ │ │ │ │ + element = element.parentNode;
│ │ │ │ │ }
│ │ │ │ │ -
│ │ │ │ │ + return element;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - /** this function takes care of redoing the rico cornering
│ │ │ │ │ - *
│ │ │ │ │ - * you can't just call updateRicoCorners() again and pass it a
│ │ │ │ │ - * new options string. you have to first remove the divs that
│ │ │ │ │ - * rico puts on top and below the content div.
│ │ │ │ │ - *
│ │ │ │ │ - * @param {DOM} theDiv - A child of the outer
that was
│ │ │ │ │ - * supplied to the `round` method.
│ │ │ │ │ - *
│ │ │ │ │ - * @param {Object} options - list of options
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: observe
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * elementParam - {DOMElement || String}
│ │ │ │ │ + * name - {String}
│ │ │ │ │ + * observer - {function}
│ │ │ │ │ + * useCapture - {Boolean}
│ │ │ │ │ */
│ │ │ │ │ - reRound: function(theDiv, options) {
│ │ │ │ │ -
│ │ │ │ │ - var topRico = theDiv.parentNode.childNodes[0];
│ │ │ │ │ - //theDiv would be theDiv.parentNode.childNodes[1]
│ │ │ │ │ - var bottomRico = theDiv.parentNode.childNodes[2];
│ │ │ │ │ -
│ │ │ │ │ - theDiv.parentNode.removeChild(topRico);
│ │ │ │ │ - theDiv.parentNode.removeChild(bottomRico);
│ │ │ │ │ -
│ │ │ │ │ - this.round(theDiv.parentNode, options);
│ │ │ │ │ - },
│ │ │ │ │ + observe: function(elementParam, name, observer, useCapture) {
│ │ │ │ │ + var element = OpenLayers.Util.getElement(elementParam);
│ │ │ │ │ + useCapture = useCapture || false;
│ │ │ │ │
│ │ │ │ │ - _roundCornersImpl: function(e, color, bgColor) {
│ │ │ │ │ - if (this.options.border) {
│ │ │ │ │ - this._renderBorder(e, bgColor);
│ │ │ │ │ - }
│ │ │ │ │ - if (this._isTopRounded()) {
│ │ │ │ │ - this._roundTopCorners(e, color, bgColor);
│ │ │ │ │ - }
│ │ │ │ │ - if (this._isBottomRounded()) {
│ │ │ │ │ - this._roundBottomCorners(e, color, bgColor);
│ │ │ │ │ + if (name == 'keypress' &&
│ │ │ │ │ + (navigator.appVersion.match(/Konqueror|Safari|KHTML/) ||
│ │ │ │ │ + element.attachEvent)) {
│ │ │ │ │ + name = 'keydown';
│ │ │ │ │ }
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ - _renderBorder: function(el, bgColor) {
│ │ │ │ │ - var borderValue = "1px solid " + this._borderColor(bgColor);
│ │ │ │ │ - var borderL = "border-left: " + borderValue;
│ │ │ │ │ - var borderR = "border-right: " + borderValue;
│ │ │ │ │ - var style = "style='" + borderL + ";" + borderR + "'";
│ │ │ │ │ - el.innerHTML = "
" + el.innerHTML + "
";
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - _roundTopCorners: function(el, color, bgColor) {
│ │ │ │ │ - var corner = this._createCorner(bgColor);
│ │ │ │ │ - for (var i = 0; i < this.options.numSlices; i++) {
│ │ │ │ │ - corner.appendChild(this._createCornerSlice(color, bgColor, i, "top"));
│ │ │ │ │ + //if observers cache has not yet been created, create it
│ │ │ │ │ + if (!this.observers) {
│ │ │ │ │ + this.observers = {};
│ │ │ │ │ }
│ │ │ │ │ - el.style.paddingTop = 0;
│ │ │ │ │ - el.insertBefore(corner, el.firstChild);
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ - _roundBottomCorners: function(el, color, bgColor) {
│ │ │ │ │ - var corner = this._createCorner(bgColor);
│ │ │ │ │ - for (var i = (this.options.numSlices - 1); i >= 0; i--) {
│ │ │ │ │ - corner.appendChild(this._createCornerSlice(color, bgColor, i, "bottom"));
│ │ │ │ │ + //if not already assigned, make a new unique cache ID
│ │ │ │ │ + if (!element._eventCacheID) {
│ │ │ │ │ + var idPrefix = "eventCacheID_";
│ │ │ │ │ + if (element.id) {
│ │ │ │ │ + idPrefix = element.id + "_" + idPrefix;
│ │ │ │ │ + }
│ │ │ │ │ + element._eventCacheID = OpenLayers.Util.createUniqueID(idPrefix);
│ │ │ │ │ }
│ │ │ │ │ - el.style.paddingBottom = 0;
│ │ │ │ │ - el.appendChild(corner);
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ - _createCorner: function(bgColor) {
│ │ │ │ │ - var corner = document.createElement("div");
│ │ │ │ │ - corner.style.backgroundColor = (this._isTransparent() ? "transparent" : bgColor);
│ │ │ │ │ - return corner;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - _createCornerSlice: function(color, bgColor, n, position) {
│ │ │ │ │ - var slice = document.createElement("span");
│ │ │ │ │ -
│ │ │ │ │ - var inStyle = slice.style;
│ │ │ │ │ - inStyle.backgroundColor = color;
│ │ │ │ │ - inStyle.display = "block";
│ │ │ │ │ - inStyle.height = "1px";
│ │ │ │ │ - inStyle.overflow = "hidden";
│ │ │ │ │ - inStyle.fontSize = "1px";
│ │ │ │ │ + var cacheID = element._eventCacheID;
│ │ │ │ │
│ │ │ │ │ - var borderColor = this._borderColor(color, bgColor);
│ │ │ │ │ - if (this.options.border && n == 0) {
│ │ │ │ │ - inStyle.borderTopStyle = "solid";
│ │ │ │ │ - inStyle.borderTopWidth = "1px";
│ │ │ │ │ - inStyle.borderLeftWidth = "0px";
│ │ │ │ │ - inStyle.borderRightWidth = "0px";
│ │ │ │ │ - inStyle.borderBottomWidth = "0px";
│ │ │ │ │ - inStyle.height = "0px"; // assumes css compliant box model
│ │ │ │ │ - inStyle.borderColor = borderColor;
│ │ │ │ │ - } else if (borderColor) {
│ │ │ │ │ - inStyle.borderColor = borderColor;
│ │ │ │ │ - inStyle.borderStyle = "solid";
│ │ │ │ │ - inStyle.borderWidth = "0px 1px";
│ │ │ │ │ + //if there is not yet a hash entry for this element, add one
│ │ │ │ │ + if (!this.observers[cacheID]) {
│ │ │ │ │ + this.observers[cacheID] = [];
│ │ │ │ │ }
│ │ │ │ │
│ │ │ │ │ - if (!this.options.compact && (n == (this.options.numSlices - 1))) {
│ │ │ │ │ - inStyle.height = "2px";
│ │ │ │ │ + //add a new observer to this element's list
│ │ │ │ │ + this.observers[cacheID].push({
│ │ │ │ │ + 'element': element,
│ │ │ │ │ + 'name': name,
│ │ │ │ │ + 'observer': observer,
│ │ │ │ │ + 'useCapture': useCapture
│ │ │ │ │ + });
│ │ │ │ │ +
│ │ │ │ │ + //add the actual browser event listener
│ │ │ │ │ + if (element.addEventListener) {
│ │ │ │ │ + element.addEventListener(name, observer, useCapture);
│ │ │ │ │ + } else if (element.attachEvent) {
│ │ │ │ │ + element.attachEvent('on' + name, observer);
│ │ │ │ │ }
│ │ │ │ │ - this._setMargin(slice, n, position);
│ │ │ │ │ - this._setBorder(slice, n, position);
│ │ │ │ │ - return slice;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - _setOptions: function(options) {
│ │ │ │ │ - this.options = {
│ │ │ │ │ - corners: "all",
│ │ │ │ │ - color: "fromElement",
│ │ │ │ │ - bgColor: "fromParent",
│ │ │ │ │ - blend: true,
│ │ │ │ │ - border: false,
│ │ │ │ │ - compact: false
│ │ │ │ │ - };
│ │ │ │ │ - OpenLayers.Util.extend(this.options, options || {});
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: stopObservingElement
│ │ │ │ │ + * Given the id of an element to stop observing, cycle through the
│ │ │ │ │ + * element's cached observers, calling stopObserving on each one,
│ │ │ │ │ + * skipping those entries which can no longer be removed.
│ │ │ │ │ + *
│ │ │ │ │ + * parameters:
│ │ │ │ │ + * elementParam - {DOMElement || String}
│ │ │ │ │ + */
│ │ │ │ │ + stopObservingElement: function(elementParam) {
│ │ │ │ │ + var element = OpenLayers.Util.getElement(elementParam);
│ │ │ │ │ + var cacheID = element._eventCacheID;
│ │ │ │ │
│ │ │ │ │ - this.options.numSlices = this.options.compact ? 2 : 4;
│ │ │ │ │ - if (this._isTransparent()) {
│ │ │ │ │ - this.options.blend = false;
│ │ │ │ │ - }
│ │ │ │ │ + this._removeElementObservers(OpenLayers.Event.observers[cacheID]);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - _whichSideTop: function() {
│ │ │ │ │ - if (this._hasString(this.options.corners, "all", "top")) {
│ │ │ │ │ - return "";
│ │ │ │ │ - }
│ │ │ │ │ - if (this.options.corners.indexOf("tl") >= 0 && this.options.corners.indexOf("tr") >= 0) {
│ │ │ │ │ - return "";
│ │ │ │ │ - }
│ │ │ │ │ - if (this.options.corners.indexOf("tl") >= 0) {
│ │ │ │ │ - return "left";
│ │ │ │ │ - } else if (this.options.corners.indexOf("tr") >= 0) {
│ │ │ │ │ - return "right";
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: _removeElementObservers
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * elementObservers - {Array(Object)} Array of (element, name,
│ │ │ │ │ + * observer, usecapture) objects,
│ │ │ │ │ + * taken directly from hashtable
│ │ │ │ │ + */
│ │ │ │ │ + _removeElementObservers: function(elementObservers) {
│ │ │ │ │ + if (elementObservers) {
│ │ │ │ │ + for (var i = elementObservers.length - 1; i >= 0; i--) {
│ │ │ │ │ + var entry = elementObservers[i];
│ │ │ │ │ + OpenLayers.Event.stopObserving.apply(this, [
│ │ │ │ │ + entry.element, entry.name, entry.observer, entry.useCapture
│ │ │ │ │ + ]);
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ - return "";
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - _whichSideBottom: function() {
│ │ │ │ │ - if (this._hasString(this.options.corners, "all", "bottom")) {
│ │ │ │ │ - return "";
│ │ │ │ │ - }
│ │ │ │ │ - if (this.options.corners.indexOf("bl") >= 0 && this.options.corners.indexOf("br") >= 0) {
│ │ │ │ │ - return "";
│ │ │ │ │ - }
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: stopObserving
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * elementParam - {DOMElement || String}
│ │ │ │ │ + * name - {String}
│ │ │ │ │ + * observer - {function}
│ │ │ │ │ + * useCapture - {Boolean}
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean} Whether or not the event observer was removed
│ │ │ │ │ + */
│ │ │ │ │ + stopObserving: function(elementParam, name, observer, useCapture) {
│ │ │ │ │ + useCapture = useCapture || false;
│ │ │ │ │
│ │ │ │ │ - if (this.options.corners.indexOf("bl") >= 0) {
│ │ │ │ │ - return "left";
│ │ │ │ │ - } else if (this.options.corners.indexOf("br") >= 0) {
│ │ │ │ │ - return "right";
│ │ │ │ │ - }
│ │ │ │ │ - return "";
│ │ │ │ │ - },
│ │ │ │ │ + var element = OpenLayers.Util.getElement(elementParam);
│ │ │ │ │ + var cacheID = element._eventCacheID;
│ │ │ │ │
│ │ │ │ │ - _borderColor: function(color, bgColor) {
│ │ │ │ │ - if (color == "transparent") {
│ │ │ │ │ - return bgColor;
│ │ │ │ │ - } else if (this.options.border) {
│ │ │ │ │ - return this.options.border;
│ │ │ │ │ - } else if (this.options.blend) {
│ │ │ │ │ - return this._blend(bgColor, color);
│ │ │ │ │ - } else {
│ │ │ │ │ - return "";
│ │ │ │ │ + if (name == 'keypress') {
│ │ │ │ │ + if (navigator.appVersion.match(/Konqueror|Safari|KHTML/) ||
│ │ │ │ │ + element.detachEvent) {
│ │ │ │ │ + name = 'keydown';
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ + // find element's entry in this.observers cache and remove it
│ │ │ │ │ + var foundEntry = false;
│ │ │ │ │ + var elementObservers = OpenLayers.Event.observers[cacheID];
│ │ │ │ │ + if (elementObservers) {
│ │ │ │ │
│ │ │ │ │ - _setMargin: function(el, n, corners) {
│ │ │ │ │ - var marginSize = this._marginSize(n);
│ │ │ │ │ - var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();
│ │ │ │ │ -
│ │ │ │ │ - if (whichSide == "left") {
│ │ │ │ │ - el.style.marginLeft = marginSize + "px";
│ │ │ │ │ - el.style.marginRight = "0px";
│ │ │ │ │ - } else if (whichSide == "right") {
│ │ │ │ │ - el.style.marginRight = marginSize + "px";
│ │ │ │ │ - el.style.marginLeft = "0px";
│ │ │ │ │ - } else {
│ │ │ │ │ - el.style.marginLeft = marginSize + "px";
│ │ │ │ │ - el.style.marginRight = marginSize + "px";
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ + // find the specific event type in the element's list
│ │ │ │ │ + var i = 0;
│ │ │ │ │ + while (!foundEntry && i < elementObservers.length) {
│ │ │ │ │ + var cacheEntry = elementObservers[i];
│ │ │ │ │
│ │ │ │ │ - _setBorder: function(el, n, corners) {
│ │ │ │ │ - var borderSize = this._borderSize(n);
│ │ │ │ │ - var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();
│ │ │ │ │ - if (whichSide == "left") {
│ │ │ │ │ - el.style.borderLeftWidth = borderSize + "px";
│ │ │ │ │ - el.style.borderRightWidth = "0px";
│ │ │ │ │ - } else if (whichSide == "right") {
│ │ │ │ │ - el.style.borderRightWidth = borderSize + "px";
│ │ │ │ │ - el.style.borderLeftWidth = "0px";
│ │ │ │ │ - } else {
│ │ │ │ │ - el.style.borderLeftWidth = borderSize + "px";
│ │ │ │ │ - el.style.borderRightWidth = borderSize + "px";
│ │ │ │ │ - }
│ │ │ │ │ - if (this.options.border != false) {
│ │ │ │ │ - el.style.borderLeftWidth = borderSize + "px";
│ │ │ │ │ - el.style.borderRightWidth = borderSize + "px";
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ + if ((cacheEntry.name == name) &&
│ │ │ │ │ + (cacheEntry.observer == observer) &&
│ │ │ │ │ + (cacheEntry.useCapture == useCapture)) {
│ │ │ │ │
│ │ │ │ │ - _marginSize: function(n) {
│ │ │ │ │ - if (this._isTransparent()) {
│ │ │ │ │ - return 0;
│ │ │ │ │ + elementObservers.splice(i, 1);
│ │ │ │ │ + if (elementObservers.length == 0) {
│ │ │ │ │ + delete OpenLayers.Event.observers[cacheID];
│ │ │ │ │ + }
│ │ │ │ │ + foundEntry = true;
│ │ │ │ │ + break;
│ │ │ │ │ + }
│ │ │ │ │ + i++;
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ - var marginSizes = [5, 3, 2, 1];
│ │ │ │ │ - var blendedMarginSizes = [3, 2, 1, 0];
│ │ │ │ │ - var compactMarginSizes = [2, 1];
│ │ │ │ │ - var smBlendedMarginSizes = [1, 0];
│ │ │ │ │
│ │ │ │ │ - if (this.options.compact && this.options.blend) {
│ │ │ │ │ - return smBlendedMarginSizes[n];
│ │ │ │ │ - } else if (this.options.compact) {
│ │ │ │ │ - return compactMarginSizes[n];
│ │ │ │ │ - } else if (this.options.blend) {
│ │ │ │ │ - return blendedMarginSizes[n];
│ │ │ │ │ - } else {
│ │ │ │ │ - return marginSizes[n];
│ │ │ │ │ + //actually remove the event listener from browser
│ │ │ │ │ + if (foundEntry) {
│ │ │ │ │ + if (element.removeEventListener) {
│ │ │ │ │ + element.removeEventListener(name, observer, useCapture);
│ │ │ │ │ + } else if (element && element.detachEvent) {
│ │ │ │ │ + element.detachEvent('on' + name, observer);
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ + return foundEntry;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - _borderSize: function(n) {
│ │ │ │ │ - var transparentBorderSizes = [5, 3, 2, 1];
│ │ │ │ │ - var blendedBorderSizes = [2, 1, 1, 1];
│ │ │ │ │ - var compactBorderSizes = [1, 0];
│ │ │ │ │ - var actualBorderSizes = [0, 2, 0, 0];
│ │ │ │ │ -
│ │ │ │ │ - if (this.options.compact && (this.options.blend || this._isTransparent())) {
│ │ │ │ │ - return 1;
│ │ │ │ │ - } else if (this.options.compact) {
│ │ │ │ │ - return compactBorderSizes[n];
│ │ │ │ │ - } else if (this.options.blend) {
│ │ │ │ │ - return blendedBorderSizes[n];
│ │ │ │ │ - } else if (this.options.border) {
│ │ │ │ │ - return actualBorderSizes[n];
│ │ │ │ │ - } else if (this._isTransparent()) {
│ │ │ │ │ - return transparentBorderSizes[n];
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: unloadCache
│ │ │ │ │ + * Cycle through all the element entries in the events cache and call
│ │ │ │ │ + * stopObservingElement on each.
│ │ │ │ │ + */
│ │ │ │ │ + unloadCache: function() {
│ │ │ │ │ + // check for OpenLayers.Event before checking for observers, because
│ │ │ │ │ + // OpenLayers.Event may be undefined in IE if no map instance was
│ │ │ │ │ + // created
│ │ │ │ │ + if (OpenLayers.Event && OpenLayers.Event.observers) {
│ │ │ │ │ + for (var cacheID in OpenLayers.Event.observers) {
│ │ │ │ │ + var elementObservers = OpenLayers.Event.observers[cacheID];
│ │ │ │ │ + OpenLayers.Event._removeElementObservers.apply(this,
│ │ │ │ │ + [elementObservers]);
│ │ │ │ │ + }
│ │ │ │ │ + OpenLayers.Event.observers = false;
│ │ │ │ │ }
│ │ │ │ │ - return 0;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - _hasString: function(str) {
│ │ │ │ │ - for (var i = 1; i < arguments.length; i++)
│ │ │ │ │ - if (str.indexOf(arguments[i]) >= 0) {
│ │ │ │ │ - return true;
│ │ │ │ │ - } return false;
│ │ │ │ │ - },
│ │ │ │ │ - _blend: function(c1, c2) {
│ │ │ │ │ - var cc1 = OpenLayers.Rico.Color.createFromHex(c1);
│ │ │ │ │ - cc1.blend(OpenLayers.Rico.Color.createFromHex(c2));
│ │ │ │ │ - return cc1;
│ │ │ │ │ - },
│ │ │ │ │ - _background: function(el) {
│ │ │ │ │ - try {
│ │ │ │ │ - return OpenLayers.Rico.Color.createColorFromBackground(el).asHex();
│ │ │ │ │ - } catch (err) {
│ │ │ │ │ - return "#ffffff";
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ - _isTransparent: function() {
│ │ │ │ │ - return this.options.color == "transparent";
│ │ │ │ │ - },
│ │ │ │ │ - _isTopRounded: function() {
│ │ │ │ │ - return this._hasString(this.options.corners, "all", "top", "tl", "tr");
│ │ │ │ │ - },
│ │ │ │ │ - _isBottomRounded: function() {
│ │ │ │ │ - return this._hasString(this.options.corners, "all", "bottom", "bl", "br");
│ │ │ │ │ - },
│ │ │ │ │ - _hasSingleTextChild: function(el) {
│ │ │ │ │ - return el.childNodes.length == 1 && el.childNodes[0].nodeType == 3;
│ │ │ │ │ - }
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Event"
│ │ │ │ │ };
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Symbolizer.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ - */
│ │ │ │ │ +/* prevent memory leaks in IE */
│ │ │ │ │ +OpenLayers.Event.observe(window, 'unload', OpenLayers.Event.unloadCache, false);
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Class: OpenLayers.Symbolizer
│ │ │ │ │ - * Base class representing a symbolizer used for feature rendering.
│ │ │ │ │ + * Class: OpenLayers.Events
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Symbolizer = OpenLayers.Class({
│ │ │ │ │ -
│ │ │ │ │ +OpenLayers.Events = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: zIndex
│ │ │ │ │ - * {Number} The zIndex determines the rendering order for a symbolizer.
│ │ │ │ │ - * Symbolizers with larger zIndex values are rendered over symbolizers
│ │ │ │ │ - * with smaller zIndex values. Default is 0.
│ │ │ │ │ + /**
│ │ │ │ │ + * Constant: BROWSER_EVENTS
│ │ │ │ │ + * {Array(String)} supported events
│ │ │ │ │ */
│ │ │ │ │ - zIndex: 0,
│ │ │ │ │ + BROWSER_EVENTS: [
│ │ │ │ │ + "mouseover", "mouseout",
│ │ │ │ │ + "mousedown", "mouseup", "mousemove",
│ │ │ │ │ + "click", "dblclick", "rightclick", "dblrightclick",
│ │ │ │ │ + "resize", "focus", "blur",
│ │ │ │ │ + "touchstart", "touchmove", "touchend",
│ │ │ │ │ + "keydown"
│ │ │ │ │ + ],
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Symbolizer
│ │ │ │ │ - * Instances of this class are not useful. See one of the subclasses.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * config - {Object} An object containing properties to be set on the
│ │ │ │ │ - * symbolizer. Any documented symbolizer property can be set at
│ │ │ │ │ - * construction.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * A new symbolizer.
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: listeners
│ │ │ │ │ + * {Object} Hashtable of Array(Function): events listener functions
│ │ │ │ │ */
│ │ │ │ │ - initialize: function(config) {
│ │ │ │ │ - OpenLayers.Util.extend(this, config);
│ │ │ │ │ - },
│ │ │ │ │ + listeners: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: clone
│ │ │ │ │ - * Create a copy of this symbolizer.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns a symbolizer of the same type with the same properties.
│ │ │ │ │ + * Property: object
│ │ │ │ │ + * {Object} the code object issuing application events
│ │ │ │ │ */
│ │ │ │ │ - clone: function() {
│ │ │ │ │ - var Type = eval(this.CLASS_NAME);
│ │ │ │ │ - return new Type(OpenLayers.Util.extend({}, this));
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Symbolizer"
│ │ │ │ │ -
│ │ │ │ │ -});
│ │ │ │ │ -
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Feature.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ - * @requires OpenLayers/Util.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Feature
│ │ │ │ │ - * Features are combinations of geography and attributes. The OpenLayers.Feature
│ │ │ │ │ - * class specifically combines a marker and a lonlat.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Feature = OpenLayers.Class({
│ │ │ │ │ + object: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: layer
│ │ │ │ │ - * {
}
│ │ │ │ │ + * Property: element
│ │ │ │ │ + * {DOMElement} the DOM element receiving browser events
│ │ │ │ │ */
│ │ │ │ │ - layer: null,
│ │ │ │ │ + element: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: id
│ │ │ │ │ - * {String}
│ │ │ │ │ + * Property: eventHandler
│ │ │ │ │ + * {Function} bound event handler attached to elements
│ │ │ │ │ */
│ │ │ │ │ - id: null,
│ │ │ │ │ + eventHandler: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: lonlat
│ │ │ │ │ - * {}
│ │ │ │ │ + * APIProperty: fallThrough
│ │ │ │ │ + * {Boolean}
│ │ │ │ │ */
│ │ │ │ │ - lonlat: null,
│ │ │ │ │ + fallThrough: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: data
│ │ │ │ │ - * {Object}
│ │ │ │ │ + * APIProperty: includeXY
│ │ │ │ │ + * {Boolean} Should the .xy property automatically be created for browser
│ │ │ │ │ + * mouse events? In general, this should be false. If it is true, then
│ │ │ │ │ + * mouse events will automatically generate a '.xy' property on the
│ │ │ │ │ + * event object that is passed. (Prior to OpenLayers 2.7, this was true
│ │ │ │ │ + * by default.) Otherwise, you can call the getMousePosition on the
│ │ │ │ │ + * relevant events handler on the object available via the 'evt.object'
│ │ │ │ │ + * property of the evt object. So, for most events, you can call:
│ │ │ │ │ + * function named(evt) {
│ │ │ │ │ + * this.xy = this.object.events.getMousePosition(evt)
│ │ │ │ │ + * }
│ │ │ │ │ + *
│ │ │ │ │ + * This option typically defaults to false for performance reasons:
│ │ │ │ │ + * when creating an events object whose primary purpose is to manage
│ │ │ │ │ + * relatively positioned mouse events within a div, it may make
│ │ │ │ │ + * sense to set it to true.
│ │ │ │ │ + *
│ │ │ │ │ + * This option is also used to control whether the events object caches
│ │ │ │ │ + * offsets. If this is false, it will not: the reason for this is that
│ │ │ │ │ + * it is only expected to be called many times if the includeXY property
│ │ │ │ │ + * is set to true. If you set this to true, you are expected to clear
│ │ │ │ │ + * the offset cache manually (using this.clearMouseCache()) if:
│ │ │ │ │ + * the border of the element changes
│ │ │ │ │ + * the location of the element in the page changes
│ │ │ │ │ */
│ │ │ │ │ - data: null,
│ │ │ │ │ + includeXY: false,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: marker
│ │ │ │ │ - * {}
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: extensions
│ │ │ │ │ + * {Object} Event extensions registered with this instance. Keys are
│ │ │ │ │ + * event types, values are {OpenLayers.Events.*} extension instances or
│ │ │ │ │ + * {Boolean} for events that an instantiated extension provides in
│ │ │ │ │ + * addition to the one it was created for.
│ │ │ │ │ + *
│ │ │ │ │ + * Extensions create an event in addition to browser events, which usually
│ │ │ │ │ + * fires when a sequence of browser events is completed. Extensions are
│ │ │ │ │ + * automatically instantiated when a listener is registered for an event
│ │ │ │ │ + * provided by an extension.
│ │ │ │ │ + *
│ │ │ │ │ + * Extensions are created in the namespace using
│ │ │ │ │ + * , and named after the event they provide.
│ │ │ │ │ + * The constructor receives the target instance as
│ │ │ │ │ + * argument. Extensions that need to capture browser events before they
│ │ │ │ │ + * propagate can register their listeners events using , with
│ │ │ │ │ + * {extension: true} as 4th argument.
│ │ │ │ │ + *
│ │ │ │ │ + * If an extension creates more than one event, an alias for each event
│ │ │ │ │ + * type should be created and reference the same class. The constructor
│ │ │ │ │ + * should set a reference in the target's extensions registry to itself.
│ │ │ │ │ + *
│ │ │ │ │ + * Below is a minimal extension that provides the "foostart" and "fooend"
│ │ │ │ │ + * event types, which replace the native "click" event type if clicked on
│ │ │ │ │ + * an element with the css class "foo":
│ │ │ │ │ + *
│ │ │ │ │ + * (code)
│ │ │ │ │ + * OpenLayers.Events.foostart = OpenLayers.Class({
│ │ │ │ │ + * initialize: function(target) {
│ │ │ │ │ + * this.target = target;
│ │ │ │ │ + * this.target.register("click", this, this.doStuff, {extension: true});
│ │ │ │ │ + * // only required if extension provides more than one event type
│ │ │ │ │ + * this.target.extensions["foostart"] = true;
│ │ │ │ │ + * this.target.extensions["fooend"] = true;
│ │ │ │ │ + * },
│ │ │ │ │ + * destroy: function() {
│ │ │ │ │ + * var target = this.target;
│ │ │ │ │ + * target.unregister("click", this, this.doStuff);
│ │ │ │ │ + * delete this.target;
│ │ │ │ │ + * // only required if extension provides more than one event type
│ │ │ │ │ + * delete target.extensions["foostart"];
│ │ │ │ │ + * delete target.extensions["fooend"];
│ │ │ │ │ + * },
│ │ │ │ │ + * doStuff: function(evt) {
│ │ │ │ │ + * var propagate = true;
│ │ │ │ │ + * if (OpenLayers.Event.element(evt).className === "foo") {
│ │ │ │ │ + * propagate = false;
│ │ │ │ │ + * var target = this.target;
│ │ │ │ │ + * target.triggerEvent("foostart");
│ │ │ │ │ + * window.setTimeout(function() {
│ │ │ │ │ + * target.triggerEvent("fooend");
│ │ │ │ │ + * }, 1000);
│ │ │ │ │ + * }
│ │ │ │ │ + * return propagate;
│ │ │ │ │ + * }
│ │ │ │ │ + * });
│ │ │ │ │ + * // only required if extension provides more than one event type
│ │ │ │ │ + * OpenLayers.Events.fooend = OpenLayers.Events.foostart;
│ │ │ │ │ + * (end)
│ │ │ │ │ + *
│ │ │ │ │ */
│ │ │ │ │ - marker: null,
│ │ │ │ │ + extensions: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: popupClass
│ │ │ │ │ - * {} The class which will be used to instantiate
│ │ │ │ │ - * a new Popup. Default is .
│ │ │ │ │ + * Property: extensionCount
│ │ │ │ │ + * {Object} Keys are event types (like in ), values are the
│ │ │ │ │ + * number of extension listeners for each event type.
│ │ │ │ │ */
│ │ │ │ │ - popupClass: null,
│ │ │ │ │ + extensionCount: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: popup
│ │ │ │ │ - * {}
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: clearMouseListener
│ │ │ │ │ + * A version of that is bound to this instance so that
│ │ │ │ │ + * it can be used with and
│ │ │ │ │ + * .
│ │ │ │ │ */
│ │ │ │ │ - popup: null,
│ │ │ │ │ + clearMouseListener: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Feature
│ │ │ │ │ - * Constructor for features.
│ │ │ │ │ + /**
│ │ │ │ │ + * Constructor: OpenLayers.Events
│ │ │ │ │ + * Construct an OpenLayers.Events object.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * layer - {}
│ │ │ │ │ - * lonlat - {}
│ │ │ │ │ - * data - {Object}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {}
│ │ │ │ │ + * object - {Object} The js object to which this Events object is being added
│ │ │ │ │ + * element - {DOMElement} A dom element to respond to browser events
│ │ │ │ │ + * eventTypes - {Array(String)} Deprecated. Array of custom application
│ │ │ │ │ + * events. A listener may be registered for any named event, regardless
│ │ │ │ │ + * of the values provided here.
│ │ │ │ │ + * fallThrough - {Boolean} Allow events to fall through after these have
│ │ │ │ │ + * been handled?
│ │ │ │ │ + * options - {Object} Options for the events object.
│ │ │ │ │ */
│ │ │ │ │ - initialize: function(layer, lonlat, data) {
│ │ │ │ │ - this.layer = layer;
│ │ │ │ │ - this.lonlat = lonlat;
│ │ │ │ │ - this.data = (data != null) ? data : {};
│ │ │ │ │ - this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
│ │ │ │ │ + initialize: function(object, element, eventTypes, fallThrough, options) {
│ │ │ │ │ + OpenLayers.Util.extend(this, options);
│ │ │ │ │ + this.object = object;
│ │ │ │ │ + this.fallThrough = fallThrough;
│ │ │ │ │ + this.listeners = {};
│ │ │ │ │ + this.extensions = {};
│ │ │ │ │ + this.extensionCount = {};
│ │ │ │ │ + this._msTouches = [];
│ │ │ │ │ +
│ │ │ │ │ + // if a dom element is specified, add a listeners list
│ │ │ │ │ + // for browser events on the element and register them
│ │ │ │ │ + if (element != null) {
│ │ │ │ │ + this.attachToElement(element);
│ │ │ │ │ + }
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: destroy
│ │ │ │ │ - * nullify references to prevent circular references and memory leaks
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: destroy
│ │ │ │ │ */
│ │ │ │ │ destroy: function() {
│ │ │ │ │ -
│ │ │ │ │ - //remove the popup from the map
│ │ │ │ │ - if ((this.layer != null) && (this.layer.map != null)) {
│ │ │ │ │ - if (this.popup != null) {
│ │ │ │ │ - this.layer.map.removePopup(this.popup);
│ │ │ │ │ + for (var e in this.extensions) {
│ │ │ │ │ + if (typeof this.extensions[e] !== "boolean") {
│ │ │ │ │ + this.extensions[e].destroy();
│ │ │ │ │ }
│ │ │ │ │ }
│ │ │ │ │ - // remove the marker from the layer
│ │ │ │ │ - if (this.layer != null && this.marker != null) {
│ │ │ │ │ - this.layer.removeMarker(this.marker);
│ │ │ │ │ + this.extensions = null;
│ │ │ │ │ + if (this.element) {
│ │ │ │ │ + OpenLayers.Event.stopObservingElement(this.element);
│ │ │ │ │ + if (this.element.hasScrollEvent) {
│ │ │ │ │ + OpenLayers.Event.stopObserving(
│ │ │ │ │ + window, "scroll", this.clearMouseListener
│ │ │ │ │ + );
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ + this.element = null;
│ │ │ │ │
│ │ │ │ │ - this.layer = null;
│ │ │ │ │ - this.id = null;
│ │ │ │ │ - this.lonlat = null;
│ │ │ │ │ - this.data = null;
│ │ │ │ │ - if (this.marker != null) {
│ │ │ │ │ - this.destroyMarker(this.marker);
│ │ │ │ │ - this.marker = null;
│ │ │ │ │ - }
│ │ │ │ │ - if (this.popup != null) {
│ │ │ │ │ - this.destroyPopup(this.popup);
│ │ │ │ │ - this.popup = null;
│ │ │ │ │ - }
│ │ │ │ │ + this.listeners = null;
│ │ │ │ │ + this.object = null;
│ │ │ │ │ + this.fallThrough = null;
│ │ │ │ │ + this.eventHandler = null;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: onScreen
│ │ │ │ │ + * APIMethod: addEventType
│ │ │ │ │ + * Deprecated. Any event can be triggered without adding it first.
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} Whether or not the feature is currently visible on screen
│ │ │ │ │ - * (based on its 'lonlat' property)
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * eventName - {String}
│ │ │ │ │ */
│ │ │ │ │ - onScreen: function() {
│ │ │ │ │ -
│ │ │ │ │ - var onScreen = false;
│ │ │ │ │ - if ((this.layer != null) && (this.layer.map != null)) {
│ │ │ │ │ - var screenBounds = this.layer.map.getExtent();
│ │ │ │ │ - onScreen = screenBounds.containsLonLat(this.lonlat);
│ │ │ │ │ - }
│ │ │ │ │ - return onScreen;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ + addEventType: function(eventName) {},
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: createMarker
│ │ │ │ │ - * Based on the data associated with the Feature, create and return a marker object.
│ │ │ │ │ + * Method: attachToElement
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} A Marker Object created from the 'lonlat' and 'icon' properties
│ │ │ │ │ - * set in this.data. If no 'lonlat' is set, returns null. If no
│ │ │ │ │ - * 'icon' is set, OpenLayers.Marker() will load the default image.
│ │ │ │ │ - *
│ │ │ │ │ - * Note - this.marker is set to return value
│ │ │ │ │ - *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * element - {HTMLDOMElement} a DOM element to attach browser events to
│ │ │ │ │ */
│ │ │ │ │ - createMarker: function() {
│ │ │ │ │ + attachToElement: function(element) {
│ │ │ │ │ + if (this.element) {
│ │ │ │ │ + OpenLayers.Event.stopObservingElement(this.element);
│ │ │ │ │ + } else {
│ │ │ │ │ + // keep a bound copy of handleBrowserEvent() so that we can
│ │ │ │ │ + // pass the same function to both Event.observe() and .stopObserving()
│ │ │ │ │ + this.eventHandler = OpenLayers.Function.bindAsEventListener(
│ │ │ │ │ + this.handleBrowserEvent, this
│ │ │ │ │ + );
│ │ │ │ │
│ │ │ │ │ - if (this.lonlat != null) {
│ │ │ │ │ - this.marker = new OpenLayers.Marker(this.lonlat, this.data.icon);
│ │ │ │ │ + // to be used with observe and stopObserving
│ │ │ │ │ + this.clearMouseListener = OpenLayers.Function.bind(
│ │ │ │ │ + this.clearMouseCache, this
│ │ │ │ │ + );
│ │ │ │ │ }
│ │ │ │ │ - return this.marker;
│ │ │ │ │ + this.element = element;
│ │ │ │ │ + var msTouch = !!window.navigator.msMaxTouchPoints;
│ │ │ │ │ + var type;
│ │ │ │ │ + for (var i = 0, len = this.BROWSER_EVENTS.length; i < len; i++) {
│ │ │ │ │ + type = this.BROWSER_EVENTS[i];
│ │ │ │ │ + // register the event cross-browser
│ │ │ │ │ + OpenLayers.Event.observe(element, type, this.eventHandler);
│ │ │ │ │ + if (msTouch && type.indexOf('touch') === 0) {
│ │ │ │ │ + this.addMsTouchListener(element, type, this.eventHandler);
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + // disable dragstart in IE so that mousedown/move/up works normally
│ │ │ │ │ + OpenLayers.Event.observe(element, "dragstart", OpenLayers.Event.stop);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: destroyMarker
│ │ │ │ │ - * Destroys marker.
│ │ │ │ │ - * If user overrides the createMarker() function, s/he should be able
│ │ │ │ │ - * to also specify an alternative function for destroying it
│ │ │ │ │ + * APIMethod: on
│ │ │ │ │ + * Convenience method for registering listeners with a common scope.
│ │ │ │ │ + * Internally, this method calls as shown in the examples
│ │ │ │ │ + * below.
│ │ │ │ │ + *
│ │ │ │ │ + * Example use:
│ │ │ │ │ + * (code)
│ │ │ │ │ + * // register a single listener for the "loadstart" event
│ │ │ │ │ + * events.on({"loadstart": loadStartListener});
│ │ │ │ │ + *
│ │ │ │ │ + * // this is equivalent to the following
│ │ │ │ │ + * events.register("loadstart", undefined, loadStartListener);
│ │ │ │ │ + *
│ │ │ │ │ + * // register multiple listeners to be called with the same `this` object
│ │ │ │ │ + * events.on({
│ │ │ │ │ + * "loadstart": loadStartListener,
│ │ │ │ │ + * "loadend": loadEndListener,
│ │ │ │ │ + * scope: object
│ │ │ │ │ + * });
│ │ │ │ │ + *
│ │ │ │ │ + * // this is equivalent to the following
│ │ │ │ │ + * events.register("loadstart", object, loadStartListener);
│ │ │ │ │ + * events.register("loadend", object, loadEndListener);
│ │ │ │ │ + * (end)
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * object - {Object}
│ │ │ │ │ */
│ │ │ │ │ - destroyMarker: function() {
│ │ │ │ │ - this.marker.destroy();
│ │ │ │ │ + on: function(object) {
│ │ │ │ │ + for (var type in object) {
│ │ │ │ │ + if (type != "scope" && object.hasOwnProperty(type)) {
│ │ │ │ │ + this.register(type, object.scope, object[type]);
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: createPopup
│ │ │ │ │ - * Creates a popup object created from the 'lonlat', 'popupSize',
│ │ │ │ │ - * and 'popupContentHTML' properties set in this.data. It uses
│ │ │ │ │ - * this.marker.icon as default anchor.
│ │ │ │ │ + * APIMethod: register
│ │ │ │ │ + * Register an event on the events object.
│ │ │ │ │ + *
│ │ │ │ │ + * When the event is triggered, the 'func' function will be called, in the
│ │ │ │ │ + * context of 'obj'. Imagine we were to register an event, specifying an
│ │ │ │ │ + * OpenLayers.Bounds Object as 'obj'. When the event is triggered, the
│ │ │ │ │ + * context in the callback function will be our Bounds object. This means
│ │ │ │ │ + * that within our callback function, we can access the properties and
│ │ │ │ │ + * methods of the Bounds object through the "this" variable. So our
│ │ │ │ │ + * callback could execute something like:
│ │ │ │ │ + * : leftStr = "Left: " + this.left;
│ │ │ │ │ + *
│ │ │ │ │ + * or
│ │ │ │ │ *
│ │ │ │ │ - * If no 'lonlat' is set, returns null.
│ │ │ │ │ - * If no this.marker has been created, no anchor is sent.
│ │ │ │ │ + * : centerStr = "Center: " + this.getCenterLonLat();
│ │ │ │ │ *
│ │ │ │ │ - * Note - the returned popup object is 'owned' by the feature, so you
│ │ │ │ │ - * cannot use the popup's destroy method to discard the popup.
│ │ │ │ │ - * Instead, you must use the feature's destroyPopup
│ │ │ │ │ - *
│ │ │ │ │ - * Note - this.popup is set to return value
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * closeBox - {Boolean} create popup with closebox or not
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} Returns the created popup, which is also set
│ │ │ │ │ - * as 'popup' property of this feature. Will be of whatever type
│ │ │ │ │ - * specified by this feature's 'popupClass' property, but must be
│ │ │ │ │ - * of type .
│ │ │ │ │ - *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * type - {String} Name of the event to register
│ │ │ │ │ + * obj - {Object} The object to bind the context to for the callback#.
│ │ │ │ │ + * If no object is specified, default is the Events's 'object' property.
│ │ │ │ │ + * func - {Function} The callback function. If no callback is
│ │ │ │ │ + * specified, this function does nothing.
│ │ │ │ │ + * priority - {Boolean|Object} If true, adds the new listener to the
│ │ │ │ │ + * *front* of the events queue instead of to the end.
│ │ │ │ │ + *
│ │ │ │ │ + * Valid options for priority:
│ │ │ │ │ + * extension - {Boolean} If true, then the event will be registered as
│ │ │ │ │ + * extension event. Extension events are handled before all other
│ │ │ │ │ + * events.
│ │ │ │ │ */
│ │ │ │ │ - createPopup: function(closeBox) {
│ │ │ │ │ -
│ │ │ │ │ - if (this.lonlat != null) {
│ │ │ │ │ - if (!this.popup) {
│ │ │ │ │ - var anchor = (this.marker) ? this.marker.icon : null;
│ │ │ │ │ - var popupClass = this.popupClass ?
│ │ │ │ │ - this.popupClass : OpenLayers.Popup.Anchored;
│ │ │ │ │ - this.popup = new popupClass(this.id + "_popup",
│ │ │ │ │ - this.lonlat,
│ │ │ │ │ - this.data.popupSize,
│ │ │ │ │ - this.data.popupContentHTML,
│ │ │ │ │ - anchor,
│ │ │ │ │ - closeBox);
│ │ │ │ │ + register: function(type, obj, func, priority) {
│ │ │ │ │ + if (type in OpenLayers.Events && !this.extensions[type]) {
│ │ │ │ │ + this.extensions[type] = new OpenLayers.Events[type](this);
│ │ │ │ │ + }
│ │ │ │ │ + if (func != null) {
│ │ │ │ │ + if (obj == null) {
│ │ │ │ │ + obj = this.object;
│ │ │ │ │ }
│ │ │ │ │ - if (this.data.overflow != null) {
│ │ │ │ │ - this.popup.contentDiv.style.overflow = this.data.overflow;
│ │ │ │ │ + var listeners = this.listeners[type];
│ │ │ │ │ + if (!listeners) {
│ │ │ │ │ + listeners = [];
│ │ │ │ │ + this.listeners[type] = listeners;
│ │ │ │ │ + this.extensionCount[type] = 0;
│ │ │ │ │ + }
│ │ │ │ │ + var listener = {
│ │ │ │ │ + obj: obj,
│ │ │ │ │ + func: func
│ │ │ │ │ + };
│ │ │ │ │ + if (priority) {
│ │ │ │ │ + listeners.splice(this.extensionCount[type], 0, listener);
│ │ │ │ │ + if (typeof priority === "object" && priority.extension) {
│ │ │ │ │ + this.extensionCount[type]++;
│ │ │ │ │ + }
│ │ │ │ │ + } else {
│ │ │ │ │ + listeners.push(listener);
│ │ │ │ │ }
│ │ │ │ │ -
│ │ │ │ │ - this.popup.feature = this;
│ │ │ │ │ }
│ │ │ │ │ - return this.popup;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ -
│ │ │ │ │ /**
│ │ │ │ │ - * Method: destroyPopup
│ │ │ │ │ - * Destroys the popup created via createPopup.
│ │ │ │ │ + * APIMethod: registerPriority
│ │ │ │ │ + * Same as register() but adds the new listener to the *front* of the
│ │ │ │ │ + * events queue instead of to the end.
│ │ │ │ │ + *
│ │ │ │ │ + * TODO: get rid of this in 3.0 - Decide whether listeners should be
│ │ │ │ │ + * called in the order they were registered or in reverse order.
│ │ │ │ │ *
│ │ │ │ │ - * As with the marker, if user overrides the createPopup() function, s/he
│ │ │ │ │ - * should also be able to override the destruction
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * type - {String} Name of the event to register
│ │ │ │ │ + * obj - {Object} The object to bind the context to for the callback#.
│ │ │ │ │ + * If no object is specified, default is the Events's
│ │ │ │ │ + * 'object' property.
│ │ │ │ │ + * func - {Function} The callback function. If no callback is
│ │ │ │ │ + * specified, this function does nothing.
│ │ │ │ │ */
│ │ │ │ │ - destroyPopup: function() {
│ │ │ │ │ - if (this.popup) {
│ │ │ │ │ - this.popup.feature = null;
│ │ │ │ │ - this.popup.destroy();
│ │ │ │ │ - this.popup = null;
│ │ │ │ │ - }
│ │ │ │ │ + registerPriority: function(type, obj, func) {
│ │ │ │ │ + this.register(type, obj, func, true);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Feature"
│ │ │ │ │ -});
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Feature/Vector.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -// TRASH THIS
│ │ │ │ │ -OpenLayers.State = {
│ │ │ │ │ - /** states */
│ │ │ │ │ - UNKNOWN: 'Unknown',
│ │ │ │ │ - INSERT: 'Insert',
│ │ │ │ │ - UPDATE: 'Update',
│ │ │ │ │ - DELETE: 'Delete'
│ │ │ │ │ -};
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/Feature.js
│ │ │ │ │ - * @requires OpenLayers/Util.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Feature.Vector
│ │ │ │ │ - * Vector features use the OpenLayers.Geometry classes as geometry description.
│ │ │ │ │ - * They have an 'attributes' property, which is the data object, and a 'style'
│ │ │ │ │ - * property, the default values of which are defined in the
│ │ │ │ │ - * objects.
│ │ │ │ │ - *
│ │ │ │ │ - * Inherits from:
│ │ │ │ │ - * -
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Feature.Vector = OpenLayers.Class(OpenLayers.Feature, {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: fid
│ │ │ │ │ - * {String}
│ │ │ │ │ - */
│ │ │ │ │ - fid: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: geometry
│ │ │ │ │ - * {}
│ │ │ │ │ - */
│ │ │ │ │ - geometry: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: attributes
│ │ │ │ │ - * {Object} This object holds arbitrary, serializable properties that
│ │ │ │ │ - * describe the feature.
│ │ │ │ │ - */
│ │ │ │ │ - attributes: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: bounds
│ │ │ │ │ - * {} The box bounding that feature's geometry, that
│ │ │ │ │ - * property can be set by an object when
│ │ │ │ │ - * deserializing the feature, so in most cases it represents an
│ │ │ │ │ - * information set by the server.
│ │ │ │ │ - */
│ │ │ │ │ - bounds: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: state
│ │ │ │ │ - * {String}
│ │ │ │ │ - */
│ │ │ │ │ - state: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: style
│ │ │ │ │ - * {Object}
│ │ │ │ │ - */
│ │ │ │ │ - style: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: url
│ │ │ │ │ - * {String} If this property is set it will be taken into account by
│ │ │ │ │ - * {} when upadting or deleting the feature.
│ │ │ │ │ - */
│ │ │ │ │ - url: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: renderIntent
│ │ │ │ │ - * {String} rendering intent currently being used
│ │ │ │ │ - */
│ │ │ │ │ - renderIntent: "default",
│ │ │ │ │ -
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: modified
│ │ │ │ │ - * {Object} An object with the originals of the geometry and attributes of
│ │ │ │ │ - * the feature, if they were changed. Currently this property is only read
│ │ │ │ │ - * by , and written by
│ │ │ │ │ - * , which sets the geometry property.
│ │ │ │ │ - * Applications can set the originals of modified attributes in the
│ │ │ │ │ - * attributes property. Note that applications have to check if this
│ │ │ │ │ - * object and the attributes property is already created before using it.
│ │ │ │ │ - * After a change made with ModifyFeature, this object could look like
│ │ │ │ │ + * APIMethod: un
│ │ │ │ │ + * Convenience method for unregistering listeners with a common scope.
│ │ │ │ │ + * Internally, this method calls as shown in the examples
│ │ │ │ │ + * below.
│ │ │ │ │ *
│ │ │ │ │ + * Example use:
│ │ │ │ │ * (code)
│ │ │ │ │ - * {
│ │ │ │ │ - * geometry: >Object
│ │ │ │ │ - * }
│ │ │ │ │ - * (end)
│ │ │ │ │ + * // unregister a single listener for the "loadstart" event
│ │ │ │ │ + * events.un({"loadstart": loadStartListener});
│ │ │ │ │ *
│ │ │ │ │ - * When an application has made changes to feature attributes, it could
│ │ │ │ │ - * have set the attributes to something like this:
│ │ │ │ │ + * // this is equivalent to the following
│ │ │ │ │ + * events.unregister("loadstart", undefined, loadStartListener);
│ │ │ │ │ *
│ │ │ │ │ - * (code)
│ │ │ │ │ - * {
│ │ │ │ │ - * attributes: {
│ │ │ │ │ - * myAttribute: "original"
│ │ │ │ │ - * }
│ │ │ │ │ - * }
│ │ │ │ │ - * (end)
│ │ │ │ │ + * // unregister multiple listeners with the same `this` object
│ │ │ │ │ + * events.un({
│ │ │ │ │ + * "loadstart": loadStartListener,
│ │ │ │ │ + * "loadend": loadEndListener,
│ │ │ │ │ + * scope: object
│ │ │ │ │ + * });
│ │ │ │ │ *
│ │ │ │ │ - * Note that only checks for truthy values in
│ │ │ │ │ - * *modified.geometry* and the attribute names in *modified.attributes*,
│ │ │ │ │ - * but it is recommended to set the original values (and not just true) as
│ │ │ │ │ - * attribute value, so applications could use this information to undo
│ │ │ │ │ - * changes.
│ │ │ │ │ + * // this is equivalent to the following
│ │ │ │ │ + * events.unregister("loadstart", object, loadStartListener);
│ │ │ │ │ + * events.unregister("loadend", object, loadEndListener);
│ │ │ │ │ + * (end)
│ │ │ │ │ */
│ │ │ │ │ - modified: null,
│ │ │ │ │ + un: function(object) {
│ │ │ │ │ + for (var type in object) {
│ │ │ │ │ + if (type != "scope" && object.hasOwnProperty(type)) {
│ │ │ │ │ + this.unregister(type, object.scope, object[type]);
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Feature.Vector
│ │ │ │ │ - * Create a vector feature.
│ │ │ │ │ - *
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: unregister
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * geometry - {} The geometry that this feature
│ │ │ │ │ - * represents.
│ │ │ │ │ - * attributes - {Object} An optional object that will be mapped to the
│ │ │ │ │ - * property.
│ │ │ │ │ - * style - {Object} An optional style object.
│ │ │ │ │ + * type - {String}
│ │ │ │ │ + * obj - {Object} If none specified, defaults to this.object
│ │ │ │ │ + * func - {Function}
│ │ │ │ │ */
│ │ │ │ │ - initialize: function(geometry, attributes, style) {
│ │ │ │ │ - OpenLayers.Feature.prototype.initialize.apply(this,
│ │ │ │ │ - [null, null, attributes]);
│ │ │ │ │ - this.lonlat = null;
│ │ │ │ │ - this.geometry = geometry ? geometry : null;
│ │ │ │ │ - this.state = null;
│ │ │ │ │ - this.attributes = {};
│ │ │ │ │ - if (attributes) {
│ │ │ │ │ - this.attributes = OpenLayers.Util.extend(this.attributes,
│ │ │ │ │ - attributes);
│ │ │ │ │ + unregister: function(type, obj, func) {
│ │ │ │ │ + if (obj == null) {
│ │ │ │ │ + obj = this.object;
│ │ │ │ │ + }
│ │ │ │ │ + var listeners = this.listeners[type];
│ │ │ │ │ + if (listeners != null) {
│ │ │ │ │ + for (var i = 0, len = listeners.length; i < len; i++) {
│ │ │ │ │ + if (listeners[i].obj == obj && listeners[i].func == func) {
│ │ │ │ │ + listeners.splice(i, 1);
│ │ │ │ │ + break;
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ - this.style = style ? style : null;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: destroy
│ │ │ │ │ - * nullify references to prevent circular references and memory leaks
│ │ │ │ │ + * Method: remove
│ │ │ │ │ + * Remove all listeners for a given event type. If type is not registered,
│ │ │ │ │ + * does nothing.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * type - {String}
│ │ │ │ │ */
│ │ │ │ │ - destroy: function() {
│ │ │ │ │ - if (this.layer) {
│ │ │ │ │ - this.layer.removeFeatures(this);
│ │ │ │ │ - this.layer = null;
│ │ │ │ │ + remove: function(type) {
│ │ │ │ │ + if (this.listeners[type] != null) {
│ │ │ │ │ + this.listeners[type] = [];
│ │ │ │ │ }
│ │ │ │ │ -
│ │ │ │ │ - this.geometry = null;
│ │ │ │ │ - this.modified = null;
│ │ │ │ │ - OpenLayers.Feature.prototype.destroy.apply(this, arguments);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: clone
│ │ │ │ │ - * Create a clone of this vector feature. Does not set any non-standard
│ │ │ │ │ - * properties.
│ │ │ │ │ + * APIMethod: triggerEvent
│ │ │ │ │ + * Trigger a specified registered event.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * type - {String}
│ │ │ │ │ + * evt - {Event || Object} will be passed to the listeners.
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {} An exact clone of this vector feature.
│ │ │ │ │ + * {Boolean} The last listener return. If a listener returns false, the
│ │ │ │ │ + * chain of listeners will stop getting called.
│ │ │ │ │ */
│ │ │ │ │ - clone: function() {
│ │ │ │ │ - return new OpenLayers.Feature.Vector(
│ │ │ │ │ - this.geometry ? this.geometry.clone() : null,
│ │ │ │ │ - this.attributes,
│ │ │ │ │ - this.style);
│ │ │ │ │ + triggerEvent: function(type, evt) {
│ │ │ │ │ + var listeners = this.listeners[type];
│ │ │ │ │ +
│ │ │ │ │ + // fast path
│ │ │ │ │ + if (!listeners || listeners.length == 0) {
│ │ │ │ │ + return undefined;
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + // prep evt object with object & div references
│ │ │ │ │ + if (evt == null) {
│ │ │ │ │ + evt = {};
│ │ │ │ │ + }
│ │ │ │ │ + evt.object = this.object;
│ │ │ │ │ + evt.element = this.element;
│ │ │ │ │ + if (!evt.type) {
│ │ │ │ │ + evt.type = type;
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + // execute all callbacks registered for specified type
│ │ │ │ │ + // get a clone of the listeners array to
│ │ │ │ │ + // allow for splicing during callbacks
│ │ │ │ │ + listeners = listeners.slice();
│ │ │ │ │ + var continueChain;
│ │ │ │ │ + for (var i = 0, len = listeners.length; i < len; i++) {
│ │ │ │ │ + var callback = listeners[i];
│ │ │ │ │ + // bind the context to callback.obj
│ │ │ │ │ + continueChain = callback.func.apply(callback.obj, [evt]);
│ │ │ │ │ +
│ │ │ │ │ + if ((continueChain != undefined) && (continueChain == false)) {
│ │ │ │ │ + // if callback returns false, execute no more callbacks.
│ │ │ │ │ + break;
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + // don't fall through to other DOM elements
│ │ │ │ │ + if (!this.fallThrough) {
│ │ │ │ │ + OpenLayers.Event.stop(evt, true);
│ │ │ │ │ + }
│ │ │ │ │ + return continueChain;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: onScreen
│ │ │ │ │ - * Determine whether the feature is within the map viewport. This method
│ │ │ │ │ - * tests for an intersection between the geometry and the viewport
│ │ │ │ │ - * bounds. If a more effecient but less precise geometry bounds
│ │ │ │ │ - * intersection is desired, call the method with the boundsOnly
│ │ │ │ │ - * parameter true.
│ │ │ │ │ + * Method: handleBrowserEvent
│ │ │ │ │ + * Basically just a wrapper to the triggerEvent() function, but takes
│ │ │ │ │ + * care to set a property 'xy' on the event with the current mouse
│ │ │ │ │ + * position.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * boundsOnly - {Boolean} Only test whether a feature's bounds intersects
│ │ │ │ │ - * the viewport bounds. Default is false. If false, the feature's
│ │ │ │ │ - * geometry must intersect the viewport for onScreen to return true.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} The feature is currently visible on screen (optionally
│ │ │ │ │ - * based on its bounds if boundsOnly is true).
│ │ │ │ │ + * evt - {Event}
│ │ │ │ │ */
│ │ │ │ │ - onScreen: function(boundsOnly) {
│ │ │ │ │ - var onScreen = false;
│ │ │ │ │ - if (this.layer && this.layer.map) {
│ │ │ │ │ - var screenBounds = this.layer.map.getExtent();
│ │ │ │ │ - if (boundsOnly) {
│ │ │ │ │ - var featureBounds = this.geometry.getBounds();
│ │ │ │ │ - onScreen = screenBounds.intersectsBounds(featureBounds);
│ │ │ │ │ - } else {
│ │ │ │ │ - var screenPoly = screenBounds.toGeometry();
│ │ │ │ │ - onScreen = screenPoly.intersects(this.geometry);
│ │ │ │ │ + handleBrowserEvent: function(evt) {
│ │ │ │ │ + var type = evt.type,
│ │ │ │ │ + listeners = this.listeners[type];
│ │ │ │ │ + if (!listeners || listeners.length == 0) {
│ │ │ │ │ + // noone's listening, bail out
│ │ │ │ │ + return;
│ │ │ │ │ + }
│ │ │ │ │ + // add clientX & clientY to all events - corresponds to average x, y
│ │ │ │ │ + var touches = evt.touches;
│ │ │ │ │ + if (touches && touches[0]) {
│ │ │ │ │ + var x = 0;
│ │ │ │ │ + var y = 0;
│ │ │ │ │ + var num = touches.length;
│ │ │ │ │ + var touch;
│ │ │ │ │ + for (var i = 0; i < num; ++i) {
│ │ │ │ │ + touch = this.getTouchClientXY(touches[i]);
│ │ │ │ │ + x += touch.clientX;
│ │ │ │ │ + y += touch.clientY;
│ │ │ │ │ }
│ │ │ │ │ + evt.clientX = x / num;
│ │ │ │ │ + evt.clientY = y / num;
│ │ │ │ │ }
│ │ │ │ │ - return onScreen;
│ │ │ │ │ + if (this.includeXY) {
│ │ │ │ │ + evt.xy = this.getMousePosition(evt);
│ │ │ │ │ + }
│ │ │ │ │ + this.triggerEvent(type, evt);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: getVisibility
│ │ │ │ │ - * Determine whether the feature is displayed or not. It may not displayed
│ │ │ │ │ - * because:
│ │ │ │ │ - * - its style display property is set to 'none',
│ │ │ │ │ - * - it doesn't belong to any layer,
│ │ │ │ │ - * - the styleMap creates a symbolizer with display property set to 'none'
│ │ │ │ │ - * for it,
│ │ │ │ │ - * - the layer which it belongs to is not visible.
│ │ │ │ │ + * Method: getTouchClientXY
│ │ │ │ │ + * WebKit has a few bugs for clientX/clientY. This method detects them
│ │ │ │ │ + * and calculate the correct values.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * evt - {Touch} a Touch object from a TouchEvent
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Boolean} The feature is currently displayed.
│ │ │ │ │ + * {Object} An object with only clientX and clientY properties with the
│ │ │ │ │ + * calculated values.
│ │ │ │ │ */
│ │ │ │ │ - getVisibility: function() {
│ │ │ │ │ - return !(this.style && this.style.display == 'none' ||
│ │ │ │ │ - !this.layer ||
│ │ │ │ │ - this.layer && this.layer.styleMap &&
│ │ │ │ │ - this.layer.styleMap.createSymbolizer(this, this.renderIntent).display == 'none' ||
│ │ │ │ │ - this.layer && !this.layer.getVisibility());
│ │ │ │ │ - },
│ │ │ │ │ + getTouchClientXY: function(evt) {
│ │ │ │ │ + // olMochWin is to override window, used for testing
│ │ │ │ │ + var win = window.olMockWin || window,
│ │ │ │ │ + winPageX = win.pageXOffset,
│ │ │ │ │ + winPageY = win.pageYOffset,
│ │ │ │ │ + x = evt.clientX,
│ │ │ │ │ + y = evt.clientY;
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: createMarker
│ │ │ │ │ - * HACK - we need to decide if all vector features should be able to
│ │ │ │ │ - * create markers
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} For now just returns null
│ │ │ │ │ - */
│ │ │ │ │ - createMarker: function() {
│ │ │ │ │ - return null;
│ │ │ │ │ - },
│ │ │ │ │ + if (evt.pageY === 0 && Math.floor(y) > Math.floor(evt.pageY) ||
│ │ │ │ │ + evt.pageX === 0 && Math.floor(x) > Math.floor(evt.pageX)) {
│ │ │ │ │ + // iOS4 include scroll offset in clientX/Y
│ │ │ │ │ + x = x - winPageX;
│ │ │ │ │ + y = y - winPageY;
│ │ │ │ │ + } else if (y < (evt.pageY - winPageY) || x < (evt.pageX - winPageX)) {
│ │ │ │ │ + // Some Android browsers have totally bogus values for clientX/Y
│ │ │ │ │ + // when scrolling/zooming a page
│ │ │ │ │ + x = evt.pageX - winPageX;
│ │ │ │ │ + y = evt.pageY - winPageY;
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: destroyMarker
│ │ │ │ │ - * HACK - we need to decide if all vector features should be able to
│ │ │ │ │ - * delete markers
│ │ │ │ │ - *
│ │ │ │ │ - * If user overrides the createMarker() function, s/he should be able
│ │ │ │ │ - * to also specify an alternative function for destroying it
│ │ │ │ │ - */
│ │ │ │ │ - destroyMarker: function() {
│ │ │ │ │ - // pass
│ │ │ │ │ + evt.olClientX = x;
│ │ │ │ │ + evt.olClientY = y;
│ │ │ │ │ +
│ │ │ │ │ + return {
│ │ │ │ │ + clientX: x,
│ │ │ │ │ + clientY: y
│ │ │ │ │ + };
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: createPopup
│ │ │ │ │ - * HACK - we need to decide if all vector features should be able to
│ │ │ │ │ - * create popups
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} For now just returns null
│ │ │ │ │ + * APIMethod: clearMouseCache
│ │ │ │ │ + * Clear cached data about the mouse position. This should be called any
│ │ │ │ │ + * time the element that events are registered on changes position
│ │ │ │ │ + * within the page.
│ │ │ │ │ */
│ │ │ │ │ - createPopup: function() {
│ │ │ │ │ - return null;
│ │ │ │ │ + clearMouseCache: function() {
│ │ │ │ │ + this.element.scrolls = null;
│ │ │ │ │ + this.element.lefttop = null;
│ │ │ │ │ + this.element.offsets = null;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: atPoint
│ │ │ │ │ - * Determins whether the feature intersects with the specified location.
│ │ │ │ │ + * Method: getMousePosition
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * lonlat - {|Object} OpenLayers.LonLat or an
│ │ │ │ │ - * object with a 'lon' and 'lat' properties.
│ │ │ │ │ - * toleranceLon - {float} Optional tolerance in Geometric Coords
│ │ │ │ │ - * toleranceLat - {float} Optional tolerance in Geographic Coords
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * evt - {Event}
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Boolean} Whether or not the feature is at the specified location
│ │ │ │ │ + * {} The current xy coordinate of the mouse, adjusted
│ │ │ │ │ + * for offsets
│ │ │ │ │ */
│ │ │ │ │ - atPoint: function(lonlat, toleranceLon, toleranceLat) {
│ │ │ │ │ - var atPoint = false;
│ │ │ │ │ - if (this.geometry) {
│ │ │ │ │ - atPoint = this.geometry.atPoint(lonlat, toleranceLon,
│ │ │ │ │ - toleranceLat);
│ │ │ │ │ + getMousePosition: function(evt) {
│ │ │ │ │ + if (!this.includeXY) {
│ │ │ │ │ + this.clearMouseCache();
│ │ │ │ │ + } else if (!this.element.hasScrollEvent) {
│ │ │ │ │ + OpenLayers.Event.observe(window, "scroll", this.clearMouseListener);
│ │ │ │ │ + this.element.hasScrollEvent = true;
│ │ │ │ │ }
│ │ │ │ │ - return atPoint;
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: destroyPopup
│ │ │ │ │ - * HACK - we need to decide if all vector features should be able to
│ │ │ │ │ - * delete popups
│ │ │ │ │ - */
│ │ │ │ │ - destroyPopup: function() {
│ │ │ │ │ - // pass
│ │ │ │ │ + if (!this.element.scrolls) {
│ │ │ │ │ + var viewportElement = OpenLayers.Util.getViewportElement();
│ │ │ │ │ + this.element.scrolls = [
│ │ │ │ │ + window.pageXOffset || viewportElement.scrollLeft,
│ │ │ │ │ + window.pageYOffset || viewportElement.scrollTop
│ │ │ │ │ + ];
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + if (!this.element.lefttop) {
│ │ │ │ │ + this.element.lefttop = [
│ │ │ │ │ + (document.documentElement.clientLeft || 0),
│ │ │ │ │ + (document.documentElement.clientTop || 0)
│ │ │ │ │ + ];
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + if (!this.element.offsets) {
│ │ │ │ │ + this.element.offsets = OpenLayers.Util.pagePosition(this.element);
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + return new OpenLayers.Pixel(
│ │ │ │ │ + (evt.clientX + this.element.scrolls[0]) - this.element.offsets[0] -
│ │ │ │ │ + this.element.lefttop[0],
│ │ │ │ │ + (evt.clientY + this.element.scrolls[1]) - this.element.offsets[1] -
│ │ │ │ │ + this.element.lefttop[1]
│ │ │ │ │ + );
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: move
│ │ │ │ │ - * Moves the feature and redraws it at its new location
│ │ │ │ │ + * Method: addMsTouchListener
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * location - { or } the
│ │ │ │ │ - * location to which to move the feature.
│ │ │ │ │ + * element - {DOMElement} The DOM element to register the listener on
│ │ │ │ │ + * type - {String} The event type
│ │ │ │ │ + * handler - {Function} the handler
│ │ │ │ │ */
│ │ │ │ │ - move: function(location) {
│ │ │ │ │ + addMsTouchListener: function(element, type, handler) {
│ │ │ │ │ + var eventHandler = this.eventHandler;
│ │ │ │ │ + var touches = this._msTouches;
│ │ │ │ │
│ │ │ │ │ - if (!this.layer || !this.geometry.move) {
│ │ │ │ │ - //do nothing if no layer or immoveable geometry
│ │ │ │ │ - return undefined;
│ │ │ │ │ + function msHandler(evt) {
│ │ │ │ │ + handler(OpenLayers.Util.applyDefaults({
│ │ │ │ │ + stopPropagation: function() {
│ │ │ │ │ + for (var i = touches.length - 1; i >= 0; --i) {
│ │ │ │ │ + touches[i].stopPropagation();
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │ + preventDefault: function() {
│ │ │ │ │ + for (var i = touches.length - 1; i >= 0; --i) {
│ │ │ │ │ + touches[i].preventDefault();
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │ + type: type
│ │ │ │ │ + }, evt));
│ │ │ │ │ }
│ │ │ │ │
│ │ │ │ │ - var pixel;
│ │ │ │ │ - if (location.CLASS_NAME == "OpenLayers.LonLat") {
│ │ │ │ │ - pixel = this.layer.getViewPortPxFromLonLat(location);
│ │ │ │ │ - } else {
│ │ │ │ │ - pixel = location;
│ │ │ │ │ + switch (type) {
│ │ │ │ │ + case 'touchstart':
│ │ │ │ │ + return this.addMsTouchListenerStart(element, type, msHandler);
│ │ │ │ │ + case 'touchend':
│ │ │ │ │ + return this.addMsTouchListenerEnd(element, type, msHandler);
│ │ │ │ │ + case 'touchmove':
│ │ │ │ │ + return this.addMsTouchListenerMove(element, type, msHandler);
│ │ │ │ │ + default:
│ │ │ │ │ + throw 'Unknown touch event type';
│ │ │ │ │ }
│ │ │ │ │ -
│ │ │ │ │ - var lastPixel = this.layer.getViewPortPxFromLonLat(this.geometry.getBounds().getCenterLonLat());
│ │ │ │ │ - var res = this.layer.map.getResolution();
│ │ │ │ │ - this.geometry.move(res * (pixel.x - lastPixel.x),
│ │ │ │ │ - res * (lastPixel.y - pixel.y));
│ │ │ │ │ - this.layer.drawFeature(this);
│ │ │ │ │ - return lastPixel;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: toState
│ │ │ │ │ - * Sets the new state
│ │ │ │ │ + * Method: addMsTouchListenerStart
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * state - {String}
│ │ │ │ │ + * element - {DOMElement} The DOM element to register the listener on
│ │ │ │ │ + * type - {String} The event type
│ │ │ │ │ + * handler - {Function} the handler
│ │ │ │ │ */
│ │ │ │ │ - toState: function(state) {
│ │ │ │ │ - if (state == OpenLayers.State.UPDATE) {
│ │ │ │ │ - switch (this.state) {
│ │ │ │ │ - case OpenLayers.State.UNKNOWN:
│ │ │ │ │ - case OpenLayers.State.DELETE:
│ │ │ │ │ - this.state = state;
│ │ │ │ │ - break;
│ │ │ │ │ - case OpenLayers.State.UPDATE:
│ │ │ │ │ - case OpenLayers.State.INSERT:
│ │ │ │ │ + addMsTouchListenerStart: function(element, type, handler) {
│ │ │ │ │ + var touches = this._msTouches;
│ │ │ │ │ +
│ │ │ │ │ + var cb = function(e) {
│ │ │ │ │ +
│ │ │ │ │ + var alreadyInArray = false;
│ │ │ │ │ + for (var i = 0, ii = touches.length; i < ii; ++i) {
│ │ │ │ │ + if (touches[i].pointerId == e.pointerId) {
│ │ │ │ │ + alreadyInArray = true;
│ │ │ │ │ break;
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ - } else if (state == OpenLayers.State.INSERT) {
│ │ │ │ │ - switch (this.state) {
│ │ │ │ │ - case OpenLayers.State.UNKNOWN:
│ │ │ │ │ - break;
│ │ │ │ │ - default:
│ │ │ │ │ - this.state = state;
│ │ │ │ │ - break;
│ │ │ │ │ + if (!alreadyInArray) {
│ │ │ │ │ + touches.push(e);
│ │ │ │ │ }
│ │ │ │ │ - } else if (state == OpenLayers.State.DELETE) {
│ │ │ │ │ - switch (this.state) {
│ │ │ │ │ - case OpenLayers.State.INSERT:
│ │ │ │ │ - // the feature should be destroyed
│ │ │ │ │ +
│ │ │ │ │ + e.touches = touches.slice();
│ │ │ │ │ + handler(e);
│ │ │ │ │ + };
│ │ │ │ │ +
│ │ │ │ │ + OpenLayers.Event.observe(element, 'MSPointerDown', cb);
│ │ │ │ │ +
│ │ │ │ │ + // Need to also listen for end events to keep the _msTouches list
│ │ │ │ │ + // accurate
│ │ │ │ │ + var internalCb = function(e) {
│ │ │ │ │ + for (var i = 0, ii = touches.length; i < ii; ++i) {
│ │ │ │ │ + if (touches[i].pointerId == e.pointerId) {
│ │ │ │ │ + touches.splice(i, 1);
│ │ │ │ │ break;
│ │ │ │ │ - case OpenLayers.State.DELETE:
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + };
│ │ │ │ │ + OpenLayers.Event.observe(element, 'MSPointerUp', internalCb);
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: addMsTouchListenerMove
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * element - {DOMElement} The DOM element to register the listener on
│ │ │ │ │ + * type - {String} The event type
│ │ │ │ │ + * handler - {Function} the handler
│ │ │ │ │ + */
│ │ │ │ │ + addMsTouchListenerMove: function(element, type, handler) {
│ │ │ │ │ + var touches = this._msTouches;
│ │ │ │ │ + var cb = function(e) {
│ │ │ │ │ +
│ │ │ │ │ + //Don't fire touch moves when mouse isn't down
│ │ │ │ │ + if (e.pointerType == e.MSPOINTER_TYPE_MOUSE && e.buttons == 0) {
│ │ │ │ │ + return;
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + if (touches.length == 1 && touches[0].pageX == e.pageX &&
│ │ │ │ │ + touches[0].pageY == e.pageY) {
│ │ │ │ │ + // don't trigger event when pointer has not moved
│ │ │ │ │ + return;
│ │ │ │ │ + }
│ │ │ │ │ + for (var i = 0, ii = touches.length; i < ii; ++i) {
│ │ │ │ │ + if (touches[i].pointerId == e.pointerId) {
│ │ │ │ │ + touches[i] = e;
│ │ │ │ │ break;
│ │ │ │ │ - case OpenLayers.State.UNKNOWN:
│ │ │ │ │ - case OpenLayers.State.UPDATE:
│ │ │ │ │ - this.state = state;
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + e.touches = touches.slice();
│ │ │ │ │ + handler(e);
│ │ │ │ │ + };
│ │ │ │ │ +
│ │ │ │ │ + OpenLayers.Event.observe(element, 'MSPointerMove', cb);
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: addMsTouchListenerEnd
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * element - {DOMElement} The DOM element to register the listener on
│ │ │ │ │ + * type - {String} The event type
│ │ │ │ │ + * handler - {Function} the handler
│ │ │ │ │ + */
│ │ │ │ │ + addMsTouchListenerEnd: function(element, type, handler) {
│ │ │ │ │ + var touches = this._msTouches;
│ │ │ │ │ +
│ │ │ │ │ + var cb = function(e) {
│ │ │ │ │ +
│ │ │ │ │ + for (var i = 0, ii = touches.length; i < ii; ++i) {
│ │ │ │ │ + if (touches[i].pointerId == e.pointerId) {
│ │ │ │ │ + touches.splice(i, 1);
│ │ │ │ │ break;
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ - } else if (state == OpenLayers.State.UNKNOWN) {
│ │ │ │ │ - this.state = state;
│ │ │ │ │ - }
│ │ │ │ │ +
│ │ │ │ │ + e.touches = touches.slice();
│ │ │ │ │ + handler(e);
│ │ │ │ │ + };
│ │ │ │ │ +
│ │ │ │ │ + OpenLayers.Event.observe(element, 'MSPointerUp', cb);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Feature.Vector"
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Events"
│ │ │ │ │ });
│ │ │ │ │ +/* ======================================================================
│ │ │ │ │ + OpenLayers/Animation.js
│ │ │ │ │ + ====================================================================== */
│ │ │ │ │
│ │ │ │ │ +/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ + * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ + * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ + * full text of the license. */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constant: OpenLayers.Feature.Vector.style
│ │ │ │ │ - * OpenLayers features can have a number of style attributes. The 'default'
│ │ │ │ │ - * style will typically be used if no other style is specified. These
│ │ │ │ │ - * styles correspond for the most part, to the styling properties defined
│ │ │ │ │ - * by the SVG standard.
│ │ │ │ │ - * Information on fill properties: http://www.w3.org/TR/SVG/painting.html#FillProperties
│ │ │ │ │ - * Information on stroke properties: http://www.w3.org/TR/SVG/painting.html#StrokeProperties
│ │ │ │ │ - *
│ │ │ │ │ - * Symbolizer properties:
│ │ │ │ │ - * fill - {Boolean} Set to false if no fill is desired.
│ │ │ │ │ - * fillColor - {String} Hex fill color. Default is "#ee9900".
│ │ │ │ │ - * fillOpacity - {Number} Fill opacity (0-1). Default is 0.4
│ │ │ │ │ - * stroke - {Boolean} Set to false if no stroke is desired.
│ │ │ │ │ - * strokeColor - {String} Hex stroke color. Default is "#ee9900".
│ │ │ │ │ - * strokeOpacity - {Number} Stroke opacity (0-1). Default is 1.
│ │ │ │ │ - * strokeWidth - {Number} Pixel stroke width. Default is 1.
│ │ │ │ │ - * strokeLinecap - {String} Stroke cap type. Default is "round". [butt | round | square]
│ │ │ │ │ - * strokeDashstyle - {String} Stroke dash style. Default is "solid". [dot | dash | dashdot | longdash | longdashdot | solid]
│ │ │ │ │ - * graphic - {Boolean} Set to false if no graphic is desired.
│ │ │ │ │ - * pointRadius - {Number} Pixel point radius. Default is 6.
│ │ │ │ │ - * pointerEvents - {String} Default is "visiblePainted".
│ │ │ │ │ - * cursor - {String} Default is "".
│ │ │ │ │ - * externalGraphic - {String} Url to an external graphic that will be used for rendering points.
│ │ │ │ │ - * graphicWidth - {Number} Pixel width for sizing an external graphic.
│ │ │ │ │ - * graphicHeight - {Number} Pixel height for sizing an external graphic.
│ │ │ │ │ - * graphicOpacity - {Number} Opacity (0-1) for an external graphic.
│ │ │ │ │ - * graphicXOffset - {Number} Pixel offset along the positive x axis for displacing an external graphic.
│ │ │ │ │ - * graphicYOffset - {Number} Pixel offset along the positive y axis for displacing an external graphic.
│ │ │ │ │ - * rotation - {Number} For point symbolizers, this is the rotation of a graphic in the clockwise direction about its center point (or any point off center as specified by graphicXOffset and graphicYOffset).
│ │ │ │ │ - * graphicZIndex - {Number} The integer z-index value to use in rendering.
│ │ │ │ │ - * graphicName - {String} Named graphic to use when rendering points. Supported values include "circle" (default),
│ │ │ │ │ - * "square", "star", "x", "cross", "triangle".
│ │ │ │ │ - * graphicTitle - {String} Tooltip when hovering over a feature. *deprecated*, use title instead
│ │ │ │ │ - * title - {String} Tooltip when hovering over a feature. Not supported by the canvas renderer.
│ │ │ │ │ - * backgroundGraphic - {String} Url to a graphic to be used as the background under an externalGraphic.
│ │ │ │ │ - * backgroundGraphicZIndex - {Number} The integer z-index value to use in rendering the background graphic.
│ │ │ │ │ - * backgroundXOffset - {Number} The x offset (in pixels) for the background graphic.
│ │ │ │ │ - * backgroundYOffset - {Number} The y offset (in pixels) for the background graphic.
│ │ │ │ │ - * backgroundHeight - {Number} The height of the background graphic. If not provided, the graphicHeight will be used.
│ │ │ │ │ - * backgroundWidth - {Number} The width of the background width. If not provided, the graphicWidth will be used.
│ │ │ │ │ - * label - {String} The text for an optional label. For browsers that use the canvas renderer, this requires either
│ │ │ │ │ - * fillText or mozDrawText to be available.
│ │ │ │ │ - * labelAlign - {String} Label alignment. This specifies the insertion point relative to the text. It is a string
│ │ │ │ │ - * composed of two characters. The first character is for the horizontal alignment, the second for the vertical
│ │ │ │ │ - * alignment. Valid values for horizontal alignment: "l"=left, "c"=center, "r"=right. Valid values for vertical
│ │ │ │ │ - * alignment: "t"=top, "m"=middle, "b"=bottom. Example values: "lt", "cm", "rb". Default is "cm".
│ │ │ │ │ - * labelXOffset - {Number} Pixel offset along the positive x axis for displacing the label. Not supported by the canvas renderer.
│ │ │ │ │ - * labelYOffset - {Number} Pixel offset along the positive y axis for displacing the label. Not supported by the canvas renderer.
│ │ │ │ │ - * labelSelect - {Boolean} If set to true, labels will be selectable using SelectFeature or similar controls.
│ │ │ │ │ - * Default is false.
│ │ │ │ │ - * labelOutlineColor - {String} The color of the label outline. Default is 'white'. Only supported by the canvas & SVG renderers.
│ │ │ │ │ - * labelOutlineWidth - {Number} The width of the label outline. Default is 3, set to 0 or null to disable. Only supported by the SVG renderers.
│ │ │ │ │ - * labelOutlineOpacity - {Number} The opacity (0-1) of the label outline. Default is fontOpacity. Only supported by the canvas & SVG renderers.
│ │ │ │ │ - * fontColor - {String} The font color for the label, to be provided like CSS.
│ │ │ │ │ - * fontOpacity - {Number} Opacity (0-1) for the label
│ │ │ │ │ - * fontFamily - {String} The font family for the label, to be provided like in CSS.
│ │ │ │ │ - * fontSize - {String} The font size for the label, to be provided like in CSS.
│ │ │ │ │ - * fontStyle - {String} The font style for the label, to be provided like in CSS.
│ │ │ │ │ - * fontWeight - {String} The font weight for the label, to be provided like in CSS.
│ │ │ │ │ - * display - {String} Symbolizers will have no effect if display is set to "none". All other values have no effect.
│ │ │ │ │ + * @requires OpenLayers/SingleFile.js
│ │ │ │ │ + * @requires OpenLayers/Util/vendorPrefix.js
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Feature.Vector.style = {
│ │ │ │ │ - 'default': {
│ │ │ │ │ - fillColor: "#ee9900",
│ │ │ │ │ - fillOpacity: 0.4,
│ │ │ │ │ - hoverFillColor: "white",
│ │ │ │ │ - hoverFillOpacity: 0.8,
│ │ │ │ │ - strokeColor: "#ee9900",
│ │ │ │ │ - strokeOpacity: 1,
│ │ │ │ │ - strokeWidth: 1,
│ │ │ │ │ - strokeLinecap: "round",
│ │ │ │ │ - strokeDashstyle: "solid",
│ │ │ │ │ - hoverStrokeColor: "red",
│ │ │ │ │ - hoverStrokeOpacity: 1,
│ │ │ │ │ - hoverStrokeWidth: 0.2,
│ │ │ │ │ - pointRadius: 6,
│ │ │ │ │ - hoverPointRadius: 1,
│ │ │ │ │ - hoverPointUnit: "%",
│ │ │ │ │ - pointerEvents: "visiblePainted",
│ │ │ │ │ - cursor: "inherit",
│ │ │ │ │ - fontColor: "#000000",
│ │ │ │ │ - labelAlign: "cm",
│ │ │ │ │ - labelOutlineColor: "white",
│ │ │ │ │ - labelOutlineWidth: 3
│ │ │ │ │ - },
│ │ │ │ │ - 'select': {
│ │ │ │ │ - fillColor: "blue",
│ │ │ │ │ - fillOpacity: 0.4,
│ │ │ │ │ - hoverFillColor: "white",
│ │ │ │ │ - hoverFillOpacity: 0.8,
│ │ │ │ │ - strokeColor: "blue",
│ │ │ │ │ - strokeOpacity: 1,
│ │ │ │ │ - strokeWidth: 2,
│ │ │ │ │ - strokeLinecap: "round",
│ │ │ │ │ - strokeDashstyle: "solid",
│ │ │ │ │ - hoverStrokeColor: "red",
│ │ │ │ │ - hoverStrokeOpacity: 1,
│ │ │ │ │ - hoverStrokeWidth: 0.2,
│ │ │ │ │ - pointRadius: 6,
│ │ │ │ │ - hoverPointRadius: 1,
│ │ │ │ │ - hoverPointUnit: "%",
│ │ │ │ │ - pointerEvents: "visiblePainted",
│ │ │ │ │ - cursor: "pointer",
│ │ │ │ │ - fontColor: "#000000",
│ │ │ │ │ - labelAlign: "cm",
│ │ │ │ │ - labelOutlineColor: "white",
│ │ │ │ │ - labelOutlineWidth: 3
│ │ │ │ │
│ │ │ │ │ - },
│ │ │ │ │ - 'temporary': {
│ │ │ │ │ - fillColor: "#66cccc",
│ │ │ │ │ - fillOpacity: 0.2,
│ │ │ │ │ - hoverFillColor: "white",
│ │ │ │ │ - hoverFillOpacity: 0.8,
│ │ │ │ │ - strokeColor: "#66cccc",
│ │ │ │ │ - strokeOpacity: 1,
│ │ │ │ │ - strokeLinecap: "round",
│ │ │ │ │ - strokeWidth: 2,
│ │ │ │ │ - strokeDashstyle: "solid",
│ │ │ │ │ - hoverStrokeColor: "red",
│ │ │ │ │ - hoverStrokeOpacity: 1,
│ │ │ │ │ - hoverStrokeWidth: 0.2,
│ │ │ │ │ - pointRadius: 6,
│ │ │ │ │ - hoverPointRadius: 1,
│ │ │ │ │ - hoverPointUnit: "%",
│ │ │ │ │ - pointerEvents: "visiblePainted",
│ │ │ │ │ - cursor: "inherit",
│ │ │ │ │ - fontColor: "#000000",
│ │ │ │ │ - labelAlign: "cm",
│ │ │ │ │ - labelOutlineColor: "white",
│ │ │ │ │ - labelOutlineWidth: 3
│ │ │ │ │ +/**
│ │ │ │ │ + * Namespace: OpenLayers.Animation
│ │ │ │ │ + * A collection of utility functions for executing methods that repaint a
│ │ │ │ │ + * portion of the browser window. These methods take advantage of the
│ │ │ │ │ + * browser's scheduled repaints where requestAnimationFrame is available.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Animation = (function(window) {
│ │ │ │ │
│ │ │ │ │ - },
│ │ │ │ │ - 'delete': {
│ │ │ │ │ - display: "none"
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: isNative
│ │ │ │ │ + * {Boolean} true if a native requestAnimationFrame function is available
│ │ │ │ │ + */
│ │ │ │ │ + var requestAnimationFrame = OpenLayers.Util.vendorPrefix.js(window, "requestAnimationFrame");
│ │ │ │ │ + var isNative = !!(requestAnimationFrame);
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Function: requestFrame
│ │ │ │ │ + * Schedule a function to be called at the next available animation frame.
│ │ │ │ │ + * Uses the native method where available. Where requestAnimationFrame is
│ │ │ │ │ + * not available, setTimeout will be called with a 16ms delay.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * callback - {Function} The function to be called at the next animation frame.
│ │ │ │ │ + * element - {DOMElement} Optional element that visually bounds the animation.
│ │ │ │ │ + */
│ │ │ │ │ + var requestFrame = (function() {
│ │ │ │ │ + var request = window[requestAnimationFrame] ||
│ │ │ │ │ + function(callback, element) {
│ │ │ │ │ + window.setTimeout(callback, 16);
│ │ │ │ │ + };
│ │ │ │ │ + // bind to window to avoid illegal invocation of native function
│ │ │ │ │ + return function(callback, element) {
│ │ │ │ │ + request.apply(window, [callback, element]);
│ │ │ │ │ + };
│ │ │ │ │ + })();
│ │ │ │ │ +
│ │ │ │ │ + // private variables for animation loops
│ │ │ │ │ + var counter = 0;
│ │ │ │ │ + var loops = {};
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Function: start
│ │ │ │ │ + * Executes a method with in series for some
│ │ │ │ │ + * duration.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * callback - {Function} The function to be called at the next animation frame.
│ │ │ │ │ + * duration - {Number} Optional duration for the loop. If not provided, the
│ │ │ │ │ + * animation loop will execute indefinitely.
│ │ │ │ │ + * element - {DOMElement} Optional element that visually bounds the animation.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Number} Identifier for the animation loop. Used to stop animations with
│ │ │ │ │ + * .
│ │ │ │ │ + */
│ │ │ │ │ + function start(callback, duration, element) {
│ │ │ │ │ + duration = duration > 0 ? duration : Number.POSITIVE_INFINITY;
│ │ │ │ │ + var id = ++counter;
│ │ │ │ │ + var start = +new Date;
│ │ │ │ │ + loops[id] = function() {
│ │ │ │ │ + if (loops[id] && +new Date - start <= duration) {
│ │ │ │ │ + callback();
│ │ │ │ │ + if (loops[id]) {
│ │ │ │ │ + requestFrame(loops[id], element);
│ │ │ │ │ + }
│ │ │ │ │ + } else {
│ │ │ │ │ + delete loops[id];
│ │ │ │ │ + }
│ │ │ │ │ + };
│ │ │ │ │ + requestFrame(loops[id], element);
│ │ │ │ │ + return id;
│ │ │ │ │ }
│ │ │ │ │ -};
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Function: stop
│ │ │ │ │ + * Terminates an animation loop started with .
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * id - {Number} Identifier returned from .
│ │ │ │ │ + */
│ │ │ │ │ + function stop(id) {
│ │ │ │ │ + delete loops[id];
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + return {
│ │ │ │ │ + isNative: isNative,
│ │ │ │ │ + requestFrame: requestFrame,
│ │ │ │ │ + start: start,
│ │ │ │ │ + stop: stop
│ │ │ │ │ + };
│ │ │ │ │ +
│ │ │ │ │ +})(window);
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Style.js
│ │ │ │ │ + OpenLayers/Tween.js
│ │ │ │ │ ====================================================================== */
│ │ │ │ │
│ │ │ │ │ /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ * full text of the license. */
│ │ │ │ │
│ │ │ │ │ -
│ │ │ │ │ /**
│ │ │ │ │ * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ - * @requires OpenLayers/Util.js
│ │ │ │ │ - * @requires OpenLayers/Feature/Vector.js
│ │ │ │ │ + * @requires OpenLayers/Animation.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Class: OpenLayers.Style
│ │ │ │ │ - * This class represents a UserStyle obtained
│ │ │ │ │ - * from a SLD, containing styling rules.
│ │ │ │ │ + * Namespace: OpenLayers.Tween
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Style = OpenLayers.Class({
│ │ │ │ │ +OpenLayers.Tween = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: id
│ │ │ │ │ - * {String} A unique id for this session.
│ │ │ │ │ + * APIProperty: easing
│ │ │ │ │ + * {(Function)} Easing equation used for the animation
│ │ │ │ │ + * Defaultly set to OpenLayers.Easing.Expo.easeOut
│ │ │ │ │ */
│ │ │ │ │ - id: null,
│ │ │ │ │ + easing: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: name
│ │ │ │ │ - * {String}
│ │ │ │ │ + * APIProperty: begin
│ │ │ │ │ + * {Object} Values to start the animation with
│ │ │ │ │ */
│ │ │ │ │ - name: null,
│ │ │ │ │ + begin: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: title
│ │ │ │ │ - * {String} Title of this style (set if included in SLD)
│ │ │ │ │ + * APIProperty: finish
│ │ │ │ │ + * {Object} Values to finish the animation with
│ │ │ │ │ */
│ │ │ │ │ - title: null,
│ │ │ │ │ + finish: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: description
│ │ │ │ │ - * {String} Description of this style (set if abstract is included in SLD)
│ │ │ │ │ + * APIProperty: duration
│ │ │ │ │ + * {int} duration of the tween (number of steps)
│ │ │ │ │ */
│ │ │ │ │ - description: null,
│ │ │ │ │ + duration: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: layerName
│ │ │ │ │ - * {} name of the layer that this style belongs to, usually
│ │ │ │ │ - * according to the NamedLayer attribute of an SLD document.
│ │ │ │ │ + * APIProperty: callbacks
│ │ │ │ │ + * {Object} An object with start, eachStep and done properties whose values
│ │ │ │ │ + * are functions to be call during the animation. They are passed the
│ │ │ │ │ + * current computed value as argument.
│ │ │ │ │ */
│ │ │ │ │ - layerName: null,
│ │ │ │ │ + callbacks: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: isDefault
│ │ │ │ │ - * {Boolean}
│ │ │ │ │ - */
│ │ │ │ │ - isDefault: false,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: rules
│ │ │ │ │ - * {Array()}
│ │ │ │ │ + * Property: time
│ │ │ │ │ + * {int} Step counter
│ │ │ │ │ */
│ │ │ │ │ - rules: null,
│ │ │ │ │ + time: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: context
│ │ │ │ │ - * {Object} An optional object with properties that symbolizers' property
│ │ │ │ │ - * values should be evaluated against. If no context is specified,
│ │ │ │ │ - * feature.attributes will be used
│ │ │ │ │ + * APIProperty: minFrameRate
│ │ │ │ │ + * {Number} The minimum framerate for animations in frames per second. After
│ │ │ │ │ + * each step, the time spent in the animation is compared to the calculated
│ │ │ │ │ + * time at this frame rate. If the animation runs longer than the calculated
│ │ │ │ │ + * time, the next step is skipped. Default is 30.
│ │ │ │ │ */
│ │ │ │ │ - context: null,
│ │ │ │ │ + minFrameRate: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: defaultStyle
│ │ │ │ │ - * {Object} hash of style properties to use as default for merging
│ │ │ │ │ - * rule-based style symbolizers onto. If no rules are defined,
│ │ │ │ │ - * createSymbolizer will return this style. If is set to
│ │ │ │ │ - * true, the defaultStyle will only be taken into account if there are
│ │ │ │ │ - * rules defined.
│ │ │ │ │ + * Property: startTime
│ │ │ │ │ + * {Number} The timestamp of the first execution step. Used for skipping
│ │ │ │ │ + * frames
│ │ │ │ │ */
│ │ │ │ │ - defaultStyle: null,
│ │ │ │ │ + startTime: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: defaultsPerSymbolizer
│ │ │ │ │ - * {Boolean} If set to true, the will extend the symbolizer
│ │ │ │ │ - * of every rule. Properties of the will also be used to set
│ │ │ │ │ - * missing symbolizer properties if the symbolizer has stroke, fill or
│ │ │ │ │ - * graphic set to true. Default is false.
│ │ │ │ │ + * Property: animationId
│ │ │ │ │ + * {int} Loop id returned by OpenLayers.Animation.start
│ │ │ │ │ */
│ │ │ │ │ - defaultsPerSymbolizer: false,
│ │ │ │ │ + animationId: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: propertyStyles
│ │ │ │ │ - * {Hash of Boolean} cache of style properties that need to be parsed for
│ │ │ │ │ - * propertyNames. Property names are keys, values won't be used.
│ │ │ │ │ + * Property: playing
│ │ │ │ │ + * {Boolean} Tells if the easing is currently playing
│ │ │ │ │ */
│ │ │ │ │ - propertyStyles: null,
│ │ │ │ │ -
│ │ │ │ │ + playing: false,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constructor: OpenLayers.Style
│ │ │ │ │ - * Creates a UserStyle.
│ │ │ │ │ + * Constructor: OpenLayers.Tween
│ │ │ │ │ + * Creates a Tween.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * style - {Object} Optional hash of style properties that will be
│ │ │ │ │ - * used as default style for this style object. This style
│ │ │ │ │ - * applies if no rules are specified. Symbolizers defined in
│ │ │ │ │ - * rules will extend this default style.
│ │ │ │ │ - * options - {Object} An optional object with properties to set on the
│ │ │ │ │ - * style.
│ │ │ │ │ - *
│ │ │ │ │ - * Valid options:
│ │ │ │ │ - * rules - {Array()} List of rules to be added to the
│ │ │ │ │ - * style.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {}
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(style, options) {
│ │ │ │ │ -
│ │ │ │ │ - OpenLayers.Util.extend(this, options);
│ │ │ │ │ - this.rules = [];
│ │ │ │ │ - if (options && options.rules) {
│ │ │ │ │ - this.addRules(options.rules);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // use the default style from OpenLayers.Feature.Vector if no style
│ │ │ │ │ - // was given in the constructor
│ │ │ │ │ - this.setDefaultStyle(style ||
│ │ │ │ │ - OpenLayers.Feature.Vector.style["default"]);
│ │ │ │ │ -
│ │ │ │ │ - this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: destroy
│ │ │ │ │ - * nullify references to prevent circular references and memory leaks
│ │ │ │ │ + * easing - {(Function)} easing function method to use
│ │ │ │ │ */
│ │ │ │ │ - destroy: function() {
│ │ │ │ │ - for (var i = 0, len = this.rules.length; i < len; i++) {
│ │ │ │ │ - this.rules[i].destroy();
│ │ │ │ │ - this.rules[i] = null;
│ │ │ │ │ - }
│ │ │ │ │ - this.rules = null;
│ │ │ │ │ - this.defaultStyle = null;
│ │ │ │ │ + initialize: function(easing) {
│ │ │ │ │ + this.easing = (easing) ? easing : OpenLayers.Easing.Expo.easeOut;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: createSymbolizer
│ │ │ │ │ - * creates a style by applying all feature-dependent rules to the base
│ │ │ │ │ - * style.
│ │ │ │ │ + * APIMethod: start
│ │ │ │ │ + * Plays the Tween, and calls the callback method on each step
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * feature - {} feature to evaluate rules for
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Object} symbolizer hash
│ │ │ │ │ + * begin - {Object} values to start the animation with
│ │ │ │ │ + * finish - {Object} values to finish the animation with
│ │ │ │ │ + * duration - {int} duration of the tween (number of steps)
│ │ │ │ │ + * options - {Object} hash of options (callbacks (start, eachStep, done),
│ │ │ │ │ + * minFrameRate)
│ │ │ │ │ */
│ │ │ │ │ - createSymbolizer: function(feature) {
│ │ │ │ │ - var style = this.defaultsPerSymbolizer ? {} : this.createLiterals(
│ │ │ │ │ - OpenLayers.Util.extend({}, this.defaultStyle), feature);
│ │ │ │ │ -
│ │ │ │ │ - var rules = this.rules;
│ │ │ │ │ -
│ │ │ │ │ - var rule, context;
│ │ │ │ │ - var elseRules = [];
│ │ │ │ │ - var appliedRules = false;
│ │ │ │ │ - for (var i = 0, len = rules.length; i < len; i++) {
│ │ │ │ │ - rule = rules[i];
│ │ │ │ │ - // does the rule apply?
│ │ │ │ │ - var applies = rule.evaluate(feature);
│ │ │ │ │ -
│ │ │ │ │ - if (applies) {
│ │ │ │ │ - if (rule instanceof OpenLayers.Rule && rule.elseFilter) {
│ │ │ │ │ - elseRules.push(rule);
│ │ │ │ │ - } else {
│ │ │ │ │ - appliedRules = true;
│ │ │ │ │ - this.applySymbolizer(rule, style, feature);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // if no other rules apply, apply the rules with else filters
│ │ │ │ │ - if (appliedRules == false && elseRules.length > 0) {
│ │ │ │ │ - appliedRules = true;
│ │ │ │ │ - for (var i = 0, len = elseRules.length; i < len; i++) {
│ │ │ │ │ - this.applySymbolizer(elseRules[i], style, feature);
│ │ │ │ │ - }
│ │ │ │ │ + start: function(begin, finish, duration, options) {
│ │ │ │ │ + this.playing = true;
│ │ │ │ │ + this.begin = begin;
│ │ │ │ │ + this.finish = finish;
│ │ │ │ │ + this.duration = duration;
│ │ │ │ │ + this.callbacks = options.callbacks;
│ │ │ │ │ + this.minFrameRate = options.minFrameRate || 30;
│ │ │ │ │ + this.time = 0;
│ │ │ │ │ + this.startTime = new Date().getTime();
│ │ │ │ │ + OpenLayers.Animation.stop(this.animationId);
│ │ │ │ │ + this.animationId = null;
│ │ │ │ │ + if (this.callbacks && this.callbacks.start) {
│ │ │ │ │ + this.callbacks.start.call(this, this.begin);
│ │ │ │ │ }
│ │ │ │ │ + this.animationId = OpenLayers.Animation.start(
│ │ │ │ │ + OpenLayers.Function.bind(this.play, this)
│ │ │ │ │ + );
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - // don't display if there were rules but none applied
│ │ │ │ │ - if (rules.length > 0 && appliedRules == false) {
│ │ │ │ │ - style.display = "none";
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: stop
│ │ │ │ │ + * Stops the Tween, and calls the done callback
│ │ │ │ │ + * Doesn't do anything if animation is already finished
│ │ │ │ │ + */
│ │ │ │ │ + stop: function() {
│ │ │ │ │ + if (!this.playing) {
│ │ │ │ │ + return;
│ │ │ │ │ }
│ │ │ │ │
│ │ │ │ │ - if (style.label != null && typeof style.label !== "string") {
│ │ │ │ │ - style.label = String(style.label);
│ │ │ │ │ + if (this.callbacks && this.callbacks.done) {
│ │ │ │ │ + this.callbacks.done.call(this, this.finish);
│ │ │ │ │ }
│ │ │ │ │ -
│ │ │ │ │ - return style;
│ │ │ │ │ + OpenLayers.Animation.stop(this.animationId);
│ │ │ │ │ + this.animationId = null;
│ │ │ │ │ + this.playing = false;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: applySymbolizer
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * rule - {}
│ │ │ │ │ - * style - {Object}
│ │ │ │ │ - * feature - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Object} A style with new symbolizer applied.
│ │ │ │ │ + * Method: play
│ │ │ │ │ + * Calls the appropriate easing method
│ │ │ │ │ */
│ │ │ │ │ - applySymbolizer: function(rule, style, feature) {
│ │ │ │ │ - var symbolizerPrefix = feature.geometry ?
│ │ │ │ │ - this.getSymbolizerPrefix(feature.geometry) :
│ │ │ │ │ - OpenLayers.Style.SYMBOLIZER_PREFIXES[0];
│ │ │ │ │ + play: function() {
│ │ │ │ │ + var value = {};
│ │ │ │ │ + for (var i in this.begin) {
│ │ │ │ │ + var b = this.begin[i];
│ │ │ │ │ + var f = this.finish[i];
│ │ │ │ │ + if (b == null || f == null || isNaN(b) || isNaN(f)) {
│ │ │ │ │ + throw new TypeError('invalid value for Tween');
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - var symbolizer = rule.symbolizer[symbolizerPrefix] || rule.symbolizer;
│ │ │ │ │ + var c = f - b;
│ │ │ │ │ + value[i] = this.easing.apply(this, [this.time, b, c, this.duration]);
│ │ │ │ │ + }
│ │ │ │ │ + this.time++;
│ │ │ │ │
│ │ │ │ │ - if (this.defaultsPerSymbolizer === true) {
│ │ │ │ │ - var defaults = this.defaultStyle;
│ │ │ │ │ - OpenLayers.Util.applyDefaults(symbolizer, {
│ │ │ │ │ - pointRadius: defaults.pointRadius
│ │ │ │ │ - });
│ │ │ │ │ - if (symbolizer.stroke === true || symbolizer.graphic === true) {
│ │ │ │ │ - OpenLayers.Util.applyDefaults(symbolizer, {
│ │ │ │ │ - strokeWidth: defaults.strokeWidth,
│ │ │ │ │ - strokeColor: defaults.strokeColor,
│ │ │ │ │ - strokeOpacity: defaults.strokeOpacity,
│ │ │ │ │ - strokeDashstyle: defaults.strokeDashstyle,
│ │ │ │ │ - strokeLinecap: defaults.strokeLinecap
│ │ │ │ │ - });
│ │ │ │ │ - }
│ │ │ │ │ - if (symbolizer.fill === true || symbolizer.graphic === true) {
│ │ │ │ │ - OpenLayers.Util.applyDefaults(symbolizer, {
│ │ │ │ │ - fillColor: defaults.fillColor,
│ │ │ │ │ - fillOpacity: defaults.fillOpacity
│ │ │ │ │ - });
│ │ │ │ │ - }
│ │ │ │ │ - if (symbolizer.graphic === true) {
│ │ │ │ │ - OpenLayers.Util.applyDefaults(symbolizer, {
│ │ │ │ │ - pointRadius: this.defaultStyle.pointRadius,
│ │ │ │ │ - externalGraphic: this.defaultStyle.externalGraphic,
│ │ │ │ │ - graphicName: this.defaultStyle.graphicName,
│ │ │ │ │ - graphicOpacity: this.defaultStyle.graphicOpacity,
│ │ │ │ │ - graphicWidth: this.defaultStyle.graphicWidth,
│ │ │ │ │ - graphicHeight: this.defaultStyle.graphicHeight,
│ │ │ │ │ - graphicXOffset: this.defaultStyle.graphicXOffset,
│ │ │ │ │ - graphicYOffset: this.defaultStyle.graphicYOffset
│ │ │ │ │ - });
│ │ │ │ │ + if (this.callbacks && this.callbacks.eachStep) {
│ │ │ │ │ + // skip frames if frame rate drops below threshold
│ │ │ │ │ + if ((new Date().getTime() - this.startTime) / this.time <= 1000 / this.minFrameRate) {
│ │ │ │ │ + this.callbacks.eachStep.call(this, value);
│ │ │ │ │ }
│ │ │ │ │ }
│ │ │ │ │
│ │ │ │ │ - // merge the style with the current style
│ │ │ │ │ - return this.createLiterals(
│ │ │ │ │ - OpenLayers.Util.extend(style, symbolizer), feature);
│ │ │ │ │ + if (this.time > this.duration) {
│ │ │ │ │ + this.stop();
│ │ │ │ │ + }
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: createLiterals
│ │ │ │ │ - * creates literals for all style properties that have an entry in
│ │ │ │ │ - * .
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * style - {Object} style to create literals for. Will be modified
│ │ │ │ │ - * inline.
│ │ │ │ │ - * feature - {Object}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Object} the modified style
│ │ │ │ │ + * Create empty functions for all easing methods.
│ │ │ │ │ */
│ │ │ │ │ - createLiterals: function(style, feature) {
│ │ │ │ │ - var context = OpenLayers.Util.extend({}, feature.attributes || feature.data);
│ │ │ │ │ - OpenLayers.Util.extend(context, this.context);
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Tween"
│ │ │ │ │ +});
│ │ │ │ │
│ │ │ │ │ - for (var i in this.propertyStyles) {
│ │ │ │ │ - style[i] = OpenLayers.Style.createLiteral(style[i], context, feature, i);
│ │ │ │ │ - }
│ │ │ │ │ - return style;
│ │ │ │ │ - },
│ │ │ │ │ +/**
│ │ │ │ │ + * Namespace: OpenLayers.Easing
│ │ │ │ │ + *
│ │ │ │ │ + * Credits:
│ │ │ │ │ + * Easing Equations by Robert Penner,
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Easing = {
│ │ │ │ │ + /**
│ │ │ │ │ + * Create empty functions for all easing methods.
│ │ │ │ │ + */
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Easing"
│ │ │ │ │ +};
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Namespace: OpenLayers.Easing.Linear
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Easing.Linear = {
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: findPropertyStyles
│ │ │ │ │ - * Looks into all rules for this style and the defaultStyle to collect
│ │ │ │ │ - * all the style hash property names containing ${...} strings that have
│ │ │ │ │ - * to be replaced using the createLiteral method before returning them.
│ │ │ │ │ + * Function: easeIn
│ │ │ │ │ *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Object} hash of property names that need createLiteral parsing. The
│ │ │ │ │ - * name of the property is the key, and the value is true;
│ │ │ │ │ + * {Float}
│ │ │ │ │ */
│ │ │ │ │ - findPropertyStyles: function() {
│ │ │ │ │ - var propertyStyles = {};
│ │ │ │ │ -
│ │ │ │ │ - // check the default style
│ │ │ │ │ - var style = this.defaultStyle;
│ │ │ │ │ - this.addPropertyStyles(propertyStyles, style);
│ │ │ │ │ -
│ │ │ │ │ - // walk through all rules to check for properties in their symbolizer
│ │ │ │ │ - var rules = this.rules;
│ │ │ │ │ - var symbolizer, value;
│ │ │ │ │ - for (var i = 0, len = rules.length; i < len; i++) {
│ │ │ │ │ - symbolizer = rules[i].symbolizer;
│ │ │ │ │ - for (var key in symbolizer) {
│ │ │ │ │ - value = symbolizer[key];
│ │ │ │ │ - if (typeof value == "object") {
│ │ │ │ │ - // symbolizer key is "Point", "Line" or "Polygon"
│ │ │ │ │ - this.addPropertyStyles(propertyStyles, value);
│ │ │ │ │ - } else {
│ │ │ │ │ - // symbolizer is a hash of style properties
│ │ │ │ │ - this.addPropertyStyles(propertyStyles, symbolizer);
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return propertyStyles;
│ │ │ │ │ + easeIn: function(t, b, c, d) {
│ │ │ │ │ + return c * t / d + b;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: addPropertyStyles
│ │ │ │ │ + * Function: easeOut
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * propertyStyles - {Object} hash to add new property styles to. Will be
│ │ │ │ │ - * modified inline
│ │ │ │ │ - * symbolizer - {Object} search this symbolizer for property styles
│ │ │ │ │ - *
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Object} propertyStyles hash
│ │ │ │ │ + * {Float}
│ │ │ │ │ */
│ │ │ │ │ - addPropertyStyles: function(propertyStyles, symbolizer) {
│ │ │ │ │ - var property;
│ │ │ │ │ - for (var key in symbolizer) {
│ │ │ │ │ - property = symbolizer[key];
│ │ │ │ │ - if (typeof property == "string" &&
│ │ │ │ │ - property.match(/\$\{\w+\}/)) {
│ │ │ │ │ - propertyStyles[key] = true;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return propertyStyles;
│ │ │ │ │ + easeOut: function(t, b, c, d) {
│ │ │ │ │ + return c * t / d + b;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: addRules
│ │ │ │ │ - * Adds rules to this style.
│ │ │ │ │ + * Function: easeInOut
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * rules - {Array()}
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Float}
│ │ │ │ │ */
│ │ │ │ │ - addRules: function(rules) {
│ │ │ │ │ - Array.prototype.push.apply(this.rules, rules);
│ │ │ │ │ - this.propertyStyles = this.findPropertyStyles();
│ │ │ │ │ + easeInOut: function(t, b, c, d) {
│ │ │ │ │ + return c * t / d + b;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Easing.Linear"
│ │ │ │ │ +};
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Namespace: OpenLayers.Easing.Expo
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Easing.Expo = {
│ │ │ │ │ +
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: setDefaultStyle
│ │ │ │ │ - * Sets the default style for this style object.
│ │ │ │ │ + * Function: easeIn
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * style - {Object} Hash of style properties
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Float}
│ │ │ │ │ */
│ │ │ │ │ - setDefaultStyle: function(style) {
│ │ │ │ │ - this.defaultStyle = style;
│ │ │ │ │ - this.propertyStyles = this.findPropertyStyles();
│ │ │ │ │ + easeIn: function(t, b, c, d) {
│ │ │ │ │ + return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: getSymbolizerPrefix
│ │ │ │ │ - * Returns the correct symbolizer prefix according to the
│ │ │ │ │ - * geometry type of the passed geometry
│ │ │ │ │ + * Function: easeOut
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * geometry - {}
│ │ │ │ │ - *
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {String} key of the according symbolizer
│ │ │ │ │ + * {Float}
│ │ │ │ │ */
│ │ │ │ │ - getSymbolizerPrefix: function(geometry) {
│ │ │ │ │ - var prefixes = OpenLayers.Style.SYMBOLIZER_PREFIXES;
│ │ │ │ │ - for (var i = 0, len = prefixes.length; i < len; i++) {
│ │ │ │ │ - if (geometry.CLASS_NAME.indexOf(prefixes[i]) != -1) {
│ │ │ │ │ - return prefixes[i];
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ + easeOut: function(t, b, c, d) {
│ │ │ │ │ + return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: clone
│ │ │ │ │ - * Clones this style.
│ │ │ │ │ + * Function: easeInOut
│ │ │ │ │ *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {} Clone of this style.
│ │ │ │ │ + * {Float}
│ │ │ │ │ */
│ │ │ │ │ - clone: function() {
│ │ │ │ │ - var options = OpenLayers.Util.extend({}, this);
│ │ │ │ │ - // clone rules
│ │ │ │ │ - if (this.rules) {
│ │ │ │ │ - options.rules = [];
│ │ │ │ │ - for (var i = 0, len = this.rules.length; i < len; ++i) {
│ │ │ │ │ - options.rules.push(this.rules[i].clone());
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - // clone context
│ │ │ │ │ - options.context = this.context && OpenLayers.Util.extend({}, this.context);
│ │ │ │ │ - //clone default style
│ │ │ │ │ - var defaultStyle = OpenLayers.Util.extend({}, this.defaultStyle);
│ │ │ │ │ - return new OpenLayers.Style(defaultStyle, options);
│ │ │ │ │ + easeInOut: function(t, b, c, d) {
│ │ │ │ │ + if (t == 0) return b;
│ │ │ │ │ + if (t == d) return b + c;
│ │ │ │ │ + if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
│ │ │ │ │ + return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Style"
│ │ │ │ │ -});
│ │ │ │ │ -
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Function: createLiteral
│ │ │ │ │ - * converts a style value holding a combination of PropertyName and Literal
│ │ │ │ │ - * into a Literal, taking the property values from the passed features.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * value - {String} value to parse. If this string contains a construct like
│ │ │ │ │ - * "foo ${bar}", then "foo " will be taken as literal, and "${bar}"
│ │ │ │ │ - * will be replaced by the value of the "bar" attribute of the passed
│ │ │ │ │ - * feature.
│ │ │ │ │ - * context - {Object} context to take attribute values from
│ │ │ │ │ - * feature - {} optional feature to pass to
│ │ │ │ │ - * for evaluating functions in the
│ │ │ │ │ - * context.
│ │ │ │ │ - * property - {String} optional, name of the property for which the literal is
│ │ │ │ │ - * being created for evaluating functions in the context.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} the parsed value. In the example of the value parameter above, the
│ │ │ │ │ - * result would be "foo valueOfBar", assuming that the passed feature has an
│ │ │ │ │ - * attribute named "bar" with the value "valueOfBar".
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Style.createLiteral = function(value, context, feature, property) {
│ │ │ │ │ - if (typeof value == "string" && value.indexOf("${") != -1) {
│ │ │ │ │ - value = OpenLayers.String.format(value, context, [feature, property]);
│ │ │ │ │ - value = (isNaN(value) || !value) ? value : parseFloat(value);
│ │ │ │ │ - }
│ │ │ │ │ - return value;
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Easing.Expo"
│ │ │ │ │ };
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constant: OpenLayers.Style.SYMBOLIZER_PREFIXES
│ │ │ │ │ - * {Array} prefixes of the sld symbolizers. These are the
│ │ │ │ │ - * same as the main geometry types
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Style.SYMBOLIZER_PREFIXES = ['Point', 'Line', 'Polygon', 'Text',
│ │ │ │ │ - 'Raster'
│ │ │ │ │ -];
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/StyleMap.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ - * @requires OpenLayers/Style.js
│ │ │ │ │ - * @requires OpenLayers/Feature/Vector.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.StyleMap
│ │ │ │ │ + * Namespace: OpenLayers.Easing.Quad
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.StyleMap = OpenLayers.Class({
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: styles
│ │ │ │ │ - * {Object} Hash of {}, keyed by names of well known
│ │ │ │ │ - * rendering intents (e.g. "default", "temporary", "select", "delete").
│ │ │ │ │ - */
│ │ │ │ │ - styles: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: extendDefault
│ │ │ │ │ - * {Boolean} if true, every render intent will extend the symbolizers
│ │ │ │ │ - * specified for the "default" intent at rendering time. Otherwise, every
│ │ │ │ │ - * rendering intent will be treated as a completely independent style.
│ │ │ │ │ - */
│ │ │ │ │ - extendDefault: true,
│ │ │ │ │ +OpenLayers.Easing.Quad = {
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constructor: OpenLayers.StyleMap
│ │ │ │ │ + * Function: easeIn
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * style - {Object} Optional. Either a style hash, or a style object, or
│ │ │ │ │ - * a hash of style objects (style hashes) keyed by rendering
│ │ │ │ │ - * intent. If just one style hash or style object is passed,
│ │ │ │ │ - * this will be used for all known render intents (default,
│ │ │ │ │ - * select, temporary)
│ │ │ │ │ - * options - {Object} optional hash of additional options for this
│ │ │ │ │ - * instance
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(style, options) {
│ │ │ │ │ - this.styles = {
│ │ │ │ │ - "default": new OpenLayers.Style(
│ │ │ │ │ - OpenLayers.Feature.Vector.style["default"]),
│ │ │ │ │ - "select": new OpenLayers.Style(
│ │ │ │ │ - OpenLayers.Feature.Vector.style["select"]),
│ │ │ │ │ - "temporary": new OpenLayers.Style(
│ │ │ │ │ - OpenLayers.Feature.Vector.style["temporary"]),
│ │ │ │ │ - "delete": new OpenLayers.Style(
│ │ │ │ │ - OpenLayers.Feature.Vector.style["delete"])
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - // take whatever the user passed as style parameter and convert it
│ │ │ │ │ - // into parts of stylemap.
│ │ │ │ │ - if (style instanceof OpenLayers.Style) {
│ │ │ │ │ - // user passed a style object
│ │ │ │ │ - this.styles["default"] = style;
│ │ │ │ │ - this.styles["select"] = style;
│ │ │ │ │ - this.styles["temporary"] = style;
│ │ │ │ │ - this.styles["delete"] = style;
│ │ │ │ │ - } else if (typeof style == "object") {
│ │ │ │ │ - for (var key in style) {
│ │ │ │ │ - if (style[key] instanceof OpenLayers.Style) {
│ │ │ │ │ - // user passed a hash of style objects
│ │ │ │ │ - this.styles[key] = style[key];
│ │ │ │ │ - } else if (typeof style[key] == "object") {
│ │ │ │ │ - // user passsed a hash of style hashes
│ │ │ │ │ - this.styles[key] = new OpenLayers.Style(style[key]);
│ │ │ │ │ - } else {
│ │ │ │ │ - // user passed a style hash (i.e. symbolizer)
│ │ │ │ │ - this.styles["default"] = new OpenLayers.Style(style);
│ │ │ │ │ - this.styles["select"] = new OpenLayers.Style(style);
│ │ │ │ │ - this.styles["temporary"] = new OpenLayers.Style(style);
│ │ │ │ │ - this.styles["delete"] = new OpenLayers.Style(style);
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - OpenLayers.Util.extend(this, options);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: destroy
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Float}
│ │ │ │ │ */
│ │ │ │ │ - destroy: function() {
│ │ │ │ │ - for (var key in this.styles) {
│ │ │ │ │ - this.styles[key].destroy();
│ │ │ │ │ - }
│ │ │ │ │ - this.styles = null;
│ │ │ │ │ + easeIn: function(t, b, c, d) {
│ │ │ │ │ + return c * (t /= d) * t + b;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: createSymbolizer
│ │ │ │ │ - * Creates the symbolizer for a feature for a render intent.
│ │ │ │ │ + * Function: easeOut
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * feature - {} The feature to evaluate the rules
│ │ │ │ │ - * of the intended style against.
│ │ │ │ │ - * intent - {String} The intent determines the symbolizer that will be
│ │ │ │ │ - * used to draw the feature. Well known intents are "default"
│ │ │ │ │ - * (for just drawing the features), "select" (for selected
│ │ │ │ │ - * features) and "temporary" (for drawing features).
│ │ │ │ │ - *
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Object} symbolizer hash
│ │ │ │ │ + * {Float}
│ │ │ │ │ */
│ │ │ │ │ - createSymbolizer: function(feature, intent) {
│ │ │ │ │ - if (!feature) {
│ │ │ │ │ - feature = new OpenLayers.Feature.Vector();
│ │ │ │ │ - }
│ │ │ │ │ - if (!this.styles[intent]) {
│ │ │ │ │ - intent = "default";
│ │ │ │ │ - }
│ │ │ │ │ - feature.renderIntent = intent;
│ │ │ │ │ - var defaultSymbolizer = {};
│ │ │ │ │ - if (this.extendDefault && intent != "default") {
│ │ │ │ │ - defaultSymbolizer = this.styles["default"].createSymbolizer(feature);
│ │ │ │ │ - }
│ │ │ │ │ - return OpenLayers.Util.extend(defaultSymbolizer,
│ │ │ │ │ - this.styles[intent].createSymbolizer(feature));
│ │ │ │ │ + easeOut: function(t, b, c, d) {
│ │ │ │ │ + return -c * (t /= d) * (t - 2) + b;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: addUniqueValueRules
│ │ │ │ │ - * Convenience method to create comparison rules for unique values of a
│ │ │ │ │ - * property. The rules will be added to the style object for a specified
│ │ │ │ │ - * rendering intent. This method is a shortcut for creating something like
│ │ │ │ │ - * the "unique value legends" familiar from well known desktop GIS systems
│ │ │ │ │ + * Function: easeInOut
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * renderIntent - {String} rendering intent to add the rules to
│ │ │ │ │ - * property - {String} values of feature attributes to create the
│ │ │ │ │ - * rules for
│ │ │ │ │ - * symbolizers - {Object} Hash of symbolizers, keyed by the desired
│ │ │ │ │ - * property values
│ │ │ │ │ - * context - {Object} An optional object with properties that
│ │ │ │ │ - * symbolizers' property values should be evaluated
│ │ │ │ │ - * against. If no context is specified, feature.attributes
│ │ │ │ │ - * will be used
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Float}
│ │ │ │ │ */
│ │ │ │ │ - addUniqueValueRules: function(renderIntent, property, symbolizers, context) {
│ │ │ │ │ - var rules = [];
│ │ │ │ │ - for (var value in symbolizers) {
│ │ │ │ │ - rules.push(new OpenLayers.Rule({
│ │ │ │ │ - symbolizer: symbolizers[value],
│ │ │ │ │ - context: context,
│ │ │ │ │ - filter: new OpenLayers.Filter.Comparison({
│ │ │ │ │ - type: OpenLayers.Filter.Comparison.EQUAL_TO,
│ │ │ │ │ - property: property,
│ │ │ │ │ - value: value
│ │ │ │ │ - })
│ │ │ │ │ - }));
│ │ │ │ │ - }
│ │ │ │ │ - this.styles[renderIntent].addRules(rules);
│ │ │ │ │ + easeInOut: function(t, b, c, d) {
│ │ │ │ │ + if ((t /= d / 2) < 1) return c / 2 * t * t + b;
│ │ │ │ │ + return -c / 2 * ((--t) * (t - 2) - 1) + b;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.StyleMap"
│ │ │ │ │ -});
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Easing.Quad"
│ │ │ │ │ +};
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Rule.js
│ │ │ │ │ + OpenLayers/Projection.js
│ │ │ │ │ ====================================================================== */
│ │ │ │ │
│ │ │ │ │ /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ * full text of the license. */
│ │ │ │ │
│ │ │ │ │ -
│ │ │ │ │ /**
│ │ │ │ │ * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ * @requires OpenLayers/Util.js
│ │ │ │ │ - * @requires OpenLayers/Style.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Class: OpenLayers.Rule
│ │ │ │ │ - * This class represents an SLD Rule, as being used for rule-based SLD styling.
│ │ │ │ │ + * Namespace: OpenLayers.Projection
│ │ │ │ │ + * Methods for coordinate transforms between coordinate systems. By default,
│ │ │ │ │ + * OpenLayers ships with the ability to transform coordinates between
│ │ │ │ │ + * geographic (EPSG:4326) and web or spherical mercator (EPSG:900913 et al.)
│ │ │ │ │ + * coordinate reference systems. See the method for details
│ │ │ │ │ + * on usage.
│ │ │ │ │ + *
│ │ │ │ │ + * Additional transforms may be added by using the
│ │ │ │ │ + * library. If the proj4js library is included, the method
│ │ │ │ │ + * will work between any two coordinate reference systems with proj4js
│ │ │ │ │ + * definitions.
│ │ │ │ │ + *
│ │ │ │ │ + * If the proj4js library is not included, or if you wish to allow transforms
│ │ │ │ │ + * between arbitrary coordinate reference systems, use the
│ │ │ │ │ + * method to register a custom transform method.
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Rule = OpenLayers.Class({
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: id
│ │ │ │ │ - * {String} A unique id for this session.
│ │ │ │ │ - */
│ │ │ │ │ - id: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: name
│ │ │ │ │ - * {String} name of this rule
│ │ │ │ │ - */
│ │ │ │ │ - name: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: title
│ │ │ │ │ - * {String} Title of this rule (set if included in SLD)
│ │ │ │ │ - */
│ │ │ │ │ - title: null,
│ │ │ │ │ +OpenLayers.Projection = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: description
│ │ │ │ │ - * {String} Description of this rule (set if abstract is included in SLD)
│ │ │ │ │ + * Property: proj
│ │ │ │ │ + * {Object} Proj4js.Proj instance.
│ │ │ │ │ */
│ │ │ │ │ - description: null,
│ │ │ │ │ + proj: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: context
│ │ │ │ │ - * {Object} An optional object with properties that the rule should be
│ │ │ │ │ - * evaluated against. If no context is specified, feature.attributes will
│ │ │ │ │ - * be used.
│ │ │ │ │ + * Property: projCode
│ │ │ │ │ + * {String}
│ │ │ │ │ */
│ │ │ │ │ - context: null,
│ │ │ │ │ + projCode: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: filter
│ │ │ │ │ - * {} Optional filter for the rule.
│ │ │ │ │ + * Property: titleRegEx
│ │ │ │ │ + * {RegExp} regular expression to strip the title from a proj4js definition
│ │ │ │ │ */
│ │ │ │ │ - filter: null,
│ │ │ │ │ + titleRegEx: /\+title=[^\+]*/,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: elseFilter
│ │ │ │ │ - * {Boolean} Determines whether this rule is only to be applied only if
│ │ │ │ │ - * no other rules match (ElseFilter according to the SLD specification).
│ │ │ │ │ - * Default is false. For instances of OpenLayers.Rule, if elseFilter is
│ │ │ │ │ - * false, the rule will always apply. For subclasses, the else property is
│ │ │ │ │ - * ignored.
│ │ │ │ │ + * Constructor: OpenLayers.Projection
│ │ │ │ │ + * This class offers several methods for interacting with a wrapped
│ │ │ │ │ + * pro4js projection object.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * projCode - {String} A string identifying the Well Known Identifier for
│ │ │ │ │ + * the projection.
│ │ │ │ │ + * options - {Object} An optional object to set additional properties
│ │ │ │ │ + * on the projection.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {} A projection object.
│ │ │ │ │ */
│ │ │ │ │ - elseFilter: false,
│ │ │ │ │ + initialize: function(projCode, options) {
│ │ │ │ │ + OpenLayers.Util.extend(this, options);
│ │ │ │ │ + this.projCode = projCode;
│ │ │ │ │ + if (typeof Proj4js == "object") {
│ │ │ │ │ + this.proj = new Proj4js.Proj(projCode);
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: symbolizer
│ │ │ │ │ - * {Object} Symbolizer or hash of symbolizers for this rule. If hash of
│ │ │ │ │ - * symbolizers, keys are one or more of ["Point", "Line", "Polygon"]. The
│ │ │ │ │ - * latter if useful if it is required to style e.g. vertices of a line
│ │ │ │ │ - * with a point symbolizer. Note, however, that this is not implemented
│ │ │ │ │ - * yet in OpenLayers, but it is the way how symbolizers are defined in
│ │ │ │ │ - * SLD.
│ │ │ │ │ + * APIMethod: getCode
│ │ │ │ │ + * Get the string SRS code.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {String} The SRS code.
│ │ │ │ │ */
│ │ │ │ │ - symbolizer: null,
│ │ │ │ │ + getCode: function() {
│ │ │ │ │ + return this.proj ? this.proj.srsCode : this.projCode;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: symbolizers
│ │ │ │ │ - * {Array} Collection of symbolizers associated with this rule. If
│ │ │ │ │ - * provided at construction, the symbolizers array has precedence
│ │ │ │ │ - * over the deprecated symbolizer property. Note that multiple
│ │ │ │ │ - * symbolizers are not currently supported by the vector renderers.
│ │ │ │ │ - * Rules with multiple symbolizers are currently only useful for
│ │ │ │ │ - * maintaining elements in an SLD document.
│ │ │ │ │ + * APIMethod: getUnits
│ │ │ │ │ + * Get the units string for the projection -- returns null if
│ │ │ │ │ + * proj4js is not available.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {String} The units abbreviation.
│ │ │ │ │ */
│ │ │ │ │ - symbolizers: null,
│ │ │ │ │ + getUnits: function() {
│ │ │ │ │ + return this.proj ? this.proj.units : null;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: minScaleDenominator
│ │ │ │ │ - * {Number} or {String} minimum scale at which to draw the feature.
│ │ │ │ │ - * In the case of a String, this can be a combination of text and
│ │ │ │ │ - * propertyNames in the form "literal ${propertyName}"
│ │ │ │ │ + * Method: toString
│ │ │ │ │ + * Convert projection to string (getCode wrapper).
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {String} The projection code.
│ │ │ │ │ */
│ │ │ │ │ - minScaleDenominator: null,
│ │ │ │ │ + toString: function() {
│ │ │ │ │ + return this.getCode();
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: maxScaleDenominator
│ │ │ │ │ - * {Number} or {String} maximum scale at which to draw the feature.
│ │ │ │ │ - * In the case of a String, this can be a combination of text and
│ │ │ │ │ - * propertyNames in the form "literal ${propertyName}"
│ │ │ │ │ - */
│ │ │ │ │ - maxScaleDenominator: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Rule
│ │ │ │ │ - * Creates a Rule.
│ │ │ │ │ + * Method: equals
│ │ │ │ │ + * Test equality of two projection instances. Determines equality based
│ │ │ │ │ + * soley on the projection code.
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * options - {Object} An optional object with properties to set on the
│ │ │ │ │ - * rule
│ │ │ │ │ - *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {}
│ │ │ │ │ + * {Boolean} The two projections are equivalent.
│ │ │ │ │ */
│ │ │ │ │ - initialize: function(options) {
│ │ │ │ │ - this.symbolizer = {};
│ │ │ │ │ - OpenLayers.Util.extend(this, options);
│ │ │ │ │ - if (this.symbolizers) {
│ │ │ │ │ - delete this.symbolizer;
│ │ │ │ │ + equals: function(projection) {
│ │ │ │ │ + var p = projection,
│ │ │ │ │ + equals = false;
│ │ │ │ │ + if (p) {
│ │ │ │ │ + if (!(p instanceof OpenLayers.Projection)) {
│ │ │ │ │ + p = new OpenLayers.Projection(p);
│ │ │ │ │ + }
│ │ │ │ │ + if ((typeof Proj4js == "object") && this.proj.defData && p.proj.defData) {
│ │ │ │ │ + equals = this.proj.defData.replace(this.titleRegEx, "") ==
│ │ │ │ │ + p.proj.defData.replace(this.titleRegEx, "");
│ │ │ │ │ + } else if (p.getCode) {
│ │ │ │ │ + var source = this.getCode(),
│ │ │ │ │ + target = p.getCode();
│ │ │ │ │ + equals = source == target ||
│ │ │ │ │ + !!OpenLayers.Projection.transforms[source] &&
│ │ │ │ │ + OpenLayers.Projection.transforms[source][target] ===
│ │ │ │ │ + OpenLayers.Projection.nullTransform;
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ - this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
│ │ │ │ │ + return equals;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: destroy
│ │ │ │ │ - * nullify references to prevent circular references and memory leaks
│ │ │ │ │ - */
│ │ │ │ │ - destroy: function() {
│ │ │ │ │ - for (var i in this.symbolizer) {
│ │ │ │ │ - this.symbolizer[i] = null;
│ │ │ │ │ - }
│ │ │ │ │ - this.symbolizer = null;
│ │ │ │ │ - delete this.symbolizers;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: evaluate
│ │ │ │ │ - * evaluates this rule for a specific feature
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * feature - {} feature to apply the rule to.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} true if the rule applies, false if it does not.
│ │ │ │ │ - * This rule is the default rule and always returns true.
│ │ │ │ │ - */
│ │ │ │ │ - evaluate: function(feature) {
│ │ │ │ │ - var context = this.getContext(feature);
│ │ │ │ │ - var applies = true;
│ │ │ │ │ -
│ │ │ │ │ - if (this.minScaleDenominator || this.maxScaleDenominator) {
│ │ │ │ │ - var scale = feature.layer.map.getScale();
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // check if within minScale/maxScale bounds
│ │ │ │ │ - if (this.minScaleDenominator) {
│ │ │ │ │ - applies = scale >= OpenLayers.Style.createLiteral(
│ │ │ │ │ - this.minScaleDenominator, context);
│ │ │ │ │ - }
│ │ │ │ │ - if (applies && this.maxScaleDenominator) {
│ │ │ │ │ - applies = scale < OpenLayers.Style.createLiteral(
│ │ │ │ │ - this.maxScaleDenominator, context);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // check if optional filter applies
│ │ │ │ │ - if (applies && this.filter) {
│ │ │ │ │ - // feature id filters get the feature, others get the context
│ │ │ │ │ - if (this.filter.CLASS_NAME == "OpenLayers.Filter.FeatureId") {
│ │ │ │ │ - applies = this.filter.evaluate(feature);
│ │ │ │ │ - } else {
│ │ │ │ │ - applies = this.filter.evaluate(context);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - return applies;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: getContext
│ │ │ │ │ - * Gets the context for evaluating this rule
│ │ │ │ │ - *
│ │ │ │ │ - * Paramters:
│ │ │ │ │ - * feature - {} feature to take the context from if
│ │ │ │ │ - * none is specified.
│ │ │ │ │ - */
│ │ │ │ │ - getContext: function(feature) {
│ │ │ │ │ - var context = this.context;
│ │ │ │ │ - if (!context) {
│ │ │ │ │ - context = feature.attributes || feature.data;
│ │ │ │ │ - }
│ │ │ │ │ - if (typeof this.context == "function") {
│ │ │ │ │ - context = this.context(feature);
│ │ │ │ │ - }
│ │ │ │ │ - return context;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: clone
│ │ │ │ │ - * Clones this rule.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} Clone of this rule.
│ │ │ │ │ - */
│ │ │ │ │ - clone: function() {
│ │ │ │ │ - var options = OpenLayers.Util.extend({}, this);
│ │ │ │ │ - if (this.symbolizers) {
│ │ │ │ │ - // clone symbolizers
│ │ │ │ │ - var len = this.symbolizers.length;
│ │ │ │ │ - options.symbolizers = new Array(len);
│ │ │ │ │ - for (var i = 0; i < len; ++i) {
│ │ │ │ │ - options.symbolizers[i] = this.symbolizers[i].clone();
│ │ │ │ │ - }
│ │ │ │ │ - } else {
│ │ │ │ │ - // clone symbolizer
│ │ │ │ │ - options.symbolizer = {};
│ │ │ │ │ - var value, type;
│ │ │ │ │ - for (var key in this.symbolizer) {
│ │ │ │ │ - value = this.symbolizer[key];
│ │ │ │ │ - type = typeof value;
│ │ │ │ │ - if (type === "object") {
│ │ │ │ │ - options.symbolizer[key] = OpenLayers.Util.extend({}, value);
│ │ │ │ │ - } else if (type === "string") {
│ │ │ │ │ - options.symbolizer[key] = value;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - // clone filter
│ │ │ │ │ - options.filter = this.filter && this.filter.clone();
│ │ │ │ │ - // clone context
│ │ │ │ │ - options.context = this.context && OpenLayers.Util.extend({}, this.context);
│ │ │ │ │ - return new OpenLayers.Rule(options);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Rule"
│ │ │ │ │ -});
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Symbolizer/Point.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/Symbolizer.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Symbolizer.Point
│ │ │ │ │ - * A symbolizer used to render point features.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Symbolizer.Point = OpenLayers.Class(OpenLayers.Symbolizer, {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: strokeColor
│ │ │ │ │ - * {String} Color for line stroke. This is a RGB hex value (e.g. "#ff0000"
│ │ │ │ │ - * for red).
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: strokeOpacity
│ │ │ │ │ - * {Number} Stroke opacity (0-1).
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: strokeWidth
│ │ │ │ │ - * {Number} Pixel stroke width.
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: strokeLinecap
│ │ │ │ │ - * {String} Stroke cap type ("butt", "round", or "square").
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: strokeDashstyle
│ │ │ │ │ - * {String} Stroke dash style according to the SLD spec. Note that the
│ │ │ │ │ - * OpenLayers values for strokeDashstyle ("dot", "dash", "dashdot",
│ │ │ │ │ - * "longdash", "longdashdot", or "solid") will not work in SLD, but
│ │ │ │ │ - * most SLD patterns will render correctly in OpenLayers.
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: fillColor
│ │ │ │ │ - * {String} RGB hex fill color (e.g. "#ff0000" for red).
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: fillOpacity
│ │ │ │ │ - * {Number} Fill opacity (0-1).
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: pointRadius
│ │ │ │ │ - * {Number} Pixel point radius.
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: externalGraphic
│ │ │ │ │ - * {String} Url to an external graphic that will be used for rendering
│ │ │ │ │ - * points.
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: graphicWidth
│ │ │ │ │ - * {Number} Pixel width for sizing an external graphic.
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: graphicHeight
│ │ │ │ │ - * {Number} Pixel height for sizing an external graphic.
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: graphicOpacity
│ │ │ │ │ - * {Number} Opacity (0-1) for an external graphic.
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: graphicXOffset
│ │ │ │ │ - * {Number} Pixel offset along the positive x axis for displacing an
│ │ │ │ │ - * external graphic.
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: graphicYOffset
│ │ │ │ │ - * {Number} Pixel offset along the positive y axis for displacing an
│ │ │ │ │ - * external graphic.
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: rotation
│ │ │ │ │ - * {Number} The rotation of a graphic in the clockwise direction about its
│ │ │ │ │ - * center point (or any point off center as specified by
│ │ │ │ │ - * and ).
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: graphicName
│ │ │ │ │ - * {String} Named graphic to use when rendering points. Supported values
│ │ │ │ │ - * include "circle", "square", "star", "x", "cross", and "triangle".
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Symbolizer.Point
│ │ │ │ │ - * Create a symbolizer for rendering points.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * config - {Object} An object containing properties to be set on the
│ │ │ │ │ - * symbolizer. Any documented symbolizer property can be set at
│ │ │ │ │ - * construction.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * A new point symbolizer.
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(config) {
│ │ │ │ │ - OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Symbolizer.Point"
│ │ │ │ │ -
│ │ │ │ │ -});
│ │ │ │ │ -
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Symbolizer/Line.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/Symbolizer.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Symbolizer.Line
│ │ │ │ │ - * A symbolizer used to render line features.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Symbolizer.Line = OpenLayers.Class(OpenLayers.Symbolizer, {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: strokeColor
│ │ │ │ │ - * {String} Color for line stroke. This is a RGB hex value (e.g. "#ff0000"
│ │ │ │ │ - * for red).
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: strokeOpacity
│ │ │ │ │ - * {Number} Stroke opacity (0-1).
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: strokeWidth
│ │ │ │ │ - * {Number} Pixel stroke width.
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: strokeLinecap
│ │ │ │ │ - * {String} Stroke cap type ("butt", "round", or "square").
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: strokeDashstyle
│ │ │ │ │ - * {String} Stroke dash style according to the SLD spec. Note that the
│ │ │ │ │ - * OpenLayers values for strokeDashstyle ("dot", "dash", "dashdot",
│ │ │ │ │ - * "longdash", "longdashdot", or "solid") will not work in SLD, but
│ │ │ │ │ - * most SLD patterns will render correctly in OpenLayers.
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Symbolizer.Line
│ │ │ │ │ - * Create a symbolizer for rendering lines.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * config - {Object} An object containing properties to be set on the
│ │ │ │ │ - * symbolizer. Any documented symbolizer property can be set at
│ │ │ │ │ - * construction.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * A new line symbolizer.
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(config) {
│ │ │ │ │ - OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Symbolizer.Line"
│ │ │ │ │ -
│ │ │ │ │ -});
│ │ │ │ │ -
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Symbolizer/Polygon.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/Symbolizer.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Symbolizer.Polygon
│ │ │ │ │ - * A symbolizer used to render line features.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Symbolizer.Polygon = OpenLayers.Class(OpenLayers.Symbolizer, {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: strokeColor
│ │ │ │ │ - * {String} Color for line stroke. This is a RGB hex value (e.g. "#ff0000"
│ │ │ │ │ - * for red).
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: strokeOpacity
│ │ │ │ │ - * {Number} Stroke opacity (0-1).
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: strokeWidth
│ │ │ │ │ - * {Number} Pixel stroke width.
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: strokeLinecap
│ │ │ │ │ - * {String} Stroke cap type ("butt", "round", or "square").
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: strokeDashstyle
│ │ │ │ │ - * {String} Stroke dash style according to the SLD spec. Note that the
│ │ │ │ │ - * OpenLayers values for strokeDashstyle ("dot", "dash", "dashdot",
│ │ │ │ │ - * "longdash", "longdashdot", or "solid") will not work in SLD, but
│ │ │ │ │ - * most SLD patterns will render correctly in OpenLayers.
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: fillColor
│ │ │ │ │ - * {String} RGB hex fill color (e.g. "#ff0000" for red).
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: fillOpacity
│ │ │ │ │ - * {Number} Fill opacity (0-1).
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Symbolizer.Polygon
│ │ │ │ │ - * Create a symbolizer for rendering polygons.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * config - {Object} An object containing properties to be set on the
│ │ │ │ │ - * symbolizer. Any documented symbolizer property can be set at
│ │ │ │ │ - * construction.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * A new polygon symbolizer.
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(config) {
│ │ │ │ │ - OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Symbolizer.Polygon"
│ │ │ │ │ -
│ │ │ │ │ -});
│ │ │ │ │ -
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Symbolizer/Text.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/Symbolizer.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Symbolizer.Text
│ │ │ │ │ - * A symbolizer used to render text labels for features.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Symbolizer.Text = OpenLayers.Class(OpenLayers.Symbolizer, {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: label
│ │ │ │ │ - * {String} The text for the label.
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: fontFamily
│ │ │ │ │ - * {String} The font family for the label.
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: fontSize
│ │ │ │ │ - * {String} The font size for the label.
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: fontWeight
│ │ │ │ │ - * {String} The font weight for the label.
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: fontStyle
│ │ │ │ │ - * {String} The font style for the label.
│ │ │ │ │ - *
│ │ │ │ │ - * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Symbolizer.Text
│ │ │ │ │ - * Create a symbolizer for rendering text labels.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * config - {Object} An object containing properties to be set on the
│ │ │ │ │ - * symbolizer. Any documented symbolizer property can be set at
│ │ │ │ │ - * construction.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * A new text symbolizer.
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(config) {
│ │ │ │ │ - OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Symbolizer.Text"
│ │ │ │ │ -
│ │ │ │ │ -});
│ │ │ │ │ -
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Symbolizer/Raster.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/Symbolizer.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Symbolizer.Raster
│ │ │ │ │ - * A symbolizer used to render raster images.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Symbolizer.Raster = OpenLayers.Class(OpenLayers.Symbolizer, {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Symbolizer.Raster
│ │ │ │ │ - * Create a symbolizer for rendering rasters.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * config - {Object} An object containing properties to be set on the
│ │ │ │ │ - * symbolizer. Any documented symbolizer property can be set at
│ │ │ │ │ - * construction.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * A new raster symbolizer.
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(config) {
│ │ │ │ │ - OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Symbolizer.Raster"
│ │ │ │ │ -
│ │ │ │ │ -});
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Style2.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ - * @requires OpenLayers/Rule.js
│ │ │ │ │ - * @requires OpenLayers/Symbolizer/Point.js
│ │ │ │ │ - * @requires OpenLayers/Symbolizer/Line.js
│ │ │ │ │ - * @requires OpenLayers/Symbolizer/Polygon.js
│ │ │ │ │ - * @requires OpenLayers/Symbolizer/Text.js
│ │ │ │ │ - * @requires OpenLayers/Symbolizer/Raster.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Style2
│ │ │ │ │ - * This class represents a collection of rules for rendering features.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Style2 = OpenLayers.Class({
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: id
│ │ │ │ │ - * {String} A unique id for this session.
│ │ │ │ │ - */
│ │ │ │ │ - id: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: name
│ │ │ │ │ - * {String} Style identifier.
│ │ │ │ │ - */
│ │ │ │ │ - name: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: title
│ │ │ │ │ - * {String} Title of this style.
│ │ │ │ │ - */
│ │ │ │ │ - title: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: description
│ │ │ │ │ - * {String} Description of this style.
│ │ │ │ │ - */
│ │ │ │ │ - description: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: layerName
│ │ │ │ │ - * {} Name of the layer that this style belongs to, usually
│ │ │ │ │ - * according to the NamedLayer attribute of an SLD document.
│ │ │ │ │ - */
│ │ │ │ │ - layerName: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: isDefault
│ │ │ │ │ - * {Boolean}
│ │ │ │ │ - */
│ │ │ │ │ - isDefault: false,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: rules
│ │ │ │ │ - * {Array()} Collection of rendering rules.
│ │ │ │ │ - */
│ │ │ │ │ - rules: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Style2
│ │ │ │ │ - * Creates a style representing a collection of rendering rules.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * config - {Object} An object containing properties to be set on the
│ │ │ │ │ - * style. Any documented properties may be set at construction.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} A new style object.
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(config) {
│ │ │ │ │ - OpenLayers.Util.extend(this, config);
│ │ │ │ │ - this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: destroy
│ │ │ │ │ - * nullify references to prevent circular references and memory leaks
│ │ │ │ │ - */
│ │ │ │ │ - destroy: function() {
│ │ │ │ │ - for (var i = 0, len = this.rules.length; i < len; i++) {
│ │ │ │ │ - this.rules[i].destroy();
│ │ │ │ │ - }
│ │ │ │ │ - delete this.rules;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: clone
│ │ │ │ │ - * Clones this style.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} Clone of this style.
│ │ │ │ │ - */
│ │ │ │ │ - clone: function() {
│ │ │ │ │ - var config = OpenLayers.Util.extend({}, this);
│ │ │ │ │ - // clone rules
│ │ │ │ │ - if (this.rules) {
│ │ │ │ │ - config.rules = [];
│ │ │ │ │ - for (var i = 0, len = this.rules.length; i < len; ++i) {
│ │ │ │ │ - config.rules.push(this.rules[i].clone());
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return new OpenLayers.Style2(config);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Style2"
│ │ │ │ │ -});
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Projection.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ - * @requires OpenLayers/Util.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Namespace: OpenLayers.Projection
│ │ │ │ │ - * Methods for coordinate transforms between coordinate systems. By default,
│ │ │ │ │ - * OpenLayers ships with the ability to transform coordinates between
│ │ │ │ │ - * geographic (EPSG:4326) and web or spherical mercator (EPSG:900913 et al.)
│ │ │ │ │ - * coordinate reference systems. See the method for details
│ │ │ │ │ - * on usage.
│ │ │ │ │ - *
│ │ │ │ │ - * Additional transforms may be added by using the
│ │ │ │ │ - * library. If the proj4js library is included, the method
│ │ │ │ │ - * will work between any two coordinate reference systems with proj4js
│ │ │ │ │ - * definitions.
│ │ │ │ │ - *
│ │ │ │ │ - * If the proj4js library is not included, or if you wish to allow transforms
│ │ │ │ │ - * between arbitrary coordinate reference systems, use the
│ │ │ │ │ - * method to register a custom transform method.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Projection = OpenLayers.Class({
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: proj
│ │ │ │ │ - * {Object} Proj4js.Proj instance.
│ │ │ │ │ - */
│ │ │ │ │ - proj: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: projCode
│ │ │ │ │ - * {String}
│ │ │ │ │ - */
│ │ │ │ │ - projCode: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: titleRegEx
│ │ │ │ │ - * {RegExp} regular expression to strip the title from a proj4js definition
│ │ │ │ │ - */
│ │ │ │ │ - titleRegEx: /\+title=[^\+]*/,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Projection
│ │ │ │ │ - * This class offers several methods for interacting with a wrapped
│ │ │ │ │ - * pro4js projection object.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * projCode - {String} A string identifying the Well Known Identifier for
│ │ │ │ │ - * the projection.
│ │ │ │ │ - * options - {Object} An optional object to set additional properties
│ │ │ │ │ - * on the projection.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} A projection object.
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(projCode, options) {
│ │ │ │ │ - OpenLayers.Util.extend(this, options);
│ │ │ │ │ - this.projCode = projCode;
│ │ │ │ │ - if (typeof Proj4js == "object") {
│ │ │ │ │ - this.proj = new Proj4js.Proj(projCode);
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: getCode
│ │ │ │ │ - * Get the string SRS code.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} The SRS code.
│ │ │ │ │ - */
│ │ │ │ │ - getCode: function() {
│ │ │ │ │ - return this.proj ? this.proj.srsCode : this.projCode;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: getUnits
│ │ │ │ │ - * Get the units string for the projection -- returns null if
│ │ │ │ │ - * proj4js is not available.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} The units abbreviation.
│ │ │ │ │ - */
│ │ │ │ │ - getUnits: function() {
│ │ │ │ │ - return this.proj ? this.proj.units : null;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: toString
│ │ │ │ │ - * Convert projection to string (getCode wrapper).
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} The projection code.
│ │ │ │ │ - */
│ │ │ │ │ - toString: function() {
│ │ │ │ │ - return this.getCode();
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: equals
│ │ │ │ │ - * Test equality of two projection instances. Determines equality based
│ │ │ │ │ - * soley on the projection code.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} The two projections are equivalent.
│ │ │ │ │ - */
│ │ │ │ │ - equals: function(projection) {
│ │ │ │ │ - var p = projection,
│ │ │ │ │ - equals = false;
│ │ │ │ │ - if (p) {
│ │ │ │ │ - if (!(p instanceof OpenLayers.Projection)) {
│ │ │ │ │ - p = new OpenLayers.Projection(p);
│ │ │ │ │ - }
│ │ │ │ │ - if ((typeof Proj4js == "object") && this.proj.defData && p.proj.defData) {
│ │ │ │ │ - equals = this.proj.defData.replace(this.titleRegEx, "") ==
│ │ │ │ │ - p.proj.defData.replace(this.titleRegEx, "");
│ │ │ │ │ - } else if (p.getCode) {
│ │ │ │ │ - var source = this.getCode(),
│ │ │ │ │ - target = p.getCode();
│ │ │ │ │ - equals = source == target ||
│ │ │ │ │ - !!OpenLayers.Projection.transforms[source] &&
│ │ │ │ │ - OpenLayers.Projection.transforms[source][target] ===
│ │ │ │ │ - OpenLayers.Projection.nullTransform;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return equals;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /* Method: destroy
│ │ │ │ │ - * Destroy projection object.
│ │ │ │ │ + /* Method: destroy
│ │ │ │ │ + * Destroy projection object.
│ │ │ │ │ */
│ │ │ │ │ destroy: function() {
│ │ │ │ │ delete this.proj;
│ │ │ │ │ delete this.projCode;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ CLASS_NAME: "OpenLayers.Projection"
│ │ │ │ │ @@ -7630,2244 +6542,14 @@
│ │ │ │ │ }
│ │ │ │ │ for (i = geographic.length - 1; i >= 0; --i) {
│ │ │ │ │ map(geographic[i], mercator);
│ │ │ │ │ }
│ │ │ │ │
│ │ │ │ │ })();
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Renderer.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Renderer
│ │ │ │ │ - * This is the base class for all renderers.
│ │ │ │ │ - *
│ │ │ │ │ - * This is based on a merger code written by Paul Spencer and Bertil Chapuis.
│ │ │ │ │ - * It is largely composed of virtual functions that are to be implemented
│ │ │ │ │ - * in technology-specific subclasses, but there is some generic code too.
│ │ │ │ │ - *
│ │ │ │ │ - * The functions that *are* implemented here merely deal with the maintenance
│ │ │ │ │ - * of the size and extent variables, as well as the cached 'resolution'
│ │ │ │ │ - * value.
│ │ │ │ │ - *
│ │ │ │ │ - * A note to the user that all subclasses should use getResolution() instead
│ │ │ │ │ - * of directly accessing this.resolution in order to correctly use the
│ │ │ │ │ - * cacheing system.
│ │ │ │ │ - *
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Renderer = OpenLayers.Class({
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: container
│ │ │ │ │ - * {DOMElement}
│ │ │ │ │ - */
│ │ │ │ │ - container: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: root
│ │ │ │ │ - * {DOMElement}
│ │ │ │ │ - */
│ │ │ │ │ - root: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: extent
│ │ │ │ │ - * {}
│ │ │ │ │ - */
│ │ │ │ │ - extent: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: locked
│ │ │ │ │ - * {Boolean} If the renderer is currently in a state where many things
│ │ │ │ │ - * are changing, the 'locked' property is set to true. This means
│ │ │ │ │ - * that renderers can expect at least one more drawFeature event to be
│ │ │ │ │ - * called with the 'locked' property set to 'true': In some renderers,
│ │ │ │ │ - * this might make sense to use as a 'only update local information'
│ │ │ │ │ - * flag.
│ │ │ │ │ - */
│ │ │ │ │ - locked: false,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: size
│ │ │ │ │ - * {}
│ │ │ │ │ - */
│ │ │ │ │ - size: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: resolution
│ │ │ │ │ - * {Float} cache of current map resolution
│ │ │ │ │ - */
│ │ │ │ │ - resolution: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: map
│ │ │ │ │ - * {} Reference to the map -- this is set in Vector's setMap()
│ │ │ │ │ - */
│ │ │ │ │ - map: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: featureDx
│ │ │ │ │ - * {Number} Feature offset in x direction. Will be calculated for and
│ │ │ │ │ - * applied to the current feature while rendering (see
│ │ │ │ │ - * ).
│ │ │ │ │ - */
│ │ │ │ │ - featureDx: 0,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Renderer
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * containerID - {}
│ │ │ │ │ - * options - {Object} options for this renderer. See sublcasses for
│ │ │ │ │ - * supported options.
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(containerID, options) {
│ │ │ │ │ - this.container = OpenLayers.Util.getElement(containerID);
│ │ │ │ │ - OpenLayers.Util.extend(this, options);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: destroy
│ │ │ │ │ - */
│ │ │ │ │ - destroy: function() {
│ │ │ │ │ - this.container = null;
│ │ │ │ │ - this.extent = null;
│ │ │ │ │ - this.size = null;
│ │ │ │ │ - this.resolution = null;
│ │ │ │ │ - this.map = null;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: supported
│ │ │ │ │ - * This should be overridden by specific subclasses
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} Whether or not the browser supports the renderer class
│ │ │ │ │ - */
│ │ │ │ │ - supported: function() {
│ │ │ │ │ - return false;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: setExtent
│ │ │ │ │ - * Set the visible part of the layer.
│ │ │ │ │ - *
│ │ │ │ │ - * Resolution has probably changed, so we nullify the resolution
│ │ │ │ │ - * cache (this.resolution) -- this way it will be re-computed when
│ │ │ │ │ - * next it is needed.
│ │ │ │ │ - * We nullify the resolution cache (this.resolution) if resolutionChanged
│ │ │ │ │ - * is set to true - this way it will be re-computed on the next
│ │ │ │ │ - * getResolution() request.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * extent - {}
│ │ │ │ │ - * resolutionChanged - {Boolean}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} true to notify the layer that the new extent does not exceed
│ │ │ │ │ - * the coordinate range, and the features will not need to be redrawn.
│ │ │ │ │ - * False otherwise.
│ │ │ │ │ - */
│ │ │ │ │ - setExtent: function(extent, resolutionChanged) {
│ │ │ │ │ - this.extent = extent.clone();
│ │ │ │ │ - if (this.map.baseLayer && this.map.baseLayer.wrapDateLine) {
│ │ │ │ │ - var ratio = extent.getWidth() / this.map.getExtent().getWidth(),
│ │ │ │ │ - extent = extent.scale(1 / ratio);
│ │ │ │ │ - this.extent = extent.wrapDateLine(this.map.getMaxExtent()).scale(ratio);
│ │ │ │ │ - }
│ │ │ │ │ - if (resolutionChanged) {
│ │ │ │ │ - this.resolution = null;
│ │ │ │ │ - }
│ │ │ │ │ - return true;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: setSize
│ │ │ │ │ - * Sets the size of the drawing surface.
│ │ │ │ │ - *
│ │ │ │ │ - * Resolution has probably changed, so we nullify the resolution
│ │ │ │ │ - * cache (this.resolution) -- this way it will be re-computed when
│ │ │ │ │ - * next it is needed.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * size - {}
│ │ │ │ │ - */
│ │ │ │ │ - setSize: function(size) {
│ │ │ │ │ - this.size = size.clone();
│ │ │ │ │ - this.resolution = null;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: getResolution
│ │ │ │ │ - * Uses cached copy of resolution if available to minimize computing
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Float} The current map's resolution
│ │ │ │ │ - */
│ │ │ │ │ - getResolution: function() {
│ │ │ │ │ - this.resolution = this.resolution || this.map.getResolution();
│ │ │ │ │ - return this.resolution;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: drawFeature
│ │ │ │ │ - * Draw the feature. The optional style argument can be used
│ │ │ │ │ - * to override the feature's own style. This method should only
│ │ │ │ │ - * be called from layer.drawFeature().
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * feature - {}
│ │ │ │ │ - * style - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} true if the feature has been drawn completely, false if not,
│ │ │ │ │ - * undefined if the feature had no geometry
│ │ │ │ │ - */
│ │ │ │ │ - drawFeature: function(feature, style) {
│ │ │ │ │ - if (style == null) {
│ │ │ │ │ - style = feature.style;
│ │ │ │ │ - }
│ │ │ │ │ - if (feature.geometry) {
│ │ │ │ │ - var bounds = feature.geometry.getBounds();
│ │ │ │ │ - if (bounds) {
│ │ │ │ │ - var worldBounds;
│ │ │ │ │ - if (this.map.baseLayer && this.map.baseLayer.wrapDateLine) {
│ │ │ │ │ - worldBounds = this.map.getMaxExtent();
│ │ │ │ │ - }
│ │ │ │ │ - if (!bounds.intersectsBounds(this.extent, {
│ │ │ │ │ - worldBounds: worldBounds
│ │ │ │ │ - })) {
│ │ │ │ │ - style = {
│ │ │ │ │ - display: "none"
│ │ │ │ │ - };
│ │ │ │ │ - } else {
│ │ │ │ │ - this.calculateFeatureDx(bounds, worldBounds);
│ │ │ │ │ - }
│ │ │ │ │ - var rendered = this.drawGeometry(feature.geometry, style, feature.id);
│ │ │ │ │ - if (style.display != "none" && style.label && rendered !== false) {
│ │ │ │ │ -
│ │ │ │ │ - var location = feature.geometry.getCentroid();
│ │ │ │ │ - if (style.labelXOffset || style.labelYOffset) {
│ │ │ │ │ - var xOffset = isNaN(style.labelXOffset) ? 0 : style.labelXOffset;
│ │ │ │ │ - var yOffset = isNaN(style.labelYOffset) ? 0 : style.labelYOffset;
│ │ │ │ │ - var res = this.getResolution();
│ │ │ │ │ - location.move(xOffset * res, yOffset * res);
│ │ │ │ │ - }
│ │ │ │ │ - this.drawText(feature.id, style, location);
│ │ │ │ │ - } else {
│ │ │ │ │ - this.removeText(feature.id);
│ │ │ │ │ - }
│ │ │ │ │ - return rendered;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: calculateFeatureDx
│ │ │ │ │ - * {Number} Calculates the feature offset in x direction. Looking at the
│ │ │ │ │ - * center of the feature bounds and the renderer extent, we calculate how
│ │ │ │ │ - * many world widths the two are away from each other. This distance is
│ │ │ │ │ - * used to shift the feature as close as possible to the center of the
│ │ │ │ │ - * current enderer extent, which ensures that the feature is visible in the
│ │ │ │ │ - * current viewport.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * bounds - {} Bounds of the feature
│ │ │ │ │ - * worldBounds - {} Bounds of the world
│ │ │ │ │ - */
│ │ │ │ │ - calculateFeatureDx: function(bounds, worldBounds) {
│ │ │ │ │ - this.featureDx = 0;
│ │ │ │ │ - if (worldBounds) {
│ │ │ │ │ - var worldWidth = worldBounds.getWidth(),
│ │ │ │ │ - rendererCenterX = (this.extent.left + this.extent.right) / 2,
│ │ │ │ │ - featureCenterX = (bounds.left + bounds.right) / 2,
│ │ │ │ │ - worldsAway = Math.round((featureCenterX - rendererCenterX) / worldWidth);
│ │ │ │ │ - this.featureDx = worldsAway * worldWidth;
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: drawGeometry
│ │ │ │ │ - *
│ │ │ │ │ - * Draw a geometry. This should only be called from the renderer itself.
│ │ │ │ │ - * Use layer.drawFeature() from outside the renderer.
│ │ │ │ │ - * virtual function
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * geometry - {}
│ │ │ │ │ - * style - {Object}
│ │ │ │ │ - * featureId - {}
│ │ │ │ │ - */
│ │ │ │ │ - drawGeometry: function(geometry, style, featureId) {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: drawText
│ │ │ │ │ - * Function for drawing text labels.
│ │ │ │ │ - * This method is only called by the renderer itself.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * featureId - {String}
│ │ │ │ │ - * style -
│ │ │ │ │ - * location - {}
│ │ │ │ │ - */
│ │ │ │ │ - drawText: function(featureId, style, location) {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: removeText
│ │ │ │ │ - * Function for removing text labels.
│ │ │ │ │ - * This method is only called by the renderer itself.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * featureId - {String}
│ │ │ │ │ - */
│ │ │ │ │ - removeText: function(featureId) {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: clear
│ │ │ │ │ - * Clear all vectors from the renderer.
│ │ │ │ │ - * virtual function.
│ │ │ │ │ - */
│ │ │ │ │ - clear: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: getFeatureIdFromEvent
│ │ │ │ │ - * Returns a feature id from an event on the renderer.
│ │ │ │ │ - * How this happens is specific to the renderer. This should be
│ │ │ │ │ - * called from layer.getFeatureFromEvent().
│ │ │ │ │ - * Virtual function.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * evt - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} A feature id or undefined.
│ │ │ │ │ - */
│ │ │ │ │ - getFeatureIdFromEvent: function(evt) {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: eraseFeatures
│ │ │ │ │ - * This is called by the layer to erase features
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * features - {Array()}
│ │ │ │ │ - */
│ │ │ │ │ - eraseFeatures: function(features) {
│ │ │ │ │ - if (!(OpenLayers.Util.isArray(features))) {
│ │ │ │ │ - features = [features];
│ │ │ │ │ - }
│ │ │ │ │ - for (var i = 0, len = features.length; i < len; ++i) {
│ │ │ │ │ - var feature = features[i];
│ │ │ │ │ - this.eraseGeometry(feature.geometry, feature.id);
│ │ │ │ │ - this.removeText(feature.id);
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: eraseGeometry
│ │ │ │ │ - * Remove a geometry from the renderer (by id).
│ │ │ │ │ - * virtual function.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * geometry - {}
│ │ │ │ │ - * featureId - {String}
│ │ │ │ │ - */
│ │ │ │ │ - eraseGeometry: function(geometry, featureId) {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: moveRoot
│ │ │ │ │ - * moves this renderer's root to a (different) renderer.
│ │ │ │ │ - * To be implemented by subclasses that require a common renderer root for
│ │ │ │ │ - * feature selection.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * renderer - {} target renderer for the moved root
│ │ │ │ │ - */
│ │ │ │ │ - moveRoot: function(renderer) {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: getRenderLayerId
│ │ │ │ │ - * Gets the layer that this renderer's output appears on. If moveRoot was
│ │ │ │ │ - * used, this will be different from the id of the layer containing the
│ │ │ │ │ - * features rendered by this renderer.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} the id of the output layer.
│ │ │ │ │ - */
│ │ │ │ │ - getRenderLayerId: function() {
│ │ │ │ │ - return this.container.id;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: applyDefaultSymbolizer
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * symbolizer - {Object}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Object}
│ │ │ │ │ - */
│ │ │ │ │ - applyDefaultSymbolizer: function(symbolizer) {
│ │ │ │ │ - var result = OpenLayers.Util.extend({},
│ │ │ │ │ - OpenLayers.Renderer.defaultSymbolizer);
│ │ │ │ │ - if (symbolizer.stroke === false) {
│ │ │ │ │ - delete result.strokeWidth;
│ │ │ │ │ - delete result.strokeColor;
│ │ │ │ │ - }
│ │ │ │ │ - if (symbolizer.fill === false) {
│ │ │ │ │ - delete result.fillColor;
│ │ │ │ │ - }
│ │ │ │ │ - OpenLayers.Util.extend(result, symbolizer);
│ │ │ │ │ - return result;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Renderer"
│ │ │ │ │ -});
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Constant: OpenLayers.Renderer.defaultSymbolizer
│ │ │ │ │ - * {Object} Properties from this symbolizer will be applied to symbolizers
│ │ │ │ │ - * with missing properties. This can also be used to set a global
│ │ │ │ │ - * symbolizer default in OpenLayers. To be SLD 1.x compliant, add the
│ │ │ │ │ - * following code before rendering any vector features:
│ │ │ │ │ - * (code)
│ │ │ │ │ - * OpenLayers.Renderer.defaultSymbolizer = {
│ │ │ │ │ - * fillColor: "#808080",
│ │ │ │ │ - * fillOpacity: 1,
│ │ │ │ │ - * strokeColor: "#000000",
│ │ │ │ │ - * strokeOpacity: 1,
│ │ │ │ │ - * strokeWidth: 1,
│ │ │ │ │ - * pointRadius: 3,
│ │ │ │ │ - * graphicName: "square"
│ │ │ │ │ - * };
│ │ │ │ │ - * (end)
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Renderer.defaultSymbolizer = {
│ │ │ │ │ - fillColor: "#000000",
│ │ │ │ │ - strokeColor: "#000000",
│ │ │ │ │ - strokeWidth: 2,
│ │ │ │ │ - fillOpacity: 1,
│ │ │ │ │ - strokeOpacity: 1,
│ │ │ │ │ - pointRadius: 0,
│ │ │ │ │ - labelAlign: 'cm'
│ │ │ │ │ -};
│ │ │ │ │ -
│ │ │ │ │ -
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Constant: OpenLayers.Renderer.symbol
│ │ │ │ │ - * Coordinate arrays for well known (named) symbols.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Renderer.symbol = {
│ │ │ │ │ - "star": [350, 75, 379, 161, 469, 161, 397, 215, 423, 301, 350, 250, 277, 301,
│ │ │ │ │ - 303, 215, 231, 161, 321, 161, 350, 75
│ │ │ │ │ - ],
│ │ │ │ │ - "cross": [4, 0, 6, 0, 6, 4, 10, 4, 10, 6, 6, 6, 6, 10, 4, 10, 4, 6, 0, 6, 0, 4, 4, 4,
│ │ │ │ │ - 4, 0
│ │ │ │ │ - ],
│ │ │ │ │ - "x": [0, 0, 25, 0, 50, 35, 75, 0, 100, 0, 65, 50, 100, 100, 75, 100, 50, 65, 25, 100, 0, 100, 35, 50, 0, 0],
│ │ │ │ │ - "square": [0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
│ │ │ │ │ - "triangle": [0, 10, 10, 10, 5, 0, 0, 10]
│ │ │ │ │ -};
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Util/vendorPrefix.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/SingleFile.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -OpenLayers.Util = OpenLayers.Util || {};
│ │ │ │ │ -/**
│ │ │ │ │ - * Namespace: OpenLayers.Util.vendorPrefix
│ │ │ │ │ - * A collection of utility functions to detect vendor prefixed features
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Util.vendorPrefix = (function() {
│ │ │ │ │ - "use strict";
│ │ │ │ │ -
│ │ │ │ │ - var VENDOR_PREFIXES = ["", "O", "ms", "Moz", "Webkit"],
│ │ │ │ │ - divStyle = document.createElement("div").style,
│ │ │ │ │ - cssCache = {},
│ │ │ │ │ - jsCache = {};
│ │ │ │ │ -
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Function: domToCss
│ │ │ │ │ - * Converts a upper camel case DOM style property name to a CSS property
│ │ │ │ │ - * i.e. transformOrigin -> transform-origin
│ │ │ │ │ - * or WebkitTransformOrigin -> -webkit-transform-origin
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * prefixedDom - {String} The property to convert
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} The CSS property
│ │ │ │ │ - */
│ │ │ │ │ - function domToCss(prefixedDom) {
│ │ │ │ │ - if (!prefixedDom) {
│ │ │ │ │ - return null;
│ │ │ │ │ - }
│ │ │ │ │ - return prefixedDom.
│ │ │ │ │ - replace(/([A-Z])/g, function(c) {
│ │ │ │ │ - return "-" + c.toLowerCase();
│ │ │ │ │ - }).
│ │ │ │ │ - replace(/^ms-/, "-ms-");
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: css
│ │ │ │ │ - * Detect which property is used for a CSS property
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * property - {String} The standard (unprefixed) CSS property name
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} The standard CSS property, prefixed property or null if not
│ │ │ │ │ - * supported
│ │ │ │ │ - */
│ │ │ │ │ - function css(property) {
│ │ │ │ │ - if (cssCache[property] === undefined) {
│ │ │ │ │ - var domProperty = property.
│ │ │ │ │ - replace(/(-[\s\S])/g, function(c) {
│ │ │ │ │ - return c.charAt(1).toUpperCase();
│ │ │ │ │ - });
│ │ │ │ │ - var prefixedDom = style(domProperty);
│ │ │ │ │ - cssCache[property] = domToCss(prefixedDom);
│ │ │ │ │ - }
│ │ │ │ │ - return cssCache[property];
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: js
│ │ │ │ │ - * Detect which property is used for a JS property/method
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * obj - {Object} The object to test on
│ │ │ │ │ - * property - {String} The standard (unprefixed) JS property name
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} The standard JS property, prefixed property or null if not
│ │ │ │ │ - * supported
│ │ │ │ │ - */
│ │ │ │ │ - function js(obj, property) {
│ │ │ │ │ - if (jsCache[property] === undefined) {
│ │ │ │ │ - var tmpProp,
│ │ │ │ │ - i = 0,
│ │ │ │ │ - l = VENDOR_PREFIXES.length,
│ │ │ │ │ - prefix,
│ │ │ │ │ - isStyleObj = (typeof obj.cssText !== "undefined");
│ │ │ │ │ -
│ │ │ │ │ - jsCache[property] = null;
│ │ │ │ │ - for (; i < l; i++) {
│ │ │ │ │ - prefix = VENDOR_PREFIXES[i];
│ │ │ │ │ - if (prefix) {
│ │ │ │ │ - if (!isStyleObj) {
│ │ │ │ │ - // js prefix should be lower-case, while style
│ │ │ │ │ - // properties have upper case on first character
│ │ │ │ │ - prefix = prefix.toLowerCase();
│ │ │ │ │ - }
│ │ │ │ │ - tmpProp = prefix + property.charAt(0).toUpperCase() + property.slice(1);
│ │ │ │ │ - } else {
│ │ │ │ │ - tmpProp = property;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - if (obj[tmpProp] !== undefined) {
│ │ │ │ │ - jsCache[property] = tmpProp;
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return jsCache[property];
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: style
│ │ │ │ │ - * Detect which property is used for a DOM style property
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * property - {String} The standard (unprefixed) style property name
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} The standard style property, prefixed property or null if not
│ │ │ │ │ - * supported
│ │ │ │ │ - */
│ │ │ │ │ - function style(property) {
│ │ │ │ │ - return js(divStyle, property);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - return {
│ │ │ │ │ - css: css,
│ │ │ │ │ - js: js,
│ │ │ │ │ - style: style,
│ │ │ │ │ -
│ │ │ │ │ - // used for testing
│ │ │ │ │ - cssCache: cssCache,
│ │ │ │ │ - jsCache: jsCache
│ │ │ │ │ - };
│ │ │ │ │ -}());
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Events.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/Util.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Namespace: OpenLayers.Event
│ │ │ │ │ - * Utility functions for event handling.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Event = {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: observers
│ │ │ │ │ - * {Object} A hashtable cache of the event observers. Keyed by
│ │ │ │ │ - * element._eventCacheID
│ │ │ │ │ - */
│ │ │ │ │ - observers: false,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constant: KEY_SPACE
│ │ │ │ │ - * {int}
│ │ │ │ │ - */
│ │ │ │ │ - KEY_SPACE: 32,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constant: KEY_BACKSPACE
│ │ │ │ │ - * {int}
│ │ │ │ │ - */
│ │ │ │ │ - KEY_BACKSPACE: 8,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constant: KEY_TAB
│ │ │ │ │ - * {int}
│ │ │ │ │ - */
│ │ │ │ │ - KEY_TAB: 9,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constant: KEY_RETURN
│ │ │ │ │ - * {int}
│ │ │ │ │ - */
│ │ │ │ │ - KEY_RETURN: 13,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constant: KEY_ESC
│ │ │ │ │ - * {int}
│ │ │ │ │ - */
│ │ │ │ │ - KEY_ESC: 27,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constant: KEY_LEFT
│ │ │ │ │ - * {int}
│ │ │ │ │ - */
│ │ │ │ │ - KEY_LEFT: 37,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constant: KEY_UP
│ │ │ │ │ - * {int}
│ │ │ │ │ - */
│ │ │ │ │ - KEY_UP: 38,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constant: KEY_RIGHT
│ │ │ │ │ - * {int}
│ │ │ │ │ - */
│ │ │ │ │ - KEY_RIGHT: 39,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constant: KEY_DOWN
│ │ │ │ │ - * {int}
│ │ │ │ │ - */
│ │ │ │ │ - KEY_DOWN: 40,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constant: KEY_DELETE
│ │ │ │ │ - * {int}
│ │ │ │ │ - */
│ │ │ │ │ - KEY_DELETE: 46,
│ │ │ │ │ -
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: element
│ │ │ │ │ - * Cross browser event element detection.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * event - {Event}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {DOMElement} The element that caused the event
│ │ │ │ │ - */
│ │ │ │ │ - element: function(event) {
│ │ │ │ │ - return event.target || event.srcElement;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: isSingleTouch
│ │ │ │ │ - * Determine whether event was caused by a single touch
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * event - {Event}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean}
│ │ │ │ │ - */
│ │ │ │ │ - isSingleTouch: function(event) {
│ │ │ │ │ - return event.touches && event.touches.length == 1;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: isMultiTouch
│ │ │ │ │ - * Determine whether event was caused by a multi touch
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * event - {Event}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean}
│ │ │ │ │ - */
│ │ │ │ │ - isMultiTouch: function(event) {
│ │ │ │ │ - return event.touches && event.touches.length > 1;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: isLeftClick
│ │ │ │ │ - * Determine whether event was caused by a left click.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * event - {Event}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean}
│ │ │ │ │ - */
│ │ │ │ │ - isLeftClick: function(event) {
│ │ │ │ │ - return (((event.which) && (event.which == 1)) ||
│ │ │ │ │ - ((event.button) && (event.button == 1)));
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: isRightClick
│ │ │ │ │ - * Determine whether event was caused by a right mouse click.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * event - {Event}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean}
│ │ │ │ │ - */
│ │ │ │ │ - isRightClick: function(event) {
│ │ │ │ │ - return (((event.which) && (event.which == 3)) ||
│ │ │ │ │ - ((event.button) && (event.button == 2)));
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: stop
│ │ │ │ │ - * Stops an event from propagating.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * event - {Event}
│ │ │ │ │ - * allowDefault - {Boolean} If true, we stop the event chain but
│ │ │ │ │ - * still allow the default browser behaviour (text selection,
│ │ │ │ │ - * radio-button clicking, etc). Default is false.
│ │ │ │ │ - */
│ │ │ │ │ - stop: function(event, allowDefault) {
│ │ │ │ │ -
│ │ │ │ │ - if (!allowDefault) {
│ │ │ │ │ - OpenLayers.Event.preventDefault(event);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - if (event.stopPropagation) {
│ │ │ │ │ - event.stopPropagation();
│ │ │ │ │ - } else {
│ │ │ │ │ - event.cancelBubble = true;
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: preventDefault
│ │ │ │ │ - * Cancels the event if it is cancelable, without stopping further
│ │ │ │ │ - * propagation of the event.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * event - {Event}
│ │ │ │ │ - */
│ │ │ │ │ - preventDefault: function(event) {
│ │ │ │ │ - if (event.preventDefault) {
│ │ │ │ │ - event.preventDefault();
│ │ │ │ │ - } else {
│ │ │ │ │ - event.returnValue = false;
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: findElement
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * event - {Event}
│ │ │ │ │ - * tagName - {String}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {DOMElement} The first node with the given tagName, starting from the
│ │ │ │ │ - * node the event was triggered on and traversing the DOM upwards
│ │ │ │ │ - */
│ │ │ │ │ - findElement: function(event, tagName) {
│ │ │ │ │ - var element = OpenLayers.Event.element(event);
│ │ │ │ │ - while (element.parentNode && (!element.tagName ||
│ │ │ │ │ - (element.tagName.toUpperCase() != tagName.toUpperCase()))) {
│ │ │ │ │ - element = element.parentNode;
│ │ │ │ │ - }
│ │ │ │ │ - return element;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: observe
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * elementParam - {DOMElement || String}
│ │ │ │ │ - * name - {String}
│ │ │ │ │ - * observer - {function}
│ │ │ │ │ - * useCapture - {Boolean}
│ │ │ │ │ - */
│ │ │ │ │ - observe: function(elementParam, name, observer, useCapture) {
│ │ │ │ │ - var element = OpenLayers.Util.getElement(elementParam);
│ │ │ │ │ - useCapture = useCapture || false;
│ │ │ │ │ -
│ │ │ │ │ - if (name == 'keypress' &&
│ │ │ │ │ - (navigator.appVersion.match(/Konqueror|Safari|KHTML/) ||
│ │ │ │ │ - element.attachEvent)) {
│ │ │ │ │ - name = 'keydown';
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - //if observers cache has not yet been created, create it
│ │ │ │ │ - if (!this.observers) {
│ │ │ │ │ - this.observers = {};
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - //if not already assigned, make a new unique cache ID
│ │ │ │ │ - if (!element._eventCacheID) {
│ │ │ │ │ - var idPrefix = "eventCacheID_";
│ │ │ │ │ - if (element.id) {
│ │ │ │ │ - idPrefix = element.id + "_" + idPrefix;
│ │ │ │ │ - }
│ │ │ │ │ - element._eventCacheID = OpenLayers.Util.createUniqueID(idPrefix);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - var cacheID = element._eventCacheID;
│ │ │ │ │ -
│ │ │ │ │ - //if there is not yet a hash entry for this element, add one
│ │ │ │ │ - if (!this.observers[cacheID]) {
│ │ │ │ │ - this.observers[cacheID] = [];
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - //add a new observer to this element's list
│ │ │ │ │ - this.observers[cacheID].push({
│ │ │ │ │ - 'element': element,
│ │ │ │ │ - 'name': name,
│ │ │ │ │ - 'observer': observer,
│ │ │ │ │ - 'useCapture': useCapture
│ │ │ │ │ - });
│ │ │ │ │ -
│ │ │ │ │ - //add the actual browser event listener
│ │ │ │ │ - if (element.addEventListener) {
│ │ │ │ │ - element.addEventListener(name, observer, useCapture);
│ │ │ │ │ - } else if (element.attachEvent) {
│ │ │ │ │ - element.attachEvent('on' + name, observer);
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: stopObservingElement
│ │ │ │ │ - * Given the id of an element to stop observing, cycle through the
│ │ │ │ │ - * element's cached observers, calling stopObserving on each one,
│ │ │ │ │ - * skipping those entries which can no longer be removed.
│ │ │ │ │ - *
│ │ │ │ │ - * parameters:
│ │ │ │ │ - * elementParam - {DOMElement || String}
│ │ │ │ │ - */
│ │ │ │ │ - stopObservingElement: function(elementParam) {
│ │ │ │ │ - var element = OpenLayers.Util.getElement(elementParam);
│ │ │ │ │ - var cacheID = element._eventCacheID;
│ │ │ │ │ -
│ │ │ │ │ - this._removeElementObservers(OpenLayers.Event.observers[cacheID]);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: _removeElementObservers
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * elementObservers - {Array(Object)} Array of (element, name,
│ │ │ │ │ - * observer, usecapture) objects,
│ │ │ │ │ - * taken directly from hashtable
│ │ │ │ │ - */
│ │ │ │ │ - _removeElementObservers: function(elementObservers) {
│ │ │ │ │ - if (elementObservers) {
│ │ │ │ │ - for (var i = elementObservers.length - 1; i >= 0; i--) {
│ │ │ │ │ - var entry = elementObservers[i];
│ │ │ │ │ - OpenLayers.Event.stopObserving.apply(this, [
│ │ │ │ │ - entry.element, entry.name, entry.observer, entry.useCapture
│ │ │ │ │ - ]);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: stopObserving
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * elementParam - {DOMElement || String}
│ │ │ │ │ - * name - {String}
│ │ │ │ │ - * observer - {function}
│ │ │ │ │ - * useCapture - {Boolean}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} Whether or not the event observer was removed
│ │ │ │ │ - */
│ │ │ │ │ - stopObserving: function(elementParam, name, observer, useCapture) {
│ │ │ │ │ - useCapture = useCapture || false;
│ │ │ │ │ -
│ │ │ │ │ - var element = OpenLayers.Util.getElement(elementParam);
│ │ │ │ │ - var cacheID = element._eventCacheID;
│ │ │ │ │ -
│ │ │ │ │ - if (name == 'keypress') {
│ │ │ │ │ - if (navigator.appVersion.match(/Konqueror|Safari|KHTML/) ||
│ │ │ │ │ - element.detachEvent) {
│ │ │ │ │ - name = 'keydown';
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // find element's entry in this.observers cache and remove it
│ │ │ │ │ - var foundEntry = false;
│ │ │ │ │ - var elementObservers = OpenLayers.Event.observers[cacheID];
│ │ │ │ │ - if (elementObservers) {
│ │ │ │ │ -
│ │ │ │ │ - // find the specific event type in the element's list
│ │ │ │ │ - var i = 0;
│ │ │ │ │ - while (!foundEntry && i < elementObservers.length) {
│ │ │ │ │ - var cacheEntry = elementObservers[i];
│ │ │ │ │ -
│ │ │ │ │ - if ((cacheEntry.name == name) &&
│ │ │ │ │ - (cacheEntry.observer == observer) &&
│ │ │ │ │ - (cacheEntry.useCapture == useCapture)) {
│ │ │ │ │ -
│ │ │ │ │ - elementObservers.splice(i, 1);
│ │ │ │ │ - if (elementObservers.length == 0) {
│ │ │ │ │ - delete OpenLayers.Event.observers[cacheID];
│ │ │ │ │ - }
│ │ │ │ │ - foundEntry = true;
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - i++;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - //actually remove the event listener from browser
│ │ │ │ │ - if (foundEntry) {
│ │ │ │ │ - if (element.removeEventListener) {
│ │ │ │ │ - element.removeEventListener(name, observer, useCapture);
│ │ │ │ │ - } else if (element && element.detachEvent) {
│ │ │ │ │ - element.detachEvent('on' + name, observer);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return foundEntry;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: unloadCache
│ │ │ │ │ - * Cycle through all the element entries in the events cache and call
│ │ │ │ │ - * stopObservingElement on each.
│ │ │ │ │ - */
│ │ │ │ │ - unloadCache: function() {
│ │ │ │ │ - // check for OpenLayers.Event before checking for observers, because
│ │ │ │ │ - // OpenLayers.Event may be undefined in IE if no map instance was
│ │ │ │ │ - // created
│ │ │ │ │ - if (OpenLayers.Event && OpenLayers.Event.observers) {
│ │ │ │ │ - for (var cacheID in OpenLayers.Event.observers) {
│ │ │ │ │ - var elementObservers = OpenLayers.Event.observers[cacheID];
│ │ │ │ │ - OpenLayers.Event._removeElementObservers.apply(this,
│ │ │ │ │ - [elementObservers]);
│ │ │ │ │ - }
│ │ │ │ │ - OpenLayers.Event.observers = false;
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Event"
│ │ │ │ │ -};
│ │ │ │ │ -
│ │ │ │ │ -/* prevent memory leaks in IE */
│ │ │ │ │ -OpenLayers.Event.observe(window, 'unload', OpenLayers.Event.unloadCache, false);
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Events
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Events = OpenLayers.Class({
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constant: BROWSER_EVENTS
│ │ │ │ │ - * {Array(String)} supported events
│ │ │ │ │ - */
│ │ │ │ │ - BROWSER_EVENTS: [
│ │ │ │ │ - "mouseover", "mouseout",
│ │ │ │ │ - "mousedown", "mouseup", "mousemove",
│ │ │ │ │ - "click", "dblclick", "rightclick", "dblrightclick",
│ │ │ │ │ - "resize", "focus", "blur",
│ │ │ │ │ - "touchstart", "touchmove", "touchend",
│ │ │ │ │ - "keydown"
│ │ │ │ │ - ],
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: listeners
│ │ │ │ │ - * {Object} Hashtable of Array(Function): events listener functions
│ │ │ │ │ - */
│ │ │ │ │ - listeners: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: object
│ │ │ │ │ - * {Object} the code object issuing application events
│ │ │ │ │ - */
│ │ │ │ │ - object: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: element
│ │ │ │ │ - * {DOMElement} the DOM element receiving browser events
│ │ │ │ │ - */
│ │ │ │ │ - element: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: eventHandler
│ │ │ │ │ - * {Function} bound event handler attached to elements
│ │ │ │ │ - */
│ │ │ │ │ - eventHandler: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: fallThrough
│ │ │ │ │ - * {Boolean}
│ │ │ │ │ - */
│ │ │ │ │ - fallThrough: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: includeXY
│ │ │ │ │ - * {Boolean} Should the .xy property automatically be created for browser
│ │ │ │ │ - * mouse events? In general, this should be false. If it is true, then
│ │ │ │ │ - * mouse events will automatically generate a '.xy' property on the
│ │ │ │ │ - * event object that is passed. (Prior to OpenLayers 2.7, this was true
│ │ │ │ │ - * by default.) Otherwise, you can call the getMousePosition on the
│ │ │ │ │ - * relevant events handler on the object available via the 'evt.object'
│ │ │ │ │ - * property of the evt object. So, for most events, you can call:
│ │ │ │ │ - * function named(evt) {
│ │ │ │ │ - * this.xy = this.object.events.getMousePosition(evt)
│ │ │ │ │ - * }
│ │ │ │ │ - *
│ │ │ │ │ - * This option typically defaults to false for performance reasons:
│ │ │ │ │ - * when creating an events object whose primary purpose is to manage
│ │ │ │ │ - * relatively positioned mouse events within a div, it may make
│ │ │ │ │ - * sense to set it to true.
│ │ │ │ │ - *
│ │ │ │ │ - * This option is also used to control whether the events object caches
│ │ │ │ │ - * offsets. If this is false, it will not: the reason for this is that
│ │ │ │ │ - * it is only expected to be called many times if the includeXY property
│ │ │ │ │ - * is set to true. If you set this to true, you are expected to clear
│ │ │ │ │ - * the offset cache manually (using this.clearMouseCache()) if:
│ │ │ │ │ - * the border of the element changes
│ │ │ │ │ - * the location of the element in the page changes
│ │ │ │ │ - */
│ │ │ │ │ - includeXY: false,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: extensions
│ │ │ │ │ - * {Object} Event extensions registered with this instance. Keys are
│ │ │ │ │ - * event types, values are {OpenLayers.Events.*} extension instances or
│ │ │ │ │ - * {Boolean} for events that an instantiated extension provides in
│ │ │ │ │ - * addition to the one it was created for.
│ │ │ │ │ - *
│ │ │ │ │ - * Extensions create an event in addition to browser events, which usually
│ │ │ │ │ - * fires when a sequence of browser events is completed. Extensions are
│ │ │ │ │ - * automatically instantiated when a listener is registered for an event
│ │ │ │ │ - * provided by an extension.
│ │ │ │ │ - *
│ │ │ │ │ - * Extensions are created in the namespace using
│ │ │ │ │ - * , and named after the event they provide.
│ │ │ │ │ - * The constructor receives the target instance as
│ │ │ │ │ - * argument. Extensions that need to capture browser events before they
│ │ │ │ │ - * propagate can register their listeners events using , with
│ │ │ │ │ - * {extension: true} as 4th argument.
│ │ │ │ │ - *
│ │ │ │ │ - * If an extension creates more than one event, an alias for each event
│ │ │ │ │ - * type should be created and reference the same class. The constructor
│ │ │ │ │ - * should set a reference in the target's extensions registry to itself.
│ │ │ │ │ - *
│ │ │ │ │ - * Below is a minimal extension that provides the "foostart" and "fooend"
│ │ │ │ │ - * event types, which replace the native "click" event type if clicked on
│ │ │ │ │ - * an element with the css class "foo":
│ │ │ │ │ - *
│ │ │ │ │ - * (code)
│ │ │ │ │ - * OpenLayers.Events.foostart = OpenLayers.Class({
│ │ │ │ │ - * initialize: function(target) {
│ │ │ │ │ - * this.target = target;
│ │ │ │ │ - * this.target.register("click", this, this.doStuff, {extension: true});
│ │ │ │ │ - * // only required if extension provides more than one event type
│ │ │ │ │ - * this.target.extensions["foostart"] = true;
│ │ │ │ │ - * this.target.extensions["fooend"] = true;
│ │ │ │ │ - * },
│ │ │ │ │ - * destroy: function() {
│ │ │ │ │ - * var target = this.target;
│ │ │ │ │ - * target.unregister("click", this, this.doStuff);
│ │ │ │ │ - * delete this.target;
│ │ │ │ │ - * // only required if extension provides more than one event type
│ │ │ │ │ - * delete target.extensions["foostart"];
│ │ │ │ │ - * delete target.extensions["fooend"];
│ │ │ │ │ - * },
│ │ │ │ │ - * doStuff: function(evt) {
│ │ │ │ │ - * var propagate = true;
│ │ │ │ │ - * if (OpenLayers.Event.element(evt).className === "foo") {
│ │ │ │ │ - * propagate = false;
│ │ │ │ │ - * var target = this.target;
│ │ │ │ │ - * target.triggerEvent("foostart");
│ │ │ │ │ - * window.setTimeout(function() {
│ │ │ │ │ - * target.triggerEvent("fooend");
│ │ │ │ │ - * }, 1000);
│ │ │ │ │ - * }
│ │ │ │ │ - * return propagate;
│ │ │ │ │ - * }
│ │ │ │ │ - * });
│ │ │ │ │ - * // only required if extension provides more than one event type
│ │ │ │ │ - * OpenLayers.Events.fooend = OpenLayers.Events.foostart;
│ │ │ │ │ - * (end)
│ │ │ │ │ - *
│ │ │ │ │ - */
│ │ │ │ │ - extensions: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: extensionCount
│ │ │ │ │ - * {Object} Keys are event types (like in ), values are the
│ │ │ │ │ - * number of extension listeners for each event type.
│ │ │ │ │ - */
│ │ │ │ │ - extensionCount: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: clearMouseListener
│ │ │ │ │ - * A version of that is bound to this instance so that
│ │ │ │ │ - * it can be used with and
│ │ │ │ │ - * .
│ │ │ │ │ - */
│ │ │ │ │ - clearMouseListener: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Events
│ │ │ │ │ - * Construct an OpenLayers.Events object.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * object - {Object} The js object to which this Events object is being added
│ │ │ │ │ - * element - {DOMElement} A dom element to respond to browser events
│ │ │ │ │ - * eventTypes - {Array(String)} Deprecated. Array of custom application
│ │ │ │ │ - * events. A listener may be registered for any named event, regardless
│ │ │ │ │ - * of the values provided here.
│ │ │ │ │ - * fallThrough - {Boolean} Allow events to fall through after these have
│ │ │ │ │ - * been handled?
│ │ │ │ │ - * options - {Object} Options for the events object.
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(object, element, eventTypes, fallThrough, options) {
│ │ │ │ │ - OpenLayers.Util.extend(this, options);
│ │ │ │ │ - this.object = object;
│ │ │ │ │ - this.fallThrough = fallThrough;
│ │ │ │ │ - this.listeners = {};
│ │ │ │ │ - this.extensions = {};
│ │ │ │ │ - this.extensionCount = {};
│ │ │ │ │ - this._msTouches = [];
│ │ │ │ │ -
│ │ │ │ │ - // if a dom element is specified, add a listeners list
│ │ │ │ │ - // for browser events on the element and register them
│ │ │ │ │ - if (element != null) {
│ │ │ │ │ - this.attachToElement(element);
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: destroy
│ │ │ │ │ - */
│ │ │ │ │ - destroy: function() {
│ │ │ │ │ - for (var e in this.extensions) {
│ │ │ │ │ - if (typeof this.extensions[e] !== "boolean") {
│ │ │ │ │ - this.extensions[e].destroy();
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - this.extensions = null;
│ │ │ │ │ - if (this.element) {
│ │ │ │ │ - OpenLayers.Event.stopObservingElement(this.element);
│ │ │ │ │ - if (this.element.hasScrollEvent) {
│ │ │ │ │ - OpenLayers.Event.stopObserving(
│ │ │ │ │ - window, "scroll", this.clearMouseListener
│ │ │ │ │ - );
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - this.element = null;
│ │ │ │ │ -
│ │ │ │ │ - this.listeners = null;
│ │ │ │ │ - this.object = null;
│ │ │ │ │ - this.fallThrough = null;
│ │ │ │ │ - this.eventHandler = null;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: addEventType
│ │ │ │ │ - * Deprecated. Any event can be triggered without adding it first.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * eventName - {String}
│ │ │ │ │ - */
│ │ │ │ │ - addEventType: function(eventName) {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: attachToElement
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * element - {HTMLDOMElement} a DOM element to attach browser events to
│ │ │ │ │ - */
│ │ │ │ │ - attachToElement: function(element) {
│ │ │ │ │ - if (this.element) {
│ │ │ │ │ - OpenLayers.Event.stopObservingElement(this.element);
│ │ │ │ │ - } else {
│ │ │ │ │ - // keep a bound copy of handleBrowserEvent() so that we can
│ │ │ │ │ - // pass the same function to both Event.observe() and .stopObserving()
│ │ │ │ │ - this.eventHandler = OpenLayers.Function.bindAsEventListener(
│ │ │ │ │ - this.handleBrowserEvent, this
│ │ │ │ │ - );
│ │ │ │ │ -
│ │ │ │ │ - // to be used with observe and stopObserving
│ │ │ │ │ - this.clearMouseListener = OpenLayers.Function.bind(
│ │ │ │ │ - this.clearMouseCache, this
│ │ │ │ │ - );
│ │ │ │ │ - }
│ │ │ │ │ - this.element = element;
│ │ │ │ │ - var msTouch = !!window.navigator.msMaxTouchPoints;
│ │ │ │ │ - var type;
│ │ │ │ │ - for (var i = 0, len = this.BROWSER_EVENTS.length; i < len; i++) {
│ │ │ │ │ - type = this.BROWSER_EVENTS[i];
│ │ │ │ │ - // register the event cross-browser
│ │ │ │ │ - OpenLayers.Event.observe(element, type, this.eventHandler);
│ │ │ │ │ - if (msTouch && type.indexOf('touch') === 0) {
│ │ │ │ │ - this.addMsTouchListener(element, type, this.eventHandler);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - // disable dragstart in IE so that mousedown/move/up works normally
│ │ │ │ │ - OpenLayers.Event.observe(element, "dragstart", OpenLayers.Event.stop);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: on
│ │ │ │ │ - * Convenience method for registering listeners with a common scope.
│ │ │ │ │ - * Internally, this method calls as shown in the examples
│ │ │ │ │ - * below.
│ │ │ │ │ - *
│ │ │ │ │ - * Example use:
│ │ │ │ │ - * (code)
│ │ │ │ │ - * // register a single listener for the "loadstart" event
│ │ │ │ │ - * events.on({"loadstart": loadStartListener});
│ │ │ │ │ - *
│ │ │ │ │ - * // this is equivalent to the following
│ │ │ │ │ - * events.register("loadstart", undefined, loadStartListener);
│ │ │ │ │ - *
│ │ │ │ │ - * // register multiple listeners to be called with the same `this` object
│ │ │ │ │ - * events.on({
│ │ │ │ │ - * "loadstart": loadStartListener,
│ │ │ │ │ - * "loadend": loadEndListener,
│ │ │ │ │ - * scope: object
│ │ │ │ │ - * });
│ │ │ │ │ - *
│ │ │ │ │ - * // this is equivalent to the following
│ │ │ │ │ - * events.register("loadstart", object, loadStartListener);
│ │ │ │ │ - * events.register("loadend", object, loadEndListener);
│ │ │ │ │ - * (end)
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * object - {Object}
│ │ │ │ │ - */
│ │ │ │ │ - on: function(object) {
│ │ │ │ │ - for (var type in object) {
│ │ │ │ │ - if (type != "scope" && object.hasOwnProperty(type)) {
│ │ │ │ │ - this.register(type, object.scope, object[type]);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: register
│ │ │ │ │ - * Register an event on the events object.
│ │ │ │ │ - *
│ │ │ │ │ - * When the event is triggered, the 'func' function will be called, in the
│ │ │ │ │ - * context of 'obj'. Imagine we were to register an event, specifying an
│ │ │ │ │ - * OpenLayers.Bounds Object as 'obj'. When the event is triggered, the
│ │ │ │ │ - * context in the callback function will be our Bounds object. This means
│ │ │ │ │ - * that within our callback function, we can access the properties and
│ │ │ │ │ - * methods of the Bounds object through the "this" variable. So our
│ │ │ │ │ - * callback could execute something like:
│ │ │ │ │ - * : leftStr = "Left: " + this.left;
│ │ │ │ │ - *
│ │ │ │ │ - * or
│ │ │ │ │ - *
│ │ │ │ │ - * : centerStr = "Center: " + this.getCenterLonLat();
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * type - {String} Name of the event to register
│ │ │ │ │ - * obj - {Object} The object to bind the context to for the callback#.
│ │ │ │ │ - * If no object is specified, default is the Events's 'object' property.
│ │ │ │ │ - * func - {Function} The callback function. If no callback is
│ │ │ │ │ - * specified, this function does nothing.
│ │ │ │ │ - * priority - {Boolean|Object} If true, adds the new listener to the
│ │ │ │ │ - * *front* of the events queue instead of to the end.
│ │ │ │ │ - *
│ │ │ │ │ - * Valid options for priority:
│ │ │ │ │ - * extension - {Boolean} If true, then the event will be registered as
│ │ │ │ │ - * extension event. Extension events are handled before all other
│ │ │ │ │ - * events.
│ │ │ │ │ - */
│ │ │ │ │ - register: function(type, obj, func, priority) {
│ │ │ │ │ - if (type in OpenLayers.Events && !this.extensions[type]) {
│ │ │ │ │ - this.extensions[type] = new OpenLayers.Events[type](this);
│ │ │ │ │ - }
│ │ │ │ │ - if (func != null) {
│ │ │ │ │ - if (obj == null) {
│ │ │ │ │ - obj = this.object;
│ │ │ │ │ - }
│ │ │ │ │ - var listeners = this.listeners[type];
│ │ │ │ │ - if (!listeners) {
│ │ │ │ │ - listeners = [];
│ │ │ │ │ - this.listeners[type] = listeners;
│ │ │ │ │ - this.extensionCount[type] = 0;
│ │ │ │ │ - }
│ │ │ │ │ - var listener = {
│ │ │ │ │ - obj: obj,
│ │ │ │ │ - func: func
│ │ │ │ │ - };
│ │ │ │ │ - if (priority) {
│ │ │ │ │ - listeners.splice(this.extensionCount[type], 0, listener);
│ │ │ │ │ - if (typeof priority === "object" && priority.extension) {
│ │ │ │ │ - this.extensionCount[type]++;
│ │ │ │ │ - }
│ │ │ │ │ - } else {
│ │ │ │ │ - listeners.push(listener);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: registerPriority
│ │ │ │ │ - * Same as register() but adds the new listener to the *front* of the
│ │ │ │ │ - * events queue instead of to the end.
│ │ │ │ │ - *
│ │ │ │ │ - * TODO: get rid of this in 3.0 - Decide whether listeners should be
│ │ │ │ │ - * called in the order they were registered or in reverse order.
│ │ │ │ │ - *
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * type - {String} Name of the event to register
│ │ │ │ │ - * obj - {Object} The object to bind the context to for the callback#.
│ │ │ │ │ - * If no object is specified, default is the Events's
│ │ │ │ │ - * 'object' property.
│ │ │ │ │ - * func - {Function} The callback function. If no callback is
│ │ │ │ │ - * specified, this function does nothing.
│ │ │ │ │ - */
│ │ │ │ │ - registerPriority: function(type, obj, func) {
│ │ │ │ │ - this.register(type, obj, func, true);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: un
│ │ │ │ │ - * Convenience method for unregistering listeners with a common scope.
│ │ │ │ │ - * Internally, this method calls as shown in the examples
│ │ │ │ │ - * below.
│ │ │ │ │ - *
│ │ │ │ │ - * Example use:
│ │ │ │ │ - * (code)
│ │ │ │ │ - * // unregister a single listener for the "loadstart" event
│ │ │ │ │ - * events.un({"loadstart": loadStartListener});
│ │ │ │ │ - *
│ │ │ │ │ - * // this is equivalent to the following
│ │ │ │ │ - * events.unregister("loadstart", undefined, loadStartListener);
│ │ │ │ │ - *
│ │ │ │ │ - * // unregister multiple listeners with the same `this` object
│ │ │ │ │ - * events.un({
│ │ │ │ │ - * "loadstart": loadStartListener,
│ │ │ │ │ - * "loadend": loadEndListener,
│ │ │ │ │ - * scope: object
│ │ │ │ │ - * });
│ │ │ │ │ - *
│ │ │ │ │ - * // this is equivalent to the following
│ │ │ │ │ - * events.unregister("loadstart", object, loadStartListener);
│ │ │ │ │ - * events.unregister("loadend", object, loadEndListener);
│ │ │ │ │ - * (end)
│ │ │ │ │ - */
│ │ │ │ │ - un: function(object) {
│ │ │ │ │ - for (var type in object) {
│ │ │ │ │ - if (type != "scope" && object.hasOwnProperty(type)) {
│ │ │ │ │ - this.unregister(type, object.scope, object[type]);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: unregister
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * type - {String}
│ │ │ │ │ - * obj - {Object} If none specified, defaults to this.object
│ │ │ │ │ - * func - {Function}
│ │ │ │ │ - */
│ │ │ │ │ - unregister: function(type, obj, func) {
│ │ │ │ │ - if (obj == null) {
│ │ │ │ │ - obj = this.object;
│ │ │ │ │ - }
│ │ │ │ │ - var listeners = this.listeners[type];
│ │ │ │ │ - if (listeners != null) {
│ │ │ │ │ - for (var i = 0, len = listeners.length; i < len; i++) {
│ │ │ │ │ - if (listeners[i].obj == obj && listeners[i].func == func) {
│ │ │ │ │ - listeners.splice(i, 1);
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: remove
│ │ │ │ │ - * Remove all listeners for a given event type. If type is not registered,
│ │ │ │ │ - * does nothing.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * type - {String}
│ │ │ │ │ - */
│ │ │ │ │ - remove: function(type) {
│ │ │ │ │ - if (this.listeners[type] != null) {
│ │ │ │ │ - this.listeners[type] = [];
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: triggerEvent
│ │ │ │ │ - * Trigger a specified registered event.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * type - {String}
│ │ │ │ │ - * evt - {Event || Object} will be passed to the listeners.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} The last listener return. If a listener returns false, the
│ │ │ │ │ - * chain of listeners will stop getting called.
│ │ │ │ │ - */
│ │ │ │ │ - triggerEvent: function(type, evt) {
│ │ │ │ │ - var listeners = this.listeners[type];
│ │ │ │ │ -
│ │ │ │ │ - // fast path
│ │ │ │ │ - if (!listeners || listeners.length == 0) {
│ │ │ │ │ - return undefined;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // prep evt object with object & div references
│ │ │ │ │ - if (evt == null) {
│ │ │ │ │ - evt = {};
│ │ │ │ │ - }
│ │ │ │ │ - evt.object = this.object;
│ │ │ │ │ - evt.element = this.element;
│ │ │ │ │ - if (!evt.type) {
│ │ │ │ │ - evt.type = type;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // execute all callbacks registered for specified type
│ │ │ │ │ - // get a clone of the listeners array to
│ │ │ │ │ - // allow for splicing during callbacks
│ │ │ │ │ - listeners = listeners.slice();
│ │ │ │ │ - var continueChain;
│ │ │ │ │ - for (var i = 0, len = listeners.length; i < len; i++) {
│ │ │ │ │ - var callback = listeners[i];
│ │ │ │ │ - // bind the context to callback.obj
│ │ │ │ │ - continueChain = callback.func.apply(callback.obj, [evt]);
│ │ │ │ │ -
│ │ │ │ │ - if ((continueChain != undefined) && (continueChain == false)) {
│ │ │ │ │ - // if callback returns false, execute no more callbacks.
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - // don't fall through to other DOM elements
│ │ │ │ │ - if (!this.fallThrough) {
│ │ │ │ │ - OpenLayers.Event.stop(evt, true);
│ │ │ │ │ - }
│ │ │ │ │ - return continueChain;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: handleBrowserEvent
│ │ │ │ │ - * Basically just a wrapper to the triggerEvent() function, but takes
│ │ │ │ │ - * care to set a property 'xy' on the event with the current mouse
│ │ │ │ │ - * position.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * evt - {Event}
│ │ │ │ │ - */
│ │ │ │ │ - handleBrowserEvent: function(evt) {
│ │ │ │ │ - var type = evt.type,
│ │ │ │ │ - listeners = this.listeners[type];
│ │ │ │ │ - if (!listeners || listeners.length == 0) {
│ │ │ │ │ - // noone's listening, bail out
│ │ │ │ │ - return;
│ │ │ │ │ - }
│ │ │ │ │ - // add clientX & clientY to all events - corresponds to average x, y
│ │ │ │ │ - var touches = evt.touches;
│ │ │ │ │ - if (touches && touches[0]) {
│ │ │ │ │ - var x = 0;
│ │ │ │ │ - var y = 0;
│ │ │ │ │ - var num = touches.length;
│ │ │ │ │ - var touch;
│ │ │ │ │ - for (var i = 0; i < num; ++i) {
│ │ │ │ │ - touch = this.getTouchClientXY(touches[i]);
│ │ │ │ │ - x += touch.clientX;
│ │ │ │ │ - y += touch.clientY;
│ │ │ │ │ - }
│ │ │ │ │ - evt.clientX = x / num;
│ │ │ │ │ - evt.clientY = y / num;
│ │ │ │ │ - }
│ │ │ │ │ - if (this.includeXY) {
│ │ │ │ │ - evt.xy = this.getMousePosition(evt);
│ │ │ │ │ - }
│ │ │ │ │ - this.triggerEvent(type, evt);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: getTouchClientXY
│ │ │ │ │ - * WebKit has a few bugs for clientX/clientY. This method detects them
│ │ │ │ │ - * and calculate the correct values.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * evt - {Touch} a Touch object from a TouchEvent
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Object} An object with only clientX and clientY properties with the
│ │ │ │ │ - * calculated values.
│ │ │ │ │ - */
│ │ │ │ │ - getTouchClientXY: function(evt) {
│ │ │ │ │ - // olMochWin is to override window, used for testing
│ │ │ │ │ - var win = window.olMockWin || window,
│ │ │ │ │ - winPageX = win.pageXOffset,
│ │ │ │ │ - winPageY = win.pageYOffset,
│ │ │ │ │ - x = evt.clientX,
│ │ │ │ │ - y = evt.clientY;
│ │ │ │ │ -
│ │ │ │ │ - if (evt.pageY === 0 && Math.floor(y) > Math.floor(evt.pageY) ||
│ │ │ │ │ - evt.pageX === 0 && Math.floor(x) > Math.floor(evt.pageX)) {
│ │ │ │ │ - // iOS4 include scroll offset in clientX/Y
│ │ │ │ │ - x = x - winPageX;
│ │ │ │ │ - y = y - winPageY;
│ │ │ │ │ - } else if (y < (evt.pageY - winPageY) || x < (evt.pageX - winPageX)) {
│ │ │ │ │ - // Some Android browsers have totally bogus values for clientX/Y
│ │ │ │ │ - // when scrolling/zooming a page
│ │ │ │ │ - x = evt.pageX - winPageX;
│ │ │ │ │ - y = evt.pageY - winPageY;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - evt.olClientX = x;
│ │ │ │ │ - evt.olClientY = y;
│ │ │ │ │ -
│ │ │ │ │ - return {
│ │ │ │ │ - clientX: x,
│ │ │ │ │ - clientY: y
│ │ │ │ │ - };
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: clearMouseCache
│ │ │ │ │ - * Clear cached data about the mouse position. This should be called any
│ │ │ │ │ - * time the element that events are registered on changes position
│ │ │ │ │ - * within the page.
│ │ │ │ │ - */
│ │ │ │ │ - clearMouseCache: function() {
│ │ │ │ │ - this.element.scrolls = null;
│ │ │ │ │ - this.element.lefttop = null;
│ │ │ │ │ - this.element.offsets = null;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: getMousePosition
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * evt - {Event}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} The current xy coordinate of the mouse, adjusted
│ │ │ │ │ - * for offsets
│ │ │ │ │ - */
│ │ │ │ │ - getMousePosition: function(evt) {
│ │ │ │ │ - if (!this.includeXY) {
│ │ │ │ │ - this.clearMouseCache();
│ │ │ │ │ - } else if (!this.element.hasScrollEvent) {
│ │ │ │ │ - OpenLayers.Event.observe(window, "scroll", this.clearMouseListener);
│ │ │ │ │ - this.element.hasScrollEvent = true;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - if (!this.element.scrolls) {
│ │ │ │ │ - var viewportElement = OpenLayers.Util.getViewportElement();
│ │ │ │ │ - this.element.scrolls = [
│ │ │ │ │ - window.pageXOffset || viewportElement.scrollLeft,
│ │ │ │ │ - window.pageYOffset || viewportElement.scrollTop
│ │ │ │ │ - ];
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - if (!this.element.lefttop) {
│ │ │ │ │ - this.element.lefttop = [
│ │ │ │ │ - (document.documentElement.clientLeft || 0),
│ │ │ │ │ - (document.documentElement.clientTop || 0)
│ │ │ │ │ - ];
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - if (!this.element.offsets) {
│ │ │ │ │ - this.element.offsets = OpenLayers.Util.pagePosition(this.element);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - return new OpenLayers.Pixel(
│ │ │ │ │ - (evt.clientX + this.element.scrolls[0]) - this.element.offsets[0] -
│ │ │ │ │ - this.element.lefttop[0],
│ │ │ │ │ - (evt.clientY + this.element.scrolls[1]) - this.element.offsets[1] -
│ │ │ │ │ - this.element.lefttop[1]
│ │ │ │ │ - );
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: addMsTouchListener
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * element - {DOMElement} The DOM element to register the listener on
│ │ │ │ │ - * type - {String} The event type
│ │ │ │ │ - * handler - {Function} the handler
│ │ │ │ │ - */
│ │ │ │ │ - addMsTouchListener: function(element, type, handler) {
│ │ │ │ │ - var eventHandler = this.eventHandler;
│ │ │ │ │ - var touches = this._msTouches;
│ │ │ │ │ -
│ │ │ │ │ - function msHandler(evt) {
│ │ │ │ │ - handler(OpenLayers.Util.applyDefaults({
│ │ │ │ │ - stopPropagation: function() {
│ │ │ │ │ - for (var i = touches.length - 1; i >= 0; --i) {
│ │ │ │ │ - touches[i].stopPropagation();
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ - preventDefault: function() {
│ │ │ │ │ - for (var i = touches.length - 1; i >= 0; --i) {
│ │ │ │ │ - touches[i].preventDefault();
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ - type: type
│ │ │ │ │ - }, evt));
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - switch (type) {
│ │ │ │ │ - case 'touchstart':
│ │ │ │ │ - return this.addMsTouchListenerStart(element, type, msHandler);
│ │ │ │ │ - case 'touchend':
│ │ │ │ │ - return this.addMsTouchListenerEnd(element, type, msHandler);
│ │ │ │ │ - case 'touchmove':
│ │ │ │ │ - return this.addMsTouchListenerMove(element, type, msHandler);
│ │ │ │ │ - default:
│ │ │ │ │ - throw 'Unknown touch event type';
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: addMsTouchListenerStart
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * element - {DOMElement} The DOM element to register the listener on
│ │ │ │ │ - * type - {String} The event type
│ │ │ │ │ - * handler - {Function} the handler
│ │ │ │ │ - */
│ │ │ │ │ - addMsTouchListenerStart: function(element, type, handler) {
│ │ │ │ │ - var touches = this._msTouches;
│ │ │ │ │ -
│ │ │ │ │ - var cb = function(e) {
│ │ │ │ │ -
│ │ │ │ │ - var alreadyInArray = false;
│ │ │ │ │ - for (var i = 0, ii = touches.length; i < ii; ++i) {
│ │ │ │ │ - if (touches[i].pointerId == e.pointerId) {
│ │ │ │ │ - alreadyInArray = true;
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - if (!alreadyInArray) {
│ │ │ │ │ - touches.push(e);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - e.touches = touches.slice();
│ │ │ │ │ - handler(e);
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - OpenLayers.Event.observe(element, 'MSPointerDown', cb);
│ │ │ │ │ -
│ │ │ │ │ - // Need to also listen for end events to keep the _msTouches list
│ │ │ │ │ - // accurate
│ │ │ │ │ - var internalCb = function(e) {
│ │ │ │ │ - for (var i = 0, ii = touches.length; i < ii; ++i) {
│ │ │ │ │ - if (touches[i].pointerId == e.pointerId) {
│ │ │ │ │ - touches.splice(i, 1);
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - };
│ │ │ │ │ - OpenLayers.Event.observe(element, 'MSPointerUp', internalCb);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: addMsTouchListenerMove
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * element - {DOMElement} The DOM element to register the listener on
│ │ │ │ │ - * type - {String} The event type
│ │ │ │ │ - * handler - {Function} the handler
│ │ │ │ │ - */
│ │ │ │ │ - addMsTouchListenerMove: function(element, type, handler) {
│ │ │ │ │ - var touches = this._msTouches;
│ │ │ │ │ - var cb = function(e) {
│ │ │ │ │ -
│ │ │ │ │ - //Don't fire touch moves when mouse isn't down
│ │ │ │ │ - if (e.pointerType == e.MSPOINTER_TYPE_MOUSE && e.buttons == 0) {
│ │ │ │ │ - return;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - if (touches.length == 1 && touches[0].pageX == e.pageX &&
│ │ │ │ │ - touches[0].pageY == e.pageY) {
│ │ │ │ │ - // don't trigger event when pointer has not moved
│ │ │ │ │ - return;
│ │ │ │ │ - }
│ │ │ │ │ - for (var i = 0, ii = touches.length; i < ii; ++i) {
│ │ │ │ │ - if (touches[i].pointerId == e.pointerId) {
│ │ │ │ │ - touches[i] = e;
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - e.touches = touches.slice();
│ │ │ │ │ - handler(e);
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - OpenLayers.Event.observe(element, 'MSPointerMove', cb);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: addMsTouchListenerEnd
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * element - {DOMElement} The DOM element to register the listener on
│ │ │ │ │ - * type - {String} The event type
│ │ │ │ │ - * handler - {Function} the handler
│ │ │ │ │ - */
│ │ │ │ │ - addMsTouchListenerEnd: function(element, type, handler) {
│ │ │ │ │ - var touches = this._msTouches;
│ │ │ │ │ -
│ │ │ │ │ - var cb = function(e) {
│ │ │ │ │ -
│ │ │ │ │ - for (var i = 0, ii = touches.length; i < ii; ++i) {
│ │ │ │ │ - if (touches[i].pointerId == e.pointerId) {
│ │ │ │ │ - touches.splice(i, 1);
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - e.touches = touches.slice();
│ │ │ │ │ - handler(e);
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - OpenLayers.Event.observe(element, 'MSPointerUp', cb);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Events"
│ │ │ │ │ -});
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Animation.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/SingleFile.js
│ │ │ │ │ - * @requires OpenLayers/Util/vendorPrefix.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Namespace: OpenLayers.Animation
│ │ │ │ │ - * A collection of utility functions for executing methods that repaint a
│ │ │ │ │ - * portion of the browser window. These methods take advantage of the
│ │ │ │ │ - * browser's scheduled repaints where requestAnimationFrame is available.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Animation = (function(window) {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: isNative
│ │ │ │ │ - * {Boolean} true if a native requestAnimationFrame function is available
│ │ │ │ │ - */
│ │ │ │ │ - var requestAnimationFrame = OpenLayers.Util.vendorPrefix.js(window, "requestAnimationFrame");
│ │ │ │ │ - var isNative = !!(requestAnimationFrame);
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Function: requestFrame
│ │ │ │ │ - * Schedule a function to be called at the next available animation frame.
│ │ │ │ │ - * Uses the native method where available. Where requestAnimationFrame is
│ │ │ │ │ - * not available, setTimeout will be called with a 16ms delay.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * callback - {Function} The function to be called at the next animation frame.
│ │ │ │ │ - * element - {DOMElement} Optional element that visually bounds the animation.
│ │ │ │ │ - */
│ │ │ │ │ - var requestFrame = (function() {
│ │ │ │ │ - var request = window[requestAnimationFrame] ||
│ │ │ │ │ - function(callback, element) {
│ │ │ │ │ - window.setTimeout(callback, 16);
│ │ │ │ │ - };
│ │ │ │ │ - // bind to window to avoid illegal invocation of native function
│ │ │ │ │ - return function(callback, element) {
│ │ │ │ │ - request.apply(window, [callback, element]);
│ │ │ │ │ - };
│ │ │ │ │ - })();
│ │ │ │ │ -
│ │ │ │ │ - // private variables for animation loops
│ │ │ │ │ - var counter = 0;
│ │ │ │ │ - var loops = {};
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Function: start
│ │ │ │ │ - * Executes a method with in series for some
│ │ │ │ │ - * duration.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * callback - {Function} The function to be called at the next animation frame.
│ │ │ │ │ - * duration - {Number} Optional duration for the loop. If not provided, the
│ │ │ │ │ - * animation loop will execute indefinitely.
│ │ │ │ │ - * element - {DOMElement} Optional element that visually bounds the animation.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Number} Identifier for the animation loop. Used to stop animations with
│ │ │ │ │ - * .
│ │ │ │ │ - */
│ │ │ │ │ - function start(callback, duration, element) {
│ │ │ │ │ - duration = duration > 0 ? duration : Number.POSITIVE_INFINITY;
│ │ │ │ │ - var id = ++counter;
│ │ │ │ │ - var start = +new Date;
│ │ │ │ │ - loops[id] = function() {
│ │ │ │ │ - if (loops[id] && +new Date - start <= duration) {
│ │ │ │ │ - callback();
│ │ │ │ │ - if (loops[id]) {
│ │ │ │ │ - requestFrame(loops[id], element);
│ │ │ │ │ - }
│ │ │ │ │ - } else {
│ │ │ │ │ - delete loops[id];
│ │ │ │ │ - }
│ │ │ │ │ - };
│ │ │ │ │ - requestFrame(loops[id], element);
│ │ │ │ │ - return id;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Function: stop
│ │ │ │ │ - * Terminates an animation loop started with .
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * id - {Number} Identifier returned from .
│ │ │ │ │ - */
│ │ │ │ │ - function stop(id) {
│ │ │ │ │ - delete loops[id];
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - return {
│ │ │ │ │ - isNative: isNative,
│ │ │ │ │ - requestFrame: requestFrame,
│ │ │ │ │ - start: start,
│ │ │ │ │ - stop: stop
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ -})(window);
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Tween.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ -
│ │ │ │ │ -/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ - * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ - * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ - * full text of the license. */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ - * @requires OpenLayers/Animation.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Namespace: OpenLayers.Tween
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Tween = OpenLayers.Class({
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: easing
│ │ │ │ │ - * {(Function)} Easing equation used for the animation
│ │ │ │ │ - * Defaultly set to OpenLayers.Easing.Expo.easeOut
│ │ │ │ │ - */
│ │ │ │ │ - easing: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: begin
│ │ │ │ │ - * {Object} Values to start the animation with
│ │ │ │ │ - */
│ │ │ │ │ - begin: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: finish
│ │ │ │ │ - * {Object} Values to finish the animation with
│ │ │ │ │ - */
│ │ │ │ │ - finish: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: duration
│ │ │ │ │ - * {int} duration of the tween (number of steps)
│ │ │ │ │ - */
│ │ │ │ │ - duration: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: callbacks
│ │ │ │ │ - * {Object} An object with start, eachStep and done properties whose values
│ │ │ │ │ - * are functions to be call during the animation. They are passed the
│ │ │ │ │ - * current computed value as argument.
│ │ │ │ │ - */
│ │ │ │ │ - callbacks: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: time
│ │ │ │ │ - * {int} Step counter
│ │ │ │ │ - */
│ │ │ │ │ - time: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: minFrameRate
│ │ │ │ │ - * {Number} The minimum framerate for animations in frames per second. After
│ │ │ │ │ - * each step, the time spent in the animation is compared to the calculated
│ │ │ │ │ - * time at this frame rate. If the animation runs longer than the calculated
│ │ │ │ │ - * time, the next step is skipped. Default is 30.
│ │ │ │ │ - */
│ │ │ │ │ - minFrameRate: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: startTime
│ │ │ │ │ - * {Number} The timestamp of the first execution step. Used for skipping
│ │ │ │ │ - * frames
│ │ │ │ │ - */
│ │ │ │ │ - startTime: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: animationId
│ │ │ │ │ - * {int} Loop id returned by OpenLayers.Animation.start
│ │ │ │ │ - */
│ │ │ │ │ - animationId: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: playing
│ │ │ │ │ - * {Boolean} Tells if the easing is currently playing
│ │ │ │ │ - */
│ │ │ │ │ - playing: false,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Tween
│ │ │ │ │ - * Creates a Tween.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * easing - {(Function)} easing function method to use
│ │ │ │ │ - */
│ │ │ │ │ - initialize: function(easing) {
│ │ │ │ │ - this.easing = (easing) ? easing : OpenLayers.Easing.Expo.easeOut;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: start
│ │ │ │ │ - * Plays the Tween, and calls the callback method on each step
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * begin - {Object} values to start the animation with
│ │ │ │ │ - * finish - {Object} values to finish the animation with
│ │ │ │ │ - * duration - {int} duration of the tween (number of steps)
│ │ │ │ │ - * options - {Object} hash of options (callbacks (start, eachStep, done),
│ │ │ │ │ - * minFrameRate)
│ │ │ │ │ - */
│ │ │ │ │ - start: function(begin, finish, duration, options) {
│ │ │ │ │ - this.playing = true;
│ │ │ │ │ - this.begin = begin;
│ │ │ │ │ - this.finish = finish;
│ │ │ │ │ - this.duration = duration;
│ │ │ │ │ - this.callbacks = options.callbacks;
│ │ │ │ │ - this.minFrameRate = options.minFrameRate || 30;
│ │ │ │ │ - this.time = 0;
│ │ │ │ │ - this.startTime = new Date().getTime();
│ │ │ │ │ - OpenLayers.Animation.stop(this.animationId);
│ │ │ │ │ - this.animationId = null;
│ │ │ │ │ - if (this.callbacks && this.callbacks.start) {
│ │ │ │ │ - this.callbacks.start.call(this, this.begin);
│ │ │ │ │ - }
│ │ │ │ │ - this.animationId = OpenLayers.Animation.start(
│ │ │ │ │ - OpenLayers.Function.bind(this.play, this)
│ │ │ │ │ - );
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: stop
│ │ │ │ │ - * Stops the Tween, and calls the done callback
│ │ │ │ │ - * Doesn't do anything if animation is already finished
│ │ │ │ │ - */
│ │ │ │ │ - stop: function() {
│ │ │ │ │ - if (!this.playing) {
│ │ │ │ │ - return;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - if (this.callbacks && this.callbacks.done) {
│ │ │ │ │ - this.callbacks.done.call(this, this.finish);
│ │ │ │ │ - }
│ │ │ │ │ - OpenLayers.Animation.stop(this.animationId);
│ │ │ │ │ - this.animationId = null;
│ │ │ │ │ - this.playing = false;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: play
│ │ │ │ │ - * Calls the appropriate easing method
│ │ │ │ │ - */
│ │ │ │ │ - play: function() {
│ │ │ │ │ - var value = {};
│ │ │ │ │ - for (var i in this.begin) {
│ │ │ │ │ - var b = this.begin[i];
│ │ │ │ │ - var f = this.finish[i];
│ │ │ │ │ - if (b == null || f == null || isNaN(b) || isNaN(f)) {
│ │ │ │ │ - throw new TypeError('invalid value for Tween');
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - var c = f - b;
│ │ │ │ │ - value[i] = this.easing.apply(this, [this.time, b, c, this.duration]);
│ │ │ │ │ - }
│ │ │ │ │ - this.time++;
│ │ │ │ │ -
│ │ │ │ │ - if (this.callbacks && this.callbacks.eachStep) {
│ │ │ │ │ - // skip frames if frame rate drops below threshold
│ │ │ │ │ - if ((new Date().getTime() - this.startTime) / this.time <= 1000 / this.minFrameRate) {
│ │ │ │ │ - this.callbacks.eachStep.call(this, value);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - if (this.time > this.duration) {
│ │ │ │ │ - this.stop();
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Create empty functions for all easing methods.
│ │ │ │ │ - */
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Tween"
│ │ │ │ │ -});
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Namespace: OpenLayers.Easing
│ │ │ │ │ - *
│ │ │ │ │ - * Credits:
│ │ │ │ │ - * Easing Equations by Robert Penner,
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Easing = {
│ │ │ │ │ - /**
│ │ │ │ │ - * Create empty functions for all easing methods.
│ │ │ │ │ - */
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Easing"
│ │ │ │ │ -};
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Namespace: OpenLayers.Easing.Linear
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Easing.Linear = {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Function: easeIn
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * t - {Float} time
│ │ │ │ │ - * b - {Float} beginning position
│ │ │ │ │ - * c - {Float} total change
│ │ │ │ │ - * d - {Float} duration of the transition
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Float}
│ │ │ │ │ - */
│ │ │ │ │ - easeIn: function(t, b, c, d) {
│ │ │ │ │ - return c * t / d + b;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Function: easeOut
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * t - {Float} time
│ │ │ │ │ - * b - {Float} beginning position
│ │ │ │ │ - * c - {Float} total change
│ │ │ │ │ - * d - {Float} duration of the transition
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Float}
│ │ │ │ │ - */
│ │ │ │ │ - easeOut: function(t, b, c, d) {
│ │ │ │ │ - return c * t / d + b;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Function: easeInOut
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * t - {Float} time
│ │ │ │ │ - * b - {Float} beginning position
│ │ │ │ │ - * c - {Float} total change
│ │ │ │ │ - * d - {Float} duration of the transition
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Float}
│ │ │ │ │ - */
│ │ │ │ │ - easeInOut: function(t, b, c, d) {
│ │ │ │ │ - return c * t / d + b;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Easing.Linear"
│ │ │ │ │ -};
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Namespace: OpenLayers.Easing.Expo
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Easing.Expo = {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Function: easeIn
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * t - {Float} time
│ │ │ │ │ - * b - {Float} beginning position
│ │ │ │ │ - * c - {Float} total change
│ │ │ │ │ - * d - {Float} duration of the transition
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Float}
│ │ │ │ │ - */
│ │ │ │ │ - easeIn: function(t, b, c, d) {
│ │ │ │ │ - return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Function: easeOut
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * t - {Float} time
│ │ │ │ │ - * b - {Float} beginning position
│ │ │ │ │ - * c - {Float} total change
│ │ │ │ │ - * d - {Float} duration of the transition
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Float}
│ │ │ │ │ - */
│ │ │ │ │ - easeOut: function(t, b, c, d) {
│ │ │ │ │ - return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Function: easeInOut
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * t - {Float} time
│ │ │ │ │ - * b - {Float} beginning position
│ │ │ │ │ - * c - {Float} total change
│ │ │ │ │ - * d - {Float} duration of the transition
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Float}
│ │ │ │ │ - */
│ │ │ │ │ - easeInOut: function(t, b, c, d) {
│ │ │ │ │ - if (t == 0) return b;
│ │ │ │ │ - if (t == d) return b + c;
│ │ │ │ │ - if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
│ │ │ │ │ - return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Easing.Expo"
│ │ │ │ │ -};
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Namespace: OpenLayers.Easing.Quad
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Easing.Quad = {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Function: easeIn
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * t - {Float} time
│ │ │ │ │ - * b - {Float} beginning position
│ │ │ │ │ - * c - {Float} total change
│ │ │ │ │ - * d - {Float} duration of the transition
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Float}
│ │ │ │ │ - */
│ │ │ │ │ - easeIn: function(t, b, c, d) {
│ │ │ │ │ - return c * (t /= d) * t + b;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Function: easeOut
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * t - {Float} time
│ │ │ │ │ - * b - {Float} beginning position
│ │ │ │ │ - * c - {Float} total change
│ │ │ │ │ - * d - {Float} duration of the transition
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Float}
│ │ │ │ │ - */
│ │ │ │ │ - easeOut: function(t, b, c, d) {
│ │ │ │ │ - return -c * (t /= d) * (t - 2) + b;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Function: easeInOut
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * t - {Float} time
│ │ │ │ │ - * b - {Float} beginning position
│ │ │ │ │ - * c - {Float} total change
│ │ │ │ │ - * d - {Float} duration of the transition
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Float}
│ │ │ │ │ - */
│ │ │ │ │ - easeInOut: function(t, b, c, d) {
│ │ │ │ │ - if ((t /= d / 2) < 1) return c / 2 * t * t + b;
│ │ │ │ │ - return -c / 2 * ((--t) * (t - 2) - 1) + b;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Easing.Quad"
│ │ │ │ │ -};
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ OpenLayers/Map.js
│ │ │ │ │ ====================================================================== */
│ │ │ │ │
│ │ │ │ │ /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ * full text of the license. */
│ │ │ │ │ @@ -12775,6895 +9457,2715 @@
│ │ │ │ │ OpenLayers.Map.TILE_WIDTH = 256;
│ │ │ │ │ /**
│ │ │ │ │ * Constant: TILE_HEIGHT
│ │ │ │ │ * {Integer} 256 Default tile height (unless otherwise specified)
│ │ │ │ │ */
│ │ │ │ │ OpenLayers.Map.TILE_HEIGHT = 256;
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Layer.js
│ │ │ │ │ + OpenLayers/Icon.js
│ │ │ │ │ ====================================================================== */
│ │ │ │ │
│ │ │ │ │ /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ * full text of the license. */
│ │ │ │ │
│ │ │ │ │ -
│ │ │ │ │ /**
│ │ │ │ │ * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ - * @requires OpenLayers/Map.js
│ │ │ │ │ - * @requires OpenLayers/Projection.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Class: OpenLayers.Layer
│ │ │ │ │ + * Class: OpenLayers.Icon
│ │ │ │ │ + *
│ │ │ │ │ + * The icon represents a graphical icon on the screen. Typically used in
│ │ │ │ │ + * conjunction with a to represent markers on a screen.
│ │ │ │ │ + *
│ │ │ │ │ + * An icon has a url, size and position. It also contains an offset which
│ │ │ │ │ + * allows the center point to be represented correctly. This can be
│ │ │ │ │ + * provided either as a fixed offset or a function provided to calculate
│ │ │ │ │ + * the desired offset.
│ │ │ │ │ + *
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Layer = OpenLayers.Class({
│ │ │ │ │ +OpenLayers.Icon = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: id
│ │ │ │ │ - * {String}
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: url
│ │ │ │ │ + * {String} image url
│ │ │ │ │ */
│ │ │ │ │ - id: null,
│ │ │ │ │ + url: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: name
│ │ │ │ │ - * {String}
│ │ │ │ │ + * Property: size
│ │ │ │ │ + * {|Object} An OpenLayers.Size or
│ │ │ │ │ + * an object with a 'w' and 'h' properties.
│ │ │ │ │ */
│ │ │ │ │ - name: null,
│ │ │ │ │ + size: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: div
│ │ │ │ │ - * {DOMElement}
│ │ │ │ │ + * Property: offset
│ │ │ │ │ + * {|Object} distance in pixels to offset the
│ │ │ │ │ + * image when being rendered. An OpenLayers.Pixel or an object
│ │ │ │ │ + * with a 'x' and 'y' properties.
│ │ │ │ │ */
│ │ │ │ │ - div: null,
│ │ │ │ │ + offset: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: opacity
│ │ │ │ │ - * {Float} The layer's opacity. Float number between 0.0 and 1.0. Default
│ │ │ │ │ - * is 1.
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: calculateOffset
│ │ │ │ │ + * {Function} Function to calculate the offset (based on the size)
│ │ │ │ │ */
│ │ │ │ │ - opacity: 1,
│ │ │ │ │ + calculateOffset: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: alwaysInRange
│ │ │ │ │ - * {Boolean} If a layer's display should not be scale-based, this should
│ │ │ │ │ - * be set to true. This will cause the layer, as an overlay, to always
│ │ │ │ │ - * be 'active', by always returning true from the calculateInRange()
│ │ │ │ │ - * function.
│ │ │ │ │ - *
│ │ │ │ │ - * If not explicitly specified for a layer, its value will be
│ │ │ │ │ - * determined on startup in initResolutions() based on whether or not
│ │ │ │ │ - * any scale-specific properties have been set as options on the
│ │ │ │ │ - * layer. If no scale-specific options have been set on the layer, we
│ │ │ │ │ - * assume that it should always be in range.
│ │ │ │ │ - *
│ │ │ │ │ - * See #987 for more info.
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: imageDiv
│ │ │ │ │ + * {DOMElement}
│ │ │ │ │ */
│ │ │ │ │ - alwaysInRange: null,
│ │ │ │ │ + imageDiv: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Constant: RESOLUTION_PROPERTIES
│ │ │ │ │ - * {Array} The properties that are used for calculating resolutions
│ │ │ │ │ - * information.
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: px
│ │ │ │ │ + * {|Object} An OpenLayers.Pixel or an object
│ │ │ │ │ + * with a 'x' and 'y' properties.
│ │ │ │ │ */
│ │ │ │ │ - RESOLUTION_PROPERTIES: [
│ │ │ │ │ - 'scales', 'resolutions',
│ │ │ │ │ - 'maxScale', 'minScale',
│ │ │ │ │ - 'maxResolution', 'minResolution',
│ │ │ │ │ - 'numZoomLevels', 'maxZoomLevel'
│ │ │ │ │ - ],
│ │ │ │ │ + px: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: events
│ │ │ │ │ - * {}
│ │ │ │ │ - *
│ │ │ │ │ - * Register a listener for a particular event with the following syntax:
│ │ │ │ │ - * (code)
│ │ │ │ │ - * layer.events.register(type, obj, listener);
│ │ │ │ │ - * (end)
│ │ │ │ │ - *
│ │ │ │ │ - * Listeners will be called with a reference to an event object. The
│ │ │ │ │ - * properties of this event depends on exactly what happened.
│ │ │ │ │ - *
│ │ │ │ │ - * All event objects have at least the following properties:
│ │ │ │ │ - * object - {Object} A reference to layer.events.object.
│ │ │ │ │ - * element - {DOMElement} A reference to layer.events.element.
│ │ │ │ │ + /**
│ │ │ │ │ + * Constructor: OpenLayers.Icon
│ │ │ │ │ + * Creates an icon, which is an image tag in a div.
│ │ │ │ │ *
│ │ │ │ │ - * Supported map event types:
│ │ │ │ │ - * loadstart - Triggered when layer loading starts. When using a Vector
│ │ │ │ │ - * layer with a Fixed or BBOX strategy, the event object includes
│ │ │ │ │ - * a *filter* property holding the OpenLayers.Filter used when
│ │ │ │ │ - * calling read on the protocol.
│ │ │ │ │ - * loadend - Triggered when layer loading ends. When using a Vector layer
│ │ │ │ │ - * with a Fixed or BBOX strategy, the event object includes a
│ │ │ │ │ - * *response* property holding an OpenLayers.Protocol.Response object.
│ │ │ │ │ - * visibilitychanged - Triggered when the layer's visibility property is
│ │ │ │ │ - * changed, e.g. by turning the layer on or off in the layer switcher.
│ │ │ │ │ - * Note that the actual visibility of the layer can also change if it
│ │ │ │ │ - * gets out of range (see ). If you also want to catch
│ │ │ │ │ - * these cases, register for the map's 'changelayer' event instead.
│ │ │ │ │ - * move - Triggered when layer moves (triggered with every mousemove
│ │ │ │ │ - * during a drag).
│ │ │ │ │ - * moveend - Triggered when layer is done moving, object passed as
│ │ │ │ │ - * argument has a zoomChanged boolean property which tells that the
│ │ │ │ │ - * zoom has changed.
│ │ │ │ │ - * added - Triggered after the layer is added to a map. Listeners will
│ │ │ │ │ - * receive an object with a *map* property referencing the map and a
│ │ │ │ │ - * *layer* property referencing the layer.
│ │ │ │ │ - * removed - Triggered after the layer is removed from the map. Listeners
│ │ │ │ │ - * will receive an object with a *map* property referencing the map and
│ │ │ │ │ - * a *layer* property referencing the layer.
│ │ │ │ │ + * url - {String}
│ │ │ │ │ + * size - {|Object} An OpenLayers.Size or an
│ │ │ │ │ + * object with a 'w' and 'h'
│ │ │ │ │ + * properties.
│ │ │ │ │ + * offset - {|Object} An OpenLayers.Pixel or an
│ │ │ │ │ + * object with a 'x' and 'y'
│ │ │ │ │ + * properties.
│ │ │ │ │ + * calculateOffset - {Function}
│ │ │ │ │ */
│ │ │ │ │ - events: null,
│ │ │ │ │ + initialize: function(url, size, offset, calculateOffset) {
│ │ │ │ │ + this.url = url;
│ │ │ │ │ + this.size = size || {
│ │ │ │ │ + w: 20,
│ │ │ │ │ + h: 20
│ │ │ │ │ + };
│ │ │ │ │ + this.offset = offset || {
│ │ │ │ │ + x: -(this.size.w / 2),
│ │ │ │ │ + y: -(this.size.h / 2)
│ │ │ │ │ + };
│ │ │ │ │ + this.calculateOffset = calculateOffset;
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: map
│ │ │ │ │ - * {} This variable is set when the layer is added to
│ │ │ │ │ - * the map, via the accessor function setMap().
│ │ │ │ │ - */
│ │ │ │ │ - map: null,
│ │ │ │ │ + var id = OpenLayers.Util.createUniqueID("OL_Icon_");
│ │ │ │ │ + this.imageDiv = OpenLayers.Util.createAlphaImageDiv(id);
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: isBaseLayer
│ │ │ │ │ - * {Boolean} Whether or not the layer is a base layer. This should be set
│ │ │ │ │ - * individually by all subclasses. Default is false
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: destroy
│ │ │ │ │ + * Nullify references and remove event listeners to prevent circular
│ │ │ │ │ + * references and memory leaks
│ │ │ │ │ */
│ │ │ │ │ - isBaseLayer: false,
│ │ │ │ │ + destroy: function() {
│ │ │ │ │ + // erase any drawn elements
│ │ │ │ │ + this.erase();
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: alpha
│ │ │ │ │ - * {Boolean} The layer's images have an alpha channel. Default is false.
│ │ │ │ │ - */
│ │ │ │ │ - alpha: false,
│ │ │ │ │ + OpenLayers.Event.stopObservingElement(this.imageDiv.firstChild);
│ │ │ │ │ + this.imageDiv.innerHTML = "";
│ │ │ │ │ + this.imageDiv = null;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: displayInLayerSwitcher
│ │ │ │ │ - * {Boolean} Display the layer's name in the layer switcher. Default is
│ │ │ │ │ - * true.
│ │ │ │ │ + * Method: clone
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {} A fresh copy of the icon.
│ │ │ │ │ */
│ │ │ │ │ - displayInLayerSwitcher: true,
│ │ │ │ │ + clone: function() {
│ │ │ │ │ + return new OpenLayers.Icon(this.url,
│ │ │ │ │ + this.size,
│ │ │ │ │ + this.offset,
│ │ │ │ │ + this.calculateOffset);
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: visibility
│ │ │ │ │ - * {Boolean} The layer should be displayed in the map. Default is true.
│ │ │ │ │ + * Method: setSize
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * size - {|Object} An OpenLayers.Size or
│ │ │ │ │ + * an object with a 'w' and 'h' properties.
│ │ │ │ │ */
│ │ │ │ │ - visibility: true,
│ │ │ │ │ + setSize: function(size) {
│ │ │ │ │ + if (size != null) {
│ │ │ │ │ + this.size = size;
│ │ │ │ │ + }
│ │ │ │ │ + this.draw();
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: attribution
│ │ │ │ │ - * {String} Attribution string, displayed when an
│ │ │ │ │ - * has been added to the map.
│ │ │ │ │ + * Method: setUrl
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * url - {String}
│ │ │ │ │ */
│ │ │ │ │ - attribution: null,
│ │ │ │ │ + setUrl: function(url) {
│ │ │ │ │ + if (url != null) {
│ │ │ │ │ + this.url = url;
│ │ │ │ │ + }
│ │ │ │ │ + this.draw();
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: inRange
│ │ │ │ │ - * {Boolean} The current map resolution is within the layer's min/max
│ │ │ │ │ - * range. This is set in whenever the zoom
│ │ │ │ │ - * changes.
│ │ │ │ │ - */
│ │ │ │ │ - inRange: false,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Propery: imageSize
│ │ │ │ │ - * {} For layers with a gutter, the image is larger than
│ │ │ │ │ - * the tile by twice the gutter in each dimension.
│ │ │ │ │ + * Method: draw
│ │ │ │ │ + * Move the div to the given pixel.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * px - {|Object} An OpenLayers.Pixel or an
│ │ │ │ │ + * object with a 'x' and 'y' properties.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {DOMElement} A new DOM Image of this icon set at the location passed-in
│ │ │ │ │ */
│ │ │ │ │ - imageSize: null,
│ │ │ │ │ -
│ │ │ │ │ - // OPTIONS
│ │ │ │ │ + draw: function(px) {
│ │ │ │ │ + OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv,
│ │ │ │ │ + null,
│ │ │ │ │ + null,
│ │ │ │ │ + this.size,
│ │ │ │ │ + this.url,
│ │ │ │ │ + "absolute");
│ │ │ │ │ + this.moveTo(px);
│ │ │ │ │ + return this.imageDiv;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: options
│ │ │ │ │ - * {Object} An optional object whose properties will be set on the layer.
│ │ │ │ │ - * Any of the layer properties can be set as a property of the options
│ │ │ │ │ - * object and sent to the constructor when the layer is created.
│ │ │ │ │ + * Method: erase
│ │ │ │ │ + * Erase the underlying image element.
│ │ │ │ │ */
│ │ │ │ │ - options: null,
│ │ │ │ │ + erase: function() {
│ │ │ │ │ + if (this.imageDiv != null && this.imageDiv.parentNode != null) {
│ │ │ │ │ + OpenLayers.Element.remove(this.imageDiv);
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: eventListeners
│ │ │ │ │ - * {Object} If set as an option at construction, the eventListeners
│ │ │ │ │ - * object will be registered with . Object
│ │ │ │ │ - * structure must be a listeners object as shown in the example for
│ │ │ │ │ - * the events.on method.
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: setOpacity
│ │ │ │ │ + * Change the icon's opacity
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * opacity - {float}
│ │ │ │ │ */
│ │ │ │ │ - eventListeners: null,
│ │ │ │ │ + setOpacity: function(opacity) {
│ │ │ │ │ + OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv, null, null, null,
│ │ │ │ │ + null, null, null, null, opacity);
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: gutter
│ │ │ │ │ - * {Integer} Determines the width (in pixels) of the gutter around image
│ │ │ │ │ - * tiles to ignore. By setting this property to a non-zero value,
│ │ │ │ │ - * images will be requested that are wider and taller than the tile
│ │ │ │ │ - * size by a value of 2 x gutter. This allows artifacts of rendering
│ │ │ │ │ - * at tile edges to be ignored. Set a gutter value that is equal to
│ │ │ │ │ - * half the size of the widest symbol that needs to be displayed.
│ │ │ │ │ - * Defaults to zero. Non-tiled layers always have zero gutter.
│ │ │ │ │ - */
│ │ │ │ │ - gutter: 0,
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: projection
│ │ │ │ │ - * {} or {} Specifies the projection of the layer.
│ │ │ │ │ - * Can be set in the layer options. If not specified in the layer options,
│ │ │ │ │ - * it is set to the default projection specified in the map,
│ │ │ │ │ - * when the layer is added to the map.
│ │ │ │ │ - * Projection along with default maxExtent and resolutions
│ │ │ │ │ - * are set automatically with commercial baselayers in EPSG:3857,
│ │ │ │ │ - * such as Google, Bing and OpenStreetMap, and do not need to be specified.
│ │ │ │ │ - * Otherwise, if specifying projection, also set maxExtent,
│ │ │ │ │ - * maxResolution or resolutions as appropriate.
│ │ │ │ │ - * When using vector layers with strategies, layer projection should be set
│ │ │ │ │ - * to the projection of the source data if that is different from the map default.
│ │ │ │ │ - *
│ │ │ │ │ - * Can be either a string or an object;
│ │ │ │ │ - * if a string is passed, will be converted to an object when
│ │ │ │ │ - * the layer is added to the map.
│ │ │ │ │ - *
│ │ │ │ │ + * Method: moveTo
│ │ │ │ │ + * move icon to passed in px.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * px - {|Object} the pixel position to move to.
│ │ │ │ │ + * An OpenLayers.Pixel or an object with a 'x' and 'y' properties.
│ │ │ │ │ */
│ │ │ │ │ - projection: null,
│ │ │ │ │ + moveTo: function(px) {
│ │ │ │ │ + //if no px passed in, use stored location
│ │ │ │ │ + if (px != null) {
│ │ │ │ │ + this.px = px;
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: units
│ │ │ │ │ - * {String} The layer map units. Defaults to null. Possible values
│ │ │ │ │ - * are 'degrees' (or 'dd'), 'm', 'ft', 'km', 'mi', 'inches'.
│ │ │ │ │ - * Normally taken from the projection.
│ │ │ │ │ - * Only required if both map and layers do not define a projection,
│ │ │ │ │ - * or if they define a projection which does not define units.
│ │ │ │ │ - */
│ │ │ │ │ - units: null,
│ │ │ │ │ + if (this.imageDiv != null) {
│ │ │ │ │ + if (this.px == null) {
│ │ │ │ │ + this.display(false);
│ │ │ │ │ + } else {
│ │ │ │ │ + if (this.calculateOffset) {
│ │ │ │ │ + this.offset = this.calculateOffset(this.size);
│ │ │ │ │ + }
│ │ │ │ │ + OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv, null, {
│ │ │ │ │ + x: this.px.x + this.offset.x,
│ │ │ │ │ + y: this.px.y + this.offset.y
│ │ │ │ │ + });
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: scales
│ │ │ │ │ - * {Array} An array of map scales in descending order. The values in the
│ │ │ │ │ - * array correspond to the map scale denominator. Note that these
│ │ │ │ │ - * values only make sense if the display (monitor) resolution of the
│ │ │ │ │ - * client is correctly guessed by whomever is configuring the
│ │ │ │ │ - * application. In addition, the units property must also be set.
│ │ │ │ │ - * Use instead wherever possible.
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: display
│ │ │ │ │ + * Hide or show the icon
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * display - {Boolean}
│ │ │ │ │ */
│ │ │ │ │ - scales: null,
│ │ │ │ │ + display: function(display) {
│ │ │ │ │ + this.imageDiv.style.display = (display) ? "" : "none";
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: resolutions
│ │ │ │ │ - * {Array} A list of map resolutions (map units per pixel) in descending
│ │ │ │ │ - * order. If this is not set in the layer constructor, it will be set
│ │ │ │ │ - * based on other resolution related properties (maxExtent,
│ │ │ │ │ - * maxResolution, maxScale, etc.).
│ │ │ │ │ - */
│ │ │ │ │ - resolutions: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: maxExtent
│ │ │ │ │ - * {|Array} If provided as an array, the array
│ │ │ │ │ - * should consist of four values (left, bottom, right, top).
│ │ │ │ │ - * The maximum extent for the layer. Defaults to null.
│ │ │ │ │ + * APIMethod: isDrawn
│ │ │ │ │ *
│ │ │ │ │ - * The center of these bounds will not stray outside
│ │ │ │ │ - * of the viewport extent during panning. In addition, if
│ │ │ │ │ - * is set to false, data will not be
│ │ │ │ │ - * requested that falls completely outside of these bounds.
│ │ │ │ │ - */
│ │ │ │ │ - maxExtent: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: minExtent
│ │ │ │ │ - * {|Array} If provided as an array, the array
│ │ │ │ │ - * should consist of four values (left, bottom, right, top).
│ │ │ │ │ - * The minimum extent for the layer. Defaults to null.
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean} Whether or not the icon is drawn.
│ │ │ │ │ */
│ │ │ │ │ - minExtent: null,
│ │ │ │ │ + isDrawn: function() {
│ │ │ │ │ + // nodeType 11 for ie, whose nodes *always* have a parentNode
│ │ │ │ │ + // (of type document fragment)
│ │ │ │ │ + var isDrawn = (this.imageDiv && this.imageDiv.parentNode &&
│ │ │ │ │ + (this.imageDiv.parentNode.nodeType != 11));
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: maxResolution
│ │ │ │ │ - * {Float} Default max is 360 deg / 256 px, which corresponds to
│ │ │ │ │ - * zoom level 0 on gmaps. Specify a different value in the layer
│ │ │ │ │ - * options if you are not using the default
│ │ │ │ │ - * and displaying the whole world.
│ │ │ │ │ - */
│ │ │ │ │ - maxResolution: null,
│ │ │ │ │ + return isDrawn;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: minResolution
│ │ │ │ │ - * {Float}
│ │ │ │ │ - */
│ │ │ │ │ - minResolution: null,
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Icon"
│ │ │ │ │ +});
│ │ │ │ │ +/* ======================================================================
│ │ │ │ │ + OpenLayers/Geometry.js
│ │ │ │ │ + ====================================================================== */
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: numZoomLevels
│ │ │ │ │ - * {Integer}
│ │ │ │ │ - */
│ │ │ │ │ - numZoomLevels: null,
│ │ │ │ │ +/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ + * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ + * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ + * full text of the license. */
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: minScale
│ │ │ │ │ - * {Float}
│ │ │ │ │ - */
│ │ │ │ │ - minScale: null,
│ │ │ │ │ +/**
│ │ │ │ │ + * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ + */
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: maxScale
│ │ │ │ │ - * {Float}
│ │ │ │ │ - */
│ │ │ │ │ - maxScale: null,
│ │ │ │ │ +/**
│ │ │ │ │ + * Class: OpenLayers.Geometry
│ │ │ │ │ + * A Geometry is a description of a geographic object. Create an instance of
│ │ │ │ │ + * this class with the constructor. This is a base class,
│ │ │ │ │ + * typical geometry types are described by subclasses of this class.
│ │ │ │ │ + *
│ │ │ │ │ + * Note that if you use the method, you must
│ │ │ │ │ + * explicitly include the OpenLayers.Format.WKT in your build.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Geometry = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: displayOutsideMaxExtent
│ │ │ │ │ - * {Boolean} Request map tiles that are completely outside of the max
│ │ │ │ │ - * extent for this layer. Defaults to false.
│ │ │ │ │ + * Property: id
│ │ │ │ │ + * {String} A unique identifier for this geometry.
│ │ │ │ │ */
│ │ │ │ │ - displayOutsideMaxExtent: false,
│ │ │ │ │ + id: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: wrapDateLine
│ │ │ │ │ - * {Boolean} Wraps the world at the international dateline, so the map can
│ │ │ │ │ - * be panned infinitely in longitudinal direction. Only use this on the
│ │ │ │ │ - * base layer, and only if the layer's maxExtent equals the world bounds.
│ │ │ │ │ - * #487 for more info.
│ │ │ │ │ + * Property: parent
│ │ │ │ │ + * {}This is set when a Geometry is added as component
│ │ │ │ │ + * of another geometry
│ │ │ │ │ */
│ │ │ │ │ - wrapDateLine: false,
│ │ │ │ │ + parent: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: metadata
│ │ │ │ │ - * {Object} This object can be used to store additional information on a
│ │ │ │ │ - * layer object.
│ │ │ │ │ + * Property: bounds
│ │ │ │ │ + * {} The bounds of this geometry
│ │ │ │ │ */
│ │ │ │ │ - metadata: null,
│ │ │ │ │ + bounds: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constructor: OpenLayers.Layer
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * name - {String} The layer name
│ │ │ │ │ - * options - {Object} Hashtable of extra options to tag onto the layer
│ │ │ │ │ + * Constructor: OpenLayers.Geometry
│ │ │ │ │ + * Creates a geometry object.
│ │ │ │ │ */
│ │ │ │ │ - initialize: function(name, options) {
│ │ │ │ │ -
│ │ │ │ │ - this.metadata = {};
│ │ │ │ │ -
│ │ │ │ │ - options = OpenLayers.Util.extend({}, options);
│ │ │ │ │ - // make sure we respect alwaysInRange if set on the prototype
│ │ │ │ │ - if (this.alwaysInRange != null) {
│ │ │ │ │ - options.alwaysInRange = this.alwaysInRange;
│ │ │ │ │ - }
│ │ │ │ │ - this.addOptions(options);
│ │ │ │ │ -
│ │ │ │ │ - this.name = name;
│ │ │ │ │ -
│ │ │ │ │ - if (this.id == null) {
│ │ │ │ │ -
│ │ │ │ │ - this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
│ │ │ │ │ -
│ │ │ │ │ - this.div = OpenLayers.Util.createDiv(this.id);
│ │ │ │ │ - this.div.style.width = "100%";
│ │ │ │ │ - this.div.style.height = "100%";
│ │ │ │ │ - this.div.dir = "ltr";
│ │ │ │ │ -
│ │ │ │ │ - this.events = new OpenLayers.Events(this, this.div);
│ │ │ │ │ - if (this.eventListeners instanceof Object) {
│ │ │ │ │ - this.events.on(this.eventListeners);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - }
│ │ │ │ │ + initialize: function() {
│ │ │ │ │ + this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ * Method: destroy
│ │ │ │ │ - * Destroy is a destructor: this is to alleviate cyclic references which
│ │ │ │ │ - * the Javascript garbage cleaner can not take care of on its own.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * setNewBaseLayer - {Boolean} Set a new base layer when this layer has
│ │ │ │ │ - * been destroyed. Default is true.
│ │ │ │ │ + * Destroy this geometry.
│ │ │ │ │ */
│ │ │ │ │ - destroy: function(setNewBaseLayer) {
│ │ │ │ │ - if (setNewBaseLayer == null) {
│ │ │ │ │ - setNewBaseLayer = true;
│ │ │ │ │ - }
│ │ │ │ │ - if (this.map != null) {
│ │ │ │ │ - this.map.removeLayer(this, setNewBaseLayer);
│ │ │ │ │ - }
│ │ │ │ │ - this.projection = null;
│ │ │ │ │ - this.map = null;
│ │ │ │ │ - this.name = null;
│ │ │ │ │ - this.div = null;
│ │ │ │ │ - this.options = null;
│ │ │ │ │ -
│ │ │ │ │ - if (this.events) {
│ │ │ │ │ - if (this.eventListeners) {
│ │ │ │ │ - this.events.un(this.eventListeners);
│ │ │ │ │ - }
│ │ │ │ │ - this.events.destroy();
│ │ │ │ │ - }
│ │ │ │ │ - this.eventListeners = null;
│ │ │ │ │ - this.events = null;
│ │ │ │ │ + destroy: function() {
│ │ │ │ │ + this.id = null;
│ │ │ │ │ + this.bounds = null;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: clone
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * obj - {} The layer to be cloned
│ │ │ │ │ - *
│ │ │ │ │ + * APIMethod: clone
│ │ │ │ │ + * Create a clone of this geometry. Does not set any non-standard
│ │ │ │ │ + * properties of the cloned geometry.
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {} An exact clone of this
│ │ │ │ │ + * {} An exact clone of this geometry.
│ │ │ │ │ */
│ │ │ │ │ - clone: function(obj) {
│ │ │ │ │ -
│ │ │ │ │ - if (obj == null) {
│ │ │ │ │ - obj = new OpenLayers.Layer(this.name, this.getOptions());
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // catch any randomly tagged-on properties
│ │ │ │ │ - OpenLayers.Util.applyDefaults(obj, this);
│ │ │ │ │ -
│ │ │ │ │ - // a cloned layer should never have its map property set
│ │ │ │ │ - // because it has not been added to a map yet.
│ │ │ │ │ - obj.map = null;
│ │ │ │ │ -
│ │ │ │ │ - return obj;
│ │ │ │ │ + clone: function() {
│ │ │ │ │ + return new OpenLayers.Geometry();
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: getOptions
│ │ │ │ │ - * Extracts an object from the layer with the properties that were set as
│ │ │ │ │ - * options, but updates them with the values currently set on the
│ │ │ │ │ - * instance.
│ │ │ │ │ + * Method: setBounds
│ │ │ │ │ + * Set the bounds for this Geometry.
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Object} the of the layer, representing the current state.
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * bounds - {}
│ │ │ │ │ */
│ │ │ │ │ - getOptions: function() {
│ │ │ │ │ - var options = {};
│ │ │ │ │ - for (var o in this.options) {
│ │ │ │ │ - options[o] = this[o];
│ │ │ │ │ + setBounds: function(bounds) {
│ │ │ │ │ + if (bounds) {
│ │ │ │ │ + this.bounds = bounds.clone();
│ │ │ │ │ }
│ │ │ │ │ - return options;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: setName
│ │ │ │ │ - * Sets the new layer name for this layer. Can trigger a changelayer event
│ │ │ │ │ - * on the map.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * newName - {String} The new name.
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: clearBounds
│ │ │ │ │ + * Nullify this components bounds and that of its parent as well.
│ │ │ │ │ */
│ │ │ │ │ - setName: function(newName) {
│ │ │ │ │ - if (newName != this.name) {
│ │ │ │ │ - this.name = newName;
│ │ │ │ │ - if (this.map != null) {
│ │ │ │ │ - this.map.events.triggerEvent("changelayer", {
│ │ │ │ │ - layer: this,
│ │ │ │ │ - property: "name"
│ │ │ │ │ - });
│ │ │ │ │ - }
│ │ │ │ │ + clearBounds: function() {
│ │ │ │ │ + this.bounds = null;
│ │ │ │ │ + if (this.parent) {
│ │ │ │ │ + this.parent.clearBounds();
│ │ │ │ │ }
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: addOptions
│ │ │ │ │ + * Method: extendBounds
│ │ │ │ │ + * Extend the existing bounds to include the new bounds.
│ │ │ │ │ + * If geometry's bounds is not yet set, then set a new Bounds.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * newOptions - {Object}
│ │ │ │ │ - * reinitialize - {Boolean} If set to true, and if resolution options of the
│ │ │ │ │ - * current baseLayer were changed, the map will be recentered to make
│ │ │ │ │ - * sure that it is displayed with a valid resolution, and a
│ │ │ │ │ - * changebaselayer event will be triggered.
│ │ │ │ │ + * newBounds - {}
│ │ │ │ │ */
│ │ │ │ │ - addOptions: function(newOptions, reinitialize) {
│ │ │ │ │ -
│ │ │ │ │ - if (this.options == null) {
│ │ │ │ │ - this.options = {};
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - if (newOptions) {
│ │ │ │ │ - // make sure this.projection references a projection object
│ │ │ │ │ - if (typeof newOptions.projection == "string") {
│ │ │ │ │ - newOptions.projection = new OpenLayers.Projection(newOptions.projection);
│ │ │ │ │ - }
│ │ │ │ │ - if (newOptions.projection) {
│ │ │ │ │ - // get maxResolution, units and maxExtent from projection defaults if
│ │ │ │ │ - // they are not defined already
│ │ │ │ │ - OpenLayers.Util.applyDefaults(newOptions,
│ │ │ │ │ - OpenLayers.Projection.defaults[newOptions.projection.getCode()]);
│ │ │ │ │ - }
│ │ │ │ │ - // allow array for extents
│ │ │ │ │ - if (newOptions.maxExtent && !(newOptions.maxExtent instanceof OpenLayers.Bounds)) {
│ │ │ │ │ - newOptions.maxExtent = new OpenLayers.Bounds(newOptions.maxExtent);
│ │ │ │ │ - }
│ │ │ │ │ - if (newOptions.minExtent && !(newOptions.minExtent instanceof OpenLayers.Bounds)) {
│ │ │ │ │ - newOptions.minExtent = new OpenLayers.Bounds(newOptions.minExtent);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // update our copy for clone
│ │ │ │ │ - OpenLayers.Util.extend(this.options, newOptions);
│ │ │ │ │ -
│ │ │ │ │ - // add new options to this
│ │ │ │ │ - OpenLayers.Util.extend(this, newOptions);
│ │ │ │ │ -
│ │ │ │ │ - // get the units from the projection, if we have a projection
│ │ │ │ │ - // and it it has units
│ │ │ │ │ - if (this.projection && this.projection.getUnits()) {
│ │ │ │ │ - this.units = this.projection.getUnits();
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // re-initialize resolutions if necessary, i.e. if any of the
│ │ │ │ │ - // properties of the "properties" array defined below is set
│ │ │ │ │ - // in the new options
│ │ │ │ │ - if (this.map) {
│ │ │ │ │ - // store current resolution so we can try to restore it later
│ │ │ │ │ - var resolution = this.map.getResolution();
│ │ │ │ │ - var properties = this.RESOLUTION_PROPERTIES.concat(
│ │ │ │ │ - ["projection", "units", "minExtent", "maxExtent"]
│ │ │ │ │ - );
│ │ │ │ │ - for (var o in newOptions) {
│ │ │ │ │ - if (newOptions.hasOwnProperty(o) &&
│ │ │ │ │ - OpenLayers.Util.indexOf(properties, o) >= 0) {
│ │ │ │ │ -
│ │ │ │ │ - this.initResolutions();
│ │ │ │ │ - if (reinitialize && this.map.baseLayer === this) {
│ │ │ │ │ - // update map position, and restore previous resolution
│ │ │ │ │ - this.map.setCenter(this.map.getCenter(),
│ │ │ │ │ - this.map.getZoomForResolution(resolution),
│ │ │ │ │ - false, true
│ │ │ │ │ - );
│ │ │ │ │ - // trigger a changebaselayer event to make sure that
│ │ │ │ │ - // all controls (especially
│ │ │ │ │ - // OpenLayers.Control.PanZoomBar) get notified of the
│ │ │ │ │ - // new options
│ │ │ │ │ - this.map.events.triggerEvent("changebaselayer", {
│ │ │ │ │ - layer: this
│ │ │ │ │ - });
│ │ │ │ │ - }
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ + extendBounds: function(newBounds) {
│ │ │ │ │ + var bounds = this.getBounds();
│ │ │ │ │ + if (!bounds) {
│ │ │ │ │ + this.setBounds(newBounds);
│ │ │ │ │ + } else {
│ │ │ │ │ + this.bounds.extend(newBounds);
│ │ │ │ │ }
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: onMapResize
│ │ │ │ │ - * This function can be implemented by subclasses
│ │ │ │ │ + * APIMethod: getBounds
│ │ │ │ │ + * Get the bounds for this Geometry. If bounds is not set, it
│ │ │ │ │ + * is calculated again, this makes queries faster.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {}
│ │ │ │ │ */
│ │ │ │ │ - onMapResize: function() {
│ │ │ │ │ - //this function can be implemented by subclasses
│ │ │ │ │ + getBounds: function() {
│ │ │ │ │ + if (this.bounds == null) {
│ │ │ │ │ + this.calculateBounds();
│ │ │ │ │ + }
│ │ │ │ │ + return this.bounds;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: redraw
│ │ │ │ │ - * Redraws the layer. Returns true if the layer was redrawn, false if not.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} The layer was redrawn.
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: calculateBounds
│ │ │ │ │ + * Recalculate the bounds for the geometry.
│ │ │ │ │ */
│ │ │ │ │ - redraw: function() {
│ │ │ │ │ - var redrawn = false;
│ │ │ │ │ - if (this.map) {
│ │ │ │ │ -
│ │ │ │ │ - // min/max Range may have changed
│ │ │ │ │ - this.inRange = this.calculateInRange();
│ │ │ │ │ -
│ │ │ │ │ - // map's center might not yet be set
│ │ │ │ │ - var extent = this.getExtent();
│ │ │ │ │ -
│ │ │ │ │ - if (extent && this.inRange && this.visibility) {
│ │ │ │ │ - var zoomChanged = true;
│ │ │ │ │ - this.moveTo(extent, zoomChanged, false);
│ │ │ │ │ - this.events.triggerEvent("moveend", {
│ │ │ │ │ - "zoomChanged": zoomChanged
│ │ │ │ │ - });
│ │ │ │ │ - redrawn = true;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return redrawn;
│ │ │ │ │ + calculateBounds: function() {
│ │ │ │ │ + //
│ │ │ │ │ + // This should be overridden by subclasses.
│ │ │ │ │ + //
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: moveTo
│ │ │ │ │ - *
│ │ │ │ │ + * APIMethod: distanceTo
│ │ │ │ │ + * Calculate the closest distance between two geometries (on the x-y plane).
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * bounds - {}
│ │ │ │ │ - * zoomChanged - {Boolean} Tells when zoom has changed, as layers have to
│ │ │ │ │ - * do some init work in that case.
│ │ │ │ │ - * dragging - {Boolean}
│ │ │ │ │ + * geometry - {} The target geometry.
│ │ │ │ │ + * options - {Object} Optional properties for configuring the distance
│ │ │ │ │ + * calculation.
│ │ │ │ │ + *
│ │ │ │ │ + * Valid options depend on the specific geometry type.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Number | Object} The distance between this geometry and the target.
│ │ │ │ │ + * If details is true, the return will be an object with distance,
│ │ │ │ │ + * x0, y0, x1, and x2 properties. The x0 and y0 properties represent
│ │ │ │ │ + * the coordinates of the closest point on this geometry. The x1 and y1
│ │ │ │ │ + * properties represent the coordinates of the closest point on the
│ │ │ │ │ + * target geometry.
│ │ │ │ │ */
│ │ │ │ │ - moveTo: function(bounds, zoomChanged, dragging) {
│ │ │ │ │ - var display = this.visibility;
│ │ │ │ │ - if (!this.isBaseLayer) {
│ │ │ │ │ - display = display && this.inRange;
│ │ │ │ │ - }
│ │ │ │ │ - this.display(display);
│ │ │ │ │ - },
│ │ │ │ │ + distanceTo: function(geometry, options) {},
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: moveByPx
│ │ │ │ │ - * Move the layer based on pixel vector. To be implemented by subclasses.
│ │ │ │ │ + * APIMethod: getVertices
│ │ │ │ │ + * Return a list of all points in this geometry.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * dx - {Number} The x coord of the displacement vector.
│ │ │ │ │ - * dy - {Number} The y coord of the displacement vector.
│ │ │ │ │ + * nodes - {Boolean} For lines, only return vertices that are
│ │ │ │ │ + * endpoints. If false, for lines, only vertices that are not
│ │ │ │ │ + * endpoints will be returned. If not provided, all vertices will
│ │ │ │ │ + * be returned.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Array} A list of all vertices in the geometry.
│ │ │ │ │ */
│ │ │ │ │ - moveByPx: function(dx, dy) {},
│ │ │ │ │ + getVertices: function(nodes) {},
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: setMap
│ │ │ │ │ - * Set the map property for the layer. This is done through an accessor
│ │ │ │ │ - * so that subclasses can override this and take special action once
│ │ │ │ │ - * they have their map variable set.
│ │ │ │ │ - *
│ │ │ │ │ - * Here we take care to bring over any of the necessary default
│ │ │ │ │ - * properties from the map.
│ │ │ │ │ + * Method: atPoint
│ │ │ │ │ + * Note - This is only an approximation based on the bounds of the
│ │ │ │ │ + * geometry.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * map - {}
│ │ │ │ │ + * lonlat - {|Object} OpenLayers.LonLat or an
│ │ │ │ │ + * object with a 'lon' and 'lat' properties.
│ │ │ │ │ + * toleranceLon - {float} Optional tolerance in Geometric Coords
│ │ │ │ │ + * toleranceLat - {float} Optional tolerance in Geographic Coords
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean} Whether or not the geometry is at the specified location
│ │ │ │ │ */
│ │ │ │ │ - setMap: function(map) {
│ │ │ │ │ - if (this.map == null) {
│ │ │ │ │ -
│ │ │ │ │ - this.map = map;
│ │ │ │ │ -
│ │ │ │ │ - // grab some essential layer data from the map if it hasn't already
│ │ │ │ │ - // been set
│ │ │ │ │ - this.maxExtent = this.maxExtent || this.map.maxExtent;
│ │ │ │ │ - this.minExtent = this.minExtent || this.map.minExtent;
│ │ │ │ │ -
│ │ │ │ │ - this.projection = this.projection || this.map.projection;
│ │ │ │ │ - if (typeof this.projection == "string") {
│ │ │ │ │ - this.projection = new OpenLayers.Projection(this.projection);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // Check the projection to see if we can get units -- if not, refer
│ │ │ │ │ - // to properties.
│ │ │ │ │ - this.units = this.projection.getUnits() ||
│ │ │ │ │ - this.units || this.map.units;
│ │ │ │ │ + atPoint: function(lonlat, toleranceLon, toleranceLat) {
│ │ │ │ │ + var atPoint = false;
│ │ │ │ │ + var bounds = this.getBounds();
│ │ │ │ │ + if ((bounds != null) && (lonlat != null)) {
│ │ │ │ │
│ │ │ │ │ - this.initResolutions();
│ │ │ │ │ + var dX = (toleranceLon != null) ? toleranceLon : 0;
│ │ │ │ │ + var dY = (toleranceLat != null) ? toleranceLat : 0;
│ │ │ │ │
│ │ │ │ │ - if (!this.isBaseLayer) {
│ │ │ │ │ - this.inRange = this.calculateInRange();
│ │ │ │ │ - var show = ((this.visibility) && (this.inRange));
│ │ │ │ │ - this.div.style.display = show ? "" : "none";
│ │ │ │ │ - }
│ │ │ │ │ + var toleranceBounds =
│ │ │ │ │ + new OpenLayers.Bounds(this.bounds.left - dX,
│ │ │ │ │ + this.bounds.bottom - dY,
│ │ │ │ │ + this.bounds.right + dX,
│ │ │ │ │ + this.bounds.top + dY);
│ │ │ │ │
│ │ │ │ │ - // deal with gutters
│ │ │ │ │ - this.setTileSize();
│ │ │ │ │ + atPoint = toleranceBounds.containsLonLat(lonlat);
│ │ │ │ │ }
│ │ │ │ │ + return atPoint;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: afterAdd
│ │ │ │ │ - * Called at the end of the map.addLayer sequence. At this point, the map
│ │ │ │ │ - * will have a base layer. To be overridden by subclasses.
│ │ │ │ │ - */
│ │ │ │ │ - afterAdd: function() {},
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: removeMap
│ │ │ │ │ - * Just as setMap() allows each layer the possibility to take a
│ │ │ │ │ - * personalized action on being added to the map, removeMap() allows
│ │ │ │ │ - * each layer to take a personalized action on being removed from it.
│ │ │ │ │ - * For now, this will be mostly unused, except for the EventPane layer,
│ │ │ │ │ - * which needs this hook so that it can remove the special invisible
│ │ │ │ │ - * pane.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * map - {}
│ │ │ │ │ - */
│ │ │ │ │ - removeMap: function(map) {
│ │ │ │ │ - //to be overridden by subclasses
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: getImageSize
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * bounds - {} optional tile bounds, can be used
│ │ │ │ │ - * by subclasses that have to deal with different tile sizes at the
│ │ │ │ │ - * layer extent edges (e.g. Zoomify)
│ │ │ │ │ + * Method: getLength
│ │ │ │ │ + * Calculate the length of this geometry. This method is defined in
│ │ │ │ │ + * subclasses.
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {} The size that the image should be, taking into
│ │ │ │ │ - * account gutters.
│ │ │ │ │ + * {Float} The length of the collection by summing its parts
│ │ │ │ │ */
│ │ │ │ │ - getImageSize: function(bounds) {
│ │ │ │ │ - return (this.imageSize || this.tileSize);
│ │ │ │ │ + getLength: function() {
│ │ │ │ │ + //to be overridden by geometries that actually have a length
│ │ │ │ │ + //
│ │ │ │ │ + return 0.0;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: setTileSize
│ │ │ │ │ - * Set the tile size based on the map size. This also sets layer.imageSize
│ │ │ │ │ - * or use by Tile.Image.
│ │ │ │ │ + * Method: getArea
│ │ │ │ │ + * Calculate the area of this geometry. This method is defined in subclasses.
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * size - {}
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Float} The area of the collection by summing its parts
│ │ │ │ │ */
│ │ │ │ │ - setTileSize: function(size) {
│ │ │ │ │ - var tileSize = (size) ? size :
│ │ │ │ │ - ((this.tileSize) ? this.tileSize :
│ │ │ │ │ - this.map.getTileSize());
│ │ │ │ │ - this.tileSize = tileSize;
│ │ │ │ │ - if (this.gutter) {
│ │ │ │ │ - // layers with gutters need non-null tile sizes
│ │ │ │ │ - //if(tileSize == null) {
│ │ │ │ │ - // OpenLayers.console.error("Error in layer.setMap() for " +
│ │ │ │ │ - // this.name + ": layers with " +
│ │ │ │ │ - // "gutters need non-null tile sizes");
│ │ │ │ │ - //}
│ │ │ │ │ - this.imageSize = new OpenLayers.Size(tileSize.w + (2 * this.gutter),
│ │ │ │ │ - tileSize.h + (2 * this.gutter));
│ │ │ │ │ - }
│ │ │ │ │ + getArea: function() {
│ │ │ │ │ + //to be overridden by geometries that actually have an area
│ │ │ │ │ + //
│ │ │ │ │ + return 0.0;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: getVisibility
│ │ │ │ │ - *
│ │ │ │ │ + * APIMethod: getCentroid
│ │ │ │ │ + * Calculate the centroid of this geometry. This method is defined in subclasses.
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Boolean} The layer should be displayed (if in range).
│ │ │ │ │ - */
│ │ │ │ │ - getVisibility: function() {
│ │ │ │ │ - return this.visibility;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: setVisibility
│ │ │ │ │ - * Set the visibility flag for the layer and hide/show & redraw
│ │ │ │ │ - * accordingly. Fire event unless otherwise specified
│ │ │ │ │ - *
│ │ │ │ │ - * Note that visibility is no longer simply whether or not the layer's
│ │ │ │ │ - * style.display is set to "block". Now we store a 'visibility' state
│ │ │ │ │ - * property on the layer class, this allows us to remember whether or
│ │ │ │ │ - * not we *desire* for a layer to be visible. In the case where the
│ │ │ │ │ - * map's resolution is out of the layer's range, this desire may be
│ │ │ │ │ - * subverted.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * visibility - {Boolean} Whether or not to display the layer (if in range)
│ │ │ │ │ - */
│ │ │ │ │ - setVisibility: function(visibility) {
│ │ │ │ │ - if (visibility != this.visibility) {
│ │ │ │ │ - this.visibility = visibility;
│ │ │ │ │ - this.display(visibility);
│ │ │ │ │ - this.redraw();
│ │ │ │ │ - if (this.map != null) {
│ │ │ │ │ - this.map.events.triggerEvent("changelayer", {
│ │ │ │ │ - layer: this,
│ │ │ │ │ - property: "visibility"
│ │ │ │ │ - });
│ │ │ │ │ - }
│ │ │ │ │ - this.events.triggerEvent("visibilitychanged");
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: display
│ │ │ │ │ - * Hide or show the Layer. This is designed to be used internally, and
│ │ │ │ │ - * is not generally the way to enable or disable the layer. For that,
│ │ │ │ │ - * use the setVisibility function instead..
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * display - {Boolean}
│ │ │ │ │ + * {} The centroid of the collection
│ │ │ │ │ */
│ │ │ │ │ - display: function(display) {
│ │ │ │ │ - if (display != (this.div.style.display != "none")) {
│ │ │ │ │ - this.div.style.display = (display && this.calculateInRange()) ? "block" : "none";
│ │ │ │ │ - }
│ │ │ │ │ + getCentroid: function() {
│ │ │ │ │ + return null;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: calculateInRange
│ │ │ │ │ - *
│ │ │ │ │ + * Method: toString
│ │ │ │ │ + * Returns a text representation of the geometry. If the WKT format is
│ │ │ │ │ + * included in a build, this will be the Well-Known Text
│ │ │ │ │ + * representation.
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Boolean} The layer is displayable at the current map's current
│ │ │ │ │ - * resolution. Note that if 'alwaysInRange' is true for the layer,
│ │ │ │ │ - * this function will always return true.
│ │ │ │ │ + * {String} String representation of this geometry.
│ │ │ │ │ */
│ │ │ │ │ - calculateInRange: function() {
│ │ │ │ │ - var inRange = false;
│ │ │ │ │ -
│ │ │ │ │ - if (this.alwaysInRange) {
│ │ │ │ │ - inRange = true;
│ │ │ │ │ + toString: function() {
│ │ │ │ │ + var string;
│ │ │ │ │ + if (OpenLayers.Format && OpenLayers.Format.WKT) {
│ │ │ │ │ + string = OpenLayers.Format.WKT.prototype.write(
│ │ │ │ │ + new OpenLayers.Feature.Vector(this)
│ │ │ │ │ + );
│ │ │ │ │ } else {
│ │ │ │ │ - if (this.map) {
│ │ │ │ │ - var resolution = this.map.getResolution();
│ │ │ │ │ - inRange = ((resolution >= this.minResolution) &&
│ │ │ │ │ - (resolution <= this.maxResolution));
│ │ │ │ │ - }
│ │ │ │ │ + string = Object.prototype.toString.call(this);
│ │ │ │ │ }
│ │ │ │ │ - return inRange;
│ │ │ │ │ + return string;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: setIsBaseLayer
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * isBaseLayer - {Boolean}
│ │ │ │ │ - */
│ │ │ │ │ - setIsBaseLayer: function(isBaseLayer) {
│ │ │ │ │ - if (isBaseLayer != this.isBaseLayer) {
│ │ │ │ │ - this.isBaseLayer = isBaseLayer;
│ │ │ │ │ - if (this.map != null) {
│ │ │ │ │ - this.map.events.triggerEvent("changebaselayer", {
│ │ │ │ │ - layer: this
│ │ │ │ │ - });
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Geometry"
│ │ │ │ │ +});
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Function: OpenLayers.Geometry.fromWKT
│ │ │ │ │ + * Generate a geometry given a Well-Known Text string. For this method to
│ │ │ │ │ + * work, you must include the OpenLayers.Format.WKT in your build
│ │ │ │ │ + * explicitly.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * wkt - {String} A string representing the geometry in Well-Known Text.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {} A geometry of the appropriate class.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Geometry.fromWKT = function(wkt) {
│ │ │ │ │ + var geom;
│ │ │ │ │ + if (OpenLayers.Format && OpenLayers.Format.WKT) {
│ │ │ │ │ + var format = OpenLayers.Geometry.fromWKT.format;
│ │ │ │ │ + if (!format) {
│ │ │ │ │ + format = new OpenLayers.Format.WKT();
│ │ │ │ │ + OpenLayers.Geometry.fromWKT.format = format;
│ │ │ │ │ + }
│ │ │ │ │ + var result = format.read(wkt);
│ │ │ │ │ + if (result instanceof OpenLayers.Feature.Vector) {
│ │ │ │ │ + geom = result.geometry;
│ │ │ │ │ + } else if (OpenLayers.Util.isArray(result)) {
│ │ │ │ │ + var len = result.length;
│ │ │ │ │ + var components = new Array(len);
│ │ │ │ │ + for (var i = 0; i < len; ++i) {
│ │ │ │ │ + components[i] = result[i].geometry;
│ │ │ │ │ }
│ │ │ │ │ + geom = new OpenLayers.Geometry.Collection(components);
│ │ │ │ │ }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /********************************************************/
│ │ │ │ │ - /* */
│ │ │ │ │ - /* Baselayer Functions */
│ │ │ │ │ - /* */
│ │ │ │ │ - /********************************************************/
│ │ │ │ │ + }
│ │ │ │ │ + return geom;
│ │ │ │ │ +};
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: initResolutions
│ │ │ │ │ - * This method's responsibility is to set up the 'resolutions' array
│ │ │ │ │ - * for the layer -- this array is what the layer will use to interface
│ │ │ │ │ - * between the zoom levels of the map and the resolution display
│ │ │ │ │ - * of the layer.
│ │ │ │ │ - *
│ │ │ │ │ - * The user has several options that determine how the array is set up.
│ │ │ │ │ - *
│ │ │ │ │ - * For a detailed explanation, see the following wiki from the
│ │ │ │ │ - * openlayers.org homepage:
│ │ │ │ │ - * http://trac.openlayers.org/wiki/SettingZoomLevels
│ │ │ │ │ - */
│ │ │ │ │ - initResolutions: function() {
│ │ │ │ │ -
│ │ │ │ │ - // ok we want resolutions, here's our strategy:
│ │ │ │ │ - //
│ │ │ │ │ - // 1. if resolutions are defined in the layer config, use them
│ │ │ │ │ - // 2. else, if scales are defined in the layer config then derive
│ │ │ │ │ - // resolutions from these scales
│ │ │ │ │ - // 3. else, attempt to calculate resolutions from maxResolution,
│ │ │ │ │ - // minResolution, numZoomLevels, maxZoomLevel set in the
│ │ │ │ │ - // layer config
│ │ │ │ │ - // 4. if we still don't have resolutions, and if resolutions
│ │ │ │ │ - // are defined in the same, use them
│ │ │ │ │ - // 5. else, if scales are defined in the map then derive
│ │ │ │ │ - // resolutions from these scales
│ │ │ │ │ - // 6. else, attempt to calculate resolutions from maxResolution,
│ │ │ │ │ - // minResolution, numZoomLevels, maxZoomLevel set in the
│ │ │ │ │ - // map
│ │ │ │ │ - // 7. hope for the best!
│ │ │ │ │ -
│ │ │ │ │ - var i, len, p;
│ │ │ │ │ - var props = {},
│ │ │ │ │ - alwaysInRange = true;
│ │ │ │ │ -
│ │ │ │ │ - // get resolution data from layer config
│ │ │ │ │ - // (we also set alwaysInRange in the layer as appropriate)
│ │ │ │ │ - for (i = 0, len = this.RESOLUTION_PROPERTIES.length; i < len; i++) {
│ │ │ │ │ - p = this.RESOLUTION_PROPERTIES[i];
│ │ │ │ │ - props[p] = this.options[p];
│ │ │ │ │ - if (alwaysInRange && this.options[p]) {
│ │ │ │ │ - alwaysInRange = false;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - if (this.options.alwaysInRange == null) {
│ │ │ │ │ - this.alwaysInRange = alwaysInRange;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // if we don't have resolutions then attempt to derive them from scales
│ │ │ │ │ - if (props.resolutions == null) {
│ │ │ │ │ - props.resolutions = this.resolutionsFromScales(props.scales);
│ │ │ │ │ +/**
│ │ │ │ │ + * Method: OpenLayers.Geometry.segmentsIntersect
│ │ │ │ │ + * Determine whether two line segments intersect. Optionally calculates
│ │ │ │ │ + * and returns the intersection point. This function is optimized for
│ │ │ │ │ + * cases where seg1.x2 >= seg2.x1 || seg2.x2 >= seg1.x1. In those
│ │ │ │ │ + * obvious cases where there is no intersection, the function should
│ │ │ │ │ + * not be called.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * seg1 - {Object} Object representing a segment with properties x1, y1, x2,
│ │ │ │ │ + * and y2. The start point is represented by x1 and y1. The end point
│ │ │ │ │ + * is represented by x2 and y2. Start and end are ordered so that x1 < x2.
│ │ │ │ │ + * seg2 - {Object} Object representing a segment with properties x1, y1, x2,
│ │ │ │ │ + * and y2. The start point is represented by x1 and y1. The end point
│ │ │ │ │ + * is represented by x2 and y2. Start and end are ordered so that x1 < x2.
│ │ │ │ │ + * options - {Object} Optional properties for calculating the intersection.
│ │ │ │ │ + *
│ │ │ │ │ + * Valid options:
│ │ │ │ │ + * point - {Boolean} Return the intersection point. If false, the actual
│ │ │ │ │ + * intersection point will not be calculated. If true and the segments
│ │ │ │ │ + * intersect, the intersection point will be returned. If true and
│ │ │ │ │ + * the segments do not intersect, false will be returned. If true and
│ │ │ │ │ + * the segments are coincident, true will be returned.
│ │ │ │ │ + * tolerance - {Number} If a non-null value is provided, if the segments are
│ │ │ │ │ + * within the tolerance distance, this will be considered an intersection.
│ │ │ │ │ + * In addition, if the point option is true and the calculated intersection
│ │ │ │ │ + * is within the tolerance distance of an end point, the endpoint will be
│ │ │ │ │ + * returned instead of the calculated intersection. Further, if the
│ │ │ │ │ + * intersection is within the tolerance of endpoints on both segments, or
│ │ │ │ │ + * if two segment endpoints are within the tolerance distance of eachother
│ │ │ │ │ + * (but no intersection is otherwise calculated), an endpoint on the
│ │ │ │ │ + * first segment provided will be returned.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean | } The two segments intersect.
│ │ │ │ │ + * If the point argument is true, the return will be the intersection
│ │ │ │ │ + * point or false if none exists. If point is true and the segments
│ │ │ │ │ + * are coincident, return will be true (and the instersection is equal
│ │ │ │ │ + * to the shorter segment).
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Geometry.segmentsIntersect = function(seg1, seg2, options) {
│ │ │ │ │ + var point = options && options.point;
│ │ │ │ │ + var tolerance = options && options.tolerance;
│ │ │ │ │ + var intersection = false;
│ │ │ │ │ + var x11_21 = seg1.x1 - seg2.x1;
│ │ │ │ │ + var y11_21 = seg1.y1 - seg2.y1;
│ │ │ │ │ + var x12_11 = seg1.x2 - seg1.x1;
│ │ │ │ │ + var y12_11 = seg1.y2 - seg1.y1;
│ │ │ │ │ + var y22_21 = seg2.y2 - seg2.y1;
│ │ │ │ │ + var x22_21 = seg2.x2 - seg2.x1;
│ │ │ │ │ + var d = (y22_21 * x12_11) - (x22_21 * y12_11);
│ │ │ │ │ + var n1 = (x22_21 * y11_21) - (y22_21 * x11_21);
│ │ │ │ │ + var n2 = (x12_11 * y11_21) - (y12_11 * x11_21);
│ │ │ │ │ + if (d == 0) {
│ │ │ │ │ + // parallel
│ │ │ │ │ + if (n1 == 0 && n2 == 0) {
│ │ │ │ │ + // coincident
│ │ │ │ │ + intersection = true;
│ │ │ │ │ }
│ │ │ │ │ -
│ │ │ │ │ - // if we still don't have resolutions then attempt to calculate them
│ │ │ │ │ - if (props.resolutions == null) {
│ │ │ │ │ - props.resolutions = this.calculateResolutions(props);
│ │ │ │ │ + } else {
│ │ │ │ │ + var along1 = n1 / d;
│ │ │ │ │ + var along2 = n2 / d;
│ │ │ │ │ + if (along1 >= 0 && along1 <= 1 && along2 >= 0 && along2 <= 1) {
│ │ │ │ │ + // intersect
│ │ │ │ │ + if (!point) {
│ │ │ │ │ + intersection = true;
│ │ │ │ │ + } else {
│ │ │ │ │ + // calculate the intersection point
│ │ │ │ │ + var x = seg1.x1 + (along1 * x12_11);
│ │ │ │ │ + var y = seg1.y1 + (along1 * y12_11);
│ │ │ │ │ + intersection = new OpenLayers.Geometry.Point(x, y);
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ + }
│ │ │ │ │ + if (tolerance) {
│ │ │ │ │ + var dist;
│ │ │ │ │ + if (intersection) {
│ │ │ │ │ + if (point) {
│ │ │ │ │ + var segs = [seg1, seg2];
│ │ │ │ │ + var seg, x, y;
│ │ │ │ │ + // check segment endpoints for proximity to intersection
│ │ │ │ │ + // set intersection to first endpoint within the tolerance
│ │ │ │ │ + outer: for (var i = 0; i < 2; ++i) {
│ │ │ │ │ + seg = segs[i];
│ │ │ │ │ + for (var j = 1; j < 3; ++j) {
│ │ │ │ │ + x = seg["x" + j];
│ │ │ │ │ + y = seg["y" + j];
│ │ │ │ │ + dist = Math.sqrt(
│ │ │ │ │ + Math.pow(x - intersection.x, 2) +
│ │ │ │ │ + Math.pow(y - intersection.y, 2)
│ │ │ │ │ + );
│ │ │ │ │ + if (dist < tolerance) {
│ │ │ │ │ + intersection.x = x;
│ │ │ │ │ + intersection.y = y;
│ │ │ │ │ + break outer;
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - // if we couldn't calculate resolutions then we look at we have
│ │ │ │ │ - // in the map
│ │ │ │ │ - if (props.resolutions == null) {
│ │ │ │ │ - for (i = 0, len = this.RESOLUTION_PROPERTIES.length; i < len; i++) {
│ │ │ │ │ - p = this.RESOLUTION_PROPERTIES[i];
│ │ │ │ │ - props[p] = this.options[p] != null ?
│ │ │ │ │ - this.options[p] : this.map[p];
│ │ │ │ │ - }
│ │ │ │ │ - if (props.resolutions == null) {
│ │ │ │ │ - props.resolutions = this.resolutionsFromScales(props.scales);
│ │ │ │ │ }
│ │ │ │ │ - if (props.resolutions == null) {
│ │ │ │ │ - props.resolutions = this.calculateResolutions(props);
│ │ │ │ │ + } else {
│ │ │ │ │ + // no calculated intersection, but segments could be within
│ │ │ │ │ + // the tolerance of one another
│ │ │ │ │ + var segs = [seg1, seg2];
│ │ │ │ │ + var source, target, x, y, p, result;
│ │ │ │ │ + // check segment endpoints for proximity to intersection
│ │ │ │ │ + // set intersection to first endpoint within the tolerance
│ │ │ │ │ + outer: for (var i = 0; i < 2; ++i) {
│ │ │ │ │ + source = segs[i];
│ │ │ │ │ + target = segs[(i + 1) % 2];
│ │ │ │ │ + for (var j = 1; j < 3; ++j) {
│ │ │ │ │ + p = {
│ │ │ │ │ + x: source["x" + j],
│ │ │ │ │ + y: source["y" + j]
│ │ │ │ │ + };
│ │ │ │ │ + result = OpenLayers.Geometry.distanceToSegment(p, target);
│ │ │ │ │ + if (result.distance < tolerance) {
│ │ │ │ │ + if (point) {
│ │ │ │ │ + intersection = new OpenLayers.Geometry.Point(p.x, p.y);
│ │ │ │ │ + } else {
│ │ │ │ │ + intersection = true;
│ │ │ │ │ + }
│ │ │ │ │ + break outer;
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ }
│ │ │ │ │ + }
│ │ │ │ │ + return intersection;
│ │ │ │ │ +};
│ │ │ │ │
│ │ │ │ │ - // ok, we new need to set properties in the instance
│ │ │ │ │ -
│ │ │ │ │ - // get maxResolution from the config if it's defined there
│ │ │ │ │ - var maxResolution;
│ │ │ │ │ - if (this.options.maxResolution &&
│ │ │ │ │ - this.options.maxResolution !== "auto") {
│ │ │ │ │ - maxResolution = this.options.maxResolution;
│ │ │ │ │ - }
│ │ │ │ │ - if (this.options.minScale) {
│ │ │ │ │ - maxResolution = OpenLayers.Util.getResolutionFromScale(
│ │ │ │ │ - this.options.minScale, this.units);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // get minResolution from the config if it's defined there
│ │ │ │ │ - var minResolution;
│ │ │ │ │ - if (this.options.minResolution &&
│ │ │ │ │ - this.options.minResolution !== "auto") {
│ │ │ │ │ - minResolution = this.options.minResolution;
│ │ │ │ │ - }
│ │ │ │ │ - if (this.options.maxScale) {
│ │ │ │ │ - minResolution = OpenLayers.Util.getResolutionFromScale(
│ │ │ │ │ - this.options.maxScale, this.units);
│ │ │ │ │ - }
│ │ │ │ │ +/**
│ │ │ │ │ + * Function: OpenLayers.Geometry.distanceToSegment
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * point - {Object} An object with x and y properties representing the
│ │ │ │ │ + * point coordinates.
│ │ │ │ │ + * segment - {Object} An object with x1, y1, x2, and y2 properties
│ │ │ │ │ + * representing endpoint coordinates.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Object} An object with distance, along, x, and y properties. The distance
│ │ │ │ │ + * will be the shortest distance between the input point and segment.
│ │ │ │ │ + * The x and y properties represent the coordinates along the segment
│ │ │ │ │ + * where the shortest distance meets the segment. The along attribute
│ │ │ │ │ + * describes how far between the two segment points the given point is.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Geometry.distanceToSegment = function(point, segment) {
│ │ │ │ │ + var result = OpenLayers.Geometry.distanceSquaredToSegment(point, segment);
│ │ │ │ │ + result.distance = Math.sqrt(result.distance);
│ │ │ │ │ + return result;
│ │ │ │ │ +};
│ │ │ │ │
│ │ │ │ │ - if (props.resolutions) {
│ │ │ │ │ +/**
│ │ │ │ │ + * Function: OpenLayers.Geometry.distanceSquaredToSegment
│ │ │ │ │ + *
│ │ │ │ │ + * Usually the distanceToSegment function should be used. This variant however
│ │ │ │ │ + * can be used for comparisons where the exact distance is not important.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * point - {Object} An object with x and y properties representing the
│ │ │ │ │ + * point coordinates.
│ │ │ │ │ + * segment - {Object} An object with x1, y1, x2, and y2 properties
│ │ │ │ │ + * representing endpoint coordinates.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Object} An object with squared distance, along, x, and y properties.
│ │ │ │ │ + * The distance will be the shortest distance between the input point and
│ │ │ │ │ + * segment. The x and y properties represent the coordinates along the
│ │ │ │ │ + * segment where the shortest distance meets the segment. The along
│ │ │ │ │ + * attribute describes how far between the two segment points the given
│ │ │ │ │ + * point is.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Geometry.distanceSquaredToSegment = function(point, segment) {
│ │ │ │ │ + var x0 = point.x;
│ │ │ │ │ + var y0 = point.y;
│ │ │ │ │ + var x1 = segment.x1;
│ │ │ │ │ + var y1 = segment.y1;
│ │ │ │ │ + var x2 = segment.x2;
│ │ │ │ │ + var y2 = segment.y2;
│ │ │ │ │ + var dx = x2 - x1;
│ │ │ │ │ + var dy = y2 - y1;
│ │ │ │ │ + var along = ((dx * (x0 - x1)) + (dy * (y0 - y1))) /
│ │ │ │ │ + (Math.pow(dx, 2) + Math.pow(dy, 2));
│ │ │ │ │ + var x, y;
│ │ │ │ │ + if (along <= 0.0) {
│ │ │ │ │ + x = x1;
│ │ │ │ │ + y = y1;
│ │ │ │ │ + } else if (along >= 1.0) {
│ │ │ │ │ + x = x2;
│ │ │ │ │ + y = y2;
│ │ │ │ │ + } else {
│ │ │ │ │ + x = x1 + along * dx;
│ │ │ │ │ + y = y1 + along * dy;
│ │ │ │ │ + }
│ │ │ │ │ + return {
│ │ │ │ │ + distance: Math.pow(x - x0, 2) + Math.pow(y - y0, 2),
│ │ │ │ │ + x: x,
│ │ │ │ │ + y: y,
│ │ │ │ │ + along: along
│ │ │ │ │ + };
│ │ │ │ │ +};
│ │ │ │ │ +/* ======================================================================
│ │ │ │ │ + OpenLayers/Feature.js
│ │ │ │ │ + ====================================================================== */
│ │ │ │ │
│ │ │ │ │ - //sort resolutions array descendingly
│ │ │ │ │ - props.resolutions.sort(function(a, b) {
│ │ │ │ │ - return (b - a);
│ │ │ │ │ - });
│ │ │ │ │ +/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ + * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ + * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ + * full text of the license. */
│ │ │ │ │
│ │ │ │ │ - // if we still don't have a maxResolution get it from the
│ │ │ │ │ - // resolutions array
│ │ │ │ │ - if (!maxResolution) {
│ │ │ │ │ - maxResolution = props.resolutions[0];
│ │ │ │ │ - }
│ │ │ │ │
│ │ │ │ │ - // if we still don't have a minResolution get it from the
│ │ │ │ │ - // resolutions array
│ │ │ │ │ - if (!minResolution) {
│ │ │ │ │ - var lastIdx = props.resolutions.length - 1;
│ │ │ │ │ - minResolution = props.resolutions[lastIdx];
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ +/**
│ │ │ │ │ + * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ + * @requires OpenLayers/Util.js
│ │ │ │ │ + */
│ │ │ │ │
│ │ │ │ │ - this.resolutions = props.resolutions;
│ │ │ │ │ - if (this.resolutions) {
│ │ │ │ │ - len = this.resolutions.length;
│ │ │ │ │ - this.scales = new Array(len);
│ │ │ │ │ - for (i = 0; i < len; i++) {
│ │ │ │ │ - this.scales[i] = OpenLayers.Util.getScaleFromResolution(
│ │ │ │ │ - this.resolutions[i], this.units);
│ │ │ │ │ - }
│ │ │ │ │ - this.numZoomLevels = len;
│ │ │ │ │ - }
│ │ │ │ │ - this.minResolution = minResolution;
│ │ │ │ │ - if (minResolution) {
│ │ │ │ │ - this.maxScale = OpenLayers.Util.getScaleFromResolution(
│ │ │ │ │ - minResolution, this.units);
│ │ │ │ │ - }
│ │ │ │ │ - this.maxResolution = maxResolution;
│ │ │ │ │ - if (maxResolution) {
│ │ │ │ │ - this.minScale = OpenLayers.Util.getScaleFromResolution(
│ │ │ │ │ - maxResolution, this.units);
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ +/**
│ │ │ │ │ + * Class: OpenLayers.Feature
│ │ │ │ │ + * Features are combinations of geography and attributes. The OpenLayers.Feature
│ │ │ │ │ + * class specifically combines a marker and a lonlat.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Feature = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: resolutionsFromScales
│ │ │ │ │ - * Derive resolutions from scales.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * scales - {Array(Number)} Scales
│ │ │ │ │ - *
│ │ │ │ │ - * Returns
│ │ │ │ │ - * {Array(Number)} Resolutions
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: layer
│ │ │ │ │ + * {}
│ │ │ │ │ */
│ │ │ │ │ - resolutionsFromScales: function(scales) {
│ │ │ │ │ - if (scales == null) {
│ │ │ │ │ - return;
│ │ │ │ │ - }
│ │ │ │ │ - var resolutions, i, len;
│ │ │ │ │ - len = scales.length;
│ │ │ │ │ - resolutions = new Array(len);
│ │ │ │ │ - for (i = 0; i < len; i++) {
│ │ │ │ │ - resolutions[i] = OpenLayers.Util.getResolutionFromScale(
│ │ │ │ │ - scales[i], this.units);
│ │ │ │ │ - }
│ │ │ │ │ - return resolutions;
│ │ │ │ │ - },
│ │ │ │ │ + layer: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: calculateResolutions
│ │ │ │ │ - * Calculate resolutions based on the provided properties.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * props - {Object} Properties
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Array({Number})} Array of resolutions.
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: id
│ │ │ │ │ + * {String}
│ │ │ │ │ */
│ │ │ │ │ - calculateResolutions: function(props) {
│ │ │ │ │ -
│ │ │ │ │ - var viewSize, wRes, hRes;
│ │ │ │ │ -
│ │ │ │ │ - // determine maxResolution
│ │ │ │ │ - var maxResolution = props.maxResolution;
│ │ │ │ │ - if (props.minScale != null) {
│ │ │ │ │ - maxResolution =
│ │ │ │ │ - OpenLayers.Util.getResolutionFromScale(props.minScale,
│ │ │ │ │ - this.units);
│ │ │ │ │ - } else if (maxResolution == "auto" && this.maxExtent != null) {
│ │ │ │ │ - viewSize = this.map.getSize();
│ │ │ │ │ - wRes = this.maxExtent.getWidth() / viewSize.w;
│ │ │ │ │ - hRes = this.maxExtent.getHeight() / viewSize.h;
│ │ │ │ │ - maxResolution = Math.max(wRes, hRes);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // determine minResolution
│ │ │ │ │ - var minResolution = props.minResolution;
│ │ │ │ │ - if (props.maxScale != null) {
│ │ │ │ │ - minResolution =
│ │ │ │ │ - OpenLayers.Util.getResolutionFromScale(props.maxScale,
│ │ │ │ │ - this.units);
│ │ │ │ │ - } else if (props.minResolution == "auto" && this.minExtent != null) {
│ │ │ │ │ - viewSize = this.map.getSize();
│ │ │ │ │ - wRes = this.minExtent.getWidth() / viewSize.w;
│ │ │ │ │ - hRes = this.minExtent.getHeight() / viewSize.h;
│ │ │ │ │ - minResolution = Math.max(wRes, hRes);
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - if (typeof maxResolution !== "number" &&
│ │ │ │ │ - typeof minResolution !== "number" &&
│ │ │ │ │ - this.maxExtent != null) {
│ │ │ │ │ - // maxResolution for default grid sets assumes that at zoom
│ │ │ │ │ - // level zero, the whole world fits on one tile.
│ │ │ │ │ - var tileSize = this.map.getTileSize();
│ │ │ │ │ - maxResolution = Math.max(
│ │ │ │ │ - this.maxExtent.getWidth() / tileSize.w,
│ │ │ │ │ - this.maxExtent.getHeight() / tileSize.h
│ │ │ │ │ - );
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // determine numZoomLevels
│ │ │ │ │ - var maxZoomLevel = props.maxZoomLevel;
│ │ │ │ │ - var numZoomLevels = props.numZoomLevels;
│ │ │ │ │ - if (typeof minResolution === "number" &&
│ │ │ │ │ - typeof maxResolution === "number" && numZoomLevels === undefined) {
│ │ │ │ │ - var ratio = maxResolution / minResolution;
│ │ │ │ │ - numZoomLevels = Math.floor(Math.log(ratio) / Math.log(2)) + 1;
│ │ │ │ │ - } else if (numZoomLevels === undefined && maxZoomLevel != null) {
│ │ │ │ │ - numZoomLevels = maxZoomLevel + 1;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // are we able to calculate resolutions?
│ │ │ │ │ - if (typeof numZoomLevels !== "number" || numZoomLevels <= 0 ||
│ │ │ │ │ - (typeof maxResolution !== "number" &&
│ │ │ │ │ - typeof minResolution !== "number")) {
│ │ │ │ │ - return;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - // now we have numZoomLevels and at least one of maxResolution
│ │ │ │ │ - // or minResolution, we can populate the resolutions array
│ │ │ │ │ -
│ │ │ │ │ - var resolutions = new Array(numZoomLevels);
│ │ │ │ │ - var base = 2;
│ │ │ │ │ - if (typeof minResolution == "number" &&
│ │ │ │ │ - typeof maxResolution == "number") {
│ │ │ │ │ - // if maxResolution and minResolution are set, we calculate
│ │ │ │ │ - // the base for exponential scaling that starts at
│ │ │ │ │ - // maxResolution and ends at minResolution in numZoomLevels
│ │ │ │ │ - // steps.
│ │ │ │ │ - base = Math.pow(
│ │ │ │ │ - (maxResolution / minResolution),
│ │ │ │ │ - (1 / (numZoomLevels - 1))
│ │ │ │ │ - );
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - var i;
│ │ │ │ │ - if (typeof maxResolution === "number") {
│ │ │ │ │ - for (i = 0; i < numZoomLevels; i++) {
│ │ │ │ │ - resolutions[i] = maxResolution / Math.pow(base, i);
│ │ │ │ │ - }
│ │ │ │ │ - } else {
│ │ │ │ │ - for (i = 0; i < numZoomLevels; i++) {
│ │ │ │ │ - resolutions[numZoomLevels - 1 - i] =
│ │ │ │ │ - minResolution * Math.pow(base, i);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ + id: null,
│ │ │ │ │
│ │ │ │ │ - return resolutions;
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: lonlat
│ │ │ │ │ + * {}
│ │ │ │ │ + */
│ │ │ │ │ + lonlat: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: getResolution
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Float} The currently selected resolution of the map, taken from the
│ │ │ │ │ - * resolutions array, indexed by current zoom level.
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: data
│ │ │ │ │ + * {Object}
│ │ │ │ │ */
│ │ │ │ │ - getResolution: function() {
│ │ │ │ │ - var zoom = this.map.getZoom();
│ │ │ │ │ - return this.getResolutionForZoom(zoom);
│ │ │ │ │ - },
│ │ │ │ │ + data: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: getExtent
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} A Bounds object which represents the lon/lat
│ │ │ │ │ - * bounds of the current viewPort.
│ │ │ │ │ + * Property: marker
│ │ │ │ │ + * {}
│ │ │ │ │ */
│ │ │ │ │ - getExtent: function() {
│ │ │ │ │ - // just use stock map calculateBounds function -- passing no arguments
│ │ │ │ │ - // means it will user map's current center & resolution
│ │ │ │ │ - //
│ │ │ │ │ - return this.map.calculateBounds();
│ │ │ │ │ - },
│ │ │ │ │ + marker: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: getZoomForExtent
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * extent - {}
│ │ │ │ │ - * closest - {Boolean} Find the zoom level that most closely fits the
│ │ │ │ │ - * specified bounds. Note that this may result in a zoom that does
│ │ │ │ │ - * not exactly contain the entire extent.
│ │ │ │ │ - * Default is false.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Integer} The index of the zoomLevel (entry in the resolutions array)
│ │ │ │ │ - * for the passed-in extent. We do this by calculating the ideal
│ │ │ │ │ - * resolution for the given extent (based on the map size) and then
│ │ │ │ │ - * calling getZoomForResolution(), passing along the 'closest'
│ │ │ │ │ - * parameter.
│ │ │ │ │ + * APIProperty: popupClass
│ │ │ │ │ + * {} The class which will be used to instantiate
│ │ │ │ │ + * a new Popup. Default is .
│ │ │ │ │ */
│ │ │ │ │ - getZoomForExtent: function(extent, closest) {
│ │ │ │ │ - var viewSize = this.map.getSize();
│ │ │ │ │ - var idealResolution = Math.max(extent.getWidth() / viewSize.w,
│ │ │ │ │ - extent.getHeight() / viewSize.h);
│ │ │ │ │ -
│ │ │ │ │ - return this.getZoomForResolution(idealResolution, closest);
│ │ │ │ │ - },
│ │ │ │ │ + popupClass: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: getDataExtent
│ │ │ │ │ - * Calculates the max extent which includes all of the data for the layer.
│ │ │ │ │ - * This function is to be implemented by subclasses.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {}
│ │ │ │ │ + * Property: popup
│ │ │ │ │ + * {}
│ │ │ │ │ */
│ │ │ │ │ - getDataExtent: function() {
│ │ │ │ │ - //to be implemented by subclasses
│ │ │ │ │ - },
│ │ │ │ │ + popup: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: getResolutionForZoom
│ │ │ │ │ - *
│ │ │ │ │ + /**
│ │ │ │ │ + * Constructor: OpenLayers.Feature
│ │ │ │ │ + * Constructor for features.
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * zoom - {Float}
│ │ │ │ │ + * layer - {}
│ │ │ │ │ + * lonlat - {}
│ │ │ │ │ + * data - {Object}
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Float} A suitable resolution for the specified zoom.
│ │ │ │ │ + * {}
│ │ │ │ │ */
│ │ │ │ │ - getResolutionForZoom: function(zoom) {
│ │ │ │ │ - zoom = Math.max(0, Math.min(zoom, this.resolutions.length - 1));
│ │ │ │ │ - var resolution;
│ │ │ │ │ - if (this.map.fractionalZoom) {
│ │ │ │ │ - var low = Math.floor(zoom);
│ │ │ │ │ - var high = Math.ceil(zoom);
│ │ │ │ │ - resolution = this.resolutions[low] -
│ │ │ │ │ - ((zoom - low) * (this.resolutions[low] - this.resolutions[high]));
│ │ │ │ │ - } else {
│ │ │ │ │ - resolution = this.resolutions[Math.round(zoom)];
│ │ │ │ │ - }
│ │ │ │ │ - return resolution;
│ │ │ │ │ + initialize: function(layer, lonlat, data) {
│ │ │ │ │ + this.layer = layer;
│ │ │ │ │ + this.lonlat = lonlat;
│ │ │ │ │ + this.data = (data != null) ? data : {};
│ │ │ │ │ + this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: getZoomForResolution
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * resolution - {Float}
│ │ │ │ │ - * closest - {Boolean} Find the zoom level that corresponds to the absolute
│ │ │ │ │ - * closest resolution, which may result in a zoom whose corresponding
│ │ │ │ │ - * resolution is actually smaller than we would have desired (if this
│ │ │ │ │ - * is being called from a getZoomForExtent() call, then this means that
│ │ │ │ │ - * the returned zoom index might not actually contain the entire
│ │ │ │ │ - * extent specified... but it'll be close).
│ │ │ │ │ - * Default is false.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Integer} The index of the zoomLevel (entry in the resolutions array)
│ │ │ │ │ - * that corresponds to the best fit resolution given the passed in
│ │ │ │ │ - * value and the 'closest' specification.
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: destroy
│ │ │ │ │ + * nullify references to prevent circular references and memory leaks
│ │ │ │ │ */
│ │ │ │ │ - getZoomForResolution: function(resolution, closest) {
│ │ │ │ │ - var zoom, i, len;
│ │ │ │ │ - if (this.map.fractionalZoom) {
│ │ │ │ │ - var lowZoom = 0;
│ │ │ │ │ - var highZoom = this.resolutions.length - 1;
│ │ │ │ │ - var highRes = this.resolutions[lowZoom];
│ │ │ │ │ - var lowRes = this.resolutions[highZoom];
│ │ │ │ │ - var res;
│ │ │ │ │ - for (i = 0, len = this.resolutions.length; i < len; ++i) {
│ │ │ │ │ - res = this.resolutions[i];
│ │ │ │ │ - if (res >= resolution) {
│ │ │ │ │ - highRes = res;
│ │ │ │ │ - lowZoom = i;
│ │ │ │ │ - }
│ │ │ │ │ - if (res <= resolution) {
│ │ │ │ │ - lowRes = res;
│ │ │ │ │ - highZoom = i;
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - var dRes = highRes - lowRes;
│ │ │ │ │ - if (dRes > 0) {
│ │ │ │ │ - zoom = lowZoom + ((highRes - resolution) / dRes);
│ │ │ │ │ - } else {
│ │ │ │ │ - zoom = lowZoom;
│ │ │ │ │ - }
│ │ │ │ │ - } else {
│ │ │ │ │ - var diff;
│ │ │ │ │ - var minDiff = Number.POSITIVE_INFINITY;
│ │ │ │ │ - for (i = 0, len = this.resolutions.length; i < len; i++) {
│ │ │ │ │ - if (closest) {
│ │ │ │ │ - diff = Math.abs(this.resolutions[i] - resolution);
│ │ │ │ │ - if (diff > minDiff) {
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - minDiff = diff;
│ │ │ │ │ - } else {
│ │ │ │ │ - if (this.resolutions[i] < resolution) {
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ + destroy: function() {
│ │ │ │ │ +
│ │ │ │ │ + //remove the popup from the map
│ │ │ │ │ + if ((this.layer != null) && (this.layer.map != null)) {
│ │ │ │ │ + if (this.popup != null) {
│ │ │ │ │ + this.layer.map.removePopup(this.popup);
│ │ │ │ │ }
│ │ │ │ │ - zoom = Math.max(0, i - 1);
│ │ │ │ │ }
│ │ │ │ │ - return zoom;
│ │ │ │ │ + // remove the marker from the layer
│ │ │ │ │ + if (this.layer != null && this.marker != null) {
│ │ │ │ │ + this.layer.removeMarker(this.marker);
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + this.layer = null;
│ │ │ │ │ + this.id = null;
│ │ │ │ │ + this.lonlat = null;
│ │ │ │ │ + this.data = null;
│ │ │ │ │ + if (this.marker != null) {
│ │ │ │ │ + this.destroyMarker(this.marker);
│ │ │ │ │ + this.marker = null;
│ │ │ │ │ + }
│ │ │ │ │ + if (this.popup != null) {
│ │ │ │ │ + this.destroyPopup(this.popup);
│ │ │ │ │ + this.popup = null;
│ │ │ │ │ + }
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: getLonLatFromViewPortPx
│ │ │ │ │ + * Method: onScreen
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * viewPortPx - {|Object} An OpenLayers.Pixel or
│ │ │ │ │ - * an object with a 'x'
│ │ │ │ │ - * and 'y' properties.
│ │ │ │ │ - *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {} An OpenLayers.LonLat which is the passed-in
│ │ │ │ │ - * view port , translated into lon/lat by the layer.
│ │ │ │ │ + * {Boolean} Whether or not the feature is currently visible on screen
│ │ │ │ │ + * (based on its 'lonlat' property)
│ │ │ │ │ */
│ │ │ │ │ - getLonLatFromViewPortPx: function(viewPortPx) {
│ │ │ │ │ - var lonlat = null;
│ │ │ │ │ - var map = this.map;
│ │ │ │ │ - if (viewPortPx != null && map.minPx) {
│ │ │ │ │ - var res = map.getResolution();
│ │ │ │ │ - var maxExtent = map.getMaxExtent({
│ │ │ │ │ - restricted: true
│ │ │ │ │ - });
│ │ │ │ │ - var lon = (viewPortPx.x - map.minPx.x) * res + maxExtent.left;
│ │ │ │ │ - var lat = (map.minPx.y - viewPortPx.y) * res + maxExtent.top;
│ │ │ │ │ - lonlat = new OpenLayers.LonLat(lon, lat);
│ │ │ │ │ + onScreen: function() {
│ │ │ │ │
│ │ │ │ │ - if (this.wrapDateLine) {
│ │ │ │ │ - lonlat = lonlat.wrapDateLine(this.maxExtent);
│ │ │ │ │ - }
│ │ │ │ │ + var onScreen = false;
│ │ │ │ │ + if ((this.layer != null) && (this.layer.map != null)) {
│ │ │ │ │ + var screenBounds = this.layer.map.getExtent();
│ │ │ │ │ + onScreen = screenBounds.containsLonLat(this.lonlat);
│ │ │ │ │ }
│ │ │ │ │ - return lonlat;
│ │ │ │ │ + return onScreen;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ +
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: getViewPortPxFromLonLat
│ │ │ │ │ - * Returns a pixel location given a map location. This method will return
│ │ │ │ │ - * fractional pixel values.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * lonlat - {|Object} An OpenLayers.LonLat or
│ │ │ │ │ - * an object with a 'lon'
│ │ │ │ │ - * and 'lat' properties.
│ │ │ │ │ + * Method: createMarker
│ │ │ │ │ + * Based on the data associated with the Feature, create and return a marker object.
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {} An which is the passed-in
│ │ │ │ │ - * lonlat translated into view port pixels.
│ │ │ │ │ - */
│ │ │ │ │ - getViewPortPxFromLonLat: function(lonlat, resolution) {
│ │ │ │ │ - var px = null;
│ │ │ │ │ - if (lonlat != null) {
│ │ │ │ │ - resolution = resolution || this.map.getResolution();
│ │ │ │ │ - var extent = this.map.calculateBounds(null, resolution);
│ │ │ │ │ - px = new OpenLayers.Pixel(
│ │ │ │ │ - (1 / resolution * (lonlat.lon - extent.left)),
│ │ │ │ │ - (1 / resolution * (extent.top - lonlat.lat))
│ │ │ │ │ - );
│ │ │ │ │ - }
│ │ │ │ │ - return px;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: setOpacity
│ │ │ │ │ - * Sets the opacity for the entire layer (all images)
│ │ │ │ │ + * {} A Marker Object created from the 'lonlat' and 'icon' properties
│ │ │ │ │ + * set in this.data. If no 'lonlat' is set, returns null. If no
│ │ │ │ │ + * 'icon' is set, OpenLayers.Marker() will load the default image.
│ │ │ │ │ + *
│ │ │ │ │ + * Note - this.marker is set to return value
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * opacity - {Float}
│ │ │ │ │ */
│ │ │ │ │ - setOpacity: function(opacity) {
│ │ │ │ │ - if (opacity != this.opacity) {
│ │ │ │ │ - this.opacity = opacity;
│ │ │ │ │ - var childNodes = this.div.childNodes;
│ │ │ │ │ - for (var i = 0, len = childNodes.length; i < len; ++i) {
│ │ │ │ │ - var element = childNodes[i].firstChild || childNodes[i];
│ │ │ │ │ - var lastChild = childNodes[i].lastChild;
│ │ │ │ │ - //TODO de-uglify this
│ │ │ │ │ - if (lastChild && lastChild.nodeName.toLowerCase() === "iframe") {
│ │ │ │ │ - element = lastChild.parentNode;
│ │ │ │ │ - }
│ │ │ │ │ - OpenLayers.Util.modifyDOMElement(element, null, null, null,
│ │ │ │ │ - null, null, null, opacity);
│ │ │ │ │ - }
│ │ │ │ │ - if (this.map != null) {
│ │ │ │ │ - this.map.events.triggerEvent("changelayer", {
│ │ │ │ │ - layer: this,
│ │ │ │ │ - property: "opacity"
│ │ │ │ │ - });
│ │ │ │ │ - }
│ │ │ │ │ + createMarker: function() {
│ │ │ │ │ +
│ │ │ │ │ + if (this.lonlat != null) {
│ │ │ │ │ + this.marker = new OpenLayers.Marker(this.lonlat, this.data.icon);
│ │ │ │ │ }
│ │ │ │ │ + return this.marker;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: getZIndex
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Integer} the z-index of this layer
│ │ │ │ │ + * Method: destroyMarker
│ │ │ │ │ + * Destroys marker.
│ │ │ │ │ + * If user overrides the createMarker() function, s/he should be able
│ │ │ │ │ + * to also specify an alternative function for destroying it
│ │ │ │ │ */
│ │ │ │ │ - getZIndex: function() {
│ │ │ │ │ - return this.div.style.zIndex;
│ │ │ │ │ + destroyMarker: function() {
│ │ │ │ │ + this.marker.destroy();
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: setZIndex
│ │ │ │ │ + * Method: createPopup
│ │ │ │ │ + * Creates a popup object created from the 'lonlat', 'popupSize',
│ │ │ │ │ + * and 'popupContentHTML' properties set in this.data. It uses
│ │ │ │ │ + * this.marker.icon as default anchor.
│ │ │ │ │ + *
│ │ │ │ │ + * If no 'lonlat' is set, returns null.
│ │ │ │ │ + * If no this.marker has been created, no anchor is sent.
│ │ │ │ │ + *
│ │ │ │ │ + * Note - the returned popup object is 'owned' by the feature, so you
│ │ │ │ │ + * cannot use the popup's destroy method to discard the popup.
│ │ │ │ │ + * Instead, you must use the feature's destroyPopup
│ │ │ │ │ + *
│ │ │ │ │ + * Note - this.popup is set to return value
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * zIndex - {Integer}
│ │ │ │ │ - */
│ │ │ │ │ - setZIndex: function(zIndex) {
│ │ │ │ │ - this.div.style.zIndex = zIndex;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: adjustBounds
│ │ │ │ │ - * This function will take a bounds, and if wrapDateLine option is set
│ │ │ │ │ - * on the layer, it will return a bounds which is wrapped around the
│ │ │ │ │ - * world. We do not wrap for bounds which *cross* the
│ │ │ │ │ - * maxExtent.left/right, only bounds which are entirely to the left
│ │ │ │ │ - * or entirely to the right.
│ │ │ │ │ + * closeBox - {Boolean} create popup with closebox or not
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {} Returns the created popup, which is also set
│ │ │ │ │ + * as 'popup' property of this feature. Will be of whatever type
│ │ │ │ │ + * specified by this feature's 'popupClass' property, but must be
│ │ │ │ │ + * of type .
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * bounds - {}
│ │ │ │ │ */
│ │ │ │ │ - adjustBounds: function(bounds) {
│ │ │ │ │ + createPopup: function(closeBox) {
│ │ │ │ │
│ │ │ │ │ - if (this.gutter) {
│ │ │ │ │ - // Adjust the extent of a bounds in map units by the
│ │ │ │ │ - // layer's gutter in pixels.
│ │ │ │ │ - var mapGutter = this.gutter * this.map.getResolution();
│ │ │ │ │ - bounds = new OpenLayers.Bounds(bounds.left - mapGutter,
│ │ │ │ │ - bounds.bottom - mapGutter,
│ │ │ │ │ - bounds.right + mapGutter,
│ │ │ │ │ - bounds.top + mapGutter);
│ │ │ │ │ + if (this.lonlat != null) {
│ │ │ │ │ + if (!this.popup) {
│ │ │ │ │ + var anchor = (this.marker) ? this.marker.icon : null;
│ │ │ │ │ + var popupClass = this.popupClass ?
│ │ │ │ │ + this.popupClass : OpenLayers.Popup.Anchored;
│ │ │ │ │ + this.popup = new popupClass(this.id + "_popup",
│ │ │ │ │ + this.lonlat,
│ │ │ │ │ + this.data.popupSize,
│ │ │ │ │ + this.data.popupContentHTML,
│ │ │ │ │ + anchor,
│ │ │ │ │ + closeBox);
│ │ │ │ │ + }
│ │ │ │ │ + if (this.data.overflow != null) {
│ │ │ │ │ + this.popup.contentDiv.style.overflow = this.data.overflow;
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + this.popup.feature = this;
│ │ │ │ │ }
│ │ │ │ │ + return this.popup;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - if (this.wrapDateLine) {
│ │ │ │ │ - // wrap around the date line, within the limits of rounding error
│ │ │ │ │ - var wrappingOptions = {
│ │ │ │ │ - 'rightTolerance': this.getResolution(),
│ │ │ │ │ - 'leftTolerance': this.getResolution()
│ │ │ │ │ - };
│ │ │ │ │ - bounds = bounds.wrapDateLine(this.maxExtent, wrappingOptions);
│ │ │ │ │
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: destroyPopup
│ │ │ │ │ + * Destroys the popup created via createPopup.
│ │ │ │ │ + *
│ │ │ │ │ + * As with the marker, if user overrides the createPopup() function, s/he
│ │ │ │ │ + * should also be able to override the destruction
│ │ │ │ │ + */
│ │ │ │ │ + destroyPopup: function() {
│ │ │ │ │ + if (this.popup) {
│ │ │ │ │ + this.popup.feature = null;
│ │ │ │ │ + this.popup.destroy();
│ │ │ │ │ + this.popup = null;
│ │ │ │ │ }
│ │ │ │ │ - return bounds;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Layer"
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Feature"
│ │ │ │ │ });
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Layer/HTTPRequest.js
│ │ │ │ │ + OpenLayers/Feature/Vector.js
│ │ │ │ │ ====================================================================== */
│ │ │ │ │
│ │ │ │ │ /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ * full text of the license. */
│ │ │ │ │
│ │ │ │ │ +// TRASH THIS
│ │ │ │ │ +OpenLayers.State = {
│ │ │ │ │ + /** states */
│ │ │ │ │ + UNKNOWN: 'Unknown',
│ │ │ │ │ + INSERT: 'Insert',
│ │ │ │ │ + UPDATE: 'Update',
│ │ │ │ │ + DELETE: 'Delete'
│ │ │ │ │ +};
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * @requires OpenLayers/Layer.js
│ │ │ │ │ + * @requires OpenLayers/Feature.js
│ │ │ │ │ + * @requires OpenLayers/Util.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Class: OpenLayers.Layer.HTTPRequest
│ │ │ │ │ + * Class: OpenLayers.Feature.Vector
│ │ │ │ │ + * Vector features use the OpenLayers.Geometry classes as geometry description.
│ │ │ │ │ + * They have an 'attributes' property, which is the data object, and a 'style'
│ │ │ │ │ + * property, the default values of which are defined in the
│ │ │ │ │ + * objects.
│ │ │ │ │ *
│ │ │ │ │ - * Inherits from:
│ │ │ │ │ - * -
│ │ │ │ │ + * Inherits from:
│ │ │ │ │ + * -
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Layer.HTTPRequest = OpenLayers.Class(OpenLayers.Layer, {
│ │ │ │ │ +OpenLayers.Feature.Vector = OpenLayers.Class(OpenLayers.Feature, {
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constant: URL_HASH_FACTOR
│ │ │ │ │ - * {Float} Used to hash URL param strings for multi-WMS server selection.
│ │ │ │ │ - * Set to the Golden Ratio per Knuth's recommendation.
│ │ │ │ │ + * Property: fid
│ │ │ │ │ + * {String}
│ │ │ │ │ */
│ │ │ │ │ - URL_HASH_FACTOR: (Math.sqrt(5) - 1) / 2,
│ │ │ │ │ + fid: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: url
│ │ │ │ │ - * {Array(String) or String} This is either an array of url strings or
│ │ │ │ │ - * a single url string.
│ │ │ │ │ + * APIProperty: geometry
│ │ │ │ │ + * {}
│ │ │ │ │ */
│ │ │ │ │ - url: null,
│ │ │ │ │ + geometry: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: params
│ │ │ │ │ - * {Object} Hashtable of key/value parameters
│ │ │ │ │ + * APIProperty: attributes
│ │ │ │ │ + * {Object} This object holds arbitrary, serializable properties that
│ │ │ │ │ + * describe the feature.
│ │ │ │ │ */
│ │ │ │ │ - params: null,
│ │ │ │ │ + attributes: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: bounds
│ │ │ │ │ + * {} The box bounding that feature's geometry, that
│ │ │ │ │ + * property can be set by an object when
│ │ │ │ │ + * deserializing the feature, so in most cases it represents an
│ │ │ │ │ + * information set by the server.
│ │ │ │ │ + */
│ │ │ │ │ + bounds: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: reproject
│ │ │ │ │ - * *Deprecated*. See http://docs.openlayers.org/library/spherical_mercator.html
│ │ │ │ │ - * for information on the replacement for this functionality.
│ │ │ │ │ - * {Boolean} Whether layer should reproject itself based on base layer
│ │ │ │ │ - * locations. This allows reprojection onto commercial layers.
│ │ │ │ │ - * Default is false: Most layers can't reproject, but layers
│ │ │ │ │ - * which can create non-square geographic pixels can, like WMS.
│ │ │ │ │ - *
│ │ │ │ │ + * Property: state
│ │ │ │ │ + * {String}
│ │ │ │ │ */
│ │ │ │ │ - reproject: false,
│ │ │ │ │ + state: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: style
│ │ │ │ │ + * {Object}
│ │ │ │ │ + */
│ │ │ │ │ + style: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constructor: OpenLayers.Layer.HTTPRequest
│ │ │ │ │ + * APIProperty: url
│ │ │ │ │ + * {String} If this property is set it will be taken into account by
│ │ │ │ │ + * {} when upadting or deleting the feature.
│ │ │ │ │ + */
│ │ │ │ │ + url: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: renderIntent
│ │ │ │ │ + * {String} rendering intent currently being used
│ │ │ │ │ + */
│ │ │ │ │ + renderIntent: "default",
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: modified
│ │ │ │ │ + * {Object} An object with the originals of the geometry and attributes of
│ │ │ │ │ + * the feature, if they were changed. Currently this property is only read
│ │ │ │ │ + * by , and written by
│ │ │ │ │ + * , which sets the geometry property.
│ │ │ │ │ + * Applications can set the originals of modified attributes in the
│ │ │ │ │ + * attributes property. Note that applications have to check if this
│ │ │ │ │ + * object and the attributes property is already created before using it.
│ │ │ │ │ + * After a change made with ModifyFeature, this object could look like
│ │ │ │ │ + *
│ │ │ │ │ + * (code)
│ │ │ │ │ + * {
│ │ │ │ │ + * geometry: >Object
│ │ │ │ │ + * }
│ │ │ │ │ + * (end)
│ │ │ │ │ + *
│ │ │ │ │ + * When an application has made changes to feature attributes, it could
│ │ │ │ │ + * have set the attributes to something like this:
│ │ │ │ │ + *
│ │ │ │ │ + * (code)
│ │ │ │ │ + * {
│ │ │ │ │ + * attributes: {
│ │ │ │ │ + * myAttribute: "original"
│ │ │ │ │ + * }
│ │ │ │ │ + * }
│ │ │ │ │ + * (end)
│ │ │ │ │ + *
│ │ │ │ │ + * Note that only checks for truthy values in
│ │ │ │ │ + * *modified.geometry* and the attribute names in *modified.attributes*,
│ │ │ │ │ + * but it is recommended to set the original values (and not just true) as
│ │ │ │ │ + * attribute value, so applications could use this information to undo
│ │ │ │ │ + * changes.
│ │ │ │ │ + */
│ │ │ │ │ + modified: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Constructor: OpenLayers.Feature.Vector
│ │ │ │ │ + * Create a vector feature.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * name - {String}
│ │ │ │ │ - * url - {Array(String) or String}
│ │ │ │ │ - * params - {Object}
│ │ │ │ │ - * options - {Object} Hashtable of extra options to tag onto the layer
│ │ │ │ │ + * geometry - {} The geometry that this feature
│ │ │ │ │ + * represents.
│ │ │ │ │ + * attributes - {Object} An optional object that will be mapped to the
│ │ │ │ │ + * property.
│ │ │ │ │ + * style - {Object} An optional style object.
│ │ │ │ │ */
│ │ │ │ │ - initialize: function(name, url, params, options) {
│ │ │ │ │ - OpenLayers.Layer.prototype.initialize.apply(this, [name, options]);
│ │ │ │ │ - this.url = url;
│ │ │ │ │ - if (!this.params) {
│ │ │ │ │ - this.params = OpenLayers.Util.extend({}, params);
│ │ │ │ │ + initialize: function(geometry, attributes, style) {
│ │ │ │ │ + OpenLayers.Feature.prototype.initialize.apply(this,
│ │ │ │ │ + [null, null, attributes]);
│ │ │ │ │ + this.lonlat = null;
│ │ │ │ │ + this.geometry = geometry ? geometry : null;
│ │ │ │ │ + this.state = null;
│ │ │ │ │ + this.attributes = {};
│ │ │ │ │ + if (attributes) {
│ │ │ │ │ + this.attributes = OpenLayers.Util.extend(this.attributes,
│ │ │ │ │ + attributes);
│ │ │ │ │ }
│ │ │ │ │ + this.style = style ? style : null;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: destroy
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: destroy
│ │ │ │ │ + * nullify references to prevent circular references and memory leaks
│ │ │ │ │ */
│ │ │ │ │ destroy: function() {
│ │ │ │ │ - this.url = null;
│ │ │ │ │ - this.params = null;
│ │ │ │ │ - OpenLayers.Layer.prototype.destroy.apply(this, arguments);
│ │ │ │ │ + if (this.layer) {
│ │ │ │ │ + this.layer.removeFeatures(this);
│ │ │ │ │ + this.layer = null;
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + this.geometry = null;
│ │ │ │ │ + this.modified = null;
│ │ │ │ │ + OpenLayers.Feature.prototype.destroy.apply(this, arguments);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: clone
│ │ │ │ │ - *
│ │ │ │ │ + * Method: clone
│ │ │ │ │ + * Create a clone of this vector feature. Does not set any non-standard
│ │ │ │ │ + * properties.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {} An exact clone of this vector feature.
│ │ │ │ │ + */
│ │ │ │ │ + clone: function() {
│ │ │ │ │ + return new OpenLayers.Feature.Vector(
│ │ │ │ │ + this.geometry ? this.geometry.clone() : null,
│ │ │ │ │ + this.attributes,
│ │ │ │ │ + this.style);
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: onScreen
│ │ │ │ │ + * Determine whether the feature is within the map viewport. This method
│ │ │ │ │ + * tests for an intersection between the geometry and the viewport
│ │ │ │ │ + * bounds. If a more effecient but less precise geometry bounds
│ │ │ │ │ + * intersection is desired, call the method with the boundsOnly
│ │ │ │ │ + * parameter true.
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * obj - {Object}
│ │ │ │ │ + * boundsOnly - {Boolean} Only test whether a feature's bounds intersects
│ │ │ │ │ + * the viewport bounds. Default is false. If false, the feature's
│ │ │ │ │ + * geometry must intersect the viewport for onScreen to return true.
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {} An exact clone of this
│ │ │ │ │ - *
│ │ │ │ │ + * {Boolean} The feature is currently visible on screen (optionally
│ │ │ │ │ + * based on its bounds if boundsOnly is true).
│ │ │ │ │ */
│ │ │ │ │ - clone: function(obj) {
│ │ │ │ │ -
│ │ │ │ │ - if (obj == null) {
│ │ │ │ │ - obj = new OpenLayers.Layer.HTTPRequest(this.name,
│ │ │ │ │ - this.url,
│ │ │ │ │ - this.params,
│ │ │ │ │ - this.getOptions());
│ │ │ │ │ + onScreen: function(boundsOnly) {
│ │ │ │ │ + var onScreen = false;
│ │ │ │ │ + if (this.layer && this.layer.map) {
│ │ │ │ │ + var screenBounds = this.layer.map.getExtent();
│ │ │ │ │ + if (boundsOnly) {
│ │ │ │ │ + var featureBounds = this.geometry.getBounds();
│ │ │ │ │ + onScreen = screenBounds.intersectsBounds(featureBounds);
│ │ │ │ │ + } else {
│ │ │ │ │ + var screenPoly = screenBounds.toGeometry();
│ │ │ │ │ + onScreen = screenPoly.intersects(this.geometry);
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ -
│ │ │ │ │ - //get all additions from superclasses
│ │ │ │ │ - obj = OpenLayers.Layer.prototype.clone.apply(this, [obj]);
│ │ │ │ │ -
│ │ │ │ │ - // copy/set any non-init, non-simple values here
│ │ │ │ │ -
│ │ │ │ │ - return obj;
│ │ │ │ │ + return onScreen;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: setUrl
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: getVisibility
│ │ │ │ │ + * Determine whether the feature is displayed or not. It may not displayed
│ │ │ │ │ + * because:
│ │ │ │ │ + * - its style display property is set to 'none',
│ │ │ │ │ + * - it doesn't belong to any layer,
│ │ │ │ │ + * - the styleMap creates a symbolizer with display property set to 'none'
│ │ │ │ │ + * for it,
│ │ │ │ │ + * - the layer which it belongs to is not visible.
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * newUrl - {String}
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean} The feature is currently displayed.
│ │ │ │ │ */
│ │ │ │ │ - setUrl: function(newUrl) {
│ │ │ │ │ - this.url = newUrl;
│ │ │ │ │ + getVisibility: function() {
│ │ │ │ │ + return !(this.style && this.style.display == 'none' ||
│ │ │ │ │ + !this.layer ||
│ │ │ │ │ + this.layer && this.layer.styleMap &&
│ │ │ │ │ + this.layer.styleMap.createSymbolizer(this, this.renderIntent).display == 'none' ||
│ │ │ │ │ + this.layer && !this.layer.getVisibility());
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: mergeNewParams
│ │ │ │ │ + * Method: createMarker
│ │ │ │ │ + * HACK - we need to decide if all vector features should be able to
│ │ │ │ │ + * create markers
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * newParams - {Object}
│ │ │ │ │ - *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * redrawn: {Boolean} whether the layer was actually redrawn.
│ │ │ │ │ + * {} For now just returns null
│ │ │ │ │ */
│ │ │ │ │ - mergeNewParams: function(newParams) {
│ │ │ │ │ - this.params = OpenLayers.Util.extend(this.params, newParams);
│ │ │ │ │ - var ret = this.redraw();
│ │ │ │ │ - if (this.map != null) {
│ │ │ │ │ - this.map.events.triggerEvent("changelayer", {
│ │ │ │ │ - layer: this,
│ │ │ │ │ - property: "params"
│ │ │ │ │ - });
│ │ │ │ │ - }
│ │ │ │ │ - return ret;
│ │ │ │ │ + createMarker: function() {
│ │ │ │ │ + return null;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: redraw
│ │ │ │ │ - * Redraws the layer. Returns true if the layer was redrawn, false if not.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * force - {Boolean} Force redraw by adding random parameter.
│ │ │ │ │ - *
│ │ │ │ │ + * Method: destroyMarker
│ │ │ │ │ + * HACK - we need to decide if all vector features should be able to
│ │ │ │ │ + * delete markers
│ │ │ │ │ + *
│ │ │ │ │ + * If user overrides the createMarker() function, s/he should be able
│ │ │ │ │ + * to also specify an alternative function for destroying it
│ │ │ │ │ + */
│ │ │ │ │ + destroyMarker: function() {
│ │ │ │ │ + // pass
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: createPopup
│ │ │ │ │ + * HACK - we need to decide if all vector features should be able to
│ │ │ │ │ + * create popups
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Boolean} The layer was redrawn.
│ │ │ │ │ + * {} For now just returns null
│ │ │ │ │ */
│ │ │ │ │ - redraw: function(force) {
│ │ │ │ │ - if (force) {
│ │ │ │ │ - return this.mergeNewParams({
│ │ │ │ │ - "_olSalt": Math.random()
│ │ │ │ │ - });
│ │ │ │ │ - } else {
│ │ │ │ │ - return OpenLayers.Layer.prototype.redraw.apply(this, []);
│ │ │ │ │ - }
│ │ │ │ │ + createPopup: function() {
│ │ │ │ │ + return null;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: selectUrl
│ │ │ │ │ - * selectUrl() implements the standard floating-point multiplicative
│ │ │ │ │ - * hash function described by Knuth, and hashes the contents of the
│ │ │ │ │ - * given param string into a float between 0 and 1. This float is then
│ │ │ │ │ - * scaled to the size of the provided urls array, and used to select
│ │ │ │ │ - * a URL.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * paramString - {String}
│ │ │ │ │ - * urls - {Array(String)}
│ │ │ │ │ + * Method: atPoint
│ │ │ │ │ + * Determins whether the feature intersects with the specified location.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * lonlat - {|Object} OpenLayers.LonLat or an
│ │ │ │ │ + * object with a 'lon' and 'lat' properties.
│ │ │ │ │ + * toleranceLon - {float} Optional tolerance in Geometric Coords
│ │ │ │ │ + * toleranceLat - {float} Optional tolerance in Geographic Coords
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {String} An entry from the urls array, deterministically selected based
│ │ │ │ │ - * on the paramString.
│ │ │ │ │ + * {Boolean} Whether or not the feature is at the specified location
│ │ │ │ │ */
│ │ │ │ │ - selectUrl: function(paramString, urls) {
│ │ │ │ │ - var product = 1;
│ │ │ │ │ - for (var i = 0, len = paramString.length; i < len; i++) {
│ │ │ │ │ - product *= paramString.charCodeAt(i) * this.URL_HASH_FACTOR;
│ │ │ │ │ - product -= Math.floor(product);
│ │ │ │ │ + atPoint: function(lonlat, toleranceLon, toleranceLat) {
│ │ │ │ │ + var atPoint = false;
│ │ │ │ │ + if (this.geometry) {
│ │ │ │ │ + atPoint = this.geometry.atPoint(lonlat, toleranceLon,
│ │ │ │ │ + toleranceLat);
│ │ │ │ │ }
│ │ │ │ │ - return urls[Math.floor(product * urls.length)];
│ │ │ │ │ + return atPoint;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: getFullRequestString
│ │ │ │ │ - * Combine url with layer's params and these newParams.
│ │ │ │ │ - *
│ │ │ │ │ - * does checking on the serverPath variable, allowing for cases when it
│ │ │ │ │ - * is supplied with trailing ? or &, as well as cases where not.
│ │ │ │ │ - *
│ │ │ │ │ - * return in formatted string like this:
│ │ │ │ │ - * "server?key1=value1&key2=value2&key3=value3"
│ │ │ │ │ - *
│ │ │ │ │ - * WARNING: The altUrl parameter is deprecated and will be removed in 3.0.
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: destroyPopup
│ │ │ │ │ + * HACK - we need to decide if all vector features should be able to
│ │ │ │ │ + * delete popups
│ │ │ │ │ + */
│ │ │ │ │ + destroyPopup: function() {
│ │ │ │ │ + // pass
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: move
│ │ │ │ │ + * Moves the feature and redraws it at its new location
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * newParams - {Object}
│ │ │ │ │ - * altUrl - {String} Use this as the url instead of the layer's url
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String}
│ │ │ │ │ + * location - { or } the
│ │ │ │ │ + * location to which to move the feature.
│ │ │ │ │ */
│ │ │ │ │ - getFullRequestString: function(newParams, altUrl) {
│ │ │ │ │ -
│ │ │ │ │ - // if not altUrl passed in, use layer's url
│ │ │ │ │ - var url = altUrl || this.url;
│ │ │ │ │ + move: function(location) {
│ │ │ │ │
│ │ │ │ │ - // create a new params hashtable with all the layer params and the
│ │ │ │ │ - // new params together. then convert to string
│ │ │ │ │ - var allParams = OpenLayers.Util.extend({}, this.params);
│ │ │ │ │ - allParams = OpenLayers.Util.extend(allParams, newParams);
│ │ │ │ │ - var paramsString = OpenLayers.Util.getParameterString(allParams);
│ │ │ │ │ + if (!this.layer || !this.geometry.move) {
│ │ │ │ │ + //do nothing if no layer or immoveable geometry
│ │ │ │ │ + return undefined;
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - // if url is not a string, it should be an array of strings,
│ │ │ │ │ - // in which case we will deterministically select one of them in
│ │ │ │ │ - // order to evenly distribute requests to different urls.
│ │ │ │ │ - //
│ │ │ │ │ - if (OpenLayers.Util.isArray(url)) {
│ │ │ │ │ - url = this.selectUrl(paramsString, url);
│ │ │ │ │ + var pixel;
│ │ │ │ │ + if (location.CLASS_NAME == "OpenLayers.LonLat") {
│ │ │ │ │ + pixel = this.layer.getViewPortPxFromLonLat(location);
│ │ │ │ │ + } else {
│ │ │ │ │ + pixel = location;
│ │ │ │ │ }
│ │ │ │ │
│ │ │ │ │ - // ignore parameters that are already in the url search string
│ │ │ │ │ - var urlParams =
│ │ │ │ │ - OpenLayers.Util.upperCaseObject(OpenLayers.Util.getParameters(url));
│ │ │ │ │ - for (var key in allParams) {
│ │ │ │ │ - if (key.toUpperCase() in urlParams) {
│ │ │ │ │ - delete allParams[key];
│ │ │ │ │ + var lastPixel = this.layer.getViewPortPxFromLonLat(this.geometry.getBounds().getCenterLonLat());
│ │ │ │ │ + var res = this.layer.map.getResolution();
│ │ │ │ │ + this.geometry.move(res * (pixel.x - lastPixel.x),
│ │ │ │ │ + res * (lastPixel.y - pixel.y));
│ │ │ │ │ + this.layer.drawFeature(this);
│ │ │ │ │ + return lastPixel;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: toState
│ │ │ │ │ + * Sets the new state
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * state - {String}
│ │ │ │ │ + */
│ │ │ │ │ + toState: function(state) {
│ │ │ │ │ + if (state == OpenLayers.State.UPDATE) {
│ │ │ │ │ + switch (this.state) {
│ │ │ │ │ + case OpenLayers.State.UNKNOWN:
│ │ │ │ │ + case OpenLayers.State.DELETE:
│ │ │ │ │ + this.state = state;
│ │ │ │ │ + break;
│ │ │ │ │ + case OpenLayers.State.UPDATE:
│ │ │ │ │ + case OpenLayers.State.INSERT:
│ │ │ │ │ + break;
│ │ │ │ │ + }
│ │ │ │ │ + } else if (state == OpenLayers.State.INSERT) {
│ │ │ │ │ + switch (this.state) {
│ │ │ │ │ + case OpenLayers.State.UNKNOWN:
│ │ │ │ │ + break;
│ │ │ │ │ + default:
│ │ │ │ │ + this.state = state;
│ │ │ │ │ + break;
│ │ │ │ │ + }
│ │ │ │ │ + } else if (state == OpenLayers.State.DELETE) {
│ │ │ │ │ + switch (this.state) {
│ │ │ │ │ + case OpenLayers.State.INSERT:
│ │ │ │ │ + // the feature should be destroyed
│ │ │ │ │ + break;
│ │ │ │ │ + case OpenLayers.State.DELETE:
│ │ │ │ │ + break;
│ │ │ │ │ + case OpenLayers.State.UNKNOWN:
│ │ │ │ │ + case OpenLayers.State.UPDATE:
│ │ │ │ │ + this.state = state;
│ │ │ │ │ + break;
│ │ │ │ │ }
│ │ │ │ │ + } else if (state == OpenLayers.State.UNKNOWN) {
│ │ │ │ │ + this.state = state;
│ │ │ │ │ }
│ │ │ │ │ - paramsString = OpenLayers.Util.getParameterString(allParams);
│ │ │ │ │ -
│ │ │ │ │ - return OpenLayers.Util.urlAppend(url, paramsString);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Layer.HTTPRequest"
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Feature.Vector"
│ │ │ │ │ });
│ │ │ │ │ +
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Constant: OpenLayers.Feature.Vector.style
│ │ │ │ │ + * OpenLayers features can have a number of style attributes. The 'default'
│ │ │ │ │ + * style will typically be used if no other style is specified. These
│ │ │ │ │ + * styles correspond for the most part, to the styling properties defined
│ │ │ │ │ + * by the SVG standard.
│ │ │ │ │ + * Information on fill properties: http://www.w3.org/TR/SVG/painting.html#FillProperties
│ │ │ │ │ + * Information on stroke properties: http://www.w3.org/TR/SVG/painting.html#StrokeProperties
│ │ │ │ │ + *
│ │ │ │ │ + * Symbolizer properties:
│ │ │ │ │ + * fill - {Boolean} Set to false if no fill is desired.
│ │ │ │ │ + * fillColor - {String} Hex fill color. Default is "#ee9900".
│ │ │ │ │ + * fillOpacity - {Number} Fill opacity (0-1). Default is 0.4
│ │ │ │ │ + * stroke - {Boolean} Set to false if no stroke is desired.
│ │ │ │ │ + * strokeColor - {String} Hex stroke color. Default is "#ee9900".
│ │ │ │ │ + * strokeOpacity - {Number} Stroke opacity (0-1). Default is 1.
│ │ │ │ │ + * strokeWidth - {Number} Pixel stroke width. Default is 1.
│ │ │ │ │ + * strokeLinecap - {String} Stroke cap type. Default is "round". [butt | round | square]
│ │ │ │ │ + * strokeDashstyle - {String} Stroke dash style. Default is "solid". [dot | dash | dashdot | longdash | longdashdot | solid]
│ │ │ │ │ + * graphic - {Boolean} Set to false if no graphic is desired.
│ │ │ │ │ + * pointRadius - {Number} Pixel point radius. Default is 6.
│ │ │ │ │ + * pointerEvents - {String} Default is "visiblePainted".
│ │ │ │ │ + * cursor - {String} Default is "".
│ │ │ │ │ + * externalGraphic - {String} Url to an external graphic that will be used for rendering points.
│ │ │ │ │ + * graphicWidth - {Number} Pixel width for sizing an external graphic.
│ │ │ │ │ + * graphicHeight - {Number} Pixel height for sizing an external graphic.
│ │ │ │ │ + * graphicOpacity - {Number} Opacity (0-1) for an external graphic.
│ │ │ │ │ + * graphicXOffset - {Number} Pixel offset along the positive x axis for displacing an external graphic.
│ │ │ │ │ + * graphicYOffset - {Number} Pixel offset along the positive y axis for displacing an external graphic.
│ │ │ │ │ + * rotation - {Number} For point symbolizers, this is the rotation of a graphic in the clockwise direction about its center point (or any point off center as specified by graphicXOffset and graphicYOffset).
│ │ │ │ │ + * graphicZIndex - {Number} The integer z-index value to use in rendering.
│ │ │ │ │ + * graphicName - {String} Named graphic to use when rendering points. Supported values include "circle" (default),
│ │ │ │ │ + * "square", "star", "x", "cross", "triangle".
│ │ │ │ │ + * graphicTitle - {String} Tooltip when hovering over a feature. *deprecated*, use title instead
│ │ │ │ │ + * title - {String} Tooltip when hovering over a feature. Not supported by the canvas renderer.
│ │ │ │ │ + * backgroundGraphic - {String} Url to a graphic to be used as the background under an externalGraphic.
│ │ │ │ │ + * backgroundGraphicZIndex - {Number} The integer z-index value to use in rendering the background graphic.
│ │ │ │ │ + * backgroundXOffset - {Number} The x offset (in pixels) for the background graphic.
│ │ │ │ │ + * backgroundYOffset - {Number} The y offset (in pixels) for the background graphic.
│ │ │ │ │ + * backgroundHeight - {Number} The height of the background graphic. If not provided, the graphicHeight will be used.
│ │ │ │ │ + * backgroundWidth - {Number} The width of the background width. If not provided, the graphicWidth will be used.
│ │ │ │ │ + * label - {String} The text for an optional label. For browsers that use the canvas renderer, this requires either
│ │ │ │ │ + * fillText or mozDrawText to be available.
│ │ │ │ │ + * labelAlign - {String} Label alignment. This specifies the insertion point relative to the text. It is a string
│ │ │ │ │ + * composed of two characters. The first character is for the horizontal alignment, the second for the vertical
│ │ │ │ │ + * alignment. Valid values for horizontal alignment: "l"=left, "c"=center, "r"=right. Valid values for vertical
│ │ │ │ │ + * alignment: "t"=top, "m"=middle, "b"=bottom. Example values: "lt", "cm", "rb". Default is "cm".
│ │ │ │ │ + * labelXOffset - {Number} Pixel offset along the positive x axis for displacing the label. Not supported by the canvas renderer.
│ │ │ │ │ + * labelYOffset - {Number} Pixel offset along the positive y axis for displacing the label. Not supported by the canvas renderer.
│ │ │ │ │ + * labelSelect - {Boolean} If set to true, labels will be selectable using SelectFeature or similar controls.
│ │ │ │ │ + * Default is false.
│ │ │ │ │ + * labelOutlineColor - {String} The color of the label outline. Default is 'white'. Only supported by the canvas & SVG renderers.
│ │ │ │ │ + * labelOutlineWidth - {Number} The width of the label outline. Default is 3, set to 0 or null to disable. Only supported by the SVG renderers.
│ │ │ │ │ + * labelOutlineOpacity - {Number} The opacity (0-1) of the label outline. Default is fontOpacity. Only supported by the canvas & SVG renderers.
│ │ │ │ │ + * fontColor - {String} The font color for the label, to be provided like CSS.
│ │ │ │ │ + * fontOpacity - {Number} Opacity (0-1) for the label
│ │ │ │ │ + * fontFamily - {String} The font family for the label, to be provided like in CSS.
│ │ │ │ │ + * fontSize - {String} The font size for the label, to be provided like in CSS.
│ │ │ │ │ + * fontStyle - {String} The font style for the label, to be provided like in CSS.
│ │ │ │ │ + * fontWeight - {String} The font weight for the label, to be provided like in CSS.
│ │ │ │ │ + * display - {String} Symbolizers will have no effect if display is set to "none". All other values have no effect.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Feature.Vector.style = {
│ │ │ │ │ + 'default': {
│ │ │ │ │ + fillColor: "#ee9900",
│ │ │ │ │ + fillOpacity: 0.4,
│ │ │ │ │ + hoverFillColor: "white",
│ │ │ │ │ + hoverFillOpacity: 0.8,
│ │ │ │ │ + strokeColor: "#ee9900",
│ │ │ │ │ + strokeOpacity: 1,
│ │ │ │ │ + strokeWidth: 1,
│ │ │ │ │ + strokeLinecap: "round",
│ │ │ │ │ + strokeDashstyle: "solid",
│ │ │ │ │ + hoverStrokeColor: "red",
│ │ │ │ │ + hoverStrokeOpacity: 1,
│ │ │ │ │ + hoverStrokeWidth: 0.2,
│ │ │ │ │ + pointRadius: 6,
│ │ │ │ │ + hoverPointRadius: 1,
│ │ │ │ │ + hoverPointUnit: "%",
│ │ │ │ │ + pointerEvents: "visiblePainted",
│ │ │ │ │ + cursor: "inherit",
│ │ │ │ │ + fontColor: "#000000",
│ │ │ │ │ + labelAlign: "cm",
│ │ │ │ │ + labelOutlineColor: "white",
│ │ │ │ │ + labelOutlineWidth: 3
│ │ │ │ │ + },
│ │ │ │ │ + 'select': {
│ │ │ │ │ + fillColor: "blue",
│ │ │ │ │ + fillOpacity: 0.4,
│ │ │ │ │ + hoverFillColor: "white",
│ │ │ │ │ + hoverFillOpacity: 0.8,
│ │ │ │ │ + strokeColor: "blue",
│ │ │ │ │ + strokeOpacity: 1,
│ │ │ │ │ + strokeWidth: 2,
│ │ │ │ │ + strokeLinecap: "round",
│ │ │ │ │ + strokeDashstyle: "solid",
│ │ │ │ │ + hoverStrokeColor: "red",
│ │ │ │ │ + hoverStrokeOpacity: 1,
│ │ │ │ │ + hoverStrokeWidth: 0.2,
│ │ │ │ │ + pointRadius: 6,
│ │ │ │ │ + hoverPointRadius: 1,
│ │ │ │ │ + hoverPointUnit: "%",
│ │ │ │ │ + pointerEvents: "visiblePainted",
│ │ │ │ │ + cursor: "pointer",
│ │ │ │ │ + fontColor: "#000000",
│ │ │ │ │ + labelAlign: "cm",
│ │ │ │ │ + labelOutlineColor: "white",
│ │ │ │ │ + labelOutlineWidth: 3
│ │ │ │ │ +
│ │ │ │ │ + },
│ │ │ │ │ + 'temporary': {
│ │ │ │ │ + fillColor: "#66cccc",
│ │ │ │ │ + fillOpacity: 0.2,
│ │ │ │ │ + hoverFillColor: "white",
│ │ │ │ │ + hoverFillOpacity: 0.8,
│ │ │ │ │ + strokeColor: "#66cccc",
│ │ │ │ │ + strokeOpacity: 1,
│ │ │ │ │ + strokeLinecap: "round",
│ │ │ │ │ + strokeWidth: 2,
│ │ │ │ │ + strokeDashstyle: "solid",
│ │ │ │ │ + hoverStrokeColor: "red",
│ │ │ │ │ + hoverStrokeOpacity: 1,
│ │ │ │ │ + hoverStrokeWidth: 0.2,
│ │ │ │ │ + pointRadius: 6,
│ │ │ │ │ + hoverPointRadius: 1,
│ │ │ │ │ + hoverPointUnit: "%",
│ │ │ │ │ + pointerEvents: "visiblePainted",
│ │ │ │ │ + cursor: "inherit",
│ │ │ │ │ + fontColor: "#000000",
│ │ │ │ │ + labelAlign: "cm",
│ │ │ │ │ + labelOutlineColor: "white",
│ │ │ │ │ + labelOutlineWidth: 3
│ │ │ │ │ +
│ │ │ │ │ + },
│ │ │ │ │ + 'delete': {
│ │ │ │ │ + display: "none"
│ │ │ │ │ + }
│ │ │ │ │ +};
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Tile.js
│ │ │ │ │ + OpenLayers/Format.js
│ │ │ │ │ ====================================================================== */
│ │ │ │ │
│ │ │ │ │ /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ * full text of the license. */
│ │ │ │ │
│ │ │ │ │ -
│ │ │ │ │ /**
│ │ │ │ │ * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ * @requires OpenLayers/Util.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Class: OpenLayers.Tile
│ │ │ │ │ - * This is a class designed to designate a single tile, however
│ │ │ │ │ - * it is explicitly designed to do relatively little. Tiles store
│ │ │ │ │ - * information about themselves -- such as the URL that they are related
│ │ │ │ │ - * to, and their size - but do not add themselves to the layer div
│ │ │ │ │ - * automatically, for example. Create a new tile with the
│ │ │ │ │ - * constructor, or a subclass.
│ │ │ │ │ - *
│ │ │ │ │ - * TBD 3.0 - remove reference to url in above paragraph
│ │ │ │ │ - *
│ │ │ │ │ + * Class: OpenLayers.Format
│ │ │ │ │ + * Base class for format reading/writing a variety of formats. Subclasses
│ │ │ │ │ + * of OpenLayers.Format are expected to have read and write methods.
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Tile = OpenLayers.Class({
│ │ │ │ │ +OpenLayers.Format = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: events
│ │ │ │ │ - * {} An events object that handles all
│ │ │ │ │ - * events on the tile.
│ │ │ │ │ - *
│ │ │ │ │ - * Register a listener for a particular event with the following syntax:
│ │ │ │ │ - * (code)
│ │ │ │ │ - * tile.events.register(type, obj, listener);
│ │ │ │ │ - * (end)
│ │ │ │ │ - *
│ │ │ │ │ - * Supported event types:
│ │ │ │ │ - * beforedraw - Triggered before the tile is drawn. Used to defer
│ │ │ │ │ - * drawing to an animation queue. To defer drawing, listeners need
│ │ │ │ │ - * to return false, which will abort drawing. The queue handler needs
│ │ │ │ │ - * to call (true) to actually draw the tile.
│ │ │ │ │ - * loadstart - Triggered when tile loading starts.
│ │ │ │ │ - * loadend - Triggered when tile loading ends.
│ │ │ │ │ - * loaderror - Triggered before the loadend event (i.e. when the tile is
│ │ │ │ │ - * still hidden) if the tile could not be loaded.
│ │ │ │ │ - * reload - Triggered when an already loading tile is reloaded.
│ │ │ │ │ - * unload - Triggered before a tile is unloaded.
│ │ │ │ │ + * Property: options
│ │ │ │ │ + * {Object} A reference to options passed to the constructor.
│ │ │ │ │ */
│ │ │ │ │ - events: null,
│ │ │ │ │ + options: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: eventListeners
│ │ │ │ │ - * {Object} If set as an option at construction, the eventListeners
│ │ │ │ │ - * object will be registered with . Object
│ │ │ │ │ - * structure must be a listeners object as shown in the example for
│ │ │ │ │ - * the events.on method.
│ │ │ │ │ - *
│ │ │ │ │ - * This options can be set in the ``tileOptions`` option from
│ │ │ │ │ - * . For example, to be notified of the
│ │ │ │ │ - * ``loadend`` event of each tiles:
│ │ │ │ │ - * (code)
│ │ │ │ │ - * new OpenLayers.Layer.OSM('osm', 'http://tile.openstreetmap.org/${z}/${x}/${y}.png', {
│ │ │ │ │ - * tileOptions: {
│ │ │ │ │ - * eventListeners: {
│ │ │ │ │ - * 'loadend': function(evt) {
│ │ │ │ │ - * // do something on loadend
│ │ │ │ │ - * }
│ │ │ │ │ - * }
│ │ │ │ │ - * }
│ │ │ │ │ - * });
│ │ │ │ │ - * (end)
│ │ │ │ │ + * APIProperty: externalProjection
│ │ │ │ │ + * {} When passed a externalProjection and
│ │ │ │ │ + * internalProjection, the format will reproject the geometries it
│ │ │ │ │ + * reads or writes. The externalProjection is the projection used by
│ │ │ │ │ + * the content which is passed into read or which comes out of write.
│ │ │ │ │ + * In order to reproject, a projection transformation function for the
│ │ │ │ │ + * specified projections must be available. This support may be
│ │ │ │ │ + * provided via proj4js or via a custom transformation function. See
│ │ │ │ │ + * {} for more information on
│ │ │ │ │ + * custom transformations.
│ │ │ │ │ */
│ │ │ │ │ - eventListeners: null,
│ │ │ │ │ + externalProjection: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: id
│ │ │ │ │ - * {String} null
│ │ │ │ │ - */
│ │ │ │ │ - id: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: layer
│ │ │ │ │ - * {} layer the tile is attached to
│ │ │ │ │ + * APIProperty: internalProjection
│ │ │ │ │ + * {} When passed a externalProjection and
│ │ │ │ │ + * internalProjection, the format will reproject the geometries it
│ │ │ │ │ + * reads or writes. The internalProjection is the projection used by
│ │ │ │ │ + * the geometries which are returned by read or which are passed into
│ │ │ │ │ + * write. In order to reproject, a projection transformation function
│ │ │ │ │ + * for the specified projections must be available. This support may be
│ │ │ │ │ + * provided via proj4js or via a custom transformation function. See
│ │ │ │ │ + * {} for more information on
│ │ │ │ │ + * custom transformations.
│ │ │ │ │ */
│ │ │ │ │ - layer: null,
│ │ │ │ │ + internalProjection: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: url
│ │ │ │ │ - * {String} url of the request.
│ │ │ │ │ - *
│ │ │ │ │ - * TBD 3.0
│ │ │ │ │ - * Deprecated. The base tile class does not need an url. This should be
│ │ │ │ │ - * handled in subclasses. Does not belong here.
│ │ │ │ │ - */
│ │ │ │ │ - url: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: bounds
│ │ │ │ │ - * {} null
│ │ │ │ │ - */
│ │ │ │ │ - bounds: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: size
│ │ │ │ │ - * {} null
│ │ │ │ │ - */
│ │ │ │ │ - size: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: position
│ │ │ │ │ - * {} Top Left pixel of the tile
│ │ │ │ │ + * APIProperty: data
│ │ │ │ │ + * {Object} When is true, this is the parsed string sent to
│ │ │ │ │ + * .
│ │ │ │ │ */
│ │ │ │ │ - position: null,
│ │ │ │ │ + data: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: isLoading
│ │ │ │ │ - * {Boolean} Is the tile loading?
│ │ │ │ │ - */
│ │ │ │ │ - isLoading: false,
│ │ │ │ │ -
│ │ │ │ │ - /** TBD 3.0 -- remove 'url' from the list of parameters to the constructor.
│ │ │ │ │ - * there is no need for the base tile class to have a url.
│ │ │ │ │ + * APIProperty: keepData
│ │ │ │ │ + * {Object} Maintain a reference () to the most recently read data.
│ │ │ │ │ + * Default is false.
│ │ │ │ │ */
│ │ │ │ │ + keepData: false,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Tile
│ │ │ │ │ - * Constructor for a new instance.
│ │ │ │ │ - *
│ │ │ │ │ + /**
│ │ │ │ │ + * Constructor: OpenLayers.Format
│ │ │ │ │ + * Instances of this class are not useful. See one of the subclasses.
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * layer - {} layer that the tile will go in.
│ │ │ │ │ - * position - {}
│ │ │ │ │ - * bounds - {}
│ │ │ │ │ - * url - {}
│ │ │ │ │ - * size - {}
│ │ │ │ │ - * options - {Object}
│ │ │ │ │ + * options - {Object} An optional object with properties to set on the
│ │ │ │ │ + * format
│ │ │ │ │ + *
│ │ │ │ │ + * Valid options:
│ │ │ │ │ + * keepData - {Boolean} If true, upon , the data property will be
│ │ │ │ │ + * set to the parsed object (e.g. the json or xml object).
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * An instance of OpenLayers.Format
│ │ │ │ │ */
│ │ │ │ │ - initialize: function(layer, position, bounds, url, size, options) {
│ │ │ │ │ - this.layer = layer;
│ │ │ │ │ - this.position = position.clone();
│ │ │ │ │ - this.setBounds(bounds);
│ │ │ │ │ - this.url = url;
│ │ │ │ │ - if (size) {
│ │ │ │ │ - this.size = size.clone();
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - //give the tile a unique id based on its BBOX.
│ │ │ │ │ - this.id = OpenLayers.Util.createUniqueID("Tile_");
│ │ │ │ │ -
│ │ │ │ │ + initialize: function(options) {
│ │ │ │ │ OpenLayers.Util.extend(this, options);
│ │ │ │ │ -
│ │ │ │ │ - this.events = new OpenLayers.Events(this);
│ │ │ │ │ - if (this.eventListeners instanceof Object) {
│ │ │ │ │ - this.events.on(this.eventListeners);
│ │ │ │ │ - }
│ │ │ │ │ + this.options = options;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: unload
│ │ │ │ │ - * Call immediately before destroying if you are listening to tile
│ │ │ │ │ - * events, so that counters are properly handled if tile is still
│ │ │ │ │ - * loading at destroy-time. Will only fire an event if the tile is
│ │ │ │ │ - * still loading.
│ │ │ │ │ - */
│ │ │ │ │ - unload: function() {
│ │ │ │ │ - if (this.isLoading) {
│ │ │ │ │ - this.isLoading = false;
│ │ │ │ │ - this.events.triggerEvent("unload");
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ * APIMethod: destroy
│ │ │ │ │ - * Nullify references to prevent circular references and memory leaks.
│ │ │ │ │ - */
│ │ │ │ │ - destroy: function() {
│ │ │ │ │ - this.layer = null;
│ │ │ │ │ - this.bounds = null;
│ │ │ │ │ - this.size = null;
│ │ │ │ │ - this.position = null;
│ │ │ │ │ -
│ │ │ │ │ - if (this.eventListeners) {
│ │ │ │ │ - this.events.un(this.eventListeners);
│ │ │ │ │ - }
│ │ │ │ │ - this.events.destroy();
│ │ │ │ │ - this.eventListeners = null;
│ │ │ │ │ - this.events = null;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: draw
│ │ │ │ │ - * Clear whatever is currently in the tile, then return whether or not
│ │ │ │ │ - * it should actually be re-drawn. This is an example implementation
│ │ │ │ │ - * that can be overridden by subclasses. The minimum thing to do here
│ │ │ │ │ - * is to call and return the result from .
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * force - {Boolean} If true, the tile will not be cleared and no beforedraw
│ │ │ │ │ - * event will be fired. This is used for drawing tiles asynchronously
│ │ │ │ │ - * after drawing has been cancelled by returning false from a beforedraw
│ │ │ │ │ - * listener.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} Whether or not the tile should actually be drawn. Returns null
│ │ │ │ │ - * if a beforedraw listener returned false.
│ │ │ │ │ + * Clean up.
│ │ │ │ │ */
│ │ │ │ │ - draw: function(force) {
│ │ │ │ │ - if (!force) {
│ │ │ │ │ - //clear tile's contents and mark as not drawn
│ │ │ │ │ - this.clear();
│ │ │ │ │ - }
│ │ │ │ │ - var draw = this.shouldDraw();
│ │ │ │ │ - if (draw && !force && this.events.triggerEvent("beforedraw") === false) {
│ │ │ │ │ - draw = null;
│ │ │ │ │ - }
│ │ │ │ │ - return draw;
│ │ │ │ │ - },
│ │ │ │ │ + destroy: function() {},
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: shouldDraw
│ │ │ │ │ - * Return whether or not the tile should actually be (re-)drawn. The only
│ │ │ │ │ - * case where we *wouldn't* want to draw the tile is if the tile is outside
│ │ │ │ │ - * its layer's maxExtent
│ │ │ │ │ + * Method: read
│ │ │ │ │ + * Read data from a string, and return an object whose type depends on the
│ │ │ │ │ + * subclass.
│ │ │ │ │ *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * data - {string} Data to read/parse.
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Boolean} Whether or not the tile should actually be drawn.
│ │ │ │ │ + * Depends on the subclass
│ │ │ │ │ */
│ │ │ │ │ - shouldDraw: function() {
│ │ │ │ │ - var withinMaxExtent = false,
│ │ │ │ │ - maxExtent = this.layer.maxExtent;
│ │ │ │ │ - if (maxExtent) {
│ │ │ │ │ - var map = this.layer.map;
│ │ │ │ │ - var worldBounds = map.baseLayer.wrapDateLine && map.getMaxExtent();
│ │ │ │ │ - if (this.bounds.intersectsBounds(maxExtent, {
│ │ │ │ │ - inclusive: false,
│ │ │ │ │ - worldBounds: worldBounds
│ │ │ │ │ - })) {
│ │ │ │ │ - withinMaxExtent = true;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - return withinMaxExtent || this.layer.displayOutsideMaxExtent;
│ │ │ │ │ + read: function(data) {
│ │ │ │ │ + throw new Error('Read not implemented.');
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: setBounds
│ │ │ │ │ - * Sets the bounds on this instance
│ │ │ │ │ + * Method: write
│ │ │ │ │ + * Accept an object, and return a string.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * bounds {}
│ │ │ │ │ - */
│ │ │ │ │ - setBounds: function(bounds) {
│ │ │ │ │ - bounds = bounds.clone();
│ │ │ │ │ - if (this.layer.map.baseLayer.wrapDateLine) {
│ │ │ │ │ - var worldExtent = this.layer.map.getMaxExtent(),
│ │ │ │ │ - tolerance = this.layer.map.getResolution();
│ │ │ │ │ - bounds = bounds.wrapDateLine(worldExtent, {
│ │ │ │ │ - leftTolerance: tolerance,
│ │ │ │ │ - rightTolerance: tolerance
│ │ │ │ │ - });
│ │ │ │ │ - }
│ │ │ │ │ - this.bounds = bounds;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: moveTo
│ │ │ │ │ - * Reposition the tile.
│ │ │ │ │ + * object - {Object} Object to be serialized
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * bounds - {}
│ │ │ │ │ - * position - {}
│ │ │ │ │ - * redraw - {Boolean} Call draw method on tile after moving.
│ │ │ │ │ - * Default is true
│ │ │ │ │ - */
│ │ │ │ │ - moveTo: function(bounds, position, redraw) {
│ │ │ │ │ - if (redraw == null) {
│ │ │ │ │ - redraw = true;
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - this.setBounds(bounds);
│ │ │ │ │ - this.position = position.clone();
│ │ │ │ │ - if (redraw) {
│ │ │ │ │ - this.draw();
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: clear
│ │ │ │ │ - * Clear the tile of any bounds/position-related data so that it can
│ │ │ │ │ - * be reused in a new location.
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {String} A string representation of the object.
│ │ │ │ │ */
│ │ │ │ │ - clear: function(draw) {
│ │ │ │ │ - // to be extended by subclasses
│ │ │ │ │ + write: function(object) {
│ │ │ │ │ + throw new Error('Write not implemented.');
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Tile"
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Format"
│ │ │ │ │ });
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Tile/Image.js
│ │ │ │ │ + OpenLayers/Geometry/Point.js
│ │ │ │ │ ====================================================================== */
│ │ │ │ │
│ │ │ │ │ /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ * full text of the license. */
│ │ │ │ │
│ │ │ │ │ -
│ │ │ │ │ /**
│ │ │ │ │ - * @requires OpenLayers/Tile.js
│ │ │ │ │ - * @requires OpenLayers/Animation.js
│ │ │ │ │ - * @requires OpenLayers/Util.js
│ │ │ │ │ + * @requires OpenLayers/Geometry.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Class: OpenLayers.Tile.Image
│ │ │ │ │ - * Instances of OpenLayers.Tile.Image are used to manage the image tiles
│ │ │ │ │ - * used by various layers. Create a new image tile with the
│ │ │ │ │ - * constructor.
│ │ │ │ │ - *
│ │ │ │ │ + * Class: OpenLayers.Geometry.Point
│ │ │ │ │ + * Point geometry class.
│ │ │ │ │ + *
│ │ │ │ │ * Inherits from:
│ │ │ │ │ - * -
│ │ │ │ │ + * -
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: events
│ │ │ │ │ - * {} An events object that handles all
│ │ │ │ │ - * events on the tile.
│ │ │ │ │ - *
│ │ │ │ │ - * Register a listener for a particular event with the following syntax:
│ │ │ │ │ - * (code)
│ │ │ │ │ - * tile.events.register(type, obj, listener);
│ │ │ │ │ - * (end)
│ │ │ │ │ - *
│ │ │ │ │ - * Supported event types (in addition to the events):
│ │ │ │ │ - * beforeload - Triggered before an image is prepared for loading, when the
│ │ │ │ │ - * url for the image is known already. Listeners may call on
│ │ │ │ │ - * the tile instance. If they do so, that image will be used and no new
│ │ │ │ │ - * one will be created.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: url
│ │ │ │ │ - * {String} The URL of the image being requested. No default. Filled in by
│ │ │ │ │ - * layer.getURL() function. May be modified by loadstart listeners.
│ │ │ │ │ - */
│ │ │ │ │ - url: null,
│ │ │ │ │ +OpenLayers.Geometry.Point = OpenLayers.Class(OpenLayers.Geometry, {
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: imgDiv
│ │ │ │ │ - * {HTMLImageElement} The image for this tile.
│ │ │ │ │ - */
│ │ │ │ │ - imgDiv: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: frame
│ │ │ │ │ - * {DOMElement} The image element is appended to the frame. Any gutter on
│ │ │ │ │ - * the image will be hidden behind the frame. If no gutter is set,
│ │ │ │ │ - * this will be null.
│ │ │ │ │ + * APIProperty: x
│ │ │ │ │ + * {float}
│ │ │ │ │ */
│ │ │ │ │ - frame: null,
│ │ │ │ │ + x: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: imageReloadAttempts
│ │ │ │ │ - * {Integer} Attempts to load the image.
│ │ │ │ │ - */
│ │ │ │ │ - imageReloadAttempts: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: layerAlphaHack
│ │ │ │ │ - * {Boolean} True if the png alpha hack needs to be applied on the layer's div.
│ │ │ │ │ - */
│ │ │ │ │ - layerAlphaHack: null,
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: asyncRequestId
│ │ │ │ │ - * {Integer} ID of an request to see if request is still valid. This is a
│ │ │ │ │ - * number which increments by 1 for each asynchronous request.
│ │ │ │ │ + * APIProperty: y
│ │ │ │ │ + * {float}
│ │ │ │ │ */
│ │ │ │ │ - asyncRequestId: null,
│ │ │ │ │ + y: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: maxGetUrlLength
│ │ │ │ │ - * {Number} If set, requests that would result in GET urls with more
│ │ │ │ │ - * characters than the number provided will be made using form-encoded
│ │ │ │ │ - * HTTP POST. It is good practice to avoid urls that are longer than 2048
│ │ │ │ │ - * characters.
│ │ │ │ │ + * Constructor: OpenLayers.Geometry.Point
│ │ │ │ │ + * Construct a point geometry.
│ │ │ │ │ *
│ │ │ │ │ - * Caution:
│ │ │ │ │ - * Older versions of Gecko based browsers (e.g. Firefox < 3.5) and most
│ │ │ │ │ - * Opera versions do not fully support this option. On all browsers,
│ │ │ │ │ - * transition effects are not supported if POST requests are used.
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * x - {float}
│ │ │ │ │ + * y - {float}
│ │ │ │ │ + *
│ │ │ │ │ */
│ │ │ │ │ - maxGetUrlLength: null,
│ │ │ │ │ + initialize: function(x, y) {
│ │ │ │ │ + OpenLayers.Geometry.prototype.initialize.apply(this, arguments);
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: canvasContext
│ │ │ │ │ - * {CanvasRenderingContext2D} A canvas context associated with
│ │ │ │ │ - * the tile image.
│ │ │ │ │ - */
│ │ │ │ │ - canvasContext: null,
│ │ │ │ │ + this.x = parseFloat(x);
│ │ │ │ │ + this.y = parseFloat(y);
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: crossOriginKeyword
│ │ │ │ │ - * The value of the crossorigin keyword to use when loading images. This is
│ │ │ │ │ - * only relevant when using for tiles from remote
│ │ │ │ │ - * origins and should be set to either 'anonymous' or 'use-credentials'
│ │ │ │ │ - * for servers that send Access-Control-Allow-Origin headers with their
│ │ │ │ │ - * tiles.
│ │ │ │ │ - */
│ │ │ │ │ - crossOriginKeyword: null,
│ │ │ │ │ -
│ │ │ │ │ - /** TBD 3.0 - reorder the parameters to the init function to remove
│ │ │ │ │ - * URL. the getUrl() function on the layer gets called on
│ │ │ │ │ - * each draw(), so no need to specify it here.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Tile.Image
│ │ │ │ │ - * Constructor for a new instance.
│ │ │ │ │ + * APIMethod: clone
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * layer - {} layer that the tile will go in.
│ │ │ │ │ - * position - {}
│ │ │ │ │ - * bounds - {