From 42865ab8c3fac75bd63510beeea6b346ed23e53e Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 21 Jan 2014 07:45:42 +0100 Subject: [PATCH 01/11] Add ol.geom.flat.linearRingsAreOriented --- src/ol/geom/flatgeom.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/ol/geom/flatgeom.js b/src/ol/geom/flatgeom.js index 88635b9100..8a7f156b7e 100644 --- a/src/ol/geom/flatgeom.js +++ b/src/ol/geom/flatgeom.js @@ -549,6 +549,28 @@ ol.geom.flat.linearRingsGetInteriorPoint = /** * @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.>} endss Endss. * @param {number} stride Stride. * @return {number} Area. From 36387adf3f8394dd42570c56d23d9412011dc28c Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 21 Jan 2014 07:45:59 +0100 Subject: [PATCH 02/11] Add ol.geom.flat.linearRingssAreOriented --- src/ol/geom/flatgeom.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/ol/geom/flatgeom.js b/src/ol/geom/flatgeom.js index 8a7f156b7e..bdde328407 100644 --- a/src/ol/geom/flatgeom.js +++ b/src/ol/geom/flatgeom.js @@ -571,6 +571,29 @@ ol.geom.flat.linearRingsAreOriented = /** + * @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. * @param {Array.>} endss Endss. * @param {number} stride Stride. * @return {number} Area. From ff73f080b33af6766705cbbb5292647ef5830897 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 21 Jan 2014 07:47:36 +0100 Subject: [PATCH 03/11] Don't automatically orient rings in ol.geom.Polygon --- src/ol/geom/polygon.js | 2 - test/spec/ol/geom/polygon.test.js | 68 ++----------------- .../ol/interaction/drawinteraction.test.js | 3 +- 3 files changed, 8 insertions(+), 65 deletions(-) diff --git a/src/ol/geom/polygon.js b/src/ol/geom/polygon.js index 3b1cb59981..0da2285d5e 100644 --- a/src/ol/geom/polygon.js +++ b/src/ol/geom/polygon.js @@ -192,8 +192,6 @@ ol.geom.Polygon.prototype.setCoordinates = function(coordinates, opt_layout) { var ends = ol.geom.flat.deflateCoordinatess( this.flatCoordinates, 0, coordinates, this.stride, this.ends_); this.flatCoordinates.length = ends.length === 0 ? 0 : ends[ends.length - 1]; - ol.geom.flat.orientLinearRings( - this.flatCoordinates, 0, this.ends_, this.stride); this.dispatchChangeEvent(); } }; diff --git a/test/spec/ol/geom/polygon.test.js b/test/spec/ol/geom/polygon.test.js index b547565ec3..a35f473816 100644 --- a/test/spec/ol/geom/polygon.test.js +++ b/test/spec/ol/geom/polygon.test.js @@ -73,19 +73,13 @@ describe('ol.geom.Polygon', function() { expect(polygon.getStride()).to.be(2); }); - it('reverses the outer ring if necessary', function() { - polygon = new ol.geom.Polygon([outerRing.reverse(), innerRing]); - expect(polygon.getFlatCoordinates()).to.eql(flatCoordinates); - }); - - it('reverses inner rings if necessary', function() { - polygon = new ol.geom.Polygon([outerRing, innerRing.reverse()]); - expect(polygon.getFlatCoordinates()).to.eql(flatCoordinates); - }); - - it('reverses all rings if necessary', function() { - polygon = new ol.geom.Polygon([outerRing.reverse(), innerRing.reverse()]); - expect(polygon.getFlatCoordinates()).to.eql(flatCoordinates); + it('does not reverse any rings', function() { + outerRing.reverse(); + innerRing.reverse(); + polygon = new ol.geom.Polygon([outerRing, innerRing]); + var coordinates = polygon.getCoordinates(); + expect(coordinates[0]).to.eql(outerRing); + expect(coordinates[1]).to.eql(innerRing); }); it('does not contain outside coordinates', function() { @@ -136,21 +130,6 @@ describe('ol.geom.Polygon', function() { expect(polygon.getStride()).to.be(3); }); - it('reverses the outer ring if necessary', function() { - polygon = new ol.geom.Polygon([outerRing.reverse(), innerRing]); - expect(polygon.getFlatCoordinates()).to.eql(flatCoordinates); - }); - - it('reverses inner rings if necessary', function() { - polygon = new ol.geom.Polygon([outerRing, innerRing.reverse()]); - expect(polygon.getFlatCoordinates()).to.eql(flatCoordinates); - }); - - it('reverses all rings if necessary', function() { - polygon = new ol.geom.Polygon([outerRing.reverse(), innerRing.reverse()]); - expect(polygon.getFlatCoordinates()).to.eql(flatCoordinates); - }); - it('does not contain outside coordinates', function() { expect(polygon.containsCoordinate(outsideOuter)).to.be(false); }); @@ -200,21 +179,6 @@ describe('ol.geom.Polygon', function() { expect(polygon.getStride()).to.be(3); }); - it('reverses the outer ring if necessary', function() { - polygon = new ol.geom.Polygon([outerRing.reverse(), innerRing]); - expect(polygon.getFlatCoordinates()).to.eql(flatCoordinates); - }); - - it('reverses inner rings if necessary', function() { - polygon = new ol.geom.Polygon([outerRing, innerRing.reverse()]); - expect(polygon.getFlatCoordinates()).to.eql(flatCoordinates); - }); - - it('reverses all rings if necessary', function() { - polygon = new ol.geom.Polygon([outerRing.reverse(), innerRing.reverse()]); - expect(polygon.getFlatCoordinates()).to.eql(flatCoordinates); - }); - it('does not contain outside coordinates', function() { expect(polygon.containsCoordinate(outsideOuter)).to.be(false); }); @@ -271,24 +235,6 @@ describe('ol.geom.Polygon', function() { expect(polygon.getStride()).to.be(4); }); - it('reverses the outer ring if necessary', function() { - polygon = new ol.geom.Polygon( - [outerRing.reverse(), innerRing1, innerRing2]); - expect(polygon.getFlatCoordinates()).to.eql(flatCoordinates); - }); - - it('reverses inner rings if necessary', function() { - polygon = new ol.geom.Polygon( - [outerRing, innerRing1.reverse(), innerRing2.reverse()]); - expect(polygon.getFlatCoordinates()).to.eql(flatCoordinates); - }); - - it('reverses all rings if necessary', function() { - polygon = new ol.geom.Polygon( - [outerRing.reverse(), innerRing1.reverse(), innerRing2.reverse()]); - expect(polygon.getFlatCoordinates()).to.eql(flatCoordinates); - }); - it('does not contain outside coordinates', function() { expect(polygon.containsCoordinate(outsideOuter)).to.be(false); }); diff --git a/test/spec/ol/interaction/drawinteraction.test.js b/test/spec/ol/interaction/drawinteraction.test.js index b2a67c52d0..4efdd2a50e 100644 --- a/test/spec/ol/interaction/drawinteraction.test.js +++ b/test/spec/ol/interaction/drawinteraction.test.js @@ -314,9 +314,8 @@ describe('ol.interaction.Draw', function() { var geometry = features[0].getGeometry(); expect(geometry).to.be.a(ol.geom.Polygon); - // note that order is forced clockwise (despite drawing counter-clockwise) expect(geometry.getCoordinates()).to.eql([ - [[10, -20], [30, -10], [30, -20], [10, -20]] + [[10, -20], [30, -20], [30, -10], [10, -20]] ]); }); From 5b5865d48e42119a06edfc0909b1da814fb8d116 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 21 Jan 2014 07:48:13 +0100 Subject: [PATCH 04/11] 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() { From 6552046aa0fc51839f5f9a0c6f27b06bfc363500 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 21 Jan 2014 07:49:01 +0100 Subject: [PATCH 05/11] Use oriented rings where needed --- src/ol/geom/polygon.js | 6 +++--- src/ol/render/canvas/canvasreplay.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ol/geom/polygon.js b/src/ol/geom/polygon.js index 937079bf02..a1ae17778e 100644 --- a/src/ol/geom/polygon.js +++ b/src/ol/geom/polygon.js @@ -104,7 +104,7 @@ ol.geom.Polygon.prototype.closestPointXY = */ ol.geom.Polygon.prototype.containsXY = function(x, y) { return ol.geom.flat.linearRingsContainsXY( - this.flatCoordinates, 0, this.ends_, this.stride, x, y); + this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride, x, y); }; @@ -113,7 +113,7 @@ ol.geom.Polygon.prototype.containsXY = function(x, y) { */ ol.geom.Polygon.prototype.getArea = function() { return ol.geom.flat.linearRingsArea( - this.flatCoordinates, 0, this.ends_, this.stride); + this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride); }; @@ -142,7 +142,7 @@ ol.geom.Polygon.prototype.getInteriorPoint = function() { var extent = this.getExtent(); var y = (extent[1] + extent[3]) / 2; this.interiorPoint_ = ol.geom.flat.linearRingsGetInteriorPoint( - this.flatCoordinates, 0, this.ends_, this.stride, y); + this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride, y); this.interiorPointRevision_ = this.getRevision(); } return this.interiorPoint_; diff --git a/src/ol/render/canvas/canvasreplay.js b/src/ol/render/canvas/canvasreplay.js index 5628b84b9e..846e00ff48 100644 --- a/src/ol/render/canvas/canvasreplay.js +++ b/src/ol/render/canvas/canvasreplay.js @@ -1096,7 +1096,7 @@ ol.render.canvas.PolygonReplay.prototype.drawPolygonGeometry = state.miterLimit, state.lineDash]); } var ends = polygonGeometry.getEnds(); - var flatCoordinates = polygonGeometry.getFlatCoordinates(); + var flatCoordinates = polygonGeometry.getOrientedFlatCoordinates(); var stride = polygonGeometry.getStride(); this.drawFlatCoordinatess_(flatCoordinates, 0, ends, stride); this.endGeometry(polygonGeometry, data); From 8e372f8db0e913f7fec18a3b31eaa09f322eb847 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 21 Jan 2014 07:51:06 +0100 Subject: [PATCH 06/11] Don't automatically orient rings in ol.geom.MultiPolygon --- src/ol/geom/multipolygon.js | 2 -- test/spec/ol/interaction/drawinteraction.test.js | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/ol/geom/multipolygon.js b/src/ol/geom/multipolygon.js index 2f3e25966f..4265e4de13 100644 --- a/src/ol/geom/multipolygon.js +++ b/src/ol/geom/multipolygon.js @@ -196,8 +196,6 @@ ol.geom.MultiPolygon.prototype.setCoordinates = var lastEnds = endss[endss.length - 1]; this.flatCoordinates.length = lastEnds.length === 0 ? 0 : lastEnds[lastEnds.length - 1]; - ol.geom.flat.orientLinearRingss( - this.flatCoordinates, 0, this.endss_, this.stride); this.dispatchChangeEvent(); } }; diff --git a/test/spec/ol/interaction/drawinteraction.test.js b/test/spec/ol/interaction/drawinteraction.test.js index 4efdd2a50e..a1a070aba5 100644 --- a/test/spec/ol/interaction/drawinteraction.test.js +++ b/test/spec/ol/interaction/drawinteraction.test.js @@ -396,9 +396,8 @@ describe('ol.interaction.Draw', function() { var coordinates = geometry.getCoordinates(); expect(coordinates).to.have.length(1); - // note that order is forced clockwise (despite drawing counter-clockwise) expect(coordinates[0]).to.eql([ - [[10, -20], [30, -10], [30, -20], [10, -20]] + [[10, -20], [30, -20], [30, -10], [10, -20]] ]); }); From 04092dac75c098664d13a1be5b9d0c731c623677 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 21 Jan 2014 07:57:50 +0100 Subject: [PATCH 07/11] Add ol.geom.MultiPolygon#getOrientedFlatCoordinates --- src/ol/geom/multipolygon.js | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/ol/geom/multipolygon.js b/src/ol/geom/multipolygon.js index 4265e4de13..01d5a5c48c 100644 --- a/src/ol/geom/multipolygon.js +++ b/src/ol/geom/multipolygon.js @@ -50,6 +50,18 @@ ol.geom.MultiPolygon = function(coordinates, opt_layout) { */ this.maxDeltaRevision_ = -1; + /** + * @private + * @type {number} + */ + this.orientedRevision_ = -1; + + /** + * @private + * @type {Array.} + */ + this.orientedFlatCoordinates_ = null; + this.setCoordinates(coordinates, opt_layout); }; @@ -137,6 +149,26 @@ ol.geom.MultiPolygon.prototype.getInteriorPoints = function() { }; +/** + * @return {Array.} Oriented flat coordinates. + */ +ol.geom.MultiPolygon.prototype.getOrientedFlatCoordinates = function() { + if (this.orientedRevision_ != this.getRevision()) { + var flatCoordinates = this.flatCoordinates; + if (ol.geom.flat.linearRingssAreOriented( + flatCoordinates, 0, this.endss_, this.stride)) { + this.orientedFlatCoordinates_ = flatCoordinates; + } else { + this.orientedFlatCoordinates_ = flatCoordinates.slice(); + this.orientedFlatCoordinates_.length = ol.geom.flat.orientLinearRingss( + this.orientedFlatCoordinates_, 0, this.endss_, this.stride); + } + this.orientedRevision_ = this.getRevision(); + } + return this.orientedFlatCoordinates_; +}; + + /** * @inheritDoc */ From ffc27719ea5ec66adb12c14c7270a36fc98465ac Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 21 Jan 2014 08:01:16 +0100 Subject: [PATCH 08/11] Use oriented rings where needed --- src/ol/geom/multipolygon.js | 8 ++++---- src/ol/render/canvas/canvasreplay.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ol/geom/multipolygon.js b/src/ol/geom/multipolygon.js index 01d5a5c48c..debf57125d 100644 --- a/src/ol/geom/multipolygon.js +++ b/src/ol/geom/multipolygon.js @@ -94,7 +94,7 @@ ol.geom.MultiPolygon.prototype.closestPointXY = this.maxDeltaRevision_ = this.getRevision(); } return ol.geom.closest.getssClosestPoint( - this.flatCoordinates, 0, this.endss_, this.stride, + this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, this.maxDelta_, true, x, y, closestPoint, minSquaredDistance); }; @@ -104,7 +104,7 @@ ol.geom.MultiPolygon.prototype.closestPointXY = */ ol.geom.MultiPolygon.prototype.containsXY = function(x, y) { return ol.geom.flat.linearRingssContainsXY( - this.flatCoordinates, 0, this.endss_, this.stride, x, y); + this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, x, y); }; @@ -113,7 +113,7 @@ ol.geom.MultiPolygon.prototype.containsXY = function(x, y) { */ ol.geom.MultiPolygon.prototype.getArea = function() { return ol.geom.flat.linearRingssArea( - this.flatCoordinates, 0, this.endss_, this.stride); + this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride); }; @@ -142,7 +142,7 @@ ol.geom.MultiPolygon.prototype.getInteriorPoints = function() { var ys = ol.geom.flat.linearRingssMidYs( this.flatCoordinates, 0, this.endss_, this.stride); this.interiorPoints_ = ol.geom.flat.linearRingssGetInteriorPoints( - this.flatCoordinates, 0, this.endss_, this.stride, ys); + this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, ys); this.interiorPointsRevision_ = this.getRevision(); } return this.interiorPoints_; diff --git a/src/ol/render/canvas/canvasreplay.js b/src/ol/render/canvas/canvasreplay.js index 846e00ff48..e3c7634c59 100644 --- a/src/ol/render/canvas/canvasreplay.js +++ b/src/ol/render/canvas/canvasreplay.js @@ -1132,7 +1132,7 @@ ol.render.canvas.PolygonReplay.prototype.drawMultiPolygonGeometry = state.miterLimit, state.lineDash]); } var endss = multiPolygonGeometry.getEndss(); - var flatCoordinates = multiPolygonGeometry.getFlatCoordinates(); + var flatCoordinates = multiPolygonGeometry.getOrientedFlatCoordinates(); var stride = multiPolygonGeometry.getStride(); var offset = 0; var i, ii; From 4d88d5314669db88f38b2979975f2ea766312b0e Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 21 Jan 2014 08:11:41 +0100 Subject: [PATCH 09/11] Add test for ol.geom.Polygon#getLinearRings --- test/spec/ol/geom/polygon.test.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/spec/ol/geom/polygon.test.js b/test/spec/ol/geom/polygon.test.js index 96c36b20cc..a245dc21ca 100644 --- a/test/spec/ol/geom/polygon.test.js +++ b/test/spec/ol/geom/polygon.test.js @@ -73,6 +73,16 @@ describe('ol.geom.Polygon', function() { expect(polygon.getStride()).to.be(2); }); + it('has the expected rings', function() { + var linearRings = polygon.getLinearRings(); + expect(linearRings).to.be.an(Array); + expect(linearRings).to.have.length(2); + expect(linearRings[0]).to.be.an(ol.geom.LinearRing); + expect(linearRings[0].getCoordinates()).to.eql(outerRing); + expect(linearRings[1]).to.be.an(ol.geom.LinearRing); + expect(linearRings[1].getCoordinates()).to.eql(innerRing); + }); + it('does not reverse any rings', function() { outerRing.reverse(); innerRing.reverse(); @@ -377,4 +387,5 @@ describe('ol.geom.Polygon', function() { goog.require('ol.extent'); +goog.require('ol.geom.LinearRing'); goog.require('ol.geom.Polygon'); From d35c40f81f015f6e12d738b3408287c5ba69e873 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 21 Jan 2014 08:12:22 +0100 Subject: [PATCH 10/11] Create linear rings directly from flat coordinates --- src/ol/geom/polygon.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/ol/geom/polygon.js b/src/ol/geom/polygon.js index a1ae17778e..bcd1dabd7e 100644 --- a/src/ol/geom/polygon.js +++ b/src/ol/geom/polygon.js @@ -153,11 +153,18 @@ ol.geom.Polygon.prototype.getInteriorPoint = function() { * @return {Array.} Linear rings. */ ol.geom.Polygon.prototype.getLinearRings = function() { + var layout = this.layout; + var flatCoordinates = this.flatCoordinates; + var ends = this.ends_; var linearRings = []; - var coordinates = this.getCoordinates(); + var offset = 0; var i, ii; - for (i = 0, ii = coordinates.length; i < ii; ++i) { - linearRings.push(new ol.geom.LinearRing(coordinates[i])); + for (i = 0, ii = ends.length; i < ii; ++i) { + var end = ends[i]; + var linearRing = new ol.geom.LinearRing(null); + linearRing.setFlatCoordinates(layout, flatCoordinates.slice(offset, end)); + linearRings.push(linearRing); + offset = end; } return linearRings; }; From d39a5cec75c0dabbe2e184f756b27b538900d064 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Tue, 21 Jan 2014 08:49:10 +0100 Subject: [PATCH 11/11] Create polygons directly from flat coordinates --- src/ol/geom/multipolygon.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/ol/geom/multipolygon.js b/src/ol/geom/multipolygon.js index debf57125d..4737d3a55b 100644 --- a/src/ol/geom/multipolygon.js +++ b/src/ol/geom/multipolygon.js @@ -191,12 +191,20 @@ ol.geom.MultiPolygon.prototype.getSimplifiedGeometryInternal = * @return {Array.} Polygons. */ ol.geom.MultiPolygon.prototype.getPolygons = function() { - // FIXME we should construct the polygons directly from the flat coordinates - var coordinates = this.getCoordinates(); + var layout = this.layout; + var flatCoordinates = this.flatCoordinates; + var endss = this.endss_; var polygons = []; + var offset = 0; var i, ii; - for (i = 0, ii = coordinates.length; i < ii; ++i) { - polygons.push(new ol.geom.Polygon(coordinates[i])); + for (i = 0, ii = endss.length; i < ii; ++i) { + var ends = endss[i]; + var end = ends[ends.length - 1]; + var polygon = new ol.geom.Polygon(null); + polygon.setFlatCoordinates( + layout, flatCoordinates.slice(offset, end), ends.slice()); + polygons.push(polygon); + offset = end; } return polygons; };