From 5b5865d48e42119a06edfc0909b1da814fb8d116 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 21 Jan 2014 07:48:13 +0100 Subject: [PATCH] Add ol.geom.Polygon#getOrientedFlatCoordinates --- src/ol/geom/polygon.js | 32 +++++++++++ test/spec/ol/geom/polygon.test.js | 94 +++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) diff --git a/src/ol/geom/polygon.js b/src/ol/geom/polygon.js index 0da2285d5e..937079bf02 100644 --- a/src/ol/geom/polygon.js +++ b/src/ol/geom/polygon.js @@ -50,6 +50,18 @@ ol.geom.Polygon = function(coordinates, opt_layout) { */ this.maxDeltaRevision_ = -1; + /** + * @private + * @type {number} + */ + this.orientedRevision_ = -1; + + /** + * @private + * @type {Array.} + */ + this.orientedFlatCoordinates_ = null; + this.setCoordinates(coordinates, opt_layout); }; @@ -151,6 +163,26 @@ ol.geom.Polygon.prototype.getLinearRings = function() { }; +/** + * @return {Array.} Oriented flat coordinates. + */ +ol.geom.Polygon.prototype.getOrientedFlatCoordinates = function() { + if (this.orientedRevision_ != this.getRevision()) { + var flatCoordinates = this.flatCoordinates; + if (ol.geom.flat.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.orientedRevision_ = this.getRevision(); + } + return this.orientedFlatCoordinates_; +}; + + /** * @inheritDoc */ diff --git a/test/spec/ol/geom/polygon.test.js b/test/spec/ol/geom/polygon.test.js index a35f473816..96c36b20cc 100644 --- a/test/spec/ol/geom/polygon.test.js +++ b/test/spec/ol/geom/polygon.test.js @@ -94,6 +94,29 @@ describe('ol.geom.Polygon', function() { expect(polygon.containsCoordinate(insideInner)).to.be(false); }); + describe('#getOrientedFlatCoordinates', function() { + + it('reverses the outer ring if necessary', function() { + outerRing.reverse(); + polygon = new ol.geom.Polygon([outerRing, innerRing]); + expect(polygon.getOrientedFlatCoordinates()).to.eql(flatCoordinates); + }); + + it('reverses inner rings if necessary', function() { + innerRing.reverse(); + polygon = new ol.geom.Polygon([outerRing, innerRing]); + expect(polygon.getOrientedFlatCoordinates()).to.eql(flatCoordinates); + }); + + it('reverses all rings if necessary', function() { + outerRing.reverse(); + innerRing.reverse(); + polygon = new ol.geom.Polygon([outerRing, innerRing]); + expect(polygon.getOrientedFlatCoordinates()).to.eql(flatCoordinates); + }); + + }); + }); describe('construct with 3D coordinates', function() { @@ -142,6 +165,29 @@ describe('ol.geom.Polygon', function() { expect(polygon.containsCoordinate(insideInner)).to.be(false); }); + describe('#getOrientedFlatCoordinates', function() { + + it('reverses the outer ring if necessary', function() { + outerRing.reverse(); + polygon = new ol.geom.Polygon([outerRing, innerRing]); + expect(polygon.getOrientedFlatCoordinates()).to.eql(flatCoordinates); + }); + + it('reverses inner rings if necessary', function() { + innerRing.reverse(); + polygon = new ol.geom.Polygon([outerRing, innerRing]); + expect(polygon.getOrientedFlatCoordinates()).to.eql(flatCoordinates); + }); + + it('reverses all rings if necessary', function() { + outerRing.reverse(); + innerRing.reverse(); + polygon = new ol.geom.Polygon([outerRing, innerRing]); + expect(polygon.getOrientedFlatCoordinates()).to.eql(flatCoordinates); + }); + + }); + }); describe('construct with 3D coordinates and layout XYM', function() { @@ -191,6 +237,29 @@ describe('ol.geom.Polygon', function() { expect(polygon.containsCoordinate(insideInner)).to.be(false); }); + describe('#getOrientedFlatCoordinates', function() { + + it('reverses the outer ring if necessary', function() { + outerRing.reverse(); + polygon = new ol.geom.Polygon([outerRing, innerRing]); + expect(polygon.getOrientedFlatCoordinates()).to.eql(flatCoordinates); + }); + + it('reverses inner rings if necessary', function() { + innerRing.reverse(); + polygon = new ol.geom.Polygon([outerRing, innerRing]); + expect(polygon.getOrientedFlatCoordinates()).to.eql(flatCoordinates); + }); + + it('reverses all rings if necessary', function() { + outerRing.reverse(); + innerRing.reverse(); + polygon = new ol.geom.Polygon([outerRing, innerRing]); + expect(polygon.getOrientedFlatCoordinates()).to.eql(flatCoordinates); + }); + + }); + }); describe('construct with 4D coordinates', function() { @@ -248,6 +317,31 @@ describe('ol.geom.Polygon', function() { expect(polygon.containsCoordinate(insideInner2)).to.be(false); }); + describe('#getOrientedFlatCoordinates', function() { + + it('reverses the outer ring if necessary', function() { + outerRing.reverse(); + polygon = new ol.geom.Polygon([outerRing, innerRing1, innerRing2]); + expect(polygon.getOrientedFlatCoordinates()).to.eql(flatCoordinates); + }); + + it('reverses inner rings if necessary', function() { + innerRing1.reverse(); + innerRing2.reverse(); + polygon = new ol.geom.Polygon([outerRing, innerRing1, innerRing2]); + expect(polygon.getOrientedFlatCoordinates()).to.eql(flatCoordinates); + }); + + it('reverses all rings if necessary', function() { + outerRing.reverse(); + innerRing1.reverse(); + innerRing2.reverse(); + polygon = new ol.geom.Polygon([outerRing, innerRing1, innerRing2]); + expect(polygon.getOrientedFlatCoordinates()).to.eql(flatCoordinates); + }); + + }); + }); describe('with a simple polygon', function() {