1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
|
OpenLayers.Geometry.LinearRing= OpenLayers.overload(OpenLayers.Geometry.LinearRing, {
containsPoint: function(point) {
var approx = OpenLayers.Number.limitSigDigs;
var digs = 14;
var px = approx(point.x, digs);
var py = approx(point.y, digs);
function getX(y, x1, y1, x2, y2) {
return (y-y2)*((x2-x1)/(y2-y1)) + x2;
}
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 = approx(start.x, digs);
y1 = approx(start.y, digs);
end = this.components[i + 1];
x2 = approx(end.x, digs);
y2 = approx(end.y, digs);
/**
* 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 = approx(getX(py, x1, y1, x2, y2), digs);
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(x1 != x2 && (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;
}
}); |
Partager