Allow orienting with the right-hand rule
This commit is contained in:
@@ -29,22 +29,34 @@ ol.geom.flat.orient.linearRingIsClockwise =
|
||||
|
||||
|
||||
/**
|
||||
* Determines if linear rings are oriented. By default, left-hand orientation
|
||||
* is tested (first ring must be clockwise, remaining rings counter-clockwise).
|
||||
* To test for right-hand orientation, use the `opt_right` argument.
|
||||
*
|
||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||
* @param {number} offset Offset.
|
||||
* @param {Array.<number>} ends Ends.
|
||||
* @param {Array.<number>} ends Array of end indexes.
|
||||
* @param {number} stride Stride.
|
||||
* @return {boolean} `true` if all rings are correctly oriented, `false`
|
||||
* otherwise.
|
||||
* @param {boolean=} opt_right Test for right-hand orientation
|
||||
* (counter-clockwise exterior ring and clockwise interior rings).
|
||||
* @return {boolean} Rings are correctly oriented.
|
||||
*/
|
||||
ol.geom.flat.orient.linearRingsAreOriented =
|
||||
function(flatCoordinates, offset, ends, stride) {
|
||||
function(flatCoordinates, offset, ends, stride, opt_right) {
|
||||
var right = goog.isDef(opt_right) ? opt_right : false;
|
||||
var i, ii;
|
||||
for (i = 0, ii = ends.length; i < ii; ++i) {
|
||||
var end = ends[i];
|
||||
var isClockwise = ol.geom.flat.orient.linearRingIsClockwise(
|
||||
flatCoordinates, offset, end, stride);
|
||||
if (i === 0 ? !isClockwise : isClockwise) {
|
||||
return false;
|
||||
if (i === 0) {
|
||||
if ((right && isClockwise) || (!right && !isClockwise)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if ((right && !isClockwise) || (!right && isClockwise)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
offset = end;
|
||||
}
|
||||
@@ -53,19 +65,24 @@ ol.geom.flat.orient.linearRingsAreOriented =
|
||||
|
||||
|
||||
/**
|
||||
* Determines if linear rings are oriented. By default, left-hand orientation
|
||||
* is tested (first ring must be clockwise, remaining rings counter-clockwise).
|
||||
* To test for right-hand orientation, use the `opt_right` argument.
|
||||
*
|
||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||
* @param {number} offset Offset.
|
||||
* @param {Array.<Array.<number>>} endss Endss.
|
||||
* @param {Array.<Array.<number>>} endss Array of array of end indexes.
|
||||
* @param {number} stride Stride.
|
||||
* @return {boolean} `true` if all rings are correctly oriented, `false`
|
||||
* otherwise.
|
||||
* @param {boolean=} opt_right Test for right-hand orientation
|
||||
* (counter-clockwise exterior ring and clockwise interior rings).
|
||||
* @return {boolean} Rings are correctly oriented.
|
||||
*/
|
||||
ol.geom.flat.orient.linearRingssAreOriented =
|
||||
function(flatCoordinates, offset, endss, stride) {
|
||||
function(flatCoordinates, offset, endss, stride, opt_right) {
|
||||
var i, ii;
|
||||
for (i = 0, ii = endss.length; i < ii; ++i) {
|
||||
if (!ol.geom.flat.orient.linearRingsAreOriented(
|
||||
flatCoordinates, offset, endss[i], stride)) {
|
||||
flatCoordinates, offset, endss[i], stride, opt_right)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -74,20 +91,29 @@ ol.geom.flat.orient.linearRingssAreOriented =
|
||||
|
||||
|
||||
/**
|
||||
* Orient coordinates in a flat array of linear rings. By default, rings
|
||||
* are oriented following the left-hand rule (clockwise for exterior and
|
||||
* counter-clockwise for interior rings). To orient according to the
|
||||
* right-hand rule, use the `opt_right` argument.
|
||||
*
|
||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||
* @param {number} offset Offset.
|
||||
* @param {Array.<number>} ends Ends.
|
||||
* @param {number} stride Stride.
|
||||
* @param {boolean=} opt_right Follow the right-hand rule for orientation.
|
||||
* @return {number} End.
|
||||
*/
|
||||
ol.geom.flat.orient.orientLinearRings =
|
||||
function(flatCoordinates, offset, ends, stride) {
|
||||
function(flatCoordinates, offset, ends, stride, opt_right) {
|
||||
var right = goog.isDef(opt_right) ? opt_right : false;
|
||||
var i, ii;
|
||||
for (i = 0, ii = ends.length; i < ii; ++i) {
|
||||
var end = ends[i];
|
||||
var isClockwise = ol.geom.flat.orient.linearRingIsClockwise(
|
||||
flatCoordinates, offset, end, stride);
|
||||
var reverse = i === 0 ? !isClockwise : isClockwise;
|
||||
var reverse = i === 0 ?
|
||||
(right && isClockwise) || (!right && !isClockwise) :
|
||||
(right && !isClockwise) || (!right && isClockwise);
|
||||
if (reverse) {
|
||||
ol.geom.flat.reverse.coordinates(flatCoordinates, offset, end, stride);
|
||||
}
|
||||
@@ -98,18 +124,24 @@ ol.geom.flat.orient.orientLinearRings =
|
||||
|
||||
|
||||
/**
|
||||
* Orient coordinates in a flat array of linear rings. By default, rings
|
||||
* are oriented following the left-hand rule (clockwise for exterior and
|
||||
* counter-clockwise for interior rings). To orient according to the
|
||||
* right-hand rule, use the `opt_right` argument.
|
||||
*
|
||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||
* @param {number} offset Offset.
|
||||
* @param {Array.<Array.<number>>} endss Endss.
|
||||
* @param {Array.<Array.<number>>} endss Array of array of end indexes.
|
||||
* @param {number} stride Stride.
|
||||
* @param {boolean=} opt_right Follow the right-hand rule for orientation.
|
||||
* @return {number} End.
|
||||
*/
|
||||
ol.geom.flat.orient.orientLinearRingss =
|
||||
function(flatCoordinates, offset, endss, stride) {
|
||||
function(flatCoordinates, offset, endss, stride, opt_right) {
|
||||
var i, ii;
|
||||
for (i = 0, ii = endss.length; i < ii; ++i) {
|
||||
offset = ol.geom.flat.orient.orientLinearRings(
|
||||
flatCoordinates, offset, endss[i], stride);
|
||||
flatCoordinates, offset, endss[i], stride, opt_right);
|
||||
}
|
||||
return offset;
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ goog.provide('ol.test.geom.flat.orient');
|
||||
|
||||
describe('ol.geom.flat.orient', function() {
|
||||
|
||||
describe('ol.geom.flat.orient.linearRingIsClockwise', function() {
|
||||
describe('ol.geom.flat.orient.linearRingIsClockwise()', function() {
|
||||
|
||||
it('identifies clockwise rings', function() {
|
||||
var flatCoordinates = [0, 1, 1, 4, 4, 3, 3, 0];
|
||||
@@ -20,6 +20,143 @@ describe('ol.geom.flat.orient', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('ol.geom.flat.orient.linearRingsAreOriented()', function() {
|
||||
var oriented = ol.geom.flat.orient.linearRingsAreOriented;
|
||||
|
||||
var rightCoords = [
|
||||
-180, -90, 180, -90, 180, 90, -180, 90, -180, -90,
|
||||
-100, -45, -100, 45, 100, 45, 100, -45, -100, -45
|
||||
];
|
||||
|
||||
var leftCoords = [
|
||||
-180, -90, -180, 90, 180, 90, 180, -90, -180, -90,
|
||||
-100, -45, 100, -45, 100, 45, -100, 45, -100, -45
|
||||
];
|
||||
|
||||
var ends = [10, 20];
|
||||
|
||||
it('checks for left-hand orientation by default', function() {
|
||||
expect(oriented(rightCoords, 0, ends, 2)).to.be(false);
|
||||
expect(oriented(leftCoords, 0, ends, 2)).to.be(true);
|
||||
});
|
||||
|
||||
it('can check for right-hand orientation', function() {
|
||||
expect(oriented(rightCoords, 0, ends, 2, true)).to.be(true);
|
||||
expect(oriented(leftCoords, 0, ends, 2, true)).to.be(false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('ol.geom.flat.orient.linearRingssAreOriented()', function() {
|
||||
var oriented = ol.geom.flat.orient.linearRingssAreOriented;
|
||||
|
||||
var rightCoords = [
|
||||
-180, -90, 180, -90, 180, 90, -180, 90, -180, -90,
|
||||
-100, -45, -100, 45, 100, 45, 100, -45, -100, -45,
|
||||
-180, -90, 180, -90, 180, 90, -180, 90, -180, -90,
|
||||
-100, -45, -100, 45, 100, 45, 100, -45, -100, -45
|
||||
];
|
||||
|
||||
var leftCoords = [
|
||||
-180, -90, -180, 90, 180, 90, 180, -90, -180, -90,
|
||||
-100, -45, 100, -45, 100, 45, -100, 45, -100, -45,
|
||||
-180, -90, -180, 90, 180, 90, 180, -90, -180, -90,
|
||||
-100, -45, 100, -45, 100, 45, -100, 45, -100, -45
|
||||
];
|
||||
|
||||
var ends = [[10, 20], [30, 40]];
|
||||
|
||||
it('checks for left-hand orientation by default', function() {
|
||||
expect(oriented(rightCoords, 0, ends, 2)).to.be(false);
|
||||
expect(oriented(leftCoords, 0, ends, 2)).to.be(true);
|
||||
});
|
||||
|
||||
it('can check for right-hand orientation', function() {
|
||||
expect(oriented(rightCoords, 0, ends, 2, true)).to.be(true);
|
||||
expect(oriented(leftCoords, 0, ends, 2, true)).to.be(false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('ol.geom.flat.orient.orientLinearRings()', function() {
|
||||
var orient = ol.geom.flat.orient.orientLinearRings;
|
||||
|
||||
var rightCoords = [
|
||||
-180, -90, 180, -90, 180, 90, -180, 90, -180, -90,
|
||||
-100, -45, -100, 45, 100, 45, 100, -45, -100, -45
|
||||
];
|
||||
|
||||
var leftCoords = [
|
||||
-180, -90, -180, 90, 180, 90, 180, -90, -180, -90,
|
||||
-100, -45, 100, -45, 100, 45, -100, 45, -100, -45
|
||||
];
|
||||
|
||||
var ends = [10, 20];
|
||||
|
||||
it('orients using the left-hand rule by default', function() {
|
||||
var rightClone = rightCoords.slice();
|
||||
orient(rightClone, 0, ends, 2);
|
||||
expect(rightClone).to.eql(leftCoords);
|
||||
|
||||
var leftClone = leftCoords.slice();
|
||||
orient(leftClone, 0, ends, 2);
|
||||
expect(leftClone).to.eql(leftCoords);
|
||||
});
|
||||
|
||||
it('can orient using the right-hand rule', function() {
|
||||
var rightClone = rightCoords.slice();
|
||||
orient(rightClone, 0, ends, 2, true);
|
||||
expect(rightClone).to.eql(rightCoords);
|
||||
|
||||
var leftClone = leftCoords.slice();
|
||||
orient(leftClone, 0, ends, 2, true);
|
||||
expect(leftClone).to.eql(rightCoords);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('ol.geom.flat.orient.orientLinearRingss()', function() {
|
||||
var orient = ol.geom.flat.orient.orientLinearRingss;
|
||||
|
||||
var rightCoords = [
|
||||
-180, -90, 180, -90, 180, 90, -180, 90, -180, -90,
|
||||
-100, -45, -100, 45, 100, 45, 100, -45, -100, -45,
|
||||
-180, -90, 180, -90, 180, 90, -180, 90, -180, -90,
|
||||
-100, -45, -100, 45, 100, 45, 100, -45, -100, -45
|
||||
];
|
||||
|
||||
var leftCoords = [
|
||||
-180, -90, -180, 90, 180, 90, 180, -90, -180, -90,
|
||||
-100, -45, 100, -45, 100, 45, -100, 45, -100, -45,
|
||||
-180, -90, -180, 90, 180, 90, 180, -90, -180, -90,
|
||||
-100, -45, 100, -45, 100, 45, -100, 45, -100, -45
|
||||
];
|
||||
|
||||
var ends = [[10, 20], [30, 40]];
|
||||
|
||||
it('orients using the left-hand rule by default', function() {
|
||||
var rightClone = rightCoords.slice();
|
||||
orient(rightClone, 0, ends, 2);
|
||||
expect(rightClone).to.eql(leftCoords);
|
||||
|
||||
var leftClone = leftCoords.slice();
|
||||
orient(leftClone, 0, ends, 2);
|
||||
expect(leftClone).to.eql(leftCoords);
|
||||
});
|
||||
|
||||
it('can orient using the right-hand rule', function() {
|
||||
var rightClone = rightCoords.slice();
|
||||
orient(rightClone, 0, ends, 2, true);
|
||||
expect(rightClone).to.eql(rightCoords);
|
||||
|
||||
var leftClone = leftCoords.slice();
|
||||
orient(leftClone, 0, ends, 2, true);
|
||||
expect(leftClone).to.eql(rightCoords);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.geom.flat.orient');
|
||||
|
||||
Reference in New Issue
Block a user