Adding distanceTo method to all geometry types. This calculates the shortest distance between any two geometries. For geometries that are entirely contained within polygons, the distance returned will be the distance to the nearest edge. Set the edge option to false to return 0 in cases where one geometry contains another. Details about the distance calculation can be returned by setting the details option true. Details include information about endpoints of the shortest segment between the two geometries. r=ahocevar (closes #1907)
git-svn-id: http://svn.openlayers.org/trunk/openlayers@8836 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
@@ -128,6 +128,28 @@ OpenLayers.Geometry = OpenLayers.Class({
|
||||
//
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: distanceTo
|
||||
* Calculate the closest distance between two geometries.
|
||||
*
|
||||
* Parameters:
|
||||
* geometry - {<OpenLayers.Geometry>} The target geometry.
|
||||
* options - {Object} Optional properties for configuring the distance
|
||||
* calculation.
|
||||
*
|
||||
* Valid options depend on the specific geometry type.
|
||||
*
|
||||
* Returns:
|
||||
* {Number | Object} The distance between this geometry and the target.
|
||||
* If details is true, the return will be an object with distance,
|
||||
* x0, y0, x1, and x2 properties. The x0 and y0 properties represent
|
||||
* the coordinates of the closest point on this geometry. The x1 and y1
|
||||
* properties represent the coordinates of the closest point on the
|
||||
* target geometry.
|
||||
*/
|
||||
distanceTo: function(geometry, options) {
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: atPoint
|
||||
* Note - This is only an approximation based on the bounds of the
|
||||
@@ -296,3 +318,46 @@ OpenLayers.Geometry.segmentsIntersect = function(seg1, seg2, point) {
|
||||
}
|
||||
return intersection;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: OpenLayers.Geometry.distanceToSegment
|
||||
*
|
||||
* Parameters:
|
||||
* point - {Object} An object with x and y properties representing the
|
||||
* point coordinates.
|
||||
* segment - {Object} An object with x1, y1, x2, and y2 properties
|
||||
* representing endpoint coordinates.
|
||||
*
|
||||
* Returns:
|
||||
* {Object} An object with distance, x, and y properties. The distance
|
||||
* will be the shortest distance between the input point and segment.
|
||||
* The x and y properties represent the coordinates along the segment
|
||||
* where the shortest distance meets the segment.
|
||||
*/
|
||||
OpenLayers.Geometry.distanceToSegment = function(point, segment) {
|
||||
var x0 = point.x;
|
||||
var y0 = point.y;
|
||||
var x1 = segment.x1;
|
||||
var y1 = segment.y1;
|
||||
var x2 = segment.x2;
|
||||
var y2 = segment.y2;
|
||||
var dx = x2 - x1;
|
||||
var dy = y2 - y1;
|
||||
var along = ((dx * (x0 - x1)) + (dy * (y0 - y1))) /
|
||||
(Math.pow(dx, 2) + Math.pow(dy, 2));
|
||||
var x, y;
|
||||
if(along <= 0.0) {
|
||||
x = x1;
|
||||
y = y1;
|
||||
} else if(along >= 1.0) {
|
||||
x = x2;
|
||||
y = y2;
|
||||
} else {
|
||||
x = x1 + along * dx;
|
||||
y = y1 + along * dy;
|
||||
}
|
||||
return {
|
||||
distance: Math.sqrt(Math.pow(x - x0, 2) + Math.pow(y - y0, 2)),
|
||||
x: x, y: y
|
||||
};
|
||||
};
|
||||
|
||||
@@ -279,6 +279,52 @@ OpenLayers.Geometry.Collection = OpenLayers.Class(OpenLayers.Geometry, {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: distanceTo
|
||||
* Calculate the closest distance between two geometries.
|
||||
*
|
||||
* Parameters:
|
||||
* geometry - {<OpenLayers.Geometry>} The target geometry.
|
||||
* options - {Object} Optional properties for configuring the distance
|
||||
* calculation.
|
||||
*
|
||||
* Valid options:
|
||||
* details - {Boolean} Return details from the distance calculation.
|
||||
* Default is false.
|
||||
* edge - {Boolean} Calculate the distance from this geometry to the
|
||||
* nearest edge of the target geometry. Default is true. If true,
|
||||
* calling distanceTo from a geometry that is wholly contained within
|
||||
* the target will result in a non-zero distance. If false, whenever
|
||||
* geometries intersect, calling distanceTo will return 0. If false,
|
||||
* details cannot be returned.
|
||||
*
|
||||
* Returns:
|
||||
* {Number | Object} The distance between this geometry and the target.
|
||||
* If details is true, the return will be an object with distance,
|
||||
* x0, y0, x1, and y1 properties. The x0 and y0 properties represent
|
||||
* the coordinates of the closest point on this geometry. The x1 and y1
|
||||
* properties represent the coordinates of the closest point on the
|
||||
* target geometry.
|
||||
*/
|
||||
distanceTo: function(geometry, options) {
|
||||
var edge = !(options && options.edge === false);
|
||||
var details = edge && options && options.details;
|
||||
var result, best;
|
||||
var min = Number.POSITIVE_INFINITY;
|
||||
for(var i=0, len=this.components.length; i<len; ++i) {
|
||||
result = this.components[i].distanceTo(geometry, options);
|
||||
distance = details ? result.distance : result;
|
||||
if(distance < min) {
|
||||
min = distance;
|
||||
best = result;
|
||||
if(min == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return best;
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: equals
|
||||
* Tests for equivalent geometries
|
||||
|
||||
@@ -154,5 +154,138 @@ OpenLayers.Geometry.LineString = OpenLayers.Class(OpenLayers.Geometry.Curve, {
|
||||
return segments.sort(byX1);
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: distanceTo
|
||||
* Calculate the closest distance between two geometries.
|
||||
*
|
||||
* Parameters:
|
||||
* geometry - {<OpenLayers.Geometry>} The target geometry.
|
||||
* options - {Object} Optional properties for configuring the distance
|
||||
* calculation.
|
||||
*
|
||||
* Valid options:
|
||||
* details - {Boolean} Return details from the distance calculation.
|
||||
* Default is false.
|
||||
* edge - {Boolean} Calculate the distance from this geometry to the
|
||||
* nearest edge of the target geometry. Default is true. If true,
|
||||
* calling distanceTo from a geometry that is wholly contained within
|
||||
* the target will result in a non-zero distance. If false, whenever
|
||||
* geometries intersect, calling distanceTo will return 0. If false,
|
||||
* details cannot be returned.
|
||||
*
|
||||
* Returns:
|
||||
* {Number | Object} The distance between this geometry and the target.
|
||||
* If details is true, the return will be an object with distance,
|
||||
* x0, y0, x1, and x2 properties. The x0 and y0 properties represent
|
||||
* the coordinates of the closest point on this geometry. The x1 and y1
|
||||
* properties represent the coordinates of the closest point on the
|
||||
* target geometry.
|
||||
*/
|
||||
distanceTo: function(geometry, options) {
|
||||
var edge = !(options && options.edge === false);
|
||||
var details = edge && options && options.details;
|
||||
var result, best = {};
|
||||
var min = Number.POSITIVE_INFINITY;
|
||||
if(geometry instanceof OpenLayers.Geometry.Point) {
|
||||
var segs = this.getSortedSegments();
|
||||
var x = geometry.x;
|
||||
var y = geometry.y;
|
||||
var seg;
|
||||
for(var i=0, len=segs.length; i<len; ++i) {
|
||||
seg = segs[i];
|
||||
result = OpenLayers.Geometry.distanceToSegment(geometry, seg);
|
||||
if(result.distance < min) {
|
||||
min = result.distance;
|
||||
best = result;
|
||||
if(min == 0) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// if distance increases and we cross y0 to the right of x0, no need to keep looking.
|
||||
if(seg.x2 > x && ((y > seg.y1 && y < seg.y2) || (y < seg.y1 && y > seg.y2))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(details) {
|
||||
best = {
|
||||
distance: best.distance,
|
||||
x0: best.x, y0: best.y,
|
||||
x1: x, y1: y
|
||||
};
|
||||
} else {
|
||||
best = best.distance;
|
||||
}
|
||||
} else if(geometry instanceof OpenLayers.Geometry.LineString) {
|
||||
var segs0 = this.getSortedSegments();
|
||||
var segs1 = geometry.getSortedSegments();
|
||||
var seg0, seg1, intersection, x0, y0;
|
||||
var len1 = segs1.length;
|
||||
outer: for(var i=0, len=segs0.length; i<len; ++i) {
|
||||
seg0 = segs0[i];
|
||||
x0 = seg0.x1;
|
||||
y0 = seg0.y1;
|
||||
for(var j=0; j<len1; ++j) {
|
||||
seg1 = segs1[j];
|
||||
intersection = OpenLayers.Geometry.segmentsIntersect(seg0, seg1, true);
|
||||
if(intersection) {
|
||||
min = 0;
|
||||
best = {
|
||||
distance: 0,
|
||||
x0: intersection.x, y0: intersection.y,
|
||||
x1: intersection.x, y1: intersection.y
|
||||
};
|
||||
break outer;
|
||||
} else {
|
||||
result = OpenLayers.Geometry.distanceToSegment({x: x0, y: y0}, seg1);
|
||||
if(result.distance < min) {
|
||||
min = result.distance;
|
||||
best = {
|
||||
distance: min,
|
||||
x0: x0, y0: y0,
|
||||
x1: result.x, y1: result.y
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!details) {
|
||||
best = best.distance;
|
||||
}
|
||||
if(min !== 0) {
|
||||
// check the final vertex in this line's sorted segments
|
||||
if(seg0) {
|
||||
result = geometry.distanceTo(
|
||||
new OpenLayers.Geometry.Point(seg0.x2, seg0.y2),
|
||||
options
|
||||
);
|
||||
var dist = details ? result.distance : result;
|
||||
if(dist < min) {
|
||||
if(details) {
|
||||
best = {
|
||||
distance: min,
|
||||
x0: result.x1, y0: result.y1,
|
||||
x1: result.x0, y1: result.y0
|
||||
};
|
||||
} else {
|
||||
best = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
best = geometry.distanceTo(this, options);
|
||||
// swap since target comes from this line
|
||||
if(details) {
|
||||
best = {
|
||||
distance: best.distance,
|
||||
x0: best.x1, y0: best.y1,
|
||||
x1: best.x0, y1: best.y0
|
||||
};
|
||||
}
|
||||
}
|
||||
return best;
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Geometry.LineString"
|
||||
});
|
||||
|
||||
@@ -71,20 +71,55 @@ OpenLayers.Geometry.Point = OpenLayers.Class(OpenLayers.Geometry, {
|
||||
|
||||
/**
|
||||
* APIMethod: distanceTo
|
||||
* Calculate the closest distance between two geometries.
|
||||
*
|
||||
* Parameters:
|
||||
* point - {<OpenLayers.Geometry.Point>}
|
||||
* geometry - {<OpenLayers.Geometry>} The target geometry.
|
||||
* options - {Object} Optional properties for configuring the distance
|
||||
* calculation.
|
||||
*
|
||||
* Valid options:
|
||||
* details - {Boolean} Return details from the distance calculation.
|
||||
* Default is false.
|
||||
* edge - {Boolean} Calculate the distance from this geometry to the
|
||||
* nearest edge of the target geometry. Default is true. If true,
|
||||
* calling distanceTo from a geometry that is wholly contained within
|
||||
* the target will result in a non-zero distance. If false, whenever
|
||||
* geometries intersect, calling distanceTo will return 0. If false,
|
||||
* details cannot be returned.
|
||||
*
|
||||
* Returns:
|
||||
* {Number | Object} The distance between this geometry and the target.
|
||||
* If details is true, the return will be an object with distance,
|
||||
* x0, y0, x1, and x2 properties. The x0 and y0 properties represent
|
||||
* the coordinates of the closest point on this geometry. The x1 and y1
|
||||
* properties represent the coordinates of the closest point on the
|
||||
* target geometry.
|
||||
*/
|
||||
distanceTo: function(point) {
|
||||
var distance = 0.0;
|
||||
if ( (this.x != null) && (this.y != null) &&
|
||||
(point != null) && (point.x != null) && (point.y != null) ) {
|
||||
|
||||
var dx2 = Math.pow(this.x - point.x, 2);
|
||||
var dy2 = Math.pow(this.y - point.y, 2);
|
||||
distance = Math.sqrt( dx2 + dy2 );
|
||||
distanceTo: function(geometry, options) {
|
||||
var edge = !(options && options.edge === false);
|
||||
var details = edge && options && options.details;
|
||||
var distance, x0, y0, x1, y1, result;
|
||||
if(geometry instanceof OpenLayers.Geometry.Point) {
|
||||
x0 = this.x;
|
||||
y0 = this.y;
|
||||
x1 = geometry.x;
|
||||
y1 = geometry.y;
|
||||
distance = Math.sqrt(Math.pow(x0 - x1, 2) + Math.pow(y0 - y1, 2));
|
||||
result = !details ?
|
||||
distance : {x0: x0, y0: y0, x1: x1, y1: y1, distance: distance};
|
||||
} else {
|
||||
result = geometry.distanceTo(this, options);
|
||||
if(details) {
|
||||
// switch coord order since this geom is target
|
||||
result = {
|
||||
x0: result.x1, y0: result.y1,
|
||||
x1: result.x0, y1: result.y0,
|
||||
distance: result.distance
|
||||
};
|
||||
}
|
||||
return distance;
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -156,6 +156,47 @@ OpenLayers.Geometry.Polygon = OpenLayers.Class(
|
||||
return intersect;
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: distanceTo
|
||||
* Calculate the closest distance between two geometries.
|
||||
*
|
||||
* Parameters:
|
||||
* geometry - {<OpenLayers.Geometry>} The target geometry.
|
||||
* options - {Object} Optional properties for configuring the distance
|
||||
* calculation.
|
||||
*
|
||||
* Valid options:
|
||||
* details - {Boolean} Return details from the distance calculation.
|
||||
* Default is false.
|
||||
* edge - {Boolean} Calculate the distance from this geometry to the
|
||||
* nearest edge of the target geometry. Default is true. If true,
|
||||
* calling distanceTo from a geometry that is wholly contained within
|
||||
* the target will result in a non-zero distance. If false, whenever
|
||||
* geometries intersect, calling distanceTo will return 0. If false,
|
||||
* details cannot be returned.
|
||||
*
|
||||
* Returns:
|
||||
* {Number | Object} The distance between this geometry and the target.
|
||||
* If details is true, the return will be an object with distance,
|
||||
* x0, y0, x1, and y1 properties. The x0 and y0 properties represent
|
||||
* the coordinates of the closest point on this geometry. The x1 and y1
|
||||
* properties represent the coordinates of the closest point on the
|
||||
* target geometry.
|
||||
*/
|
||||
distanceTo: function(geometry, options) {
|
||||
var edge = !(options && options.edge === false);
|
||||
var result;
|
||||
// this is the case where we might not be looking for distance to edge
|
||||
if(!edge && this.intersects(geometry)) {
|
||||
result = 0;
|
||||
} else {
|
||||
result = OpenLayers.Geometry.Collection.prototype.distanceTo.apply(
|
||||
this, [geometry, options]
|
||||
);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Geometry.Polygon"
|
||||
});
|
||||
|
||||
|
||||
@@ -252,6 +252,36 @@
|
||||
}
|
||||
}
|
||||
|
||||
function test_distanceToSegment(t) {
|
||||
var dist = OpenLayers.Geometry.distanceToSegment;
|
||||
|
||||
var cases = [{
|
||||
got: dist({x: 0, y: 0}, {x1: 0, y1: 1, x2: 1, y2: 1}),
|
||||
expected: {distance: 1, x: 0, y: 1}
|
||||
}, {
|
||||
got: dist({x: 0, y: 0}, {x1: -1, y1: -1, x2: 0, y2: -1}),
|
||||
expected: {distance: 1, x: 0, y: -1}
|
||||
}, {
|
||||
got: dist({x: 0, y: 0}, {x1: -1, y1: -1, x2: 1, y2: 1}),
|
||||
expected: {distance: 0, x: 0, y: 0}
|
||||
}, {
|
||||
got: dist({x: 1, y: 1}, {x1: 2, y1: 0, x2: 2, y2: 3}),
|
||||
expected: {distance: 1, x: 2, y: 1}
|
||||
}, {
|
||||
got: dist({x: -1, y: -1}, {x1: -2, y1: -2, x2: -1, y2: -3}),
|
||||
expected: {distance: Math.sqrt(2), x: -2, y: -2}
|
||||
}, {
|
||||
got: dist({x: -1, y: 1}, {x1: -3, y1: 1, x2: -1, y2: 3}),
|
||||
expected: {distance: Math.sqrt(2), x: -2, y: 2}
|
||||
}];
|
||||
|
||||
t.plan(cases.length);
|
||||
for(var i=0; i<cases.length; ++i) {
|
||||
t.eq(cases[i].got, cases[i].expected, "case " + i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function test_fromWKT(t) {
|
||||
|
||||
var cases = [{
|
||||
|
||||
@@ -148,6 +148,32 @@
|
||||
|
||||
}
|
||||
|
||||
function test_distanceTo(t) {
|
||||
var wkt = OpenLayers.Geometry.fromWKT;
|
||||
var geoms = [
|
||||
wkt("POINT(0 0)"),
|
||||
wkt("LINESTRING(-2 0, 0 -2, 2 -1, 2 0)")
|
||||
];
|
||||
|
||||
var cases = [{
|
||||
got: geoms[1].distanceTo(geoms[0]),
|
||||
expected: Math.sqrt(2)
|
||||
}, {
|
||||
got: geoms[1].distanceTo(geoms[0], {details: true}),
|
||||
expected: {
|
||||
distance: Math.sqrt(2),
|
||||
x0: -1, y0: -1,
|
||||
x1: 0, y1: 0
|
||||
}
|
||||
}];
|
||||
|
||||
t.plan(cases.length);
|
||||
for(var i=0; i<cases.length; ++i) {
|
||||
t.eq(cases[i].got, cases[i].expected, "case " + i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function test_LineString_equals(t) {
|
||||
t.plan(3);
|
||||
|
||||
|
||||
@@ -34,6 +34,60 @@
|
||||
t.eq(multipoint.components[0].y, y + dy, "move() correctly modifies y");
|
||||
}
|
||||
|
||||
function test_distanceTo(t) {
|
||||
var points = [
|
||||
new OpenLayers.Geometry.Point(0, 0),
|
||||
new OpenLayers.Geometry.Point(10, 0),
|
||||
new OpenLayers.Geometry.Point(0, 9),
|
||||
new OpenLayers.Geometry.Point(-5, 0),
|
||||
new OpenLayers.Geometry.Point(-5, 4)
|
||||
];
|
||||
|
||||
var geoms = [
|
||||
new OpenLayers.Geometry.MultiPoint([points[0], points[1]]),
|
||||
new OpenLayers.Geometry.MultiPoint([points[2], points[3]]),
|
||||
points[4]
|
||||
];
|
||||
|
||||
var cases = [{
|
||||
got: geoms[0].distanceTo(geoms[0]),
|
||||
expected: 0
|
||||
}, {
|
||||
got: geoms[0].distanceTo(geoms[1]),
|
||||
expected: 5
|
||||
}, {
|
||||
got: geoms[1].distanceTo(geoms[2]),
|
||||
expected: 4
|
||||
}, {
|
||||
got: geoms[0].distanceTo(geoms[1], {details: true}),
|
||||
expected: {
|
||||
distance: 5,
|
||||
x0: 0, y0: 0,
|
||||
x1: -5, y1: 0
|
||||
}
|
||||
}, {
|
||||
got: geoms[1].distanceTo(geoms[0], {details: true}),
|
||||
expected: {
|
||||
distance: 5,
|
||||
x0: -5, y0: 0,
|
||||
x1: 0, y1: 0
|
||||
}
|
||||
}, {
|
||||
got: geoms[1].distanceTo(geoms[2], {details: true}),
|
||||
expected: {
|
||||
distance: 4,
|
||||
x0: -5, y0: 0,
|
||||
x1: -5, y1: 4
|
||||
}
|
||||
}];
|
||||
|
||||
t.plan(cases.length);
|
||||
for(var i=0; i<cases.length; ++i) {
|
||||
t.eq(cases[i].got, cases[i].expected, "case " + i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function test_MultiPoint_equals(t) {
|
||||
t.plan(3);
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
}
|
||||
|
||||
function test_Point_distanceTo(t) {
|
||||
t.plan(2);
|
||||
t.plan(7);
|
||||
|
||||
var x1 = 10;
|
||||
var y1 = 20;
|
||||
@@ -65,6 +65,15 @@
|
||||
var dist = point1.distanceTo(point2)
|
||||
t.eq( dist, 201.24611797498107267682563018581, "distances calculating correctly");
|
||||
t.eq( dist, Math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)), "distance calculation correct");
|
||||
|
||||
// test that details are returned (though trivial in this case)
|
||||
var result = point1.distanceTo(point2, {details: true});
|
||||
t.eq(result.distance, point1.distanceTo(point2), "[details] distance property is same as return without details");
|
||||
t.eq(result.x0, x1, "[details] x0 property is correct");
|
||||
t.eq(result.y0, y1, "[details] y0 property is correct");
|
||||
t.eq(result.x1, x2, "[details] x1 property is correct");
|
||||
t.eq(result.y1, y2, "[details] y1 property is correct");
|
||||
|
||||
}
|
||||
|
||||
function test_Point_toString(t) {
|
||||
|
||||
@@ -258,6 +258,55 @@
|
||||
"equals() returns false for a geometry with offset y");
|
||||
}
|
||||
|
||||
function test_distanceTo(t) {
|
||||
var wkt = OpenLayers.Geometry.fromWKT;
|
||||
var geoms = [
|
||||
wkt("POLYGON((0 3, 1 4, 2 3, 1 2, 0 3))"),
|
||||
wkt("POINT(0 0)"),
|
||||
wkt("LINESTRING(-2 0, 0 -2, 2 -1, 2 0)"),
|
||||
wkt("LINESTRING(0 2, 1 3)"),
|
||||
wkt("POINT(1 3)")
|
||||
];
|
||||
|
||||
var cases = [{
|
||||
got: geoms[0].distanceTo(geoms[1]),
|
||||
expected: Math.sqrt(5)
|
||||
}, {
|
||||
got: geoms[0].distanceTo(geoms[1], {details: true}),
|
||||
expected: {
|
||||
distance: Math.sqrt(5),
|
||||
x0: 1, y0: 2,
|
||||
x1: 0, y1: 0
|
||||
}
|
||||
}, {
|
||||
got: geoms[0].distanceTo(geoms[2], {details: true}),
|
||||
expected: {
|
||||
distance: Math.sqrt(5),
|
||||
x0: 1, y0: 2,
|
||||
x1: 2, y1: 0
|
||||
}
|
||||
}, {
|
||||
got: geoms[0].distanceTo(geoms[3], {details: true}),
|
||||
expected: {
|
||||
distance: 0,
|
||||
x0: 0.5, y0: 2.5,
|
||||
x1: 0.5, y1: 2.5
|
||||
}
|
||||
}, {
|
||||
got: geoms[0].distanceTo(geoms[4]),
|
||||
expected: Math.sqrt(0.5)
|
||||
}, {
|
||||
got: geoms[0].distanceTo(geoms[4], {edge: false}),
|
||||
expected: 0
|
||||
}];
|
||||
|
||||
t.plan(cases.length);
|
||||
for(var i=0; i<cases.length; ++i) {
|
||||
t.eq(cases[i].got, cases[i].expected, "case " + i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function test_Polygon_clone(t) {
|
||||
t.plan(2);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user