OpenLayers OpenLayers

Ticket #1244: ovmap.patch

File ovmap.patch, 18.3 kB (added by tschaub, 1 year ago)

improve the overview map control

  • theme/default/style.css

    old new  
    6464} 
    6565 
    6666.olControlOverviewMapExtentRectangle { 
    67    cursor: move; 
     67    overflow: hidden; 
     68    background-image: url("img/blank.gif"); 
     69    cursor: move; 
    6870    border: 2px dotted red; 
    6971} 
     72.olControlOverviewMapRectReplacement { 
     73    overflow: hidden; 
     74    cursor: move; 
     75    background-image: url("img/overview_replacement.gif"); 
     76    background-repeat: no-repeat; 
     77    background-position: center; 
     78} 
     79 
    7080.olLayerGeoRSSDescription { 
    7181    float:left; 
    7282    width:100%; 
  • tests/Control/test_OverviewMap.html

    old new  
    5151        t.eq(cent.lon, -71.3515625, "Clicking on the Overview Map has the correct effect on map lon"); 
    5252        t.eq(cent.lat, 42.17578125, "Clicking on the Overview Map has the correct effect on map lat"); 
    5353 
    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}); 
     54        control.dragHandler = { 
     55            last: new OpenLayers.Pixel(5,5), 
     56            destroy: function() {} 
     57        }; 
     58        control.rectDrag(new OpenLayers.Pixel(15, 15)); 
     59        control.updateMapToRect(); 
    5760         
    5861        var cent = map.getCenter(); 
    5962        t.eq(cent.lon, -71.2734375, "Dragging on the Overview Map has the correct effect on map lon"); 
  • lib/OpenLayers/Map.js

    old new  
    5353     * {DOMElement} The element that contains the map 
    5454     */ 
    5555    div: null, 
     56     
     57    /** 
     58     * Property: dragging 
     59     * {Boolean} The map is currently being dragged. 
     60     */ 
     61    dragging: false, 
    5662 
    5763    /** 
    5864     * Property: size 
     
    12211227     * TBD: reconsider forceZoomChange in 3.0 
    12221228     */ 
    12231229    setCenter: function (lonlat, zoom, dragging, forceZoomChange) { 
    1224  
     1230        this.dragging = !!dragging; 
     1231         
    12251232        if (!this.center && !this.isValidLonLat(lonlat)) { 
    12261233            lonlat = this.maxExtent.getCenterLonLat(); 
    12271234        } 
  • lib/OpenLayers/Control/OverviewMap.js

    old new  
    2020OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, { 
    2121 
    2222    /** 
    23      * Property: id 
    24      * {String} For div.id 
    25      */ 
    26     id:  "OverviewMap", 
    27  
    28     /** 
    2923     * Property: element 
    3024     * {DOMElement} The DOM element that contains the overview map 
    3125     */ 
     
    3630     * {<OpenLayers.Map>} A reference to the overvew map itself. 
    3731     */ 
    3832    ovmap: null, 
    39          
     33 
    4034    /** 
    4135     * APIProperty: size 
    4236     * {<OpenLayers.Size>} The overvew map size in pixels.  Note that this is 
     
    5246     * If none are sent at construction, the base layer for the main map is used. 
    5347     */ 
    5448    layers: null, 
     49     
     50    /** 
     51     * APIProperty: minRectSize 
     52     * {Integer} The minimum width or height (in pixels) of the extent 
     53     *     rectangle on the overview map.  When the extent rectangle reaches 
     54     *     this size, it will be replaced depending on the value of the 
     55     *     <minRectDisplayClass> property.  Default is 10 pixels. 
     56     */ 
     57    minRectSize: 15, 
     58     
     59    /** 
     60     * APIProperty: minRectDisplayClass 
     61     * {String} Replacement style class name for the extent rectangle when 
     62     *     <minRectSize> is reached.  This string will be suffixed on to the 
     63     *     displayClass.  Default is "RectReplacement". 
     64     * 
     65     * Example CSS declaration: 
     66     * (code) 
     67     * .olControlOverviewMapRectReplacement { 
     68     *     background-image: url("img/overview_replacement.png"); 
     69     *     background-repeat: no-repeat; 
     70     *     background-position: center; 
     71     * } 
     72     * (end) 
     73     */ 
     74    minRectDisplayClass: "RectReplacement", 
    5575 
    5676    /** 
    5777     * APIProperty: minRatio 
     
    7494     * options that the main map was constructed with. 
    7595     */ 
    7696    mapOptions: null, 
     97     
     98    /** 
     99     * Property: dragHandler 
     100     * {<OpenLayers.Handler.Drag>} A handler for dragging the extent rectangle. 
     101     */ 
     102    dragHandler: null, 
    77103 
    78104    /** 
    79105     * Constructor: OpenLayers.Control.OverviewMap 
     
    97123        if (!this.mapDiv) { // we've already been destroyed 
    98124            return; 
    99125        } 
     126        this.dragHandler.destroy(); 
     127        this.clickHandler.destroy(); 
     128 
    100129        this.mapDiv.removeChild(this.extentRectangle); 
    101130        this.extentRectangle = null; 
    102131        this.rectEvents.destroy(); 
     
    107136         
    108137        this.element.removeChild(this.mapDiv); 
    109138        this.mapDiv = null; 
    110         this.mapDivEvents.destroy();  
    111         this.mapDivEvents = null; 
    112139 
    113140        this.div.removeChild(this.element); 
    114141        this.element = null; 
    115         this.elementEvents.destroy(); 
    116         this.elementEvents = null; 
    117142 
    118143        if (this.maximizeDiv) { 
    119144            OpenLayers.Event.stopObservingElement(this.maximizeDiv); 
     
    165190        this.extentRectangle = document.createElement('div'); 
    166191        this.extentRectangle.style.position = 'absolute'; 
    167192        this.extentRectangle.style.zIndex = 1000;  //HACK 
    168         this.extentRectangle.style.overflow = 'hidden'; 
    169         this.extentRectangle.style.backgroundImage = 'url(' + 
    170                                         OpenLayers.Util.getImagesLocation() + 
    171                                         'blank.gif)'; 
    172193        this.extentRectangle.className = this.displayClass+'ExtentRectangle'; 
    173194        this.mapDiv.appendChild(this.extentRectangle); 
    174                  
     195 
    175196        this.element.appendChild(this.mapDiv);   
    176197 
    177198        this.div.appendChild(this.element); 
    178199 
    179200        this.map.events.register('moveend', this, this.update); 
    180          
    181         // Set up events.  The image div recenters the map on click. 
    182         // The extent rectangle can be dragged to recenter the map. 
    183         // If the mousedown happened elsewhere, then mousemove and mouseup 
    184         // should slip through. 
    185         this.elementEvents = new OpenLayers.Events(this, this.element); 
    186         this.elementEvents.register('mousedown', this, function(e) { 
    187             OpenLayers.Event.stop(e); 
    188         }); 
    189         this.elementEvents.register('click', this, function(e) { 
    190             OpenLayers.Event.stop(e); 
    191         }); 
    192         this.elementEvents.register('dblclick', this, function(e) { 
    193             OpenLayers.Event.stop(e); 
    194         }); 
    195         this.rectEvents = new OpenLayers.Events(this, this.extentRectangle, 
    196                                                 null, true); 
    197         this.rectEvents.register('mouseout', this, this.rectMouseOut); 
    198         this.rectEvents.register('mousedown', this, this.rectMouseDown); 
    199         this.rectEvents.register('mousemove', this, this.rectMouseMove); 
    200         this.rectEvents.register('mouseup', this, this.rectMouseUp); 
    201         this.rectEvents.register('click', this, function(e) { 
    202             OpenLayers.Event.stop(e); 
    203         }); 
    204         this.rectEvents.register('dblclick', this, this.rectDblClick ); 
    205         this.mapDivEvents = new OpenLayers.Events(this, this.mapDiv); 
    206         this.mapDivEvents.register('click', this, this.mapDivClick); 
    207201 
    208202        // Optionally add min/max buttons if the control will go in the 
    209203        // map viewport. 
     
    276270    }, 
    277271 
    278272    /** 
    279      * Method: rectMouseOut 
    280      * Handle browser events 
     273     * Method: rectDrag 
     274     * Handle extent rectangle drag 
    281275     * 
    282276     * Parameters: 
    283      * evt - {<OpenLayers.Event>} evt 
     277     * px - {<OpenLayers.Pixel>} The pixel location of the drag. 
    284278     */ 
    285     rectMouseOut: function (evt) { 
    286         if(this.rectDragStart != null) { 
    287             if(this.performedRectDrag) { 
    288                 this.rectMouseMove(evt); 
    289                 var rectPxBounds = this.getRectPxBounds();  
    290                 // if we're off of the overview map, update the main map 
    291                 // otherwise, keep moving the rect 
    292                 if((rectPxBounds.top <= 0) || (rectPxBounds.left <= 0) ||  
    293                    (rectPxBounds.bottom >= this.size.h - this.hComp) ||  
    294                    (rectPxBounds.right >= this.size.w - this.wComp)) { 
    295                     this.updateMapToRect(); 
    296                 } else { 
    297                     return;  
    298                 } 
    299             } 
    300             document.onselectstart = null; 
    301             this.rectDragStart = null; 
    302         } 
    303     }, 
    304  
    305     /** 
    306      * Method: rectMouseDown 
    307      * Handle browser events 
    308      * 
    309      * Parameters: 
    310      * evt - {<OpenLayers.Event>} evt 
    311      */ 
    312     rectMouseDown: function (evt) { 
    313         if(!OpenLayers.Event.isLeftClick(evt)) { 
    314             return; 
    315         } 
    316         this.rectDragStart = evt.xy.clone(); 
    317         this.performedRectDrag = false; 
    318         OpenLayers.Event.stop(evt); 
    319     }, 
    320  
    321     /** 
    322      * Method: rectMouseMove 
    323      * Handle browser events 
    324      * 
    325      * Parameters: 
    326      * evt - {<OpenLayers.Event>} evt 
    327      */ 
    328     rectMouseMove: function(evt) { 
    329         if(this.rectDragStart != null) { 
    330             var deltaX = this.rectDragStart.x - evt.xy.x; 
    331             var deltaY = this.rectDragStart.y - evt.xy.y; 
    332             var rectPxBounds = this.getRectPxBounds(); 
    333             var rectTop = rectPxBounds.top; 
    334             var rectLeft = rectPxBounds.left; 
    335             var rectHeight = Math.abs(rectPxBounds.getHeight()); 
    336             var rectWidth = rectPxBounds.getWidth(); 
     279    rectDrag: function(px) { 
     280        var deltaX = this.dragHandler.last.x - px.x; 
     281        var deltaY = this.dragHandler.last.y - px.y; 
     282        if(deltaX != 0 || deltaY != 0) { 
     283            var rectTop = this.rectPxBounds.top; 
     284            var rectLeft = this.rectPxBounds.left; 
     285            var rectHeight = Math.abs(this.rectPxBounds.getHeight()); 
     286            var rectWidth = this.rectPxBounds.getWidth(); 
    337287            // don't allow dragging off of parent element 
    338288            var newTop = Math.max(0, (rectTop - deltaY)); 
    339289            newTop = Math.min(newTop, 
     
    345295                                                       newTop + rectHeight, 
    346296                                                       newLeft + rectWidth, 
    347297                                                       newTop)); 
    348             this.rectDragStart = evt.xy.clone(); 
    349             this.performedRectDrag = true; 
    350             OpenLayers.Event.stop(evt); 
    351298        } 
    352299    }, 
    353  
    354     /** 
    355      * Method: rectMouseUp 
    356      * Handle browser events 
    357      * 
    358      * Parameters: 
    359      * evt - {<OpenLayers.Event>} evt 
    360      */ 
    361     rectMouseUp: function(evt) { 
    362         if(!OpenLayers.Event.isLeftClick(evt)) { 
    363             return; 
    364         } 
    365         if(this.performedRectDrag) { 
    366             this.updateMapToRect(); 
    367             OpenLayers.Event.stop(evt); 
    368         }         
    369         document.onselectstart = null; 
    370         this.rectDragStart = null; 
    371     }, 
    372300     
    373301    /** 
    374      * Method: rectDblClick 
    375      * Handle browser events 
    376      * 
    377      * Parameters: 
    378      * evt - {<OpenLayers.Event>} evt 
    379      */ 
    380     rectDblClick: function(evt) { 
    381         this.performedRectDrag = false; 
    382         OpenLayers.Event.stop(evt); 
    383         this.updateOverview(); 
    384     }, 
    385  
    386     /** 
    387302     * Method: mapDivClick 
    388303     * Handle browser events 
    389304     * 
     
    391306     * evt - {<OpenLayers.Event>} evt 
    392307     */ 
    393308    mapDivClick: function(evt) { 
    394         var pxBounds = this.getRectPxBounds(); 
    395         var pxCenter = pxBounds.getCenterPixel(); 
     309        var pxCenter = this.rectPxBounds.getCenterPixel(); 
    396310        var deltaX = evt.xy.x - pxCenter.x; 
    397311        var deltaY = evt.xy.y - pxCenter.y; 
    398         var top = pxBounds.top; 
    399         var left = pxBounds.left; 
    400         var height = Math.abs(pxBounds.getHeight()); 
    401         var width = pxBounds.getWidth(); 
     312        var top = this.rectPxBounds.top; 
     313        var left = this.rectPxBounds.left; 
     314        var height = Math.abs(this.rectPxBounds.getHeight()); 
     315        var width = this.rectPxBounds.getWidth(); 
    402316        var newTop = Math.max(0, (top + deltaY)); 
    403317        newTop = Math.min(newTop, this.ovmap.size.h - height); 
    404318        var newLeft = Math.max(0, (left + deltaX)); 
     
    532446                     parseInt(OpenLayers.Element.getStyle(this.extentRectangle, 
    533447                                               'border-bottom-width')); 
    534448        this.hComp = (this.hComp) ? this.hComp : 2; 
     449 
     450        this.dragHandler = new OpenLayers.Handler.Drag( 
     451            this, {move: this.rectDrag, done: this.updateMapToRect}, 
     452            {map: this.ovmap} 
     453        ); 
     454        this.clickHandler = new OpenLayers.Handler.Click( 
     455            this, { 
     456                "click": this.mapDivClick 
     457            },{ 
     458                "single": true, "double": false, 
     459                "stopSingle": true, "stopDouble": true, 
     460                "pixelTolerance": 1, 
     461                map: this.ovmap 
     462            } 
     463        ); 
     464        this.clickHandler.activate(); 
     465         
     466        this.rectEvents = new OpenLayers.Events(this, this.extentRectangle, 
     467                                                null, true); 
     468        this.rectEvents.register("mouseover", this, function(e) { 
     469            if(!this.dragHandler.active && !this.map.dragging) { 
     470                // this click handler de/activation can be removed when 
     471                // ticket #1247 is addressed 
     472                this.clickHandler.deactivate(); 
     473                this.dragHandler.activate(); 
     474                this.clickHandler.activate(); 
     475            } 
     476        }); 
     477        this.rectEvents.register("mouseout", this, function(e) { 
     478            if(!this.dragHandler.dragging) { 
     479                this.dragHandler.deactivate(); 
     480            } 
     481        }); 
     482 
    535483    }, 
    536484         
    537485    /** 
     
    548496        } 
    549497        var pxBounds = this.getRectBoundsFromMapBounds(this.map.getExtent()); 
    550498        if (pxBounds) { 
    551           this.setRectPxBounds(pxBounds); 
     499            this.setRectPxBounds(pxBounds); 
    552500        } 
    553501    }, 
    554502     
     
    557505     * Updates the map extent to match the extent rectangle position and size 
    558506     */ 
    559507    updateMapToRect: function() { 
    560         var pxBounds = this.getRectPxBounds(); 
    561         var lonLatBounds = this.getMapBoundsFromRectBounds(pxBounds); 
     508        var lonLatBounds = this.getMapBoundsFromRectBounds(this.rectPxBounds); 
    562509        this.map.setCenter(lonLatBounds.getCenterLonLat(), this.map.zoom); 
    563510    }, 
    564      
    565     /** 
    566      * Method: getRectPxBounds 
    567      * Get extent rectangle pixel bounds 
    568      * 
    569      * Returns: 
    570      * {<OpenLayers.Bounds>} A bounds which is the extent rectangle's pixel 
    571      * bounds (relative to the parent element) 
    572      */ 
    573     getRectPxBounds: function() { 
    574         var top = parseInt(this.extentRectangle.style.top); 
    575         var left = parseInt(this.extentRectangle.style.left); 
    576         var height = parseInt(this.extentRectangle.style.height); 
    577         var width = parseInt(this.extentRectangle.style.width); 
    578         return new OpenLayers.Bounds(left, top + height, left + width, top); 
    579     }, 
    580511 
    581512    /** 
    582513     * Method: setRectPxBounds 
     
    592523                              this.ovmap.size.h - this.hComp); 
    593524        var right = Math.min(pxBounds.left + pxBounds.getWidth(), 
    594525                             this.ovmap.size.w - this.wComp); 
    595         this.extentRectangle.style.top = parseInt(top) + 'px'; 
    596         this.extentRectangle.style.left = parseInt(left) + 'px'; 
    597         this.extentRectangle.style.height = parseInt(Math.max(bottom - top, 0))+ 'px'; 
    598         this.extentRectangle.style.width = parseInt(Math.max(right - left, 0)) + 'px'; 
     526        var width = Math.max(right - left, 0); 
     527        var height = Math.max(bottom - top, 0); 
     528        if(width < this.minRectSize || height < this.minRectSize) { 
     529            this.extentRectangle.className = this.displayClass + 
     530                                             this.minRectDisplayClass; 
     531            var rLeft = left + (width / 2) - (this.minRectSize / 2); 
     532            var rTop = top + (height / 2) - (this.minRectSize / 2); 
     533            this.extentRectangle.style.top = Math.round(rTop) + 'px'; 
     534            this.extentRectangle.style.left = Math.round(rLeft) + 'px'; 
     535            this.extentRectangle.style.height = this.minRectSize + 'px'; 
     536            this.extentRectangle.style.width = this.minRectSize + 'px'; 
     537        } else { 
     538            this.extentRectangle.className = this.displayClass + 
     539                                             'ExtentRectangle'; 
     540            this.extentRectangle.style.top = Math.round(top) + 'px'; 
     541            this.extentRectangle.style.left = Math.round(left) + 'px'; 
     542            this.extentRectangle.style.height = Math.round(height) + 'px'; 
     543            this.extentRectangle.style.width = Math.round(width) + 'px'; 
     544        } 
     545        this.rectPxBounds = new OpenLayers.Bounds( 
     546            Math.round(left), Math.round(bottom), 
     547            Math.round(right), Math.round(top) 
     548        ); 
    599549    }, 
    600550 
    601551    /** 
  • examples/overviewmap.html

    old new  
    8686        map2.addLayers([bos]); 
    8787        map2.addControl(new OpenLayers.Control.LayerSwitcher()); 
    8888         
    89         // create an overview map control with the default options 
     89        // create an overview map control with non-default options 
    9090        var controlOptions = { 
    9191            mapOptions: mapOptions 
    9292        }