From cbe1650c79f2ad6a0c8b3965aa3079f441eb6e9a Mon Sep 17 00:00:00 2001 From: oterral Date: Mon, 13 Jan 2014 14:49:18 +0100 Subject: [PATCH 1/2] Finish polygon drawing on last point --- src/ol/interaction/drawinteraction.js | 30 ++++++++++++++++++++------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/ol/interaction/drawinteraction.js b/src/ol/interaction/drawinteraction.js index 6caaee7e3c..e0594c9d49 100644 --- a/src/ol/interaction/drawinteraction.js +++ b/src/ol/interaction/drawinteraction.js @@ -309,20 +309,30 @@ ol.interaction.Draw.prototype.atFinish_ = function(event) { if (!goog.isNull(this.sketchFeature_)) { var geometry = this.sketchFeature_.getGeometry(); var potentiallyDone = false; + var potentiallyFinishCoordinates = [this.finishCoordinate_]; if (this.mode_ === ol.interaction.DrawMode.LINE_STRING) { goog.asserts.assertInstanceof(geometry, ol.geom.LineString); potentiallyDone = geometry.getCoordinates().length > 2; } else if (this.mode_ === ol.interaction.DrawMode.POLYGON) { goog.asserts.assertInstanceof(geometry, ol.geom.Polygon); - potentiallyDone = geometry.getCoordinates()[0].length > 3; + potentiallyDone = geometry.getCoordinates()[0].length > 2; + potentiallyFinishCoordinates = [this.sketchRawPolygon_[0][0], + this.sketchRawPolygon_[0][this.sketchRawPolygon_[0].length - 2]]; } if (potentiallyDone) { var map = event.map; - var finishPixel = map.getPixelFromCoordinate(this.finishCoordinate_); - var pixel = event.getPixel(); - var dx = pixel[0] - finishPixel[0]; - var dy = pixel[1] - finishPixel[1]; - at = Math.sqrt(dx * dx + dy * dy) <= this.snapTolerance_; + for (var i = 0, ii = potentiallyFinishCoordinates.length; i < ii; i++) { + var finishCoordinate = potentiallyFinishCoordinates[i]; + var finishPixel = map.getPixelFromCoordinate(finishCoordinate); + var pixel = event.getPixel(); + var dx = pixel[0] - finishPixel[0]; + var dy = pixel[1] - finishPixel[1]; + at = Math.sqrt(dx * dx + dy * dy) <= this.snapTolerance_; + if (at) { + this.finishCoordinate_ = finishCoordinate; + break; + } + } } } return at; @@ -453,9 +463,13 @@ ol.interaction.Draw.prototype.finishDrawing_ = function(event) { geometry.setCoordinates(coordinates); } else if (this.mode_ === ol.interaction.DrawMode.POLYGON) { goog.asserts.assertInstanceof(geometry, ol.geom.Polygon); + // When we finish drawing a polygon on the last point, + // the last coordinate is duplicated as for LineString + // we force the replacement by the first point + this.sketchRawPolygon_[0].pop(); + this.sketchRawPolygon_[0].push(this.sketchRawPolygon_[0][0]); + geometry.setCoordinates(this.sketchRawPolygon_); coordinates = geometry.getCoordinates(); - // force clockwise order for exterior ring - sketchFeature.setGeometry(new ol.geom.Polygon(coordinates)); } // cast multi-part geometries From b2819a23324a36066621e7e978851acff252a569 Mon Sep 17 00:00:00 2001 From: oterral Date: Tue, 14 Jan 2014 16:35:54 +0100 Subject: [PATCH 2/2] Add some tests for drawing polygons --- .../ol/interaction/drawinteraction.test.js | 90 ++++++++++++++++--- 1 file changed, 80 insertions(+), 10 deletions(-) diff --git a/test/spec/ol/interaction/drawinteraction.test.js b/test/spec/ol/interaction/drawinteraction.test.js index a1a070aba5..bdac50dd3f 100644 --- a/test/spec/ol/interaction/drawinteraction.test.js +++ b/test/spec/ol/interaction/drawinteraction.test.js @@ -298,10 +298,10 @@ describe('ol.interaction.Draw', function() { simulateEvent('click', 30, 20); // third point - simulateEvent('mousemove', 30, 10); - simulateEvent('mousedown', 30, 10); - simulateEvent('mouseup', 30, 10); - simulateEvent('click', 30, 10); + simulateEvent('mousemove', 40, 10); + simulateEvent('mousedown', 40, 10); + simulateEvent('mouseup', 40, 10); + simulateEvent('click', 40, 10); // finish on first point simulateEvent('mousemove', 10, 20); @@ -315,7 +315,41 @@ describe('ol.interaction.Draw', function() { expect(geometry).to.be.a(ol.geom.Polygon); expect(geometry.getCoordinates()).to.eql([ - [[10, -20], [30, -20], [30, -10], [10, -20]] + [[10, -20], [30, -20], [40, -10], [10, -20]] + ]); + }); + + it('draws polygon with clicks, finishing on last point', function() { + // first point + simulateEvent('mousemove', 10, 20); + simulateEvent('mousedown', 10, 20); + simulateEvent('mouseup', 10, 20); + simulateEvent('click', 10, 20); + + // second point + simulateEvent('mousemove', 30, 20); + simulateEvent('mousedown', 30, 20); + simulateEvent('mouseup', 30, 20); + simulateEvent('click', 30, 20); + + // third point + simulateEvent('mousemove', 40, 10); + simulateEvent('mousedown', 40, 10); + simulateEvent('mouseup', 40, 10); + simulateEvent('click', 40, 10); + + // finish on last point + simulateEvent('mousedown', 40, 10); + simulateEvent('mouseup', 40, 10); + simulateEvent('click', 40, 11); + + var features = source.getAllFeatures(); + expect(features).to.have.length(1); + var geometry = features[0].getGeometry(); + expect(geometry).to.be.a(ol.geom.Polygon); + + expect(geometry.getCoordinates()).to.eql([ + [[10, -20], [30, -20], [40, -10], [10, -20]] ]); }); @@ -378,10 +412,10 @@ describe('ol.interaction.Draw', function() { simulateEvent('click', 30, 20); // third point - simulateEvent('mousemove', 30, 10); - simulateEvent('mousedown', 30, 10); - simulateEvent('mouseup', 30, 10); - simulateEvent('click', 30, 10); + simulateEvent('mousemove', 40, 10); + simulateEvent('mousedown', 40, 10); + simulateEvent('mouseup', 40, 10); + simulateEvent('click', 40, 10); // finish on first point simulateEvent('mousemove', 10, 20); @@ -397,7 +431,43 @@ describe('ol.interaction.Draw', function() { expect(coordinates).to.have.length(1); expect(coordinates[0]).to.eql([ - [[10, -20], [30, -20], [30, -10], [10, -20]] + [[10, -20], [30, -20], [40, -10], [10, -20]] + ]); + }); + + it('draws multi with clicks, finishing on last point', function() { + // first point + simulateEvent('mousemove', 10, 20); + simulateEvent('mousedown', 10, 20); + simulateEvent('mouseup', 10, 20); + simulateEvent('click', 10, 20); + + // second point + simulateEvent('mousemove', 30, 20); + simulateEvent('mousedown', 30, 20); + simulateEvent('mouseup', 30, 20); + simulateEvent('click', 30, 20); + + // third point + simulateEvent('mousemove', 40, 10); + simulateEvent('mousedown', 40, 10); + simulateEvent('mouseup', 40, 10); + simulateEvent('click', 40, 10); + + // finish on last point + simulateEvent('mousedown', 40, 10); + simulateEvent('mouseup', 40, 10); + simulateEvent('click', 40, 10); + + var features = source.getAllFeatures(); + expect(features).to.have.length(1); + var geometry = features[0].getGeometry(); + expect(geometry).to.be.a(ol.geom.MultiPolygon); + var coordinates = geometry.getCoordinates(); + expect(coordinates).to.have.length(1); + + expect(coordinates[0]).to.eql([ + [[10, -20], [30, -20], [40, -10], [10, -20]] ]); });