git-svn-id: http://svn.openlayers.org/trunk/openlayers@7627 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
159 lines
5.4 KiB
JavaScript
159 lines
5.4 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/Geometry/Curve.js
|
|
*/
|
|
|
|
/**
|
|
* Class: OpenLayers.Geometry.LineString
|
|
* A LineString is a Curve which, once two points have been added to it, can
|
|
* never be less than two points long.
|
|
*
|
|
* Inherits from:
|
|
* - <OpenLayers.Geometry.Curve>
|
|
*/
|
|
OpenLayers.Geometry.LineString = OpenLayers.Class(OpenLayers.Geometry.Curve, {
|
|
|
|
/**
|
|
* Constructor: OpenLayers.Geometry.LineString
|
|
* Create a new LineString geometry
|
|
*
|
|
* Parameters:
|
|
* points - {Array(<OpenLayers.Geometry.Point>)} An array of points used to
|
|
* generate the linestring
|
|
*
|
|
*/
|
|
initialize: function(points) {
|
|
OpenLayers.Geometry.Curve.prototype.initialize.apply(this, arguments);
|
|
},
|
|
|
|
/**
|
|
* APIMethod: removeComponent
|
|
* Only allows removal of a point if there are three or more points in
|
|
* the linestring. (otherwise the result would be just a single point)
|
|
*
|
|
* Parameters:
|
|
* point - {<OpenLayers.Geometry.Point>} The point to be removed
|
|
*/
|
|
removeComponent: function(point) {
|
|
if ( this.components && (this.components.length > 2)) {
|
|
OpenLayers.Geometry.Collection.prototype.removeComponent.apply(this,
|
|
arguments);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* APIMethod: intersects
|
|
* Test for instersection between two geometries. This is a cheapo
|
|
* implementation of the Bently-Ottmann algorigithm. It doesn't
|
|
* really keep track of a sweep line data structure. It is closer
|
|
* to the brute force method, except that segments are sorted and
|
|
* potential intersections are only calculated when bounding boxes
|
|
* intersect.
|
|
*
|
|
* Parameters:
|
|
* geometry - {<OpenLayers.Geometry>}
|
|
*
|
|
* Returns:
|
|
* {Boolean} The input geometry intersects this geometry.
|
|
*/
|
|
intersects: function(geometry) {
|
|
var intersect = false;
|
|
var type = geometry.CLASS_NAME;
|
|
if(type == "OpenLayers.Geometry.LineString" ||
|
|
type == "OpenLayers.Geometry.LinearRing" ||
|
|
type == "OpenLayers.Geometry.Point") {
|
|
var segs1 = this.getSortedSegments();
|
|
var segs2;
|
|
if(type == "OpenLayers.Geometry.Point") {
|
|
segs2 = [{
|
|
x1: geometry.x, y1: geometry.y,
|
|
x2: geometry.x, y2: geometry.y
|
|
}];
|
|
} else {
|
|
segs2 = geometry.getSortedSegments();
|
|
}
|
|
var seg1, seg1x1, seg1x2, seg1y1, seg1y2,
|
|
seg2, seg2y1, seg2y2;
|
|
// sweep right
|
|
outer: for(var i=0, len=segs1.length; i<len; ++i) {
|
|
seg1 = segs1[i];
|
|
seg1x1 = seg1.x1;
|
|
seg1x2 = seg1.x2;
|
|
seg1y1 = seg1.y1;
|
|
seg1y2 = seg1.y2;
|
|
inner: for(var j=0, jlen=segs2.length; j<jlen; ++j) {
|
|
seg2 = segs2[j];
|
|
if(seg2.x1 > seg1x2) {
|
|
// seg1 still left of seg2
|
|
break;
|
|
}
|
|
if(seg2.x2 < seg1x1) {
|
|
// seg2 still left of seg1
|
|
continue;
|
|
}
|
|
seg2y1 = seg2.y1;
|
|
seg2y2 = seg2.y2;
|
|
if(Math.min(seg2y1, seg2y2) > Math.max(seg1y1, seg1y2)) {
|
|
// seg2 above seg1
|
|
continue;
|
|
}
|
|
if(Math.max(seg2y1, seg2y2) < Math.min(seg1y1, seg1y2)) {
|
|
// seg2 below seg1
|
|
continue;
|
|
}
|
|
if(OpenLayers.Geometry.segmentsIntersect(seg1, seg2)) {
|
|
intersect = true;
|
|
break outer;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
intersect = geometry.intersects(this);
|
|
}
|
|
return intersect;
|
|
},
|
|
|
|
/**
|
|
* Method: getSortedSegments
|
|
*
|
|
* Returns:
|
|
* {Array} An array of segment objects. Segment objects have 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.
|
|
*/
|
|
getSortedSegments: function() {
|
|
var numSeg = this.components.length - 1;
|
|
var segments = new Array(numSeg);
|
|
for(var i=0; i<numSeg; ++i) {
|
|
point1 = this.components[i];
|
|
point2 = this.components[i + 1];
|
|
if(point1.x < point2.x) {
|
|
segments[i] = {
|
|
x1: point1.x,
|
|
y1: point1.y,
|
|
x2: point2.x,
|
|
y2: point2.y
|
|
};
|
|
} else {
|
|
segments[i] = {
|
|
x1: point2.x,
|
|
y1: point2.y,
|
|
x2: point1.x,
|
|
y2: point1.y
|
|
};
|
|
}
|
|
}
|
|
// more efficient to define this somewhere static
|
|
function byX1(seg1, seg2) {
|
|
return seg1.x1 - seg2.x1;
|
|
}
|
|
return segments.sort(byX1);
|
|
},
|
|
|
|
CLASS_NAME: "OpenLayers.Geometry.LineString"
|
|
});
|