From 19c91235ceb9a481c34f120135ac0a5e957c660f Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Fri, 8 May 2015 11:21:16 +0200 Subject: [PATCH] Add convenience function to create a regular polygon geometryFunction --- examples/draw-features.html | 4 ++- examples/draw-features.js | 9 ++++- src/ol/interaction/drawinteraction.js | 36 +++++++++++++++++++ .../ol/interaction/drawinteraction.test.js | 30 ++++++++++++++++ 4 files changed, 77 insertions(+), 2 deletions(-) diff --git a/examples/draw-features.html b/examples/draw-features.html index a7c902d6d8..e9ec02e794 100644 --- a/examples/draw-features.html +++ b/examples/draw-features.html @@ -6,7 +6,8 @@ docs: > Example of using the Draw interaction. Select a geometry type from the dropdown above to start drawing. To finish drawing, click the last point. To activate freehand drawing for lines and polygons, hold the `Shift` - key. + key. Square drawing is achieved by using Circle mode with a `geometryFunction` + that creates a 4-sided regular polygon instead of a circle. tags: "draw, edit, freehand, vector" ---
@@ -20,6 +21,7 @@ tags: "draw, edit, freehand, vector" +
diff --git a/examples/draw-features.js b/examples/draw-features.js index dcab9c70db..70ef9935ac 100644 --- a/examples/draw-features.js +++ b/examples/draw-features.js @@ -51,9 +51,16 @@ var draw; // global so we can remove it later function addInteraction() { var value = typeSelect.value; if (value !== 'None') { + var geometryFunction; + if (value === 'Square') { + value = 'Circle'; + geometryFunction = + ol.interaction.Draw.createRegularPolygon(4, Math.PI / 4); + } draw = new ol.interaction.Draw({ source: source, - type: /** @type {ol.geom.GeometryType} */ (value) + type: /** @type {ol.geom.GeometryType} */ (value), + geometryFunction: geometryFunction }); map.addInteraction(draw); } diff --git a/src/ol/interaction/drawinteraction.js b/src/ol/interaction/drawinteraction.js index a7f9423cbe..2142494328 100644 --- a/src/ol/interaction/drawinteraction.js +++ b/src/ol/interaction/drawinteraction.js @@ -705,6 +705,42 @@ ol.interaction.Draw.prototype.updateState_ = function() { }; +/** + * Create a `geometryFunction` for `mode: 'Circle'` that will create a regular + * polygon with a user specified number of sides and start angle instead of an + * `ol.geom.Circle` geometry. + * @param {number=} opt_sides Number of sides of the regular polygon. Default is + * 32. + * @param {number=} opt_angle Angle of the first point in radians. 0 means East. + * Default is 0. + * @return {ol.interaction.Draw.GeometryFunctionType} Function that draws a + * polygon. + * @api + */ +ol.interaction.Draw.createRegularPolygon = function(opt_sides, opt_angle) { + var sides = goog.isDef(opt_sides) ? opt_sides : 32; + var angle = goog.isDef(opt_angle) ? opt_angle : 0; + return ( + /** + * @param {ol.Coordinate|Array.|Array.>} coordinates + * @param {ol.geom.SimpleGeometry=} opt_geometry + * @return {ol.geom.SimpleGeometry} + */ + function(coordinates, opt_geometry) { + var center = coordinates[0]; + var radius = Math.sqrt( + ol.coordinate.squaredDistance(coordinates[0], coordinates[1])); + var geometry = goog.isDef(opt_geometry) ? opt_geometry : + ol.geom.Polygon.fromCircle(new ol.geom.Circle(center), sides); + goog.asserts.assertInstanceof(geometry, ol.geom.Polygon, + 'geometry must be a polygon'); + ol.geom.Polygon.makeRegular(geometry, center, radius, angle); + return geometry; + } + ); +}; + + /** * Get the drawing mode. The mode for mult-part geometries is the same as for * their single-part cousins. diff --git a/test/spec/ol/interaction/drawinteraction.test.js b/test/spec/ol/interaction/drawinteraction.test.js index dda8d2dcdc..684449a289 100644 --- a/test/spec/ol/interaction/drawinteraction.test.js +++ b/test/spec/ol/interaction/drawinteraction.test.js @@ -708,6 +708,36 @@ describe('ol.interaction.Draw', function() { }); }); + + describe('ol.interaction.Draw.createRegularPolygon', function() { + it('creates a regular polygon in Circle mode', function() { + var draw = new ol.interaction.Draw({ + source: source, + type: ol.geom.GeometryType.CIRCLE, + geometryFunction: + ol.interaction.Draw.createRegularPolygon(4, Math.PI / 4) + }); + map.addInteraction(draw); + + // first point + simulateEvent('pointermove', 0, 0); + simulateEvent('pointerdown', 0, 0); + simulateEvent('pointerup', 0, 0); + + // finish on second point + simulateEvent('pointermove', 20, 20); + simulateEvent('pointerdown', 20, 20); + simulateEvent('pointerup', 20, 20); + + var features = source.getFeatures(); + var geometry = features[0].getGeometry(); + expect(geometry).to.be.a(ol.geom.Polygon); + var coordinates = geometry.getCoordinates(); + expect(coordinates[0].length).to.eql(5); + expect(coordinates[0][0][0]).to.roughlyEqual(20, 1e-9); + expect(coordinates[0][0][1]).to.roughlyEqual(20, 1e-9); + }); + }); }); goog.require('goog.dispose');