Factor out ol.geom.flat.orient

This commit is contained in:
Tom Payne
2014-03-12 12:27:12 +01:00
parent becd1318bd
commit 1363ce3a58
6 changed files with 150 additions and 135 deletions

View File

@@ -0,0 +1,115 @@
goog.provide('ol.geom.flat.orient');
goog.require('ol.geom.flat');
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {number} end End.
* @param {number} stride Stride.
* @return {boolean} Is clockwise.
*/
ol.geom.flat.orient.linearRingIsClockwise =
function(flatCoordinates, offset, end, stride) {
// http://tinyurl.com/clockwise-method
// https://github.com/OSGeo/gdal/blob/trunk/gdal/ogr/ogrlinearring.cpp
var edge = 0;
var x1 = flatCoordinates[end - stride];
var y1 = flatCoordinates[end - stride + 1];
for (; offset < end; offset += stride) {
var x2 = flatCoordinates[offset];
var y2 = flatCoordinates[offset + 1];
edge += (x2 - x1) * (y2 + y1);
x1 = x2;
y1 = y2;
}
return edge > 0;
};
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {Array.<number>} ends Ends.
* @param {number} stride Stride.
* @return {boolean} `true` if all rings are correctly oriented, `false`
* otherwise.
*/
ol.geom.flat.orient.linearRingsAreOriented =
function(flatCoordinates, offset, ends, stride) {
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;
}
offset = end;
}
return true;
};
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {Array.<Array.<number>>} endss Endss.
* @param {number} stride Stride.
* @return {boolean} `true` if all rings are correctly oriented, `false`
* otherwise.
*/
ol.geom.flat.linearRingssAreOriented =
function(flatCoordinates, offset, endss, stride) {
var i, ii;
for (i = 0, ii = endss.length; i < ii; ++i) {
if (!ol.geom.flat.orient.linearRingsAreOriented(
flatCoordinates, offset, endss[i], stride)) {
return false;
}
}
return true;
};
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {Array.<number>} ends Ends.
* @param {number} stride Stride.
* @return {number} End.
*/
ol.geom.flat.orient.orientLinearRings =
function(flatCoordinates, offset, ends, stride) {
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;
if (reverse) {
ol.geom.flat.reverseCoordinates(flatCoordinates, offset, end, stride);
}
offset = end;
}
return offset;
};
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {Array.<Array.<number>>} endss Endss.
* @param {number} stride Stride.
* @return {number} End.
*/
ol.geom.flat.orient.orientLinearRingss =
function(flatCoordinates, offset, endss, stride) {
var i, ii;
for (i = 0, ii = endss.length; i < ii; ++i) {
offset = ol.geom.flat.orient.orientLinearRings(
flatCoordinates, offset, endss[i], stride);
}
return offset;
};

View File

@@ -228,31 +228,6 @@ ol.geom.flat.linearRingContainsXY =
};
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {number} end End.
* @param {number} stride Stride.
* @return {boolean} Is clockwise.
*/
ol.geom.flat.linearRingIsClockwise =
function(flatCoordinates, offset, end, stride) {
// http://tinyurl.com/clockwise-method
// https://github.com/OSGeo/gdal/blob/trunk/gdal/ogr/ogrlinearring.cpp
var edge = 0;
var x1 = flatCoordinates[end - stride];
var y1 = flatCoordinates[end - stride + 1];
for (; offset < end; offset += stride) {
var x2 = flatCoordinates[offset];
var y2 = flatCoordinates[offset + 1];
edge += (x2 - x1) * (y2 + y1);
x1 = x2;
y1 = y2;
}
return edge > 0;
};
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
@@ -348,51 +323,6 @@ ol.geom.flat.linearRingsGetInteriorPoint = function(flatCoordinates, offset,
};
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {Array.<number>} ends Ends.
* @param {number} stride Stride.
* @return {boolean} `true` if all rings are correctly oriented, `false`
* otherwise.
*/
ol.geom.flat.linearRingsAreOriented =
function(flatCoordinates, offset, ends, stride) {
var i, ii;
for (i = 0, ii = ends.length; i < ii; ++i) {
var end = ends[i];
var isClockwise = ol.geom.flat.linearRingIsClockwise(
flatCoordinates, offset, end, stride);
if (i === 0 ? !isClockwise : isClockwise) {
return false;
}
offset = end;
}
return true;
};
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {Array.<Array.<number>>} endss Endss.
* @param {number} stride Stride.
* @return {boolean} `true` if all rings are correctly oriented, `false`
* otherwise.
*/
ol.geom.flat.linearRingssAreOriented =
function(flatCoordinates, offset, endss, stride) {
var i, ii;
for (i = 0, ii = endss.length; i < ii; ++i) {
if (!ol.geom.flat.linearRingsAreOriented(
flatCoordinates, offset, endss[i], stride)) {
return false;
}
}
return true;
};
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
@@ -467,48 +397,6 @@ ol.geom.flat.linearRingssGetFlatCenters =
};
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {Array.<number>} ends Ends.
* @param {number} stride Stride.
* @return {number} End.
*/
ol.geom.flat.orientLinearRings =
function(flatCoordinates, offset, ends, stride) {
var i, ii;
for (i = 0, ii = ends.length; i < ii; ++i) {
var end = ends[i];
var isClockwise = ol.geom.flat.linearRingIsClockwise(
flatCoordinates, offset, end, stride);
var reverse = i === 0 ? !isClockwise : isClockwise;
if (reverse) {
ol.geom.flat.reverseCoordinates(flatCoordinates, offset, end, stride);
}
offset = end;
}
return offset;
};
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {Array.<Array.<number>>} endss Endss.
* @param {number} stride Stride.
* @return {number} End.
*/
ol.geom.flat.orientLinearRingss =
function(flatCoordinates, offset, endss, stride) {
var i, ii;
for (i = 0, ii = endss.length; i < ii; ++i) {
offset = ol.geom.flat.orientLinearRings(
flatCoordinates, offset, endss[i], stride);
}
return offset;
};
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.

View File

@@ -10,6 +10,7 @@ goog.require('ol.geom.SimpleGeometry');
goog.require('ol.geom.flat');
goog.require('ol.geom.flat.area');
goog.require('ol.geom.flat.closest');
goog.require('ol.geom.flat.orient');
goog.require('ol.geom.flat.simplify');
@@ -204,8 +205,9 @@ ol.geom.MultiPolygon.prototype.getOrientedFlatCoordinates = function() {
this.orientedFlatCoordinates_ = flatCoordinates;
} else {
this.orientedFlatCoordinates_ = flatCoordinates.slice();
this.orientedFlatCoordinates_.length = ol.geom.flat.orientLinearRingss(
this.orientedFlatCoordinates_, 0, this.endss_, this.stride);
this.orientedFlatCoordinates_.length =
ol.geom.flat.orient.orientLinearRingss(
this.orientedFlatCoordinates_, 0, this.endss_, this.stride);
}
this.orientedRevision_ = this.getRevision();
}

View File

@@ -10,6 +10,7 @@ goog.require('ol.geom.SimpleGeometry');
goog.require('ol.geom.flat');
goog.require('ol.geom.flat.area');
goog.require('ol.geom.flat.closest');
goog.require('ol.geom.flat.orient');
goog.require('ol.geom.flat.simplify');
@@ -223,13 +224,14 @@ ol.geom.Polygon.prototype.getLinearRings = function() {
ol.geom.Polygon.prototype.getOrientedFlatCoordinates = function() {
if (this.orientedRevision_ != this.getRevision()) {
var flatCoordinates = this.flatCoordinates;
if (ol.geom.flat.linearRingsAreOriented(
if (ol.geom.flat.orient.linearRingsAreOriented(
flatCoordinates, 0, this.ends_, this.stride)) {
this.orientedFlatCoordinates_ = flatCoordinates;
} else {
this.orientedFlatCoordinates_ = flatCoordinates.slice();
this.orientedFlatCoordinates_.length = ol.geom.flat.orientLinearRings(
this.orientedFlatCoordinates_, 0, this.ends_, this.stride);
this.orientedFlatCoordinates_.length =
ol.geom.flat.orient.orientLinearRings(
this.orientedFlatCoordinates_, 0, this.ends_, this.stride);
}
this.orientedRevision_ = this.getRevision();
}

View File

@@ -0,0 +1,26 @@
goog.provide('ol.test.geom.flat.orient');
describe('ol.geom.flat.orient', function() {
describe('ol.geom.flat.orient.linearRingIsClockwise', function() {
it('identifies clockwise rings', function() {
var flatCoordinates = [0, 1, 1, 4, 4, 3, 3, 0];
var isClockwise = ol.geom.flat.orient.linearRingIsClockwise(
flatCoordinates, 0, flatCoordinates.length, 2);
expect(isClockwise).to.be(true);
});
it('identifies anti-clockwise rings', function() {
var flatCoordinates = [2, 2, 3, 2, 3, 3, 2, 3];
var isClockwise = ol.geom.flat.orient.linearRingIsClockwise(
flatCoordinates, 0, flatCoordinates.length, 2);
expect(isClockwise).to.be(false);
});
});
});
goog.require('ol.geom.flat');
goog.require('ol.geom.flat.orient');

View File

@@ -85,24 +85,6 @@ describe('ol.geom.flat', function() {
});
describe('ol.geom.flat.linearRingIsClockwise', function() {
it('identifies clockwise rings', function() {
var flatCoordinates = [0, 1, 1, 4, 4, 3, 3, 0];
var isClockwise = ol.geom.flat.linearRingIsClockwise(
flatCoordinates, 0, flatCoordinates.length, 2);
expect(isClockwise).to.be(true);
});
it('identifies anti-clockwise rings', function() {
var flatCoordinates = [2, 2, 3, 2, 3, 3, 2, 3];
var isClockwise = ol.geom.flat.linearRingIsClockwise(
flatCoordinates, 0, flatCoordinates.length, 2);
expect(isClockwise).to.be(false);
});
});
describe('ol.geom.flat.reverseCoordinates', function() {
describe('with a stride of 2', function() {