OpenLayers OpenLayers

Ticket #828: regular-poly.patch

File regular-poly.patch, 29.8 kB (added by tschaub, 1 year ago)

updated patch

  • tests/Geometry/test_Polygon.html

    old new  
    173173         
    174174    } 
    175175 
     176    function test_Polygon_createRegular(t) { 
     177        t.plan(22); 
     178        var sides = 40; 
     179        var poly = OpenLayers.Geometry.Polygon.createRegularPolygon(new OpenLayers.Geometry.Point(5,0), 6, sides); 
     180        var polyBounds = poly.getBounds(); 
     181        t.eq(polyBounds.toBBOX(), "-0.981504,-5.981504,10.981504,5.981504", sides + " sided figure generates correct bbox."); 
     182        t.eq(poly.components.length, 1, "Poly has one linear ring"); 
     183        t.eq(poly.components[0].components.length, sides + 1, "ring has 41 components"); 
     184        t.eq(poly.components[0].components[0].id, poly.components[0].components[sides].id, "ring starts and ends with same geom"); 
     185        t.eq(Math.round(poly.getArea()), Math.round(Math.PI * 36), "area of "+sides+" sided poly rounds to same area as a circle."); 
     186         
     187        var sides = 3; 
     188        var poly = OpenLayers.Geometry.Polygon.createRegularPolygon(new OpenLayers.Geometry.Point(5,0), 6, sides); 
     189        var polyBounds = poly.getBounds(); 
     190        t.eq(polyBounds.toBBOX(), "-0.196152,-3,10.196152,6", sides + " sided figure generates correct bbox."); 
     191        t.eq(poly.components.length, 1, "Poly has one linear ring"); 
     192        t.eq(poly.components[0].components.length, sides + 1, "ring has  correct count of  components"); 
     193        t.eq(poly.components[0].components[0].id, poly.components[0].components[sides].id, "ring starts and ends with same geom"); 
     194        t.eq(Math.round(poly.getArea()), 47, "area of 3 sided poly is correct"); 
     195         
     196        var sides = 3; 
     197        var poly3 = OpenLayers.Geometry.Polygon.createRegularPolygon(new OpenLayers.Geometry.Point(10,0), 15, sides); 
     198        var polyBounds = poly3.getBounds(); 
     199        t.eq(polyBounds.toBBOX(), "-2.990381,-7.5,22.990381,15", sides + " sided figure generates correct bbox."); 
     200        t.eq(Math.round(polyBounds.getCenterLonLat().lon), 10, "longitude of center of bounds is same as origin"); 
     201        t.eq(poly3.components.length, 1, "Poly has one linear ring"); 
     202        t.eq(poly3.components[0].components.length, sides + 1, "ring has  correct count of  components"); 
     203        t.eq(poly3.components[0].components[0].id, poly3.components[0].components[sides].id, "ring starts and ends with same geom"); 
     204        t.ok(poly3.getArea() > poly.getArea(), "area with radius 15 > poly with radius 6");  
     205         
     206        var sides = 4; 
     207        var poly4 = OpenLayers.Geometry.Polygon.createRegularPolygon(new OpenLayers.Geometry.Point(10,0), 15, sides); 
     208        var polyBounds = poly4.getBounds(); 
     209        t.eq(polyBounds.toBBOX(), "-0.606602,-10.606602,20.606602,10.606602", sides + " sided figure generates correct bbox."); 
     210        t.eq(Math.round(polyBounds.getCenterLonLat().lon), 10, "longitude of center of bounds is same as origin"); 
     211        t.eq(poly4.components.length, 1, "Poly has one linear ring"); 
     212        t.eq(poly4.components[0].components.length, sides + 1, "ring has  correct count of  components"); 
     213        t.eq(poly4.components[0].components[0].id, poly4.components[0].components[sides].id, "ring starts and ends with same geom"); 
     214        t.ok(poly4.getArea() > poly3.getArea(), "square with radius 15 > triangle with radius 15");  
     215    } 
     216 
    176217    function test_Polygon_equals(t) { 
    177218        t.plan(3); 
    178219         
  • tests/Handler/test_RegularPolygon.html

    old new  
     1<html> 
     2<head> 
     3  <script src="../../lib/OpenLayers.js"></script> 
     4  <script type="text/javascript"> 
     5    function test_Handler_RegularPolygon_constructor(t) { 
     6        t.plan(3); 
     7        var control = new OpenLayers.Control(); 
     8        control.id = Math.random(); 
     9        var callbacks = {foo: "bar"}; 
     10        var options = {bar: "foo"}; 
     11         
     12        var oldInit = OpenLayers.Handler.prototype.initialize; 
     13         
     14        OpenLayers.Handler.prototype.initialize = function(con, call, opt) { 
     15            t.eq(con.id, control.id, 
     16                 "constructor calls parent with the correct control"); 
     17            t.eq(call, callbacks, 
     18                 "constructor calls parent with the correct callbacks"); 
     19            t.eq(opt, options, 
     20                 "regular polygon constructor calls parent with the correct options"); 
     21        } 
     22        var handler = new OpenLayers.Handler.RegularPolygon(control, callbacks, options); 
     23 
     24        OpenLayers.Handler.prototype.initialize = oldInit; 
     25    } 
     26 
     27    function test_Handler_RegularPolygon_activation(t) { 
     28        t.plan(3); 
     29        var map = new OpenLayers.Map('map'); 
     30        var control = new OpenLayers.Control(); 
     31        map.addControl(control); 
     32        var handler = new OpenLayers.Handler.RegularPolygon(control); 
     33        handler.active = true; 
     34        var activated = handler.activate(); 
     35        t.ok(!activated, 
     36             "activate returns false if the handler was already active"); 
     37        handler.active = false; 
     38        activated = handler.activate(); 
     39        t.ok(activated, 
     40             "activate returns true if the handler was not already active"); 
     41        activated = handler.deactivate(); 
     42        t.ok(activated, 
     43             "deactivate returns true if the handler was active already"); 
     44    } 
     45 
     46    function test_Handler_RegularPolygon_four_corners(t) { 
     47        t.plan(7); 
     48        var map = new OpenLayers.Map('map'); 
     49        map.addLayer(new OpenLayers.Layer.WMS("", "", {})); 
     50        map.zoomToMaxExtent(); 
     51        var control = new OpenLayers.Control(); 
     52        map.addControl(control); 
     53        var handler = new OpenLayers.Handler.RegularPolygon(control, {}); 
     54        var activated = handler.activate(); 
     55        var evt = {xy: new OpenLayers.Pixel(150, 75), which: 1}; 
     56        handler.down(evt); 
     57        var evt = {xy: new OpenLayers.Pixel(175, 75), which: 1}; 
     58        handler.move(evt); 
     59        t.eq(handler.feature.geometry.getBounds().toBBOX(), 
     60             "-35.15625,-35.15625,35.15625,35.15625", 
     61             "correct bounds after move"); 
     62        t.eq(handler.feature.geometry.components[0].components.length, 5, 
     63             "geometry has 5 components"); 
     64        t.eq(handler.feature.geometry.CLASS_NAME, 
     65             "OpenLayers.Geometry.Polygon", 
     66             "geometry is a polygon"); 
     67        t.eq(handler.radius, 25*1.40625, "feature radius as set on handler"); 
     68        var evt = {xy: new OpenLayers.Pixel(175, 80), which: 1}; 
     69        handler.move(evt); 
     70        t.eq(handler.feature.geometry.getBounds().toBBOX(), 
     71             "-35.15625,-35.15625,35.15625,35.15625", 
     72             "correct bounds after move with a fixed radius"); 
     73        handler.cancel(); 
     74        handler.setOptions({radius:2 / Math.sqrt(2)}); 
     75        var evt = {xy: new OpenLayers.Pixel(150, 75), which: 1}; 
     76        handler.down(evt); 
     77         
     78        t.eq(handler.feature.geometry.getBounds().toBBOX(), 
     79             "-1,-1,1,1", 
     80             "bounds with manual radius setting"); 
     81        var evt = {xy: new OpenLayers.Pixel(175, 90), which: 1}; 
     82        handler.move(evt); 
     83        t.eq(handler.feature.geometry.getBounds().toBBOX(), 
     84             "34.15625,-22.09375,36.15625,-20.09375", 
     85             "bounds with manual radius setting and mousemove"); 
     86    } 
     87 
     88    function test_Handler_RegularPolygon_circle(t) { 
     89        t.plan(7); 
     90        var map = new OpenLayers.Map('map'); 
     91        map.addLayer(new OpenLayers.Layer.WMS("", "", {})); 
     92        map.zoomToMaxExtent(); 
     93        var control = new OpenLayers.Control(); 
     94        map.addControl(control); 
     95        var handler = new OpenLayers.Handler.RegularPolygon(control, {}, {'sides':40}); 
     96        var activated = handler.activate(); 
     97        var evt = {xy: new OpenLayers.Pixel(150, 75), which: 1}; 
     98        handler.down(evt); 
     99        var evt = {xy: new OpenLayers.Pixel(175, 75), which: 1}; 
     100        handler.move(evt); 
     101        t.eq(handler.feature.geometry.getBounds().toBBOX(), 
     102             "-35.15625,-35.15625,35.15625,35.15625", 
     103             "correct bounds after move"); 
     104        t.eq(handler.feature.geometry.components[0].components.length, 41, 
     105             "geometry has correct numbre of components"); 
     106        t.eq(handler.feature.geometry.CLASS_NAME, 
     107             "OpenLayers.Geometry.Polygon", 
     108             "geometry is a polygon"); 
     109        t.eq(handler.radius, 25*1.40625, "feature radius as set on handler"); 
     110        var evt = {xy: new OpenLayers.Pixel(175, 80), which: 1}; 
     111        handler.move(evt); 
     112        t.eq(handler.feature.geometry.getBounds().toBBOX(), 
     113             "-35.823348,-35.823348,35.823348,35.823348", 
     114             "correct bounds after move with fixed radius"); 
     115        handler.cancel(); 
     116        handler.setOptions({radius:1}); 
     117        var evt = {xy: new OpenLayers.Pixel(150, 75), which: 1}; 
     118        handler.down(evt); 
     119         
     120        t.eq(handler.feature.geometry.getBounds().toBBOX(), 
     121             "-0.996917,-0.996917,0.996917,0.996917", 
     122             "bounds with manual radius setting"); 
     123        var evt = {xy: new OpenLayers.Pixel(175, 80), which: 1}; 
     124        handler.move(evt); 
     125        t.eq(handler.feature.geometry.getBounds().toBBOX(), 
     126             "34.159333,-8.028167,36.153167,-6.034333", 
     127             "bounds with manual radius setting and mousemove"); 
     128    }      
     129 
     130  </script> 
     131</head> 
     132<body> 
     133    <div id="map" style="width: 300px; height: 150px;"/> 
     134</body> 
     135</html> 
  • tests/list-tests.html

    old new  
    8080    <li>Handler/test_Point.html</li> 
    8181    <li>Handler/test_Path.html</li> 
    8282    <li>Handler/test_Polygon.html</li> 
     83    <li>Handler/test_RegularPolygon.html</li> 
    8384    <li>test_Map.html</li> 
    8485</ul> 
  • lib/OpenLayers/Geometry/Polygon.js

    old new  
    5959 
    6060    CLASS_NAME: "OpenLayers.Geometry.Polygon" 
    6161}); 
     62 
     63/** 
     64 * APIMethod: createRegularPolygon 
     65 * Create a regular polygon around a radius. Useful for creating circles  
     66 * and the like. 
     67 * 
     68 * Parameters: 
     69 * origin - {<OpenLayers.Geometry.Point>} center of polygon. 
     70 * radius - {Float} distance to vertex, in map units. 
     71 * sides - {Integer} Number of sides. 20 approximates a circle. 
     72 * rotation - {Float} original angle of rotation, in degrees. 
     73 */ 
     74OpenLayers.Geometry.Polygon.createRegularPolygon = function(origin, radius, sides, rotation) {   
     75    var angle = Math.PI * ((1/sides) - (1/2)); 
     76    if(rotation) { 
     77        angle += (rotation / 180) * Math.PI; 
     78    } 
     79    var rotateAngle, x, y; 
     80    var points = []; 
     81    for(var i=0; i<sides; ++i) { 
     82        rotatedAngle = angle + (i * 2 * Math.PI / sides); 
     83        x = origin.x + (radius * Math.cos(rotatedAngle)); 
     84        y = origin.y + (radius * Math.sin(rotatedAngle)); 
     85        points.push(new OpenLayers.Geometry.Point(x, y)); 
     86    } 
     87    var ring = new OpenLayers.Geometry.LinearRing(points); 
     88    return new OpenLayers.Geometry.Polygon([ring]); 
     89} 
  • lib/OpenLayers/Handler/RegularPolygon.js

    old new  
     1/* Copyright (c) 2006 MetaCarta, Inc., published under a modified BSD license. 
     2 * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt  
     3 * for the full text of the license. */ 
     4 
     5 
     6/** 
     7 * @requires OpenLayers/Handler/Drag.js 
     8 *  
     9 * Class: OpenLayers.Handler.RegularPolygon 
     10 * Handler to draw a regular polygon on the map.  Polygon is displayed on mouse 
     11 *     down, moves or is modified on mouse move, and is finished on mouse up. 
     12 *     The handler triggers callbacks for 'done' and 'cancel'.  Create a new 
     13 *     instance with the <OpenLayers.Handler.RegularPolygon> constructor. 
     14 *  
     15 * Inherits from: 
     16 *  - <OpenLayers.Handler> 
     17 */ 
     18OpenLayers.Handler.RegularPolygon = OpenLayers.Class.create(); 
     19OpenLayers.Handler.RegularPolygon.prototype =  
     20  OpenLayers.Class.inherit(OpenLayers.Handler.Drag, { 
     21     
     22    /** 
     23     * APIProperty: sides 
     24     * {Integer} Number of sides for the regular polygon.  Needs to be greater 
     25     *     than 2.  Defaults to 4. 
     26     */ 
     27    sides: 4, 
     28 
     29    /** 
     30     * APIProperty: radius 
     31     * {Float} Optional radius in map units of the regular polygon.  If this is 
     32     *     set to some non-zero value, a polygon with a fixed radius will be 
     33     *     drawn and dragged with mose movements.  If this property is not 
     34     *     set, dragging changes the radius of the polygon.  Set to null by 
     35     *     default. 
     36     */ 
     37    radius: null, 
     38     
     39    /** 
     40     * APIProperty: snapAngle 
     41     * {Float} If set to a non-zero value, the handler will snap the polygon 
     42     *     rotation to multiples of the snapAngle.  Value is an angle measured 
     43     *     in degrees counterclockwise from the positive x-axis.   
     44     */ 
     45    snapAngle: null, 
     46     
     47    /** 
     48     * APIProperty: snapToggle 
     49     * {String} If set, snapToggle is checked on mouse events and will set 
     50     *     the snap mode to the opposite of what it currently is.  To disallow 
     51     *     toggling between snap and non-snap mode, set freehandToggle to 
     52     *     null.  Acceptable toggle values are 'shiftKey', 'ctrlKey', and 
     53     *     'altKey'. Snap mode is only possible if this.snapAngle is set to a 
     54     *     non-zero value. 
     55     */ 
     56    snapToggle: 'shiftKey', 
     57     
     58    /** 
     59     * APIProperty: persist 
     60     * {Boolean} Leave the feature rendered until clear is called.  Default 
     61     *     is false.  If set to true, the feature remains rendered until 
     62     *     clear is called, typically by deactivating the handler or starting 
     63     *     another drawing. 
     64     */ 
     65    persist: false, 
     66 
     67    /** 
     68     * Property: angle 
     69     * {Float} The angle from the origin (mouse down) to the current mouse 
     70     *     position, in radians.  This is measured counterclockwise from the 
     71     *     positive x-axis. 
     72     */ 
     73    angle: null, 
     74 
     75    /** 
     76     * Property: fixedRadius 
     77     * {Boolean} The polygon has a fixed radius.  True if a radius is set before 
     78     *     drawing begins.  False otherwise. 
     79     */ 
     80    fixedRadius: false, 
     81 
     82    /** 
     83     * Property: feature 
     84     * {<OpenLayers.Feature.Vector>} The currently drawn polygon feature 
     85     */ 
     86    feature: null, 
     87 
     88    /** 
     89     * Property: layer 
     90     * {<OpenLayers.Layer.Vector>} The temporary drawing layer 
     91     */ 
     92    layer: null, 
     93 
     94    /** 
     95     * Property: origin 
     96     * {<OpenLayers.Geometry.Point>} Location of the first mouse down 
     97     */ 
     98    origin: null, 
     99 
     100    /** 
     101     * Constructor: OpenLayers.Handler.RegularPolygon 
     102     * Create a new regular polygon handler. 
     103     * 
     104     * Parameters: 
     105     * control - {<OpenLayers.Control>} The control that owns this handler 
     106     * callbacks - {Array} An object with a 'done' property whos value is a 
     107     *     function to be called when the polygon drawing is finished. 
     108     *     The callback should expect to recieve a single argument, 
     109     *     the polygon geometry.  If the callbacks object contains a 
     110     *     'cancel' property, this function will be called when the 
     111     *     handler is deactivated while drawing.  The cancel should 
     112     *     expect to receive a geometry. 
     113     * options - {Object} An object with properties to be set on the handler. 
     114     *     If the options.sides property is not specified, the number of sides 
     115     *     will default to 4. 
     116     */ 
     117    initialize: function(control, callbacks, options) { 
     118        this.style = OpenLayers.Util.extend(OpenLayers.Feature.Vector.style['default'], {}); 
     119 
     120        OpenLayers.Handler.prototype.initialize.apply(this, 
     121                                                [control, callbacks, options]); 
     122        this.options = (options) ? options : new Object(); 
     123    }, 
     124     
     125    /** 
     126     * APIMethod: setOptions 
     127     *  
     128     * Parameters: 
     129     * newOptions - {Object}  
     130     */ 
     131    setOptions: function (newOptions) { 
     132        OpenLayers.Util.extend(this.options, newOptions); 
     133        OpenLayers.Util.extend(this, newOptions); 
     134    }, 
     135     
     136    /** 
     137     * APIMethod: activate 
     138     * Turn on the handler. 
     139     * 
     140     * Return: 
     141     * {Boolean} The handler was successfully activated 
     142     */ 
     143    activate: function() { 
     144        var activated = false; 
     145        if(OpenLayers.Handler.prototype.activate.apply(this, arguments)) { 
     146            // create temporary vector layer for rendering geometry sketch 
     147            var options = {displayInLayerSwitcher: false}; 
     148            this.layer = new OpenLayers.Layer.Vector(this.CLASS_NAME, options); 
     149            this.map.addLayer(this.layer); 
     150            activated = true; 
     151        } 
     152        return activated; 
     153    }, 
     154 
     155    /** 
     156     * APIMethod: deactivate 
     157     * Turn off the handler. 
     158     * 
     159     * Return: 
     160     * {Boolean} The handler was successfully deactivated 
     161     */ 
     162    deactivate: function() { 
     163        var deactivated = false; 
     164        if(OpenLayers.Handler.Drag.prototype.deactivate.apply(this, arguments)) { 
     165            // call the cancel callback if mid-drawing 
     166            if(this.dragging) { 
     167                this.cancel(); 
     168            } 
     169            this.map.removeLayer(this.layer, false); 
     170            this.layer.destroy(); 
     171            if (this.feature) { 
     172                this.feature.destroy(); 
     173            }     
     174            deactivated = true; 
     175        } 
     176        return deactivated; 
     177    }, 
     178     
     179    /** 
     180     * Method: downFeature 
     181     * Start drawing a new feature 
     182     * 
     183     * Parameters: 
     184     * evt - {Event} The drag start event 
     185     */ 
     186    down: function(evt) { 
     187        this.fixedRadius = !!(this.radius); 
     188        var maploc = this.map.getLonLatFromPixel(evt.xy); 
     189        this.origin = new OpenLayers.Geometry.Point(maploc.lon, maploc.lat); 
     190        // create the new polygon 
     191        if(!this.fixedRadius) { 
     192            // smallest radius should not be less one pixel in map units 
     193            // VML doesn't behave well with smaller 
     194            this.radius = this.map.getResolution(); 
     195        } 
     196        if(this.persist) { 
     197            this.clear(); 
     198        } 
     199        this.feature = new OpenLayers.Feature.Vector(); 
     200        this.createGeometry(); 
     201        this.layer.addFeatures([this.feature]); 
     202        this.layer.drawFeature(this.feature, this.style); 
     203    }, 
     204     
     205    /** 
     206     * Method: move 
     207     * Respond to drag move events 
     208     * 
     209     * Parameters: 
     210     * evt - {Evt} The move event 
     211     */ 
     212    move: function(evt) { 
     213        var maploc = this.map.getLonLatFromPixel(evt.xy); 
     214        var point = new OpenLayers.Geometry.Point(maploc.lon, maploc.lat); 
     215        if(this.fixedRadius) { 
     216            this.origin = point; 
     217        } else { 
     218            this.calculateAngle(point, evt); 
     219            this.radius = Math.max(this.map.getResolution() / 2, 
     220                                   point.distanceTo(this.origin)); 
     221        } 
     222        this.modifyGeometry(); 
     223        this.layer.drawFeature(this.feature, this.style); 
     224    }, 
     225 
     226    /** 
     227     * Method: up 
     228     * Finish drawing the feature 
     229     * 
     230     * Parameters: 
     231     * evt - {Event} The mouse up event 
     232     */ 
     233    up: function(evt) { 
     234        this.finalize(); 
     235    }, 
     236 
     237    /** 
     238     * Method: out 
     239     * Finish drawing the feature. 
     240     * 
     241     * Parameters: 
     242     * evt - {Event} The mouse out event 
     243     */ 
     244    out: function(evt) { 
     245        this.finalize(); 
     246    }, 
     247 
     248    /** 
     249     * Method: createGeometry 
     250     * Create the new polygon geometry.  This is called at the start of the 
     251     *     drag and at any point during the drag if the number of sides 
     252     *     changes. 
     253     */ 
     254    createGeometry: function() { 
     255        this.angle = Math.PI * ((1/this.sides) - (1/2)); 
     256        if(this.snapAngle) { 
     257            this.angle += this.snapAngle * (Math.PI / 180); 
     258        } 
     259        this.feature.geometry = OpenLayers.Geometry.Polygon.createRegularPolygon( 
     260            this.origin, this.radius, this.sides, this.snapAngle 
     261        ); 
     262    }, 
     263     
     264    /** 
     265     * Method: modifyGeometry 
     266     * Modify the polygon geometry in place. 
     267     */ 
     268    modifyGeometry: function() { 
     269        var angle, dx, dy, point; 
     270        var ring = this.feature.geometry.components[0]; 
     271        // if the number of sides ever changes, create a new geometry 
     272        if(ring.components.length != (this.sides + 1)) { 
     273            this.createGeometry(); 
     274        } 
     275        for(var i=0; i<this.sides; ++i) { 
     276            point = ring.components[i]; 
     277            angle = this.angle + (i * 2 * Math.PI / this.sides); 
     278            point.x = this.origin.x + (this.radius * Math.cos(angle)); 
     279            point.y = this.origin.y + (this.radius * Math.sin(angle)); 
     280            point.clearBounds(); 
     281        } 
     282    }, 
     283     
     284    /** 
     285     * Method: calculateAngle 
     286     * Calculate the angle based on settings. 
     287     * 
     288     * Parameters: 
     289     * point - {OpenLayers.Geometry.Point} 
     290     * evt - {Event} 
     291     */ 
     292    calculateAngle: function(point, evt) { 
     293        var alpha = Math.atan2(point.y - this.origin.y, 
     294                               point.x - this.origin.x); 
     295        if(this.snapAngle && (this.snapToggle && !evt[this.snapToggle])) { 
     296            var snapAngleRad = (Math.PI / 180) * this.snapAngle; 
     297            this.angle = Math.round(alpha / snapAngleRad) * snapAngleRad; 
     298        } else { 
     299            this.angle = alpha; 
     300        } 
     301    }, 
     302 
     303    /** 
     304     * APIMethod: cancel 
     305     * Finish the geometry and call the "cancel" callback. 
     306     */ 
     307    cancel: function() { 
     308        // the polygon geometry gets cloned in the callback method 
     309        this.callback("cancel", null); 
     310        this.finalize(); 
     311    }, 
     312 
     313    /** 
     314     * Method: finalize 
     315     * Finish the geometry and call the "done" callback. 
     316     */ 
     317    finalize: function() { 
     318        this.origin = null; 
     319        this.radius = this.options.radius; 
     320    }, 
     321 
     322    /** 
     323     * APIMethod: clear 
     324     * Clear any rendered features on the temporary layer.  This is called 
     325     *     when the handler is deactivated, canceled, or done (unless persist 
     326     *     is true). 
     327     */ 
     328    clear: function() { 
     329        this.layer.renderer.clear(); 
     330        this.layer.destroyFeatures(); 
     331    }, 
     332     
     333    /** 
     334     * Method: callback 
     335     * Trigger the control's named callback with the given arguments 
     336     * 
     337     * Parameters: 
     338     * name - {String} The key for the callback that is one of the properties 
     339     *     of the handler's callbacks object. 
     340     * args - {Array} An array of arguments with which to call the callback 
     341     *     (defined by the control). 
     342     */ 
     343    callback: function (name, args) { 
     344        // override the callback method to always send the polygon geometry 
     345        if (this.callbacks[name]) { 
     346            this.callbacks[name].apply(this.control, 
     347                                       [this.feature.geometry.clone()]); 
     348        } 
     349        // since sketch features are added to the temporary layer 
     350        // they must be cleared here if done or cancel 
     351        if(!this.persist && (name == "done" || name == "cancel")) { 
     352            this.clear(); 
     353        } 
     354    }, 
     355 
     356    /** @final @type String */ 
     357    CLASS_NAME: "OpenLayers.Handler.RegularPolygon" 
     358}); 
  • lib/OpenLayers.js

    old new  
    119119            "OpenLayers/Handler/Polygon.js", 
    120120            "OpenLayers/Handler/Feature.js", 
    121121            "OpenLayers/Handler/Drag.js", 
     122            "OpenLayers/Handler/RegularPolygon.js", 
    122123            "OpenLayers/Handler/Box.js", 
    123124            "OpenLayers/Handler/MouseWheel.js", 
    124125            "OpenLayers/Handler/Keyboard.js", 
  • examples/regular-polygons.html

    old new  
     1<html xmlns="http://www.w3.org/1999/xhtml"> 
     2  <head> 
     3    <title>OpenLayers Regular Polygon Example</title> 
     4    <style type="text/css"> 
     5        html, body { 
     6            margin: 0; 
     7            padding: 1em; 
     8            font: 0.9em Verdana, Arial, sans serif; 
     9        } 
     10        input, select, textarea { 
     11            font: 1em Verdana, Arial, sans serif; 
     12        } 
     13        #map { 
     14            width: 512px; 
     15            height: 350px; 
     16            border: 1px solid gray; 
     17        } 
     18        p { 
     19            width: 512px; 
     20        } 
     21        #config { 
     22            margin-top: 1em; 
     23            width: 512px; 
     24            position: relative; 
     25            height: 8em; 
     26        } 
     27        #controls { 
     28            padding-left: 2em; 
     29            margin-left: 0; 
     30            width: 12em; 
     31        } 
     32        #controls li { 
     33            padding-top: 0.5em; 
     34            list-style: none; 
     35        } 
     36        #options { 
     37            font-size: 1em; 
     38            top: 0; 
     39            margin-left: 15em; 
     40            position: absolute; 
     41        } 
     42    </style> 
     43    <script src="../lib/OpenLayers.js"></script> 
     44    <script type="text/javascript"> 
     45        <!-- 
     46        var map, polygonControl; 
     47        OpenLayers.Util.onImageLoadErrorColor = "transparent"; 
     48        function init(){ 
     49            map = new OpenLayers.Map('map'); 
     50             
     51            var wmsLayer = new OpenLayers.Layer.WMS( "OpenLayers WMS",  
     52                "http://labs.metacarta.com/wms/vmap0?", {layers: 'basic'});  
     53 
     54            var polygonLayer = new OpenLayers.Layer.Vector("Polygon Layer"); 
     55 
     56            map.addLayers([wmsLayer, polygonLayer]); 
     57            map.addControl(new OpenLayers.Control.LayerSwitcher()); 
     58            map.addControl(new OpenLayers.Control.MousePosition()); 
     59 
     60            polyOptions = {sides: 4}; 
     61            polygonControl = new OpenLayers.Control.DrawFeature(polygonLayer, 
     62                                            OpenLayers.Handler.RegularPolygon, 
     63                                            {handlerOptions: polyOptions}); 
     64             
     65            map.addControl(polygonControl); 
     66             
     67            map.setCenter(new OpenLayers.LonLat(0, 0), 3); 
     68             
     69            document.getElementById('noneToggle').checked = true; 
     70        } 
     71        function setOptions(options) { 
     72            polygonControl.handler.setOptions(options); 
     73        } 
     74        function setSize(fraction) { 
     75            var radius = fraction * map.getExtent().getHeight(); 
     76            polygonControl.handler.setOptions({radius: radius, 
     77                                               angle: 0}); 
     78        } 
     79        // --> 
     80    </script> 
     81  </head> 
     82  <body onload="init()"> 
     83    <h2>OpenLayers Regular Polygon Example</h2> 
     84    <div id="map"></div> 
     85    <div id="config"> 
     86         
     87        <ul id="controls"><b>Map Controls</b> 
     88            <li> 
     89                <input type="radio" name="type" 
     90                       value="none" id="noneToggle" 
     91                       onclick="polygonControl.deactivate()" 
     92                       checked="checked" /> 
     93                <label for="noneToggle">navigate</label> 
     94            </li> 
     95            <li> 
     96                <input type="radio" name="type" 
     97                       value="polygon" id="polygonToggle" 
     98                       onclick="polygonControl.activate()" /> 
     99                <label for="polygonToggle">draw polygon</label> 
     100            </li> 
     101        </ul> 
     102        <table id="options"> 
     103            <tbody> 
     104                <tr> 
     105                    <th>Draw Option</th> 
     106                    <th>Value</th> 
     107                </tr> 
     108                <tr> 
     109                    <td> 
     110                        shape 
     111                    </td> 
     112                    <td> 
     113                        <select name="sides" 
     114                                onchange="setOptions({sides: parseInt(this.value)})"> 
     115                            <option value="3">triangle</option> 
     116                            <option value="4" selected="selected">square</option> 
     117                            <option value="5">pentagon</option> 
     118                            <option value="6">hexagon</option> 
     119                            <option value="40">circle</option> 
     120                        </select> 
     121                    </td> 
     122                </tr> 
     123                <tr> 
     124                    <td> 
     125                        snap angle 
     126                    </td> 
     127                    <td> 
     128                        <select name="angle" 
     129                                onchange="setOptions({snapAngle: parseFloat(this.value)})"> 
     130                            <option value="" selected="selected">no snap</option> 
     131                            <option value="15">15&deg;</option> 
     132                            <option value="45">45&deg;</option> 
     133                            <option value="90">90&deg;</option> 
     134                        </select> 
     135                    </td> 
     136                </tr> 
     137                <tr> 
     138                    <td> 
     139                        size 
     140                    </td> 
     141                    <td> 
     142                        <select name="size" 
     143                                onchange="setSize(parseFloat(this.value))"> 
     144                            <option value="" selected="selected">variable</option> 
     145                            <option value="0.1">small</option> 
     146                            <option value="0.2">medium</option> 
     147                            <option value="0.4">large</option> 
     148                        </select> 
     149                    </td> 
     150                </tr> 
     151            </tbody> 
     152        </table> 
     153    </div> 
     154    <p> 
     155        Regular polygons can be drawn by pointing a DrawFeature control to the 
     156        RegularPolygon handler class.  The options above demonstrate how the 
     157        handler can be configured.  Note if you are in angle snapping mode (if 
     158        the snap angle is non-null) and you hold down the <b>Shift</b> key, you 
     159        will toggle to non-snapping mode. 
     160    </p> 
     161  </body> 
     162</html>