git-svn-id: http://svn.openlayers.org/trunk/openlayers@5614 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
269 lines
7.9 KiB
JavaScript
269 lines
7.9 KiB
JavaScript
/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
|
|
* license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
|
|
* full text of the license. */
|
|
|
|
/**
|
|
* @requires OpenLayers/Format/WKT.js
|
|
* @requires OpenLayers/Feature/Vector.js
|
|
*/
|
|
|
|
/**
|
|
* Class: OpenLayers.Geometry
|
|
* A Geometry is a description of a geographic object. Create an instance of
|
|
* this class with the <OpenLayers.Geometry> constructor. This is a base class,
|
|
* typical geometry types are described by subclasses of this class.
|
|
*/
|
|
OpenLayers.Geometry = OpenLayers.Class({
|
|
|
|
/**
|
|
* Property: id
|
|
* {String} A unique identifier for this geometry.
|
|
*/
|
|
id: null,
|
|
|
|
/**
|
|
* Property: parent
|
|
* {<OpenLayers.Geometry>}This is set when a Geometry is added as component
|
|
* of another geometry
|
|
*/
|
|
parent: null,
|
|
|
|
/**
|
|
* Property: bounds
|
|
* {<OpenLayers.Bounds>} The bounds of this geometry
|
|
*/
|
|
bounds: null,
|
|
|
|
/**
|
|
* Constructor: OpenLayers.Geometry
|
|
* Creates a geometry object.
|
|
*/
|
|
initialize: function() {
|
|
this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME+ "_");
|
|
},
|
|
|
|
/**
|
|
* Method: destroy
|
|
* Destroy this geometry.
|
|
*/
|
|
destroy: function() {
|
|
this.id = null;
|
|
this.bounds = null;
|
|
},
|
|
|
|
/**
|
|
* APIMethod: clone
|
|
* Create a clone of this geometry. Does not set any non-standard
|
|
* properties of the cloned geometry.
|
|
*
|
|
* Returns:
|
|
* {<OpenLayers.Geometry>} An exact clone of this geometry.
|
|
*/
|
|
clone: function() {
|
|
return new OpenLayers.Geometry();
|
|
},
|
|
|
|
/**
|
|
* Set the bounds for this Geometry.
|
|
*
|
|
* Parameters:
|
|
* object - {<OpenLayers.Bounds>}
|
|
*/
|
|
setBounds: function(bounds) {
|
|
if (bounds) {
|
|
this.bounds = bounds.clone();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Method: clearBounds
|
|
* Nullify this components bounds and that of its parent as well.
|
|
*/
|
|
clearBounds: function() {
|
|
this.bounds = null;
|
|
if (this.parent) {
|
|
this.parent.clearBounds();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Method: extendBounds
|
|
* Extend the existing bounds to include the new bounds.
|
|
* If geometry's bounds is not yet set, then set a new Bounds.
|
|
*
|
|
* Parameters:
|
|
* newBounds - {<OpenLayers.Bounds>}
|
|
*/
|
|
extendBounds: function(newBounds){
|
|
var bounds = this.getBounds();
|
|
if (!bounds) {
|
|
this.setBounds(newBounds);
|
|
} else {
|
|
this.bounds.extend(newBounds);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* APIMethod: getBounds
|
|
* Get the bounds for this Geometry. If bounds is not set, it
|
|
* is calculated again, this makes queries faster.
|
|
*
|
|
* Returns:
|
|
* {<OpenLayers.Bounds>}
|
|
*/
|
|
getBounds: function() {
|
|
if (this.bounds == null) {
|
|
this.calculateBounds();
|
|
}
|
|
return this.bounds;
|
|
},
|
|
|
|
/**
|
|
* APIMethod: calculateBounds
|
|
* Recalculate the bounds for the geometry.
|
|
*/
|
|
calculateBounds: function() {
|
|
//
|
|
// This should be overridden by subclasses.
|
|
//
|
|
},
|
|
|
|
/**
|
|
* Method: atPoint
|
|
* Note - This is only an approximation based on the bounds of the
|
|
* geometry.
|
|
*
|
|
* Parameters:
|
|
* lonlat - {<OpenLayers.LonLat>}
|
|
* toleranceLon - {float} Optional tolerance in Geometric Coords
|
|
* toleranceLat - {float} Optional tolerance in Geographic Coords
|
|
*
|
|
* Returns:
|
|
* {Boolean} Whether or not the geometry is at the specified location
|
|
*/
|
|
atPoint: function(lonlat, toleranceLon, toleranceLat) {
|
|
var atPoint = false;
|
|
var bounds = this.getBounds();
|
|
if ((bounds != null) && (lonlat != null)) {
|
|
|
|
var dX = (toleranceLon != null) ? toleranceLon : 0;
|
|
var dY = (toleranceLat != null) ? toleranceLat : 0;
|
|
|
|
var toleranceBounds =
|
|
new OpenLayers.Bounds(this.bounds.left - dX,
|
|
this.bounds.bottom - dY,
|
|
this.bounds.right + dX,
|
|
this.bounds.top + dY);
|
|
|
|
atPoint = toleranceBounds.containsLonLat(lonlat);
|
|
}
|
|
return atPoint;
|
|
},
|
|
|
|
/**
|
|
* Method: getLength
|
|
* Calculate the length of this geometry. This method is defined in
|
|
* subclasses.
|
|
*
|
|
* Returns:
|
|
* {Float} The length of the collection by summing its parts
|
|
*/
|
|
getLength: function() {
|
|
//to be overridden by geometries that actually have a length
|
|
//
|
|
return 0.0;
|
|
},
|
|
|
|
/**
|
|
* Method: getArea
|
|
* Calculate the area of this geometry. This method is defined in subclasses.
|
|
*
|
|
* Returns:
|
|
* {Float} The area of the collection by summing its parts
|
|
*/
|
|
getArea: function() {
|
|
//to be overridden by geometries that actually have an area
|
|
//
|
|
return 0.0;
|
|
},
|
|
|
|
/**
|
|
* Method: toString
|
|
* Returns the Well-Known Text representation of a geometry
|
|
*
|
|
* Returns:
|
|
* {String} Well-Known Text
|
|
*/
|
|
toString: function() {
|
|
return OpenLayers.Format.WKT.prototype.write(
|
|
new OpenLayers.Feature.Vector(this)
|
|
);
|
|
},
|
|
|
|
CLASS_NAME: "OpenLayers.Geometry"
|
|
});
|
|
|
|
|
|
/**
|
|
* Method: OpenLayers.Geometry.segmentsIntersect
|
|
* Determine whether two line segments intersect. Optionally calculates
|
|
* and returns the intersection point. This function is optimized for
|
|
* cases where seg1.x2 >= seg2.x1 || seg2.x2 >= seg1.x1. In those
|
|
* obvious cases where there is no intersection, the function should
|
|
* not be called.
|
|
*
|
|
* Parameters:
|
|
* seg1 - {Object} Object representing a segment with properties x1, y1, x2,
|
|
* and y2. The start point is represented by x1 and y1. The end point
|
|
* is represented by x2 and y2. Start and end are ordered so that x1 < x2.
|
|
* seg2 - {Object} Object representing a segment with properties x1, y1, x2,
|
|
* and y2. The start point is represented by x1 and y1. The end point
|
|
* is represented by x2 and y2. Start and end are ordered so that x1 < x2.
|
|
* point - {Boolean} Return the intersection point. If false, the actual
|
|
* intersection point will not be calculated. If true and the segments
|
|
* intersect, the intersection point will be returned. If true and
|
|
* the segments do not intersect, false will be returned. If true and
|
|
* the segments are coincident, true will be returned.
|
|
*
|
|
* Returns:
|
|
* {Boolean | <OpenLayers.Geometry.Point>} The two segments intersect.
|
|
* If the point argument is true, the return will be the intersection
|
|
* point or false if none exists. If point is true and the segments
|
|
* are coincident, return will be true (and the instersection is equal
|
|
* to the shorter segment).
|
|
*/
|
|
OpenLayers.Geometry.segmentsIntersect = function(seg1, seg2, point) {
|
|
var intersection = false;
|
|
var x11_21 = seg1.x1 - seg2.x1;
|
|
var y11_21 = seg1.y1 - seg2.y1;
|
|
var x12_11 = seg1.x2 - seg1.x1;
|
|
var y12_11 = seg1.y2 - seg1.y1;
|
|
var y22_21 = seg2.y2 - seg2.y1;
|
|
var x22_21 = seg2.x2 - seg2.x1;
|
|
var d = (y22_21 * x12_11) - (x22_21 * y12_11);
|
|
var n1 = (x22_21 * y11_21) - (y22_21 * x11_21);
|
|
var n2 = (x12_11 * y11_21) - (y12_11 * x11_21);
|
|
if(d == 0) {
|
|
// parallel
|
|
if(n1 == 0 && n2 == 0) {
|
|
// coincident
|
|
intersection = true;
|
|
}
|
|
} else {
|
|
var along1 = n1 / d;
|
|
var along2 = n2 / d;
|
|
if(along1 >= 0 && along1 <= 1 && along2 >=0 && along2 <= 1) {
|
|
// intersect
|
|
if(!point) {
|
|
intersection = true;
|
|
} else {
|
|
// calculate the intersection point
|
|
var x = seg1.x1 + (along1 * x12_11);
|
|
var y = seg1.y1 + (along1 * y12_11);
|
|
intersection = new OpenLayers.Geometry.Point(x, y);
|
|
}
|
|
}
|
|
}
|
|
return intersection;
|
|
};
|