Add convenience function to create a regular polygon geometryFunction

This commit is contained in:
Andreas Hocevar
2015-05-08 11:21:16 +02:00
parent 901a0f6d8e
commit 19c91235ce
4 changed files with 77 additions and 2 deletions

View File

@@ -6,7 +6,8 @@ docs: >
Example of using the Draw interaction. Select a geometry type from the Example of using the Draw interaction. Select a geometry type from the
dropdown above to start drawing. To finish drawing, click the last dropdown above to start drawing. To finish drawing, click the last
point. To activate freehand drawing for lines and polygons, hold the `Shift` 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" tags: "draw, edit, freehand, vector"
--- ---
<div class="row-fluid"> <div class="row-fluid">
@@ -20,6 +21,7 @@ tags: "draw, edit, freehand, vector"
<option value="LineString">LineString</option> <option value="LineString">LineString</option>
<option value="Polygon">Polygon</option> <option value="Polygon">Polygon</option>
<option value="Circle">Circle</option> <option value="Circle">Circle</option>
<option value="Square">Square</option>
</select> </select>
</form> </form>
</div> </div>

View File

@@ -51,9 +51,16 @@ var draw; // global so we can remove it later
function addInteraction() { function addInteraction() {
var value = typeSelect.value; var value = typeSelect.value;
if (value !== 'None') { if (value !== 'None') {
var geometryFunction;
if (value === 'Square') {
value = 'Circle';
geometryFunction =
ol.interaction.Draw.createRegularPolygon(4, Math.PI / 4);
}
draw = new ol.interaction.Draw({ draw = new ol.interaction.Draw({
source: source, source: source,
type: /** @type {ol.geom.GeometryType} */ (value) type: /** @type {ol.geom.GeometryType} */ (value),
geometryFunction: geometryFunction
}); });
map.addInteraction(draw); map.addInteraction(draw);
} }

View File

@@ -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.<ol.Coordinate>|Array.<Array.<ol.Coordinate>>} 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 * Get the drawing mode. The mode for mult-part geometries is the same as for
* their single-part cousins. * their single-part cousins.

View File

@@ -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'); goog.require('goog.dispose');