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.js @ 76

Revision 76, 14.5 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/Format/WKT.js
8 * @requires OpenLayers/Feature/Vector.js
9 */
10
11/**
12 * Class: OpenLayers.Geometry
13 * A Geometry is a description of a geographic object.  Create an instance of
14 * this class with the <OpenLayers.Geometry> constructor.  This is a base class,
15 * typical geometry types are described by subclasses of this class.
16 */
17OpenLayers.Geometry = OpenLayers.Class({
18
19    /**
20     * Property: id
21     * {String} A unique identifier for this geometry.
22     */
23    id: null,
24
25    /**
26     * Property: parent
27     * {<OpenLayers.Geometry>}This is set when a Geometry is added as component
28     * of another geometry
29     */
30    parent: null,
31
32    /**
33     * Property: bounds
34     * {<OpenLayers.Bounds>} The bounds of this geometry
35     */
36    bounds: null,
37
38    /**
39     * Constructor: OpenLayers.Geometry
40     * Creates a geometry object. 
41     */
42    initialize: function() {
43        this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME+ "_");
44    },
45   
46    /**
47     * Method: destroy
48     * Destroy this geometry.
49     */
50    destroy: function() {
51        this.id = null;
52        this.bounds = null;
53    },
54   
55    /**
56     * APIMethod: clone
57     * Create a clone of this geometry.  Does not set any non-standard
58     *     properties of the cloned geometry.
59     *
60     * Returns:
61     * {<OpenLayers.Geometry>} An exact clone of this geometry.
62     */
63    clone: function() {
64        return new OpenLayers.Geometry();
65    },
66   
67    /**
68     * Set the bounds for this Geometry.
69     *
70     * Parameters:
71     * object - {<OpenLayers.Bounds>}
72     */
73    setBounds: function(bounds) {
74        if (bounds) {
75            this.bounds = bounds.clone();
76        }
77    },
78   
79    /**
80     * Method: clearBounds
81     * Nullify this components bounds and that of its parent as well.
82     */
83    clearBounds: function() {
84        this.bounds = null;
85        if (this.parent) {
86            this.parent.clearBounds();
87        }   
88    },
89   
90    /**
91     * Method: extendBounds
92     * Extend the existing bounds to include the new bounds.
93     * If geometry's bounds is not yet set, then set a new Bounds.
94     *
95     * Parameters:
96     * newBounds - {<OpenLayers.Bounds>}
97     */
98    extendBounds: function(newBounds){
99        var bounds = this.getBounds();
100        if (!bounds) {
101            this.setBounds(newBounds);
102        } else {
103            this.bounds.extend(newBounds);
104        }
105    },
106   
107    /**
108     * APIMethod: getBounds
109     * Get the bounds for this Geometry. If bounds is not set, it
110     * is calculated again, this makes queries faster.
111     *
112     * Returns:
113     * {<OpenLayers.Bounds>}
114     */
115    getBounds: function() {
116        if (this.bounds == null) {
117            this.calculateBounds();
118        }
119        return this.bounds;
120    },
121   
122    /**
123     * APIMethod: calculateBounds
124     * Recalculate the bounds for the geometry.
125     */
126    calculateBounds: function() {
127        //
128        // This should be overridden by subclasses.
129        //
130    },
131   
132    /**
133     * APIMethod: distanceTo
134     * Calculate the closest distance between two geometries (on the x-y plane).
135     *
136     * Parameters:
137     * geometry - {<OpenLayers.Geometry>} The target geometry.
138     * options - {Object} Optional properties for configuring the distance
139     *     calculation.
140     *
141     * Valid options depend on the specific geometry type.
142     *
143     * Returns:
144     * {Number | Object} The distance between this geometry and the target.
145     *     If details is true, the return will be an object with distance,
146     *     x0, y0, x1, and x2 properties.  The x0 and y0 properties represent
147     *     the coordinates of the closest point on this geometry. The x1 and y1
148     *     properties represent the coordinates of the closest point on the
149     *     target geometry.
150     */
151    distanceTo: function(geometry, options) {
152    },
153   
154    /**
155     * APIMethod: getVertices
156     * Return a list of all points in this geometry.
157     *
158     * Parameters:
159     * nodes - {Boolean} For lines, only return vertices that are
160     *     endpoints.  If false, for lines, only vertices that are not
161     *     endpoints will be returned.  If not provided, all vertices will
162     *     be returned.
163     *
164     * Returns:
165     * {Array} A list of all vertices in the geometry.
166     */
167    getVertices: function(nodes) {
168    },
169
170    /**
171     * Method: atPoint
172     * Note - This is only an approximation based on the bounds of the
173     * geometry.
174     *
175     * Parameters:
176     * lonlat - {<OpenLayers.LonLat>}
177     * toleranceLon - {float} Optional tolerance in Geometric Coords
178     * toleranceLat - {float} Optional tolerance in Geographic Coords
179     *
180     * Returns:
181     * {Boolean} Whether or not the geometry is at the specified location
182     */
183    atPoint: function(lonlat, toleranceLon, toleranceLat) {
184        var atPoint = false;
185        var bounds = this.getBounds();
186        if ((bounds != null) && (lonlat != null)) {
187
188            var dX = (toleranceLon != null) ? toleranceLon : 0;
189            var dY = (toleranceLat != null) ? toleranceLat : 0;
190   
191            var toleranceBounds = 
192                new OpenLayers.Bounds(this.bounds.left - dX,
193                                      this.bounds.bottom - dY,
194                                      this.bounds.right + dX,
195                                      this.bounds.top + dY);
196
197            atPoint = toleranceBounds.containsLonLat(lonlat);
198        }
199        return atPoint;
200    },
201   
202    /**
203     * Method: getLength
204     * Calculate the length of this geometry. This method is defined in
205     * subclasses.
206     *
207     * Returns:
208     * {Float} The length of the collection by summing its parts
209     */
210    getLength: function() {
211        //to be overridden by geometries that actually have a length
212        //
213        return 0.0;
214    },
215
216    /**
217     * Method: getArea
218     * Calculate the area of this geometry. This method is defined in subclasses.
219     *
220     * Returns:
221     * {Float} The area of the collection by summing its parts
222     */
223    getArea: function() {
224        //to be overridden by geometries that actually have an area
225        //
226        return 0.0;
227    },
228   
229    /**
230     * APIMethod: getCentroid
231     * Calculate the centroid of this geometry. This method is defined in subclasses.
232     *
233     * Returns:
234     * {<OpenLayers.Geometry.Point>} The centroid of the collection
235     */
236    getCentroid: function() {
237        return null;
238    },
239
240    /**
241     * Method: toString
242     * Returns the Well-Known Text representation of a geometry
243     *
244     * Returns:
245     * {String} Well-Known Text
246     */
247    toString: function() {
248        return OpenLayers.Format.WKT.prototype.write(
249            new OpenLayers.Feature.Vector(this)
250        );
251    },
252
253    CLASS_NAME: "OpenLayers.Geometry"
254});
255
256/**
257 * Function: OpenLayers.Geometry.fromWKT
258 * Generate a geometry given a Well-Known Text string.
259 *
260 * Parameters:
261 * wkt - {String} A string representing the geometry in Well-Known Text.
262 *
263 * Returns:
264 * {<OpenLayers.Geometry>} A geometry of the appropriate class.
265 */
266OpenLayers.Geometry.fromWKT = function(wkt) {
267    var format = arguments.callee.format;
268    if(!format) {
269        format = new OpenLayers.Format.WKT();
270        arguments.callee.format = format;
271    }
272    var geom;
273    var result = format.read(wkt);
274    if(result instanceof OpenLayers.Feature.Vector) {
275        geom = result.geometry;
276    } else if(result instanceof Array) {
277        var len = result.length;
278        var components = new Array(len);
279        for(var i=0; i<len; ++i) {
280            components[i] = result[i].geometry;
281        }
282        geom = new OpenLayers.Geometry.Collection(components);
283    }
284    return geom;
285};
286   
287/**
288 * Method: OpenLayers.Geometry.segmentsIntersect
289 * Determine whether two line segments intersect.  Optionally calculates
290 *     and returns the intersection point.  This function is optimized for
291 *     cases where seg1.x2 >= seg2.x1 || seg2.x2 >= seg1.x1.  In those
292 *     obvious cases where there is no intersection, the function should
293 *     not be called.
294 *
295 * Parameters:
296 * seg1 - {Object} Object representing a segment with properties x1, y1, x2,
297 *     and y2.  The start point is represented by x1 and y1.  The end point
298 *     is represented by x2 and y2.  Start and end are ordered so that x1 < x2.
299 * seg2 - {Object} Object representing a segment with properties x1, y1, x2,
300 *     and y2.  The start point is represented by x1 and y1.  The end point
301 *     is represented by x2 and y2.  Start and end are ordered so that x1 < x2.
302 * options - {Object} Optional properties for calculating the intersection.
303 *
304 * Valid options:
305 * point - {Boolean} Return the intersection point.  If false, the actual
306 *     intersection point will not be calculated.  If true and the segments
307 *     intersect, the intersection point will be returned.  If true and
308 *     the segments do not intersect, false will be returned.  If true and
309 *     the segments are coincident, true will be returned.
310 * tolerance - {Number} If a non-null value is provided, if the segments are
311 *     within the tolerance distance, this will be considered an intersection.
312 *     In addition, if the point option is true and the calculated intersection
313 *     is within the tolerance distance of an end point, the endpoint will be
314 *     returned instead of the calculated intersection.  Further, if the
315 *     intersection is within the tolerance of endpoints on both segments, or
316 *     if two segment endpoints are within the tolerance distance of eachother
317 *     (but no intersection is otherwise calculated), an endpoint on the
318 *     first segment provided will be returned.
319 *
320 * Returns:
321 * {Boolean | <OpenLayers.Geometry.Point>}  The two segments intersect.
322 *     If the point argument is true, the return will be the intersection
323 *     point or false if none exists.  If point is true and the segments
324 *     are coincident, return will be true (and the instersection is equal
325 *     to the shorter segment).
326 */
327OpenLayers.Geometry.segmentsIntersect = function(seg1, seg2, options) {
328    var point = options && options.point;
329    var tolerance = options && options.tolerance;
330    var intersection = false;
331    var x11_21 = seg1.x1 - seg2.x1;
332    var y11_21 = seg1.y1 - seg2.y1;
333    var x12_11 = seg1.x2 - seg1.x1;
334    var y12_11 = seg1.y2 - seg1.y1;
335    var y22_21 = seg2.y2 - seg2.y1;
336    var x22_21 = seg2.x2 - seg2.x1;
337    var d = (y22_21 * x12_11) - (x22_21 * y12_11);
338    var n1 = (x22_21 * y11_21) - (y22_21 * x11_21);
339    var n2 = (x12_11 * y11_21) - (y12_11 * x11_21);
340    if(d == 0) {
341        // parallel
342        if(n1 == 0 && n2 == 0) {
343            // coincident
344            intersection = true;
345        }
346    } else {
347        var along1 = n1 / d;
348        var along2 = n2 / d;
349        if(along1 >= 0 && along1 <= 1 && along2 >=0 && along2 <= 1) {
350            // intersect
351            if(!point) {
352                intersection = true;
353            } else {
354                // calculate the intersection point
355                var x = seg1.x1 + (along1 * x12_11);
356                var y = seg1.y1 + (along1 * y12_11);
357                intersection = new OpenLayers.Geometry.Point(x, y);
358            }
359        }
360    }
361    if(tolerance) {
362        var dist;
363        if(intersection) {
364            if(point) {
365                var segs = [seg1, seg2];
366                var seg, x, y;
367                // check segment endpoints for proximity to intersection
368                // set intersection to first endpoint within the tolerance
369                outer: for(var i=0; i<2; ++i) {
370                    seg = segs[i];
371                    for(var j=1; j<3; ++j) {
372                        x = seg["x" + j];
373                        y = seg["y" + j];
374                        dist = Math.sqrt(
375                            Math.pow(x - intersection.x, 2) +
376                            Math.pow(y - intersection.y, 2)
377                        );
378                        if(dist < tolerance) {
379                            intersection.x = x;
380                            intersection.y = y;
381                            break outer;
382                        }
383                    }
384                }
385               
386            }
387        } else {
388            // no calculated intersection, but segments could be within
389            // the tolerance of one another
390            var segs = [seg1, seg2];
391            var source, target, x, y, p, result;
392            // check segment endpoints for proximity to intersection
393            // set intersection to first endpoint within the tolerance
394            outer: for(var i=0; i<2; ++i) {
395                source = segs[i];
396                target = segs[(i+1)%2];
397                for(var j=1; j<3; ++j) {
398                    p = {x: source["x"+j], y: source["y"+j]};
399                    result = OpenLayers.Geometry.distanceToSegment(p, target);
400                    if(result.distance < tolerance) {
401                        if(point) {
402                            intersection = new OpenLayers.Geometry.Point(p.x, p.y);
403                        } else {
404                            intersection = true;
405                        }
406                        break outer;
407                    }
408                }
409            }
410        }
411    }
412    return intersection;
413};
414
415/**
416 * Function: OpenLayers.Geometry.distanceToSegment
417 *
418 * Parameters:
419 * point - {Object} An object with x and y properties representing the
420 *     point coordinates.
421 * segment - {Object} An object with x1, y1, x2, and y2 properties
422 *     representing endpoint coordinates.
423 *
424 * Returns:
425 * {Object} An object with distance, x, and y properties.  The distance
426 *     will be the shortest distance between the input point and segment.
427 *     The x and y properties represent the coordinates along the segment
428 *     where the shortest distance meets the segment.
429 */
430OpenLayers.Geometry.distanceToSegment = function(point, segment) {
431    var x0 = point.x;
432    var y0 = point.y;
433    var x1 = segment.x1;
434    var y1 = segment.y1;
435    var x2 = segment.x2;
436    var y2 = segment.y2;
437    var dx = x2 - x1;
438    var dy = y2 - y1;
439    var along = ((dx * (x0 - x1)) + (dy * (y0 - y1))) /
440                (Math.pow(dx, 2) + Math.pow(dy, 2));
441    var x, y;
442    if(along <= 0.0) {
443        x = x1;
444        y = y1;
445    } else if(along >= 1.0) {
446        x = x2;
447        y = y2;
448    } else {
449        x = x1 + along * dx;
450        y = y1 + along * dy;
451    }
452    return {
453        distance: Math.sqrt(Math.pow(x - x0, 2) + Math.pow(y - y0, 2)),
454        x: x, y: y
455    };
456};
Note: See TracBrowser for help on using the repository browser.