More trip planner testing with colors
[busui.git] / labs / openlayers / lib / OpenLayers / Layer / Vector.js
blob:a/labs/openlayers/lib/OpenLayers/Layer/Vector.js -> blob:b/labs/openlayers/lib/OpenLayers/Layer/Vector.js
  /* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
  * full list of contributors). Published under the Clear BSD license.
  * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
  * full text of the license. */
   
  /**
  * @requires OpenLayers/Layer.js
  * @requires OpenLayers/Renderer.js
  * @requires OpenLayers/StyleMap.js
  * @requires OpenLayers/Feature/Vector.js
  * @requires OpenLayers/Console.js
  */
   
  /**
  * Class: OpenLayers.Layer.Vector
  * Instances of OpenLayers.Layer.Vector are used to render vector data from
  * a variety of sources. Create a new vector layer with the
  * <OpenLayers.Layer.Vector> constructor.
  *
  * Inherits from:
  * - <OpenLayers.Layer>
  */
  OpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, {
   
  /**
  * Constant: EVENT_TYPES
  * {Array(String)} Supported application event types. Register a listener
  * for a particular event with the following syntax:
  * (code)
  * layer.events.register(type, obj, listener);
  * (end)
  *
  * Listeners will be called with a reference to an event object. The
  * properties of this event depends on exactly what happened.
  *
  * All event objects have at least the following properties:
  * object - {Object} A reference to layer.events.object.
  * element - {DOMElement} A reference to layer.events.element.
  *
  * Supported map event types (in addition to those from <OpenLayers.Layer>):
  * beforefeatureadded - Triggered before a feature is added. Listeners
  * will receive an object with a *feature* property referencing the
  * feature to be added. To stop the feature from being added, a
  * listener should return false.
  * beforefeaturesadded - Triggered before an array of features is added.
  * Listeners will receive an object with a *features* property
  * referencing the feature to be added. To stop the features from
  * being added, a listener should return false.
  * featureadded - Triggered after a feature is added. The event
  * object passed to listeners will have a *feature* property with a
  * reference to the added feature.
  * featuresadded - Triggered after features are added. The event
  * object passed to listeners will have a *features* property with a
  * reference to an array of added features.
  * beforefeatureremoved - Triggered before a feature is removed. Listeners
  * will receive an object with a *feature* property referencing the
  * feature to be removed.
  * beforefeaturesremoved - Triggered before multiple features are removed.
  * Listeners will receive an object with a *features* property
  * referencing the features to be removed.
  * featureremoved - Triggerd after a feature is removed. The event
  * object passed to listeners will have a *feature* property with a
  * reference to the removed feature.
  * featuresremoved - Triggered after features are removed. The event
  * object passed to listeners will have a *features* property with a
  * reference to an array of removed features.
  * featureselected - Triggered after a feature is selected. Listeners
  * will receive an object with a *feature* property referencing the
  * selected feature.
  * featureunselected - Triggered after a feature is unselected.
  * Listeners will receive an object with a *feature* property
  * referencing the unselected feature.
  * beforefeaturemodified - Triggered when a feature is selected to
  * be modified. Listeners will receive an object with a *feature*
  * property referencing the selected feature.
  * featuremodified - Triggered when a feature has been modified.
  * Listeners will receive an object with a *feature* property referencing
  * the modified feature.
  * afterfeaturemodified - Triggered when a feature is finished being modified.
  * Listeners will receive an object with a *feature* property referencing
  * the modified feature.
  * vertexmodified - Triggered when a vertex within any feature geometry
  * has been modified. Listeners will receive an object with a
  * *feature* property referencing the modified feature, a *vertex*
  * property referencing the vertex modified (always a point geometry),
  * and a *pixel* property referencing the pixel location of the
  * modification.
  * sketchstarted - Triggered when a feature sketch bound for this layer
  * is started. Listeners will receive an object with a *feature*
  * property referencing the new sketch feature and a *vertex* property
  * referencing the creation point.
  * sketchmodified - Triggered when a feature sketch bound for this layer
  * is modified. Listeners will receive an object with a *vertex*
  * property referencing the modified vertex and a *feature* property
  * referencing the sketch feature.
  * sketchcomplete - Triggered when a feature sketch bound for this layer
  * is complete. Listeners will receive an object with a *feature*
  * property referencing the sketch feature. By returning false, a
  * listener can stop the sketch feature from being added to the layer.
  * refresh - Triggered when something wants a strategy to ask the protocol
  * for a new set of features.
  */
  EVENT_TYPES: ["beforefeatureadded", "beforefeaturesadded",
  "featureadded", "featuresadded", "beforefeatureremoved",
  "beforefeaturesremoved", "featureremoved", "featuresremoved",
  "beforefeatureselected", "featureselected", "featureunselected",
  "beforefeaturemodified", "featuremodified", "afterfeaturemodified",
  "vertexmodified", "sketchstarted", "sketchmodified",
  "sketchcomplete", "refresh"],
   
  /**
  * APIProperty: isBaseLayer
  * {Boolean} The layer is a base layer. Default is false. Set this property
  * in the layer options.
  */
  isBaseLayer: false,
   
  /**
  * APIProperty: isFixed
  * {Boolean} Whether the layer remains in one place while dragging the
  * map.
  */
  isFixed: false,
   
  /**
  * APIProperty: isVector
  * {Boolean} Whether the layer is a vector layer.
  */
  isVector: true,
   
  /**
  * APIProperty: features
  * {Array(<OpenLayers.Feature.Vector>)}
  */
  features: null,
   
  /**
  * Property: filter
  * {<OpenLayers.Filter>} The filter set in this layer,
  * a strategy launching read requests can combined
  * this filter with its own filter.
  */
  filter: null,
   
  /**
  * Property: selectedFeatures
  * {Array(<OpenLayers.Feature.Vector>)}
  */
  selectedFeatures: null,
   
  /**
  * Property: unrenderedFeatures
  * {Object} hash of features, keyed by feature.id, that the renderer
  * failed to draw
  */
  unrenderedFeatures: null,
   
  /**
  * APIProperty: reportError
  * {Boolean} report friendly error message when loading of renderer
  * fails.
  */
  reportError: true,
   
  /**
  * APIProperty: style
  * {Object} Default style for the layer
  */
  style: null,
   
  /**
  * Property: styleMap
  * {<OpenLayers.StyleMap>}
  */
  styleMap: null,
   
  /**
  * Property: strategies
  * {Array(<OpenLayers.Strategy>})} Optional list of strategies for the layer.
  */
  strategies: null,
   
  /**
  * Property: protocol
  * {<OpenLayers.Protocol>} Optional protocol for the layer.
  */
  protocol: null,
   
  /**
  * Property: renderers
  * {Array(String)} List of supported Renderer classes. Add to this list to
  * add support for additional renderers. This list is ordered:
  * the first renderer which returns true for the 'supported()'
  * method will be used, if not defined in the 'renderer' option.
  */
  renderers: ['SVG', 'VML', 'Canvas'],
   
  /**
  * Property: renderer
  * {<OpenLayers.Renderer>}
  */
  renderer: null,
   
  /**
  * APIProperty: rendererOptions
  * {Object} Options for the renderer. See {<OpenLayers.Renderer>} for
  * supported options.
  */
  rendererOptions: null,
   
  /**
  * APIProperty: geometryType
  * {String} geometryType allows you to limit the types of geometries this
  * layer supports. This should be set to something like
  * "OpenLayers.Geometry.Point" to limit types.
  */
  geometryType: null,
   
  /**
  * Property: drawn
  * {Boolean} Whether the Vector Layer features have been drawn yet.
  */
  drawn: false,
   
  /**
  * Constructor: OpenLayers.Layer.Vector
  * Create a new vector layer
  *
  * Parameters:
  * name - {String} A name for the layer
  * options - {Object} Optional object with non-default properties to set on
  * the layer.
  *
  * Returns:
  * {<OpenLayers.Layer.Vector>} A new vector layer
  */
  initialize: function(name, options) {
   
  // concatenate events specific to vector with those from the base
  this.EVENT_TYPES =
  OpenLayers.Layer.Vector.prototype.EVENT_TYPES.concat(
  OpenLayers.Layer.prototype.EVENT_TYPES
  );
   
  OpenLayers.Layer.prototype.initialize.apply(this, arguments);
   
  // allow user-set renderer, otherwise assign one
  if (!this.renderer || !this.renderer.supported()) {
  this.assignRenderer();
  }
   
  // if no valid renderer found, display error
  if (!this.renderer || !this.renderer.supported()) {
  this.renderer = null;
  this.displayError();
  }
   
  if (!this.styleMap) {
  this.styleMap = new OpenLayers.StyleMap();
  }
   
  this.features = [];
  this.selectedFeatures = [];
  this.unrenderedFeatures = {};
   
  // Allow for custom layer behavior
  if(this.strategies){
  for(var i=0, len=this.strategies.length; i<len; i++) {
  this.strategies[i].setLayer(this);
  }
  }
   
  },
   
  /**
  * APIMethod: destroy
  * Destroy this layer
  */
  destroy: function() {
  if (this.strategies) {
  var strategy, i, len;
  for(i=0, len=this.strategies.length; i<len; i++) {
  strategy = this.strategies[i];
  if(strategy.autoDestroy) {
  strategy.destroy();
  }
  }
  this.strategies = null;
  }
  if (this.protocol) {
  if(this.protocol.autoDestroy) {
  this.protocol.destroy();
  }
  this.protocol = null;
  }
  this.destroyFeatures();
  this.features = null;
  this.selectedFeatures = null;
  this.unrenderedFeatures = null;
  if (this.renderer) {
  this.renderer.destroy();
  }
  this.renderer = null;
  this.geometryType = null;
  this.drawn = null;
  OpenLayers.Layer.prototype.destroy.apply(this, arguments);
  },
   
  /**
  * Method: clone
  * Create a clone of this layer.
  *
  * Note: Features of the layer are also cloned.
  *
  * Returns:
  * {<OpenLayers.Layer.Vector>} An exact clone of this layer
  */
  clone: function (obj) {
   
  if (obj == null) {
  obj = new OpenLayers.Layer.Vector(this.name, this.getOptions());
  }
   
  //get all additions from superclasses
  obj = OpenLayers.Layer.prototype.clone.apply(this, [obj]);
   
  // copy/set any non-init, non-simple values here
  var features = this.features;
  var len = features.length;
  var clonedFeatures = new Array(len);
  for(var i=0; i<len; ++i) {
  clonedFeatures[i] = features[i].clone();
  }
  obj.features = clonedFeatures;
   
  return obj;
  },
   
  /**
  * Method: refresh
  * Ask the layer to request features again and redraw them. Triggers
  * the refresh event if the layer is in range and visible.
  *
  * Parameters:
  * obj - {Object} Optional object with properties for any listener of
  * the refresh event.
  */
  refresh: function(obj) {
  if(this.calculateInRange() && this.visibility) {
  this.events.triggerEvent("refresh", obj);
  }
  },
   
  /**
  * Method: assignRenderer
  * Iterates through the available renderer implementations and selects
  * and assigns the first one whose "supported()" function returns true.
  */
  assignRenderer: function() {
  for (var i=0, len=this.renderers.length; i<len; i++) {
  var rendererClass = this.renderers[i];
  var renderer = (typeof rendererClass == "function") ?
  rendererClass :
  OpenLayers.Renderer[rendererClass];
  if (renderer && renderer.prototype.supported()) {
  this.renderer = new renderer(this.div, this.rendererOptions);
  break;