Project

General

Profile

Download (6.51 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
 */
9

    
10
/**
11
 * Class: OpenLayers.Control.ScaleLine
12
 * The ScaleLine displays a small line indicator representing the current 
13
 * map scale on the map. By default it is drawn in the lower left corner of
14
 * the map.
15
 * 
16
 * Inherits from:
17
 *  - <OpenLayers.Control>
18
 *  
19
 * Is a very close copy of:
20
 *  - <OpenLayers.Control.Scale>
21
 */
22
OpenLayers.Control.ScaleLine = OpenLayers.Class(OpenLayers.Control, {
23

    
24
    /**
25
     * Property: maxWidth
26
     * {Integer} Maximum width of the scale line in pixels.  Default is 100.
27
     */
28
    maxWidth: 100,
29

    
30
    /**
31
     * Property: topOutUnits
32
     * {String} Units for zoomed out on top bar.  Default is km.
33
     */
34
    topOutUnits: "km",
35
    
36
    /**
37
     * Property: topInUnits
38
     * {String} Units for zoomed in on top bar.  Default is m.
39
     */
40
    topInUnits: "m",
41

    
42
    /**
43
     * Property: bottomOutUnits
44
     * {String} Units for zoomed out on bottom bar.  Default is mi.
45
     */
46
    bottomOutUnits: "mi",
47

    
48
    /**
49
     * Property: bottomInUnits
50
     * {String} Units for zoomed in on bottom bar.  Default is ft.
51
     */
52
    bottomInUnits: "ft",
53
    
54
    /**
55
     * Property: eTop
56
     * {DOMElement}
57
     */
58
    eTop: null,
59

    
60
    /**
61
     * Property: eBottom
62
     * {DOMElement}
63
     */
64
    eBottom:null,
65
    
66
    /**
67
     * APIProperty: geodesic
68
     * {Boolean} Use geodesic measurement. Default is false. The recommended
69
     * setting for maps in EPSG:4326 is false, and true EPSG:900913. If set to
70
     * true, the scale will be calculated based on the horizontal size of the
71
     * pixel in the center of the map viewport.
72
     */
73
    geodesic: false,
74

    
75
    /**
76
     * Constructor: OpenLayers.Control.ScaleLine
77
     * Create a new scale line control.
78
     * 
79
     * Parameters:
80
     * options - {Object} An optional object whose properties will be used
81
     *     to extend the control.
82
     */
83

    
84
    /**
85
     * Method: draw
86
     * 
87
     * Returns:
88
     * {DOMElement}
89
     */
90
    draw: function() {
91
        OpenLayers.Control.prototype.draw.apply(this, arguments);
92
        if (!this.eTop) {
93
            // stick in the top bar
94
            this.eTop = document.createElement("div");
95
            this.eTop.className = this.displayClass + "Top";
96
            var theLen = this.topInUnits.length;
97
            this.div.appendChild(this.eTop);
98
            if((this.topOutUnits == "") || (this.topInUnits == "")) {
99
                this.eTop.style.visibility = "hidden";
100
            } else {
101
                this.eTop.style.visibility = "visible";
102
            }
103

    
104
            // and the bottom bar
105
            this.eBottom = document.createElement("div");
106
            this.eBottom.className = this.displayClass + "Bottom";
107
            this.div.appendChild(this.eBottom);
108
            if((this.bottomOutUnits == "") || (this.bottomInUnits == "")) {
109
                this.eBottom.style.visibility = "hidden";
110
            } else {
111
                this.eBottom.style.visibility = "visible";
112
            }
113
        }
114
        this.map.events.register('moveend', this, this.update);
115
        this.update();
116
        return this.div;
117
    },
118

    
119
    /** 
120
     * Method: getBarLen
121
     * Given a number, round it down to the nearest 1,2,5 times a power of 10.
122
     * That seems a fairly useful set of number groups to use.
123
     * 
124
     * Parameters:
125
     * maxLen - {float}  the number we're rounding down from
126
     * 
127
     * Returns:
128
     * {Float} the rounded number (less than or equal to maxLen)
129
     */
130
    getBarLen: function(maxLen) {
131
        // nearest power of 10 lower than maxLen
132
        var digits = parseInt(Math.log(maxLen) / Math.log(10));
133
        var pow10 = Math.pow(10, digits);
134
        
135
        // ok, find first character
136
        var firstChar = parseInt(maxLen / pow10);
137

    
138
        // right, put it into the correct bracket
139
        var barLen;
140
        if(firstChar > 5) {
141
            barLen = 5;
142
        } else if(firstChar > 2) {
143
            barLen = 2;
144
        } else {
145
            barLen = 1;
146
        }
147

    
148
        // scale it up the correct power of 10
149
        return barLen * pow10;
150
    },
151

    
152
    /**
153
     * Method: update
154
     * Update the size of the bars, and the labels they contain.
155
     */
156
    update: function() {
157
        var res = this.map.getResolution();
158
        if (!res) {
159
            return;
160
        }
161

    
162
        var curMapUnits = this.map.getUnits();
163
        var inches = OpenLayers.INCHES_PER_UNIT;
164

    
165
        // convert maxWidth to map units
166
        var maxSizeData = this.maxWidth * res * inches[curMapUnits];
167
        var geodesicRatio = 1;
168
        if(this.geodesic === true) {
169
            var maxSizeGeodesic = (this.map.getGeodesicPixelSize().w ||
170
                0.000001) * this.maxWidth;
171
            var maxSizeKilometers = maxSizeData / inches["km"];
172
            geodesicRatio = maxSizeGeodesic / maxSizeKilometers;
173
            maxSizeData *= geodesicRatio;
174
        }
175

    
176
        // decide whether to use large or small scale units     
177
        var topUnits;
178
        var bottomUnits;
179
        if(maxSizeData > 100000) {
180
            topUnits = this.topOutUnits;
181
            bottomUnits = this.bottomOutUnits;
182
        } else {
183
            topUnits = this.topInUnits;
184
            bottomUnits = this.bottomInUnits;
185
        }
186

    
187
        // and to map units units
188
        var topMax = maxSizeData / inches[topUnits];
189
        var bottomMax = maxSizeData / inches[bottomUnits];
190

    
191
        // now trim this down to useful block length
192
        var topRounded = this.getBarLen(topMax);
193
        var bottomRounded = this.getBarLen(bottomMax);
194

    
195
        // and back to display units
196
        topMax = topRounded / inches[curMapUnits] * inches[topUnits];
197
        bottomMax = bottomRounded / inches[curMapUnits] * inches[bottomUnits];
198

    
199
        // and to pixel units
200
        var topPx = topMax / res / geodesicRatio;
201
        var bottomPx = bottomMax / res / geodesicRatio;
202
        
203
        // now set the pixel widths
204
        // and the values inside them
205
        
206
        if (this.eBottom.style.visibility == "visible"){
207
            this.eBottom.style.width = Math.round(bottomPx) + "px"; 
208
            this.eBottom.innerHTML = bottomRounded + " " + bottomUnits ;
209
        }
210
            
211
        if (this.eTop.style.visibility == "visible"){
212
            this.eTop.style.width = Math.round(topPx) + "px";
213
            this.eTop.innerHTML = topRounded + " " + topUnits;
214
        }
215
        
216
    }, 
217

    
218
    CLASS_NAME: "OpenLayers.Control.ScaleLine"
219
});
220

    
(31-31/45)