--- /srv/reproducible-results/rbuild-debian/r-b-build.59zYmMjR/b1/openlayers_2.13.1+ds2-10_amd64.changes
+++ /srv/reproducible-results/rbuild-debian/r-b-build.59zYmMjR/b2/openlayers_2.13.1+ds2-10_amd64.changes
├── Files
│ @@ -1,2 +1,2 @@
│
│ - b8f862d3ec74ba06200c117bb86bd490 715748 javascript optional libjs-openlayers_2.13.1+ds2-10_all.deb
│ + ed0d68076b09c8e93a24f9653872d0fa 706992 javascript optional libjs-openlayers_2.13.1+ds2-10_all.deb
├── libjs-openlayers_2.13.1+ds2-10_all.deb
│ ├── file list
│ │ @@ -1,3 +1,3 @@
│ │ -rw-r--r-- 0 0 0 4 2023-01-14 13:27:41.000000 debian-binary
│ │ --rw-r--r-- 0 0 0 3684 2023-01-14 13:27:41.000000 control.tar.xz
│ │ --rw-r--r-- 0 0 0 711872 2023-01-14 13:27:41.000000 data.tar.xz
│ │ +-rw-r--r-- 0 0 0 3680 2023-01-14 13:27:41.000000 control.tar.xz
│ │ +-rw-r--r-- 0 0 0 703120 2023-01-14 13:27:41.000000 data.tar.xz
│ ├── control.tar.xz
│ │ ├── control.tar
│ │ │ ├── ./md5sums
│ │ │ │ ├── ./md5sums
│ │ │ │ │┄ Files differ
│ ├── data.tar.xz
│ │ ├── data.tar
│ │ │ ├── ./usr/share/javascript/openlayers/OpenLayers.js
│ │ │ │ ├── js-beautify {}
│ │ │ │ │ @@ -136,14 +136,394 @@
│ │ │ │ │ * (code)
│ │ │ │ │ *
│ │ │ │ │ * (end code)
│ │ │ │ │ */
│ │ │ │ │ ImgPath: ''
│ │ │ │ │ };
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ + OpenLayers/BaseTypes/Class.js
│ │ │ │ │ + ====================================================================== */
│ │ │ │ │ +
│ │ │ │ │ +/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ + * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ + * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ + * full text of the license. */
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * @requires OpenLayers/SingleFile.js
│ │ │ │ │ + */
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Constructor: OpenLayers.Class
│ │ │ │ │ + * Base class used to construct all other classes. Includes support for
│ │ │ │ │ + * multiple inheritance.
│ │ │ │ │ + *
│ │ │ │ │ + * This constructor is new in OpenLayers 2.5. At OpenLayers 3.0, the old
│ │ │ │ │ + * syntax for creating classes and dealing with inheritance
│ │ │ │ │ + * will be removed.
│ │ │ │ │ + *
│ │ │ │ │ + * To create a new OpenLayers-style class, use the following syntax:
│ │ │ │ │ + * (code)
│ │ │ │ │ + * var MyClass = OpenLayers.Class(prototype);
│ │ │ │ │ + * (end)
│ │ │ │ │ + *
│ │ │ │ │ + * To create a new OpenLayers-style class with multiple inheritance, use the
│ │ │ │ │ + * following syntax:
│ │ │ │ │ + * (code)
│ │ │ │ │ + * var MyClass = OpenLayers.Class(Class1, Class2, prototype);
│ │ │ │ │ + * (end)
│ │ │ │ │ + *
│ │ │ │ │ + * Note that instanceof reflection will only reveal Class1 as superclass.
│ │ │ │ │ + *
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Class = function() {
│ │ │ │ │ + var len = arguments.length;
│ │ │ │ │ + var P = arguments[0];
│ │ │ │ │ + var F = arguments[len - 1];
│ │ │ │ │ +
│ │ │ │ │ + var C = typeof F.initialize == "function" ?
│ │ │ │ │ + F.initialize :
│ │ │ │ │ + function() {
│ │ │ │ │ + P.prototype.initialize.apply(this, arguments);
│ │ │ │ │ + };
│ │ │ │ │ +
│ │ │ │ │ + if (len > 1) {
│ │ │ │ │ + var newArgs = [C, P].concat(
│ │ │ │ │ + Array.prototype.slice.call(arguments).slice(1, len - 1), F);
│ │ │ │ │ + OpenLayers.inherit.apply(null, newArgs);
│ │ │ │ │ + } else {
│ │ │ │ │ + C.prototype = F;
│ │ │ │ │ + }
│ │ │ │ │ + return C;
│ │ │ │ │ +};
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Function: OpenLayers.inherit
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * C - {Object} the class that inherits
│ │ │ │ │ + * P - {Object} the superclass to inherit from
│ │ │ │ │ + *
│ │ │ │ │ + * In addition to the mandatory C and P parameters, an arbitrary number of
│ │ │ │ │ + * objects can be passed, which will extend C.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.inherit = function(C, P) {
│ │ │ │ │ + var F = function() {};
│ │ │ │ │ + F.prototype = P.prototype;
│ │ │ │ │ + C.prototype = new F;
│ │ │ │ │ + var i, l, o;
│ │ │ │ │ + for (i = 2, l = arguments.length; i < l; i++) {
│ │ │ │ │ + o = arguments[i];
│ │ │ │ │ + if (typeof o === "function") {
│ │ │ │ │ + o = o.prototype;
│ │ │ │ │ + }
│ │ │ │ │ + OpenLayers.Util.extend(C.prototype, o);
│ │ │ │ │ + }
│ │ │ │ │ +};
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * APIFunction: extend
│ │ │ │ │ + * Copy all properties of a source object to a destination object. Modifies
│ │ │ │ │ + * the passed in destination object. Any properties on the source object
│ │ │ │ │ + * that are set to undefined will not be (re)set on the destination object.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * destination - {Object} The object that will be modified
│ │ │ │ │ + * source - {Object} The object with properties to be set on the destination
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Object} The destination object.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Util = OpenLayers.Util || {};
│ │ │ │ │ +OpenLayers.Util.extend = function(destination, source) {
│ │ │ │ │ + destination = destination || {};
│ │ │ │ │ + if (source) {
│ │ │ │ │ + for (var property in source) {
│ │ │ │ │ + var value = source[property];
│ │ │ │ │ + if (value !== undefined) {
│ │ │ │ │ + destination[property] = value;
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * IE doesn't include the toString property when iterating over an object's
│ │ │ │ │ + * properties with the for(property in object) syntax. Explicitly check if
│ │ │ │ │ + * the source has its own toString property.
│ │ │ │ │ + */
│ │ │ │ │ +
│ │ │ │ │ + /*
│ │ │ │ │ + * FF/Windows < 2.0.0.13 reports "Illegal operation on WrappedNative
│ │ │ │ │ + * prototype object" when calling hawOwnProperty if the source object
│ │ │ │ │ + * is an instance of window.Event.
│ │ │ │ │ + */
│ │ │ │ │ +
│ │ │ │ │ + var sourceIsEvt = typeof window.Event == "function" &&
│ │ │ │ │ + source instanceof window.Event;
│ │ │ │ │ +
│ │ │ │ │ + if (!sourceIsEvt &&
│ │ │ │ │ + source.hasOwnProperty && source.hasOwnProperty("toString")) {
│ │ │ │ │ + destination.toString = source.toString;
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + return destination;
│ │ │ │ │ +};
│ │ │ │ │ +/* ======================================================================
│ │ │ │ │ + OpenLayers/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
│ │ │ │ │ + */
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Class: OpenLayers.Icon
│ │ │ │ │ + *
│ │ │ │ │ + * The icon represents a graphical icon on the screen. Typically used in
│ │ │ │ │ + * conjunction with a to represent markers on a screen.
│ │ │ │ │ + *
│ │ │ │ │ + * An icon has a url, size and position. It also contains an offset which
│ │ │ │ │ + * allows the center point to be represented correctly. This can be
│ │ │ │ │ + * provided either as a fixed offset or a function provided to calculate
│ │ │ │ │ + * the desired offset.
│ │ │ │ │ + *
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Icon = OpenLayers.Class({
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: url
│ │ │ │ │ + * {String} image url
│ │ │ │ │ + */
│ │ │ │ │ + url: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: size
│ │ │ │ │ + * {|Object} An OpenLayers.Size or
│ │ │ │ │ + * an object with a 'w' and 'h' properties.
│ │ │ │ │ + */
│ │ │ │ │ + size: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * 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.
│ │ │ │ │ + */
│ │ │ │ │ + offset: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: calculateOffset
│ │ │ │ │ + * {Function} Function to calculate the offset (based on the size)
│ │ │ │ │ + */
│ │ │ │ │ + calculateOffset: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: imageDiv
│ │ │ │ │ + * {DOMElement}
│ │ │ │ │ + */
│ │ │ │ │ + imageDiv: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: px
│ │ │ │ │ + * {|Object} An OpenLayers.Pixel or an object
│ │ │ │ │ + * with a 'x' and 'y' properties.
│ │ │ │ │ + */
│ │ │ │ │ + px: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Constructor: OpenLayers.Icon
│ │ │ │ │ + * Creates an icon, which is an image tag in a div.
│ │ │ │ │ + *
│ │ │ │ │ + * url - {String}
│ │ │ │ │ + * size - {|Object} An OpenLayers.Size or an
│ │ │ │ │ + * object with a 'w' and 'h'
│ │ │ │ │ + * properties.
│ │ │ │ │ + * offset - {|Object} An OpenLayers.Pixel or an
│ │ │ │ │ + * object with a 'x' and 'y'
│ │ │ │ │ + * properties.
│ │ │ │ │ + * calculateOffset - {Function}
│ │ │ │ │ + */
│ │ │ │ │ + initialize: function(url, size, offset, calculateOffset) {
│ │ │ │ │ + this.url = url;
│ │ │ │ │ + this.size = size || {
│ │ │ │ │ + w: 20,
│ │ │ │ │ + h: 20
│ │ │ │ │ + };
│ │ │ │ │ + this.offset = offset || {
│ │ │ │ │ + x: -(this.size.w / 2),
│ │ │ │ │ + y: -(this.size.h / 2)
│ │ │ │ │ + };
│ │ │ │ │ + this.calculateOffset = calculateOffset;
│ │ │ │ │ +
│ │ │ │ │ + var id = OpenLayers.Util.createUniqueID("OL_Icon_");
│ │ │ │ │ + this.imageDiv = OpenLayers.Util.createAlphaImageDiv(id);
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: destroy
│ │ │ │ │ + * Nullify references and remove event listeners to prevent circular
│ │ │ │ │ + * references and memory leaks
│ │ │ │ │ + */
│ │ │ │ │ + destroy: function() {
│ │ │ │ │ + // erase any drawn elements
│ │ │ │ │ + this.erase();
│ │ │ │ │ +
│ │ │ │ │ + OpenLayers.Event.stopObservingElement(this.imageDiv.firstChild);
│ │ │ │ │ + this.imageDiv.innerHTML = "";
│ │ │ │ │ + this.imageDiv = null;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: clone
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {} A fresh copy of the icon.
│ │ │ │ │ + */
│ │ │ │ │ + clone: function() {
│ │ │ │ │ + return new OpenLayers.Icon(this.url,
│ │ │ │ │ + this.size,
│ │ │ │ │ + this.offset,
│ │ │ │ │ + this.calculateOffset);
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: setSize
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * size - {|Object} An OpenLayers.Size or
│ │ │ │ │ + * an object with a 'w' and 'h' properties.
│ │ │ │ │ + */
│ │ │ │ │ + setSize: function(size) {
│ │ │ │ │ + if (size != null) {
│ │ │ │ │ + this.size = size;
│ │ │ │ │ + }
│ │ │ │ │ + this.draw();
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: setUrl
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * url - {String}
│ │ │ │ │ + */
│ │ │ │ │ + setUrl: function(url) {
│ │ │ │ │ + if (url != null) {
│ │ │ │ │ + this.url = url;
│ │ │ │ │ + }
│ │ │ │ │ + this.draw();
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * 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
│ │ │ │ │ + */
│ │ │ │ │ + draw: function(px) {
│ │ │ │ │ + OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv,
│ │ │ │ │ + null,
│ │ │ │ │ + null,
│ │ │ │ │ + this.size,
│ │ │ │ │ + this.url,
│ │ │ │ │ + "absolute");
│ │ │ │ │ + this.moveTo(px);
│ │ │ │ │ + return this.imageDiv;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: erase
│ │ │ │ │ + * Erase the underlying image element.
│ │ │ │ │ + */
│ │ │ │ │ + erase: function() {
│ │ │ │ │ + if (this.imageDiv != null && this.imageDiv.parentNode != null) {
│ │ │ │ │ + OpenLayers.Element.remove(this.imageDiv);
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: setOpacity
│ │ │ │ │ + * Change the icon's opacity
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * opacity - {float}
│ │ │ │ │ + */
│ │ │ │ │ + setOpacity: function(opacity) {
│ │ │ │ │ + OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv, null, null, null,
│ │ │ │ │ + null, null, null, null, opacity);
│ │ │ │ │ +
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: moveTo
│ │ │ │ │ + * move icon to passed in px.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * px - {|Object} the pixel position to move to.
│ │ │ │ │ + * An OpenLayers.Pixel or an object with a 'x' and 'y' properties.
│ │ │ │ │ + */
│ │ │ │ │ + moveTo: function(px) {
│ │ │ │ │ + //if no px passed in, use stored location
│ │ │ │ │ + if (px != null) {
│ │ │ │ │ + this.px = px;
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + if (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
│ │ │ │ │ + });
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: display
│ │ │ │ │ + * Hide or show the icon
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * display - {Boolean}
│ │ │ │ │ + */
│ │ │ │ │ + display: function(display) {
│ │ │ │ │ + this.imageDiv.style.display = (display) ? "" : "none";
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: isDrawn
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Boolean} Whether or not the icon is drawn.
│ │ │ │ │ + */
│ │ │ │ │ + isDrawn: function() {
│ │ │ │ │ + // nodeType 11 for ie, whose nodes *always* have a parentNode
│ │ │ │ │ + // (of type document fragment)
│ │ │ │ │ + var isDrawn = (this.imageDiv && this.imageDiv.parentNode &&
│ │ │ │ │ + (this.imageDiv.parentNode.nodeType != 11));
│ │ │ │ │ +
│ │ │ │ │ + return isDrawn;
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Icon"
│ │ │ │ │ +});
│ │ │ │ │ +/* ======================================================================
│ │ │ │ │ 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. */
│ │ │ │ │ @@ -383,645 +763,377 @@
│ │ │ │ │ requestFrame: requestFrame,
│ │ │ │ │ start: start,
│ │ │ │ │ stop: stop
│ │ │ │ │ };
│ │ │ │ │
│ │ │ │ │ })(window);
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/BaseTypes/Class.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/SingleFile.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Constructor: OpenLayers.Class
│ │ │ │ │ - * Base class used to construct all other classes. Includes support for
│ │ │ │ │ - * multiple inheritance.
│ │ │ │ │ - *
│ │ │ │ │ - * This constructor is new in OpenLayers 2.5. At OpenLayers 3.0, the old
│ │ │ │ │ - * syntax for creating classes and dealing with inheritance
│ │ │ │ │ - * will be removed.
│ │ │ │ │ - *
│ │ │ │ │ - * To create a new OpenLayers-style class, use the following syntax:
│ │ │ │ │ - * (code)
│ │ │ │ │ - * var MyClass = OpenLayers.Class(prototype);
│ │ │ │ │ - * (end)
│ │ │ │ │ - *
│ │ │ │ │ - * To create a new OpenLayers-style class with multiple inheritance, use the
│ │ │ │ │ - * following syntax:
│ │ │ │ │ - * (code)
│ │ │ │ │ - * var MyClass = OpenLayers.Class(Class1, Class2, prototype);
│ │ │ │ │ - * (end)
│ │ │ │ │ - *
│ │ │ │ │ - * Note that instanceof reflection will only reveal Class1 as superclass.
│ │ │ │ │ - *
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Class = function() {
│ │ │ │ │ - var len = arguments.length;
│ │ │ │ │ - var P = arguments[0];
│ │ │ │ │ - var F = arguments[len - 1];
│ │ │ │ │ -
│ │ │ │ │ - var C = typeof F.initialize == "function" ?
│ │ │ │ │ - F.initialize :
│ │ │ │ │ - function() {
│ │ │ │ │ - P.prototype.initialize.apply(this, arguments);
│ │ │ │ │ - };
│ │ │ │ │ -
│ │ │ │ │ - if (len > 1) {
│ │ │ │ │ - var newArgs = [C, P].concat(
│ │ │ │ │ - Array.prototype.slice.call(arguments).slice(1, len - 1), F);
│ │ │ │ │ - OpenLayers.inherit.apply(null, newArgs);
│ │ │ │ │ - } else {
│ │ │ │ │ - C.prototype = F;
│ │ │ │ │ - }
│ │ │ │ │ - return C;
│ │ │ │ │ -};
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Function: OpenLayers.inherit
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * C - {Object} the class that inherits
│ │ │ │ │ - * P - {Object} the superclass to inherit from
│ │ │ │ │ - *
│ │ │ │ │ - * In addition to the mandatory C and P parameters, an arbitrary number of
│ │ │ │ │ - * objects can be passed, which will extend C.
│ │ │ │ │ + * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ + * @requires OpenLayers/Animation.js
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.inherit = function(C, P) {
│ │ │ │ │ - var F = function() {};
│ │ │ │ │ - F.prototype = P.prototype;
│ │ │ │ │ - C.prototype = new F;
│ │ │ │ │ - var i, l, o;
│ │ │ │ │ - for (i = 2, l = arguments.length; i < l; i++) {
│ │ │ │ │ - o = arguments[i];
│ │ │ │ │ - if (typeof o === "function") {
│ │ │ │ │ - o = o.prototype;
│ │ │ │ │ - }
│ │ │ │ │ - OpenLayers.Util.extend(C.prototype, o);
│ │ │ │ │ - }
│ │ │ │ │ -};
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIFunction: extend
│ │ │ │ │ - * Copy all properties of a source object to a destination object. Modifies
│ │ │ │ │ - * the passed in destination object. Any properties on the source object
│ │ │ │ │ - * that are set to undefined will not be (re)set on the destination object.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * destination - {Object} The object that will be modified
│ │ │ │ │ - * source - {Object} The object with properties to be set on the destination
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Object} The destination object.
│ │ │ │ │ + * Namespace: OpenLayers.Tween
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Util = OpenLayers.Util || {};
│ │ │ │ │ -OpenLayers.Util.extend = function(destination, source) {
│ │ │ │ │ - destination = destination || {};
│ │ │ │ │ - if (source) {
│ │ │ │ │ - for (var property in source) {
│ │ │ │ │ - var value = source[property];
│ │ │ │ │ - if (value !== undefined) {
│ │ │ │ │ - destination[property] = value;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * IE doesn't include the toString property when iterating over an object's
│ │ │ │ │ - * properties with the for(property in object) syntax. Explicitly check if
│ │ │ │ │ - * the source has its own toString property.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /*
│ │ │ │ │ - * FF/Windows < 2.0.0.13 reports "Illegal operation on WrappedNative
│ │ │ │ │ - * prototype object" when calling hawOwnProperty if the source object
│ │ │ │ │ - * is an instance of window.Event.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - var sourceIsEvt = typeof window.Event == "function" &&
│ │ │ │ │ - source instanceof window.Event;
│ │ │ │ │ +OpenLayers.Tween = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ - if (!sourceIsEvt &&
│ │ │ │ │ - source.hasOwnProperty && source.hasOwnProperty("toString")) {
│ │ │ │ │ - destination.toString = source.toString;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return destination;
│ │ │ │ │ -};
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Geometry.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: easing
│ │ │ │ │ + * {(Function)} Easing equation used for the animation
│ │ │ │ │ + * Defaultly set to OpenLayers.Easing.Expo.easeOut
│ │ │ │ │ + */
│ │ │ │ │ + easing: 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: begin
│ │ │ │ │ + * {Object} Values to start the animation with
│ │ │ │ │ + */
│ │ │ │ │ + begin: null,
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ - */
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: finish
│ │ │ │ │ + * {Object} Values to finish the animation with
│ │ │ │ │ + */
│ │ │ │ │ + finish: 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: duration
│ │ │ │ │ + * {int} duration of the tween (number of steps)
│ │ │ │ │ + */
│ │ │ │ │ + duration: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: id
│ │ │ │ │ - * {String} A unique identifier for this geometry.
│ │ │ │ │ + * 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.
│ │ │ │ │ */
│ │ │ │ │ - id: null,
│ │ │ │ │ + callbacks: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: parent
│ │ │ │ │ - * {}This is set when a Geometry is added as component
│ │ │ │ │ - * of another geometry
│ │ │ │ │ + * Property: time
│ │ │ │ │ + * {int} Step counter
│ │ │ │ │ */
│ │ │ │ │ - parent: null,
│ │ │ │ │ + time: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: bounds
│ │ │ │ │ - * {} The bounds of this geometry
│ │ │ │ │ + * 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.
│ │ │ │ │ */
│ │ │ │ │ - bounds: null,
│ │ │ │ │ + minFrameRate: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constructor: OpenLayers.Geometry
│ │ │ │ │ - * Creates a geometry object.
│ │ │ │ │ + * Property: startTime
│ │ │ │ │ + * {Number} The timestamp of the first execution step. Used for skipping
│ │ │ │ │ + * frames
│ │ │ │ │ */
│ │ │ │ │ - initialize: function() {
│ │ │ │ │ - this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
│ │ │ │ │ - },
│ │ │ │ │ + startTime: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: destroy
│ │ │ │ │ - * Destroy this geometry.
│ │ │ │ │ + * Property: animationId
│ │ │ │ │ + * {int} Loop id returned by OpenLayers.Animation.start
│ │ │ │ │ */
│ │ │ │ │ - destroy: function() {
│ │ │ │ │ - this.id = null;
│ │ │ │ │ - this.bounds = null;
│ │ │ │ │ - },
│ │ │ │ │ + animationId: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * 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 geometry.
│ │ │ │ │ + * Property: playing
│ │ │ │ │ + * {Boolean} Tells if the easing is currently playing
│ │ │ │ │ */
│ │ │ │ │ - clone: function() {
│ │ │ │ │ - return new OpenLayers.Geometry();
│ │ │ │ │ + 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;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: setBounds
│ │ │ │ │ - * Set the bounds for this Geometry.
│ │ │ │ │ + * APIMethod: start
│ │ │ │ │ + * Plays the Tween, and calls the callback method on each step
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * bounds - {}
│ │ │ │ │ + * 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)
│ │ │ │ │ */
│ │ │ │ │ - setBounds: function(bounds) {
│ │ │ │ │ - if (bounds) {
│ │ │ │ │ - this.bounds = bounds.clone();
│ │ │ │ │ + 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)
│ │ │ │ │ + );
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: clearBounds
│ │ │ │ │ - * Nullify this components bounds and that of its parent as well.
│ │ │ │ │ + * APIMethod: stop
│ │ │ │ │ + * Stops the Tween, and calls the done callback
│ │ │ │ │ + * Doesn't do anything if animation is already finished
│ │ │ │ │ */
│ │ │ │ │ - clearBounds: function() {
│ │ │ │ │ - this.bounds = null;
│ │ │ │ │ - if (this.parent) {
│ │ │ │ │ - this.parent.clearBounds();
│ │ │ │ │ + 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: extendBounds
│ │ │ │ │ - * Extend the existing bounds to include the new bounds.
│ │ │ │ │ - * If geometry's bounds is not yet set, then set a new Bounds.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * newBounds - {}
│ │ │ │ │ + * Method: play
│ │ │ │ │ + * Calls the appropriate easing method
│ │ │ │ │ */
│ │ │ │ │ - extendBounds: function(newBounds) {
│ │ │ │ │ - var bounds = this.getBounds();
│ │ │ │ │ - if (!bounds) {
│ │ │ │ │ - this.setBounds(newBounds);
│ │ │ │ │ - } else {
│ │ │ │ │ - this.bounds.extend(newBounds);
│ │ │ │ │ + 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();
│ │ │ │ │ }
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: getBounds
│ │ │ │ │ - * Get the bounds for this Geometry. If bounds is not set, it
│ │ │ │ │ - * is calculated again, this makes queries faster.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {}
│ │ │ │ │ + * Create empty functions for all easing methods.
│ │ │ │ │ */
│ │ │ │ │ - getBounds: function() {
│ │ │ │ │ - if (this.bounds == null) {
│ │ │ │ │ - this.calculateBounds();
│ │ │ │ │ - }
│ │ │ │ │ - return this.bounds;
│ │ │ │ │ - },
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Tween"
│ │ │ │ │ +});
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: calculateBounds
│ │ │ │ │ - * Recalculate the bounds for the geometry.
│ │ │ │ │ +/**
│ │ │ │ │ + * Namespace: OpenLayers.Easing
│ │ │ │ │ + *
│ │ │ │ │ + * Credits:
│ │ │ │ │ + * Easing Equations by Robert Penner,
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Easing = {
│ │ │ │ │ + /**
│ │ │ │ │ + * Create empty functions for all easing methods.
│ │ │ │ │ */
│ │ │ │ │ - calculateBounds: function() {
│ │ │ │ │ - //
│ │ │ │ │ - // This should be overridden by subclasses.
│ │ │ │ │ - //
│ │ │ │ │ - },
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Easing"
│ │ │ │ │ +};
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Namespace: OpenLayers.Easing.Linear
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Easing.Linear = {
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: distanceTo
│ │ │ │ │ - * Calculate the closest distance between two geometries (on the x-y plane).
│ │ │ │ │ - *
│ │ │ │ │ + * Function: easeIn
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * geometry - {} The target geometry.
│ │ │ │ │ - * options - {Object} Optional properties for configuring the distance
│ │ │ │ │ - * calculation.
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ *
│ │ │ │ │ - * 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.
│ │ │ │ │ + * {Float}
│ │ │ │ │ */
│ │ │ │ │ - distanceTo: function(geometry, options) {},
│ │ │ │ │ + easeIn: function(t, b, c, d) {
│ │ │ │ │ + return c * t / d + b;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: getVertices
│ │ │ │ │ - * Return a list of all points in this geometry.
│ │ │ │ │ - *
│ │ │ │ │ + * Function: easeOut
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * 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.
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Array} A list of all vertices in the geometry.
│ │ │ │ │ + * {Float}
│ │ │ │ │ */
│ │ │ │ │ - getVertices: function(nodes) {},
│ │ │ │ │ + easeOut: function(t, b, c, d) {
│ │ │ │ │ + return c * t / d + b;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: atPoint
│ │ │ │ │ - * Note - This is only an approximation based on the bounds of the
│ │ │ │ │ - * geometry.
│ │ │ │ │ + * Function: easeInOut
│ │ │ │ │ *
│ │ │ │ │ * 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
│ │ │ │ │ - *
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Boolean} Whether or not the geometry is at the specified location
│ │ │ │ │ + * {Float}
│ │ │ │ │ */
│ │ │ │ │ - atPoint: function(lonlat, toleranceLon, toleranceLat) {
│ │ │ │ │ - var atPoint = false;
│ │ │ │ │ - var bounds = this.getBounds();
│ │ │ │ │ - if ((bounds != null) && (lonlat != null)) {
│ │ │ │ │ + easeInOut: function(t, b, c, d) {
│ │ │ │ │ + return c * t / d + b;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - var dX = (toleranceLon != null) ? toleranceLon : 0;
│ │ │ │ │ - var dY = (toleranceLat != null) ? toleranceLat : 0;
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Easing.Linear"
│ │ │ │ │ +};
│ │ │ │ │
│ │ │ │ │ - var toleranceBounds =
│ │ │ │ │ - new OpenLayers.Bounds(this.bounds.left - dX,
│ │ │ │ │ - this.bounds.bottom - dY,
│ │ │ │ │ - this.bounds.right + dX,
│ │ │ │ │ - this.bounds.top + dY);
│ │ │ │ │ +/**
│ │ │ │ │ + * Namespace: OpenLayers.Easing.Expo
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Easing.Expo = {
│ │ │ │ │
│ │ │ │ │ - atPoint = toleranceBounds.containsLonLat(lonlat);
│ │ │ │ │ - }
│ │ │ │ │ - return atPoint;
│ │ │ │ │ + /**
│ │ │ │ │ + * 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;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: getLength
│ │ │ │ │ - * Calculate the length of this geometry. This method is defined in
│ │ │ │ │ - * subclasses.
│ │ │ │ │ + * Function: easeOut
│ │ │ │ │ *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Float} The length of the collection by summing its parts
│ │ │ │ │ + * {Float}
│ │ │ │ │ */
│ │ │ │ │ - getLength: function() {
│ │ │ │ │ - //to be overridden by geometries that actually have a length
│ │ │ │ │ - //
│ │ │ │ │ - return 0.0;
│ │ │ │ │ + easeOut: function(t, b, c, d) {
│ │ │ │ │ + return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: getArea
│ │ │ │ │ - * Calculate the area of this geometry. This method is defined in subclasses.
│ │ │ │ │ + * Function: easeInOut
│ │ │ │ │ *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Float} The area of the collection by summing its parts
│ │ │ │ │ + * {Float}
│ │ │ │ │ */
│ │ │ │ │ - getArea: function() {
│ │ │ │ │ - //to be overridden by geometries that actually have an area
│ │ │ │ │ - //
│ │ │ │ │ - return 0.0;
│ │ │ │ │ + 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 = {
│ │ │ │ │ +
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: getCentroid
│ │ │ │ │ - * Calculate the centroid of this geometry. This method is defined in subclasses.
│ │ │ │ │ + * Function: easeIn
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {} The centroid of the collection
│ │ │ │ │ + * {Float}
│ │ │ │ │ */
│ │ │ │ │ - getCentroid: function() {
│ │ │ │ │ - return null;
│ │ │ │ │ + easeIn: function(t, b, c, d) {
│ │ │ │ │ + return c * (t /= d) * t + b;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * 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.
│ │ │ │ │ + * Function: easeOut
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * t - {Float} time
│ │ │ │ │ + * b - {Float} beginning position
│ │ │ │ │ + * c - {Float} total change
│ │ │ │ │ + * d - {Float} duration of the transition
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {String} String representation of this geometry.
│ │ │ │ │ + * {Float}
│ │ │ │ │ */
│ │ │ │ │ - toString: function() {
│ │ │ │ │ - var string;
│ │ │ │ │ - if (OpenLayers.Format && OpenLayers.Format.WKT) {
│ │ │ │ │ - string = OpenLayers.Format.WKT.prototype.write(
│ │ │ │ │ - new OpenLayers.Feature.Vector(this)
│ │ │ │ │ - );
│ │ │ │ │ - } else {
│ │ │ │ │ - string = Object.prototype.toString.call(this);
│ │ │ │ │ - }
│ │ │ │ │ - return string;
│ │ │ │ │ + easeOut: function(t, b, c, d) {
│ │ │ │ │ + return -c * (t /= d) * (t - 2) + b;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - 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);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return geom;
│ │ │ │ │ -};
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * 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;
│ │ │ │ │ - }
│ │ │ │ │ - } 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;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - }
│ │ │ │ │ - } 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;
│ │ │ │ │ -};
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * 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;
│ │ │ │ │ -};
│ │ │ │ │ + /**
│ │ │ │ │ + * 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;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * 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
│ │ │ │ │ - };
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Easing.Quad"
│ │ │ │ │ };
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ 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.
│ │ │ │ │ @@ -5922,12905 +6034,10200 @@
│ │ │ │ │
│ │ │ │ │ },
│ │ │ │ │ 'delete': {
│ │ │ │ │ display: "none"
│ │ │ │ │ }
│ │ │ │ │ };
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Format.js
│ │ │ │ │ + OpenLayers/Style.js
│ │ │ │ │ ====================================================================== */
│ │ │ │ │
│ │ │ │ │ /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
│ │ │ │ │ * full list of contributors). Published under the 2-clause BSD license.
│ │ │ │ │ * See license.txt in the OpenLayers distribution or repository for the
│ │ │ │ │ * full text of the license. */
│ │ │ │ │
│ │ │ │ │ +
│ │ │ │ │ /**
│ │ │ │ │ * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ * @requires OpenLayers/Util.js
│ │ │ │ │ + * @requires OpenLayers/Feature/Vector.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Class: OpenLayers.Format
│ │ │ │ │ - * Base class for format reading/writing a variety of formats. Subclasses
│ │ │ │ │ - * of OpenLayers.Format are expected to have read and write methods.
│ │ │ │ │ + * Class: OpenLayers.Style
│ │ │ │ │ + * This class represents a UserStyle obtained
│ │ │ │ │ + * from a SLD, containing styling rules.
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Format = OpenLayers.Class({
│ │ │ │ │ +OpenLayers.Style = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: options
│ │ │ │ │ - * {Object} A reference to options passed to the constructor.
│ │ │ │ │ + * Property: id
│ │ │ │ │ + * {String} A unique id for this session.
│ │ │ │ │ */
│ │ │ │ │ - options: null,
│ │ │ │ │ + id: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: externalProjection
│ │ │ │ │ - * {} When passed a externalProjection and
│ │ │ │ │ - * internalProjection, the format will reproject the geometries it
│ │ │ │ │ - * reads or writes. The externalProjection is the projection used by
│ │ │ │ │ - * the content which is passed into read or which comes out of write.
│ │ │ │ │ - * In order to reproject, a projection transformation function for the
│ │ │ │ │ - * specified projections must be available. This support may be
│ │ │ │ │ - * provided via proj4js or via a custom transformation function. See
│ │ │ │ │ - * {} for more information on
│ │ │ │ │ - * custom transformations.
│ │ │ │ │ + * APIProperty: name
│ │ │ │ │ + * {String}
│ │ │ │ │ */
│ │ │ │ │ - externalProjection: null,
│ │ │ │ │ + name: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: internalProjection
│ │ │ │ │ - * {} When passed a externalProjection and
│ │ │ │ │ - * internalProjection, the format will reproject the geometries it
│ │ │ │ │ - * reads or writes. The internalProjection is the projection used by
│ │ │ │ │ - * the geometries which are returned by read or which are passed into
│ │ │ │ │ - * write. In order to reproject, a projection transformation function
│ │ │ │ │ - * for the specified projections must be available. This support may be
│ │ │ │ │ - * provided via proj4js or via a custom transformation function. See
│ │ │ │ │ - * {} for more information on
│ │ │ │ │ - * custom transformations.
│ │ │ │ │ + * Property: title
│ │ │ │ │ + * {String} Title of this style (set if included in SLD)
│ │ │ │ │ */
│ │ │ │ │ - internalProjection: null,
│ │ │ │ │ + title: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: data
│ │ │ │ │ - * {Object} When is true, this is the parsed string sent to
│ │ │ │ │ - * .
│ │ │ │ │ + * Property: description
│ │ │ │ │ + * {String} Description of this style (set if abstract is included in SLD)
│ │ │ │ │ */
│ │ │ │ │ - data: null,
│ │ │ │ │ + description: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: keepData
│ │ │ │ │ - * {Object} Maintain a reference () to the most recently read data.
│ │ │ │ │ - * Default is false.
│ │ │ │ │ + * APIProperty: layerName
│ │ │ │ │ + * {} name of the layer that this style belongs to, usually
│ │ │ │ │ + * according to the NamedLayer attribute of an SLD document.
│ │ │ │ │ */
│ │ │ │ │ - keepData: false,
│ │ │ │ │ + layerName: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constructor: OpenLayers.Format
│ │ │ │ │ - * Instances of this class are not useful. See one of the subclasses.
│ │ │ │ │ + * APIProperty: isDefault
│ │ │ │ │ + * {Boolean}
│ │ │ │ │ + */
│ │ │ │ │ + isDefault: false,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: rules
│ │ │ │ │ + * {Array()}
│ │ │ │ │ + */
│ │ │ │ │ + rules: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: context
│ │ │ │ │ + * {Object} An optional object with properties that symbolizers' property
│ │ │ │ │ + * values should be evaluated against. If no context is specified,
│ │ │ │ │ + * feature.attributes will be used
│ │ │ │ │ + */
│ │ │ │ │ + context: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: defaultStyle
│ │ │ │ │ + * {Object} hash of style properties to use as default for merging
│ │ │ │ │ + * rule-based style symbolizers onto. If no rules are defined,
│ │ │ │ │ + * createSymbolizer will return this style. If is set to
│ │ │ │ │ + * true, the defaultStyle will only be taken into account if there are
│ │ │ │ │ + * rules defined.
│ │ │ │ │ + */
│ │ │ │ │ + defaultStyle: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: defaultsPerSymbolizer
│ │ │ │ │ + * {Boolean} If set to true, the will extend the symbolizer
│ │ │ │ │ + * of every rule. Properties of the will also be used to set
│ │ │ │ │ + * missing symbolizer properties if the symbolizer has stroke, fill or
│ │ │ │ │ + * graphic set to true. Default is false.
│ │ │ │ │ + */
│ │ │ │ │ + defaultsPerSymbolizer: false,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: propertyStyles
│ │ │ │ │ + * {Hash of Boolean} cache of style properties that need to be parsed for
│ │ │ │ │ + * propertyNames. Property names are keys, values won't be used.
│ │ │ │ │ + */
│ │ │ │ │ + propertyStyles: null,
│ │ │ │ │ +
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Constructor: OpenLayers.Style
│ │ │ │ │ + * Creates a UserStyle.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ + * style - {Object} Optional hash of style properties that will be
│ │ │ │ │ + * used as default style for this style object. This style
│ │ │ │ │ + * applies if no rules are specified. Symbolizers defined in
│ │ │ │ │ + * rules will extend this default style.
│ │ │ │ │ * options - {Object} An optional object with properties to set on the
│ │ │ │ │ - * format
│ │ │ │ │ + * style.
│ │ │ │ │ *
│ │ │ │ │ * Valid options:
│ │ │ │ │ - * keepData - {Boolean} If true, upon , the data property will be
│ │ │ │ │ - * set to the parsed object (e.g. the json or xml object).
│ │ │ │ │ - *
│ │ │ │ │ + * rules - {Array()} List of rules to be added to the
│ │ │ │ │ + * style.
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * An instance of OpenLayers.Format
│ │ │ │ │ + * {}
│ │ │ │ │ */
│ │ │ │ │ - initialize: function(options) {
│ │ │ │ │ + initialize: function(style, options) {
│ │ │ │ │ +
│ │ │ │ │ OpenLayers.Util.extend(this, options);
│ │ │ │ │ - this.options = 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
│ │ │ │ │ - * Clean up.
│ │ │ │ │ + * nullify references to prevent circular references and memory leaks
│ │ │ │ │ */
│ │ │ │ │ - destroy: function() {},
│ │ │ │ │ + destroy: function() {
│ │ │ │ │ + for (var i = 0, len = this.rules.length; i < len; i++) {
│ │ │ │ │ + this.rules[i].destroy();
│ │ │ │ │ + this.rules[i] = null;
│ │ │ │ │ + }
│ │ │ │ │ + this.rules = null;
│ │ │ │ │ + this.defaultStyle = null;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: read
│ │ │ │ │ - * Read data from a string, and return an object whose type depends on the
│ │ │ │ │ - * subclass.
│ │ │ │ │ + * Method: createSymbolizer
│ │ │ │ │ + * creates a style by applying all feature-dependent rules to the base
│ │ │ │ │ + * style.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * data - {string} Data to read/parse.
│ │ │ │ │ - *
│ │ │ │ │ + * feature - {} feature to evaluate rules for
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * Depends on the subclass
│ │ │ │ │ + * {Object} symbolizer hash
│ │ │ │ │ */
│ │ │ │ │ - read: function(data) {
│ │ │ │ │ - throw new Error('Read not implemented.');
│ │ │ │ │ + createSymbolizer: function(feature) {
│ │ │ │ │ + var style = this.defaultsPerSymbolizer ? {} : this.createLiterals(
│ │ │ │ │ + OpenLayers.Util.extend({}, this.defaultStyle), feature);
│ │ │ │ │ +
│ │ │ │ │ + var rules = this.rules;
│ │ │ │ │ +
│ │ │ │ │ + var rule, context;
│ │ │ │ │ + var elseRules = [];
│ │ │ │ │ + var appliedRules = false;
│ │ │ │ │ + for (var i = 0, len = rules.length; i < len; i++) {
│ │ │ │ │ + rule = rules[i];
│ │ │ │ │ + // does the rule apply?
│ │ │ │ │ + var applies = rule.evaluate(feature);
│ │ │ │ │ +
│ │ │ │ │ + if (applies) {
│ │ │ │ │ + if (rule instanceof OpenLayers.Rule && rule.elseFilter) {
│ │ │ │ │ + elseRules.push(rule);
│ │ │ │ │ + } else {
│ │ │ │ │ + appliedRules = true;
│ │ │ │ │ + this.applySymbolizer(rule, style, feature);
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + // if no other rules apply, apply the rules with else filters
│ │ │ │ │ + if (appliedRules == false && elseRules.length > 0) {
│ │ │ │ │ + appliedRules = true;
│ │ │ │ │ + for (var i = 0, len = elseRules.length; i < len; i++) {
│ │ │ │ │ + this.applySymbolizer(elseRules[i], style, feature);
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + // don't display if there were rules but none applied
│ │ │ │ │ + if (rules.length > 0 && appliedRules == false) {
│ │ │ │ │ + style.display = "none";
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + if (style.label != null && typeof style.label !== "string") {
│ │ │ │ │ + style.label = String(style.label);
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + return style;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: write
│ │ │ │ │ - * Accept an object, and return a string.
│ │ │ │ │ + * Method: applySymbolizer
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * object - {Object} Object to be serialized
│ │ │ │ │ + * rule - {}
│ │ │ │ │ + * style - {Object}
│ │ │ │ │ + * feature - {}
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {String} A string representation of the object.
│ │ │ │ │ + * {Object} A style with new symbolizer applied.
│ │ │ │ │ */
│ │ │ │ │ - write: function(object) {
│ │ │ │ │ - throw new Error('Write not implemented.');
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Format"
│ │ │ │ │ -});
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Geometry/Point.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ + applySymbolizer: function(rule, style, feature) {
│ │ │ │ │ + var symbolizerPrefix = feature.geometry ?
│ │ │ │ │ + this.getSymbolizerPrefix(feature.geometry) :
│ │ │ │ │ + OpenLayers.Style.SYMBOLIZER_PREFIXES[0];
│ │ │ │ │
│ │ │ │ │ -/* 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. */
│ │ │ │ │ + var symbolizer = rule.symbolizer[symbolizerPrefix] || rule.symbolizer;
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/Geometry.js
│ │ │ │ │ - */
│ │ │ │ │ + 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
│ │ │ │ │ + });
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Geometry.Point
│ │ │ │ │ - * Point geometry class.
│ │ │ │ │ - *
│ │ │ │ │ - * Inherits from:
│ │ │ │ │ - * -
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Geometry.Point = OpenLayers.Class(OpenLayers.Geometry, {
│ │ │ │ │ + // merge the style with the current style
│ │ │ │ │ + return this.createLiterals(
│ │ │ │ │ + OpenLayers.Util.extend(style, symbolizer), feature);
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: x
│ │ │ │ │ - * {float}
│ │ │ │ │ + /**
│ │ │ │ │ + * 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
│ │ │ │ │ */
│ │ │ │ │ - x: null,
│ │ │ │ │ + createLiterals: function(style, feature) {
│ │ │ │ │ + var context = OpenLayers.Util.extend({}, feature.attributes || feature.data);
│ │ │ │ │ + OpenLayers.Util.extend(context, this.context);
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: y
│ │ │ │ │ - * {float}
│ │ │ │ │ - */
│ │ │ │ │ - y: null,
│ │ │ │ │ + for (var i in this.propertyStyles) {
│ │ │ │ │ + style[i] = OpenLayers.Style.createLiteral(style[i], context, feature, i);
│ │ │ │ │ + }
│ │ │ │ │ + return style;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constructor: OpenLayers.Geometry.Point
│ │ │ │ │ - * Construct a point geometry.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * x - {float}
│ │ │ │ │ - * y - {float}
│ │ │ │ │ + * Method: findPropertyStyles
│ │ │ │ │ + * Looks into all rules for this style and the defaultStyle to collect
│ │ │ │ │ + * all the style hash property names containing ${...} strings that have
│ │ │ │ │ + * to be replaced using the createLiteral method before returning them.
│ │ │ │ │ *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {Object} hash of property names that need createLiteral parsing. The
│ │ │ │ │ + * name of the property is the key, and the value is true;
│ │ │ │ │ */
│ │ │ │ │ - initialize: function(x, y) {
│ │ │ │ │ - OpenLayers.Geometry.prototype.initialize.apply(this, arguments);
│ │ │ │ │ + findPropertyStyles: function() {
│ │ │ │ │ + var propertyStyles = {};
│ │ │ │ │
│ │ │ │ │ - this.x = parseFloat(x);
│ │ │ │ │ - this.y = parseFloat(y);
│ │ │ │ │ + // 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;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: clone
│ │ │ │ │ + * Method: addPropertyStyles
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * propertyStyles - {Object} hash to add new property styles to. Will be
│ │ │ │ │ + * modified inline
│ │ │ │ │ + * symbolizer - {Object} search this symbolizer for property styles
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {} An exact clone of this OpenLayers.Geometry.Point
│ │ │ │ │ + * {Object} propertyStyles hash
│ │ │ │ │ */
│ │ │ │ │ - clone: function(obj) {
│ │ │ │ │ - if (obj == null) {
│ │ │ │ │ - obj = new OpenLayers.Geometry.Point(this.x, this.y);
│ │ │ │ │ + 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;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - // catch any randomly tagged-on properties
│ │ │ │ │ - OpenLayers.Util.applyDefaults(obj, this);
│ │ │ │ │ -
│ │ │ │ │ - return obj;
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: addRules
│ │ │ │ │ + * Adds rules to this style.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * rules - {Array()}
│ │ │ │ │ + */
│ │ │ │ │ + addRules: function(rules) {
│ │ │ │ │ + Array.prototype.push.apply(this.rules, rules);
│ │ │ │ │ + this.propertyStyles = this.findPropertyStyles();
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: calculateBounds
│ │ │ │ │ - * Create a new Bounds based on the lon/lat
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: setDefaultStyle
│ │ │ │ │ + * Sets the default style for this style object.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * style - {Object} Hash of style properties
│ │ │ │ │ */
│ │ │ │ │ - calculateBounds: function() {
│ │ │ │ │ - this.bounds = new OpenLayers.Bounds(this.x, this.y,
│ │ │ │ │ - this.x, this.y);
│ │ │ │ │ + setDefaultStyle: function(style) {
│ │ │ │ │ + this.defaultStyle = style;
│ │ │ │ │ + this.propertyStyles = this.findPropertyStyles();
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: distanceTo
│ │ │ │ │ - * Calculate the closest distance between two geometries (on the x-y plane).
│ │ │ │ │ - *
│ │ │ │ │ + * Method: getSymbolizerPrefix
│ │ │ │ │ + * Returns the correct symbolizer prefix according to the
│ │ │ │ │ + * geometry type of the passed geometry
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * geometry - {} The target geometry.
│ │ │ │ │ - * options - {Object} Optional properties for configuring the distance
│ │ │ │ │ - * calculation.
│ │ │ │ │ - *
│ │ │ │ │ - * Valid options:
│ │ │ │ │ - * details - {Boolean} Return details from the distance calculation.
│ │ │ │ │ - * Default is false.
│ │ │ │ │ - * edge - {Boolean} Calculate the distance from this geometry to the
│ │ │ │ │ - * nearest edge of the target geometry. Default is true. If true,
│ │ │ │ │ - * calling distanceTo from a geometry that is wholly contained within
│ │ │ │ │ - * the target will result in a non-zero distance. If false, whenever
│ │ │ │ │ - * geometries intersect, calling distanceTo will return 0. If false,
│ │ │ │ │ - * details cannot be returned.
│ │ │ │ │ - *
│ │ │ │ │ + * geometry - {}
│ │ │ │ │ + *
│ │ │ │ │ * 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.
│ │ │ │ │ + * {String} key of the according symbolizer
│ │ │ │ │ */
│ │ │ │ │ - distanceTo: function(geometry, options) {
│ │ │ │ │ - var edge = !(options && options.edge === false);
│ │ │ │ │ - var details = edge && options && options.details;
│ │ │ │ │ - var distance, x0, y0, x1, y1, result;
│ │ │ │ │ - if (geometry instanceof OpenLayers.Geometry.Point) {
│ │ │ │ │ - x0 = this.x;
│ │ │ │ │ - y0 = this.y;
│ │ │ │ │ - x1 = geometry.x;
│ │ │ │ │ - y1 = geometry.y;
│ │ │ │ │ - distance = Math.sqrt(Math.pow(x0 - x1, 2) + Math.pow(y0 - y1, 2));
│ │ │ │ │ - result = !details ?
│ │ │ │ │ - distance : {
│ │ │ │ │ - x0: x0,
│ │ │ │ │ - y0: y0,
│ │ │ │ │ - x1: x1,
│ │ │ │ │ - y1: y1,
│ │ │ │ │ - distance: distance
│ │ │ │ │ - };
│ │ │ │ │ - } else {
│ │ │ │ │ - result = geometry.distanceTo(this, options);
│ │ │ │ │ - if (details) {
│ │ │ │ │ - // switch coord order since this geom is target
│ │ │ │ │ - result = {
│ │ │ │ │ - x0: result.x1,
│ │ │ │ │ - y0: result.y1,
│ │ │ │ │ - x1: result.x0,
│ │ │ │ │ - y1: result.y0,
│ │ │ │ │ - distance: result.distance
│ │ │ │ │ - };
│ │ │ │ │ + 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];
│ │ │ │ │ }
│ │ │ │ │ }
│ │ │ │ │ - return result;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: equals
│ │ │ │ │ - * Determine whether another geometry is equivalent to this one. Geometries
│ │ │ │ │ - * are considered equivalent if all components have the same coordinates.
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: clone
│ │ │ │ │ + * Clones this style.
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * geom - {} The geometry to test.
│ │ │ │ │ - *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Boolean} The supplied geometry is equivalent to this geometry.
│ │ │ │ │ + * {} Clone of this style.
│ │ │ │ │ */
│ │ │ │ │ - equals: function(geom) {
│ │ │ │ │ - var equals = false;
│ │ │ │ │ - if (geom != null) {
│ │ │ │ │ - equals = ((this.x == geom.x && this.y == geom.y) ||
│ │ │ │ │ - (isNaN(this.x) && isNaN(this.y) && isNaN(geom.x) && isNaN(geom.y)));
│ │ │ │ │ + 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());
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ - return equals;
│ │ │ │ │ + // clone context
│ │ │ │ │ + options.context = this.context && OpenLayers.Util.extend({}, this.context);
│ │ │ │ │ + //clone default style
│ │ │ │ │ + var defaultStyle = OpenLayers.Util.extend({}, this.defaultStyle);
│ │ │ │ │ + return new OpenLayers.Style(defaultStyle, options);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Style"
│ │ │ │ │ +});
│ │ │ │ │ +
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Function: createLiteral
│ │ │ │ │ + * converts a style value holding a combination of PropertyName and Literal
│ │ │ │ │ + * into a Literal, taking the property values from the passed features.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * value - {String} value to parse. If this string contains a construct like
│ │ │ │ │ + * "foo ${bar}", then "foo " will be taken as literal, and "${bar}"
│ │ │ │ │ + * will be replaced by the value of the "bar" attribute of the passed
│ │ │ │ │ + * feature.
│ │ │ │ │ + * context - {Object} context to take attribute values from
│ │ │ │ │ + * feature - {} optional feature to pass to
│ │ │ │ │ + * for evaluating functions in the
│ │ │ │ │ + * context.
│ │ │ │ │ + * property - {String} optional, name of the property for which the literal is
│ │ │ │ │ + * being created for evaluating functions in the context.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * {String} the parsed value. In the example of the value parameter above, the
│ │ │ │ │ + * result would be "foo valueOfBar", assuming that the passed feature has an
│ │ │ │ │ + * attribute named "bar" with the value "valueOfBar".
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Style.createLiteral = function(value, context, feature, property) {
│ │ │ │ │ + if (typeof value == "string" && value.indexOf("${") != -1) {
│ │ │ │ │ + value = OpenLayers.String.format(value, context, [feature, property]);
│ │ │ │ │ + value = (isNaN(value) || !value) ? value : parseFloat(value);
│ │ │ │ │ + }
│ │ │ │ │ + return value;
│ │ │ │ │ +};
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * Constant: OpenLayers.Style.SYMBOLIZER_PREFIXES
│ │ │ │ │ + * {Array} prefixes of the sld symbolizers. These are the
│ │ │ │ │ + * same as the main geometry types
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Style.SYMBOLIZER_PREFIXES = ['Point', 'Line', 'Polygon', 'Text',
│ │ │ │ │ + 'Raster'
│ │ │ │ │ +];
│ │ │ │ │ +/* ======================================================================
│ │ │ │ │ + OpenLayers/Rule.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.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Rule = OpenLayers.Class({
│ │ │ │ │ +
│ │ │ │ │ /**
│ │ │ │ │ - * Method: toShortString
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} Shortened String representation of Point object.
│ │ │ │ │ - * (ex. "5, 42")
│ │ │ │ │ + * Property: id
│ │ │ │ │ + * {String} A unique id for this session.
│ │ │ │ │ */
│ │ │ │ │ - toShortString: function() {
│ │ │ │ │ - return (this.x + ", " + this.y);
│ │ │ │ │ - },
│ │ │ │ │ + id: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: move
│ │ │ │ │ - * Moves a geometry by the given displacement along positive x and y axes.
│ │ │ │ │ - * This modifies the position of the geometry and clears the cached
│ │ │ │ │ - * bounds.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * x - {Float} Distance to move geometry in positive x direction.
│ │ │ │ │ - * y - {Float} Distance to move geometry in positive y direction.
│ │ │ │ │ + * APIProperty: name
│ │ │ │ │ + * {String} name of this rule
│ │ │ │ │ */
│ │ │ │ │ - move: function(x, y) {
│ │ │ │ │ - this.x = this.x + x;
│ │ │ │ │ - this.y = this.y + y;
│ │ │ │ │ - this.clearBounds();
│ │ │ │ │ - },
│ │ │ │ │ + name: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: rotate
│ │ │ │ │ - * Rotate a point around another.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * angle - {Float} Rotation angle in degrees (measured counterclockwise
│ │ │ │ │ - * from the positive x-axis)
│ │ │ │ │ - * origin - {} Center point for the rotation
│ │ │ │ │ + * Property: title
│ │ │ │ │ + * {String} Title of this rule (set if included in SLD)
│ │ │ │ │ */
│ │ │ │ │ - rotate: function(angle, origin) {
│ │ │ │ │ - angle *= Math.PI / 180;
│ │ │ │ │ - var radius = this.distanceTo(origin);
│ │ │ │ │ - var theta = angle + Math.atan2(this.y - origin.y, this.x - origin.x);
│ │ │ │ │ - this.x = origin.x + (radius * Math.cos(theta));
│ │ │ │ │ - this.y = origin.y + (radius * Math.sin(theta));
│ │ │ │ │ - this.clearBounds();
│ │ │ │ │ - },
│ │ │ │ │ + title: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: getCentroid
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} The centroid of the collection
│ │ │ │ │ + * Property: description
│ │ │ │ │ + * {String} Description of this rule (set if abstract is included in SLD)
│ │ │ │ │ */
│ │ │ │ │ - getCentroid: function() {
│ │ │ │ │ - return new OpenLayers.Geometry.Point(this.x, this.y);
│ │ │ │ │ - },
│ │ │ │ │ + description: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: resize
│ │ │ │ │ - * Resize a point relative to some origin. For points, this has the effect
│ │ │ │ │ - * of scaling a vector (from the origin to the point). This method is
│ │ │ │ │ - * more useful on geometry collection subclasses.
│ │ │ │ │ + * 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.
│ │ │ │ │ + */
│ │ │ │ │ + context: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: filter
│ │ │ │ │ + * {} Optional filter for the rule.
│ │ │ │ │ + */
│ │ │ │ │ + filter: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * 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.
│ │ │ │ │ + */
│ │ │ │ │ + elseFilter: false,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * 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.
│ │ │ │ │ + */
│ │ │ │ │ + symbolizer: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * 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.
│ │ │ │ │ + */
│ │ │ │ │ + symbolizers: 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}"
│ │ │ │ │ + */
│ │ │ │ │ + minScaleDenominator: null,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * 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.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * scale - {Float} Ratio of the new distance from the origin to the old
│ │ │ │ │ - * distance from the origin. A scale of 2 doubles the
│ │ │ │ │ - * distance between the point and origin.
│ │ │ │ │ - * origin - {} Point of origin for resizing
│ │ │ │ │ - * ratio - {Float} Optional x:y ratio for resizing. Default ratio is 1.
│ │ │ │ │ + * options - {Object} An optional object with properties to set on the
│ │ │ │ │ + * rule
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {} - The current geometry.
│ │ │ │ │ + * {}
│ │ │ │ │ */
│ │ │ │ │ - resize: function(scale, origin, ratio) {
│ │ │ │ │ - ratio = (ratio == undefined) ? 1 : ratio;
│ │ │ │ │ - this.x = origin.x + (scale * ratio * (this.x - origin.x));
│ │ │ │ │ - this.y = origin.y + (scale * (this.y - origin.y));
│ │ │ │ │ - this.clearBounds();
│ │ │ │ │ - return this;
│ │ │ │ │ + initialize: function(options) {
│ │ │ │ │ + this.symbolizer = {};
│ │ │ │ │ + OpenLayers.Util.extend(this, options);
│ │ │ │ │ + if (this.symbolizers) {
│ │ │ │ │ + delete this.symbolizer;
│ │ │ │ │ + }
│ │ │ │ │ + this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * 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: intersects
│ │ │ │ │ - * Determine if the input geometry intersects this one.
│ │ │ │ │ - *
│ │ │ │ │ + * APIMethod: evaluate
│ │ │ │ │ + * evaluates this rule for a specific feature
│ │ │ │ │ + *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * geometry - {} Any type of geometry.
│ │ │ │ │ - *
│ │ │ │ │ + * feature - {} feature to apply the rule to.
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Boolean} The input geometry intersects this one.
│ │ │ │ │ + * {Boolean} true if the rule applies, false if it does not.
│ │ │ │ │ + * This rule is the default rule and always returns true.
│ │ │ │ │ */
│ │ │ │ │ - intersects: function(geometry) {
│ │ │ │ │ - var intersect = false;
│ │ │ │ │ - if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
│ │ │ │ │ - intersect = this.equals(geometry);
│ │ │ │ │ - } else {
│ │ │ │ │ - intersect = geometry.intersects(this);
│ │ │ │ │ + evaluate: function(feature) {
│ │ │ │ │ + var context = this.getContext(feature);
│ │ │ │ │ + var applies = true;
│ │ │ │ │ +
│ │ │ │ │ + if (this.minScaleDenominator || this.maxScaleDenominator) {
│ │ │ │ │ + var scale = feature.layer.map.getScale();
│ │ │ │ │ }
│ │ │ │ │ - return intersect;
│ │ │ │ │ +
│ │ │ │ │ + // 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;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: transform
│ │ │ │ │ - * Translate the x,y properties of the point from source to dest.
│ │ │ │ │ + * Method: getContext
│ │ │ │ │ + * Gets the context for evaluating this rule
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * source - {}
│ │ │ │ │ - * dest - {}
│ │ │ │ │ + * 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.
│ │ │ │ │ */
│ │ │ │ │ - transform: function(source, dest) {
│ │ │ │ │ - if ((source && dest)) {
│ │ │ │ │ - OpenLayers.Projection.transform(
│ │ │ │ │ - this, source, dest);
│ │ │ │ │ - this.bounds = null;
│ │ │ │ │ + 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;
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ - return this;
│ │ │ │ │ + // 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.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.Symbolizer
│ │ │ │ │ + * Base class representing a symbolizer used for feature rendering.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Symbolizer = OpenLayers.Class({
│ │ │ │ │ +
│ │ │ │ │ +
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: getVertices
│ │ │ │ │ - * Return a list of all points in this geometry.
│ │ │ │ │ + * 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.
│ │ │ │ │ + */
│ │ │ │ │ + zIndex: 0,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Constructor: OpenLayers.Symbolizer
│ │ │ │ │ + * Instances of this class are not useful. See one of the subclasses.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * 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.
│ │ │ │ │ + * config - {Object} An object containing properties to be set on the
│ │ │ │ │ + * symbolizer. Any documented symbolizer property can be set at
│ │ │ │ │ + * construction.
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Array} A list of all vertices in the geometry.
│ │ │ │ │ + * A new symbolizer.
│ │ │ │ │ */
│ │ │ │ │ - getVertices: function(nodes) {
│ │ │ │ │ - return [this];
│ │ │ │ │ + initialize: function(config) {
│ │ │ │ │ + OpenLayers.Util.extend(this, config);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Geometry.Point"
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: clone
│ │ │ │ │ + * Create a copy of this symbolizer.
│ │ │ │ │ + *
│ │ │ │ │ + * Returns a symbolizer of the same type with the same properties.
│ │ │ │ │ + */
│ │ │ │ │ + clone: function() {
│ │ │ │ │ + var Type = eval(this.CLASS_NAME);
│ │ │ │ │ + return new Type(OpenLayers.Util.extend({}, this));
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Symbolizer"
│ │ │ │ │ +
│ │ │ │ │ });
│ │ │ │ │ +
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Geometry/Collection.js
│ │ │ │ │ + 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/Geometry.js
│ │ │ │ │ + * @requires OpenLayers/Symbolizer.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Class: OpenLayers.Geometry.Collection
│ │ │ │ │ - * A Collection is exactly what it sounds like: A collection of different
│ │ │ │ │ - * Geometries. These are stored in the local parameter (which
│ │ │ │ │ - * can be passed as a parameter to the constructor).
│ │ │ │ │ - *
│ │ │ │ │ - * As new geometries are added to the collection, they are NOT cloned.
│ │ │ │ │ - * When removing geometries, they need to be specified by reference (ie you
│ │ │ │ │ - * have to pass in the *exact* geometry to be removed).
│ │ │ │ │ - *
│ │ │ │ │ - * The and functions here merely iterate through
│ │ │ │ │ - * the components, summing their respective areas and lengths.
│ │ │ │ │ - *
│ │ │ │ │ - * Create a new instance with the constructor.
│ │ │ │ │ - *
│ │ │ │ │ - * Inherits from:
│ │ │ │ │ - * -
│ │ │ │ │ + * Class: OpenLayers.Symbolizer.Point
│ │ │ │ │ + * A symbolizer used to render point features.
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Geometry.Collection = OpenLayers.Class(OpenLayers.Geometry, {
│ │ │ │ │ +OpenLayers.Symbolizer.Point = OpenLayers.Class(OpenLayers.Symbolizer, {
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: components
│ │ │ │ │ - * {Array()} The component parts of this geometry
│ │ │ │ │ + * 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.
│ │ │ │ │ */
│ │ │ │ │ - components: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: componentTypes
│ │ │ │ │ - * {Array(String)} An array of class names representing the types of
│ │ │ │ │ - * components that the collection can include. A null value means the
│ │ │ │ │ - * component types are not restricted.
│ │ │ │ │ + * APIProperty: strokeOpacity
│ │ │ │ │ + * {Number} Stroke opacity (0-1).
│ │ │ │ │ + *
│ │ │ │ │ + * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ */
│ │ │ │ │ - componentTypes: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constructor: OpenLayers.Geometry.Collection
│ │ │ │ │ - * Creates a Geometry Collection -- a list of geoms.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * components - {Array()} Optional array of geometries
│ │ │ │ │ - *
│ │ │ │ │ + * APIProperty: strokeWidth
│ │ │ │ │ + * {Number} Pixel stroke width.
│ │ │ │ │ + *
│ │ │ │ │ + * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ */
│ │ │ │ │ - initialize: function(components) {
│ │ │ │ │ - OpenLayers.Geometry.prototype.initialize.apply(this, arguments);
│ │ │ │ │ - this.components = [];
│ │ │ │ │ - if (components != null) {
│ │ │ │ │ - this.addComponents(components);
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: destroy
│ │ │ │ │ - * Destroy this geometry.
│ │ │ │ │ + * APIProperty: strokeLinecap
│ │ │ │ │ + * {String} Stroke cap type ("butt", "round", or "square").
│ │ │ │ │ + *
│ │ │ │ │ + * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ */
│ │ │ │ │ - destroy: function() {
│ │ │ │ │ - this.components.length = 0;
│ │ │ │ │ - this.components = null;
│ │ │ │ │ - OpenLayers.Geometry.prototype.destroy.apply(this, arguments);
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: clone
│ │ │ │ │ - * Clone this geometry.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} An exact clone of this collection
│ │ │ │ │ + * 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.
│ │ │ │ │ */
│ │ │ │ │ - clone: function() {
│ │ │ │ │ - var geometry = eval("new " + this.CLASS_NAME + "()");
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len; i++) {
│ │ │ │ │ - geometry.addComponent(this.components[i].clone());
│ │ │ │ │ - }
│ │ │ │ │
│ │ │ │ │ - // catch any randomly tagged-on properties
│ │ │ │ │ - OpenLayers.Util.applyDefaults(geometry, this);
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: fillColor
│ │ │ │ │ + * {String} RGB hex fill color (e.g. "#ff0000" for red).
│ │ │ │ │ + *
│ │ │ │ │ + * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ + */
│ │ │ │ │
│ │ │ │ │ - return geometry;
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: fillOpacity
│ │ │ │ │ + * {Number} Fill opacity (0-1).
│ │ │ │ │ + *
│ │ │ │ │ + * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ + */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: getComponentsString
│ │ │ │ │ - * Get a string representing the components for this collection
│ │ │ │ │ + * APIProperty: pointRadius
│ │ │ │ │ + * {Number} Pixel point radius.
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} A string representation of the components of this geometry
│ │ │ │ │ + * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ */
│ │ │ │ │ - getComponentsString: function() {
│ │ │ │ │ - var strings = [];
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len; i++) {
│ │ │ │ │ - strings.push(this.components[i].toShortString());
│ │ │ │ │ - }
│ │ │ │ │ - return strings.join(",");
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: calculateBounds
│ │ │ │ │ - * Recalculate the bounds by iterating through the components and
│ │ │ │ │ - * calling calling extendBounds() on each item.
│ │ │ │ │ + * 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.
│ │ │ │ │ */
│ │ │ │ │ - calculateBounds: function() {
│ │ │ │ │ - this.bounds = null;
│ │ │ │ │ - var bounds = new OpenLayers.Bounds();
│ │ │ │ │ - var components = this.components;
│ │ │ │ │ - if (components) {
│ │ │ │ │ - for (var i = 0, len = components.length; i < len; i++) {
│ │ │ │ │ - bounds.extend(components[i].getBounds());
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - // to preserve old behavior, we only set bounds if non-null
│ │ │ │ │ - // in the future, we could add bounds.isEmpty()
│ │ │ │ │ - if (bounds.left != null && bounds.bottom != null &&
│ │ │ │ │ - bounds.right != null && bounds.top != null) {
│ │ │ │ │ - this.setBounds(bounds);
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: addComponents
│ │ │ │ │ - * Add components to this geometry.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * components - {Array()} An array of geometries to add
│ │ │ │ │ + * APIProperty: graphicWidth
│ │ │ │ │ + * {Number} Pixel width for sizing an external graphic.
│ │ │ │ │ + *
│ │ │ │ │ + * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ */
│ │ │ │ │ - addComponents: function(components) {
│ │ │ │ │ - if (!(OpenLayers.Util.isArray(components))) {
│ │ │ │ │ - components = [components];
│ │ │ │ │ - }
│ │ │ │ │ - for (var i = 0, len = components.length; i < len; i++) {
│ │ │ │ │ - this.addComponent(components[i]);
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: addComponent
│ │ │ │ │ - * Add a new component (geometry) to the collection. If this.componentTypes
│ │ │ │ │ - * is set, then the component class name must be in the componentTypes array.
│ │ │ │ │ - *
│ │ │ │ │ - * The bounds cache is reset.
│ │ │ │ │ + * APIProperty: graphicHeight
│ │ │ │ │ + * {Number} Pixel height for sizing an external graphic.
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * component - {} A geometry to add
│ │ │ │ │ - * index - {int} Optional index into the array to insert the component
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} The component geometry was successfully added
│ │ │ │ │ + * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ */
│ │ │ │ │ - addComponent: function(component, index) {
│ │ │ │ │ - var added = false;
│ │ │ │ │ - if (component) {
│ │ │ │ │ - if (this.componentTypes == null ||
│ │ │ │ │ - (OpenLayers.Util.indexOf(this.componentTypes,
│ │ │ │ │ - component.CLASS_NAME) > -1)) {
│ │ │ │ │
│ │ │ │ │ - if (index != null && (index < this.components.length)) {
│ │ │ │ │ - var components1 = this.components.slice(0, index);
│ │ │ │ │ - var components2 = this.components.slice(index,
│ │ │ │ │ - this.components.length);
│ │ │ │ │ - components1.push(component);
│ │ │ │ │ - this.components = components1.concat(components2);
│ │ │ │ │ - } else {
│ │ │ │ │ - this.components.push(component);
│ │ │ │ │ - }
│ │ │ │ │ - component.parent = this;
│ │ │ │ │ - this.clearBounds();
│ │ │ │ │ - added = true;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return added;
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: graphicOpacity
│ │ │ │ │ + * {Number} Opacity (0-1) for an external graphic.
│ │ │ │ │ + *
│ │ │ │ │ + * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ + */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: removeComponents
│ │ │ │ │ - * Remove components from this geometry.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * components - {Array()} The components to be removed
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} A component was removed.
│ │ │ │ │ + * 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.
│ │ │ │ │ */
│ │ │ │ │ - removeComponents: function(components) {
│ │ │ │ │ - var removed = false;
│ │ │ │ │
│ │ │ │ │ - if (!(OpenLayers.Util.isArray(components))) {
│ │ │ │ │ - components = [components];
│ │ │ │ │ - }
│ │ │ │ │ - for (var i = components.length - 1; i >= 0; --i) {
│ │ │ │ │ - removed = this.removeComponent(components[i]) || removed;
│ │ │ │ │ - }
│ │ │ │ │ - return removed;
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * 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.
│ │ │ │ │ + */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: removeComponent
│ │ │ │ │ - * Remove a component from this geometry.
│ │ │ │ │ + * 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:
│ │ │ │ │ - * component - {}
│ │ │ │ │ + * config - {Object} An object containing properties to be set on the
│ │ │ │ │ + * symbolizer. Any documented symbolizer property can be set at
│ │ │ │ │ + * construction.
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} The component was removed.
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * A new point symbolizer.
│ │ │ │ │ */
│ │ │ │ │ - removeComponent: function(component) {
│ │ │ │ │ + initialize: function(config) {
│ │ │ │ │ + OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - OpenLayers.Util.removeItem(this.components, component);
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Symbolizer.Point"
│ │ │ │ │
│ │ │ │ │ - // clearBounds() so that it gets recalculated on the next call
│ │ │ │ │ - // to this.getBounds();
│ │ │ │ │ - this.clearBounds();
│ │ │ │ │ - return true;
│ │ │ │ │ - },
│ │ │ │ │ +});
│ │ │ │ │ +
│ │ │ │ │ +/* ======================================================================
│ │ │ │ │ + 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, {
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: getLength
│ │ │ │ │ - * Calculate the length of this geometry
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Float} The length of the geometry
│ │ │ │ │ + * 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.
│ │ │ │ │ */
│ │ │ │ │ - getLength: function() {
│ │ │ │ │ - var length = 0.0;
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len; i++) {
│ │ │ │ │ - length += this.components[i].getLength();
│ │ │ │ │ - }
│ │ │ │ │ - return length;
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: getArea
│ │ │ │ │ - * Calculate the area of this geometry. Note how this function is overridden
│ │ │ │ │ - * in .
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Float} The area of the collection by summing its parts
│ │ │ │ │ + * APIProperty: strokeOpacity
│ │ │ │ │ + * {Number} Stroke opacity (0-1).
│ │ │ │ │ + *
│ │ │ │ │ + * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ */
│ │ │ │ │ - getArea: function() {
│ │ │ │ │ - var area = 0.0;
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len; i++) {
│ │ │ │ │ - area += this.components[i].getArea();
│ │ │ │ │ - }
│ │ │ │ │ - return area;
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: getGeodesicArea
│ │ │ │ │ - * Calculate the approximate area of the polygon were it projected onto
│ │ │ │ │ - * the earth.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * projection - {} The spatial reference system
│ │ │ │ │ - * for the geometry coordinates. If not provided, Geographic/WGS84 is
│ │ │ │ │ - * assumed.
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: strokeWidth
│ │ │ │ │ + * {Number} Pixel stroke width.
│ │ │ │ │ *
│ │ │ │ │ - * Reference:
│ │ │ │ │ - * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for
│ │ │ │ │ - * Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion
│ │ │ │ │ - * Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {float} The approximate geodesic area of the geometry in square meters.
│ │ │ │ │ + * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ */
│ │ │ │ │ - getGeodesicArea: function(projection) {
│ │ │ │ │ - var area = 0.0;
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len; i++) {
│ │ │ │ │ - area += this.components[i].getGeodesicArea(projection);
│ │ │ │ │ - }
│ │ │ │ │ - return area;
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: getCentroid
│ │ │ │ │ - *
│ │ │ │ │ - * Compute the centroid for this geometry collection.
│ │ │ │ │ + * 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:
│ │ │ │ │ - * weighted - {Boolean} Perform the getCentroid computation recursively,
│ │ │ │ │ - * returning an area weighted average of all geometries in this collection.
│ │ │ │ │ + * config - {Object} An object containing properties to be set on the
│ │ │ │ │ + * symbolizer. Any documented symbolizer property can be set at
│ │ │ │ │ + * construction.
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {} The centroid of the collection
│ │ │ │ │ + * A new line symbolizer.
│ │ │ │ │ */
│ │ │ │ │ - getCentroid: function(weighted) {
│ │ │ │ │ - if (!weighted) {
│ │ │ │ │ - return this.components.length && this.components[0].getCentroid();
│ │ │ │ │ - }
│ │ │ │ │ - var len = this.components.length;
│ │ │ │ │ - if (!len) {
│ │ │ │ │ - return false;
│ │ │ │ │ - }
│ │ │ │ │ + initialize: function(config) {
│ │ │ │ │ + OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - var areas = [];
│ │ │ │ │ - var centroids = [];
│ │ │ │ │ - var areaSum = 0;
│ │ │ │ │ - var minArea = Number.MAX_VALUE;
│ │ │ │ │ - var component;
│ │ │ │ │ - for (var i = 0; i < len; ++i) {
│ │ │ │ │ - component = this.components[i];
│ │ │ │ │ - var area = component.getArea();
│ │ │ │ │ - var centroid = component.getCentroid(true);
│ │ │ │ │ - if (isNaN(area) || isNaN(centroid.x) || isNaN(centroid.y)) {
│ │ │ │ │ - continue;
│ │ │ │ │ - }
│ │ │ │ │ - areas.push(area);
│ │ │ │ │ - areaSum += area;
│ │ │ │ │ - minArea = (area < minArea && area > 0) ? area : minArea;
│ │ │ │ │ - centroids.push(centroid);
│ │ │ │ │ - }
│ │ │ │ │ - len = areas.length;
│ │ │ │ │ - if (areaSum === 0) {
│ │ │ │ │ - // all the components in this collection have 0 area
│ │ │ │ │ - // probably a collection of points -- weight all the points the same
│ │ │ │ │ - for (var i = 0; i < len; ++i) {
│ │ │ │ │ - areas[i] = 1;
│ │ │ │ │ - }
│ │ │ │ │ - areaSum = areas.length;
│ │ │ │ │ - } else {
│ │ │ │ │ - // normalize all the areas where the smallest area will get
│ │ │ │ │ - // a value of 1
│ │ │ │ │ - for (var i = 0; i < len; ++i) {
│ │ │ │ │ - areas[i] /= minArea;
│ │ │ │ │ - }
│ │ │ │ │ - areaSum /= minArea;
│ │ │ │ │ - }
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Symbolizer.Line"
│ │ │ │ │
│ │ │ │ │ - var xSum = 0,
│ │ │ │ │ - ySum = 0,
│ │ │ │ │ - centroid, area;
│ │ │ │ │ - for (var i = 0; i < len; ++i) {
│ │ │ │ │ - centroid = centroids[i];
│ │ │ │ │ - area = areas[i];
│ │ │ │ │ - xSum += centroid.x * area;
│ │ │ │ │ - ySum += centroid.y * area;
│ │ │ │ │ - }
│ │ │ │ │ +});
│ │ │ │ │
│ │ │ │ │ - return new OpenLayers.Geometry.Point(xSum / areaSum, ySum / areaSum);
│ │ │ │ │ - },
│ │ │ │ │ +/* ======================================================================
│ │ │ │ │ + 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, {
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: getGeodesicLength
│ │ │ │ │ - * Calculate the approximate length of the geometry were it projected onto
│ │ │ │ │ - * the earth.
│ │ │ │ │ - *
│ │ │ │ │ - * projection - {} The spatial reference system
│ │ │ │ │ - * for the geometry coordinates. If not provided, Geographic/WGS84 is
│ │ │ │ │ - * assumed.
│ │ │ │ │ + * APIProperty: strokeColor
│ │ │ │ │ + * {String} Color for line stroke. This is a RGB hex value (e.g. "#ff0000"
│ │ │ │ │ + * for red).
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Float} The appoximate geodesic length of the geometry in meters.
│ │ │ │ │ + * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ */
│ │ │ │ │ - getGeodesicLength: function(projection) {
│ │ │ │ │ - var length = 0.0;
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len; i++) {
│ │ │ │ │ - length += this.components[i].getGeodesicLength(projection);
│ │ │ │ │ - }
│ │ │ │ │ - return length;
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: move
│ │ │ │ │ - * Moves a geometry by the given displacement along positive x and y axes.
│ │ │ │ │ - * This modifies the position of the geometry and clears the cached
│ │ │ │ │ - * bounds.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * x - {Float} Distance to move geometry in positive x direction.
│ │ │ │ │ - * y - {Float} Distance to move geometry in positive y direction.
│ │ │ │ │ + * APIProperty: strokeOpacity
│ │ │ │ │ + * {Number} Stroke opacity (0-1).
│ │ │ │ │ + *
│ │ │ │ │ + * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ */
│ │ │ │ │ - move: function(x, y) {
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len; i++) {
│ │ │ │ │ - this.components[i].move(x, y);
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: rotate
│ │ │ │ │ - * Rotate a geometry around some origin
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * angle - {Float} Rotation angle in degrees (measured counterclockwise
│ │ │ │ │ - * from the positive x-axis)
│ │ │ │ │ - * origin - {} Center point for the rotation
│ │ │ │ │ + * APIProperty: strokeWidth
│ │ │ │ │ + * {Number} Pixel stroke width.
│ │ │ │ │ + *
│ │ │ │ │ + * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ */
│ │ │ │ │ - rotate: function(angle, origin) {
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len; ++i) {
│ │ │ │ │ - this.components[i].rotate(angle, origin);
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: resize
│ │ │ │ │ - * Resize a geometry relative to some origin. Use this method to apply
│ │ │ │ │ - * a uniform scaling to a geometry.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * scale - {Float} Factor by which to scale the geometry. A scale of 2
│ │ │ │ │ - * doubles the size of the geometry in each dimension
│ │ │ │ │ - * (lines, for example, will be twice as long, and polygons
│ │ │ │ │ - * will have four times the area).
│ │ │ │ │ - * origin - {} Point of origin for resizing
│ │ │ │ │ - * ratio - {Float} Optional x:y ratio for resizing. Default ratio is 1.
│ │ │ │ │ + * APIProperty: strokeLinecap
│ │ │ │ │ + * {String} Stroke cap type ("butt", "round", or "square").
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} - The current geometry.
│ │ │ │ │ + * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ */
│ │ │ │ │ - resize: function(scale, origin, ratio) {
│ │ │ │ │ - for (var i = 0; i < this.components.length; ++i) {
│ │ │ │ │ - this.components[i].resize(scale, origin, ratio);
│ │ │ │ │ - }
│ │ │ │ │ - return this;
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: distanceTo
│ │ │ │ │ - * Calculate the closest distance between two geometries (on the x-y plane).
│ │ │ │ │ + * 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:
│ │ │ │ │ - * geometry - {} The target geometry.
│ │ │ │ │ - * options - {Object} Optional properties for configuring the distance
│ │ │ │ │ - * calculation.
│ │ │ │ │ - *
│ │ │ │ │ - * Valid options:
│ │ │ │ │ - * details - {Boolean} Return details from the distance calculation.
│ │ │ │ │ - * Default is false.
│ │ │ │ │ - * edge - {Boolean} Calculate the distance from this geometry to the
│ │ │ │ │ - * nearest edge of the target geometry. Default is true. If true,
│ │ │ │ │ - * calling distanceTo from a geometry that is wholly contained within
│ │ │ │ │ - * the target will result in a non-zero distance. If false, whenever
│ │ │ │ │ - * geometries intersect, calling distanceTo will return 0. If false,
│ │ │ │ │ - * details cannot be returned.
│ │ │ │ │ + * config - {Object} An object containing properties to be set on the
│ │ │ │ │ + * symbolizer. Any documented symbolizer property can be set at
│ │ │ │ │ + * construction.
│ │ │ │ │ *
│ │ │ │ │ * 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 y1 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.
│ │ │ │ │ + * A new polygon symbolizer.
│ │ │ │ │ */
│ │ │ │ │ - distanceTo: function(geometry, options) {
│ │ │ │ │ - var edge = !(options && options.edge === false);
│ │ │ │ │ - var details = edge && options && options.details;
│ │ │ │ │ - var result, best, distance;
│ │ │ │ │ - var min = Number.POSITIVE_INFINITY;
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len; ++i) {
│ │ │ │ │ - result = this.components[i].distanceTo(geometry, options);
│ │ │ │ │ - distance = details ? result.distance : result;
│ │ │ │ │ - if (distance < min) {
│ │ │ │ │ - min = distance;
│ │ │ │ │ - best = result;
│ │ │ │ │ - if (min == 0) {
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return best;
│ │ │ │ │ + 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, {
│ │ │ │ │ +
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: equals
│ │ │ │ │ - * Determine whether another geometry is equivalent to this one. Geometries
│ │ │ │ │ - * are considered equivalent if all components have the same coordinates.
│ │ │ │ │ + * APIProperty: label
│ │ │ │ │ + * {String} The text for the label.
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * geometry - {} The geometry to test.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} The supplied geometry is equivalent to this geometry.
│ │ │ │ │ + * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ */
│ │ │ │ │ - equals: function(geometry) {
│ │ │ │ │ - var equivalent = true;
│ │ │ │ │ - if (!geometry || !geometry.CLASS_NAME ||
│ │ │ │ │ - (this.CLASS_NAME != geometry.CLASS_NAME)) {
│ │ │ │ │ - equivalent = false;
│ │ │ │ │ - } else if (!(OpenLayers.Util.isArray(geometry.components)) ||
│ │ │ │ │ - (geometry.components.length != this.components.length)) {
│ │ │ │ │ - equivalent = false;
│ │ │ │ │ - } else {
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len; ++i) {
│ │ │ │ │ - if (!this.components[i].equals(geometry.components[i])) {
│ │ │ │ │ - equivalent = false;
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return equivalent;
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: transform
│ │ │ │ │ - * Reproject the components geometry from source to dest.
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: fontFamily
│ │ │ │ │ + * {String} The font family for the label.
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * source - {}
│ │ │ │ │ - * dest - {}
│ │ │ │ │ + * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ + */
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: fontSize
│ │ │ │ │ + * {String} The font size for the label.
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {}
│ │ │ │ │ + * 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.
│ │ │ │ │ */
│ │ │ │ │ - transform: function(source, dest) {
│ │ │ │ │ - if (source && dest) {
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len; i++) {
│ │ │ │ │ - var component = this.components[i];
│ │ │ │ │ - component.transform(source, dest);
│ │ │ │ │ - }
│ │ │ │ │ - this.bounds = null;
│ │ │ │ │ - }
│ │ │ │ │ - return this;
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: intersects
│ │ │ │ │ - * Determine if the input geometry intersects this one.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * geometry - {} Any type of geometry.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} The input geometry intersects this one.
│ │ │ │ │ + * Property: fontStyle
│ │ │ │ │ + * {String} The font style for the label.
│ │ │ │ │ + *
│ │ │ │ │ + * No default set here. Use OpenLayers.Renderer.defaultRenderer for defaults.
│ │ │ │ │ */
│ │ │ │ │ - intersects: function(geometry) {
│ │ │ │ │ - var intersect = false;
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len; ++i) {
│ │ │ │ │ - intersect = geometry.intersects(this.components[i]);
│ │ │ │ │ - if (intersect) {
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return intersect;
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: getVertices
│ │ │ │ │ - * Return a list of all points in this geometry.
│ │ │ │ │ + * Constructor: OpenLayers.Symbolizer.Text
│ │ │ │ │ + * Create a symbolizer for rendering text labels.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * 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.
│ │ │ │ │ + * config - {Object} An object containing properties to be set on the
│ │ │ │ │ + * symbolizer. Any documented symbolizer property can be set at
│ │ │ │ │ + * construction.
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Array} A list of all vertices in the geometry.
│ │ │ │ │ + * A new text symbolizer.
│ │ │ │ │ */
│ │ │ │ │ - getVertices: function(nodes) {
│ │ │ │ │ - var vertices = [];
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len; ++i) {
│ │ │ │ │ - Array.prototype.push.apply(
│ │ │ │ │ - vertices, this.components[i].getVertices(nodes)
│ │ │ │ │ - );
│ │ │ │ │ - }
│ │ │ │ │ - return vertices;
│ │ │ │ │ + initialize: function(config) {
│ │ │ │ │ + OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Symbolizer.Text"
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Geometry.Collection"
│ │ │ │ │ });
│ │ │ │ │ +
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Geometry/MultiPoint.js
│ │ │ │ │ + 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/Geometry/Collection.js
│ │ │ │ │ - * @requires OpenLayers/Geometry/Point.js
│ │ │ │ │ + * @requires OpenLayers/Symbolizer.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Class: OpenLayers.Geometry.MultiPoint
│ │ │ │ │ - * MultiPoint is a collection of Points. Create a new instance with the
│ │ │ │ │ - * constructor.
│ │ │ │ │ - *
│ │ │ │ │ - * Inherits from:
│ │ │ │ │ - * -
│ │ │ │ │ - * -
│ │ │ │ │ + * Class: OpenLayers.Symbolizer.Raster
│ │ │ │ │ + * A symbolizer used to render raster images.
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Geometry.MultiPoint = OpenLayers.Class(
│ │ │ │ │ - OpenLayers.Geometry.Collection, {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: componentTypes
│ │ │ │ │ - * {Array(String)} An array of class names representing the types of
│ │ │ │ │ - * components that the collection can include. A null value means the
│ │ │ │ │ - * component types are not restricted.
│ │ │ │ │ - */
│ │ │ │ │ - componentTypes: ["OpenLayers.Geometry.Point"],
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Geometry.MultiPoint
│ │ │ │ │ - * Create a new MultiPoint Geometry
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * components - {Array()}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {}
│ │ │ │ │ - */
│ │ │ │ │ +OpenLayers.Symbolizer.Raster = OpenLayers.Class(OpenLayers.Symbolizer, {
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: addPoint
│ │ │ │ │ - * Wrapper for
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * point - {} Point to be added
│ │ │ │ │ - * index - {Integer} Optional index
│ │ │ │ │ - */
│ │ │ │ │ - addPoint: function(point, index) {
│ │ │ │ │ - this.addComponent(point, index);
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * 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);
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: removePoint
│ │ │ │ │ - * Wrapper for
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * point - {} Point to be removed
│ │ │ │ │ - */
│ │ │ │ │ - removePoint: function(point) {
│ │ │ │ │ - this.removeComponent(point);
│ │ │ │ │ - },
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Symbolizer.Raster"
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Geometry.MultiPoint"
│ │ │ │ │ - });
│ │ │ │ │ +});
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Geometry/Curve.js
│ │ │ │ │ + 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/Geometry/MultiPoint.js
│ │ │ │ │ + * @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.Geometry.Curve
│ │ │ │ │ - * A Curve is a MultiPoint, whose points are assumed to be connected. To
│ │ │ │ │ - * this end, we provide a "getLength()" function, which iterates through
│ │ │ │ │ - * the points, summing the distances between them.
│ │ │ │ │ - *
│ │ │ │ │ - * Inherits:
│ │ │ │ │ - * -
│ │ │ │ │ + * Class: OpenLayers.Style2
│ │ │ │ │ + * This class represents a collection of rules for rendering features.
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Geometry.Curve = OpenLayers.Class(OpenLayers.Geometry.MultiPoint, {
│ │ │ │ │ +OpenLayers.Style2 = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: componentTypes
│ │ │ │ │ - * {Array(String)} An array of class names representing the types of
│ │ │ │ │ - * components that the collection can include. A null
│ │ │ │ │ - * value means the component types are not restricted.
│ │ │ │ │ + * Property: id
│ │ │ │ │ + * {String} A unique id for this session.
│ │ │ │ │ */
│ │ │ │ │ - componentTypes: ["OpenLayers.Geometry.Point"],
│ │ │ │ │ + id: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constructor: OpenLayers.Geometry.Curve
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * point - {Array()}
│ │ │ │ │ + * APIProperty: name
│ │ │ │ │ + * {String} Style identifier.
│ │ │ │ │ */
│ │ │ │ │ + name: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: getLength
│ │ │ │ │ - *
│ │ │ │ │ + * 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:
│ │ │ │ │ - * {Float} The length of the curve
│ │ │ │ │ + * {} A new style object.
│ │ │ │ │ */
│ │ │ │ │ - getLength: function() {
│ │ │ │ │ - var length = 0.0;
│ │ │ │ │ - if (this.components && (this.components.length > 1)) {
│ │ │ │ │ - for (var i = 1, len = this.components.length; i < len; i++) {
│ │ │ │ │ - length += this.components[i - 1].distanceTo(this.components[i]);
│ │ │ │ │ - }
│ │ │ │ │ + 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();
│ │ │ │ │ }
│ │ │ │ │ - return length;
│ │ │ │ │ + delete this.rules;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: getGeodesicLength
│ │ │ │ │ - * Calculate the approximate length of the geometry were it projected onto
│ │ │ │ │ - * the earth.
│ │ │ │ │ - *
│ │ │ │ │ - * projection - {} The spatial reference system
│ │ │ │ │ - * for the geometry coordinates. If not provided, Geographic/WGS84 is
│ │ │ │ │ - * assumed.
│ │ │ │ │ + * APIMethod: clone
│ │ │ │ │ + * Clones this style.
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Float} The appoximate geodesic length of the geometry in meters.
│ │ │ │ │ + * {} Clone of this style.
│ │ │ │ │ */
│ │ │ │ │ - getGeodesicLength: function(projection) {
│ │ │ │ │ - var geom = this; // so we can work with a clone if needed
│ │ │ │ │ - if (projection) {
│ │ │ │ │ - var gg = new OpenLayers.Projection("EPSG:4326");
│ │ │ │ │ - if (!gg.equals(projection)) {
│ │ │ │ │ - geom = this.clone().transform(projection, gg);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - var length = 0.0;
│ │ │ │ │ - if (geom.components && (geom.components.length > 1)) {
│ │ │ │ │ - var p1, p2;
│ │ │ │ │ - for (var i = 1, len = geom.components.length; i < len; i++) {
│ │ │ │ │ - p1 = geom.components[i - 1];
│ │ │ │ │ - p2 = geom.components[i];
│ │ │ │ │ - // this returns km and requires lon/lat properties
│ │ │ │ │ - length += OpenLayers.Util.distVincenty({
│ │ │ │ │ - lon: p1.x,
│ │ │ │ │ - lat: p1.y
│ │ │ │ │ - }, {
│ │ │ │ │ - lon: p2.x,
│ │ │ │ │ - lat: p2.y
│ │ │ │ │ - });
│ │ │ │ │ + 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());
│ │ │ │ │ }
│ │ │ │ │ }
│ │ │ │ │ - // convert to m
│ │ │ │ │ - return length * 1000;
│ │ │ │ │ + return new OpenLayers.Style2(config);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Geometry.Curve"
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Style2"
│ │ │ │ │ });
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Geometry/LineString.js
│ │ │ │ │ + OpenLayers/Kinetic.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/Geometry/Curve.js
│ │ │ │ │ + * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ + * @requires OpenLayers/Animation.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Geometry.LineString
│ │ │ │ │ - * A LineString is a Curve which, once two points have been added to it, can
│ │ │ │ │ - * never be less than two points long.
│ │ │ │ │ - *
│ │ │ │ │ - * Inherits from:
│ │ │ │ │ - * -
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Geometry.LineString = OpenLayers.Class(OpenLayers.Geometry.Curve, {
│ │ │ │ │ +OpenLayers.Kinetic = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constructor: OpenLayers.Geometry.LineString
│ │ │ │ │ - * Create a new LineString geometry
│ │ │ │ │ + * Property: threshold
│ │ │ │ │ + * In most cases changing the threshold isn't needed.
│ │ │ │ │ + * In px/ms, default to 0.
│ │ │ │ │ + */
│ │ │ │ │ + threshold: 0,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: deceleration
│ │ │ │ │ + * {Float} the deseleration in px/ms², default to 0.0035.
│ │ │ │ │ + */
│ │ │ │ │ + deceleration: 0.0035,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: nbPoints
│ │ │ │ │ + * {Integer} the number of points we use to calculate the kinetic
│ │ │ │ │ + * initial values.
│ │ │ │ │ + */
│ │ │ │ │ + nbPoints: 100,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: delay
│ │ │ │ │ + * {Float} time to consider to calculate the kinetic initial values.
│ │ │ │ │ + * In ms, default to 200.
│ │ │ │ │ + */
│ │ │ │ │ + delay: 200,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: points
│ │ │ │ │ + * List of points use to calculate the kinetic initial values.
│ │ │ │ │ + */
│ │ │ │ │ + points: undefined,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: timerId
│ │ │ │ │ + * ID of the timer.
│ │ │ │ │ + */
│ │ │ │ │ + timerId: undefined,
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Constructor: OpenLayers.Kinetic
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * points - {Array()} An array of points used to
│ │ │ │ │ - * generate the linestring
│ │ │ │ │ - *
│ │ │ │ │ + * options - {Object}
│ │ │ │ │ */
│ │ │ │ │ + initialize: function(options) {
│ │ │ │ │ + OpenLayers.Util.extend(this, options);
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: removeComponent
│ │ │ │ │ - * Only allows removal of a point if there are three or more points in
│ │ │ │ │ - * the linestring. (otherwise the result would be just a single point)
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * point - {} The point to be removed
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} The component was removed.
│ │ │ │ │ + * Method: begin
│ │ │ │ │ + * Begins the dragging.
│ │ │ │ │ */
│ │ │ │ │ - removeComponent: function(point) {
│ │ │ │ │ - var removed = this.components && (this.components.length > 2);
│ │ │ │ │ - if (removed) {
│ │ │ │ │ - OpenLayers.Geometry.Collection.prototype.removeComponent.apply(this,
│ │ │ │ │ - arguments);
│ │ │ │ │ - }
│ │ │ │ │ - return removed;
│ │ │ │ │ + begin: function() {
│ │ │ │ │ + OpenLayers.Animation.stop(this.timerId);
│ │ │ │ │ + this.timerId = undefined;
│ │ │ │ │ + this.points = [];
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: intersects
│ │ │ │ │ - * Test for instersection between two geometries. This is a cheapo
│ │ │ │ │ - * implementation of the Bently-Ottmann algorigithm. It doesn't
│ │ │ │ │ - * really keep track of a sweep line data structure. It is closer
│ │ │ │ │ - * to the brute force method, except that segments are sorted and
│ │ │ │ │ - * potential intersections are only calculated when bounding boxes
│ │ │ │ │ - * intersect.
│ │ │ │ │ + * Method: update
│ │ │ │ │ + * Updates during the dragging.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * geometry - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} The input geometry intersects this geometry.
│ │ │ │ │ + * xy - {} The new position.
│ │ │ │ │ */
│ │ │ │ │ - intersects: function(geometry) {
│ │ │ │ │ - var intersect = false;
│ │ │ │ │ - var type = geometry.CLASS_NAME;
│ │ │ │ │ - if (type == "OpenLayers.Geometry.LineString" ||
│ │ │ │ │ - type == "OpenLayers.Geometry.LinearRing" ||
│ │ │ │ │ - type == "OpenLayers.Geometry.Point") {
│ │ │ │ │ - var segs1 = this.getSortedSegments();
│ │ │ │ │ - var segs2;
│ │ │ │ │ - if (type == "OpenLayers.Geometry.Point") {
│ │ │ │ │ - segs2 = [{
│ │ │ │ │ - x1: geometry.x,
│ │ │ │ │ - y1: geometry.y,
│ │ │ │ │ - x2: geometry.x,
│ │ │ │ │ - y2: geometry.y
│ │ │ │ │ - }];
│ │ │ │ │ - } else {
│ │ │ │ │ - segs2 = geometry.getSortedSegments();
│ │ │ │ │ - }
│ │ │ │ │ - var seg1, seg1x1, seg1x2, seg1y1, seg1y2,
│ │ │ │ │ - seg2, seg2y1, seg2y2;
│ │ │ │ │ - // sweep right
│ │ │ │ │ - outer: for (var i = 0, len = segs1.length; i < len; ++i) {
│ │ │ │ │ - seg1 = segs1[i];
│ │ │ │ │ - seg1x1 = seg1.x1;
│ │ │ │ │ - seg1x2 = seg1.x2;
│ │ │ │ │ - seg1y1 = seg1.y1;
│ │ │ │ │ - seg1y2 = seg1.y2;
│ │ │ │ │ - inner: for (var j = 0, jlen = segs2.length; j < jlen; ++j) {
│ │ │ │ │ - seg2 = segs2[j];
│ │ │ │ │ - if (seg2.x1 > seg1x2) {
│ │ │ │ │ - // seg1 still left of seg2
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - if (seg2.x2 < seg1x1) {
│ │ │ │ │ - // seg2 still left of seg1
│ │ │ │ │ - continue;
│ │ │ │ │ - }
│ │ │ │ │ - seg2y1 = seg2.y1;
│ │ │ │ │ - seg2y2 = seg2.y2;
│ │ │ │ │ - if (Math.min(seg2y1, seg2y2) > Math.max(seg1y1, seg1y2)) {
│ │ │ │ │ - // seg2 above seg1
│ │ │ │ │ - continue;
│ │ │ │ │ - }
│ │ │ │ │ - if (Math.max(seg2y1, seg2y2) < Math.min(seg1y1, seg1y2)) {
│ │ │ │ │ - // seg2 below seg1
│ │ │ │ │ - continue;
│ │ │ │ │ - }
│ │ │ │ │ - if (OpenLayers.Geometry.segmentsIntersect(seg1, seg2)) {
│ │ │ │ │ - intersect = true;
│ │ │ │ │ - break outer;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - } else {
│ │ │ │ │ - intersect = geometry.intersects(this);
│ │ │ │ │ + update: function(xy) {
│ │ │ │ │ + this.points.unshift({
│ │ │ │ │ + xy: xy,
│ │ │ │ │ + tick: new Date().getTime()
│ │ │ │ │ + });
│ │ │ │ │ + if (this.points.length > this.nbPoints) {
│ │ │ │ │ + this.points.pop();
│ │ │ │ │ }
│ │ │ │ │ - return intersect;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: getSortedSegments
│ │ │ │ │ + * Method: end
│ │ │ │ │ + * Ends the dragging, start the kinetic.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * xy - {} The last position.
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Array} An array of segment objects. Segment objects have 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.
│ │ │ │ │ + * {Object} An object with two properties: "speed", and "theta". The
│ │ │ │ │ + * "speed" and "theta" values are to be passed to the move
│ │ │ │ │ + * function when starting the animation.
│ │ │ │ │ */
│ │ │ │ │ - getSortedSegments: function() {
│ │ │ │ │ - var numSeg = this.components.length - 1;
│ │ │ │ │ - var segments = new Array(numSeg),
│ │ │ │ │ - point1, point2;
│ │ │ │ │ - for (var i = 0; i < numSeg; ++i) {
│ │ │ │ │ - point1 = this.components[i];
│ │ │ │ │ - point2 = this.components[i + 1];
│ │ │ │ │ - if (point1.x < point2.x) {
│ │ │ │ │ - segments[i] = {
│ │ │ │ │ - x1: point1.x,
│ │ │ │ │ - y1: point1.y,
│ │ │ │ │ - x2: point2.x,
│ │ │ │ │ - y2: point2.y
│ │ │ │ │ - };
│ │ │ │ │ - } else {
│ │ │ │ │ - segments[i] = {
│ │ │ │ │ - x1: point2.x,
│ │ │ │ │ - y1: point2.y,
│ │ │ │ │ - x2: point1.x,
│ │ │ │ │ - y2: point1.y
│ │ │ │ │ - };
│ │ │ │ │ + end: function(xy) {
│ │ │ │ │ + var last, now = new Date().getTime();
│ │ │ │ │ + for (var i = 0, l = this.points.length, point; i < l; i++) {
│ │ │ │ │ + point = this.points[i];
│ │ │ │ │ + if (now - point.tick > this.delay) {
│ │ │ │ │ + break;
│ │ │ │ │ }
│ │ │ │ │ + last = point;
│ │ │ │ │ }
│ │ │ │ │ - // more efficient to define this somewhere static
│ │ │ │ │ - function byX1(seg1, seg2) {
│ │ │ │ │ - return seg1.x1 - seg2.x1;
│ │ │ │ │ + if (!last) {
│ │ │ │ │ + return;
│ │ │ │ │ }
│ │ │ │ │ - return segments.sort(byX1);
│ │ │ │ │ + var time = new Date().getTime() - last.tick;
│ │ │ │ │ + var dist = Math.sqrt(Math.pow(xy.x - last.xy.x, 2) +
│ │ │ │ │ + Math.pow(xy.y - last.xy.y, 2));
│ │ │ │ │ + var speed = dist / time;
│ │ │ │ │ + if (speed == 0 || speed < this.threshold) {
│ │ │ │ │ + return;
│ │ │ │ │ + }
│ │ │ │ │ + var theta = Math.asin((xy.y - last.xy.y) / dist);
│ │ │ │ │ + if (last.xy.x <= xy.x) {
│ │ │ │ │ + theta = Math.PI - theta;
│ │ │ │ │ + }
│ │ │ │ │ + return {
│ │ │ │ │ + speed: speed,
│ │ │ │ │ + theta: theta
│ │ │ │ │ + };
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: splitWithSegment
│ │ │ │ │ - * Split this geometry with the given segment.
│ │ │ │ │ + * Method: move
│ │ │ │ │ + * Launch the kinetic move pan.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * seg - {Object} An object with x1, y1, x2, and y2 properties referencing
│ │ │ │ │ - * segment endpoint coordinates.
│ │ │ │ │ - * options - {Object} Properties of this object will be used to determine
│ │ │ │ │ - * how the split is conducted.
│ │ │ │ │ - *
│ │ │ │ │ - * Valid options:
│ │ │ │ │ - * edge - {Boolean} Allow splitting when only edges intersect. Default is
│ │ │ │ │ - * true. If false, a vertex on the source segment must be within the
│ │ │ │ │ - * tolerance distance of the intersection to be considered a split.
│ │ │ │ │ - * tolerance - {Number} If a non-null value is provided, intersections
│ │ │ │ │ - * within the tolerance distance of one of the source segment's
│ │ │ │ │ - * endpoints will be assumed to occur at the endpoint.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Object} An object with *lines* and *points* properties. If the given
│ │ │ │ │ - * segment intersects this linestring, the lines array will reference
│ │ │ │ │ - * geometries that result from the split. The points array will contain
│ │ │ │ │ - * all intersection points. Intersection points are sorted along the
│ │ │ │ │ - * segment (in order from x1,y1 to x2,y2).
│ │ │ │ │ + * info - {Object} An object with two properties, "speed", and "theta".
│ │ │ │ │ + * These values are those returned from the "end" call.
│ │ │ │ │ + * callback - {Function} Function called on every step of the animation,
│ │ │ │ │ + * receives x, y (values to pan), end (is the last point).
│ │ │ │ │ */
│ │ │ │ │ - splitWithSegment: function(seg, options) {
│ │ │ │ │ - var edge = !(options && options.edge === false);
│ │ │ │ │ - var tolerance = options && options.tolerance;
│ │ │ │ │ - var lines = [];
│ │ │ │ │ - var verts = this.getVertices();
│ │ │ │ │ - var points = [];
│ │ │ │ │ - var intersections = [];
│ │ │ │ │ - var split = false;
│ │ │ │ │ - var vert1, vert2, point;
│ │ │ │ │ - var node, vertex, target;
│ │ │ │ │ - var interOptions = {
│ │ │ │ │ - point: true,
│ │ │ │ │ - tolerance: tolerance
│ │ │ │ │ - };
│ │ │ │ │ - var result = null;
│ │ │ │ │ - for (var i = 0, stop = verts.length - 2; i <= stop; ++i) {
│ │ │ │ │ - vert1 = verts[i];
│ │ │ │ │ - points.push(vert1.clone());
│ │ │ │ │ - vert2 = verts[i + 1];
│ │ │ │ │ - target = {
│ │ │ │ │ - x1: vert1.x,
│ │ │ │ │ - y1: vert1.y,
│ │ │ │ │ - x2: vert2.x,
│ │ │ │ │ - y2: vert2.y
│ │ │ │ │ - };
│ │ │ │ │ - point = OpenLayers.Geometry.segmentsIntersect(
│ │ │ │ │ - seg, target, interOptions
│ │ │ │ │ - );
│ │ │ │ │ - if (point instanceof OpenLayers.Geometry.Point) {
│ │ │ │ │ - if ((point.x === seg.x1 && point.y === seg.y1) ||
│ │ │ │ │ - (point.x === seg.x2 && point.y === seg.y2) ||
│ │ │ │ │ - point.equals(vert1) || point.equals(vert2)) {
│ │ │ │ │ - vertex = true;
│ │ │ │ │ - } else {
│ │ │ │ │ - vertex = false;
│ │ │ │ │ - }
│ │ │ │ │ - if (vertex || edge) {
│ │ │ │ │ - // push intersections different than the previous
│ │ │ │ │ - if (!point.equals(intersections[intersections.length - 1])) {
│ │ │ │ │ - intersections.push(point.clone());
│ │ │ │ │ - }
│ │ │ │ │ - if (i === 0) {
│ │ │ │ │ - if (point.equals(vert1)) {
│ │ │ │ │ - continue;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - if (point.equals(vert2)) {
│ │ │ │ │ - continue;
│ │ │ │ │ - }
│ │ │ │ │ - split = true;
│ │ │ │ │ - if (!point.equals(vert1)) {
│ │ │ │ │ - points.push(point);
│ │ │ │ │ - }
│ │ │ │ │ - lines.push(new OpenLayers.Geometry.LineString(points));
│ │ │ │ │ - points = [point.clone()];
│ │ │ │ │ - }
│ │ │ │ │ + move: function(info, callback) {
│ │ │ │ │ + var v0 = info.speed;
│ │ │ │ │ + var fx = Math.cos(info.theta);
│ │ │ │ │ + var fy = -Math.sin(info.theta);
│ │ │ │ │ +
│ │ │ │ │ + var initialTime = new Date().getTime();
│ │ │ │ │ +
│ │ │ │ │ + var lastX = 0;
│ │ │ │ │ + var lastY = 0;
│ │ │ │ │ +
│ │ │ │ │ + var timerCallback = function() {
│ │ │ │ │ + if (this.timerId == null) {
│ │ │ │ │ + return;
│ │ │ │ │ }
│ │ │ │ │ - }
│ │ │ │ │ - if (split) {
│ │ │ │ │ - points.push(vert2.clone());
│ │ │ │ │ - lines.push(new OpenLayers.Geometry.LineString(points));
│ │ │ │ │ - }
│ │ │ │ │ - if (intersections.length > 0) {
│ │ │ │ │ - // sort intersections along segment
│ │ │ │ │ - var xDir = seg.x1 < seg.x2 ? 1 : -1;
│ │ │ │ │ - var yDir = seg.y1 < seg.y2 ? 1 : -1;
│ │ │ │ │ - result = {
│ │ │ │ │ - lines: lines,
│ │ │ │ │ - points: intersections.sort(function(p1, p2) {
│ │ │ │ │ - return (xDir * p1.x - xDir * p2.x) || (yDir * p1.y - yDir * p2.y);
│ │ │ │ │ - })
│ │ │ │ │ - };
│ │ │ │ │ - }
│ │ │ │ │ - return result;
│ │ │ │ │ +
│ │ │ │ │ + var t = new Date().getTime() - initialTime;
│ │ │ │ │ +
│ │ │ │ │ + var p = (-this.deceleration * Math.pow(t, 2)) / 2.0 + v0 * t;
│ │ │ │ │ + var x = p * fx;
│ │ │ │ │ + var y = p * fy;
│ │ │ │ │ +
│ │ │ │ │ + var args = {};
│ │ │ │ │ + args.end = false;
│ │ │ │ │ + var v = -this.deceleration * t + v0;
│ │ │ │ │ +
│ │ │ │ │ + if (v <= 0) {
│ │ │ │ │ + OpenLayers.Animation.stop(this.timerId);
│ │ │ │ │ + this.timerId = null;
│ │ │ │ │ + args.end = true;
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + args.x = x - lastX;
│ │ │ │ │ + args.y = y - lastY;
│ │ │ │ │ + lastX = x;
│ │ │ │ │ + lastY = y;
│ │ │ │ │ + callback(args.x, args.y, args.end);
│ │ │ │ │ + };
│ │ │ │ │ +
│ │ │ │ │ + this.timerId = OpenLayers.Animation.start(
│ │ │ │ │ + OpenLayers.Function.bind(timerCallback, this)
│ │ │ │ │ + );
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Kinetic"
│ │ │ │ │ +});
│ │ │ │ │ +/* ======================================================================
│ │ │ │ │ + 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,
│ │ │ │ │ +
│ │ │ │ │ /**
│ │ │ │ │ - * Method: split
│ │ │ │ │ - * Use this geometry (the source) to attempt to split a target geometry.
│ │ │ │ │ + * 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:
│ │ │ │ │ - * target - {} The target geometry.
│ │ │ │ │ - * options - {Object} Properties of this object will be used to determine
│ │ │ │ │ - * how the split is conducted.
│ │ │ │ │ - *
│ │ │ │ │ - * Valid options:
│ │ │ │ │ - * mutual - {Boolean} Split the source geometry in addition to the target
│ │ │ │ │ - * geometry. Default is false.
│ │ │ │ │ - * edge - {Boolean} Allow splitting when only edges intersect. Default is
│ │ │ │ │ - * true. If false, a vertex on the source must be within the tolerance
│ │ │ │ │ - * distance of the intersection to be considered a split.
│ │ │ │ │ - * tolerance - {Number} If a non-null value is provided, intersections
│ │ │ │ │ - * within the tolerance distance of an existing vertex on the source
│ │ │ │ │ - * will be assumed to occur at the vertex.
│ │ │ │ │ + * event - {Event}
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Array} A list of geometries (of this same type as the target) that
│ │ │ │ │ - * result from splitting the target with the source geometry. The
│ │ │ │ │ - * source and target geometry will remain unmodified. If no split
│ │ │ │ │ - * results, null will be returned. If mutual is true and a split
│ │ │ │ │ - * results, return will be an array of two arrays - the first will be
│ │ │ │ │ - * all geometries that result from splitting the source geometry and
│ │ │ │ │ - * the second will be all geometries that result from splitting the
│ │ │ │ │ - * target geometry.
│ │ │ │ │ + * {DOMElement} The element that caused the event
│ │ │ │ │ */
│ │ │ │ │ - split: function(target, options) {
│ │ │ │ │ - var results = null;
│ │ │ │ │ - var mutual = options && options.mutual;
│ │ │ │ │ - var sourceSplit, targetSplit, sourceParts, targetParts;
│ │ │ │ │ - if (target instanceof OpenLayers.Geometry.LineString) {
│ │ │ │ │ - var verts = this.getVertices();
│ │ │ │ │ - var vert1, vert2, seg, splits, lines, point;
│ │ │ │ │ - var points = [];
│ │ │ │ │ - sourceParts = [];
│ │ │ │ │ - for (var i = 0, stop = verts.length - 2; i <= stop; ++i) {
│ │ │ │ │ - vert1 = verts[i];
│ │ │ │ │ - vert2 = verts[i + 1];
│ │ │ │ │ - seg = {
│ │ │ │ │ - x1: vert1.x,
│ │ │ │ │ - y1: vert1.y,
│ │ │ │ │ - x2: vert2.x,
│ │ │ │ │ - y2: vert2.y
│ │ │ │ │ - };
│ │ │ │ │ - targetParts = targetParts || [target];
│ │ │ │ │ - if (mutual) {
│ │ │ │ │ - points.push(vert1.clone());
│ │ │ │ │ - }
│ │ │ │ │ - for (var j = 0; j < targetParts.length; ++j) {
│ │ │ │ │ - splits = targetParts[j].splitWithSegment(seg, options);
│ │ │ │ │ - if (splits) {
│ │ │ │ │ - // splice in new features
│ │ │ │ │ - lines = splits.lines;
│ │ │ │ │ - if (lines.length > 0) {
│ │ │ │ │ - lines.unshift(j, 1);
│ │ │ │ │ - Array.prototype.splice.apply(targetParts, lines);
│ │ │ │ │ - j += lines.length - 2;
│ │ │ │ │ - }
│ │ │ │ │ - if (mutual) {
│ │ │ │ │ - for (var k = 0, len = splits.points.length; k < len; ++k) {
│ │ │ │ │ - point = splits.points[k];
│ │ │ │ │ - if (!point.equals(vert1)) {
│ │ │ │ │ - points.push(point);
│ │ │ │ │ - sourceParts.push(new OpenLayers.Geometry.LineString(points));
│ │ │ │ │ - if (point.equals(vert2)) {
│ │ │ │ │ - points = [];
│ │ │ │ │ - } else {
│ │ │ │ │ - points = [point.clone()];
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - if (mutual && sourceParts.length > 0 && points.length > 0) {
│ │ │ │ │ - points.push(vert2.clone());
│ │ │ │ │ - sourceParts.push(new OpenLayers.Geometry.LineString(points));
│ │ │ │ │ - }
│ │ │ │ │ - } else {
│ │ │ │ │ - results = target.splitWith(this, options);
│ │ │ │ │ - }
│ │ │ │ │ - if (targetParts && targetParts.length > 1) {
│ │ │ │ │ - targetSplit = true;
│ │ │ │ │ - } else {
│ │ │ │ │ - targetParts = [];
│ │ │ │ │ - }
│ │ │ │ │ - if (sourceParts && sourceParts.length > 1) {
│ │ │ │ │ - sourceSplit = true;
│ │ │ │ │ - } else {
│ │ │ │ │ - sourceParts = [];
│ │ │ │ │ - }
│ │ │ │ │ - if (targetSplit || sourceSplit) {
│ │ │ │ │ - if (mutual) {
│ │ │ │ │ - results = [sourceParts, targetParts];
│ │ │ │ │ - } else {
│ │ │ │ │ - results = targetParts;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return results;
│ │ │ │ │ + element: function(event) {
│ │ │ │ │ + return event.target || event.srcElement;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: splitWith
│ │ │ │ │ - * Split this geometry (the target) with the given geometry (the source).
│ │ │ │ │ + * Method: isSingleTouch
│ │ │ │ │ + * Determine whether event was caused by a single touch
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * geometry - {} A geometry used to split this
│ │ │ │ │ - * geometry (the source).
│ │ │ │ │ - * options - {Object} Properties of this object will be used to determine
│ │ │ │ │ - * how the split is conducted.
│ │ │ │ │ + * event - {Event}
│ │ │ │ │ *
│ │ │ │ │ - * Valid options:
│ │ │ │ │ - * mutual - {Boolean} Split the source geometry in addition to the target
│ │ │ │ │ - * geometry. Default is false.
│ │ │ │ │ - * edge - {Boolean} Allow splitting when only edges intersect. Default is
│ │ │ │ │ - * true. If false, a vertex on the source must be within the tolerance
│ │ │ │ │ - * distance of the intersection to be considered a split.
│ │ │ │ │ - * tolerance - {Number} If a non-null value is provided, intersections
│ │ │ │ │ - * within the tolerance distance of an existing vertex on the source
│ │ │ │ │ - * will be assumed to occur at the vertex.
│ │ │ │ │ - *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Array} A list of geometries (of this same type as the target) that
│ │ │ │ │ - * result from splitting the target with the source geometry. The
│ │ │ │ │ - * source and target geometry will remain unmodified. If no split
│ │ │ │ │ - * results, null will be returned. If mutual is true and a split
│ │ │ │ │ - * results, return will be an array of two arrays - the first will be
│ │ │ │ │ - * all geometries that result from splitting the source geometry and
│ │ │ │ │ - * the second will be all geometries that result from splitting the
│ │ │ │ │ - * target geometry.
│ │ │ │ │ + * {Boolean}
│ │ │ │ │ */
│ │ │ │ │ - splitWith: function(geometry, options) {
│ │ │ │ │ - return geometry.split(this, options);
│ │ │ │ │ -
│ │ │ │ │ + isSingleTouch: function(event) {
│ │ │ │ │ + return event.touches && event.touches.length == 1;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: getVertices
│ │ │ │ │ - * Return a list of all points in this geometry.
│ │ │ │ │ + * Method: isMultiTouch
│ │ │ │ │ + * Determine whether event was caused by a multi touch
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * 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.
│ │ │ │ │ + * event - {Event}
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Array} A list of all vertices in the geometry.
│ │ │ │ │ + * {Boolean}
│ │ │ │ │ */
│ │ │ │ │ - getVertices: function(nodes) {
│ │ │ │ │ - var vertices;
│ │ │ │ │ - if (nodes === true) {
│ │ │ │ │ - vertices = [
│ │ │ │ │ - this.components[0],
│ │ │ │ │ - this.components[this.components.length - 1]
│ │ │ │ │ - ];
│ │ │ │ │ - } else if (nodes === false) {
│ │ │ │ │ - vertices = this.components.slice(1, this.components.length - 1);
│ │ │ │ │ - } else {
│ │ │ │ │ - vertices = this.components.slice();
│ │ │ │ │ - }
│ │ │ │ │ - return vertices;
│ │ │ │ │ + isMultiTouch: function(event) {
│ │ │ │ │ + return event.touches && event.touches.length > 1;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: distanceTo
│ │ │ │ │ - * Calculate the closest distance between two geometries (on the x-y plane).
│ │ │ │ │ + * Method: isLeftClick
│ │ │ │ │ + * Determine whether event was caused by a left click.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * geometry - {} The target geometry.
│ │ │ │ │ - * options - {Object} Optional properties for configuring the distance
│ │ │ │ │ - * calculation.
│ │ │ │ │ - *
│ │ │ │ │ - * Valid options:
│ │ │ │ │ - * details - {Boolean} Return details from the distance calculation.
│ │ │ │ │ - * Default is false.
│ │ │ │ │ - * edge - {Boolean} Calculate the distance from this geometry to the
│ │ │ │ │ - * nearest edge of the target geometry. Default is true. If true,
│ │ │ │ │ - * calling distanceTo from a geometry that is wholly contained within
│ │ │ │ │ - * the target will result in a non-zero distance. If false, whenever
│ │ │ │ │ - * geometries intersect, calling distanceTo will return 0. If false,
│ │ │ │ │ - * details cannot be returned.
│ │ │ │ │ + * 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:
│ │ │ │ │ - * {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.
│ │ │ │ │ + * {Boolean}
│ │ │ │ │ */
│ │ │ │ │ - distanceTo: function(geometry, options) {
│ │ │ │ │ - var edge = !(options && options.edge === false);
│ │ │ │ │ - var details = edge && options && options.details;
│ │ │ │ │ - var result, best = {};
│ │ │ │ │ - var min = Number.POSITIVE_INFINITY;
│ │ │ │ │ - if (geometry instanceof OpenLayers.Geometry.Point) {
│ │ │ │ │ - var segs = this.getSortedSegments();
│ │ │ │ │ - var x = geometry.x;
│ │ │ │ │ - var y = geometry.y;
│ │ │ │ │ - var seg;
│ │ │ │ │ - for (var i = 0, len = segs.length; i < len; ++i) {
│ │ │ │ │ - seg = segs[i];
│ │ │ │ │ - result = OpenLayers.Geometry.distanceToSegment(geometry, seg);
│ │ │ │ │ - if (result.distance < min) {
│ │ │ │ │ - min = result.distance;
│ │ │ │ │ - best = result;
│ │ │ │ │ - if (min === 0) {
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - } else {
│ │ │ │ │ - // if distance increases and we cross y0 to the right of x0, no need to keep looking.
│ │ │ │ │ - if (seg.x2 > x && ((y > seg.y1 && y < seg.y2) || (y < seg.y1 && y > seg.y2))) {
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - if (details) {
│ │ │ │ │ - best = {
│ │ │ │ │ - distance: best.distance,
│ │ │ │ │ - x0: best.x,
│ │ │ │ │ - y0: best.y,
│ │ │ │ │ - x1: x,
│ │ │ │ │ - y1: y
│ │ │ │ │ - };
│ │ │ │ │ - } else {
│ │ │ │ │ - best = best.distance;
│ │ │ │ │ - }
│ │ │ │ │ - } else if (geometry instanceof OpenLayers.Geometry.LineString) {
│ │ │ │ │ - var segs0 = this.getSortedSegments();
│ │ │ │ │ - var segs1 = geometry.getSortedSegments();
│ │ │ │ │ - var seg0, seg1, intersection, x0, y0;
│ │ │ │ │ - var len1 = segs1.length;
│ │ │ │ │ - var interOptions = {
│ │ │ │ │ - point: true
│ │ │ │ │ - };
│ │ │ │ │ - outer: for (var i = 0, len = segs0.length; i < len; ++i) {
│ │ │ │ │ - seg0 = segs0[i];
│ │ │ │ │ - x0 = seg0.x1;
│ │ │ │ │ - y0 = seg0.y1;
│ │ │ │ │ - for (var j = 0; j < len1; ++j) {
│ │ │ │ │ - seg1 = segs1[j];
│ │ │ │ │ - intersection = OpenLayers.Geometry.segmentsIntersect(seg0, seg1, interOptions);
│ │ │ │ │ - if (intersection) {
│ │ │ │ │ - min = 0;
│ │ │ │ │ - best = {
│ │ │ │ │ - distance: 0,
│ │ │ │ │ - x0: intersection.x,
│ │ │ │ │ - y0: intersection.y,
│ │ │ │ │ - x1: intersection.x,
│ │ │ │ │ - y1: intersection.y
│ │ │ │ │ - };
│ │ │ │ │ - break outer;
│ │ │ │ │ - } else {
│ │ │ │ │ - result = OpenLayers.Geometry.distanceToSegment({
│ │ │ │ │ - x: x0,
│ │ │ │ │ - y: y0
│ │ │ │ │ - }, seg1);
│ │ │ │ │ - if (result.distance < min) {
│ │ │ │ │ - min = result.distance;
│ │ │ │ │ - best = {
│ │ │ │ │ - distance: min,
│ │ │ │ │ - x0: x0,
│ │ │ │ │ - y0: y0,
│ │ │ │ │ - x1: result.x,
│ │ │ │ │ - y1: result.y
│ │ │ │ │ - };
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - if (!details) {
│ │ │ │ │ - best = best.distance;
│ │ │ │ │ - }
│ │ │ │ │ - if (min !== 0) {
│ │ │ │ │ - // check the final vertex in this line's sorted segments
│ │ │ │ │ - if (seg0) {
│ │ │ │ │ - result = geometry.distanceTo(
│ │ │ │ │ - new OpenLayers.Geometry.Point(seg0.x2, seg0.y2),
│ │ │ │ │ - options
│ │ │ │ │ - );
│ │ │ │ │ - var dist = details ? result.distance : result;
│ │ │ │ │ - if (dist < min) {
│ │ │ │ │ - if (details) {
│ │ │ │ │ - best = {
│ │ │ │ │ - distance: min,
│ │ │ │ │ - x0: result.x1,
│ │ │ │ │ - y0: result.y1,
│ │ │ │ │ - x1: result.x0,
│ │ │ │ │ - y1: result.y0
│ │ │ │ │ - };
│ │ │ │ │ - } else {
│ │ │ │ │ - best = dist;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ + 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 {
│ │ │ │ │ - best = geometry.distanceTo(this, options);
│ │ │ │ │ - // swap since target comes from this line
│ │ │ │ │ - if (details) {
│ │ │ │ │ - best = {
│ │ │ │ │ - distance: best.distance,
│ │ │ │ │ - x0: best.x1,
│ │ │ │ │ - y0: best.y1,
│ │ │ │ │ - x1: best.x0,
│ │ │ │ │ - y1: best.y0
│ │ │ │ │ - };
│ │ │ │ │ - }
│ │ │ │ │ + event.cancelBubble = true;
│ │ │ │ │ }
│ │ │ │ │ - return best;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: simplify
│ │ │ │ │ - * This function will return a simplified LineString.
│ │ │ │ │ - * Simplification is based on the Douglas-Peucker algorithm.
│ │ │ │ │ - *
│ │ │ │ │ + * Method: preventDefault
│ │ │ │ │ + * Cancels the event if it is cancelable, without stopping further
│ │ │ │ │ + * propagation of the event.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * tolerance - {number} threshhold for simplification in map units
│ │ │ │ │ - *
│ │ │ │ │ + * event - {Event}
│ │ │ │ │ + */
│ │ │ │ │ + preventDefault: function(event) {
│ │ │ │ │ + if (event.preventDefault) {
│ │ │ │ │ + event.preventDefault();
│ │ │ │ │ + } else {
│ │ │ │ │ + event.returnValue = false;
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │ +
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: findElement
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * event - {Event}
│ │ │ │ │ + * tagName - {String}
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {OpenLayers.Geometry.LineString} the simplified LineString
│ │ │ │ │ + * {DOMElement} The first node with the given tagName, starting from the
│ │ │ │ │ + * node the event was triggered on and traversing the DOM upwards
│ │ │ │ │ */
│ │ │ │ │ - simplify: function(tolerance) {
│ │ │ │ │ - if (this && this !== null) {
│ │ │ │ │ - var points = this.getVertices();
│ │ │ │ │ - if (points.length < 3) {
│ │ │ │ │ - return this;
│ │ │ │ │ + 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 compareNumbers = function(a, b) {
│ │ │ │ │ - return (a - b);
│ │ │ │ │ - };
│ │ │ │ │ + var cacheID = element._eventCacheID;
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Private function doing the Douglas-Peucker reduction
│ │ │ │ │ - */
│ │ │ │ │ - var douglasPeuckerReduction = function(points, firstPoint, lastPoint, tolerance) {
│ │ │ │ │ - var maxDistance = 0;
│ │ │ │ │ - var indexFarthest = 0;
│ │ │ │ │ + //if there is not yet a hash entry for this element, add one
│ │ │ │ │ + if (!this.observers[cacheID]) {
│ │ │ │ │ + this.observers[cacheID] = [];
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - for (var index = firstPoint, distance; index < lastPoint; index++) {
│ │ │ │ │ - distance = perpendicularDistance(points[firstPoint], points[lastPoint], points[index]);
│ │ │ │ │ - if (distance > maxDistance) {
│ │ │ │ │ - maxDistance = distance;
│ │ │ │ │ - indexFarthest = index;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ + //add a new observer to this element's list
│ │ │ │ │ + this.observers[cacheID].push({
│ │ │ │ │ + 'element': element,
│ │ │ │ │ + 'name': name,
│ │ │ │ │ + 'observer': observer,
│ │ │ │ │ + 'useCapture': useCapture
│ │ │ │ │ + });
│ │ │ │ │
│ │ │ │ │ - if (maxDistance > tolerance && indexFarthest != firstPoint) {
│ │ │ │ │ - //Add the largest point that exceeds the tolerance
│ │ │ │ │ - pointIndexsToKeep.push(indexFarthest);
│ │ │ │ │ - douglasPeuckerReduction(points, firstPoint, indexFarthest, tolerance);
│ │ │ │ │ - douglasPeuckerReduction(points, indexFarthest, lastPoint, tolerance);
│ │ │ │ │ - }
│ │ │ │ │ - };
│ │ │ │ │ + //add the actual browser event listener
│ │ │ │ │ + if (element.addEventListener) {
│ │ │ │ │ + element.addEventListener(name, observer, useCapture);
│ │ │ │ │ + } else if (element.attachEvent) {
│ │ │ │ │ + element.attachEvent('on' + name, observer);
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Private function calculating the perpendicular distance
│ │ │ │ │ - * TODO: check whether OpenLayers.Geometry.LineString::distanceTo() is faster or slower
│ │ │ │ │ - */
│ │ │ │ │ - var perpendicularDistance = function(point1, point2, point) {
│ │ │ │ │ - //Area = |(1/2)(x1y2 + x2y3 + x3y1 - x2y1 - x3y2 - x1y3)| *Area of triangle
│ │ │ │ │ - //Base = v((x1-x2)²+(x1-x2)²) *Base of Triangle*
│ │ │ │ │ - //Area = .5*Base*H *Solve for height
│ │ │ │ │ - //Height = Area/.5/Base
│ │ │ │ │ + /**
│ │ │ │ │ + * 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;
│ │ │ │ │
│ │ │ │ │ - var area = Math.abs(0.5 * (point1.x * point2.y + point2.x * point.y + point.x * point1.y - point2.x * point1.y - point.x * point2.y - point1.x * point.y));
│ │ │ │ │ - var bottom = Math.sqrt(Math.pow(point1.x - point2.x, 2) + Math.pow(point1.y - point2.y, 2));
│ │ │ │ │ - var height = area / bottom * 2;
│ │ │ │ │ + this._removeElementObservers(OpenLayers.Event.observers[cacheID]);
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - return height;
│ │ │ │ │ - };
│ │ │ │ │ + /**
│ │ │ │ │ + * 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
│ │ │ │ │ + ]);
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - var firstPoint = 0;
│ │ │ │ │ - var lastPoint = points.length - 1;
│ │ │ │ │ - var pointIndexsToKeep = [];
│ │ │ │ │ + /**
│ │ │ │ │ + * 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;
│ │ │ │ │
│ │ │ │ │ - //Add the first and last index to the keepers
│ │ │ │ │ - pointIndexsToKeep.push(firstPoint);
│ │ │ │ │ - pointIndexsToKeep.push(lastPoint);
│ │ │ │ │ + var element = OpenLayers.Util.getElement(elementParam);
│ │ │ │ │ + var cacheID = element._eventCacheID;
│ │ │ │ │
│ │ │ │ │ - //The first and the last point cannot be the same
│ │ │ │ │ - while (points[firstPoint].equals(points[lastPoint])) {
│ │ │ │ │ - lastPoint--;
│ │ │ │ │ - //Addition: the first point not equal to first point in the LineString is kept as well
│ │ │ │ │ - pointIndexsToKeep.push(lastPoint);
│ │ │ │ │ + if (name == 'keypress') {
│ │ │ │ │ + if (navigator.appVersion.match(/Konqueror|Safari|KHTML/) ||
│ │ │ │ │ + element.detachEvent) {
│ │ │ │ │ + name = 'keydown';
│ │ │ │ │ }
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - douglasPeuckerReduction(points, firstPoint, lastPoint, tolerance);
│ │ │ │ │ - var returnPoints = [];
│ │ │ │ │ - pointIndexsToKeep.sort(compareNumbers);
│ │ │ │ │ - for (var index = 0; index < pointIndexsToKeep.length; index++) {
│ │ │ │ │ - returnPoints.push(points[pointIndexsToKeep[index]]);
│ │ │ │ │ + // 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++;
│ │ │ │ │ }
│ │ │ │ │ - return new OpenLayers.Geometry.LineString(returnPoints);
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - } else {
│ │ │ │ │ - return this;
│ │ │ │ │ + //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;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Geometry.LineString"
│ │ │ │ │ -});
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Geometry/MultiLineString.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ + /**
│ │ │ │ │ + * 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;
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ -/* 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. */
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Event"
│ │ │ │ │ +};
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/Geometry/Collection.js
│ │ │ │ │ - * @requires OpenLayers/Geometry/LineString.js
│ │ │ │ │ - */
│ │ │ │ │ +/* prevent memory leaks in IE */
│ │ │ │ │ +OpenLayers.Event.observe(window, 'unload', OpenLayers.Event.unloadCache, false);
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Class: OpenLayers.Geometry.MultiLineString
│ │ │ │ │ - * A MultiLineString is a geometry with multiple
│ │ │ │ │ - * components.
│ │ │ │ │ - *
│ │ │ │ │ - * Inherits from:
│ │ │ │ │ - * -
│ │ │ │ │ - * -
│ │ │ │ │ + * Class: OpenLayers.Events
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Geometry.MultiLineString = OpenLayers.Class(
│ │ │ │ │ - OpenLayers.Geometry.Collection, {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: componentTypes
│ │ │ │ │ - * {Array(String)} An array of class names representing the types of
│ │ │ │ │ - * components that the collection can include. A null value means the
│ │ │ │ │ - * component types are not restricted.
│ │ │ │ │ - */
│ │ │ │ │ - componentTypes: ["OpenLayers.Geometry.LineString"],
│ │ │ │ │ +OpenLayers.Events = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Geometry.MultiLineString
│ │ │ │ │ - * Constructor for a MultiLineString Geometry.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * components - {Array()}
│ │ │ │ │ - *
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: split
│ │ │ │ │ - * Use this geometry (the source) to attempt to split a target geometry.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * geometry - {} The target geometry.
│ │ │ │ │ - * options - {Object} Properties of this object will be used to determine
│ │ │ │ │ - * how the split is conducted.
│ │ │ │ │ - *
│ │ │ │ │ - * Valid options:
│ │ │ │ │ - * mutual - {Boolean} Split the source geometry in addition to the target
│ │ │ │ │ - * geometry. Default is false.
│ │ │ │ │ - * edge - {Boolean} Allow splitting when only edges intersect. Default is
│ │ │ │ │ - * true. If false, a vertex on the source must be within the tolerance
│ │ │ │ │ - * distance of the intersection to be considered a split.
│ │ │ │ │ - * tolerance - {Number} If a non-null value is provided, intersections
│ │ │ │ │ - * within the tolerance distance of an existing vertex on the source
│ │ │ │ │ - * will be assumed to occur at the vertex.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Array} A list of geometries (of this same type as the target) that
│ │ │ │ │ - * result from splitting the target with the source geometry. The
│ │ │ │ │ - * source and target geometry will remain unmodified. If no split
│ │ │ │ │ - * results, null will be returned. If mutual is true and a split
│ │ │ │ │ - * results, return will be an array of two arrays - the first will be
│ │ │ │ │ - * all geometries that result from splitting the source geometry and
│ │ │ │ │ - * the second will be all geometries that result from splitting the
│ │ │ │ │ - * target geometry.
│ │ │ │ │ - */
│ │ │ │ │ - split: function(geometry, options) {
│ │ │ │ │ - var results = null;
│ │ │ │ │ - var mutual = options && options.mutual;
│ │ │ │ │ - var splits, sourceLine, sourceLines, sourceSplit, targetSplit;
│ │ │ │ │ - var sourceParts = [];
│ │ │ │ │ - var targetParts = [geometry];
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len; ++i) {
│ │ │ │ │ - sourceLine = this.components[i];
│ │ │ │ │ - sourceSplit = false;
│ │ │ │ │ - for (var j = 0; j < targetParts.length; ++j) {
│ │ │ │ │ - splits = sourceLine.split(targetParts[j], options);
│ │ │ │ │ - if (splits) {
│ │ │ │ │ - if (mutual) {
│ │ │ │ │ - sourceLines = splits[0];
│ │ │ │ │ - for (var k = 0, klen = sourceLines.length; k < klen; ++k) {
│ │ │ │ │ - if (k === 0 && sourceParts.length) {
│ │ │ │ │ - sourceParts[sourceParts.length - 1].addComponent(
│ │ │ │ │ - sourceLines[k]
│ │ │ │ │ - );
│ │ │ │ │ - } else {
│ │ │ │ │ - sourceParts.push(
│ │ │ │ │ - new OpenLayers.Geometry.MultiLineString([
│ │ │ │ │ - sourceLines[k]
│ │ │ │ │ - ])
│ │ │ │ │ - );
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - sourceSplit = true;
│ │ │ │ │ - splits = splits[1];
│ │ │ │ │ - }
│ │ │ │ │ - if (splits.length) {
│ │ │ │ │ - // splice in new target parts
│ │ │ │ │ - splits.unshift(j, 1);
│ │ │ │ │ - Array.prototype.splice.apply(targetParts, splits);
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - if (!sourceSplit) {
│ │ │ │ │ - // source line was not hit
│ │ │ │ │ - if (sourceParts.length) {
│ │ │ │ │ - // add line to existing multi
│ │ │ │ │ - sourceParts[sourceParts.length - 1].addComponent(
│ │ │ │ │ - sourceLine.clone()
│ │ │ │ │ - );
│ │ │ │ │ - } else {
│ │ │ │ │ - // create a fresh multi
│ │ │ │ │ - sourceParts = [
│ │ │ │ │ - new OpenLayers.Geometry.MultiLineString(
│ │ │ │ │ - sourceLine.clone()
│ │ │ │ │ - )
│ │ │ │ │ - ];
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - if (sourceParts && sourceParts.length > 1) {
│ │ │ │ │ - sourceSplit = true;
│ │ │ │ │ - } else {
│ │ │ │ │ - sourceParts = [];
│ │ │ │ │ - }
│ │ │ │ │ - if (targetParts && targetParts.length > 1) {
│ │ │ │ │ - targetSplit = true;
│ │ │ │ │ - } else {
│ │ │ │ │ - targetParts = [];
│ │ │ │ │ - }
│ │ │ │ │ - if (sourceSplit || targetSplit) {
│ │ │ │ │ - if (mutual) {
│ │ │ │ │ - results = [sourceParts, targetParts];
│ │ │ │ │ - } else {
│ │ │ │ │ - results = targetParts;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return results;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: splitWith
│ │ │ │ │ - * Split this geometry (the target) with the given geometry (the source).
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * geometry - {} A geometry used to split this
│ │ │ │ │ - * geometry (the source).
│ │ │ │ │ - * options - {Object} Properties of this object will be used to determine
│ │ │ │ │ - * how the split is conducted.
│ │ │ │ │ - *
│ │ │ │ │ - * Valid options:
│ │ │ │ │ - * mutual - {Boolean} Split the source geometry in addition to the target
│ │ │ │ │ - * geometry. Default is false.
│ │ │ │ │ - * edge - {Boolean} Allow splitting when only edges intersect. Default is
│ │ │ │ │ - * true. If false, a vertex on the source must be within the tolerance
│ │ │ │ │ - * distance of the intersection to be considered a split.
│ │ │ │ │ - * tolerance - {Number} If a non-null value is provided, intersections
│ │ │ │ │ - * within the tolerance distance of an existing vertex on the source
│ │ │ │ │ - * will be assumed to occur at the vertex.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Array} A list of geometries (of this same type as the target) that
│ │ │ │ │ - * result from splitting the target with the source geometry. The
│ │ │ │ │ - * source and target geometry will remain unmodified. If no split
│ │ │ │ │ - * results, null will be returned. If mutual is true and a split
│ │ │ │ │ - * results, return will be an array of two arrays - the first will be
│ │ │ │ │ - * all geometries that result from splitting the source geometry and
│ │ │ │ │ - * the second will be all geometries that result from splitting the
│ │ │ │ │ - * target geometry.
│ │ │ │ │ - */
│ │ │ │ │ - splitWith: function(geometry, options) {
│ │ │ │ │ - var results = null;
│ │ │ │ │ - var mutual = options && options.mutual;
│ │ │ │ │ - var splits, targetLine, sourceLines, sourceSplit, targetSplit, sourceParts, targetParts;
│ │ │ │ │ - if (geometry instanceof OpenLayers.Geometry.LineString) {
│ │ │ │ │ - targetParts = [];
│ │ │ │ │ - sourceParts = [geometry];
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len; ++i) {
│ │ │ │ │ - targetSplit = false;
│ │ │ │ │ - targetLine = this.components[i];
│ │ │ │ │ - for (var j = 0; j < sourceParts.length; ++j) {
│ │ │ │ │ - splits = sourceParts[j].split(targetLine, options);
│ │ │ │ │ - if (splits) {
│ │ │ │ │ - if (mutual) {
│ │ │ │ │ - sourceLines = splits[0];
│ │ │ │ │ - if (sourceLines.length) {
│ │ │ │ │ - // splice in new source parts
│ │ │ │ │ - sourceLines.unshift(j, 1);
│ │ │ │ │ - Array.prototype.splice.apply(sourceParts, sourceLines);
│ │ │ │ │ - j += sourceLines.length - 2;
│ │ │ │ │ - }
│ │ │ │ │ - splits = splits[1];
│ │ │ │ │ - if (splits.length === 0) {
│ │ │ │ │ - splits = [targetLine.clone()];
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - for (var k = 0, klen = splits.length; k < klen; ++k) {
│ │ │ │ │ - if (k === 0 && targetParts.length) {
│ │ │ │ │ - targetParts[targetParts.length - 1].addComponent(
│ │ │ │ │ - splits[k]
│ │ │ │ │ - );
│ │ │ │ │ - } else {
│ │ │ │ │ - targetParts.push(
│ │ │ │ │ - new OpenLayers.Geometry.MultiLineString([
│ │ │ │ │ - splits[k]
│ │ │ │ │ - ])
│ │ │ │ │ - );
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - targetSplit = true;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - if (!targetSplit) {
│ │ │ │ │ - // target component was not hit
│ │ │ │ │ - if (targetParts.length) {
│ │ │ │ │ - // add it to any existing multi-line
│ │ │ │ │ - targetParts[targetParts.length - 1].addComponent(
│ │ │ │ │ - targetLine.clone()
│ │ │ │ │ - );
│ │ │ │ │ - } else {
│ │ │ │ │ - // or start with a fresh multi-line
│ │ │ │ │ - targetParts = [
│ │ │ │ │ - new OpenLayers.Geometry.MultiLineString([
│ │ │ │ │ - targetLine.clone()
│ │ │ │ │ - ])
│ │ │ │ │ - ];
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - } else {
│ │ │ │ │ - results = geometry.split(this);
│ │ │ │ │ - }
│ │ │ │ │ - if (sourceParts && sourceParts.length > 1) {
│ │ │ │ │ - sourceSplit = true;
│ │ │ │ │ - } else {
│ │ │ │ │ - sourceParts = [];
│ │ │ │ │ - }
│ │ │ │ │ - if (targetParts && targetParts.length > 1) {
│ │ │ │ │ - targetSplit = true;
│ │ │ │ │ - } else {
│ │ │ │ │ - targetParts = [];
│ │ │ │ │ - }
│ │ │ │ │ - if (sourceSplit || targetSplit) {
│ │ │ │ │ - if (mutual) {
│ │ │ │ │ - results = [sourceParts, targetParts];
│ │ │ │ │ - } else {
│ │ │ │ │ - results = targetParts;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return results;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Geometry.MultiLineString"
│ │ │ │ │ - });
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Geometry/LinearRing.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ + /**
│ │ │ │ │ + * 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"
│ │ │ │ │ + ],
│ │ │ │ │
│ │ │ │ │ -/* 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. */
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: listeners
│ │ │ │ │ + * {Object} Hashtable of Array(Function): events listener functions
│ │ │ │ │ + */
│ │ │ │ │ + listeners: null,
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/Geometry/LineString.js
│ │ │ │ │ - */
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: object
│ │ │ │ │ + * {Object} the code object issuing application events
│ │ │ │ │ + */
│ │ │ │ │ + object: null,
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Geometry.LinearRing
│ │ │ │ │ - *
│ │ │ │ │ - * A Linear Ring is a special LineString which is closed. It closes itself
│ │ │ │ │ - * automatically on every addPoint/removePoint by adding a copy of the first
│ │ │ │ │ - * point as the last point.
│ │ │ │ │ - *
│ │ │ │ │ - * Also, as it is the first in the line family to close itself, a getArea()
│ │ │ │ │ - * function is defined to calculate the enclosed area of the linearRing
│ │ │ │ │ - *
│ │ │ │ │ - * Inherits:
│ │ │ │ │ - * -
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Geometry.LinearRing = OpenLayers.Class(
│ │ │ │ │ - OpenLayers.Geometry.LineString, {
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: element
│ │ │ │ │ + * {DOMElement} the DOM element receiving browser events
│ │ │ │ │ + */
│ │ │ │ │ + element: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: componentTypes
│ │ │ │ │ - * {Array(String)} An array of class names representing the types of
│ │ │ │ │ - * components that the collection can include. A null
│ │ │ │ │ - * value means the component types are not restricted.
│ │ │ │ │ - */
│ │ │ │ │ - componentTypes: ["OpenLayers.Geometry.Point"],
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: eventHandler
│ │ │ │ │ + * {Function} bound event handler attached to elements
│ │ │ │ │ + */
│ │ │ │ │ + eventHandler: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Geometry.LinearRing
│ │ │ │ │ - * Linear rings are constructed with an array of points. This array
│ │ │ │ │ - * can represent a closed or open ring. If the ring is open (the last
│ │ │ │ │ - * point does not equal the first point), the constructor will close
│ │ │ │ │ - * the ring. If the ring is already closed (the last point does equal
│ │ │ │ │ - * the first point), it will be left closed.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * points - {Array()} points
│ │ │ │ │ - */
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: fallThrough
│ │ │ │ │ + * {Boolean}
│ │ │ │ │ + */
│ │ │ │ │ + fallThrough: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: addComponent
│ │ │ │ │ - * Adds a point to geometry components. If the point is to be added to
│ │ │ │ │ - * the end of the components array and it is the same as the last point
│ │ │ │ │ - * already in that array, the duplicate point is not added. This has
│ │ │ │ │ - * the effect of closing the ring if it is not already closed, and
│ │ │ │ │ - * doing the right thing if it is already closed. This behavior can
│ │ │ │ │ - * be overridden by calling the method with a non-null index as the
│ │ │ │ │ - * second argument.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * point - {}
│ │ │ │ │ - * index - {Integer} Index into the array to insert the component
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} Was the Point successfully added?
│ │ │ │ │ - */
│ │ │ │ │ - addComponent: function(point, index) {
│ │ │ │ │ - var added = false;
│ │ │ │ │ + /**
│ │ │ │ │ + * 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,
│ │ │ │ │
│ │ │ │ │ - //remove last point
│ │ │ │ │ - var lastPoint = this.components.pop();
│ │ │ │ │ + /**
│ │ │ │ │ + * 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,
│ │ │ │ │
│ │ │ │ │ - // given an index, add the point
│ │ │ │ │ - // without an index only add non-duplicate points
│ │ │ │ │ - if (index != null || !point.equals(lastPoint)) {
│ │ │ │ │ - added = OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,
│ │ │ │ │ - arguments);
│ │ │ │ │ - }
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: extensionCount
│ │ │ │ │ + * {Object} Keys are event types (like in ), values are the
│ │ │ │ │ + * number of extension listeners for each event type.
│ │ │ │ │ + */
│ │ │ │ │ + extensionCount: null,
│ │ │ │ │
│ │ │ │ │ - //append copy of first point
│ │ │ │ │ - var firstPoint = this.components[0];
│ │ │ │ │ - OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,
│ │ │ │ │ - [firstPoint]);
│ │ │ │ │ + /**
│ │ │ │ │ + * Method: clearMouseListener
│ │ │ │ │ + * A version of that is bound to this instance so that
│ │ │ │ │ + * it can be used with and
│ │ │ │ │ + * .
│ │ │ │ │ + */
│ │ │ │ │ + clearMouseListener: null,
│ │ │ │ │
│ │ │ │ │ - return added;
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * 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 = [];
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: removeComponent
│ │ │ │ │ - * Removes a point from geometry components.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * point - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} The component was removed.
│ │ │ │ │ - */
│ │ │ │ │ - removeComponent: function(point) {
│ │ │ │ │ - var removed = this.components && (this.components.length > 3);
│ │ │ │ │ - if (removed) {
│ │ │ │ │ - //remove last point
│ │ │ │ │ - this.components.pop();
│ │ │ │ │ + // 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);
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - //remove our point
│ │ │ │ │ - OpenLayers.Geometry.Collection.prototype.removeComponent.apply(this,
│ │ │ │ │ - arguments);
│ │ │ │ │ - //append copy of first point
│ │ │ │ │ - var firstPoint = this.components[0];
│ │ │ │ │ - OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,
│ │ │ │ │ - [firstPoint]);
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: destroy
│ │ │ │ │ + */
│ │ │ │ │ + destroy: function() {
│ │ │ │ │ + for (var e in this.extensions) {
│ │ │ │ │ + if (typeof this.extensions[e] !== "boolean") {
│ │ │ │ │ + this.extensions[e].destroy();
│ │ │ │ │ }
│ │ │ │ │ - return removed;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: move
│ │ │ │ │ - * Moves a geometry by the given displacement along positive x and y axes.
│ │ │ │ │ - * This modifies the position of the geometry and clears the cached
│ │ │ │ │ - * bounds.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * x - {Float} Distance to move geometry in positive x direction.
│ │ │ │ │ - * y - {Float} Distance to move geometry in positive y direction.
│ │ │ │ │ - */
│ │ │ │ │ - move: function(x, y) {
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len - 1; i++) {
│ │ │ │ │ - this.components[i].move(x, y);
│ │ │ │ │ + }
│ │ │ │ │ + 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;
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: rotate
│ │ │ │ │ - * Rotate a geometry around some origin
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * angle - {Float} Rotation angle in degrees (measured counterclockwise
│ │ │ │ │ - * from the positive x-axis)
│ │ │ │ │ - * origin - {} Center point for the rotation
│ │ │ │ │ - */
│ │ │ │ │ - rotate: function(angle, origin) {
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len - 1; ++i) {
│ │ │ │ │ - this.components[i].rotate(angle, origin);
│ │ │ │ │ - }
│ │ │ │ │ - },
│ │ │ │ │ + this.listeners = null;
│ │ │ │ │ + this.object = null;
│ │ │ │ │ + this.fallThrough = null;
│ │ │ │ │ + this.eventHandler = null;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: resize
│ │ │ │ │ - * Resize a geometry relative to some origin. Use this method to apply
│ │ │ │ │ - * a uniform scaling to a geometry.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * scale - {Float} Factor by which to scale the geometry. A scale of 2
│ │ │ │ │ - * doubles the size of the geometry in each dimension
│ │ │ │ │ - * (lines, for example, will be twice as long, and polygons
│ │ │ │ │ - * will have four times the area).
│ │ │ │ │ - * origin - {} Point of origin for resizing
│ │ │ │ │ - * ratio - {Float} Optional x:y ratio for resizing. Default ratio is 1.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} - The current geometry.
│ │ │ │ │ - */
│ │ │ │ │ - resize: function(scale, origin, ratio) {
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len - 1; ++i) {
│ │ │ │ │ - this.components[i].resize(scale, origin, ratio);
│ │ │ │ │ - }
│ │ │ │ │ - return this;
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * APIMethod: addEventType
│ │ │ │ │ + * Deprecated. Any event can be triggered without adding it first.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * eventName - {String}
│ │ │ │ │ + */
│ │ │ │ │ + addEventType: function(eventName) {},
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: transform
│ │ │ │ │ - * Reproject the components geometry from source to dest.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * source - {}
│ │ │ │ │ - * dest - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {}
│ │ │ │ │ - */
│ │ │ │ │ - transform: function(source, dest) {
│ │ │ │ │ - if (source && dest) {
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len - 1; i++) {
│ │ │ │ │ - var component = this.components[i];
│ │ │ │ │ - component.transform(source, dest);
│ │ │ │ │ - }
│ │ │ │ │ - this.bounds = null;
│ │ │ │ │ - }
│ │ │ │ │ - return this;
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * 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
│ │ │ │ │ + );
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: getCentroid
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} The centroid of the collection
│ │ │ │ │ - */
│ │ │ │ │ - getCentroid: function() {
│ │ │ │ │ - if (this.components) {
│ │ │ │ │ - var len = this.components.length;
│ │ │ │ │ - if (len > 0 && len <= 2) {
│ │ │ │ │ - return this.components[0].clone();
│ │ │ │ │ - } else if (len > 2) {
│ │ │ │ │ - var sumX = 0.0;
│ │ │ │ │ - var sumY = 0.0;
│ │ │ │ │ - var x0 = this.components[0].x;
│ │ │ │ │ - var y0 = this.components[0].y;
│ │ │ │ │ - var area = -1 * this.getArea();
│ │ │ │ │ - if (area != 0) {
│ │ │ │ │ - for (var i = 0; i < len - 1; i++) {
│ │ │ │ │ - var b = this.components[i];
│ │ │ │ │ - var c = this.components[i + 1];
│ │ │ │ │ - sumX += (b.x + c.x - 2 * x0) * ((b.x - x0) * (c.y - y0) - (c.x - x0) * (b.y - y0));
│ │ │ │ │ - sumY += (b.y + c.y - 2 * y0) * ((b.x - x0) * (c.y - y0) - (c.x - x0) * (b.y - y0));
│ │ │ │ │ - }
│ │ │ │ │ - var x = x0 + sumX / (6 * area);
│ │ │ │ │ - var y = y0 + sumY / (6 * area);
│ │ │ │ │ - } else {
│ │ │ │ │ - for (var i = 0; i < len - 1; i++) {
│ │ │ │ │ - sumX += this.components[i].x;
│ │ │ │ │ - sumY += this.components[i].y;
│ │ │ │ │ - }
│ │ │ │ │ - var x = sumX / (len - 1);
│ │ │ │ │ - var y = sumY / (len - 1);
│ │ │ │ │ - }
│ │ │ │ │ - return new OpenLayers.Geometry.Point(x, y);
│ │ │ │ │ - } else {
│ │ │ │ │ - return null;
│ │ │ │ │ - }
│ │ │ │ │ + // 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: getArea
│ │ │ │ │ - * Note - The area is positive if the ring is oriented CW, otherwise
│ │ │ │ │ - * it will be negative.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Float} The signed area for a ring.
│ │ │ │ │ - */
│ │ │ │ │ - getArea: function() {
│ │ │ │ │ - var area = 0.0;
│ │ │ │ │ - if (this.components && (this.components.length > 2)) {
│ │ │ │ │ - var sum = 0.0;
│ │ │ │ │ - for (var i = 0, len = this.components.length; i < len - 1; i++) {
│ │ │ │ │ - var b = this.components[i];
│ │ │ │ │ - var c = this.components[i + 1];
│ │ │ │ │ - sum += (b.x + c.x) * (c.y - b.y);
│ │ │ │ │ - }
│ │ │ │ │ - area = -sum / 2.0;
│ │ │ │ │ + /**
│ │ │ │ │ + * 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]);
│ │ │ │ │ }
│ │ │ │ │ - return area;
│ │ │ │ │ - },
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: getGeodesicArea
│ │ │ │ │ - * Calculate the approximate area of the polygon were it projected onto
│ │ │ │ │ - * the earth. Note that this area will be positive if ring is oriented
│ │ │ │ │ - * clockwise, otherwise it will be negative.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * projection - {} The spatial reference system
│ │ │ │ │ - * for the geometry coordinates. If not provided, Geographic/WGS84 is
│ │ │ │ │ - * assumed.
│ │ │ │ │ - *
│ │ │ │ │ - * Reference:
│ │ │ │ │ - * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for
│ │ │ │ │ - * Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion
│ │ │ │ │ - * Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {float} The approximate signed geodesic area of the polygon in square
│ │ │ │ │ - * meters.
│ │ │ │ │ - */
│ │ │ │ │ - getGeodesicArea: function(projection) {
│ │ │ │ │ - var ring = this; // so we can work with a clone if needed
│ │ │ │ │ - if (projection) {
│ │ │ │ │ - var gg = new OpenLayers.Projection("EPSG:4326");
│ │ │ │ │ - if (!gg.equals(projection)) {
│ │ │ │ │ - ring = this.clone().transform(projection, gg);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - var area = 0.0;
│ │ │ │ │ - var len = ring.components && ring.components.length;
│ │ │ │ │ - if (len > 2) {
│ │ │ │ │ - var p1, p2;
│ │ │ │ │ - for (var i = 0; i < len - 1; i++) {
│ │ │ │ │ - p1 = ring.components[i];
│ │ │ │ │ - p2 = ring.components[i + 1];
│ │ │ │ │ - area += OpenLayers.Util.rad(p2.x - p1.x) *
│ │ │ │ │ - (2 + Math.sin(OpenLayers.Util.rad(p1.y)) +
│ │ │ │ │ - Math.sin(OpenLayers.Util.rad(p2.y)));
│ │ │ │ │ - }
│ │ │ │ │ - area = area * 6378137.0 * 6378137.0 / 2.0;
│ │ │ │ │ + /**
│ │ │ │ │ + * 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;
│ │ │ │ │ }
│ │ │ │ │ - return area;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: containsPoint
│ │ │ │ │ - * Test if a point is inside a linear ring. For the case where a point
│ │ │ │ │ - * is coincident with a linear ring edge, returns 1. Otherwise,
│ │ │ │ │ - * returns boolean.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * point - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean | Number} The point is inside the linear ring. Returns 1 if
│ │ │ │ │ - * the point is coincident with an edge. Returns boolean otherwise.
│ │ │ │ │ - */
│ │ │ │ │ - containsPoint: function(point) {
│ │ │ │ │ - var approx = OpenLayers.Number.limitSigDigs;
│ │ │ │ │ - var digs = 14;
│ │ │ │ │ - var px = approx(point.x, digs);
│ │ │ │ │ - var py = approx(point.y, digs);
│ │ │ │ │ -
│ │ │ │ │ - function getX(y, x1, y1, x2, y2) {
│ │ │ │ │ - return (y - y2) * ((x2 - x1) / (y2 - y1)) + x2;
│ │ │ │ │ + var listeners = this.listeners[type];
│ │ │ │ │ + if (!listeners) {
│ │ │ │ │ + listeners = [];
│ │ │ │ │ + this.listeners[type] = listeners;
│ │ │ │ │ + this.extensionCount[type] = 0;
│ │ │ │ │ }
│ │ │ │ │ - var numSeg = this.components.length - 1;
│ │ │ │ │ - var start, end, x1, y1, x2, y2, cx, cy;
│ │ │ │ │ - var crosses = 0;
│ │ │ │ │ - for (var i = 0; i < numSeg; ++i) {
│ │ │ │ │ - start = this.components[i];
│ │ │ │ │ - x1 = approx(start.x, digs);
│ │ │ │ │ - y1 = approx(start.y, digs);
│ │ │ │ │ - end = this.components[i + 1];
│ │ │ │ │ - x2 = approx(end.x, digs);
│ │ │ │ │ - y2 = approx(end.y, digs);
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * The following conditions enforce five edge-crossing rules:
│ │ │ │ │ - * 1. points coincident with edges are considered contained;
│ │ │ │ │ - * 2. an upward edge includes its starting endpoint, and
│ │ │ │ │ - * excludes its final endpoint;
│ │ │ │ │ - * 3. a downward edge excludes its starting endpoint, and
│ │ │ │ │ - * includes its final endpoint;
│ │ │ │ │ - * 4. horizontal edges are excluded; and
│ │ │ │ │ - * 5. the edge-ray intersection point must be strictly right
│ │ │ │ │ - * of the point P.
│ │ │ │ │ - */
│ │ │ │ │ - if (y1 == y2) {
│ │ │ │ │ - // horizontal edge
│ │ │ │ │ - if (py == y1) {
│ │ │ │ │ - // point on horizontal line
│ │ │ │ │ - if (x1 <= x2 && (px >= x1 && px <= x2) || // right or vert
│ │ │ │ │ - x1 >= x2 && (px <= x1 && px >= x2)) { // left or vert
│ │ │ │ │ - // point on edge
│ │ │ │ │ - crosses = -1;
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - // ignore other horizontal edges
│ │ │ │ │ - continue;
│ │ │ │ │ - }
│ │ │ │ │ - cx = approx(getX(py, x1, y1, x2, y2), digs);
│ │ │ │ │ - if (cx == px) {
│ │ │ │ │ - // point on line
│ │ │ │ │ - if (y1 < y2 && (py >= y1 && py <= y2) || // upward
│ │ │ │ │ - y1 > y2 && (py <= y1 && py >= y2)) { // downward
│ │ │ │ │ - // point on edge
│ │ │ │ │ - crosses = -1;
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - if (cx <= px) {
│ │ │ │ │ - // no crossing to the right
│ │ │ │ │ - continue;
│ │ │ │ │ - }
│ │ │ │ │ - if (x1 != x2 && (cx < Math.min(x1, x2) || cx > Math.max(x1, x2))) {
│ │ │ │ │ - // no crossing
│ │ │ │ │ - continue;
│ │ │ │ │ - }
│ │ │ │ │ - if (y1 < y2 && (py >= y1 && py < y2) || // upward
│ │ │ │ │ - y1 > y2 && (py < y1 && py >= y2)) { // downward
│ │ │ │ │ - ++crosses;
│ │ │ │ │ + var listener = {
│ │ │ │ │ + obj: obj,
│ │ │ │ │ + func: func
│ │ │ │ │ + };
│ │ │ │ │ + if (priority) {
│ │ │ │ │ + listeners.splice(this.extensionCount[type], 0, listener);
│ │ │ │ │ + if (typeof priority === "object" && priority.extension) {
│ │ │ │ │ + this.extensionCount[type]++;
│ │ │ │ │ }
│ │ │ │ │ - }
│ │ │ │ │ - var contained = (crosses == -1) ?
│ │ │ │ │ - // on edge
│ │ │ │ │ - 1 :
│ │ │ │ │ - // even (out) or odd (in)
│ │ │ │ │ - !!(crosses & 1);
│ │ │ │ │ -
│ │ │ │ │ - return contained;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: intersects
│ │ │ │ │ - * Determine if the input geometry intersects this one.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * geometry - {} Any type of geometry.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} The input geometry intersects this one.
│ │ │ │ │ - */
│ │ │ │ │ - intersects: function(geometry) {
│ │ │ │ │ - var intersect = false;
│ │ │ │ │ - if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
│ │ │ │ │ - intersect = this.containsPoint(geometry);
│ │ │ │ │ - } else if (geometry.CLASS_NAME == "OpenLayers.Geometry.LineString") {
│ │ │ │ │ - intersect = geometry.intersects(this);
│ │ │ │ │ - } else if (geometry.CLASS_NAME == "OpenLayers.Geometry.LinearRing") {
│ │ │ │ │ - intersect = OpenLayers.Geometry.LineString.prototype.intersects.apply(
│ │ │ │ │ - this, [geometry]
│ │ │ │ │ - );
│ │ │ │ │ } else {
│ │ │ │ │ - // check for component intersections
│ │ │ │ │ - for (var i = 0, len = geometry.components.length; i < len; ++i) {
│ │ │ │ │ - intersect = geometry.components[i].intersects(this);
│ │ │ │ │ - if (intersect) {
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return intersect;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: getVertices
│ │ │ │ │ - * Return a list of all points in this geometry.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * 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.
│ │ │ │ │ - */
│ │ │ │ │ - getVertices: function(nodes) {
│ │ │ │ │ - return (nodes === true) ? [] : this.components.slice(0, this.components.length - 1);
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Geometry.LinearRing"
│ │ │ │ │ - });
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Geometry/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/Geometry/Collection.js
│ │ │ │ │ - * @requires OpenLayers/Geometry/LinearRing.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Geometry.Polygon
│ │ │ │ │ - * Polygon is a collection of Geometry.LinearRings.
│ │ │ │ │ - *
│ │ │ │ │ - * Inherits from:
│ │ │ │ │ - * -
│ │ │ │ │ - * -
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Geometry.Polygon = OpenLayers.Class(
│ │ │ │ │ - OpenLayers.Geometry.Collection, {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: componentTypes
│ │ │ │ │ - * {Array(String)} An array of class names representing the types of
│ │ │ │ │ - * components that the collection can include. A null value means the
│ │ │ │ │ - * component types are not restricted.
│ │ │ │ │ - */
│ │ │ │ │ - componentTypes: ["OpenLayers.Geometry.LinearRing"],
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Geometry.Polygon
│ │ │ │ │ - * Constructor for a Polygon geometry.
│ │ │ │ │ - * The first ring (this.component[0])is the outer bounds of the polygon and
│ │ │ │ │ - * all subsequent rings (this.component[1-n]) are internal holes.
│ │ │ │ │ - *
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * components - {Array()}
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: getArea
│ │ │ │ │ - * Calculated by subtracting the areas of the internal holes from the
│ │ │ │ │ - * area of the outer hole.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {float} The area of the geometry
│ │ │ │ │ - */
│ │ │ │ │ - getArea: function() {
│ │ │ │ │ - var area = 0.0;
│ │ │ │ │ - if (this.components && (this.components.length > 0)) {
│ │ │ │ │ - area += Math.abs(this.components[0].getArea());
│ │ │ │ │ - for (var i = 1, len = this.components.length; i < len; i++) {
│ │ │ │ │ - area -= Math.abs(this.components[i].getArea());
│ │ │ │ │ - }
│ │ │ │ │ + listeners.push(listener);
│ │ │ │ │ }
│ │ │ │ │ - return area;
│ │ │ │ │ - },
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: getGeodesicArea
│ │ │ │ │ - * Calculate the approximate area of the polygon were it projected onto
│ │ │ │ │ - * the earth.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * projection - {} The spatial reference system
│ │ │ │ │ - * for the geometry coordinates. If not provided, Geographic/WGS84 is
│ │ │ │ │ - * assumed.
│ │ │ │ │ - *
│ │ │ │ │ - * Reference:
│ │ │ │ │ - * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for
│ │ │ │ │ - * Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion
│ │ │ │ │ - * Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {float} The approximate geodesic area of the polygon in square meters.
│ │ │ │ │ - */
│ │ │ │ │ - getGeodesicArea: function(projection) {
│ │ │ │ │ - var area = 0.0;
│ │ │ │ │ - if (this.components && (this.components.length > 0)) {
│ │ │ │ │ - area += Math.abs(this.components[0].getGeodesicArea(projection));
│ │ │ │ │ - for (var i = 1, len = this.components.length; i < len; i++) {
│ │ │ │ │ - area -= Math.abs(this.components[i].getGeodesicArea(projection));
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return area;
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * 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);
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: containsPoint
│ │ │ │ │ - * Test if a point is inside a polygon. Points on a polygon edge are
│ │ │ │ │ - * considered inside.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * point - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean | Number} The point is inside the polygon. Returns 1 if the
│ │ │ │ │ - * point is on an edge. Returns boolean otherwise.
│ │ │ │ │ - */
│ │ │ │ │ - containsPoint: function(point) {
│ │ │ │ │ - var numRings = this.components.length;
│ │ │ │ │ - var contained = false;
│ │ │ │ │ - if (numRings > 0) {
│ │ │ │ │ - // check exterior ring - 1 means on edge, boolean otherwise
│ │ │ │ │ - contained = this.components[0].containsPoint(point);
│ │ │ │ │ - if (contained !== 1) {
│ │ │ │ │ - if (contained && numRings > 1) {
│ │ │ │ │ - // check interior rings
│ │ │ │ │ - var hole;
│ │ │ │ │ - for (var i = 1; i < numRings; ++i) {
│ │ │ │ │ - hole = this.components[i].containsPoint(point);
│ │ │ │ │ - if (hole) {
│ │ │ │ │ - if (hole === 1) {
│ │ │ │ │ - // on edge
│ │ │ │ │ - contained = 1;
│ │ │ │ │ - } else {
│ │ │ │ │ - // in hole
│ │ │ │ │ - contained = false;
│ │ │ │ │ - }
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ + /**
│ │ │ │ │ + * 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]);
│ │ │ │ │ }
│ │ │ │ │ - return contained;
│ │ │ │ │ - },
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: intersects
│ │ │ │ │ - * Determine if the input geometry intersects this one.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * geometry - {} Any type of geometry.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} The input geometry intersects this one.
│ │ │ │ │ - */
│ │ │ │ │ - intersects: function(geometry) {
│ │ │ │ │ - var intersect = false;
│ │ │ │ │ - var i, len;
│ │ │ │ │ - if (geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
│ │ │ │ │ - intersect = this.containsPoint(geometry);
│ │ │ │ │ - } else if (geometry.CLASS_NAME == "OpenLayers.Geometry.LineString" ||
│ │ │ │ │ - geometry.CLASS_NAME == "OpenLayers.Geometry.LinearRing") {
│ │ │ │ │ - // check if rings/linestrings intersect
│ │ │ │ │ - for (i = 0, len = this.components.length; i < len; ++i) {
│ │ │ │ │ - intersect = geometry.intersects(this.components[i]);
│ │ │ │ │ - if (intersect) {
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - if (!intersect) {
│ │ │ │ │ - // check if this poly contains points of the ring/linestring
│ │ │ │ │ - for (i = 0, len = geometry.components.length; i < len; ++i) {
│ │ │ │ │ - intersect = this.containsPoint(geometry.components[i]);
│ │ │ │ │ - if (intersect) {
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - } else {
│ │ │ │ │ - for (i = 0, len = geometry.components.length; i < len; ++i) {
│ │ │ │ │ - intersect = this.intersects(geometry.components[i]);
│ │ │ │ │ - if (intersect) {
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - // check case where this poly is wholly contained by another
│ │ │ │ │ - if (!intersect && geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") {
│ │ │ │ │ - // exterior ring points will be contained in the other geometry
│ │ │ │ │ - var ring = this.components[0];
│ │ │ │ │ - for (i = 0, len = ring.components.length; i < len; ++i) {
│ │ │ │ │ - intersect = geometry.containsPoint(ring.components[i]);
│ │ │ │ │ - if (intersect) {
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ + /**
│ │ │ │ │ + * 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;
│ │ │ │ │ }
│ │ │ │ │ }
│ │ │ │ │ - return intersect;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: distanceTo
│ │ │ │ │ - * Calculate the closest distance between two geometries (on the x-y plane).
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * geometry - {} The target geometry.
│ │ │ │ │ - * options - {Object} Optional properties for configuring the distance
│ │ │ │ │ - * calculation.
│ │ │ │ │ - *
│ │ │ │ │ - * Valid options:
│ │ │ │ │ - * details - {Boolean} Return details from the distance calculation.
│ │ │ │ │ - * Default is false.
│ │ │ │ │ - * edge - {Boolean} Calculate the distance from this geometry to the
│ │ │ │ │ - * nearest edge of the target geometry. Default is true. If true,
│ │ │ │ │ - * calling distanceTo from a geometry that is wholly contained within
│ │ │ │ │ - * the target will result in a non-zero distance. If false, whenever
│ │ │ │ │ - * geometries intersect, calling distanceTo will return 0. If false,
│ │ │ │ │ - * details cannot be returned.
│ │ │ │ │ - *
│ │ │ │ │ - * 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 y1 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.
│ │ │ │ │ - */
│ │ │ │ │ - distanceTo: function(geometry, options) {
│ │ │ │ │ - var edge = !(options && options.edge === false);
│ │ │ │ │ - var result;
│ │ │ │ │ - // this is the case where we might not be looking for distance to edge
│ │ │ │ │ - if (!edge && this.intersects(geometry)) {
│ │ │ │ │ - result = 0;
│ │ │ │ │ - } else {
│ │ │ │ │ - result = OpenLayers.Geometry.Collection.prototype.distanceTo.apply(
│ │ │ │ │ - this, [geometry, options]
│ │ │ │ │ - );
│ │ │ │ │ - }
│ │ │ │ │ - return result;
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Geometry.Polygon"
│ │ │ │ │ - });
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * APIMethod: createRegularPolygon
│ │ │ │ │ - * Create a regular polygon around a radius. Useful for creating circles
│ │ │ │ │ - * and the like.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * origin - {} center of polygon.
│ │ │ │ │ - * radius - {Float} distance to vertex, in map units.
│ │ │ │ │ - * sides - {Integer} Number of sides. 20 approximates a circle.
│ │ │ │ │ - * rotation - {Float} original angle of rotation, in degrees.
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Geometry.Polygon.createRegularPolygon = function(origin, radius, sides, rotation) {
│ │ │ │ │ - var angle = Math.PI * ((1 / sides) - (1 / 2));
│ │ │ │ │ - if (rotation) {
│ │ │ │ │ - angle += (rotation / 180) * Math.PI;
│ │ │ │ │ - }
│ │ │ │ │ - var rotatedAngle, x, y;
│ │ │ │ │ - var points = [];
│ │ │ │ │ - for (var i = 0; i < sides; ++i) {
│ │ │ │ │ - rotatedAngle = angle + (i * 2 * Math.PI / sides);
│ │ │ │ │ - x = origin.x + (radius * Math.cos(rotatedAngle));
│ │ │ │ │ - y = origin.y + (radius * Math.sin(rotatedAngle));
│ │ │ │ │ - points.push(new OpenLayers.Geometry.Point(x, y));
│ │ │ │ │ - }
│ │ │ │ │ - var ring = new OpenLayers.Geometry.LinearRing(points);
│ │ │ │ │ - return new OpenLayers.Geometry.Polygon([ring]);
│ │ │ │ │ -};
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Geometry/MultiPolygon.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/Geometry/Collection.js
│ │ │ │ │ - * @requires OpenLayers/Geometry/Polygon.js
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Geometry.MultiPolygon
│ │ │ │ │ - * MultiPolygon is a geometry with multiple
│ │ │ │ │ - * components. Create a new instance with the
│ │ │ │ │ - * constructor.
│ │ │ │ │ - *
│ │ │ │ │ - * Inherits from:
│ │ │ │ │ - * -
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Geometry.MultiPolygon = OpenLayers.Class(
│ │ │ │ │ - OpenLayers.Geometry.Collection, {
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: componentTypes
│ │ │ │ │ - * {Array(String)} An array of class names representing the types of
│ │ │ │ │ - * components that the collection can include. A null value means the
│ │ │ │ │ - * component types are not restricted.
│ │ │ │ │ - */
│ │ │ │ │ - componentTypes: ["OpenLayers.Geometry.Polygon"],
│ │ │ │ │ + /**
│ │ │ │ │ + * 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] = [];
│ │ │ │ │ + }
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Constructor: OpenLayers.Geometry.MultiPolygon
│ │ │ │ │ - * Create a new MultiPolygon geometry
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * components - {Array()} An array of polygons
│ │ │ │ │ - * used to generate the MultiPolygon
│ │ │ │ │ - *
│ │ │ │ │ - */
│ │ │ │ │ + /**
│ │ │ │ │ + * 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];
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Geometry.MultiPolygon"
│ │ │ │ │ - });
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Format/WKT.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ + // fast path
│ │ │ │ │ + if (!listeners || listeners.length == 0) {
│ │ │ │ │ + return undefined;
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ -/* 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. */
│ │ │ │ │ + // 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;
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/Format.js
│ │ │ │ │ - * @requires OpenLayers/Feature/Vector.js
│ │ │ │ │ - * @requires OpenLayers/Geometry/Point.js
│ │ │ │ │ - * @requires OpenLayers/Geometry/MultiPoint.js
│ │ │ │ │ - * @requires OpenLayers/Geometry/LineString.js
│ │ │ │ │ - * @requires OpenLayers/Geometry/MultiLineString.js
│ │ │ │ │ - * @requires OpenLayers/Geometry/Polygon.js
│ │ │ │ │ - * @requires OpenLayers/Geometry/MultiPolygon.js
│ │ │ │ │ - */
│ │ │ │ │ + // 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]);
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Format.WKT
│ │ │ │ │ - * Class for reading and writing Well-Known Text. Create a new instance
│ │ │ │ │ - * with the constructor.
│ │ │ │ │ - *
│ │ │ │ │ - * Inherits from:
│ │ │ │ │ - * -
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Format.WKT = OpenLayers.Class(OpenLayers.Format, {
│ │ │ │ │ + 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;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constructor: OpenLayers.Format.WKT
│ │ │ │ │ - * Create a new parser for WKT
│ │ │ │ │ + * 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:
│ │ │ │ │ - * options - {Object} An optional object whose properties will be set on
│ │ │ │ │ - * this instance
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} A new WKT parser.
│ │ │ │ │ + * evt - {Event}
│ │ │ │ │ */
│ │ │ │ │ - initialize: function(options) {
│ │ │ │ │ - this.regExes = {
│ │ │ │ │ - 'typeStr': /^\s*(\w+)\s*\(\s*(.*)\s*\)\s*$/,
│ │ │ │ │ - 'spaces': /\s+/,
│ │ │ │ │ - 'parenComma': /\)\s*,\s*\(/,
│ │ │ │ │ - 'doubleParenComma': /\)\s*\)\s*,\s*\(\s*\(/, // can't use {2} here
│ │ │ │ │ - 'trimParens': /^\s*\(?(.*?)\)?\s*$/
│ │ │ │ │ - };
│ │ │ │ │ - OpenLayers.Format.prototype.initialize.apply(this, [options]);
│ │ │ │ │ + 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);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: read
│ │ │ │ │ - * Deserialize a WKT string and return a vector feature or an
│ │ │ │ │ - * array of vector features. Supports WKT for POINT, MULTIPOINT,
│ │ │ │ │ - * LINESTRING, MULTILINESTRING, POLYGON, MULTIPOLYGON, and
│ │ │ │ │ - * GEOMETRYCOLLECTION.
│ │ │ │ │ + * Method: getTouchClientXY
│ │ │ │ │ + * WebKit has a few bugs for clientX/clientY. This method detects them
│ │ │ │ │ + * and calculate the correct values.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * wkt - {String} A WKT string
│ │ │ │ │ - *
│ │ │ │ │ + * evt - {Touch} a Touch object from a TouchEvent
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {|Array} A feature or array of features for
│ │ │ │ │ - * GEOMETRYCOLLECTION WKT.
│ │ │ │ │ + * {Object} An object with only clientX and clientY properties with the
│ │ │ │ │ + * calculated values.
│ │ │ │ │ */
│ │ │ │ │ - read: function(wkt) {
│ │ │ │ │ - var features, type, str;
│ │ │ │ │ - wkt = wkt.replace(/[\n\r]/g, " ");
│ │ │ │ │ - var matches = this.regExes.typeStr.exec(wkt);
│ │ │ │ │ - if (matches) {
│ │ │ │ │ - type = matches[1].toLowerCase();
│ │ │ │ │ - str = matches[2];
│ │ │ │ │ - if (this.parse[type]) {
│ │ │ │ │ - features = this.parse[type].apply(this, [str]);
│ │ │ │ │ - }
│ │ │ │ │ - if (this.internalProjection && this.externalProjection) {
│ │ │ │ │ - if (features &&
│ │ │ │ │ - features.CLASS_NAME == "OpenLayers.Feature.Vector") {
│ │ │ │ │ - features.geometry.transform(this.externalProjection,
│ │ │ │ │ - this.internalProjection);
│ │ │ │ │ - } else if (features &&
│ │ │ │ │ - type != "geometrycollection" &&
│ │ │ │ │ - typeof features == "object") {
│ │ │ │ │ - for (var i = 0, len = features.length; i < len; i++) {
│ │ │ │ │ - var component = features[i];
│ │ │ │ │ - component.geometry.transform(this.externalProjection,
│ │ │ │ │ - this.internalProjection);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ + 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;
│ │ │ │ │ }
│ │ │ │ │ - return features;
│ │ │ │ │ +
│ │ │ │ │ + evt.olClientX = x;
│ │ │ │ │ + evt.olClientY = y;
│ │ │ │ │ +
│ │ │ │ │ + return {
│ │ │ │ │ + clientX: x,
│ │ │ │ │ + clientY: y
│ │ │ │ │ + };
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: write
│ │ │ │ │ - * Serialize a feature or array of features into a WKT string.
│ │ │ │ │ - *
│ │ │ │ │ + * 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:
│ │ │ │ │ - * features - {|Array} A feature or array of
│ │ │ │ │ - * features
│ │ │ │ │ - *
│ │ │ │ │ + * evt - {Event}
│ │ │ │ │ + *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {String} The WKT string representation of the input geometries
│ │ │ │ │ + * {} The current xy coordinate of the mouse, adjusted
│ │ │ │ │ + * for offsets
│ │ │ │ │ */
│ │ │ │ │ - write: function(features) {
│ │ │ │ │ - var collection, geometry, isCollection;
│ │ │ │ │ - if (features.constructor == Array) {
│ │ │ │ │ - collection = features;
│ │ │ │ │ - isCollection = true;
│ │ │ │ │ - } else {
│ │ │ │ │ - collection = [features];
│ │ │ │ │ - isCollection = false;
│ │ │ │ │ + getMousePosition: function(evt) {
│ │ │ │ │ + if (!this.includeXY) {
│ │ │ │ │ + this.clearMouseCache();
│ │ │ │ │ + } else if (!this.element.hasScrollEvent) {
│ │ │ │ │ + OpenLayers.Event.observe(window, "scroll", this.clearMouseListener);
│ │ │ │ │ + this.element.hasScrollEvent = true;
│ │ │ │ │ }
│ │ │ │ │ - var pieces = [];
│ │ │ │ │ - if (isCollection) {
│ │ │ │ │ - pieces.push('GEOMETRYCOLLECTION(');
│ │ │ │ │ +
│ │ │ │ │ + if (!this.element.scrolls) {
│ │ │ │ │ + var viewportElement = OpenLayers.Util.getViewportElement();
│ │ │ │ │ + this.element.scrolls = [
│ │ │ │ │ + window.pageXOffset || viewportElement.scrollLeft,
│ │ │ │ │ + window.pageYOffset || viewportElement.scrollTop
│ │ │ │ │ + ];
│ │ │ │ │ }
│ │ │ │ │ - for (var i = 0, len = collection.length; i < len; ++i) {
│ │ │ │ │ - if (isCollection && i > 0) {
│ │ │ │ │ - pieces.push(',');
│ │ │ │ │ - }
│ │ │ │ │ - geometry = collection[i].geometry;
│ │ │ │ │ - pieces.push(this.extractGeometry(geometry));
│ │ │ │ │ +
│ │ │ │ │ + if (!this.element.lefttop) {
│ │ │ │ │ + this.element.lefttop = [
│ │ │ │ │ + (document.documentElement.clientLeft || 0),
│ │ │ │ │ + (document.documentElement.clientTop || 0)
│ │ │ │ │ + ];
│ │ │ │ │ }
│ │ │ │ │ - if (isCollection) {
│ │ │ │ │ - pieces.push(')');
│ │ │ │ │ +
│ │ │ │ │ + if (!this.element.offsets) {
│ │ │ │ │ + this.element.offsets = OpenLayers.Util.pagePosition(this.element);
│ │ │ │ │ }
│ │ │ │ │ - return pieces.join('');
│ │ │ │ │ +
│ │ │ │ │ + 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: extractGeometry
│ │ │ │ │ - * Entry point to construct the WKT for a single Geometry object.
│ │ │ │ │ + * Method: addMsTouchListener
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * geometry - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} A WKT string of representing the geometry
│ │ │ │ │ + * element - {DOMElement} The DOM element to register the listener on
│ │ │ │ │ + * type - {String} The event type
│ │ │ │ │ + * handler - {Function} the handler
│ │ │ │ │ */
│ │ │ │ │ - extractGeometry: function(geometry) {
│ │ │ │ │ - var type = geometry.CLASS_NAME.split('.')[2].toLowerCase();
│ │ │ │ │ - if (!this.extract[type]) {
│ │ │ │ │ - return null;
│ │ │ │ │ + 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));
│ │ │ │ │ }
│ │ │ │ │ - if (this.internalProjection && this.externalProjection) {
│ │ │ │ │ - geometry = geometry.clone();
│ │ │ │ │ - geometry.transform(this.internalProjection, this.externalProjection);
│ │ │ │ │ +
│ │ │ │ │ + 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 wktType = type == 'collection' ? 'GEOMETRYCOLLECTION' : type.toUpperCase();
│ │ │ │ │ - var data = wktType + '(' + this.extract[type].apply(this, [geometry]) + ')';
│ │ │ │ │ - return data;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Object with properties corresponding to the geometry types.
│ │ │ │ │ - * Property values are functions that do the actual data extraction.
│ │ │ │ │ + * Method: addMsTouchListenerStart
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * element - {DOMElement} The DOM element to register the listener on
│ │ │ │ │ + * type - {String} The event type
│ │ │ │ │ + * handler - {Function} the handler
│ │ │ │ │ */
│ │ │ │ │ - extract: {
│ │ │ │ │ - /**
│ │ │ │ │ - * Return a space delimited string of point coordinates.
│ │ │ │ │ - * @param {OpenLayers.Geometry.Point} point
│ │ │ │ │ - * @returns {String} A string of coordinates representing the point
│ │ │ │ │ - */
│ │ │ │ │ - 'point': function(point) {
│ │ │ │ │ - return point.x + ' ' + point.y;
│ │ │ │ │ - },
│ │ │ │ │ + addMsTouchListenerStart: function(element, type, handler) {
│ │ │ │ │ + var touches = this._msTouches;
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Return a comma delimited string of point coordinates from a multipoint.
│ │ │ │ │ - * @param {OpenLayers.Geometry.MultiPoint} multipoint
│ │ │ │ │ - * @returns {String} A string of point coordinate strings representing
│ │ │ │ │ - * the multipoint
│ │ │ │ │ - */
│ │ │ │ │ - 'multipoint': function(multipoint) {
│ │ │ │ │ - var array = [];
│ │ │ │ │ - for (var i = 0, len = multipoint.components.length; i < len; ++i) {
│ │ │ │ │ - array.push('(' +
│ │ │ │ │ - this.extract.point.apply(this, [multipoint.components[i]]) +
│ │ │ │ │ - ')');
│ │ │ │ │ - }
│ │ │ │ │ - return array.join(',');
│ │ │ │ │ - },
│ │ │ │ │ + var cb = function(e) {
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Return a comma delimited string of point coordinates from a line.
│ │ │ │ │ - * @param {OpenLayers.Geometry.LineString} linestring
│ │ │ │ │ - * @returns {String} A string of point coordinate strings representing
│ │ │ │ │ - * the linestring
│ │ │ │ │ - */
│ │ │ │ │ - 'linestring': function(linestring) {
│ │ │ │ │ - var array = [];
│ │ │ │ │ - for (var i = 0, len = linestring.components.length; i < len; ++i) {
│ │ │ │ │ - array.push(this.extract.point.apply(this, [linestring.components[i]]));
│ │ │ │ │ + var alreadyInArray = false;
│ │ │ │ │ + for (var i = 0, ii = touches.length; i < ii; ++i) {
│ │ │ │ │ + if (touches[i].pointerId == e.pointerId) {
│ │ │ │ │ + alreadyInArray = true;
│ │ │ │ │ + break;
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ - return array.join(',');
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Return a comma delimited string of linestring strings from a multilinestring.
│ │ │ │ │ - * @param {OpenLayers.Geometry.MultiLineString} multilinestring
│ │ │ │ │ - * @returns {String} A string of of linestring strings representing
│ │ │ │ │ - * the multilinestring
│ │ │ │ │ - */
│ │ │ │ │ - 'multilinestring': function(multilinestring) {
│ │ │ │ │ - var array = [];
│ │ │ │ │ - for (var i = 0, len = multilinestring.components.length; i < len; ++i) {
│ │ │ │ │ - array.push('(' +
│ │ │ │ │ - this.extract.linestring.apply(this, [multilinestring.components[i]]) +
│ │ │ │ │ - ')');
│ │ │ │ │ + if (!alreadyInArray) {
│ │ │ │ │ + touches.push(e);
│ │ │ │ │ }
│ │ │ │ │ - return array.join(',');
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Return a comma delimited string of linear ring arrays from a polygon.
│ │ │ │ │ - * @param {OpenLayers.Geometry.Polygon} polygon
│ │ │ │ │ - * @returns {String} An array of linear ring arrays representing the polygon
│ │ │ │ │ - */
│ │ │ │ │ - 'polygon': function(polygon) {
│ │ │ │ │ - var array = [];
│ │ │ │ │ - for (var i = 0, len = polygon.components.length; i < len; ++i) {
│ │ │ │ │ - array.push('(' +
│ │ │ │ │ - this.extract.linestring.apply(this, [polygon.components[i]]) +
│ │ │ │ │ - ')');
│ │ │ │ │ - }
│ │ │ │ │ - return array.join(',');
│ │ │ │ │ - },
│ │ │ │ │ + e.touches = touches.slice();
│ │ │ │ │ + handler(e);
│ │ │ │ │ + };
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Return an array of polygon arrays from a multipolygon.
│ │ │ │ │ - * @param {OpenLayers.Geometry.MultiPolygon} multipolygon
│ │ │ │ │ - * @returns {String} An array of polygon arrays representing
│ │ │ │ │ - * the multipolygon
│ │ │ │ │ - */
│ │ │ │ │ - 'multipolygon': function(multipolygon) {
│ │ │ │ │ - var array = [];
│ │ │ │ │ - for (var i = 0, len = multipolygon.components.length; i < len; ++i) {
│ │ │ │ │ - array.push('(' +
│ │ │ │ │ - this.extract.polygon.apply(this, [multipolygon.components[i]]) +
│ │ │ │ │ - ')');
│ │ │ │ │ - }
│ │ │ │ │ - return array.join(',');
│ │ │ │ │ - },
│ │ │ │ │ + OpenLayers.Event.observe(element, 'MSPointerDown', cb);
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Return the WKT portion between 'GEOMETRYCOLLECTION(' and ')' for an
│ │ │ │ │ - * @param {OpenLayers.Geometry.Collection} collection
│ │ │ │ │ - * @returns {String} internal WKT representation of the collection
│ │ │ │ │ - */
│ │ │ │ │ - 'collection': function(collection) {
│ │ │ │ │ - var array = [];
│ │ │ │ │ - for (var i = 0, len = collection.components.length; i < len; ++i) {
│ │ │ │ │ - array.push(this.extractGeometry.apply(this, [collection.components[i]]));
│ │ │ │ │ + // 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;
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ - return array.join(',');
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ + };
│ │ │ │ │ + OpenLayers.Event.observe(element, 'MSPointerUp', internalCb);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Object with properties corresponding to the geometry types.
│ │ │ │ │ - * Property values are functions that do the actual parsing.
│ │ │ │ │ + * Method: addMsTouchListenerMove
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * element - {DOMElement} The DOM element to register the listener on
│ │ │ │ │ + * type - {String} The event type
│ │ │ │ │ + * handler - {Function} the handler
│ │ │ │ │ */
│ │ │ │ │ - parse: {
│ │ │ │ │ - /**
│ │ │ │ │ - * Return point feature given a point WKT fragment.
│ │ │ │ │ - * @param {String} str A WKT fragment representing the point
│ │ │ │ │ - * @returns {OpenLayers.Feature.Vector} A point feature
│ │ │ │ │ - * @private
│ │ │ │ │ - */
│ │ │ │ │ - 'point': function(str) {
│ │ │ │ │ - var coords = OpenLayers.String.trim(str).split(this.regExes.spaces);
│ │ │ │ │ - return new OpenLayers.Feature.Vector(
│ │ │ │ │ - new OpenLayers.Geometry.Point(coords[0], coords[1])
│ │ │ │ │ - );
│ │ │ │ │ - },
│ │ │ │ │ + addMsTouchListenerMove: function(element, type, handler) {
│ │ │ │ │ + var touches = this._msTouches;
│ │ │ │ │ + var cb = function(e) {
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Return a multipoint feature given a multipoint WKT fragment.
│ │ │ │ │ - * @param {String} str A WKT fragment representing the multipoint
│ │ │ │ │ - * @returns {OpenLayers.Feature.Vector} A multipoint feature
│ │ │ │ │ - * @private
│ │ │ │ │ - */
│ │ │ │ │ - 'multipoint': function(str) {
│ │ │ │ │ - var point;
│ │ │ │ │ - var points = OpenLayers.String.trim(str).split(',');
│ │ │ │ │ - var components = [];
│ │ │ │ │ - for (var i = 0, len = points.length; i < len; ++i) {
│ │ │ │ │ - point = points[i].replace(this.regExes.trimParens, '$1');
│ │ │ │ │ - components.push(this.parse.point.apply(this, [point]).geometry);
│ │ │ │ │ + //Don't fire touch moves when mouse isn't down
│ │ │ │ │ + if (e.pointerType == e.MSPOINTER_TYPE_MOUSE && e.buttons == 0) {
│ │ │ │ │ + return;
│ │ │ │ │ }
│ │ │ │ │ - return new OpenLayers.Feature.Vector(
│ │ │ │ │ - new OpenLayers.Geometry.MultiPoint(components)
│ │ │ │ │ - );
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Return a linestring feature given a linestring WKT fragment.
│ │ │ │ │ - * @param {String} str A WKT fragment representing the linestring
│ │ │ │ │ - * @returns {OpenLayers.Feature.Vector} A linestring feature
│ │ │ │ │ - * @private
│ │ │ │ │ - */
│ │ │ │ │ - 'linestring': function(str) {
│ │ │ │ │ - var points = OpenLayers.String.trim(str).split(',');
│ │ │ │ │ - var components = [];
│ │ │ │ │ - for (var i = 0, len = points.length; i < len; ++i) {
│ │ │ │ │ - components.push(this.parse.point.apply(this, [points[i]]).geometry);
│ │ │ │ │ + if (touches.length == 1 && touches[0].pageX == e.pageX &&
│ │ │ │ │ + touches[0].pageY == e.pageY) {
│ │ │ │ │ + // don't trigger event when pointer has not moved
│ │ │ │ │ + return;
│ │ │ │ │ }
│ │ │ │ │ - return new OpenLayers.Feature.Vector(
│ │ │ │ │ - new OpenLayers.Geometry.LineString(components)
│ │ │ │ │ - );
│ │ │ │ │ - },
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * Return a multilinestring feature given a multilinestring WKT fragment.
│ │ │ │ │ - * @param {String} str A WKT fragment representing the multilinestring
│ │ │ │ │ - * @returns {OpenLayers.Feature.Vector} A multilinestring feature
│ │ │ │ │ - * @private
│ │ │ │ │ - */
│ │ │ │ │ - 'multilinestring': function(str) {
│ │ │ │ │ - var line;
│ │ │ │ │ - var lines = OpenLayers.String.trim(str).split(this.regExes.parenComma);
│ │ │ │ │ - var components = [];
│ │ │ │ │ - for (var i = 0, len = lines.length; i < len; ++i) {
│ │ │ │ │ - line = lines[i].replace(this.regExes.trimParens, '$1');
│ │ │ │ │ - components.push(this.parse.linestring.apply(this, [line]).geometry);
│ │ │ │ │ + for (var i = 0, ii = touches.length; i < ii; ++i) {
│ │ │ │ │ + if (touches[i].pointerId == e.pointerId) {
│ │ │ │ │ + touches[i] = e;
│ │ │ │ │ + break;
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ - return new OpenLayers.Feature.Vector(
│ │ │ │ │ - new OpenLayers.Geometry.MultiLineString(components)
│ │ │ │ │ - );
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Return a polygon feature given a polygon WKT fragment.
│ │ │ │ │ - * @param {String} str A WKT fragment representing the polygon
│ │ │ │ │ - * @returns {OpenLayers.Feature.Vector} A polygon feature
│ │ │ │ │ - * @private
│ │ │ │ │ - */
│ │ │ │ │ - 'polygon': function(str) {
│ │ │ │ │ - var ring, linestring, linearring;
│ │ │ │ │ - var rings = OpenLayers.String.trim(str).split(this.regExes.parenComma);
│ │ │ │ │ - var components = [];
│ │ │ │ │ - for (var i = 0, len = rings.length; i < len; ++i) {
│ │ │ │ │ - ring = rings[i].replace(this.regExes.trimParens, '$1');
│ │ │ │ │ - linestring = this.parse.linestring.apply(this, [ring]).geometry;
│ │ │ │ │ - linearring = new OpenLayers.Geometry.LinearRing(linestring.components);
│ │ │ │ │ - components.push(linearring);
│ │ │ │ │ - }
│ │ │ │ │ - return new OpenLayers.Feature.Vector(
│ │ │ │ │ - new OpenLayers.Geometry.Polygon(components)
│ │ │ │ │ - );
│ │ │ │ │ - },
│ │ │ │ │ + e.touches = touches.slice();
│ │ │ │ │ + handler(e);
│ │ │ │ │ + };
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Return a multipolygon feature given a multipolygon WKT fragment.
│ │ │ │ │ - * @param {String} str A WKT fragment representing the multipolygon
│ │ │ │ │ - * @returns {OpenLayers.Feature.Vector} A multipolygon feature
│ │ │ │ │ - * @private
│ │ │ │ │ - */
│ │ │ │ │ - 'multipolygon': function(str) {
│ │ │ │ │ - var polygon;
│ │ │ │ │ - var polygons = OpenLayers.String.trim(str).split(this.regExes.doubleParenComma);
│ │ │ │ │ - var components = [];
│ │ │ │ │ - for (var i = 0, len = polygons.length; i < len; ++i) {
│ │ │ │ │ - polygon = polygons[i].replace(this.regExes.trimParens, '$1');
│ │ │ │ │ - components.push(this.parse.polygon.apply(this, [polygon]).geometry);
│ │ │ │ │ - }
│ │ │ │ │ - return new OpenLayers.Feature.Vector(
│ │ │ │ │ - new OpenLayers.Geometry.MultiPolygon(components)
│ │ │ │ │ - );
│ │ │ │ │ - },
│ │ │ │ │ + OpenLayers.Event.observe(element, 'MSPointerMove', cb);
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Return an array of features given a geometrycollection WKT fragment.
│ │ │ │ │ - * @param {String} str A WKT fragment representing the geometrycollection
│ │ │ │ │ - * @returns {Array} An array of OpenLayers.Feature.Vector
│ │ │ │ │ - * @private
│ │ │ │ │ - */
│ │ │ │ │ - 'geometrycollection': function(str) {
│ │ │ │ │ - // separate components of the collection with |
│ │ │ │ │ - str = str.replace(/,\s*([A-Za-z])/g, '|$1');
│ │ │ │ │ - var wktArray = OpenLayers.String.trim(str).split('|');
│ │ │ │ │ - var components = [];
│ │ │ │ │ - for (var i = 0, len = wktArray.length; i < len; ++i) {
│ │ │ │ │ - components.push(OpenLayers.Format.WKT.prototype.read.apply(this, [wktArray[i]]));
│ │ │ │ │ + /**
│ │ │ │ │ + * 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;
│ │ │ │ │ + }
│ │ │ │ │ }
│ │ │ │ │ - return components;
│ │ │ │ │ - }
│ │ │ │ │
│ │ │ │ │ + e.touches = touches.slice();
│ │ │ │ │ + handler(e);
│ │ │ │ │ + };
│ │ │ │ │ +
│ │ │ │ │ + OpenLayers.Event.observe(element, 'MSPointerUp', cb);
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Format.WKT"
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Events"
│ │ │ │ │ });
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Format/JSON.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. */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Note:
│ │ │ │ │ - * This work draws heavily from the public domain JSON serializer/deserializer
│ │ │ │ │ - * at http://www.json.org/json.js. Rewritten so that it doesn't modify
│ │ │ │ │ - * basic data prototypes.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ -/**
│ │ │ │ │ - * @requires OpenLayers/Format.js
│ │ │ │ │ + * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ + * @requires OpenLayers/Util.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Class: OpenLayers.Format.JSON
│ │ │ │ │ - * A parser to read/write JSON safely. Create a new instance with the
│ │ │ │ │ - * constructor.
│ │ │ │ │ + * 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.
│ │ │ │ │ *
│ │ │ │ │ - * Inherits from:
│ │ │ │ │ - * -
│ │ │ │ │ + * 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.Format.JSON = OpenLayers.Class(OpenLayers.Format, {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: indent
│ │ │ │ │ - * {String} For "pretty" printing, the indent string will be used once for
│ │ │ │ │ - * each indentation level.
│ │ │ │ │ - */
│ │ │ │ │ - indent: " ",
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: space
│ │ │ │ │ - * {String} For "pretty" printing, the space string will be used after
│ │ │ │ │ - * the ":" separating a name/value pair.
│ │ │ │ │ - */
│ │ │ │ │ - space: " ",
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIProperty: newline
│ │ │ │ │ - * {String} For "pretty" printing, the newline string will be used at the
│ │ │ │ │ - * end of each name/value pair or array item.
│ │ │ │ │ - */
│ │ │ │ │ - newline: "\n",
│ │ │ │ │ +OpenLayers.Projection = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: level
│ │ │ │ │ - * {Integer} For "pretty" printing, this is incremented/decremented during
│ │ │ │ │ - * serialization.
│ │ │ │ │ + * Property: proj
│ │ │ │ │ + * {Object} Proj4js.Proj instance.
│ │ │ │ │ */
│ │ │ │ │ - level: 0,
│ │ │ │ │ + proj: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: pretty
│ │ │ │ │ - * {Boolean} Serialize with extra whitespace for structure. This is set
│ │ │ │ │ - * by the method.
│ │ │ │ │ + * Property: projCode
│ │ │ │ │ + * {String}
│ │ │ │ │ */
│ │ │ │ │ - pretty: false,
│ │ │ │ │ + projCode: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: nativeJSON
│ │ │ │ │ - * {Boolean} Does the browser support native json?
│ │ │ │ │ + * Property: titleRegEx
│ │ │ │ │ + * {RegExp} regular expression to strip the title from a proj4js definition
│ │ │ │ │ */
│ │ │ │ │ - nativeJSON: (function() {
│ │ │ │ │ - return !!(window.JSON && typeof JSON.parse == "function" && typeof JSON.stringify == "function");
│ │ │ │ │ - })(),
│ │ │ │ │ + titleRegEx: /\+title=[^\+]*/,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constructor: OpenLayers.Format.JSON
│ │ │ │ │ - * Create a new parser for JSON.
│ │ │ │ │ + * Constructor: OpenLayers.Projection
│ │ │ │ │ + * This class offers several methods for interacting with a wrapped
│ │ │ │ │ + * pro4js projection object.
│ │ │ │ │ *
│ │ │ │ │ * Parameters:
│ │ │ │ │ - * options - {Object} An optional object whose properties will be set on
│ │ │ │ │ - * this instance.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: read
│ │ │ │ │ - * Deserialize a json string.
│ │ │ │ │ + * projCode - {String} A string identifying the Well Known Identifier for
│ │ │ │ │ + * the projection.
│ │ │ │ │ + * options - {Object} An optional object to set additional properties
│ │ │ │ │ + * on the projection.
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * json - {String} A JSON string
│ │ │ │ │ - * filter - {Function} A function which will be called for every key and
│ │ │ │ │ - * value at every level of the final result. Each value will be
│ │ │ │ │ - * replaced by the result of the filter function. This can be used to
│ │ │ │ │ - * reform generic objects into instances of classes, or to transform
│ │ │ │ │ - * date strings into Date objects.
│ │ │ │ │ - *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {Object} An object, array, string, or number .
│ │ │ │ │ + * {} A projection object.
│ │ │ │ │ */
│ │ │ │ │ - read: function(json, filter) {
│ │ │ │ │ - var object;
│ │ │ │ │ - if (this.nativeJSON) {
│ │ │ │ │ - object = JSON.parse(json, filter);
│ │ │ │ │ - } else try {
│ │ │ │ │ - /**
│ │ │ │ │ - * Parsing happens in three stages. In the first stage, we run the
│ │ │ │ │ - * text against a regular expression which looks for non-JSON
│ │ │ │ │ - * characters. We are especially concerned with '()' and 'new'
│ │ │ │ │ - * because they can cause invocation, and '=' because it can
│ │ │ │ │ - * cause mutation. But just to be safe, we will reject all
│ │ │ │ │ - * unexpected characters.
│ │ │ │ │ - */
│ │ │ │ │ - if (/^[\],:{}\s]*$/.test(json.replace(/\\["\\\/bfnrtu]/g, '@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * In the second stage we use the eval function to compile the
│ │ │ │ │ - * text into a JavaScript structure. The '{' operator is
│ │ │ │ │ - * subject to a syntactic ambiguity in JavaScript - it can
│ │ │ │ │ - * begin a block or an object literal. We wrap the text in
│ │ │ │ │ - * parens to eliminate the ambiguity.
│ │ │ │ │ - */
│ │ │ │ │ - object = eval('(' + json + ')');
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * In the optional third stage, we recursively walk the new
│ │ │ │ │ - * structure, passing each name/value pair to a filter
│ │ │ │ │ - * function for possible transformation.
│ │ │ │ │ - */
│ │ │ │ │ - if (typeof filter === 'function') {
│ │ │ │ │ - function walk(k, v) {
│ │ │ │ │ - if (v && typeof v === 'object') {
│ │ │ │ │ - for (var i in v) {
│ │ │ │ │ - if (v.hasOwnProperty(i)) {
│ │ │ │ │ - v[i] = walk(i, v[i]);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return filter(k, v);
│ │ │ │ │ - }
│ │ │ │ │ - object = walk('', object);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - } catch (e) {
│ │ │ │ │ - // Fall through if the regexp test fails.
│ │ │ │ │ - }
│ │ │ │ │ -
│ │ │ │ │ - if (this.keepData) {
│ │ │ │ │ - this.data = object;
│ │ │ │ │ + initialize: function(projCode, options) {
│ │ │ │ │ + OpenLayers.Util.extend(this, options);
│ │ │ │ │ + this.projCode = projCode;
│ │ │ │ │ + if (typeof Proj4js == "object") {
│ │ │ │ │ + this.proj = new Proj4js.Proj(projCode);
│ │ │ │ │ }
│ │ │ │ │ -
│ │ │ │ │ - return object;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: write
│ │ │ │ │ - * Serialize an object into a JSON string.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * value - {String} The object, array, string, number, boolean or date
│ │ │ │ │ - * to be serialized.
│ │ │ │ │ - * pretty - {Boolean} Structure the output with newlines and indentation.
│ │ │ │ │ - * Default is false.
│ │ │ │ │ + * APIMethod: getCode
│ │ │ │ │ + * Get the string SRS code.
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {String} The JSON string representation of the input value.
│ │ │ │ │ + * {String} The SRS code.
│ │ │ │ │ */
│ │ │ │ │ - write: function(value, pretty) {
│ │ │ │ │ - this.pretty = !!pretty;
│ │ │ │ │ - var json = null;
│ │ │ │ │ - var type = typeof value;
│ │ │ │ │ - if (this.serialize[type]) {
│ │ │ │ │ - try {
│ │ │ │ │ - json = (!this.pretty && this.nativeJSON) ?
│ │ │ │ │ - JSON.stringify(value) :
│ │ │ │ │ - this.serialize[type].apply(this, [value]);
│ │ │ │ │ - } catch (err) {
│ │ │ │ │ - OpenLayers.Console.error("Trouble serializing: " + err);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return json;
│ │ │ │ │ + getCode: function() {
│ │ │ │ │ + return this.proj ? this.proj.srsCode : this.projCode;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: writeIndent
│ │ │ │ │ - * Output an indentation string depending on the indentation level.
│ │ │ │ │ + * APIMethod: getUnits
│ │ │ │ │ + * Get the units string for the projection -- returns null if
│ │ │ │ │ + * proj4js is not available.
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {String} An appropriate indentation string.
│ │ │ │ │ + * {String} The units abbreviation.
│ │ │ │ │ */
│ │ │ │ │ - writeIndent: function() {
│ │ │ │ │ - var pieces = [];
│ │ │ │ │ - if (this.pretty) {
│ │ │ │ │ - for (var i = 0; i < this.level; ++i) {
│ │ │ │ │ - pieces.push(this.indent);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return pieces.join('');
│ │ │ │ │ + getUnits: function() {
│ │ │ │ │ + return this.proj ? this.proj.units : null;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: writeNewline
│ │ │ │ │ - * Output a string representing a newline if in pretty printing mode.
│ │ │ │ │ + * Method: toString
│ │ │ │ │ + * Convert projection to string (getCode wrapper).
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {String} A string representing a new line.
│ │ │ │ │ + * {String} The projection code.
│ │ │ │ │ */
│ │ │ │ │ - writeNewline: function() {
│ │ │ │ │ - return (this.pretty) ? this.newline : '';
│ │ │ │ │ + toString: function() {
│ │ │ │ │ + return this.getCode();
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: writeSpace
│ │ │ │ │ - * Output a string representing a space if in pretty printing mode.
│ │ │ │ │ + * Method: equals
│ │ │ │ │ + * Test equality of two projection instances. Determines equality based
│ │ │ │ │ + * soley on the projection code.
│ │ │ │ │ *
│ │ │ │ │ * Returns:
│ │ │ │ │ - * {String} A space.
│ │ │ │ │ + * {Boolean} The two projections are equivalent.
│ │ │ │ │ */
│ │ │ │ │ - writeSpace: function() {
│ │ │ │ │ - return (this.pretty) ? this.space : '';
│ │ │ │ │ + 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;
│ │ │ │ │ },
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Property: serialize
│ │ │ │ │ - * Object with properties corresponding to the serializable data types.
│ │ │ │ │ - * Property values are functions that do the actual serializing.
│ │ │ │ │ + /* Method: destroy
│ │ │ │ │ + * Destroy projection object.
│ │ │ │ │ */
│ │ │ │ │ - serialize: {
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: serialize.object
│ │ │ │ │ - * Transform an object into a JSON string.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * object - {Object} The object to be serialized.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} A JSON string representing the object.
│ │ │ │ │ - */
│ │ │ │ │ - 'object': function(object) {
│ │ │ │ │ - // three special objects that we want to treat differently
│ │ │ │ │ - if (object == null) {
│ │ │ │ │ - return "null";
│ │ │ │ │ - }
│ │ │ │ │ - if (object.constructor == Date) {
│ │ │ │ │ - return this.serialize.date.apply(this, [object]);
│ │ │ │ │ - }
│ │ │ │ │ - if (object.constructor == Array) {
│ │ │ │ │ - return this.serialize.array.apply(this, [object]);
│ │ │ │ │ - }
│ │ │ │ │ - var pieces = ['{'];
│ │ │ │ │ - this.level += 1;
│ │ │ │ │ - var key, keyJSON, valueJSON;
│ │ │ │ │ + destroy: function() {
│ │ │ │ │ + delete this.proj;
│ │ │ │ │ + delete this.projCode;
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ - var addComma = false;
│ │ │ │ │ - for (key in object) {
│ │ │ │ │ - if (object.hasOwnProperty(key)) {
│ │ │ │ │ - // recursive calls need to allow for sub-classing
│ │ │ │ │ - keyJSON = OpenLayers.Format.JSON.prototype.write.apply(this,
│ │ │ │ │ - [key, this.pretty]);
│ │ │ │ │ - valueJSON = OpenLayers.Format.JSON.prototype.write.apply(this,
│ │ │ │ │ - [object[key], this.pretty]);
│ │ │ │ │ - if (keyJSON != null && valueJSON != null) {
│ │ │ │ │ - if (addComma) {
│ │ │ │ │ - pieces.push(',');
│ │ │ │ │ - }
│ │ │ │ │ - pieces.push(this.writeNewline(), this.writeIndent(),
│ │ │ │ │ - keyJSON, ':', this.writeSpace(), valueJSON);
│ │ │ │ │ - addComma = true;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ + CLASS_NAME: "OpenLayers.Projection"
│ │ │ │ │ +});
│ │ │ │ │
│ │ │ │ │ - this.level -= 1;
│ │ │ │ │ - pieces.push(this.writeNewline(), this.writeIndent(), '}');
│ │ │ │ │ - return pieces.join('');
│ │ │ │ │ - },
│ │ │ │ │ +/**
│ │ │ │ │ + * Property: transforms
│ │ │ │ │ + * {Object} Transforms is an object, with from properties, each of which may
│ │ │ │ │ + * have a to property. This allows you to define projections without
│ │ │ │ │ + * requiring support for proj4js to be included.
│ │ │ │ │ + *
│ │ │ │ │ + * This object has keys which correspond to a 'source' projection object. The
│ │ │ │ │ + * keys should be strings, corresponding to the projection.getCode() value.
│ │ │ │ │ + * Each source projection object should have a set of destination projection
│ │ │ │ │ + * keys included in the object.
│ │ │ │ │ + *
│ │ │ │ │ + * Each value in the destination object should be a transformation function,
│ │ │ │ │ + * where the function is expected to be passed an object with a .x and a .y
│ │ │ │ │ + * property. The function should return the object, with the .x and .y
│ │ │ │ │ + * transformed according to the transformation function.
│ │ │ │ │ + *
│ │ │ │ │ + * Note - Properties on this object should not be set directly. To add a
│ │ │ │ │ + * transform method to this object, use the method. For an
│ │ │ │ │ + * example of usage, see the OpenLayers.Layer.SphericalMercator file.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Projection.transforms = {};
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: serialize.array
│ │ │ │ │ - * Transform an array into a JSON string.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * array - {Array} The array to be serialized
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} A JSON string representing the array.
│ │ │ │ │ - */
│ │ │ │ │ - 'array': function(array) {
│ │ │ │ │ - var json;
│ │ │ │ │ - var pieces = ['['];
│ │ │ │ │ - this.level += 1;
│ │ │ │ │ +/**
│ │ │ │ │ + * APIProperty: defaults
│ │ │ │ │ + * {Object} Defaults for the SRS codes known to OpenLayers (currently
│ │ │ │ │ + * EPSG:4326, CRS:84, urn:ogc:def:crs:EPSG:6.6:4326, EPSG:900913, EPSG:3857,
│ │ │ │ │ + * EPSG:102113 and EPSG:102100). Keys are the SRS code, values are units,
│ │ │ │ │ + * maxExtent (the validity extent for the SRS) and yx (true if this SRS is
│ │ │ │ │ + * known to have a reverse axis order).
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Projection.defaults = {
│ │ │ │ │ + "EPSG:4326": {
│ │ │ │ │ + units: "degrees",
│ │ │ │ │ + maxExtent: [-180, -90, 180, 90],
│ │ │ │ │ + yx: true
│ │ │ │ │ + },
│ │ │ │ │ + "CRS:84": {
│ │ │ │ │ + units: "degrees",
│ │ │ │ │ + maxExtent: [-180, -90, 180, 90]
│ │ │ │ │ + },
│ │ │ │ │ + "EPSG:900913": {
│ │ │ │ │ + units: "m",
│ │ │ │ │ + maxExtent: [-20037508.34, -20037508.34, 20037508.34, 20037508.34]
│ │ │ │ │ + }
│ │ │ │ │ +};
│ │ │ │ │
│ │ │ │ │ - for (var i = 0, len = array.length; i < len; ++i) {
│ │ │ │ │ - // recursive calls need to allow for sub-classing
│ │ │ │ │ - json = OpenLayers.Format.JSON.prototype.write.apply(this,
│ │ │ │ │ - [array[i], this.pretty]);
│ │ │ │ │ - if (json != null) {
│ │ │ │ │ - if (i > 0) {
│ │ │ │ │ - pieces.push(',');
│ │ │ │ │ - }
│ │ │ │ │ - pieces.push(this.writeNewline(), this.writeIndent(), json);
│ │ │ │ │ - }
│ │ │ │ │ +/**
│ │ │ │ │ + * APIMethod: addTransform
│ │ │ │ │ + * Set a custom transform method between two projections. Use this method in
│ │ │ │ │ + * cases where the proj4js lib is not available or where custom projections
│ │ │ │ │ + * need to be handled.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * from - {String} The code for the source projection
│ │ │ │ │ + * to - {String} the code for the destination projection
│ │ │ │ │ + * method - {Function} A function that takes a point as an argument and
│ │ │ │ │ + * transforms that point from the source to the destination projection
│ │ │ │ │ + * in place. The original point should be modified.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Projection.addTransform = function(from, to, method) {
│ │ │ │ │ + if (method === OpenLayers.Projection.nullTransform) {
│ │ │ │ │ + var defaults = OpenLayers.Projection.defaults[from];
│ │ │ │ │ + if (defaults && !OpenLayers.Projection.defaults[to]) {
│ │ │ │ │ + OpenLayers.Projection.defaults[to] = defaults;
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + if (!OpenLayers.Projection.transforms[from]) {
│ │ │ │ │ + OpenLayers.Projection.transforms[from] = {};
│ │ │ │ │ + }
│ │ │ │ │ + OpenLayers.Projection.transforms[from][to] = method;
│ │ │ │ │ +};
│ │ │ │ │ +
│ │ │ │ │ +/**
│ │ │ │ │ + * APIMethod: transform
│ │ │ │ │ + * Transform a point coordinate from one projection to another. Note that
│ │ │ │ │ + * the input point is transformed in place.
│ │ │ │ │ + *
│ │ │ │ │ + * Parameters:
│ │ │ │ │ + * point - { | Object} An object with x and y
│ │ │ │ │ + * properties representing coordinates in those dimensions.
│ │ │ │ │ + * source - {OpenLayers.Projection} Source map coordinate system
│ │ │ │ │ + * dest - {OpenLayers.Projection} Destination map coordinate system
│ │ │ │ │ + *
│ │ │ │ │ + * Returns:
│ │ │ │ │ + * point - {object} A transformed coordinate. The original point is modified.
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Projection.transform = function(point, source, dest) {
│ │ │ │ │ + if (source && dest) {
│ │ │ │ │ + if (!(source instanceof OpenLayers.Projection)) {
│ │ │ │ │ + source = new OpenLayers.Projection(source);
│ │ │ │ │ + }
│ │ │ │ │ + if (!(dest instanceof OpenLayers.Projection)) {
│ │ │ │ │ + dest = new OpenLayers.Projection(dest);
│ │ │ │ │ + }
│ │ │ │ │ + if (source.proj && dest.proj) {
│ │ │ │ │ + point = Proj4js.transform(source.proj, dest.proj, point);
│ │ │ │ │ + } else {
│ │ │ │ │ + var sourceCode = source.getCode();
│ │ │ │ │ + var destCode = dest.getCode();
│ │ │ │ │ + var transforms = OpenLayers.Projection.transforms;
│ │ │ │ │ + if (transforms[sourceCode] && transforms[sourceCode][destCode]) {
│ │ │ │ │ + transforms[sourceCode][destCode](point);
│ │ │ │ │ }
│ │ │ │ │ + }
│ │ │ │ │ + }
│ │ │ │ │ + return point;
│ │ │ │ │ +};
│ │ │ │ │
│ │ │ │ │ - this.level -= 1;
│ │ │ │ │ - pieces.push(this.writeNewline(), this.writeIndent(), ']');
│ │ │ │ │ - return pieces.join('');
│ │ │ │ │ - },
│ │ │ │ │ +/**
│ │ │ │ │ + * APIFunction: nullTransform
│ │ │ │ │ + * A null transformation - useful for defining projection aliases when
│ │ │ │ │ + * proj4js is not available:
│ │ │ │ │ + *
│ │ │ │ │ + * (code)
│ │ │ │ │ + * OpenLayers.Projection.addTransform("EPSG:3857", "EPSG:900913",
│ │ │ │ │ + * OpenLayers.Projection.nullTransform);
│ │ │ │ │ + * OpenLayers.Projection.addTransform("EPSG:900913", "EPSG:3857",
│ │ │ │ │ + * OpenLayers.Projection.nullTransform);
│ │ │ │ │ + * (end)
│ │ │ │ │ + */
│ │ │ │ │ +OpenLayers.Projection.nullTransform = function(point) {
│ │ │ │ │ + return point;
│ │ │ │ │ +};
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: serialize.string
│ │ │ │ │ - * Transform a string into a JSON string.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * string - {String} The string to be serialized
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} A JSON string representing the string.
│ │ │ │ │ - */
│ │ │ │ │ - 'string': function(string) {
│ │ │ │ │ - // If the string contains no control characters, no quote characters, and no
│ │ │ │ │ - // backslash characters, then we can simply slap some quotes around it.
│ │ │ │ │ - // Otherwise we must also replace the offending characters with safe
│ │ │ │ │ - // sequences.
│ │ │ │ │ - var m = {
│ │ │ │ │ - '\b': '\\b',
│ │ │ │ │ - '\t': '\\t',
│ │ │ │ │ - '\n': '\\n',
│ │ │ │ │ - '\f': '\\f',
│ │ │ │ │ - '\r': '\\r',
│ │ │ │ │ - '"': '\\"',
│ │ │ │ │ - '\\': '\\\\'
│ │ │ │ │ - };
│ │ │ │ │ - if (/["\\\x00-\x1f]/.test(string)) {
│ │ │ │ │ - return '"' + string.replace(/([\x00-\x1f\\"])/g, function(a, b) {
│ │ │ │ │ - var c = m[b];
│ │ │ │ │ - if (c) {
│ │ │ │ │ - return c;
│ │ │ │ │ - }
│ │ │ │ │ - c = b.charCodeAt();
│ │ │ │ │ - return '\\u00' +
│ │ │ │ │ - Math.floor(c / 16).toString(16) +
│ │ │ │ │ - (c % 16).toString(16);
│ │ │ │ │ - }) + '"';
│ │ │ │ │ - }
│ │ │ │ │ - return '"' + string + '"';
│ │ │ │ │ - },
│ │ │ │ │ +/**
│ │ │ │ │ + * Note: Transforms for web mercator <-> geographic
│ │ │ │ │ + * OpenLayers recognizes EPSG:3857, EPSG:900913, EPSG:102113 and EPSG:102100.
│ │ │ │ │ + * OpenLayers originally started referring to EPSG:900913 as web mercator.
│ │ │ │ │ + * The EPSG has declared EPSG:3857 to be web mercator.
│ │ │ │ │ + * ArcGIS 10 recognizes the EPSG:3857, EPSG:102113, and EPSG:102100 as
│ │ │ │ │ + * equivalent. See http://blogs.esri.com/Dev/blogs/arcgisserver/archive/2009/11/20/ArcGIS-Online-moving-to-Google-_2F00_-Bing-tiling-scheme_3A00_-What-does-this-mean-for-you_3F00_.aspx#12084.
│ │ │ │ │ + * For geographic, OpenLayers recognizes EPSG:4326, CRS:84 and
│ │ │ │ │ + * urn:ogc:def:crs:EPSG:6.6:4326. OpenLayers also knows about the reverse axis
│ │ │ │ │ + * order for EPSG:4326.
│ │ │ │ │ + */
│ │ │ │ │ +(function() {
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: serialize.number
│ │ │ │ │ - * Transform a number into a JSON string.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * number - {Number} The number to be serialized.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} A JSON string representing the number.
│ │ │ │ │ - */
│ │ │ │ │ - 'number': function(number) {
│ │ │ │ │ - return isFinite(number) ? String(number) : "null";
│ │ │ │ │ - },
│ │ │ │ │ + var pole = 20037508.34;
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: serialize.boolean
│ │ │ │ │ - * Transform a boolean into a JSON string.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * bool - {Boolean} The boolean to be serialized.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} A JSON string representing the boolean.
│ │ │ │ │ - */
│ │ │ │ │ - 'boolean': function(bool) {
│ │ │ │ │ - return String(bool);
│ │ │ │ │ - },
│ │ │ │ │ + function inverseMercator(xy) {
│ │ │ │ │ + xy.x = 180 * xy.x / pole;
│ │ │ │ │ + xy.y = 180 / Math.PI * (2 * Math.atan(Math.exp((xy.y / pole) * Math.PI)) - Math.PI / 2);
│ │ │ │ │ + return xy;
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: serialize.object
│ │ │ │ │ - * Transform a date into a JSON string.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * date - {Date} The date to be serialized.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} A JSON string representing the date.
│ │ │ │ │ - */
│ │ │ │ │ - 'date': function(date) {
│ │ │ │ │ - function format(number) {
│ │ │ │ │ - // Format integers to have at least two digits.
│ │ │ │ │ - return (number < 10) ? '0' + number : number;
│ │ │ │ │ + function forwardMercator(xy) {
│ │ │ │ │ + xy.x = xy.x * pole / 180;
│ │ │ │ │ + var y = Math.log(Math.tan((90 + xy.y) * Math.PI / 360)) / Math.PI * pole;
│ │ │ │ │ + xy.y = Math.max(-20037508.34, Math.min(y, 20037508.34));
│ │ │ │ │ + return xy;
│ │ │ │ │ + }
│ │ │ │ │ +
│ │ │ │ │ + function map(base, codes) {
│ │ │ │ │ + var add = OpenLayers.Projection.addTransform;
│ │ │ │ │ + var same = OpenLayers.Projection.nullTransform;
│ │ │ │ │ + var i, len, code, other, j;
│ │ │ │ │ + for (i = 0, len = codes.length; i < len; ++i) {
│ │ │ │ │ + code = codes[i];
│ │ │ │ │ + add(base, code, forwardMercator);
│ │ │ │ │ + add(code, base, inverseMercator);
│ │ │ │ │ + for (j = i + 1; j < len; ++j) {
│ │ │ │ │ + other = codes[j];
│ │ │ │ │ + add(code, other, same);
│ │ │ │ │ + add(other, code, same);
│ │ │ │ │ }
│ │ │ │ │ - return '"' + date.getFullYear() + '-' +
│ │ │ │ │ - format(date.getMonth() + 1) + '-' +
│ │ │ │ │ - format(date.getDate()) + 'T' +
│ │ │ │ │ - format(date.getHours()) + ':' +
│ │ │ │ │ - format(date.getMinutes()) + ':' +
│ │ │ │ │ - format(date.getSeconds()) + '"';
│ │ │ │ │ }
│ │ │ │ │ - },
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Format.JSON"
│ │ │ │ │ + // list of equivalent codes for web mercator
│ │ │ │ │ + var mercator = ["EPSG:900913", "EPSG:3857", "EPSG:102113", "EPSG:102100"],
│ │ │ │ │ + geographic = ["CRS:84", "urn:ogc:def:crs:EPSG:6.6:4326", "EPSG:4326"],
│ │ │ │ │ + i;
│ │ │ │ │ + for (i = mercator.length - 1; i >= 0; --i) {
│ │ │ │ │ + map(mercator[i], geographic);
│ │ │ │ │ + }
│ │ │ │ │ + for (i = geographic.length - 1; i >= 0; --i) {
│ │ │ │ │ + map(geographic[i], mercator);
│ │ │ │ │ + }
│ │ │ │ │
│ │ │ │ │ -});
│ │ │ │ │ +})();
│ │ │ │ │ /* ======================================================================
│ │ │ │ │ - OpenLayers/Format/GeoJSON.js
│ │ │ │ │ + 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. */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * @requires OpenLayers/Format/JSON.js
│ │ │ │ │ - * @requires OpenLayers/Feature/Vector.js
│ │ │ │ │ - * @requires OpenLayers/Geometry/Point.js
│ │ │ │ │ - * @requires OpenLayers/Geometry/MultiPoint.js
│ │ │ │ │ - * @requires OpenLayers/Geometry/LineString.js
│ │ │ │ │ - * @requires OpenLayers/Geometry/MultiLineString.js
│ │ │ │ │ - * @requires OpenLayers/Geometry/Polygon.js
│ │ │ │ │ - * @requires OpenLayers/Geometry/MultiPolygon.js
│ │ │ │ │ - * @requires OpenLayers/Console.js
│ │ │ │ │ + * @requires OpenLayers/BaseTypes/Class.js
│ │ │ │ │ + * @requires OpenLayers/Util.js
│ │ │ │ │ + * @requires OpenLayers/Util/vendorPrefix.js
│ │ │ │ │ + * @requires OpenLayers/Events.js
│ │ │ │ │ + * @requires OpenLayers/Tween.js
│ │ │ │ │ + * @requires OpenLayers/Projection.js
│ │ │ │ │ */
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Class: OpenLayers.Format.GeoJSON
│ │ │ │ │ - * Read and write GeoJSON. Create a new parser with the
│ │ │ │ │ - * constructor.
│ │ │ │ │ - *
│ │ │ │ │ - * Inherits from:
│ │ │ │ │ - * -
│ │ │ │ │ + * Class: OpenLayers.Map
│ │ │ │ │ + * Instances of OpenLayers.Map are interactive maps embedded in a web page.
│ │ │ │ │ + * Create a new map with the constructor.
│ │ │ │ │ + *
│ │ │ │ │ + * On their own maps do not provide much functionality. To extend a map
│ │ │ │ │ + * it's necessary to add controls () and
│ │ │ │ │ + * layers () to the map.
│ │ │ │ │ */
│ │ │ │ │ -OpenLayers.Format.GeoJSON = OpenLayers.Class(OpenLayers.Format.JSON, {
│ │ │ │ │ +OpenLayers.Map = OpenLayers.Class({
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIProperty: ignoreExtraDims
│ │ │ │ │ - * {Boolean} Ignore dimensions higher than 2 when reading geometry
│ │ │ │ │ - * coordinates.
│ │ │ │ │ + * Constant: Z_INDEX_BASE
│ │ │ │ │ + * {Object} Base z-indexes for different classes of thing
│ │ │ │ │ */
│ │ │ │ │ - ignoreExtraDims: false,
│ │ │ │ │ + Z_INDEX_BASE: {
│ │ │ │ │ + BaseLayer: 100,
│ │ │ │ │ + Overlay: 325,
│ │ │ │ │ + Feature: 725,
│ │ │ │ │ + Popup: 750,
│ │ │ │ │ + Control: 1000
│ │ │ │ │ + },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Constructor: OpenLayers.Format.GeoJSON
│ │ │ │ │ - * Create a new parser for GeoJSON.
│ │ │ │ │ + * APIProperty: events
│ │ │ │ │ + * {}
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * options - {Object} An optional object whose properties will be set on
│ │ │ │ │ - * this instance.
│ │ │ │ │ - */
│ │ │ │ │ -
│ │ │ │ │ - /**
│ │ │ │ │ - * APIMethod: read
│ │ │ │ │ - * Deserialize a GeoJSON string.
│ │ │ │ │ + * Register a listener for a particular event with the following syntax:
│ │ │ │ │ + * (code)
│ │ │ │ │ + * map.events.register(type, obj, listener);
│ │ │ │ │ + * (end)
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * json - {String} A GeoJSON string
│ │ │ │ │ - * type - {String} Optional string that determines the structure of
│ │ │ │ │ - * the output. Supported values are "Geometry", "Feature", and
│ │ │ │ │ - * "FeatureCollection". If absent or null, a default of
│ │ │ │ │ - * "FeatureCollection" is assumed.
│ │ │ │ │ - * filter - {Function} A function which will be called for every key and
│ │ │ │ │ - * value at every level of the final result. Each value will be
│ │ │ │ │ - * replaced by the result of the filter function. This can be used to
│ │ │ │ │ - * reform generic objects into instances of classes, or to transform
│ │ │ │ │ - * date strings into Date objects.
│ │ │ │ │ + * Listeners will be called with a reference to an event object. The
│ │ │ │ │ + * properties of this event depends on exactly what happened.
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Object} The return depends on the value of the type argument. If type
│ │ │ │ │ - * is "FeatureCollection" (the default), the return will be an array
│ │ │ │ │ - * of . If type is "Geometry", the input json
│ │ │ │ │ - * must represent a single geometry, and the return will be an
│ │ │ │ │ - * . If type is "Feature", the input json must
│ │ │ │ │ - * represent a single feature, and the return will be an
│ │ │ │ │ - * .
│ │ │ │ │ + * All event objects have at least the following properties:
│ │ │ │ │ + * object - {Object} A reference to map.events.object.
│ │ │ │ │ + * element - {DOMElement} A reference to map.events.element.
│ │ │ │ │ + *
│ │ │ │ │ + * Browser events have the following additional properties:
│ │ │ │ │ + * xy - {} The pixel location of the event (relative
│ │ │ │ │ + * to the the map viewport).
│ │ │ │ │ + *
│ │ │ │ │ + * Supported map event types:
│ │ │ │ │ + * preaddlayer - triggered before a layer has been added. The event
│ │ │ │ │ + * object will include a *layer* property that references the layer
│ │ │ │ │ + * to be added. When a listener returns "false" the adding will be
│ │ │ │ │ + * aborted.
│ │ │ │ │ + * addlayer - triggered after a layer has been added. The event object
│ │ │ │ │ + * will include a *layer* property that references the added layer.
│ │ │ │ │ + * preremovelayer - triggered before a layer has been removed. The event
│ │ │ │ │ + * object will include a *layer* property that references the layer
│ │ │ │ │ + * to be removed. When a listener returns "false" the removal will be
│ │ │ │ │ + * aborted.
│ │ │ │ │ + * removelayer - triggered after a layer has been removed. The event
│ │ │ │ │ + * object will include a *layer* property that references the removed
│ │ │ │ │ + * layer.
│ │ │ │ │ + * changelayer - triggered after a layer name change, order change,
│ │ │ │ │ + * opacity change, params change, visibility change (actual visibility,
│ │ │ │ │ + * not the layer's visibility property) or attribution change (due to
│ │ │ │ │ + * extent change). Listeners will receive an event object with *layer*
│ │ │ │ │ + * and *property* properties. The *layer* property will be a reference
│ │ │ │ │ + * to the changed layer. The *property* property will be a key to the
│ │ │ │ │ + * changed property (name, order, opacity, params, visibility or
│ │ │ │ │ + * attribution).
│ │ │ │ │ + * movestart - triggered after the start of a drag, pan, or zoom. The event
│ │ │ │ │ + * object may include a *zoomChanged* property that tells whether the
│ │ │ │ │ + * zoom has changed.
│ │ │ │ │ + * move - triggered after each drag, pan, or zoom
│ │ │ │ │ + * moveend - triggered after a drag, pan, or zoom completes
│ │ │ │ │ + * zoomend - triggered after a zoom completes
│ │ │ │ │ + * mouseover - triggered after mouseover the map
│ │ │ │ │ + * mouseout - triggered after mouseout the map
│ │ │ │ │ + * mousemove - triggered after mousemove the map
│ │ │ │ │ + * changebaselayer - triggered after the base layer changes
│ │ │ │ │ + * updatesize - triggered after the method was executed
│ │ │ │ │ */
│ │ │ │ │ - read: function(json, type, filter) {
│ │ │ │ │ - type = (type) ? type : "FeatureCollection";
│ │ │ │ │ - var results = null;
│ │ │ │ │ - var obj = null;
│ │ │ │ │ - if (typeof json == "string") {
│ │ │ │ │ - obj = OpenLayers.Format.JSON.prototype.read.apply(this,
│ │ │ │ │ - [json, filter]);
│ │ │ │ │ - } else {
│ │ │ │ │ - obj = json;
│ │ │ │ │ - }
│ │ │ │ │ - if (!obj) {
│ │ │ │ │ - OpenLayers.Console.error("Bad JSON: " + json);
│ │ │ │ │ - } else if (typeof(obj.type) != "string") {
│ │ │ │ │ - OpenLayers.Console.error("Bad GeoJSON - no type: " + json);
│ │ │ │ │ - } else if (this.isValidType(obj, type)) {
│ │ │ │ │ - switch (type) {
│ │ │ │ │ - case "Geometry":
│ │ │ │ │ - try {
│ │ │ │ │ - results = this.parseGeometry(obj);
│ │ │ │ │ - } catch (err) {
│ │ │ │ │ - OpenLayers.Console.error(err);
│ │ │ │ │ - }
│ │ │ │ │ - break;
│ │ │ │ │ - case "Feature":
│ │ │ │ │ - try {
│ │ │ │ │ - results = this.parseFeature(obj);
│ │ │ │ │ - results.type = "Feature";
│ │ │ │ │ - } catch (err) {
│ │ │ │ │ - OpenLayers.Console.error(err);
│ │ │ │ │ - }
│ │ │ │ │ - break;
│ │ │ │ │ - case "FeatureCollection":
│ │ │ │ │ - // for type FeatureCollection, we allow input to be any type
│ │ │ │ │ - results = [];
│ │ │ │ │ - switch (obj.type) {
│ │ │ │ │ - case "Feature":
│ │ │ │ │ - try {
│ │ │ │ │ - results.push(this.parseFeature(obj));
│ │ │ │ │ - } catch (err) {
│ │ │ │ │ - results = null;
│ │ │ │ │ - OpenLayers.Console.error(err);
│ │ │ │ │ - }
│ │ │ │ │ - break;
│ │ │ │ │ - case "FeatureCollection":
│ │ │ │ │ - for (var i = 0, len = obj.features.length; i < len; ++i) {
│ │ │ │ │ - try {
│ │ │ │ │ - results.push(this.parseFeature(obj.features[i]));
│ │ │ │ │ - } catch (err) {
│ │ │ │ │ - results = null;
│ │ │ │ │ - OpenLayers.Console.error(err);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - break;
│ │ │ │ │ - default:
│ │ │ │ │ - try {
│ │ │ │ │ - var geom = this.parseGeometry(obj);
│ │ │ │ │ - results.push(new OpenLayers.Feature.Vector(geom));
│ │ │ │ │ - } catch (err) {
│ │ │ │ │ - results = null;
│ │ │ │ │ - OpenLayers.Console.error(err);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - break;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return results;
│ │ │ │ │ - },
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: isValidType
│ │ │ │ │ - * Check if a GeoJSON object is a valid representative of the given type.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Boolean} The object is valid GeoJSON object of the given type.
│ │ │ │ │ + * Property: id
│ │ │ │ │ + * {String} Unique identifier for the map
│ │ │ │ │ */
│ │ │ │ │ - isValidType: function(obj, type) {
│ │ │ │ │ - var valid = false;
│ │ │ │ │ - switch (type) {
│ │ │ │ │ - case "Geometry":
│ │ │ │ │ - if (OpenLayers.Util.indexOf(
│ │ │ │ │ - ["Point", "MultiPoint", "LineString", "MultiLineString",
│ │ │ │ │ - "Polygon", "MultiPolygon", "Box", "GeometryCollection"
│ │ │ │ │ - ],
│ │ │ │ │ - obj.type) == -1) {
│ │ │ │ │ - // unsupported geometry type
│ │ │ │ │ - OpenLayers.Console.error("Unsupported geometry type: " +
│ │ │ │ │ - obj.type);
│ │ │ │ │ - } else {
│ │ │ │ │ - valid = true;
│ │ │ │ │ - }
│ │ │ │ │ - break;
│ │ │ │ │ - case "FeatureCollection":
│ │ │ │ │ - // allow for any type to be converted to a feature collection
│ │ │ │ │ - valid = true;
│ │ │ │ │ - break;
│ │ │ │ │ - default:
│ │ │ │ │ - // for Feature types must match
│ │ │ │ │ - if (obj.type == type) {
│ │ │ │ │ - valid = true;
│ │ │ │ │ - } else {
│ │ │ │ │ - OpenLayers.Console.error("Cannot convert types from " +
│ │ │ │ │ - obj.type + " to " + type);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return valid;
│ │ │ │ │ - },
│ │ │ │ │ + id: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: parseFeature
│ │ │ │ │ - * Convert a feature object from GeoJSON into an
│ │ │ │ │ - * .
│ │ │ │ │ + * Property: fractionalZoom
│ │ │ │ │ + * {Boolean} For a base layer that supports it, allow the map resolution
│ │ │ │ │ + * to be set to a value between one of the values in the resolutions
│ │ │ │ │ + * array. Default is false.
│ │ │ │ │ *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * obj - {Object} An object created from a GeoJSON object
│ │ │ │ │ + * When fractionalZoom is set to true, it is possible to zoom to
│ │ │ │ │ + * an arbitrary extent. This requires a base layer from a source
│ │ │ │ │ + * that supports requests for arbitrary extents (i.e. not cached
│ │ │ │ │ + * tiles on a regular lattice). This means that fractionalZoom
│ │ │ │ │ + * will not work with commercial layers (Google, Yahoo, VE), layers
│ │ │ │ │ + * using TileCache, or any other pre-cached data sources.
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} A feature.
│ │ │ │ │ + * If you are using fractionalZoom, then you should also use
│ │ │ │ │ + * instead of layer.resolutions[zoom] as the
│ │ │ │ │ + * former works for non-integer zoom levels.
│ │ │ │ │ */
│ │ │ │ │ - parseFeature: function(obj) {
│ │ │ │ │ - var feature, geometry, attributes, bbox;
│ │ │ │ │ - attributes = (obj.properties) ? obj.properties : {};
│ │ │ │ │ - bbox = (obj.geometry && obj.geometry.bbox) || obj.bbox;
│ │ │ │ │ - try {
│ │ │ │ │ - geometry = this.parseGeometry(obj.geometry);
│ │ │ │ │ - } catch (err) {
│ │ │ │ │ - // deal with bad geometries
│ │ │ │ │ - throw err;
│ │ │ │ │ - }
│ │ │ │ │ - feature = new OpenLayers.Feature.Vector(geometry, attributes);
│ │ │ │ │ - if (bbox) {
│ │ │ │ │ - feature.bounds = OpenLayers.Bounds.fromArray(bbox);
│ │ │ │ │ - }
│ │ │ │ │ - if (obj.id) {
│ │ │ │ │ - feature.fid = obj.id;
│ │ │ │ │ - }
│ │ │ │ │ - return feature;
│ │ │ │ │ - },
│ │ │ │ │ + fractionalZoom: false,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: parseGeometry
│ │ │ │ │ - * Convert a geometry object from GeoJSON into an .
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * obj - {Object} An object created from a GeoJSON object
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} A geometry.
│ │ │ │ │ + * APIProperty: events
│ │ │ │ │ + * {} An events object that handles all
│ │ │ │ │ + * events on the map
│ │ │ │ │ */
│ │ │ │ │ - parseGeometry: function(obj) {
│ │ │ │ │ - if (obj == null) {
│ │ │ │ │ - return null;
│ │ │ │ │ - }
│ │ │ │ │ - var geometry, collection = false;
│ │ │ │ │ - if (obj.type == "GeometryCollection") {
│ │ │ │ │ - if (!(OpenLayers.Util.isArray(obj.geometries))) {
│ │ │ │ │ - throw "GeometryCollection must have geometries array: " + obj;
│ │ │ │ │ - }
│ │ │ │ │ - var numGeom = obj.geometries.length;
│ │ │ │ │ - var components = new Array(numGeom);
│ │ │ │ │ - for (var i = 0; i < numGeom; ++i) {
│ │ │ │ │ - components[i] = this.parseGeometry.apply(
│ │ │ │ │ - this, [obj.geometries[i]]
│ │ │ │ │ - );
│ │ │ │ │ - }
│ │ │ │ │ - geometry = new OpenLayers.Geometry.Collection(components);
│ │ │ │ │ - collection = true;
│ │ │ │ │ - } else {
│ │ │ │ │ - if (!(OpenLayers.Util.isArray(obj.coordinates))) {
│ │ │ │ │ - throw "Geometry must have coordinates array: " + obj;
│ │ │ │ │ - }
│ │ │ │ │ - if (!this.parseCoords[obj.type.toLowerCase()]) {
│ │ │ │ │ - throw "Unsupported geometry type: " + obj.type;
│ │ │ │ │ - }
│ │ │ │ │ - try {
│ │ │ │ │ - geometry = this.parseCoords[obj.type.toLowerCase()].apply(
│ │ │ │ │ - this, [obj.coordinates]
│ │ │ │ │ - );
│ │ │ │ │ - } catch (err) {
│ │ │ │ │ - // deal with bad coordinates
│ │ │ │ │ - throw err;
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - // We don't reproject collections because the children are reprojected
│ │ │ │ │ - // for us when they are created.
│ │ │ │ │ - if (this.internalProjection && this.externalProjection && !collection) {
│ │ │ │ │ - geometry.transform(this.externalProjection,
│ │ │ │ │ - this.internalProjection);
│ │ │ │ │ - }
│ │ │ │ │ - return geometry;
│ │ │ │ │ - },
│ │ │ │ │ + events: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: parseCoords
│ │ │ │ │ - * Object with properties corresponding to the GeoJSON geometry types.
│ │ │ │ │ - * Property values are functions that do the actual parsing.
│ │ │ │ │ + * APIProperty: allOverlays
│ │ │ │ │ + * {Boolean} Allow the map to function with "overlays" only. Defaults to
│ │ │ │ │ + * false. If true, the lowest layer in the draw order will act as
│ │ │ │ │ + * the base layer. In addition, if set to true, all layers will
│ │ │ │ │ + * have isBaseLayer set to false when they are added to the map.
│ │ │ │ │ + *
│ │ │ │ │ + * Note:
│ │ │ │ │ + * If you set map.allOverlays to true, then you *cannot* use
│ │ │ │ │ + * map.setBaseLayer or layer.setIsBaseLayer. With allOverlays true,
│ │ │ │ │ + * the lowest layer in the draw layer is the base layer. So, to change
│ │ │ │ │ + * the base layer, use or to set the layer
│ │ │ │ │ + * index to 0.
│ │ │ │ │ */
│ │ │ │ │ - parseCoords: {
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: parseCoords.point
│ │ │ │ │ - * Convert a coordinate array from GeoJSON into an
│ │ │ │ │ - * .
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * array - {Object} The coordinates array from the GeoJSON fragment.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} A geometry.
│ │ │ │ │ - */
│ │ │ │ │ - "point": function(array) {
│ │ │ │ │ - if (this.ignoreExtraDims == false &&
│ │ │ │ │ - array.length != 2) {
│ │ │ │ │ - throw "Only 2D points are supported: " + array;
│ │ │ │ │ - }
│ │ │ │ │ - return new OpenLayers.Geometry.Point(array[0], array[1]);
│ │ │ │ │ - },
│ │ │ │ │ + allOverlays: false,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: parseCoords.multipoint
│ │ │ │ │ - * Convert a coordinate array from GeoJSON into an
│ │ │ │ │ - * .
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * array - {Object} The coordinates array from the GeoJSON fragment.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} A geometry.
│ │ │ │ │ - */
│ │ │ │ │ - "multipoint": function(array) {
│ │ │ │ │ - var points = [];
│ │ │ │ │ - var p = null;
│ │ │ │ │ - for (var i = 0, len = array.length; i < len; ++i) {
│ │ │ │ │ - try {
│ │ │ │ │ - p = this.parseCoords["point"].apply(this, [array[i]]);
│ │ │ │ │ - } catch (err) {
│ │ │ │ │ - throw err;
│ │ │ │ │ - }
│ │ │ │ │ - points.push(p);
│ │ │ │ │ - }
│ │ │ │ │ - return new OpenLayers.Geometry.MultiPoint(points);
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: div
│ │ │ │ │ + * {DOMElement|String} The element that contains the map (or an id for
│ │ │ │ │ + * that element). If the constructor is called
│ │ │ │ │ + * with two arguments, this should be provided as the first argument.
│ │ │ │ │ + * Alternatively, the map constructor can be called with the options
│ │ │ │ │ + * object as the only argument. In this case (one argument), a
│ │ │ │ │ + * div property may or may not be provided. If the div property
│ │ │ │ │ + * is not provided, the map can be rendered to a container later
│ │ │ │ │ + * using the method.
│ │ │ │ │ + *
│ │ │ │ │ + * Note:
│ │ │ │ │ + * If you are calling after map construction, do not use
│ │ │ │ │ + * auto. Instead, divide your by your
│ │ │ │ │ + * maximum expected dimension.
│ │ │ │ │ + */
│ │ │ │ │ + div: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: parseCoords.linestring
│ │ │ │ │ - * Convert a coordinate array from GeoJSON into an
│ │ │ │ │ - * .
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * array - {Object} The coordinates array from the GeoJSON fragment.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} A geometry.
│ │ │ │ │ - */
│ │ │ │ │ - "linestring": function(array) {
│ │ │ │ │ - var points = [];
│ │ │ │ │ - var p = null;
│ │ │ │ │ - for (var i = 0, len = array.length; i < len; ++i) {
│ │ │ │ │ - try {
│ │ │ │ │ - p = this.parseCoords["point"].apply(this, [array[i]]);
│ │ │ │ │ - } catch (err) {
│ │ │ │ │ - throw err;
│ │ │ │ │ - }
│ │ │ │ │ - points.push(p);
│ │ │ │ │ - }
│ │ │ │ │ - return new OpenLayers.Geometry.LineString(points);
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: dragging
│ │ │ │ │ + * {Boolean} The map is currently being dragged.
│ │ │ │ │ + */
│ │ │ │ │ + dragging: false,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: parseCoords.multilinestring
│ │ │ │ │ - * Convert a coordinate array from GeoJSON into an
│ │ │ │ │ - * .
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * array - {Object} The coordinates array from the GeoJSON fragment.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} A geometry.
│ │ │ │ │ - */
│ │ │ │ │ - "multilinestring": function(array) {
│ │ │ │ │ - var lines = [];
│ │ │ │ │ - var l = null;
│ │ │ │ │ - for (var i = 0, len = array.length; i < len; ++i) {
│ │ │ │ │ - try {
│ │ │ │ │ - l = this.parseCoords["linestring"].apply(this, [array[i]]);
│ │ │ │ │ - } catch (err) {
│ │ │ │ │ - throw err;
│ │ │ │ │ - }
│ │ │ │ │ - lines.push(l);
│ │ │ │ │ - }
│ │ │ │ │ - return new OpenLayers.Geometry.MultiLineString(lines);
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: size
│ │ │ │ │ + * {} Size of the main div (this.div)
│ │ │ │ │ + */
│ │ │ │ │ + size: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: parseCoords.polygon
│ │ │ │ │ - * Convert a coordinate array from GeoJSON into an
│ │ │ │ │ - * .
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} A geometry.
│ │ │ │ │ - */
│ │ │ │ │ - "polygon": function(array) {
│ │ │ │ │ - var rings = [];
│ │ │ │ │ - var r, l;
│ │ │ │ │ - for (var i = 0, len = array.length; i < len; ++i) {
│ │ │ │ │ - try {
│ │ │ │ │ - l = this.parseCoords["linestring"].apply(this, [array[i]]);
│ │ │ │ │ - } catch (err) {
│ │ │ │ │ - throw err;
│ │ │ │ │ - }
│ │ │ │ │ - r = new OpenLayers.Geometry.LinearRing(l.components);
│ │ │ │ │ - rings.push(r);
│ │ │ │ │ - }
│ │ │ │ │ - return new OpenLayers.Geometry.Polygon(rings);
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: viewPortDiv
│ │ │ │ │ + * {HTMLDivElement} The element that represents the map viewport
│ │ │ │ │ + */
│ │ │ │ │ + viewPortDiv: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: parseCoords.multipolygon
│ │ │ │ │ - * Convert a coordinate array from GeoJSON into an
│ │ │ │ │ - * .
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * array - {Object} The coordinates array from the GeoJSON fragment.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} A geometry.
│ │ │ │ │ - */
│ │ │ │ │ - "multipolygon": function(array) {
│ │ │ │ │ - var polys = [];
│ │ │ │ │ - var p = null;
│ │ │ │ │ - for (var i = 0, len = array.length; i < len; ++i) {
│ │ │ │ │ - try {
│ │ │ │ │ - p = this.parseCoords["polygon"].apply(this, [array[i]]);
│ │ │ │ │ - } catch (err) {
│ │ │ │ │ - throw err;
│ │ │ │ │ - }
│ │ │ │ │ - polys.push(p);
│ │ │ │ │ - }
│ │ │ │ │ - return new OpenLayers.Geometry.MultiPolygon(polys);
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: layerContainerOrigin
│ │ │ │ │ + * {} The lonlat at which the later container was
│ │ │ │ │ + * re-initialized (on-zoom)
│ │ │ │ │ + */
│ │ │ │ │ + layerContainerOrigin: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: parseCoords.box
│ │ │ │ │ - * Convert a coordinate array from GeoJSON into an
│ │ │ │ │ - * .
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * array - {Object} The coordinates array from the GeoJSON fragment.
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {} A geometry.
│ │ │ │ │ - */
│ │ │ │ │ - "box": function(array) {
│ │ │ │ │ - if (array.length != 2) {
│ │ │ │ │ - throw "GeoJSON box coordinates must have 2 elements";
│ │ │ │ │ - }
│ │ │ │ │ - return new OpenLayers.Geometry.Polygon([
│ │ │ │ │ - new OpenLayers.Geometry.LinearRing([
│ │ │ │ │ - new OpenLayers.Geometry.Point(array[0][0], array[0][1]),
│ │ │ │ │ - new OpenLayers.Geometry.Point(array[1][0], array[0][1]),
│ │ │ │ │ - new OpenLayers.Geometry.Point(array[1][0], array[1][1]),
│ │ │ │ │ - new OpenLayers.Geometry.Point(array[0][0], array[1][1]),
│ │ │ │ │ - new OpenLayers.Geometry.Point(array[0][0], array[0][1])
│ │ │ │ │ - ])
│ │ │ │ │ - ]);
│ │ │ │ │ - }
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: layerContainerDiv
│ │ │ │ │ + * {HTMLDivElement} The element that contains the layers.
│ │ │ │ │ + */
│ │ │ │ │ + layerContainerDiv: null,
│ │ │ │ │
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: layers
│ │ │ │ │ + * {Array()} Ordered list of layers in the map
│ │ │ │ │ + */
│ │ │ │ │ + layers: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * APIMethod: write
│ │ │ │ │ - * Serialize a feature, geometry, array of features into a GeoJSON string.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * obj - {Object} An , ,
│ │ │ │ │ - * or an array of features.
│ │ │ │ │ - * pretty - {Boolean} Structure the output with newlines and indentation.
│ │ │ │ │ - * Default is false.
│ │ │ │ │ + * APIProperty: controls
│ │ │ │ │ + * {Array()} List of controls associated with the map.
│ │ │ │ │ *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {String} The GeoJSON string representation of the input geometry,
│ │ │ │ │ - * features, or array of features.
│ │ │ │ │ + * If not provided in the map options at construction, the map will
│ │ │ │ │ + * by default be given the following controls if present in the build:
│ │ │ │ │ + * - or
│ │ │ │ │ + * - or
│ │ │ │ │ + * -
│ │ │ │ │ + * -
│ │ │ │ │ */
│ │ │ │ │ - write: function(obj, pretty) {
│ │ │ │ │ - var geojson = {
│ │ │ │ │ - "type": null
│ │ │ │ │ - };
│ │ │ │ │ - if (OpenLayers.Util.isArray(obj)) {
│ │ │ │ │ - geojson.type = "FeatureCollection";
│ │ │ │ │ - var numFeatures = obj.length;
│ │ │ │ │ - geojson.features = new Array(numFeatures);
│ │ │ │ │ - for (var i = 0; i < numFeatures; ++i) {
│ │ │ │ │ - var element = obj[i];
│ │ │ │ │ - if (!element instanceof OpenLayers.Feature.Vector) {
│ │ │ │ │ - var msg = "FeatureCollection only supports collections " +
│ │ │ │ │ - "of features: " + element;
│ │ │ │ │ - throw msg;
│ │ │ │ │ - }
│ │ │ │ │ - geojson.features[i] = this.extract.feature.apply(
│ │ │ │ │ - this, [element]
│ │ │ │ │ - );
│ │ │ │ │ - }
│ │ │ │ │ - } else if (obj.CLASS_NAME.indexOf("OpenLayers.Geometry") == 0) {
│ │ │ │ │ - geojson = this.extract.geometry.apply(this, [obj]);
│ │ │ │ │ - } else if (obj instanceof OpenLayers.Feature.Vector) {
│ │ │ │ │ - geojson = this.extract.feature.apply(this, [obj]);
│ │ │ │ │ - if (obj.layer && obj.layer.projection) {
│ │ │ │ │ - geojson.crs = this.createCRSObject(obj);
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return OpenLayers.Format.JSON.prototype.write.apply(this,
│ │ │ │ │ - [geojson, pretty]);
│ │ │ │ │ - },
│ │ │ │ │ + controls: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Method: createCRSObject
│ │ │ │ │ - * Create the CRS object for an object.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * object - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Object} An object which can be assigned to the crs property
│ │ │ │ │ - * of a GeoJSON object.
│ │ │ │ │ + * Property: popups
│ │ │ │ │ + * {Array()} List of popups associated with the map
│ │ │ │ │ */
│ │ │ │ │ - createCRSObject: function(object) {
│ │ │ │ │ - var proj = object.layer.projection.toString();
│ │ │ │ │ - var crs = {};
│ │ │ │ │ - if (proj.match(/epsg:/i)) {
│ │ │ │ │ - var code = parseInt(proj.substring(proj.indexOf(":") + 1));
│ │ │ │ │ - if (code == 4326) {
│ │ │ │ │ - crs = {
│ │ │ │ │ - "type": "name",
│ │ │ │ │ - "properties": {
│ │ │ │ │ - "name": "urn:ogc:def:crs:OGC:1.3:CRS84"
│ │ │ │ │ - }
│ │ │ │ │ - };
│ │ │ │ │ - } else {
│ │ │ │ │ - crs = {
│ │ │ │ │ - "type": "name",
│ │ │ │ │ - "properties": {
│ │ │ │ │ - "name": "EPSG:" + code
│ │ │ │ │ - }
│ │ │ │ │ - };
│ │ │ │ │ - }
│ │ │ │ │ - }
│ │ │ │ │ - return crs;
│ │ │ │ │ - },
│ │ │ │ │ + popups: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: extract
│ │ │ │ │ - * Object with properties corresponding to the GeoJSON types.
│ │ │ │ │ - * Property values are functions that do the actual value extraction.
│ │ │ │ │ + * APIProperty: baseLayer
│ │ │ │ │ + * {} The currently selected base layer. This determines
│ │ │ │ │ + * min/max zoom level, projection, etc.
│ │ │ │ │ */
│ │ │ │ │ - extract: {
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: extract.feature
│ │ │ │ │ - * Return a partial GeoJSON object representing a single feature.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * feature - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Object} An object representing the point.
│ │ │ │ │ - */
│ │ │ │ │ - 'feature': function(feature) {
│ │ │ │ │ - var geom = this.extract.geometry.apply(this, [feature.geometry]);
│ │ │ │ │ - var json = {
│ │ │ │ │ - "type": "Feature",
│ │ │ │ │ - "properties": feature.attributes,
│ │ │ │ │ - "geometry": geom
│ │ │ │ │ - };
│ │ │ │ │ - if (feature.fid != null) {
│ │ │ │ │ - json.id = feature.fid;
│ │ │ │ │ - }
│ │ │ │ │ - return json;
│ │ │ │ │ - },
│ │ │ │ │ + baseLayer: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: extract.geometry
│ │ │ │ │ - * Return a GeoJSON object representing a single geometry.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * geometry - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Object} An object representing the geometry.
│ │ │ │ │ - */
│ │ │ │ │ - 'geometry': function(geometry) {
│ │ │ │ │ - if (geometry == null) {
│ │ │ │ │ - return null;
│ │ │ │ │ - }
│ │ │ │ │ - if (this.internalProjection && this.externalProjection) {
│ │ │ │ │ - geometry = geometry.clone();
│ │ │ │ │ - geometry.transform(this.internalProjection,
│ │ │ │ │ - this.externalProjection);
│ │ │ │ │ - }
│ │ │ │ │ - var geometryType = geometry.CLASS_NAME.split('.')[2];
│ │ │ │ │ - var data = this.extract[geometryType.toLowerCase()].apply(this, [geometry]);
│ │ │ │ │ - var json;
│ │ │ │ │ - if (geometryType == "Collection") {
│ │ │ │ │ - json = {
│ │ │ │ │ - "type": "GeometryCollection",
│ │ │ │ │ - "geometries": data
│ │ │ │ │ - };
│ │ │ │ │ - } else {
│ │ │ │ │ - json = {
│ │ │ │ │ - "type": geometryType,
│ │ │ │ │ - "coordinates": data
│ │ │ │ │ - };
│ │ │ │ │ - }
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: center
│ │ │ │ │ + * {} The current center of the map
│ │ │ │ │ + */
│ │ │ │ │ + center: null,
│ │ │ │ │
│ │ │ │ │ - return json;
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: resolution
│ │ │ │ │ + * {Float} The resolution of the map.
│ │ │ │ │ + */
│ │ │ │ │ + resolution: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: extract.point
│ │ │ │ │ - * Return an array of coordinates from a point.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * point - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Array} An array of coordinates representing the point.
│ │ │ │ │ - */
│ │ │ │ │ - 'point': function(point) {
│ │ │ │ │ - return [point.x, point.y];
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: zoom
│ │ │ │ │ + * {Integer} The current zoom level of the map
│ │ │ │ │ + */
│ │ │ │ │ + zoom: 0,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: extract.multipoint
│ │ │ │ │ - * Return an array of point coordinates from a multipoint.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * multipoint - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Array} An array of point coordinate arrays representing
│ │ │ │ │ - * the multipoint.
│ │ │ │ │ - */
│ │ │ │ │ - 'multipoint': function(multipoint) {
│ │ │ │ │ - var array = [];
│ │ │ │ │ - for (var i = 0, len = multipoint.components.length; i < len; ++i) {
│ │ │ │ │ - array.push(this.extract.point.apply(this, [multipoint.components[i]]));
│ │ │ │ │ - }
│ │ │ │ │ - return array;
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * Property: panRatio
│ │ │ │ │ + * {Float} The ratio of the current extent within
│ │ │ │ │ + * which panning will tween.
│ │ │ │ │ + */
│ │ │ │ │ + panRatio: 1.5,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: extract.linestring
│ │ │ │ │ - * Return an array of coordinate arrays from a linestring.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * linestring - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Array} An array of coordinate arrays representing
│ │ │ │ │ - * the linestring.
│ │ │ │ │ - */
│ │ │ │ │ - 'linestring': function(linestring) {
│ │ │ │ │ - var array = [];
│ │ │ │ │ - for (var i = 0, len = linestring.components.length; i < len; ++i) {
│ │ │ │ │ - array.push(this.extract.point.apply(this, [linestring.components[i]]));
│ │ │ │ │ - }
│ │ │ │ │ - return array;
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: options
│ │ │ │ │ + * {Object} The options object passed to the class constructor. Read-only.
│ │ │ │ │ + */
│ │ │ │ │ + options: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: extract.multilinestring
│ │ │ │ │ - * Return an array of linestring arrays from a linestring.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * multilinestring - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Array} An array of linestring arrays representing
│ │ │ │ │ - * the multilinestring.
│ │ │ │ │ - */
│ │ │ │ │ - 'multilinestring': function(multilinestring) {
│ │ │ │ │ - var array = [];
│ │ │ │ │ - for (var i = 0, len = multilinestring.components.length; i < len; ++i) {
│ │ │ │ │ - array.push(this.extract.linestring.apply(this, [multilinestring.components[i]]));
│ │ │ │ │ - }
│ │ │ │ │ - return array;
│ │ │ │ │ - },
│ │ │ │ │ + // Options
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: extract.polygon
│ │ │ │ │ - * Return an array of linear ring arrays from a polygon.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * polygon - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Array} An array of linear ring arrays representing the polygon.
│ │ │ │ │ - */
│ │ │ │ │ - 'polygon': function(polygon) {
│ │ │ │ │ - var array = [];
│ │ │ │ │ - for (var i = 0, len = polygon.components.length; i < len; ++i) {
│ │ │ │ │ - array.push(this.extract.linestring.apply(this, [polygon.components[i]]));
│ │ │ │ │ - }
│ │ │ │ │ - return array;
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: tileSize
│ │ │ │ │ + * {} Set in the map options to override the default tile
│ │ │ │ │ + * size for this map.
│ │ │ │ │ + */
│ │ │ │ │ + tileSize: null,
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: extract.multipolygon
│ │ │ │ │ - * Return an array of polygon arrays from a multipolygon.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * multipolygon - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Array} An array of polygon arrays representing
│ │ │ │ │ - * the multipolygon
│ │ │ │ │ - */
│ │ │ │ │ - 'multipolygon': function(multipolygon) {
│ │ │ │ │ - var array = [];
│ │ │ │ │ - for (var i = 0, len = multipolygon.components.length; i < len; ++i) {
│ │ │ │ │ - array.push(this.extract.polygon.apply(this, [multipolygon.components[i]]));
│ │ │ │ │ - }
│ │ │ │ │ - return array;
│ │ │ │ │ - },
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: projection
│ │ │ │ │ + * {String} Set in the map options to specify the default projection
│ │ │ │ │ + * for layers added to this map. When using a projection other than EPSG:4326
│ │ │ │ │ + * (CRS:84, Geographic) or EPSG:3857 (EPSG:900913, Web Mercator),
│ │ │ │ │ + * also set maxExtent, maxResolution or resolutions. Default is "EPSG:4326".
│ │ │ │ │ + * Note that the projection of the map is usually determined
│ │ │ │ │ + * by that of the current baseLayer (see and ).
│ │ │ │ │ + */
│ │ │ │ │ + projection: "EPSG:4326",
│ │ │ │ │
│ │ │ │ │ - /**
│ │ │ │ │ - * Method: extract.collection
│ │ │ │ │ - * Return an array of geometries from a geometry collection.
│ │ │ │ │ - *
│ │ │ │ │ - * Parameters:
│ │ │ │ │ - * collection - {}
│ │ │ │ │ - *
│ │ │ │ │ - * Returns:
│ │ │ │ │ - * {Array} An array of geometry objects representing the geometry
│ │ │ │ │ - * collection.
│ │ │ │ │ - */
│ │ │ │ │ - 'collection': function(collection) {
│ │ │ │ │ - var len = collection.components.length;
│ │ │ │ │ - var array = new Array(len);
│ │ │ │ │ - for (var i = 0; i < len; ++i) {
│ │ │ │ │ - array[i] = this.extract.geometry.apply(
│ │ │ │ │ - this, [collection.components[i]]
│ │ │ │ │ - );
│ │ │ │ │ - }
│ │ │ │ │ - return array;
│ │ │ │ │ - }
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: units
│ │ │ │ │ + * {String} The map units. 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,
│ │ │ │ │
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: resolutions
│ │ │ │ │ + * {Array(Float)} 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: maxResolution
│ │ │ │ │ + * {Float} Required if you are not displaying the whole world on a tile
│ │ │ │ │ + * with the size specified in .
│ │ │ │ │ + */
│ │ │ │ │ + maxResolution: null,
│ │ │ │ │
│ │ │ │ │ - CLASS_NAME: "OpenLayers.Format.GeoJSON"
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: minResolution
│ │ │ │ │ + * {Float}
│ │ │ │ │ + */
│ │ │ │ │ + minResolution: null,
│ │ │ │ │
│ │ │ │ │ -});
│ │ │ │ │ -/* ======================================================================
│ │ │ │ │ - OpenLayers/Format/XML.js
│ │ │ │ │ - ====================================================================== */
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: maxScale
│ │ │ │ │ + * {Float}
│ │ │ │ │ + */
│ │ │ │ │ + maxScale: 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/Format.js
│ │ │ │ │ - */
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: maxExtent
│ │ │ │ │ + * {|Array} If provided as an array, the array
│ │ │ │ │ + * should consist of four values (left, bottom, right, top).
│ │ │ │ │ + * The maximum extent for the map.
│ │ │ │ │ + * Default depends on projection; if this is one of those defined in OpenLayers.Projection.defaults
│ │ │ │ │ + * (EPSG:4326 or web mercator), maxExtent will be set to the value defined there;
│ │ │ │ │ + * else, defaults to null.
│ │ │ │ │ + * To restrict user panning and zooming of the map, use instead.
│ │ │ │ │ + * The value for will change calculations for tile URLs.
│ │ │ │ │ + */
│ │ │ │ │ + maxExtent: null,
│ │ │ │ │
│ │ │ │ │ -/**
│ │ │ │ │ - * Class: OpenLayers.Format.XML
│ │ │ │ │ - * Read and write XML. For cross-browser XML generation, use methods on an
│ │ │ │ │ - * instance of the XML format class instead of on document.
│ │ │ │ │ - * The DOM creation and traversing methods exposed here all mimic the
│ │ │ │ │ - * W3C XML DOM methods. Create a new parser with the
│ │ │ │ │ - * constructor.
│ │ │ │ │ - *
│ │ │ │ │ - * Inherits from:
│ │ │ │ │ - * -
│ │ │ │ │ - */
│ │ │ │ │ -OpenLayers.Format.XML = OpenLayers.Class(OpenLayers.Format, {
│ │ │ │ │ + /**
│ │ │ │ │ + * APIProperty: minExtent
│ │ │ │ │ + * {|Array} If provided as an array, the array
│ │ │ │ │ + * should consist of four values (left, bottom, right, top).
│ │ │ │ │ + * The minimum extent for the map. Defaults to null.
│ │ │ │ │ + */
│ │ │ │ │ + minExtent: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: namespaces
│ │ │ │ │ - * {Object} Mapping of namespace aliases to namespace URIs. Properties
│ │ │ │ │ - * of this object should not be set individually. Read-only. All
│ │ │ │ │ - * XML subclasses should have their own namespaces object. Use
│ │ │ │ │ - * to add or set a namespace alias after construction.
│ │ │ │ │ + * APIProperty: restrictedExtent
│ │ │ │ │ + * {|Array} If provided as an array, the array
│ │ │ │ │ + * should consist of four values (left, bottom, right, top).
│ │ │ │ │ + * Limit map navigation to this extent where possible.
│ │ │ │ │ + * If a non-null restrictedExtent is set, panning will be restricted
│ │ │ │ │ + * to the given bounds. In addition, zooming to a resolution that
│ │ │ │ │ + * displays more than the restricted extent will center the map
│ │ │ │ │ + * on the restricted extent. If you wish to limit the zoom level
│ │ │ │ │ + * or resolution, use maxResolution.
│ │ │ │ │ */
│ │ │ │ │ - namespaces: null,
│ │ │ │ │ + restrictedExtent: null,
│ │ │ │ │
│ │ │ │ │ /**
│ │ │ │ │ - * Property: namespaceAlias
│ │ │ │ │ - * {Object} Mapping of namespace URI to namespace alias. This object
│ │ │ │ │ - * is read-only. Use