Bienvenue sur PostGIS.fr

Bienvenue sur PostGIS.fr , le site de la communauté des utilisateurs francophones de PostGIS.

PostGIS ajoute le support d'objets géographique à la base de données PostgreSQL. En effet, PostGIS "spatialise" le serverur PostgreSQL, ce qui permet de l'utiliser comme une base de données SIG.

Maintenu à jour, en fonction de nos disponibilités et des diverses sorties des outils que nous testons, nous vous proposons l'ensemble de nos travaux publiés en langue française.

source: trunk/workshop-routing-foss4g/web/OpenLayers/lib/OpenLayers/Geometry/Collection.js @ 76

Revision 76, 17.7 KB checked in by djay, 12 years ago (diff)

Ajout du répertoire web

  • Property svn:executable set to *
Line 
1/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
2 * full list of contributors). Published under the Clear BSD license. 
3 * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
4 * full text of the license. */
5
6/**
7 * @requires OpenLayers/Geometry.js
8 */
9
10/**
11 * Class: OpenLayers.Geometry.Collection
12 * A Collection is exactly what it sounds like: A collection of different
13 * Geometries. These are stored in the local parameter <components> (which
14 * can be passed as a parameter to the constructor).
15 *
16 * As new geometries are added to the collection, they are NOT cloned.
17 * When removing geometries, they need to be specified by reference (ie you
18 * have to pass in the *exact* geometry to be removed).
19 *
20 * The <getArea> and <getLength> functions here merely iterate through
21 * the components, summing their respective areas and lengths.
22 *
23 * Create a new instance with the <OpenLayers.Geometry.Collection> constructor.
24 *
25 * Inerhits from:
26 *  - <OpenLayers.Geometry>
27 */
28OpenLayers.Geometry.Collection = OpenLayers.Class(OpenLayers.Geometry, {
29
30    /**
31     * APIProperty: components
32     * {Array(<OpenLayers.Geometry>)} The component parts of this geometry
33     */
34    components: null,
35   
36    /**
37     * Property: componentTypes
38     * {Array(String)} An array of class names representing the types of
39     * components that the collection can include.  A null value means the
40     * component types are not restricted.
41     */
42    componentTypes: null,
43
44    /**
45     * Constructor: OpenLayers.Geometry.Collection
46     * Creates a Geometry Collection -- a list of geoms.
47     *
48     * Parameters:
49     * components - {Array(<OpenLayers.Geometry>)} Optional array of geometries
50     *
51     */
52    initialize: function (components) {
53        OpenLayers.Geometry.prototype.initialize.apply(this, arguments);
54        this.components = [];
55        if (components != null) {
56            this.addComponents(components);
57        }
58    },
59
60    /**
61     * APIMethod: destroy
62     * Destroy this geometry.
63     */
64    destroy: function () {
65        this.components.length = 0;
66        this.components = null;
67        OpenLayers.Geometry.prototype.destroy.apply(this, arguments);
68    },
69
70    /**
71     * APIMethod: clone
72     * Clone this geometry.
73     *
74     * Returns:
75     * {<OpenLayers.Geometry.Collection>} An exact clone of this collection
76     */
77    clone: function() {
78        var geometry = eval("new " + this.CLASS_NAME + "()");
79        for(var i=0, len=this.components.length; i<len; i++) {
80            geometry.addComponent(this.components[i].clone());
81        }
82       
83        // catch any randomly tagged-on properties
84        OpenLayers.Util.applyDefaults(geometry, this);
85       
86        return geometry;
87    },
88
89    /**
90     * Method: getComponentsString
91     * Get a string representing the components for this collection
92     *
93     * Returns:
94     * {String} A string representation of the components of this geometry
95     */
96    getComponentsString: function(){
97        var strings = [];
98        for(var i=0, len=this.components.length; i<len; i++) {
99            strings.push(this.components[i].toShortString()); 
100        }
101        return strings.join(",");
102    },
103
104    /**
105     * APIMethod: calculateBounds
106     * Recalculate the bounds by iterating through the components and
107     * calling calling extendBounds() on each item.
108     */
109    calculateBounds: function() {
110        this.bounds = null;
111        if ( this.components && this.components.length > 0) {
112            this.setBounds(this.components[0].getBounds());
113            for (var i=1, len=this.components.length; i<len; i++) {
114                this.extendBounds(this.components[i].getBounds());
115            }
116        }
117    },
118
119    /**
120     * APIMethod: addComponents
121     * Add components to this geometry.
122     *
123     * Parameters:
124     * components - {Array(<OpenLayers.Geometry>)} An array of geometries to add
125     */
126    addComponents: function(components){
127        if(!(components instanceof Array)) {
128            components = [components];
129        }
130        for(var i=0, len=components.length; i<len; i++) {
131            this.addComponent(components[i]);
132        }
133    },
134
135    /**
136     * Method: addComponent
137     * Add a new component (geometry) to the collection.  If this.componentTypes
138     * is set, then the component class name must be in the componentTypes array.
139     *
140     * The bounds cache is reset.
141     *
142     * Parameters:
143     * component - {<OpenLayers.Geometry>} A geometry to add
144     * index - {int} Optional index into the array to insert the component
145     *
146     * Returns:
147     * {Boolean} The component geometry was successfully added
148     */   
149    addComponent: function(component, index) {
150        var added = false;
151        if(component) {
152            if(this.componentTypes == null ||
153               (OpenLayers.Util.indexOf(this.componentTypes,
154                                        component.CLASS_NAME) > -1)) {
155
156                if(index != null && (index < this.components.length)) {
157                    var components1 = this.components.slice(0, index);
158                    var components2 = this.components.slice(index, 
159                                                           this.components.length);
160                    components1.push(component);
161                    this.components = components1.concat(components2);
162                } else {
163                    this.components.push(component);
164                }
165                component.parent = this;
166                this.clearBounds();
167                added = true;
168            }
169        }
170        return added;
171    },
172   
173    /**
174     * APIMethod: removeComponents
175     * Remove components from this geometry.
176     *
177     * Parameters:
178     * components - {Array(<OpenLayers.Geometry>)} The components to be removed
179     */
180    removeComponents: function(components) {
181        if(!(components instanceof Array)) {
182            components = [components];
183        }
184        for(var i=components.length-1; i>=0; --i) {
185            this.removeComponent(components[i]);
186        }
187    },
188   
189    /**
190     * Method: removeComponent
191     * Remove a component from this geometry.
192     *
193     * Parameters:
194     * component - {<OpenLayers.Geometry>}
195     */
196    removeComponent: function(component) {
197       
198        OpenLayers.Util.removeItem(this.components, component);
199       
200        // clearBounds() so that it gets recalculated on the next call
201        // to this.getBounds();
202        this.clearBounds();
203    },
204
205    /**
206     * APIMethod: getLength
207     * Calculate the length of this geometry
208     *
209     * Returns:
210     * {Float} The length of the geometry
211     */
212    getLength: function() {
213        var length = 0.0;
214        for (var i=0, len=this.components.length; i<len; i++) {
215            length += this.components[i].getLength();
216        }
217        return length;
218    },
219   
220    /**
221     * APIMethod: getArea
222     * Calculate the area of this geometry. Note how this function is overridden
223     * in <OpenLayers.Geometry.Polygon>.
224     *
225     * Returns:
226     * {Float} The area of the collection by summing its parts
227     */
228    getArea: function() {
229        var area = 0.0;
230        for (var i=0, len=this.components.length; i<len; i++) {
231            area += this.components[i].getArea();
232        }
233        return area;
234    },
235
236    /**
237     * APIMethod: getGeodesicArea
238     * Calculate the approximate area of the polygon were it projected onto
239     *     the earth.
240     *
241     * Parameters:
242     * projection - {<OpenLayers.Projection>} The spatial reference system
243     *     for the geometry coordinates.  If not provided, Geographic/WGS84 is
244     *     assumed.
245     *
246     * Reference:
247     * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for
248     *     Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion
249     *     Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409
250     *
251     * Returns:
252     * {float} The approximate geodesic area of the geometry in square meters.
253     */
254    getGeodesicArea: function(projection) {
255        var area = 0.0;
256        for(var i=0, len=this.components.length; i<len; i++) {
257            area += this.components[i].getGeodesicArea(projection);
258        }
259        return area;
260    },
261   
262    /**
263     * APIMethod: getCentroid
264     *
265     * Compute the centroid for this geometry collection.
266     *
267     * Parameters:
268     * weighted - {Boolean} Perform the getCentroid computation recursively,
269     * returning an area weighted average of all geometries in this collection.
270     *
271     * Returns:
272     * {<OpenLayers.Geometry.Point>} The centroid of the collection
273     */
274    getCentroid: function(weighted) {
275        if (!weighted) {
276            return this.components.length && this.components[0].getCentroid();
277        }
278        var len = this.components.length;
279        if (!len) {
280            return false;
281        }
282       
283        var areas = [];
284        var centroids = [];
285        var areaSum = 0;
286        var minArea = Number.MAX_VALUE;
287        var component;
288        for (var i=0; i<len; ++i) {
289            component = this.components[i];
290            var area = component.getArea();
291            var centroid = component.getCentroid(true);
292            if (isNaN(area) || isNaN(centroid.x) || isNaN(centroid.y)) {
293                continue;
294            }
295            areas.push(area);
296            areaSum += area;
297            minArea = (area < minArea && area > 0) ? area : minArea;
298            centroids.push(centroid);
299        }
300        len = areas.length;
301        if (areaSum === 0) {
302            // all the components in this collection have 0 area
303            // probably a collection of points -- weight all the points the same
304            for (var i=0; i<len; ++i) {
305                areas[i] = 1;
306            }
307            areaSum = areas.length;
308        } else {
309            // normalize all the areas where the smallest area will get
310            // a value of 1
311            for (var i=0; i<len; ++i) {
312                areas[i] /= minArea;
313            }
314            areaSum /= minArea;
315        }
316       
317        var xSum = 0, ySum = 0, centroid, area;
318        for (var i=0; i<len; ++i) {
319            centroid = centroids[i];
320            area = areas[i];
321            xSum += centroid.x * area;
322            ySum += centroid.y * area;
323        }
324       
325        return new OpenLayers.Geometry.Point(xSum/areaSum, ySum/areaSum);
326    },
327
328    /**
329     * APIMethod: getGeodesicLength
330     * Calculate the approximate length of the geometry were it projected onto
331     *     the earth.
332     *
333     * projection - {<OpenLayers.Projection>} The spatial reference system
334     *     for the geometry coordinates.  If not provided, Geographic/WGS84 is
335     *     assumed.
336     *
337     * Returns:
338     * {Float} The appoximate geodesic length of the geometry in meters.
339     */
340    getGeodesicLength: function(projection) {
341        var length = 0.0;
342        for(var i=0, len=this.components.length; i<len; i++) {
343            length += this.components[i].getGeodesicLength(projection);
344        }
345        return length;
346    },
347
348    /**
349     * APIMethod: move
350     * Moves a geometry by the given displacement along positive x and y axes.
351     *     This modifies the position of the geometry and clears the cached
352     *     bounds.
353     *
354     * Parameters:
355     * x - {Float} Distance to move geometry in positive x direction.
356     * y - {Float} Distance to move geometry in positive y direction.
357     */
358    move: function(x, y) {
359        for(var i=0, len=this.components.length; i<len; i++) {
360            this.components[i].move(x, y);
361        }
362    },
363
364    /**
365     * APIMethod: rotate
366     * Rotate a geometry around some origin
367     *
368     * Parameters:
369     * angle - {Float} Rotation angle in degrees (measured counterclockwise
370     *                 from the positive x-axis)
371     * origin - {<OpenLayers.Geometry.Point>} Center point for the rotation
372     */
373    rotate: function(angle, origin) {
374        for(var i=0, len=this.components.length; i<len; ++i) {
375            this.components[i].rotate(angle, origin);
376        }
377    },
378
379    /**
380     * APIMethod: resize
381     * Resize a geometry relative to some origin.  Use this method to apply
382     *     a uniform scaling to a geometry.
383     *
384     * Parameters:
385     * scale - {Float} Factor by which to scale the geometry.  A scale of 2
386     *                 doubles the size of the geometry in each dimension
387     *                 (lines, for example, will be twice as long, and polygons
388     *                 will have four times the area).
389     * origin - {<OpenLayers.Geometry.Point>} Point of origin for resizing
390     * ratio - {Float} Optional x:y ratio for resizing.  Default ratio is 1.
391     *
392     * Returns:
393     * {OpenLayers.Geometry} - The current geometry.
394     */
395    resize: function(scale, origin, ratio) {
396        for(var i=0; i<this.components.length; ++i) {
397            this.components[i].resize(scale, origin, ratio);
398        }
399        return this;
400    },
401
402    /**
403     * APIMethod: distanceTo
404     * Calculate the closest distance between two geometries (on the x-y plane).
405     *
406     * Parameters:
407     * geometry - {<OpenLayers.Geometry>} The target geometry.
408     * options - {Object} Optional properties for configuring the distance
409     *     calculation.
410     *
411     * Valid options:
412     * details - {Boolean} Return details from the distance calculation.
413     *     Default is false.
414     * edge - {Boolean} Calculate the distance from this geometry to the
415     *     nearest edge of the target geometry.  Default is true.  If true,
416     *     calling distanceTo from a geometry that is wholly contained within
417     *     the target will result in a non-zero distance.  If false, whenever
418     *     geometries intersect, calling distanceTo will return 0.  If false,
419     *     details cannot be returned.
420     *
421     * Returns:
422     * {Number | Object} The distance between this geometry and the target.
423     *     If details is true, the return will be an object with distance,
424     *     x0, y0, x1, and y1 properties.  The x0 and y0 properties represent
425     *     the coordinates of the closest point on this geometry. The x1 and y1
426     *     properties represent the coordinates of the closest point on the
427     *     target geometry.
428     */
429    distanceTo: function(geometry, options) {
430        var edge = !(options && options.edge === false);
431        var details = edge && options && options.details;
432        var result, best, distance;
433        var min = Number.POSITIVE_INFINITY;
434        for(var i=0, len=this.components.length; i<len; ++i) {
435            result = this.components[i].distanceTo(geometry, options);
436            distance = details ? result.distance : result;
437            if(distance < min) {
438                min = distance;
439                best = result;
440                if(min == 0) {
441                    break;
442                }
443            }
444        }
445        return best;
446    },
447
448    /**
449     * APIMethod: equals
450     * Determine whether another geometry is equivalent to this one.  Geometries
451     *     are considered equivalent if all components have the same coordinates.
452     *
453     * Parameters:
454     * geom - {<OpenLayers.Geometry>} The geometry to test.
455     *
456     * Returns:
457     * {Boolean} The supplied geometry is equivalent to this geometry.
458     */
459    equals: function(geometry) {
460        var equivalent = true;
461        if(!geometry || !geometry.CLASS_NAME ||
462           (this.CLASS_NAME != geometry.CLASS_NAME)) {
463            equivalent = false;
464        } else if(!(geometry.components instanceof Array) ||
465                  (geometry.components.length != this.components.length)) {
466            equivalent = false;
467        } else {
468            for(var i=0, len=this.components.length; i<len; ++i) {
469                if(!this.components[i].equals(geometry.components[i])) {
470                    equivalent = false;
471                    break;
472                }
473            }
474        }
475        return equivalent;
476    },
477
478    /**
479     * APIMethod: transform
480     * Reproject the components geometry from source to dest.
481     *
482     * Parameters:
483     * source - {<OpenLayers.Projection>}
484     * dest - {<OpenLayers.Projection>}
485     *
486     * Returns:
487     * {<OpenLayers.Geometry>}
488     */
489    transform: function(source, dest) {
490        if (source && dest) {
491            for (var i=0, len=this.components.length; i<len; i++) { 
492                var component = this.components[i];
493                component.transform(source, dest);
494            }
495            this.bounds = null;
496        }
497        return this;
498    },
499
500    /**
501     * APIMethod: intersects
502     * Determine if the input geometry intersects this one.
503     *
504     * Parameters:
505     * geometry - {<OpenLayers.Geometry>} Any type of geometry.
506     *
507     * Returns:
508     * {Boolean} The input geometry intersects this one.
509     */
510    intersects: function(geometry) {
511        var intersect = false;
512        for(var i=0, len=this.components.length; i<len; ++ i) {
513            intersect = geometry.intersects(this.components[i]);
514            if(intersect) {
515                break;
516            }
517        }
518        return intersect;
519    },
520
521    /**
522     * APIMethod: getVertices
523     * Return a list of all points in this geometry.
524     *
525     * Parameters:
526     * nodes - {Boolean} For lines, only return vertices that are
527     *     endpoints.  If false, for lines, only vertices that are not
528     *     endpoints will be returned.  If not provided, all vertices will
529     *     be returned.
530     *
531     * Returns:
532     * {Array} A list of all vertices in the geometry.
533     */
534    getVertices: function(nodes) {
535        var vertices = [];
536        for(var i=0, len=this.components.length; i<len; ++i) {
537            Array.prototype.push.apply(
538                vertices, this.components[i].getVertices(nodes)
539            );
540        }
541        return vertices;
542    },
543
544
545    CLASS_NAME: "OpenLayers.Geometry.Collection"
546});
Note: See TracBrowser for help on using the repository browser.