/* 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/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 (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. * * Inerhits from: * - */ OpenLayers.Geometry.Collection = OpenLayers.Class(OpenLayers.Geometry, { /** * APIProperty: components * {Array()} 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()} Optional array of geometries * */ initialize: function (components) { OpenLayers.Geometry.prototype.initialize.apply(this, arguments); this.components = []; if (components != null) { this.addComponents(components); } }, /** * APIMethod: destroy * Destroy this geometry. */ 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 */ clone: function() { var geometry = eval("new " + this.CLASS_NAME + "()"); for(var i=0, len=this.components.length; i 0) { this.setBounds(this.components[0].getBounds()); for (var i=1, len=this.components.length; i)} An array of geometries to add */ addComponents: function(components){ if(!(components instanceof Array)) { components = [components]; } for(var i=0, len=components.length; i} A geometry to add * index - {int} Optional index into the array to insert the component * * Returns: * {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()} The components to be removed */ removeComponents: function(components) { if(!(components instanceof Array)) { components = [components]; } for(var i=components.length-1; i>=0; --i) { this.removeComponent(components[i]); } }, /** * Method: removeComponent * Remove a component from this geometry. * * Parameters: * component - {} */ 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 * * Returns: * {Float} The length of the geometry */ getLength: function() { var length = 0.0; for (var i=0, len=this.components.length; i. * * Returns: * {Float} The area of the collection by summing its parts */ getArea: function() { var area = 0.0; for (var i=0, len=this.components.length; i} 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 geometry in square meters. */ getGeodesicArea: function(projection) { var area = 0.0; for(var i=0, len=this.components.length; i} The centroid of the collection */ getCentroid: function(weighted) { if (!weighted) { return this.components.length && this.components[0].getCentroid(); } var len = this.components.length; if (!len) { return false; } var areas = []; var centroids = []; var areaSum = 0; var minArea = Number.MAX_VALUE; var component; for (var i=0; i 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} The spatial reference system * for the geometry coordinates. If not provided, Geographic/WGS84 is * assumed. * * Returns: * {Float} The appoximate geodesic length of the geometry in meters. */ getGeodesicLength: function(projection) { var length = 0.0; for(var i=0, len=this.components.length; i} Center point for the rotation */ rotate: function(angle, origin) { for(var i=0, len=this.components.length; i} Point of origin for resizing * ratio - {Float} Optional x:y ratio for resizing. Default ratio is 1. * * Returns: * {OpenLayers.Geometry} - The current geometry. */ resize: function(scale, origin, ratio) { for(var i=0; i} 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 details = edge && options && options.details; var result, best, distance; var min = Number.POSITIVE_INFINITY; for(var i=0, len=this.components.length; i} The geometry to test. * * Returns: * {Boolean} The supplied geometry is equivalent to this geometry. */ equals: function(geometry) { var equivalent = true; if(!geometry || !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, len=this.components.length; i} * dest - {} * * Returns: * {} */ transform: function(source, dest) { if (source && dest) { for (var i=0, len=this.components.length; i} Any type of geometry. * * Returns: * {Boolean} The input geometry intersects this one. */ intersects: function(geometry) { var intersect = false; for(var i=0, len=this.components.length; i