Files
openlayers/lib/OpenLayers/Geometry/Collection.js
crschmidt 3948913bfc Merge all changes from the naturaldocs sandbox. This brings all the work that
has been done in the NaturalDocs branch back to trunk. Thanks to everyone who
helped out in making this happen. (I could list people, but the list would
be long, and I'm already mentally on vacation.)


git-svn-id: http://svn.openlayers.org/trunk/openlayers@3545 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
2007-06-29 15:59:20 +00:00

282 lines
8.4 KiB
JavaScript

/* Copyright (c) 2006 MetaCarta, Inc., published under a modified BSD license.
* See http://svn.openlayers.org/trunk/openlayers/repository-license.txt
* for the full text of the license. */
/**
* @requires OpenLayers/Geometry.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 <components> (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 <getArea> and <getLength> functions here merely iterate through
* the components, summing their respective areas and lengths.
*
* Create a new instance with the <OpenLayers.Geometry.Collection> constructor.
*
* Inerhits from:
* - <OpenLayers.Geometry>
*/
OpenLayers.Geometry.Collection = OpenLayers.Class.create();
OpenLayers.Geometry.Collection.prototype =
OpenLayers.Class.inherit( OpenLayers.Geometry, {
/**
* APIProperty: components
* {Array(<OpenLayers.Geometry>)} The component parts of this geometry
*/
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.
*/
componentTypes: null,
/**
* Constructor: OpenLayers.Geometry.Collection
* Creates a Geometry Collection -- a list of geoms.
*
* Parameters:
* components - {Array(<OpenLayers.Geometry>)} Optional array of geometries
*
*/
initialize: function (components) {
OpenLayers.Geometry.prototype.initialize.apply(this, arguments);
this.components = new Array();
if (components != null) {
this.addComponents(components);
}
},
/**
* APIMethod: destroy
* Destroy this geometry.
*/
destroy: function () {
this.components.length = 0;
this.components = null;
},
/**
* APIMethod: clone
* Clone this geometry.
*
* Return:
* {<OpenLayers.Geometry.Collection>} An exact clone of this collection
*/
clone: function() {
var geometry = eval("new " + this.CLASS_NAME + "()");
for(var i=0; i<this.components.length; i++) {
geometry.addComponent(this.components[i].clone());
}
// catch any randomly tagged-on properties
OpenLayers.Util.applyDefaults(geometry, this);
return geometry;
},
/**
* Method: getComponentsString
* Get a string representing the components for this collection
*
* Return:
* {String} A string representation of the components of this geometry
*/
getComponentsString: function(){
var strings = [];
for(var i = 0; i < this.components.length; 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.
*/
calculateBounds: function() {
this.bounds = null;
if ( !this.components || (this.components.length > 0)) {
this.setBounds(this.components[0].getBounds());
for (var i = 1; i < this.components.length; i++) {
this.extendBounds(this.components[i].getBounds());
}
}
},
/**
* APIMethod: addComponents
* Add components to this geometry.
*
* Parameters:
* components - {Array(<OpenLayers.Geometry>)} An array of geometries to add
*/
addComponents: function(components){
if(!(components instanceof Array)) {
components = [components];
}
for(var i=0; i < components.length; 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.
*
* Parameters:
* component - {<OpenLayers.Geometry>} A geometry to add
* index - {int} Optional index into the array to insert the component
*
* Return:
* {Boolean} The component geometry was successfully added
*/
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;
},
/**
* APIMethod: removeComponents
* Remove components from this geometry.
*
* Parameters:
* components - {Array(<OpenLayers.Geometry>)} The components to be removed
*/
removeComponents: function(components) {
if(!(components instanceof Array)) {
components = [components];
}
for (var i = 0; i < components.length; i++) {
this.removeComponent(components[i]);
}
},
/**
* Method: removeComponent
* Remove a component from this geometry.
*
* Parameters:
* component - {<OpenLayers.Geometry>}
*/
removeComponent: function(component) {
OpenLayers.Util.removeItem(this.components, component);
// clearBounds() so that it gets recalculated on the next call
// to this.getBounds();
this.clearBounds();
},
/**
* APIMethod: getLength
* Calculate the length of this geometry
*
* Return:
* {Float} The length of the geometry
*/
getLength: function() {
var length = 0.0;
for (var i = 0; i < this.components.length; i++) {
length += this.components[i].getLength();
}
return length;
},
/**
* APIMethod: getArea
* Calculate the area of this geometry. Note how this function is overridden
* in <OpenLayers.Geometry.Polygon>.
*
* Return:
* {Float} The area of the collection by summing its parts
*/
getArea: function() {
var area = 0.0;
for (var i = 0; i < this.components.length; i++) {
area += this.components[i].getArea();
}
return area;
},
/**
* APIMethod: move
* Moves a collection in place
*
* Parameters:
* x - {Float} The x-displacement (in map units)
* y - {Float} The y-displacement (in map units)
*/
move: function(x, y) {
for(var i = 0; i < this.components.length; i++) {
this.components[i].move(x, y);
}
},
/**
* APIMethod: equals
* Tests for equivalent geometries
*
* Parameters:
* geometry - {<OpenLayers.Geometry>}
*
* Return:
* {Boolean} The coordinates are equivalent
*/
equals: function(geometry) {
var equivalent = true;
if(!geometry.CLASS_NAME || (this.CLASS_NAME != geometry.CLASS_NAME)) {
equivalent = false;
} else if(!(geometry.components instanceof Array) ||
(geometry.components.length != this.components.length)) {
equivalent = false;
} else {
for(var i=0; i<this.components.length; ++i) {
if(!this.components[i].equals(geometry.components[i])) {
equivalent = false;
break;
}
}
}
return equivalent;
},
/**
* Constant: CLASS_NAME
* {String} Name of class.
*/
CLASS_NAME: "OpenLayers.Geometry.Collection"
});