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:
@@ -174,6 +174,125 @@ OpenLayers.Geometry.LinearRing = OpenLayers.Class(
|
||||
}
|
||||
return area;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: containsPoint
|
||||
* Test if a point is inside a linear ring. For the case where a point
|
||||
* is coincident with a linear ring edge, returns 1. Otherwise,
|
||||
* returns boolean.
|
||||
*
|
||||
* Parameters:
|
||||
* point - {<OpenLayers.Geometry.Point>}
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean | Number} The point is inside the linear ring. Returns 1 if
|
||||
* the point is coincident with an edge. Returns boolean otherwise.
|
||||
*/
|
||||
containsPoint: function(point) {
|
||||
var px = point.x;
|
||||
var py = point.y;
|
||||
function getX(y, x1, y1, x2, y2) {
|
||||
return (((x1 - x2) * y) + ((x2 * y1) - (x1 * y2))) / (y1 - y2);
|
||||
}
|
||||
var numSeg = this.components.length - 1;
|
||||
var start, end, x1, y1, x2, y2, cx, cy;
|
||||
var crosses = 0;
|
||||
for(var i=0; i<numSeg; ++i) {
|
||||
start = this.components[i];
|
||||
x1 = start.x;
|
||||
y1 = start.y;
|
||||
end = this.components[i + 1];
|
||||
x2 = end.x;
|
||||
y2 = end.y;
|
||||
|
||||
/**
|
||||
* The following conditions enforce five edge-crossing rules:
|
||||
* 1. points coincident with edges are considered contained;
|
||||
* 2. an upward edge includes its starting endpoint, and
|
||||
* excludes its final endpoint;
|
||||
* 3. a downward edge excludes its starting endpoint, and
|
||||
* includes its final endpoint;
|
||||
* 4. horizontal edges are excluded; and
|
||||
* 5. the edge-ray intersection point must be strictly right
|
||||
* of the point P.
|
||||
*/
|
||||
if(y1 == y2) {
|
||||
// horizontal edge
|
||||
if(py == y1) {
|
||||
// point on horizontal line
|
||||
if(x1 <= x2 && (px >= x1 && px <= x2) || // right or vert
|
||||
x1 >= x2 && (px <= x1 && px >= x2)) { // left or vert
|
||||
// point on edge
|
||||
crosses = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// ignore other horizontal edges
|
||||
continue;
|
||||
}
|
||||
cx = getX(py, x1, y1, x2, y2);
|
||||
if(cx == px) {
|
||||
// point on line
|
||||
if(y1 < y2 && (py >= y1 && py <= y2) || // upward
|
||||
y1 > y2 && (py <= y1 && py >= y2)) { // downward
|
||||
// point on edge
|
||||
crosses = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(cx <= px) {
|
||||
// no crossing to the right
|
||||
continue;
|
||||
}
|
||||
if(cx < Math.min(x1, x2) || cx > Math.max(x1, x2)) {
|
||||
// no crossing
|
||||
continue;
|
||||
}
|
||||
if(y1 < y2 && (py >= y1 && py < y2) || // upward
|
||||
y1 > y2 && (py < y1 && py >= y2)) { // downward
|
||||
++crosses;
|
||||
}
|
||||
}
|
||||
var contained = (crosses == -1) ?
|
||||
// on edge
|
||||
1 :
|
||||
// even (out) or odd (in)
|
||||
!!(crosses & 1);
|
||||
|
||||
return contained;
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: intersects
|
||||
* Determine if the input geometry intersects this one.
|
||||
*
|
||||
* Parameters:
|
||||
* geometry - {<OpenLayers.Geometry>} Any type of geometry.
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} The input geometry intersects this one.
|
||||
*/
|
||||
intersects: function(geometry) {
|
||||
var intersect = false;
|
||||
if(geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
|
||||
intersect = this.containsPoint(geometry);
|
||||
} else if(geometry.CLASS_NAME == "OpenLayers.Geometry.LineString") {
|
||||
intersect = geometry.intersects(this);
|
||||
} else if(geometry.CLASS_NAME == "OpenLayers.Geometry.LinearRing") {
|
||||
intersect = OpenLayers.Geometry.LineString.prototype.intersects.apply(
|
||||
this, [geometry]
|
||||
);
|
||||
} else {
|
||||
// check for component intersections
|
||||
for(var i=0; i<geometry.components.length; ++ i) {
|
||||
intersect = geometry.components[i].intersects(this);
|
||||
if(intersect) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return intersect;
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Geometry.LinearRing"
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user