diff --git a/src/ol/geom/flat/orientflatgeom.js b/src/ol/geom/flat/orientflatgeom.js new file mode 100644 index 0000000000..06fc092e2c --- /dev/null +++ b/src/ol/geom/flat/orientflatgeom.js @@ -0,0 +1,115 @@ +goog.provide('ol.geom.flat.orient'); + +goog.require('ol.geom.flat'); + + +/** + * @param {Array.} 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.} flatCoordinates Flat coordinates. + * @param {number} offset Offset. + * @param {Array.} 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.} flatCoordinates Flat coordinates. + * @param {number} offset Offset. + * @param {Array.>} 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.} flatCoordinates Flat coordinates. + * @param {number} offset Offset. + * @param {Array.} 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.} flatCoordinates Flat coordinates. + * @param {number} offset Offset. + * @param {Array.>} 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; +}; diff --git a/src/ol/geom/flatgeom.js b/src/ol/geom/flatgeom.js index 4e69680230..917f4b6b3d 100644 --- a/src/ol/geom/flatgeom.js +++ b/src/ol/geom/flatgeom.js @@ -228,31 +228,6 @@ ol.geom.flat.linearRingContainsXY = }; -/** - * @param {Array.} 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.} flatCoordinates Flat coordinates. * @param {number} offset Offset. @@ -348,51 +323,6 @@ ol.geom.flat.linearRingsGetInteriorPoint = function(flatCoordinates, offset, }; -/** - * @param {Array.} flatCoordinates Flat coordinates. - * @param {number} offset Offset. - * @param {Array.} 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.} flatCoordinates Flat coordinates. - * @param {number} offset Offset. - * @param {Array.>} 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.} flatCoordinates Flat coordinates. * @param {number} offset Offset. @@ -467,48 +397,6 @@ ol.geom.flat.linearRingssGetFlatCenters = }; -/** - * @param {Array.} flatCoordinates Flat coordinates. - * @param {number} offset Offset. - * @param {Array.} 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.} flatCoordinates Flat coordinates. - * @param {number} offset Offset. - * @param {Array.>} 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.} flatCoordinates Flat coordinates. * @param {number} offset Offset. diff --git a/src/ol/geom/multipolygon.js b/src/ol/geom/multipolygon.js index d37817582e..7000aef599 100644 --- a/src/ol/geom/multipolygon.js +++ b/src/ol/geom/multipolygon.js @@ -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(); } diff --git a/src/ol/geom/polygon.js b/src/ol/geom/polygon.js index 85c9e24cec..5966f850bb 100644 --- a/src/ol/geom/polygon.js +++ b/src/ol/geom/polygon.js @@ -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(); } diff --git a/test/spec/ol/geom/flat/orientflatgeom.test.js b/test/spec/ol/geom/flat/orientflatgeom.test.js new file mode 100644 index 0000000000..010d25d33b --- /dev/null +++ b/test/spec/ol/geom/flat/orientflatgeom.test.js @@ -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'); diff --git a/test/spec/ol/geom/flatgeom.test.js b/test/spec/ol/geom/flatgeom.test.js index 1ffa7ed5bc..41f4a7f9cd 100644 --- a/test/spec/ol/geom/flatgeom.test.js +++ b/test/spec/ol/geom/flatgeom.test.js @@ -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() {