add geometry.intersects method for all geometry types (closes #1072)
git-svn-id: http://svn.openlayers.org/trunk/openlayers@5458 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
@@ -41,6 +41,116 @@ OpenLayers.Geometry.LineString = OpenLayers.Class(OpenLayers.Geometry.Curve, {
|
||||
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; i<segs1.length; ++i) {
|
||||
seg1 = segs1[i];
|
||||
seg1x1 = seg1.x1;
|
||||
seg1x2 = seg1.x2;
|
||||
seg1y1 = seg1.y1;
|
||||
seg1y2 = seg1.y2;
|
||||
inner: for(var j=0; j<segs2.length; ++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"
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user