Add split method for linestring and multilinestring geometries. Use for splitting one geometry with another. Optionally performs a mutual split. r=ahocevar (closes #1929)

git-svn-id: http://svn.openlayers.org/trunk/openlayers@8974 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
Tim Schaub
2009-03-09 22:19:07 +00:00
parent 837efd0b9c
commit a10b319413
5 changed files with 806 additions and 3 deletions

View File

@@ -287,11 +287,23 @@ OpenLayers.Geometry.fromWKT = function(wkt) {
* 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.
* options - {Object} Optional properties for calculating the intersection.
*
* Valid options:
* 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.
* tolerance - {Number} If a non-null value is provided, if the segments are
* within the tolerance distance, this will be considered an intersection.
* In addition, if the point option is true and the calculated intersection
* is within the tolerance distance of an end point, the endpoint will be
* returned instead of the calculated intersection. Further, if the
* intersection is within the tolerance of endpoints on both segments, or
* if two segment endpoints are within the tolerance distance of eachother
* (but no intersection is otherwise calculated), an endpoint on the
* first segment provided will be returned.
*
* Returns:
* {Boolean | <OpenLayers.Geometry.Point>} The two segments intersect.
@@ -300,7 +312,9 @@ OpenLayers.Geometry.fromWKT = function(wkt) {
* are coincident, return will be true (and the instersection is equal
* to the shorter segment).
*/
OpenLayers.Geometry.segmentsIntersect = function(seg1, seg2, point) {
OpenLayers.Geometry.segmentsIntersect = function(seg1, seg2, options) {
var point = options && options.point;
var tolerance = options && options.tolerance;
var intersection = false;
var x11_21 = seg1.x1 - seg2.x1;
var y11_21 = seg1.y1 - seg2.y1;
@@ -332,6 +346,57 @@ OpenLayers.Geometry.segmentsIntersect = function(seg1, seg2, point) {
}
}
}
if(tolerance) {
var dist;
if(intersection) {
if(point) {
var segs = [seg1, seg2];
var seg, x, y;
// check segment endpoints for proximity to intersection
// set intersection to first endpoint within the tolerance
outer: for(var i=0; i<2; ++i) {
seg = segs[i];
for(var j=1; j<3; ++j) {
x = seg["x" + j];
y = seg["y" + j];
dist = Math.sqrt(
Math.pow(x - intersection.x, 2) +
Math.pow(y - intersection.y, 2)
)
if(dist < tolerance) {
intersection.x = x;
intersection.y = y;
break outer;
}
}
}
}
} else {
// no calculated intersection, but segments could be within
// the tolerance of one another
var segs = [seg1, seg2];
var source, target, x, y, p, result;
// check segment endpoints for proximity to intersection
// set intersection to first endpoint within the tolerance
outer: for(var i=0; i<2; ++i) {
source = segs[i];
target = segs[(i+1)%2];
for(var j=1; j<3; ++j) {
p = {x: source["x"+j], y: source["y"+j]};
result = OpenLayers.Geometry.distanceToSegment(p, target);
if(result.distance < tolerance) {
if(point) {
intersection = new OpenLayers.Geometry.Point(p.x, p.y);
} else {
intersection = true;
}
break outer;
}
}
}
}
}
return intersection;
};