Project

General

Profile

Download (26.1 KB) Statistics
| Branch: | Tag: | Revision:
1
/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
2
 * full list of contributors). Published under the 2-clause BSD license.
3
 * See license.txt in the OpenLayers distribution or repository for the
4
 * full text of the license. */
5

    
6
/** 
7
 * @requires OpenLayers/Control.js
8
 * @requires OpenLayers/BaseTypes.js
9
 * @requires OpenLayers/Events/buttonclick.js
10
 * @requires OpenLayers/Map.js
11
 * @requires OpenLayers/Handler/Click.js
12
 * @requires OpenLayers/Handler/Drag.js
13
 */
14

    
15
/**
16
 * Class: OpenLayers.Control.OverviewMap
17
 * The OverMap control creates a small overview map, useful to display the 
18
 * extent of a zoomed map and your main map and provide additional 
19
 * navigation options to the User.  By default the overview map is drawn in
20
 * the lower right corner of the main map. Create a new overview map with the
21
 * <OpenLayers.Control.OverviewMap> constructor.
22
 *
23
 * Inherits from:
24
 *  - <OpenLayers.Control>
25
 */
26
OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
27

    
28
    /**
29
     * Property: element
30
     * {DOMElement} The DOM element that contains the overview map
31
     */
32
    element: null,
33
    
34
    /**
35
     * APIProperty: ovmap
36
     * {<OpenLayers.Map>} A reference to the overview map itself.
37
     */
38
    ovmap: null,
39

    
40
    /**
41
     * APIProperty: size
42
     * {<OpenLayers.Size>} The overvew map size in pixels.  Note that this is
43
     * the size of the map itself - the element that contains the map (default
44
     * class name olControlOverviewMapElement) may have padding or other style
45
     * attributes added via CSS.
46
     */
47
    size: {w: 180, h: 90},
48

    
49
    /**
50
     * APIProperty: layers
51
     * {Array(<OpenLayers.Layer>)} Ordered list of layers in the overview map.
52
     * If none are sent at construction, the base layer for the main map is used.
53
     */
54
    layers: null,
55
    
56
    /**
57
     * APIProperty: minRectSize
58
     * {Integer} The minimum width or height (in pixels) of the extent
59
     *     rectangle on the overview map.  When the extent rectangle reaches
60
     *     this size, it will be replaced depending on the value of the
61
     *     <minRectDisplayClass> property.  Default is 15 pixels.
62
     */
63
    minRectSize: 15,
64
    
65
    /**
66
     * APIProperty: minRectDisplayClass
67
     * {String} Replacement style class name for the extent rectangle when
68
     *     <minRectSize> is reached.  This string will be suffixed on to the
69
     *     displayClass.  Default is "RectReplacement".
70
     *
71
     * Example CSS declaration:
72
     * (code)
73
     * .olControlOverviewMapRectReplacement {
74
     *     overflow: hidden;
75
     *     cursor: move;
76
     *     background-image: url("img/overview_replacement.gif");
77
     *     background-repeat: no-repeat;
78
     *     background-position: center;
79
     * }
80
     * (end)
81
     */
82
    minRectDisplayClass: "RectReplacement",
83

    
84
    /**
85
     * APIProperty: minRatio
86
     * {Float} The ratio of the overview map resolution to the main map
87
     *     resolution at which to zoom farther out on the overview map.
88
     */
89
    minRatio: 8,
90

    
91
    /**
92
     * APIProperty: maxRatio
93
     * {Float} The ratio of the overview map resolution to the main map
94
     *     resolution at which to zoom farther in on the overview map.
95
     */
96
    maxRatio: 32,
97
    
98
    /**
99
     * APIProperty: mapOptions
100
     * {Object} An object containing any non-default properties to be sent to
101
     *     the overview map's map constructor.  These should include any
102
     *     non-default options that the main map was constructed with.
103
     */
104
    mapOptions: null,
105

    
106
    /**
107
     * APIProperty: autoPan
108
     * {Boolean} Always pan the overview map, so the extent marker remains in
109
     *     the center.  Default is false.  If true, when you drag the extent
110
     *     marker, the overview map will update itself so the marker returns
111
     *     to the center.
112
     */
113
    autoPan: false,
114
    
115
    /**
116
     * Property: handlers
117
     * {Object}
118
     */
119
    handlers: null,
120

    
121
    /**
122
     * Property: resolutionFactor
123
     * {Object}
124
     */
125
    resolutionFactor: 1,
126

    
127
    /**
128
     * APIProperty: maximized
129
     * {Boolean} Start as maximized (visible). Defaults to false.
130
     */
131
    maximized: false,
132

    
133
    /**
134
     * APIProperty: maximizeTitle
135
     * {String}  This property is used for showing a tooltip over the  
136
     * maximize div. Defaults to "" (no title).
137
     */ 
138
    maximizeTitle: "",
139

    
140
    /**
141
     * APIProperty: minimizeTitle
142
     * {String}  This property is used for showing a tooltip over the  
143
     * minimize div. Defaults to "" (no title).
144
     */ 
145
    minimizeTitle: "",
146

    
147
    /**
148
     * Constructor: OpenLayers.Control.OverviewMap
149
     * Create a new overview map
150
     *
151
     * Parameters:
152
     * options - {Object} Properties of this object will be set on the overview
153
     * map object.  Note, to set options on the map object contained in this
154
     * control, set <mapOptions> as one of the options properties.
155
     */
156
    initialize: function(options) {
157
        this.layers = [];
158
        this.handlers = {};
159
        OpenLayers.Control.prototype.initialize.apply(this, [options]);
160
    },
161
    
162
    /**
163
     * APIMethod: destroy
164
     * Deconstruct the control
165
     */
166
    destroy: function() {
167
        if (!this.mapDiv) { // we've already been destroyed
168
            return;
169
        }
170
        if (this.handlers.click) {
171
            this.handlers.click.destroy();
172
        }
173
        if (this.handlers.drag) {
174
            this.handlers.drag.destroy();
175
        }
176

    
177
        this.ovmap && this.ovmap.viewPortDiv.removeChild(this.extentRectangle);
178
        this.extentRectangle = null;
179

    
180
        if (this.rectEvents) {
181
            this.rectEvents.destroy();
182
            this.rectEvents = null;
183
        }
184

    
185
        if (this.ovmap) {
186
            this.ovmap.destroy();
187
            this.ovmap = null;
188
        }
189
        
190
        this.element.removeChild(this.mapDiv);
191
        this.mapDiv = null;
192

    
193
        this.div.removeChild(this.element);
194
        this.element = null;
195

    
196
        if (this.maximizeDiv) {
197
            this.div.removeChild(this.maximizeDiv);
198
            this.maximizeDiv = null;
199
        }
200
        
201
        if (this.minimizeDiv) {
202
            this.div.removeChild(this.minimizeDiv);
203
            this.minimizeDiv = null;
204
        }
205

    
206
        this.map.events.un({
207
            buttonclick: this.onButtonClick,
208
            moveend: this.update,
209
            changebaselayer: this.baseLayerDraw,
210
            scope: this
211
        });
212

    
213
        OpenLayers.Control.prototype.destroy.apply(this, arguments);    
214
    },
215

    
216
    /**
217
     * Method: draw
218
     * Render the control in the browser.
219
     */    
220
    draw: function() {
221
        OpenLayers.Control.prototype.draw.apply(this, arguments);
222
        if (this.layers.length === 0) {
223
            if (this.map.baseLayer) {
224
                var layer = this.map.baseLayer.clone();
225
                this.layers = [layer];
226
            } else {
227
                this.map.events.register("changebaselayer", this, this.baseLayerDraw);
228
                return this.div;
229
            }
230
        }
231

    
232
        // create overview map DOM elements
233
        this.element = document.createElement('div');
234
        this.element.className = this.displayClass + 'Element';
235
        this.element.style.display = 'none';
236

    
237
        this.mapDiv = document.createElement('div');
238
        this.mapDiv.style.width = this.size.w + 'px';
239
        this.mapDiv.style.height = this.size.h + 'px';
240
        this.mapDiv.style.position = 'relative';
241
        this.mapDiv.style.overflow = 'hidden';
242
        this.mapDiv.id = OpenLayers.Util.createUniqueID('overviewMap');
243
        
244
        this.extentRectangle = document.createElement('div');
245
        this.extentRectangle.style.position = 'absolute';
246
        this.extentRectangle.style.zIndex = 1000;  //HACK
247
        this.extentRectangle.className = this.displayClass+'ExtentRectangle';
248

    
249
        this.element.appendChild(this.mapDiv);  
250

    
251
        this.div.appendChild(this.element);
252

    
253
        // Optionally add min/max buttons if the control will go in the
254
        // map viewport.
255
        if(!this.outsideViewport) {
256
            this.div.className += " " + this.displayClass + 'Container';
257
            // maximize button div
258
            var img = OpenLayers.Util.getImageLocation('layer-switcher-maximize.png');
259
            this.maximizeDiv = OpenLayers.Util.createAlphaImageDiv(
260
                                        this.displayClass + 'MaximizeButton', 
261
                                        null, 
262
                                        null, 
263
                                        img, 
264
                                        'absolute');
265
            this.maximizeDiv.style.display = 'none';
266
            this.maximizeDiv.className = this.displayClass + 'MaximizeButton olButton';
267
            if (this.maximizeTitle) {
268
                this.maximizeDiv.title = this.maximizeTitle;
269
            }
270
            this.div.appendChild(this.maximizeDiv);
271
    
272
            // minimize button div
273
            var img = OpenLayers.Util.getImageLocation('layer-switcher-minimize.png');
274
            this.minimizeDiv = OpenLayers.Util.createAlphaImageDiv(
275
                                        'OpenLayers_Control_minimizeDiv', 
276
                                        null, 
277
                                        null, 
278
                                        img, 
279
                                        'absolute');
280
            this.minimizeDiv.style.display = 'none';
281
            this.minimizeDiv.className = this.displayClass + 'MinimizeButton olButton';
282
            if (this.minimizeTitle) {
283
                this.minimizeDiv.title = this.minimizeTitle;
284
            }
285
            this.div.appendChild(this.minimizeDiv);            
286
            this.minimizeControl();
287
        } else {
288
            // show the overview map
289
            this.element.style.display = '';
290
        }
291
        if(this.map.getExtent()) {
292
            this.update();
293
        }
294
        
295
        this.map.events.on({
296
            buttonclick: this.onButtonClick,
297
            moveend: this.update,
298
            scope: this
299
        });
300
        
301
        if (this.maximized) {
302
            this.maximizeControl();
303
        }
304
        return this.div;
305
    },
306
    
307
    /**
308
     * Method: baseLayerDraw
309
     * Draw the base layer - called if unable to complete in the initial draw
310
     */
311
    baseLayerDraw: function() {
312
        this.draw();
313
        this.map.events.unregister("changebaselayer", this, this.baseLayerDraw);
314
    },
315

    
316
    /**
317
     * Method: rectDrag
318
     * Handle extent rectangle drag
319
     *
320
     * Parameters:
321
     * px - {<OpenLayers.Pixel>} The pixel location of the drag.
322
     */
323
    rectDrag: function(px) {
324
        var deltaX = this.handlers.drag.last.x - px.x;
325
        var deltaY = this.handlers.drag.last.y - px.y;
326
        if(deltaX != 0 || deltaY != 0) {
327
            var rectTop = this.rectPxBounds.top;
328
            var rectLeft = this.rectPxBounds.left;
329
            var rectHeight = Math.abs(this.rectPxBounds.getHeight());
330
            var rectWidth = this.rectPxBounds.getWidth();
331
            // don't allow dragging off of parent element
332
            var newTop = Math.max(0, (rectTop - deltaY));
333
            newTop = Math.min(newTop,
334
                              this.ovmap.size.h - this.hComp - rectHeight);
335
            var newLeft = Math.max(0, (rectLeft - deltaX));
336
            newLeft = Math.min(newLeft,
337
                               this.ovmap.size.w - this.wComp - rectWidth);
338
            this.setRectPxBounds(new OpenLayers.Bounds(newLeft,
339
                                                       newTop + rectHeight,
340
                                                       newLeft + rectWidth,
341
                                                       newTop));
342
        }
343
    },
344
    
345
    /**
346
     * Method: mapDivClick
347
     * Handle browser events
348
     *
349
     * Parameters:
350
     * evt - {<OpenLayers.Event>} evt
351
     */
352
    mapDivClick: function(evt) {
353
        var pxCenter = this.rectPxBounds.getCenterPixel();
354
        var deltaX = evt.xy.x - pxCenter.x;
355
        var deltaY = evt.xy.y - pxCenter.y;
356
        var top = this.rectPxBounds.top;
357
        var left = this.rectPxBounds.left;
358
        var height = Math.abs(this.rectPxBounds.getHeight());
359
        var width = this.rectPxBounds.getWidth();
360
        var newTop = Math.max(0, (top + deltaY));
361
        newTop = Math.min(newTop, this.ovmap.size.h - height);
362
        var newLeft = Math.max(0, (left + deltaX));
363
        newLeft = Math.min(newLeft, this.ovmap.size.w - width);
364
        this.setRectPxBounds(new OpenLayers.Bounds(newLeft,
365
                                                   newTop + height,
366
                                                   newLeft + width,
367
                                                   newTop));
368
        this.updateMapToRect();
369
    },
370
    
371
    /**
372
     * Method: onButtonClick
373
     *
374
     * Parameters:
375
     * evt - {Event}
376
     */
377
    onButtonClick: function(evt) {
378
        if (evt.buttonElement === this.minimizeDiv) {
379
            this.minimizeControl();
380
        } else if (evt.buttonElement === this.maximizeDiv) {
381
            this.maximizeControl();
382
        }
383
    },
384

    
385
    /**
386
     * Method: maximizeControl
387
     * Unhide the control.  Called when the control is in the map viewport.
388
     *
389
     * Parameters:
390
     * e - {<OpenLayers.Event>}
391
     */
392
    maximizeControl: function(e) {
393
        this.element.style.display = '';
394
        this.showToggle(false);
395
        if (e != null) {
396
            OpenLayers.Event.stop(e);                                            
397
        }
398
    },
399

    
400
    /**
401
     * Method: minimizeControl
402
     * Hide all the contents of the control, shrink the size, 
403
     * add the maximize icon
404
     * 
405
     * Parameters:
406
     * e - {<OpenLayers.Event>}
407
     */
408
    minimizeControl: function(e) {
409
        this.element.style.display = 'none';
410
        this.showToggle(true);
411
        if (e != null) {
412
            OpenLayers.Event.stop(e);                                            
413
        }
414
    },
415

    
416
    /**
417
     * Method: showToggle
418
     * Hide/Show the toggle depending on whether the control is minimized
419
     *
420
     * Parameters:
421
     * minimize - {Boolean} 
422
     */
423
    showToggle: function(minimize) {
424
        if (this.maximizeDiv) {
425
            this.maximizeDiv.style.display = minimize ? '' : 'none';
426
        }
427
        if (this.minimizeDiv) {
428
            this.minimizeDiv.style.display = minimize ? 'none' : '';
429
        }
430
    },
431

    
432
    /**
433
     * Method: update
434
     * Update the overview map after layers move.
435
     */
436
    update: function() {
437
        if(this.ovmap == null) {
438
            this.createMap();
439
        }
440
        
441
        if(this.autoPan || !this.isSuitableOverview()) {
442
            this.updateOverview();
443
        }
444
        
445
        // update extent rectangle
446
        this.updateRectToMap();
447
    },
448
    
449
    /**
450
     * Method: isSuitableOverview
451
     * Determines if the overview map is suitable given the extent and
452
     * resolution of the main map.
453
     */
454
    isSuitableOverview: function() {
455
        var mapExtent = this.map.getExtent();
456
        var maxExtent = this.map.getMaxExtent();
457
        var testExtent = new OpenLayers.Bounds(
458
                                Math.max(mapExtent.left, maxExtent.left),
459
                                Math.max(mapExtent.bottom, maxExtent.bottom),
460
                                Math.min(mapExtent.right, maxExtent.right),
461
                                Math.min(mapExtent.top, maxExtent.top));        
462

    
463
        if (this.ovmap.getProjection() != this.map.getProjection()) {
464
            testExtent = testExtent.transform(
465
                this.map.getProjectionObject(),
466
                this.ovmap.getProjectionObject() );
467
        }
468

    
469
        var resRatio = this.ovmap.getResolution() / this.map.getResolution();
470
        return ((resRatio > this.minRatio) &&
471
                (resRatio <= this.maxRatio) &&
472
                (this.ovmap.getExtent().containsBounds(testExtent)));
473
    },
474
    
475
    /**
476
     * Method updateOverview
477
     * Called by <update> if <isSuitableOverview> returns true
478
     */
479
    updateOverview: function() {
480
        var mapRes = this.map.getResolution();
481
        var targetRes = this.ovmap.getResolution();
482
        var resRatio = targetRes / mapRes;
483
        if(resRatio > this.maxRatio) {
484
            // zoom in overview map
485
            targetRes = this.minRatio * mapRes;            
486
        } else if(resRatio <= this.minRatio) {
487
            // zoom out overview map
488
            targetRes = this.maxRatio * mapRes;
489
        }
490
        var center;
491
        if (this.ovmap.getProjection() != this.map.getProjection()) {
492
            center = this.map.center.clone();
493
            center.transform(this.map.getProjectionObject(),
494
                this.ovmap.getProjectionObject() );
495
        } else {
496
            center = this.map.center;
497
        }
498
        this.ovmap.setCenter(center, this.ovmap.getZoomForResolution(
499
            targetRes * this.resolutionFactor));
500
        this.updateRectToMap();
501
    },
502
    
503
    /**
504
     * Method: createMap
505
     * Construct the map that this control contains
506
     */
507
    createMap: function() {
508
        // create the overview map
509
        var options = OpenLayers.Util.extend(
510
                        {controls: [], maxResolution: 'auto', 
511
                         fallThrough: false}, this.mapOptions);
512
        this.ovmap = new OpenLayers.Map(this.mapDiv, options);
513
        this.ovmap.viewPortDiv.appendChild(this.extentRectangle);
514
        
515
        // prevent ovmap from being destroyed when the page unloads, because
516
        // the OverviewMap control has to do this (and does it).
517
        OpenLayers.Event.stopObserving(window, 'unload', this.ovmap.unloadDestroy);
518
        
519
        this.ovmap.addLayers(this.layers);
520
        this.ovmap.zoomToMaxExtent();
521
        // check extent rectangle border width
522
        this.wComp = parseInt(OpenLayers.Element.getStyle(this.extentRectangle,
523
                                               'border-left-width')) +
524
                     parseInt(OpenLayers.Element.getStyle(this.extentRectangle,
525
                                               'border-right-width'));
526
        this.wComp = (this.wComp) ? this.wComp : 2;
527
        this.hComp = parseInt(OpenLayers.Element.getStyle(this.extentRectangle,
528
                                               'border-top-width')) +
529
                     parseInt(OpenLayers.Element.getStyle(this.extentRectangle,
530
                                               'border-bottom-width'));
531
        this.hComp = (this.hComp) ? this.hComp : 2;
532

    
533
        this.handlers.drag = new OpenLayers.Handler.Drag(
534
            this, {move: this.rectDrag, done: this.updateMapToRect},
535
            {map: this.ovmap}
536
        );
537
        this.handlers.click = new OpenLayers.Handler.Click(
538
            this, {
539
                "click": this.mapDivClick
540
            },{
541
                "single": true, "double": false,
542
                "stopSingle": true, "stopDouble": true,
543
                "pixelTolerance": 1,
544
                map: this.ovmap
545
            }
546
        );
547
        this.handlers.click.activate();
548
        
549
        this.rectEvents = new OpenLayers.Events(this, this.extentRectangle,
550
                                                null, true);
551
        this.rectEvents.register("mouseover", this, function(e) {
552
            if(!this.handlers.drag.active && !this.map.dragging) {
553
                this.handlers.drag.activate();
554
            }
555
        });
556
        this.rectEvents.register("mouseout", this, function(e) {
557
            if(!this.handlers.drag.dragging) {
558
                this.handlers.drag.deactivate();
559
            }
560
        });
561

    
562
        if (this.ovmap.getProjection() != this.map.getProjection()) {
563
            var sourceUnits = this.map.getProjectionObject().getUnits() ||
564
                this.map.units || this.map.baseLayer.units;
565
            var targetUnits = this.ovmap.getProjectionObject().getUnits() ||
566
                this.ovmap.units || this.ovmap.baseLayer.units;
567
            this.resolutionFactor = sourceUnits && targetUnits ?
568
                OpenLayers.INCHES_PER_UNIT[sourceUnits] /
569
                OpenLayers.INCHES_PER_UNIT[targetUnits] : 1;
570
        }
571
    },
572
        
573
    /**
574
     * Method: updateRectToMap
575
     * Updates the extent rectangle position and size to match the map extent
576
     */
577
    updateRectToMap: function() {
578
        // If the projections differ we need to reproject
579
        var bounds;
580
        if (this.ovmap.getProjection() != this.map.getProjection()) {
581
            bounds = this.map.getExtent().transform(
582
                this.map.getProjectionObject(), 
583
                this.ovmap.getProjectionObject() );
584
        } else {
585
            bounds = this.map.getExtent();
586
        }
587
        var pxBounds = this.getRectBoundsFromMapBounds(bounds);
588
        if (pxBounds) {
589
            this.setRectPxBounds(pxBounds);
590
        }
591
    },
592
    
593
    /**
594
     * Method: updateMapToRect
595
     * Updates the map extent to match the extent rectangle position and size
596
     */
597
    updateMapToRect: function() {
598
        var lonLatBounds = this.getMapBoundsFromRectBounds(this.rectPxBounds);
599
        if (this.ovmap.getProjection() != this.map.getProjection()) {
600
            lonLatBounds = lonLatBounds.transform(
601
                this.ovmap.getProjectionObject(),
602
                this.map.getProjectionObject() );
603
        }
604
        this.map.panTo(lonLatBounds.getCenterLonLat());
605
    },
606

    
607
    /**
608
     * Method: setRectPxBounds
609
     * Set extent rectangle pixel bounds.
610
     *
611
     * Parameters:
612
     * pxBounds - {<OpenLayers.Bounds>}
613
     */
614
    setRectPxBounds: function(pxBounds) {
615
        var top = Math.max(pxBounds.top, 0);
616
        var left = Math.max(pxBounds.left, 0);
617
        var bottom = Math.min(pxBounds.top + Math.abs(pxBounds.getHeight()),
618
                              this.ovmap.size.h - this.hComp);
619
        var right = Math.min(pxBounds.left + pxBounds.getWidth(),
620
                             this.ovmap.size.w - this.wComp);
621
        var width = Math.max(right - left, 0);
622
        var height = Math.max(bottom - top, 0);
623
        if(width < this.minRectSize || height < this.minRectSize) {
624
            this.extentRectangle.className = this.displayClass +
625
                                             this.minRectDisplayClass;
626
            var rLeft = left + (width / 2) - (this.minRectSize / 2);
627
            var rTop = top + (height / 2) - (this.minRectSize / 2);
628
            this.extentRectangle.style.top = Math.round(rTop) + 'px';
629
            this.extentRectangle.style.left = Math.round(rLeft) + 'px';
630
            this.extentRectangle.style.height = this.minRectSize + 'px';
631
            this.extentRectangle.style.width = this.minRectSize + 'px';
632
        } else {
633
            this.extentRectangle.className = this.displayClass +
634
                                             'ExtentRectangle';
635
            this.extentRectangle.style.top = Math.round(top) + 'px';
636
            this.extentRectangle.style.left = Math.round(left) + 'px';
637
            this.extentRectangle.style.height = Math.round(height) + 'px';
638
            this.extentRectangle.style.width = Math.round(width) + 'px';
639
        }
640
        this.rectPxBounds = new OpenLayers.Bounds(
641
            Math.round(left), Math.round(bottom),
642
            Math.round(right), Math.round(top)
643
        );
644
    },
645

    
646
    /**
647
     * Method: getRectBoundsFromMapBounds
648
     * Get the rect bounds from the map bounds.
649
     *
650
     * Parameters:
651
     * lonLatBounds - {<OpenLayers.Bounds>}
652
     *
653
     * Returns:
654
     * {<OpenLayers.Bounds>}A bounds which is the passed-in map lon/lat extent
655
     * translated into pixel bounds for the overview map
656
     */
657
    getRectBoundsFromMapBounds: function(lonLatBounds) {
658
        var leftBottomPx = this.getOverviewPxFromLonLat({
659
            lon: lonLatBounds.left,
660
            lat: lonLatBounds.bottom
661
        });
662
        var rightTopPx = this.getOverviewPxFromLonLat({
663
            lon: lonLatBounds.right,
664
            lat: lonLatBounds.top
665
        });
666
        var bounds = null;
667
        if (leftBottomPx && rightTopPx) {
668
            bounds = new OpenLayers.Bounds(leftBottomPx.x, leftBottomPx.y,
669
                                           rightTopPx.x, rightTopPx.y);
670
        }
671
        return bounds;
672
    },
673

    
674
    /**
675
     * Method: getMapBoundsFromRectBounds
676
     * Get the map bounds from the rect bounds.
677
     *
678
     * Parameters:
679
     * pxBounds - {<OpenLayers.Bounds>}
680
     *
681
     * Returns:
682
     * {<OpenLayers.Bounds>} Bounds which is the passed-in overview rect bounds
683
     * translated into lon/lat bounds for the overview map
684
     */
685
    getMapBoundsFromRectBounds: function(pxBounds) {
686
        var leftBottomLonLat = this.getLonLatFromOverviewPx({
687
            x: pxBounds.left,
688
            y: pxBounds.bottom
689
        });
690
        var rightTopLonLat = this.getLonLatFromOverviewPx({
691
            x: pxBounds.right,
692
            y: pxBounds.top
693
        });
694
        return new OpenLayers.Bounds(leftBottomLonLat.lon, leftBottomLonLat.lat,
695
                                     rightTopLonLat.lon, rightTopLonLat.lat);
696
    },
697

    
698
    /**
699
     * Method: getLonLatFromOverviewPx
700
     * Get a map location from a pixel location
701
     *
702
     * Parameters:
703
     * overviewMapPx - {<OpenLayers.Pixel>|Object} OpenLayers.Pixel or
704
     *                                             an object with a
705
     *                                             'x' and 'y' properties.
706
     *
707
     * Returns:
708
     * {Object} Location which is the passed-in overview map
709
     * OpenLayers.Pixel, translated into lon/lat by the overview
710
     * map. An object with a 'lon' and 'lat' properties.
711
     */
712
    getLonLatFromOverviewPx: function(overviewMapPx) {
713
        var size = this.ovmap.size;
714
        var res  = this.ovmap.getResolution();
715
        var center = this.ovmap.getExtent().getCenterLonLat();
716
    
717
        var deltaX = overviewMapPx.x - (size.w / 2);
718
        var deltaY = overviewMapPx.y - (size.h / 2);
719

    
720
        return {
721
            lon: center.lon + deltaX * res,
722
            lat: center.lat - deltaY * res
723
        };
724
    },
725

    
726
    /**
727
     * Method: getOverviewPxFromLonLat
728
     * Get a pixel location from a map location
729
     *
730
     * Parameters:
731
     * lonlat - {<OpenLayers.LonLat>|Object} OpenLayers.LonLat or an
732
     *     object with a 'lon' and 'lat' properties.
733
     *
734
     * Returns:
735
     * {Object} Location which is the passed-in OpenLayers.LonLat, 
736
     * translated into overview map pixels
737
     */
738
    getOverviewPxFromLonLat: function(lonlat) {
739
        var res = this.ovmap.getResolution();
740
        var extent = this.ovmap.getExtent();
741
        if (extent) {
742
            return {
743
                x: Math.round(1/res * (lonlat.lon - extent.left)),
744
                y: Math.round(1/res * (extent.top - lonlat.lat))
745
            };
746
        } 
747
    },
748

    
749
    CLASS_NAME: 'OpenLayers.Control.OverviewMap'
750
});
(21-21/45)