More trip planner testing with colors
[busui.git] / labs / openlayers / lib / OpenLayers / Feature / Vector.js
blob:a/labs/openlayers/lib/OpenLayers/Feature/Vector.js -> blob:b/labs/openlayers/lib/OpenLayers/Feature/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. */
   
  // TRASH THIS
  OpenLayers.State = {
  /** states */
  UNKNOWN: 'Unknown',
  INSERT: 'Insert',
  UPDATE: 'Update',
  DELETE: 'Delete'
  };
   
  /**
  * @requires OpenLayers/Feature.js
  * @requires OpenLayers/Util.js
  */
   
  /**
  * Class: OpenLayers.Feature.Vector
  * Vector features use the OpenLayers.Geometry classes as geometry description.
  * They have an 'attributes' property, which is the data object, and a 'style'
  * property, the default values of which are defined in the
  * <OpenLayers.Feature.Vector.style> objects.
  *
  * Inherits from:
  * - <OpenLayers.Feature>
  */
  OpenLayers.Feature.Vector = OpenLayers.Class(OpenLayers.Feature, {
   
  /**
  * Property: fid
  * {String}
  */
  fid: null,
   
  /**
  * APIProperty: geometry
  * {<OpenLayers.Geometry>}
  */
  geometry: null,
   
  /**
  * APIProperty: attributes
  * {Object} This object holds arbitrary, serializable properties that
  * describe the feature.
  */
  attributes: null,
   
  /**
  * Property: bounds
  * {<OpenLayers.Bounds>} The box bounding that feature's geometry, that
  * property can be set by an <OpenLayers.Format> object when
  * deserializing the feature, so in most cases it represents an
  * information set by the server.
  */
  bounds: null,
   
  /**
  * Property: state
  * {String}
  */
  state: null,
   
  /**
  * APIProperty: style
  * {Object}
  */
  style: null,
   
  /**
  * APIProperty: url
  * {String} If this property is set it will be taken into account by
  * {<OpenLayers.HTTP>} when upadting or deleting the feature.
  */
  url: null,
   
  /**
  * Property: renderIntent
  * {String} rendering intent currently being used
  */
  renderIntent: "default",
   
  /**
  * Constructor: OpenLayers.Feature.Vector
  * Create a vector feature.
  *
  * Parameters:
  * geometry - {<OpenLayers.Geometry>} The geometry that this feature
  * represents.
  * attributes - {Object} An optional object that will be mapped to the
  * <attributes> property.
  * style - {Object} An optional style object.
  */
  initialize: function(geometry, attributes, style) {
  OpenLayers.Feature.prototype.initialize.apply(this,
  [null, null, attributes]);
  this.lonlat = null;
  this.geometry = geometry ? geometry : null;
  this.state = null;
  this.attributes = {};
  if (attributes) {
  this.attributes = OpenLayers.Util.extend(this.attributes,
  attributes);
  }
  this.style = style ? style : null;
  },
   
  /**
  * Method: destroy
  * nullify references to prevent circular references and memory leaks
  */
  destroy: function() {
  if (this.layer) {
  this.layer.removeFeatures(this);
  this.layer = null;
  }
   
  this.geometry = null;
  OpenLayers.Feature.prototype.destroy.apply(this, arguments);
  },
   
  /**
  * Method: clone
  * Create a clone of this vector feature. Does not set any non-standard
  * properties.
  *
  * Returns:
  * {<OpenLayers.Feature.Vector>} An exact clone of this vector feature.
  */
  clone: function () {
  return new OpenLayers.Feature.Vector(
  this.geometry ? this.geometry.clone() : null,
  this.attributes,
  this.style);
  },
   
  /**
  * Method: onScreen
  * Determine whether the feature is within the map viewport. This method
  * tests for an intersection between the geometry and the viewport
  * bounds. If a more effecient but less precise geometry bounds
  * intersection is desired, call the method with the boundsOnly
  * parameter true.
  *
  * Parameters:
  * boundsOnly - {Boolean} Only test whether a feature's bounds intersects
  * the viewport bounds. Default is false. If false, the feature's
  * geometry must intersect the viewport for onScreen to return true.
  *
  * Returns:
  * {Boolean} The feature is currently visible on screen (optionally
  * based on its bounds if boundsOnly is true).
  */
  onScreen:function(boundsOnly) {
  var onScreen = false;
  if(this.layer && this.layer.map) {
  var screenBounds = this.layer.map.getExtent();
  if(boundsOnly) {
  var featureBounds = this.geometry.getBounds();
  onScreen = screenBounds.intersectsBounds(featureBounds);
  } else {
  var screenPoly = screenBounds.toGeometry();
  onScreen = screenPoly.intersects(this.geometry);
  }
  }
  return onScreen;
  },
   
  /**
  * Method: getVisibility
  * Determine whether the feature is displayed or not. It may not displayed
  * because:
  * - its style display property is set to 'none',
  * - it doesn't belong to any layer,
  * - the styleMap creates a symbolizer with display property set to 'none'
  * for it,
  * - the layer which it belongs to is not visible.
  *
  * Returns:
  * {Boolean} The feature is currently displayed.
  */
  getVisibility: function() {
  return !(this.style && this.style.display == 'none' ||
  !this.layer ||
  this.layer && this.layer.styleMap &&
  this.layer.styleMap.createSymbolizer(this, this.renderIntent).display == 'none' ||
  this.layer && !this.layer.getVisibility());
  },
   
  /**
  * Method: createMarker
  * HACK - we need to decide if all vector features should be able to
  * create markers
  *
  * Returns:
  * {<OpenLayers.Marker>} For now just returns null
  */
  createMarker: function() {
  return null;
  },
   
  /**
  * Method: destroyMarker
  * HACK - we need to decide if all vector features should be able to
  * delete markers
  *
  * If user overrides the createMarker() function, s/he should be able
  * to also specify an alternative function for destroying it
  */
  destroyMarker: function() {
  // pass
  },
   
  /**
  * Method: createPopup
  * HACK - we need to decide if all vector features should be able to
  * create popups
  *
  * Returns:
  * {<OpenLayers.Popup>} For now just returns null
  */
  createPopup: function() {
  return null;
  },
   
  /**
  * Method: atPoint
  * Determins whether the feature intersects with the specified location.
  *
  * Parameters:
  * lonlat - {<OpenLayers.LonLat>}
  * toleranceLon - {float} Optional tolerance in Geometric Coords
  * toleranceLat - {float} Optional tolerance in Geographic Coords
  *
  * Returns:
  * {Boolean} Whether or not the feature is at the specified location
  */
  atPoint: function(lonlat, toleranceLon, toleranceLat) {
  var atPoint = false;
  if(this.geometry) {
  atPoint = this.geometry.atPoint(lonlat, toleranceLon,
  toleranceLat);
  }
  return atPoint;
  },
   
  /**
  * Method: destroyPopup
  * HACK - we need to decide if all vector features should be able to
  * delete popups
  */
  destroyPopup: function() {
  // pass
  },
   
  /**
  * Method: move
  * Moves the feature and redraws it at its new location
  *
  * Parameters:
  * state - {OpenLayers.LonLat or OpenLayers.Pixel} the
  * location to which to move the feature.
  */
  move: function(location) {
   
  if(!this.layer || !this.geometry.move){
  //do nothing if no layer or immoveable geometry
  return;
  }
   
  var pixel;
  if (location.CLASS_NAME == "OpenLayers.LonLat") {
  pixel = this.layer.getViewPortPxFromLonLat(location);
  } else {
  pixel = location;
  }
   
  var lastPixel = this.layer.getViewPortPxFromLonLat(this.geometry.getBounds().getCenterLonLat());
  var res = this.layer.map.getResolution();
  this.geometry.move(res * (pixel.x - lastPixel.x),
  res * (lastPixel.y - pixel.y));
  this.layer.drawFeature(this);
  return lastPixel;
  },
   
  /**
  * Method: toState
  * Sets the new state
  *
  * Parameters:
  * state - {String}
  */
  toState: function(state) {
  if (state == OpenLayers.State.UPDATE) {
  switch (this.state) {
  case OpenLayers.State.UNKNOWN:
  case OpenLayers.State.DELETE:
  this.state = state;
  break;
  case OpenLayers.State.UPDATE:
  case OpenLayers.State.INSERT:
  break;
  }
  } else if (state == OpenLayers.State.INSERT) {
  switch (this.state) {
  case OpenLayers.State.UNKNOWN:
  break;
  default:
  this.state = state;
  break;
  }
  } else if (state == OpenLayers.State.DELETE) {
  switch (this.state) {
  case OpenLayers.State.INSERT:
  // the feature should be destroyed
  break;
  case OpenLayers.State.DELETE:
  break;
  case OpenLayers.State.UNKNOWN:
  case OpenLayers.State.UPDATE:
  this.state = state;
  break;
  }
  } else if (state == OpenLayers.State.UNKNOWN) {
  this.state = state;
  }
  },
   
  CLASS_NAME: "OpenLayers.Feature.Vector"
  });
   
   
  /**
  * Constant: OpenLayers.Feature.Vector.style
  * OpenLayers features can have a number of style attributes. The 'default'
  * style will typically be used if no other style is specified. These
  * styles correspond for the most part, to the styling properties defined
  * by the SVG standard.
  * Information on fill properties: http://www.w3.org/TR/SVG/painting.html#FillProperties
  * Information on stroke properties: http://www.w3.org/TR/SVG/painting.html#StrokeProperties
  *
  * Symbolizer properties:
  * fill - {Boolean} Set to false if no fill is desired.
  * fillColor - {String} Hex fill color. Default is "#ee9900".
  * fillOpacity - {Number} Fill opacity (0-1). Default is 0.4
  * stroke - {Boolean} Set to false if no stroke is desired.
  * strokeColor - {String} Hex stroke color. Default is "#ee9900".
  * strokeOpacity - {Number} Stroke opacity (0-1). Default is 1.
  * strokeWidth - {Number} Pixel stroke width. Default is 1.
  * strokeLinecap - {String} Stroke cap type. Default is "round". [butt | round | square]
  * strokeDashstyle - {String} Stroke dash style. Default is "solid". [dot | dash | dashdot | longdash | longdashdot | solid]
  * graphic - {Boolean} Set to false if no graphic is desired.
  * pointRadius - {Number} Pixel point radius. Default is 6.
  * pointerEvents - {String} Default is "visiblePainted".
  * cursor - {String} Default is "".
  * externalGraphic - {String} Url to an external graphic that will be used for rendering points.
  * graphicWidth - {Number} Pixel width for sizing an external graphic.
  * graphicHeight - {Number} Pixel height for sizing an external graphic.
  * graphicOpacity - {Number} Opacity (0-1) for an external graphic.
  * graphicXOffset - {Number} Pixel offset along the positive x axis for displacing an external graphic.
  * graphicYOffset - {Number} Pixel offset along the positive y axis for displacing an external graphic.
  * rotation - {Number} For point symbolizers, this is the rotation of a graphic in the clockwise direction about its center point (or any point off center as specified by graphicXOffset and graphicYOffset).
  * graphicZIndex - {Number} The integer z-index value to use in rendering.
  * graphicName - {String} Named graphic to use when rendering points. Supported values include "circle" (default),
  * "square", "star", "x", "cross", "triangle".
  * graphicTitle - {String} Tooltip for an external graphic. Only supported in Firefox and Internet Explorer.
  * backgroundGraphic - {String} Url to a graphic to be used as the background under an externalGraphic.
  * backgroundGraphicZIndex - {Number} The integer z-index value to use in rendering the background graphic.
  * backgroundXOffset - {Number} The x offset (in