OpenLayers OpenLayers

Ticket #442: final_animatedZooming_OverviewMap.patch

File final_animatedZooming_OverviewMap.patch, 13.6 kB (added by emanuel, 3 years ago)

CverviewMap supports animated zooming and panning (included unit tests)

  • tests/Control/test_OverviewMap.html

    old new  
    33  <script src="../../lib/OpenLayers.js"></script> 
    44  <script type="text/javascript"><!-- 
    55    var map;  
    6     function test_01_Control_PanZoom_constructor (t) { 
     6    function test_01_Control_OverviewMap_constructor (t) { 
    77        t.plan( 1 ); 
    88     
    99        control = new OpenLayers.Control.OverviewMap(); 
    1010        t.ok( control instanceof OpenLayers.Control.OverviewMap, "new OpenLayers.Control.OverviewMap returns object" ); 
    1111    } 
    12     function test_02_Control_PanZoom_addControl (t) { 
     12    function test_02_Control_OverviewMap_addControl (t) { 
    1313        t.plan( 6 ); 
    1414        map = new OpenLayers.Map('map'); 
    1515        control = new OpenLayers.Control.OverviewMap(); 
     
    2323 
    2424        map.destroy(); 
    2525    } 
    26     function test_03_Control_PanZoom_control_events (t) { 
     26    function test_03_Control_OverviewMap_control_events (t) { 
    2727        t.plan( 10 ); 
    2828        var evt = {which: 1}; // control expects left-click 
    2929        map = new OpenLayers.Map('map'); 
     
    4444        t.eq(overviewCenter.lat, 42, "Overviewmap center lat correct"); 
    4545        t.eq(overviewZoom, 8, "Overviewmap zoomcorrect"); 
    4646         
    47         control.mapDivClick({'xy':new OpenLayers.Pixel(5,5)}); 
    48          
    49         var cent = map.getCenter(); 
    50         t.eq(cent.lon, -71.3515625, "Clicking on the Overview Map has the correct effect on map lon"); 
    51         t.eq(cent.lat, 42.17578125, "Clicking on the Overview Map has the correct effect on map lat"); 
     47        control.mapDivDblClick({'xy':new OpenLayers.Pixel(5,5)}); 
     48        t.delay_call( 
     49            1, function() { 
     50                var cent = map.getCenter(); 
     51                t.eq(cent.lon, -71.3515625, "Clicking on the Overview Map has the correct effect on map lon"); 
     52                t.eq(cent.lat, 42.17578125, "Clicking on the Overview Map has the correct effect on map lat"); 
    5253 
    53         control.rectMouseDown({'xy':new OpenLayers.Pixel(5,5), 'which':1}); 
    54         control.rectMouseMove({'xy':new OpenLayers.Pixel(15,15), 'which':1}); 
    55         control.rectMouseUp({'xy':new OpenLayers.Pixel(15,15), 'which':1}); 
    56          
    57         var cent = map.getCenter(); 
    58         t.eq(cent.lon, -71.2734375, "Dragging on the Overview Map has the correct effect on map lon"); 
    59         t.eq(cent.lat, 42.09765625, "Dragging on the Overview Map has the correct effect on map lat"); 
    60          
    61         map.setCenter(new OpenLayers.LonLat(0,0), 0); 
    62         var overviewCenter = control.ovmap.getCenter(); 
    63         var overviewZoom = control.ovmap.getZoom(); 
    64         t.eq(overviewCenter.lon, 0, "Overviewmap center lon correct -- second zoom"); 
    65         t.eq(overviewCenter.lat, 0, "Overviewmap center lat correct -- second zoom"); 
    66         t.eq(overviewZoom, 0, "Overviewmap zoomcorrect -- second zoom"); 
    67          
    68         map.destroy(); 
     54                control.rectMouseDown({'xy':new OpenLayers.Pixel(5,5), 'which':1}); 
     55                control.rectMouseMove({'xy':new OpenLayers.Pixel(15,15), 'which':1}); 
     56                control.rectMouseUp({'xy':new OpenLayers.Pixel(15,15), 'which':1}); 
     57            }, 
     58             
     59            1, function() { 
     60                var cent = map.getCenter(); 
     61                t.eq(cent.lon, -71.27328491210938, "Dragging on the Overview Map has the correct effect on map lon"); 
     62                t.eq(cent.lat, 42.09407043457031, "Dragging on the Overview Map has the correct effect on map lat"); 
     63                 
     64                map.setCenter(new OpenLayers.LonLat(0,0), 0); 
     65                var overviewCenter = control.ovmap.getCenter(); 
     66                var overviewZoom = control.ovmap.getZoom(); 
     67                t.eq(overviewCenter.lon, 0, "Overviewmap center lon correct -- second zoom"); 
     68                t.eq(overviewCenter.lat, 0, "Overviewmap center lat correct -- second zoom"); 
     69                t.eq(overviewZoom, 0, "Overviewmap zoomcorrect -- second zoom"); 
     70                map.destroy(); 
     71           } 
     72        ); 
     73    } 
    6974 
     75    function test_04_Control_OverviewMap_updateRectToMap (t) { 
     76        t.plan( 4 ); 
     77 
     78        map = new OpenLayers.Map('map'); 
     79        var layer = new OpenLayers.Layer.WMS("Test Layer",  
     80            "http://octo.metacarta.com/cgi-bin/mapserv?", 
     81            {map: "/mapdata/vmap_wms.map", layers: "basic"}); 
     82        map.addLayer(layer); 
     83 
     84        control = new OpenLayers.Control.OverviewMap(); 
     85        map.addControl(control, new OpenLayers.Pixel(20,20)); 
     86        map.setCenter(new OpenLayers.LonLat(0,0), 5); 
     87        control.updateRectToMap(); 
     88        t.eq(control.extentRectangle.style.left, "45px", "rectangle left position has been set correctly"); 
     89        t.eq(control.extentRectangle.style.top, "23px", "rectangle top position has been set correctly"); 
     90        t.eq(control.extentRectangle.style.width, "90px", "rectangle width position has been set correctly"); 
     91        t.eq(control.extentRectangle.style.height, "45px", "rectangle height position has been set correctly"); 
    7092    } 
     93 
     94    function test_05_Control_OverviewMap_updateMapToRect (t) { 
     95        t.plan( 4 ); 
     96 
     97        map = new OpenLayers.Map('map'); 
     98        var layer = new OpenLayers.Layer.WMS("Test Layer",  
     99            "http://octo.metacarta.com/cgi-bin/mapserv?", 
     100            {map: "/mapdata/vmap_wms.map", layers: "basic"}); 
     101        map.addLayer(layer); 
     102 
     103        control = new OpenLayers.Control.OverviewMap(); 
     104        map.addControl(control, new OpenLayers.Pixel(20,20)); 
     105        map.setCenter(new OpenLayers.LonLat(0,0), 5); 
     106        control.updateRectToMap(); 
     107        t.eq(control.extentRectangle.style.left, "45px", "rectangle left position has been set correctly"); 
     108        t.eq(control.extentRectangle.style.top, "23px", "rectangle top position has been set correctly"); 
     109        t.eq(control.extentRectangle.style.width, "90px", "rectangle width position has been set correctly"); 
     110        t.eq(control.extentRectangle.style.height, "45px", "rectangle height position has been set correctly"); 
     111    } 
     112 
    71113  // --> 
    72114  </script> 
    73115</head> 
  • lib/OpenLayers/Control/OverviewMap.js

    old new  
    119119 
    120120        this.div.appendChild(this.element); 
    121121 
    122         this.map.events.register('moveend', this, this.update); 
     122        // update overviewmap during map is panning 
     123        this.map.events.register('move', this, this.update); 
    123124         
    124         // Set up events.  The image div recenters the map on click. 
     125        // Set up events.  The image div recenters the map on doubleclick. 
    125126        // The extent rectangle can be dragged to recenter the map. 
    126127        // If the mousedown happened elsewhere, then mousemove and mouseup 
    127128        // should slip through. 
     
    143144        this.rectEvents.register('click', this, function(e) { 
    144145            OpenLayers.Event.stop(e); 
    145146        }); 
    146         this.rectEvents.register('dblclick', this, this.rectDblClick ); 
    147147        this.mapDivEvents = new OpenLayers.Events(this, this.mapDiv); 
    148         this.mapDivEvents.register('click', this, this.mapDivClick); 
     148        this.mapDivEvents.register('dblclick', this, this.mapDivDblClick); 
    149149 
    150150        // Optionally add min/max buttons if the control will go in the 
    151151        // map viewport. 
     
    283283        this.rectDragStart = null; 
    284284    }, 
    285285     
    286     /** 
    287     * @param {OpenLayers.Event} evt 
    288     */ 
    289     rectDblClick: function(evt) { 
    290         this.performedRectDrag = false; 
    291         OpenLayers.Event.stop(evt); 
    292         this.updateOverview(); 
    293     }, 
    294286 
    295287    /** 
    296288    * @param {OpenLayers.Event} evt 
    297289    */ 
    298     mapDivClick: function(evt) { 
     290    mapDivDblClick: function(evt) { 
    299291        var pxBounds = this.getRectPxBounds(); 
    300292        var pxCenter = pxBounds.getCenterPixel(); 
    301293        var deltaX = evt.xy.x - pxCenter.x; 
     
    308300        newTop = Math.min(newTop, this.ovmap.size.h - height); 
    309301        var newLeft = Math.max(0, (left + deltaX)); 
    310302        newLeft = Math.min(newLeft, this.ovmap.size.w - width); 
    311         this.setRectPxBounds(new OpenLayers.Bounds(newLeft, 
     303        pxBounds = new OpenLayers.Bounds(newLeft, 
    312304                                                   newTop + height, 
    313305                                                   newLeft + width, 
    314                                                    newTop))
    315         this.updateMapToRect(); 
     306                                                   newTop)
     307        this.updateMapToRect(pxBounds); 
    316308        OpenLayers.Event.stop(evt); 
    317309    }, 
    318310 
     
    360352        if(this.ovmap == null) { 
    361353            this.createMap(); 
    362354        } 
    363          
     355 
    364356        if(!this.isSuitableOverview()) { 
    365357            this.updateOverview(); 
    366358        } 
    367          
     359 
    368360        // update extent rectangle 
    369361        this.updateRectToMap(); 
     362 
     363        this.updateOverview(); 
    370364    }, 
    371      
     365 
    372366    /** 
    373367     * Determines if the overview map is suitable given the extent and 
    374368     * resolution of the main map. 
     
    380374                                Math.max(mapExtent.left, maxExtent.left), 
    381375                                Math.max(mapExtent.bottom, maxExtent.bottom), 
    382376                                Math.min(mapExtent.right, maxExtent.right), 
    383                                 Math.min(mapExtent.top, maxExtent.top));         
     377                                Math.min(mapExtent.top, maxExtent.top)); 
    384378        var resRatio = this.ovmap.getResolution() / this.map.getResolution(); 
    385379        return ((resRatio > this.minRatio) && 
    386380                (resRatio <= this.maxRatio) && 
    387381                (this.ovmap.getExtent().containsBounds(testExtent))); 
    388382    }, 
    389      
    390     updateOverview: function() { 
    391         var mapRes = this.map.getResolution(); 
     383 
     384    /*  
     385     * Updates the overview map. If the map is scaling (by zooming) the parameters 
     386     * define the values of the new resolution and bounds. 
     387     * 
     388     * @param {float} newResolution 
     389     * @param {OpenLayers.Bounds} bounds 
     390     */     
     391    updateOverview: function(newResolution, bounds) { 
     392        //set new map resolution only by scaling 
     393        if (newResolution) 
     394            var mapRes = newResolution; 
     395        else 
     396            var mapRes = this.map.getResolution(); 
    392397        var targetRes = this.ovmap.getResolution(); 
    393398        var resRatio = targetRes / mapRes; 
    394399        if(resRatio > this.maxRatio) { 
     
    400405        } 
    401406        this.ovmap.setCenter(this.map.center, 
    402407                            this.ovmap.getZoomForResolution(targetRes)); 
    403         this.updateRectToMap(); 
     408        this.updateRectToMap(bounds); 
    404409    }, 
    405410     
    406411    createMap: function() { 
     
    424429    }, 
    425430         
    426431    /** 
    427      * Updates the extent rectangle position and size to match the map extent 
     432     * Updates the extent rectangle position and size to match the map extent   
     433     * If the map is scaling (by zooming) the parameter defines the 
     434     * new bounds of the current map 
     435     * 
     436     * @param {OpenLayers.Bounds} bounds 
    428437     */ 
    429     updateRectToMap: function() { 
     438    updateRectToMap: function(bounds) { 
    430439        // The base layer for overview map needs to be in the same projection 
    431440        // as the base layer for the main map.  This should be made more robust. 
    432441        if(this.map.units != 'degrees') { 
     
    434443                alert('The overview map only works when it is in the same projection as the main map'); 
    435444            } 
    436445        } 
    437         var pxBounds = this.getRectBoundsFromMapBounds(this.map.getExtent()); 
     446 
     447        if (!bounds) 
     448            bounds=this.map.getExtent(); 
     449        var pxBounds = this.getRectBoundsFromMapBounds(bounds); 
    438450        if (pxBounds) { 
    439451          this.setRectPxBounds(pxBounds); 
    440452        } 
     
    443455    /** 
    444456     * Updates the map extent to match the extent rectangle position and size 
    445457     */ 
    446     updateMapToRect: function() { 
    447         var pxBounds = this.getRectPxBounds(); 
     458    updateMapToRect: function(pxBounds) { 
     459        if (!pxBounds) 
     460            var pxBounds = this.getRectPxBounds(); 
    448461        var lonLatBounds = this.getMapBoundsFromRectBounds(pxBounds); 
    449         this.map.setCenter(lonLatBounds.getCenterLonLat(), this.map.zoom); 
     462 
     463        var centerPx = this.map.getViewPortPxFromLonLat(lonLatBounds.getCenterLonLat()); 
     464 
     465        var resolution = this.map.getResolution(); 
     466         
     467        var width = lonLatBounds.getWidth(); 
     468        width = width / resolution; 
     469        var height = lonLatBounds.getHeight(); 
     470        height = height / resolution; 
     471 
     472        // pan to recenter rectangle 
     473        this.map.pan(centerPx.x-width/2,centerPx.y-height/2); 
    450474    }, 
    451475     
    452476    /** 
  • lib/OpenLayers/Map.js

    old new  
    906906        return valid; 
    907907    }, 
    908908 
     909    /** Sets the map resolution during zooming/scaling. 
     910     *  
     911     * @param {float} newResolution 
     912     */  
     913    setScaleResolution: function (newResolution) { 
     914        //calculate the current bounds of the new viewport 
     915        var newScaleBounds = this.calculateBounds(this.getCenter(), newResolution); 
     916         
     917        //update the overviewMap 
     918        for (i=0; i<this.controls.length; i++) { 
     919            if (this.controls[i].CLASS_NAME == "OpenLayers.Control.OverviewMap")  
     920                this.controls[i].updateOverview(newResolution, newScaleBounds); 
     921        }           
     922    }, 
     923 
     924 
    909925  /********************************************************/ 
    910926  /*                                                      */ 
    911927  /*                 Layer Options                        */