OpenLayers OpenLayers

Ticket #638: dragFeature.patch

File dragFeature.patch, 20.3 kB (added by tschaub, 1 year ago)

let features be dragged

  • tests/Control/test_DragFeature.html

    old new  
     1<html> 
     2<head> 
     3    <script src="../../lib/OpenLayers.js"></script> 
     4    <script type="text/javascript"> 
     5    function test_Control_DragFeature_constructor(t) { 
     6        t.plan(3); 
     7         
     8        var options = { 
     9            geometryTypes: "foo" 
     10        }; 
     11        var layer = "bar"; 
     12        var control = new OpenLayers.Control.DragFeature(layer, options); 
     13        t.ok(control instanceof OpenLayers.Control.DragFeature, 
     14             "new OpenLayers.Control.DragFeature returns an instance"); 
     15        t.eq(control.layer, "bar", 
     16             "constructor sets layer correctly");         
     17        t.eq(control.featureHandler.geometryTypes, "foo", 
     18             "constructor sets options correctly on feature handler"); 
     19    } 
     20     
     21    function test_Control_DragFeature_destroy(t) { 
     22        t.plan(2); 
     23        var map = new OpenLayers.Map("map"); 
     24        var layer = new OpenLayers.Layer.Vector(); 
     25        map.addLayer(layer); 
     26        var control = new OpenLayers.Control.DragFeature(layer); 
     27        control.dragHandler.destroy = function() { 
     28            t.ok(true, 
     29                 "control.destroy calls destroy on drag handler"); 
     30        } 
     31        control.featureHandler.destroy = function() { 
     32            t.ok(true, 
     33                 "control.destroy calls destroy on feature handler"); 
     34        } 
     35        control.destroy(); 
     36         
     37    } 
     38     
     39    function test_Control_DragFeature_activate(t) { 
     40        t.plan(2); 
     41        var map = new OpenLayers.Map("map"); 
     42        var layer = new OpenLayers.Layer.Vector(); 
     43        map.addLayer(layer); 
     44        var control = new OpenLayers.Control.DragFeature(layer); 
     45        map.addControl(control); 
     46        t.ok(!control.featureHandler.active, 
     47             "feature handler is not active prior to activating control"); 
     48        control.activate(); 
     49        t.ok(control.featureHandler.active, 
     50             "feature handler is active after activating control"); 
     51    } 
     52 
     53    function test_Control_DragFeature_deactivate(t) { 
     54        t.plan(2); 
     55        var map = new OpenLayers.Map("map"); 
     56        var layer = new OpenLayers.Layer.Vector(); 
     57        map.addLayer(layer); 
     58        var control = new OpenLayers.Control.DragFeature(layer); 
     59        map.addControl(control); 
     60         
     61        control.dragHandler.deactivate = function() { 
     62            t.ok(true, 
     63                 "control.deactivate calls deactivate on drag handler"); 
     64        } 
     65        control.featureHandler.deactivate = function() { 
     66            t.ok(true, 
     67                 "control.deactivate calls deactivate on feature handler"); 
     68        } 
     69        control.deactivate(); 
     70    } 
     71     
     72    function test_Control_DragFeature_over(t) { 
     73        t.plan(3); 
     74        var map = new OpenLayers.Map("map"); 
     75        var layer = new OpenLayers.Layer.Vector(); 
     76        map.addLayer(layer); 
     77        var control = new OpenLayers.Control.DragFeature(layer); 
     78        map.addControl(control); 
     79         
     80        control.activate(); 
     81        t.ok(!control.dragHandler.active, 
     82             "drag handler is not active before over a feature"); 
     83         
     84        // simulate a mouseover on a feature 
     85        layer.getFeatureFromEvent = function(evt) { 
     86            return "foo"; 
     87        } 
     88        map.events.triggerEvent("mousemove"); 
     89         
     90        t.eq(control.feature, "foo", 
     91             "control gets the proper feature from the feature handler"); 
     92        t.ok(control.dragHandler.active, 
     93             "drag handler activated when over a feature"); 
     94    } 
     95 
     96    function test_Control_DragFeature_down(t) { 
     97        t.plan(3); 
     98        var map = new OpenLayers.Map("map"); 
     99        var layer = new OpenLayers.Layer.Vector(); 
     100        map.addLayer(layer); 
     101        var control = new OpenLayers.Control.DragFeature(layer); 
     102        map.addControl(control); 
     103         
     104        control.activate(); 
     105         
     106        // simulate a mouseover on a feature 
     107        layer.getFeatureFromEvent = function(evt) { 
     108            return "foo"; 
     109        } 
     110        map.events.triggerEvent("mousemove"); 
     111 
     112        t.ok(!control.dragHandler.dragging, 
     113             "control is not dragging before the mousedown"); 
     114         
     115        // simulate a mousedown on a feature 
     116        map.events.triggerEvent("mousedown", {xy: "bar", which: 1}); 
     117 
     118        t.ok(control.dragHandler.dragging, 
     119             "drag is dragging after the mousedown"); 
     120        t.eq(control.lastPixel, "bar", 
     121             "mousedown sets the lastPixel correctly"); 
     122    } 
     123 
     124    function test_Control_DragFeature_move(t) { 
     125        t.plan(3); 
     126        var map = new OpenLayers.Map("map"); 
     127        var layer = new OpenLayers.Layer.Vector(); 
     128        map.addLayer(layer); 
     129        var control = new OpenLayers.Control.DragFeature(layer); 
     130        map.addControl(control); 
     131        map.getResolution = function() { 
     132            return 2; 
     133        } 
     134 
     135        control.activate(); 
     136 
     137        // mock up a feature - for the sole purpose of testing mousemove 
     138        var uid = Math.random(); 
     139        layer.getFeatureFromEvent = function() { 
     140            var geom = new OpenLayers.Geometry.Point(Math.random(), 
     141                                                     Math.random()); 
     142            geom.move = function(x, y) { 
     143                t.eq(x, 2, "move called with dx * res"); 
     144                t.eq(y, -4, "move called with -dy * res"); 
     145            }; 
     146            var feature = new OpenLayers.Feature.Vector(geom); 
     147            feature.uid = uid; 
     148            return feature; 
     149        }; 
     150        layer.drawFeature = function(feature) { 
     151            t.eq(feature.uid, uid, 
     152                 "layer.drawFeature called with correct feature"); 
     153        }; 
     154 
     155        // simulate a mouseover on a feature 
     156        map.events.triggerEvent("mousemove"); 
     157 
     158        // simulate a mousedown on a feature 
     159        var down = new OpenLayers.Pixel(0, 0); 
     160        map.events.triggerEvent("mousedown", {xy: down, which: 1}); 
     161 
     162        // simulate a mousemove on a feature 
     163        var move = new OpenLayers.Pixel(1, 2); 
     164        map.events.triggerEvent("mousemove", {xy: move, which: 1}); 
     165         
     166    } 
     167 
     168    </script> 
     169</head> 
     170<body> 
     171    <div id="map" style="width: 400px; height: 250px;"/> 
     172</body> 
     173</html> 
  • tests/list-tests.html

    old new  
    5858    <li>test_Tile.html</li> 
    5959    <li>Tile/test_Image.html</li> 
    6060    <li>test_Control.html</li> 
     61    <li>Control/test_DragFeature.html</li> 
    6162    <li>Control/test_DragPan.html</li> 
    6263    <li>Control/test_OverviewMap.html</li> 
    6364    <li>Control/test_NavToolbar.html</li> 
  • lib/OpenLayers/Control/DragFeature.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/Control.js 
     8 * @requires OpenLayers/Handler/Drag.js 
     9 * @requires OpenLayers/Handler/Feature.js 
     10 *  
     11 * Class: OpenLayers.Control.DragFeature 
     12 * Move a feature with a drag.  Create a new control with the 
     13 *     <OpenLayers.Control.DragFeature> constructor. 
     14 * 
     15 * Inherits From: 
     16 *  - <OpenLayers.Control> 
     17 */ 
     18OpenLayers.Control.DragFeature = OpenLayers.Class(OpenLayers.Control, { 
     19 
     20    /** 
     21     * APIProperty: geometryTypes 
     22     * {Array(String)} To restrict dragging to a limited set of geometry types, 
     23     *     send a list of strings corresponding to the geometry class names. 
     24     */ 
     25    geometryTypes: null, 
     26     
     27    /** 
     28     * APIProperty: onDrag 
     29     * {Function} Define this function if you want to know about each move of a 
     30     *     feature. The function should expect to receive two arguments: the 
     31     *     feature that is being dragged and the pixel location of the mouse. 
     32     * 
     33     * Parameters: 
     34     * feature - {OpenLayers.Feature.Vector} The feature that was dragged. 
     35     * pixel - {OpenLayers.Pixel} The pixel location of the mouse. 
     36     */ 
     37    onDrag: function(feature, pixel) {}, 
     38 
     39    /** 
     40     * APIProperty: onComplete 
     41     * {Function} Define this function if you want to know when a feature is 
     42     *     done dragging. The function should expect to receive two arguments: 
     43     *     the feature that is being dragged and the pixel location of the 
     44     *     mouse. 
     45     * 
     46     * Parameters: 
     47     * feature - {OpenLayers.Feature.Vector} The feature that was dragged. 
     48     * pixel - {OpenLayers.Pixel} The pixel location of the mouse. 
     49     */ 
     50    onComplete: function(feature, pixel) {}, 
     51 
     52    /** 
     53     * Property: layer 
     54     * {OpenLayers.Layer.Vector} 
     55     */ 
     56    layer: null, 
     57     
     58    /** 
     59     * Property: feature 
     60     * {OpenLayers.Feature.Vector} 
     61     */ 
     62    feature: null, 
     63 
     64    /** 
     65     * Property: dragHandler 
     66     * {OpenLayers.Handler.Drag} 
     67     */ 
     68    dragHandler: null, 
     69 
     70    /** 
     71     * Property: dragCallbacks 
     72     * {Object} The functions that are sent to the drag handler for callback. 
     73     */ 
     74    dragCallbacks: {}, 
     75 
     76    /** 
     77     * Property: featureHandler 
     78     * {OpenLayers.Handler.Feature} 
     79     */ 
     80    featureHandler: null, 
     81 
     82    /** 
     83     * Property: featureCallbacks 
     84     * {Object} The functions that are sent to the feature handler for callback. 
     85     */ 
     86    featureCallbacks: {}, 
     87     
     88    /** 
     89     * Property: lastPixel 
     90     * {OpenLayers.Pixel} 
     91     */ 
     92    lastPixel: null, 
     93 
     94    /** 
     95     * Constructor: OpenLayers.Control.DragFeature 
     96     * Create a new control to drag features. 
     97     * 
     98     * Parameters: 
     99     * layer - {OpenLayers.Layer.Vector} The layer containing features to be 
     100     *     dragged. 
     101     * options - {Object} Optional object whose properties will be set on the 
     102     *     control. 
     103     */ 
     104    initialize: function(layer, options) { 
     105        OpenLayers.Control.prototype.initialize.apply(this, [options]); 
     106        this.layer = layer; 
     107        this.dragCallbacks = OpenLayers.Util.extend({down: this.downFeature, 
     108                                                     move: this.moveFeature, 
     109                                                     up: this.upFeature, 
     110                                                     out: this.cancel, 
     111                                                     done: this.doneDragging 
     112                                                    }, this.dragCallbacks); 
     113        this.dragHandler = new OpenLayers.Handler.Drag(this, this.dragCallbacks); 
     114        this.featureCallbacks = OpenLayers.Util.extend({over: this.overFeature, 
     115                                                        out: this.outFeature 
     116                                                       }, this.featureCallbacks); 
     117        var handlerOptions = {geometryTypes: this.geometryTypes}; 
     118        this.featureHandler = new OpenLayers.Handler.Feature(this, this.layer, 
     119                                                        this.featureCallbacks, 
     120                                                        handlerOptions); 
     121    }, 
     122     
     123    /** 
     124     * APIMethod: destroy 
     125     * Take care of things that are not handled in superclass 
     126     */ 
     127    destroy: function() { 
     128        this.layer = null; 
     129        this.dragHandler.destroy(); 
     130        this.featureHandler.destroy(); 
     131        OpenLayers.Control.prototype.destroy.apply(this, []); 
     132    }, 
     133 
     134    /** 
     135     * APIMethod: activate 
     136     * Activate the control and the feature handler. 
     137     *  
     138     * Returns: 
     139     * {Boolean} Successfully activated the control and feature handler. 
     140     */ 
     141    activate: function() { 
     142        return (this.featureHandler.activate() && 
     143                OpenLayers.Control.prototype.activate.apply(this, arguments)); 
     144    }, 
     145 
     146    /** 
     147     * APIMethod: deactivate 
     148     * Deactivate the control and all handlers. 
     149     *  
     150     * Returns: 
     151     * {Boolean} Successfully deactivated the control. 
     152     */ 
     153    deactivate: function() { 
     154        // the return from the handlers is unimportant in this case 
     155        this.dragHandler.deactivate(); 
     156        this.featureHandler.deactivate(); 
     157        return OpenLayers.Control.prototype.deactivate.apply(this, arguments); 
     158    }, 
     159 
     160    /** 
     161     * Method: overFeature 
     162     * Called when the feature handler detects a mouse-over on a feature. 
     163     *     This activates the drag handler. 
     164     * 
     165     * Parameters: 
     166     * feature - {OpenLayers.Feature.Vector} The selected feature. 
     167     */ 
     168    overFeature: function(feature) { 
     169        if(!this.dragHandler.dragging) { 
     170            this.feature = feature; 
     171            this.dragHandler.activate(); 
     172            this.over = true; 
     173            // TBD replace with CSS classes 
     174            this.map.div.style.cursor = "move"; 
     175        } else { 
     176            if(this.feature.id == feature.id) { 
     177                this.over = true; 
     178            } else { 
     179                this.over = false; 
     180            } 
     181        } 
     182    }, 
     183 
     184    /** 
     185     * Method: downFeature 
     186     * Called when the drag handler detects a mouse-down. 
     187     * 
     188     * Parameters: 
     189     * pixel - {OpenLayers.Pixel} Location of the mouse event. 
     190     */ 
     191    downFeature: function(pixel) { 
     192        this.dragHandler.dragging = true; 
     193        this.lastPixel = pixel; 
     194    }, 
     195 
     196    /** 
     197     * Method: moveFeature 
     198     * Called when the drag handler detects a mouse-move.  Also calls the 
     199     *     optional onDrag method. 
     200     *  
     201     * Parameters: 
     202     * pixel - {OpenLayers.Pixel} Location of the mouse event. 
     203     */ 
     204    moveFeature: function(pixel) { 
     205        var res = this.map.getResolution(); 
     206        this.feature.geometry.move(res * (pixel.x - this.lastPixel.x), 
     207                                   res * (this.lastPixel.y - pixel.y)); 
     208        this.layer.drawFeature(this.feature); 
     209        this.lastPixel = pixel; 
     210        this.onDrag(this.feature, pixel); 
     211    }, 
     212 
     213    /** 
     214     * Method: upFeature 
     215     * Called when the drag handler detects a mouse-up.  Also calls the 
     216     *     optional onComplete method. 
     217     *  
     218     * Parameters: 
     219     * pixel - {OpenLayers.Pixel} Location of the mouse event. 
     220     */ 
     221    upFeature: function(pixel) { 
     222        if(!this.over) { 
     223            this.dragHandler.deactivate(); 
     224            this.feature = null; 
     225            // TBD replace with CSS classes 
     226            this.map.div.style.cursor = "default"; 
     227        } 
     228    }, 
     229 
     230    /** 
     231     * Method: doneDragging 
     232     * Called when the drag handler is done dragging. 
     233     * 
     234     * Parameters: 
     235     * pixel - {OpenLayers.Pixel} The last event pixel location.  If this event 
     236     *     came from a mouseout, this may not be in the map viewport. 
     237     */ 
     238    doneDragging: function(pixel) { 
     239        this.onComplete(this.feature, pixel); 
     240    }, 
     241 
     242    /** 
     243     * Method: outFeature 
     244     * Called when the feature handler detects a mouse-out on a feature. 
     245     * 
     246     * Parameters: 
     247     * feature - {OpenLayers.Feature.Vector} The feature that the mouse left. 
     248     */ 
     249    outFeature: function(feature) { 
     250        if(!this.dragHandler.dragging) { 
     251            this.over = false; 
     252            this.dragHandler.deactivate(); 
     253            // TBD replace with CSS classes 
     254            this.map.div.style.cursor = "default"; 
     255        } else { 
     256            if(this.feature.id == feature.id) { 
     257                this.over = false; 
     258            } 
     259        } 
     260    }, 
     261         
     262    /** 
     263     * Method: cancel 
     264     * Called when the drag handler detects a mouse-out (from the map viewport). 
     265     */ 
     266    cancel: function() { 
     267        this.dragHandler.deactivate(); 
     268        this.over = false; 
     269    }, 
     270 
     271    /** 
     272     * Method: setMap 
     273     * Set the map property for the control and all handlers. 
     274     * 
     275     * Parameters:  
     276     * map - {OpenLayers.Map} The control's map. 
     277     */ 
     278    setMap: function(map) { 
     279        this.dragHandler.setMap(map); 
     280        this.featureHandler.setMap(map); 
     281        OpenLayers.Control.prototype.setMap.apply(this, arguments); 
     282    }, 
     283 
     284    CLASS_NAME: "OpenLayers.Control.DragFeature" 
     285}); 
  • lib/OpenLayers.js

    old new  
    138138            "OpenLayers/Control/Scale.js", 
    139139            "OpenLayers/Control/LayerSwitcher.js", 
    140140            "OpenLayers/Control/DrawFeature.js", 
     141            "OpenLayers/Control/DragFeature.js", 
    141142            "OpenLayers/Control/Panel.js", 
    142143            "OpenLayers/Control/SelectFeature.js", 
    143144            "OpenLayers/Geometry.js", 
  • examples/drag-feature.html

    old new  
     1<html xmlns="http://www.w3.org/1999/xhtml"> 
     2  <head> 
     3    <title>Drag Feature</title> 
     4    <style type="text/css"> 
     5        #map { 
     6            width: 512px; 
     7            height: 350px; 
     8            border: 1px solid gray; 
     9        } 
     10        #controls { 
     11            width: 512px; 
     12        } 
     13        #controlToggle { 
     14            padding-left: 1em; 
     15        } 
     16        #controlToggle li { 
     17            list-style: none; 
     18        } 
     19    </style> 
     20    <script src="../lib/OpenLayers.js"></script> 
     21    <script type="text/javascript"> 
     22        <!-- 
     23        var map, vectors, controls; 
     24        function init(){ 
     25            map = new OpenLayers.Map('map'); 
     26            var wms = new OpenLayers.Layer.WMS( "OpenLayers WMS",  
     27                "http://labs.metacarta.com/wms/vmap0?", {layers: 'basic'});  
     28 
     29            vectors = new OpenLayers.Layer.Vector("Vector Layer"); 
     30 
     31            map.addLayers([wms, vectors]); 
     32            map.addControl(new OpenLayers.Control.LayerSwitcher()); 
     33            map.addControl(new OpenLayers.Control.MousePosition()); 
     34             
     35            controls = { 
     36                point: new OpenLayers.Control.DrawFeature(vectors, 
     37                            OpenLayers.Handler.Point), 
     38                line: new OpenLayers.Control.DrawFeature(vectors, 
     39                            OpenLayers.Handler.Path), 
     40                polygon: new OpenLayers.Control.DrawFeature(vectors, 
     41                            OpenLayers.Handler.Polygon), 
     42                drag: new OpenLayers.Control.DragFeature(vectors) 
     43            }; 
     44             
     45            for(var key in controls) { 
     46                map.addControl(controls[key]); 
     47            } 
     48             
     49            map.setCenter(new OpenLayers.LonLat(0, 0), 3); 
     50            document.getElementById('noneToggle').checked = true; 
     51        } 
     52 
     53        function toggleControl(element) { 
     54            for(key in controls) { 
     55                var control = controls[key]; 
     56                if(element.value == key && element.checked) { 
     57                    control.activate(); 
     58                } else { 
     59                    control.deactivate(); 
     60                } 
     61            } 
     62        } 
     63         
     64        // --> 
     65    </script> 
     66  </head> 
     67  <body onload="init()"> 
     68    <h1>OpenLayers Drag Feature Example</h1> 
     69    <div id="map"></div> 
     70    <div id="controls"> 
     71        <ul id="controlToggle"> 
     72            <li> 
     73                <input type="radio" name="type" value="none" id="noneToggle" 
     74                       onclick="toggleControl(this);" checked="checked" /> 
     75                <label for="noneToggle">navigate</label> 
     76            </li> 
     77            <li> 
     78                <input type="radio" name="type" value="point" id="pointToggle" onclick="toggleControl(this);" /> 
     79                <label for="pointToggle">draw point</label> 
     80            </li> 
     81            <li> 
     82                <input type="radio" name="type" value="line" id="lineToggle" onclick="toggleControl(this);" /> 
     83                <label for="lineToggle">draw line</label> 
     84            </li> 
     85            <li> 
     86                <input type="radio" name="type" value="polygon" id="polygonToggle" onclick="toggleControl(this);" /> 
     87                <label for="polygonToggle">draw polygon</label> 
     88            </li> 
     89            <li> 
     90                <input type="radio" name="type" value="drag" id="dragToggle" 
     91                       onclick="toggleControl(this);" /> 
     92                <label for="dragToggle">drag feature</label> 
     93            </li> 
     94        </ul> 
     95    </div> 
     96  </body> 
     97</html>