cygnal/src/tools/geometry.spec.js

165 lines
7.8 KiB
JavaScript

var assert = require('assert');
var geometry = require('./geometry');
describe('Geometry tools', function() {
describe('isInRing', function () {
var ring = [[0, 0], [0, 1], [1, 1], [0.5, 0.5], [1, 0], [0, 0]];
it('should return true for a point in the ring', function () {
assert(geometry.isInRing([0, 0], ring, false) === true);
assert(geometry.isInRing([0.25, 0.25], ring, false)) === true;
assert(geometry.isInRing([0.25, 0.25], ring, true) === true);
});
it('should return false for a point outside of the ring', function () {
assert(geometry.isInRing([0, 0], ring, true) === false);
assert(geometry.isInRing([0.8, 0.6], ring, true) === false);
assert(geometry.isInRing([0.8, 0.6], ring, false) === false);
assert(geometry.isInRing([2, 2], ring, false) === false);
assert(geometry.isInRing([2, 2], ring, true) === false);
})
});
describe('isInBBox', function () {
it('should return true for a point inside the bbox', function () {
assert(geometry.isInBBox([0.5, 0.5], [0, 0, 1, 1]) == true);
assert(geometry.isInBBox([0, 1], [0, 0, 1, 1]) === true);
assert(geometry.isInBBox([1, 0], [0, 0, 1, 1]) === true);
});
it('should return false for a point outside of the bbox', function () {
assert(geometry.isInBBox([2, 0], [0, 0, 1, 1]) === false);
assert(geometry.isInBBox([0, 2], [0, 0, 1, 1]) === false);
});
});
describe('computeBBox', function () {
it('should return correct BBox', function () {
assert.deepEqual(geometry.computeBBox([[0, 0], [1, 0], [1, 1], [0, 1]]), [0, 0, 1, 1]);
});
});
describe('isWithinPolygon', function () {
var ring = [[0, 0], [0, 1], [1, 1], [0.5, 0.5], [1, 0], [0, 0]];
it('should return true for points inside the polygon', function () {
assert(geometry.isWithinPolygon([0, 0], ring, false) === true);
assert(geometry.isWithinPolygon([0.25, 0.25], ring, false) === true);
assert(geometry.isWithinPolygon([0.25, 0.25], ring, true) === true);
});
it('should return false for points outside the polygon', function () {
assert(geometry.isWithinPolygon([0, 0], ring, true) === false);
assert(geometry.isWithinPolygon([0.8, 0.6], ring, true) === false);
assert(geometry.isWithinPolygon([0.8, 0.6], ring, false) === false);
assert(geometry.isWithinPolygon([2, 2], ring, false) === false);
assert(geometry.isWithinPolygon([2, 2], ring, true) === false);
});
});
describe('pointToPointDistance', function () {
it('should return results close to Vincenty\'s formula', function () {
assert(
(Math.abs(
geometry.pointToPointDistance([48.8171, 2.3186], [48.8454, 2.3746])
- 5177.692 // Vincenty's formula result
) / 5177.692)
< 1 / 100
);
assert(
(Math.abs(
geometry.pointToPointDistance([50.6314, 3.0027], [50.6271, 3.1116])
- 7720.121 // Vincenty's formula result
) / 7720.121)
< 1 / 100
);
assert(
(Math.abs(
geometry.pointToPointDistance([42.6722, 2.8508], [42.7093, 2.9679])
- 10443.762 // Vincenty's formula result
) / 10443.762)
< 1 / 100
);
});
});
describe('dot', function () {
it('should return the correct dot product', function () {
assert(Math.abs(geometry.dot([1, 0], [0, 0]) - 0) < Number.EPSILON);
assert(Math.abs(geometry.dot([1, 0], [1, 0]) - 1) < Number.EPSILON);
assert(Math.abs(geometry.dot([1, 1], [1, 2]) - 3) < Number.EPSILON);
})
});
describe('pointToLineDistance', function () {
var polyLine = [[48.8105, 2.3088], [48.8098, 2.3218]];
it('should return the correct distance for a point at the end', function () {
assert(Math.abs(geometry.pointToLineDistance([48.8105, 2.3088], polyLine) - 0) < Number.EPSILON);
assert(Math.abs(geometry.pointToLineDistance([48.8098, 2.3218], polyLine) - 0) < Number.EPSILON);
});
it('should return the correct distance for any point', function () {
assert(Math.abs(geometry.pointToLineDistance([48.8170, 2.3188], polyLine) - 780) / 780 < 1 / 100);
assert(Math.abs(geometry.pointToLineDistance([48.8121, 2.3074], polyLine) - 205) / 205 < 1 / 100);
assert(Math.abs(geometry.pointToLineDistance([48.8089, 2.3315], polyLine) - 720) / 720 < 5 / 100);
});
it('should return the correct distance for longer lines', function () {
assert(
Math.abs(
geometry.pointToLineDistance(
[48.8098, 2.3218],
[[48.8105, 2.3088], [48.8098, 2.3218], [48.8089, 2.3315]]
) - 0
) < Number.EPSILON
);
assert(
(Math.abs(
geometry.pointToLineDistance(
[48.82787, 2.32686],
[[48.809982, 2.3190774], [48.8176872, 2.3320935], [48.8182127, 2.3323712], [48.8222148, 2.3143633], [48.8222632, 2.314133], [48.8115136, 2.3002323], [48.8113242, 2.3000166], [48.809982, 2.3190774]]
) - 900
) / 900)
< 1 / 100);
});
});
describe('pointToPolygonDistance', function () {
var polygon = [[48.809982, 2.3190774], [48.8176872, 2.3320935], [48.8182127, 2.3323712], [48.8222148, 2.3143633], [48.8222632, 2.314133], [48.8115136, 2.3002323], [48.8113242, 2.3000166], [48.809982, 2.3190774]];
it('should return correct distance for a point on the ring', function () {
assert(Math.abs(geometry.pointToPolygonDistance([48.809982, 2.3190774], polygon) - 0) < Number.EPSILON);
});
it('should return correct distance for a point in the inside', function () {
assert(Math.abs(geometry.pointToPolygonDistance([48.8161, 2.3169], polygon) - 0) < Number.EPSILON);
});
it('should return correct distance for a point outside', function () {
assert(Math.abs(geometry.pointToPolygonDistance([48.82787, 2.32686], polygon) - 900) / 900 < 1 / 100);
});
});
describe('pointToGeometryDistance', function () {
it('should return correct distance for a point', function () {
var point = { type: 'Point', coordinates: [2.3746, 48.8454] };
assert(Math.abs(geometry.pointToGeometryDistance([48.8171, 2.3186], point) - 5177.692) / 5177.692 < 1 / 100);
});
it('should return correct distance for a line', function () {
var lineString = { type: 'LineString', coordinates: [[2.3088, 48.8105], [2.3218, 48.8098]] };
assert(Math.abs(geometry.pointToGeometryDistance([48.8170, 2.3188], lineString) - 780) / 780 < 1 / 100);
});
it('should return correct distance for a polygon', function () {
var polygon = { type: 'Polygon', coordinates: [[[2.3190774, 48.809982], [2.3320935, 48.8176872], [2.3323712, 48.8182127], [2.3143633, 48.8222148], [2.314133, 48.8222632], [2.3002323, 48.8115136], [2.3000166, 48.8113242], [2.3190774, 48.809982]]] };
assert(Math.abs(geometry.pointToGeometryDistance([48.82787, 2.32686], polygon) - 900) / 900 < 1 / 100);
});
it('should return null for an unknown geometry', function () {
var unknownGeometry = { type: 'Foobar', coordinates: [48.8454, 2.3746] };
assert(geometry.pointToGeometryDistance([48.82787, 2.32686], unknownGeometry) === null);
});
});
});