]> dev.renevier.net Git - syp.git/blob - openlayers/lib/OpenLayers/Control/ScaleLine.js
initial commit
[syp.git] / openlayers / lib / OpenLayers / Control / ScaleLine.js
1 /* Copyright (c) 2006-2007 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  * @requires OpenLayers/Control.js
7  */
8
9 /**
10  * Class: OpenLayers.Control.ScaleLine
11  * The ScaleLine displays a small line indicator representing the current 
12  * map scale on the map. By default it is drawn in the lower left corner of
13  * the map.
14  * 
15  * Inherits from:
16  *  - <OpenLayers.Control>
17  *  
18  * Is a very close copy of:
19  *  - <OpenLayers.Control.Scale>
20  */
21 OpenLayers.Control.ScaleLine = OpenLayers.Class(OpenLayers.Control, {
22
23     /**
24      * Property: maxWidth
25      * {Integer} Maximum width of the scale line in pixels.  Default is 100.
26      */
27     maxWidth: 100,
28
29     /**
30      * Property: topOutUnits
31      * {String} Units for zoomed out on top bar.  Default is km.
32      */
33     topOutUnits: "km",
34     
35     /**
36      * Property: topInUnits
37      * {String} Units for zoomed in on top bar.  Default is m.
38      */
39     topInUnits: "m",
40
41     /**
42      * Property: bottomOutUnits
43      * {String} Units for zoomed out on bottom bar.  Default is mi.
44      */
45     bottomOutUnits: "mi",
46
47     /**
48      * Property: bottomInUnits
49      * {String} Units for zoomed in on bottom bar.  Default is ft.
50      */
51     bottomInUnits: "ft",
52     
53     /**
54      * Property: eTop
55      * {DOMElement}
56      */
57     eTop: null,
58
59     /**
60      * Property: eBottom
61      * {DOMElement}
62      */
63     eBottom:null,
64
65     /**
66      * Constructor: OpenLayers.Control.ScaleLine
67      * Create a new scale line control.
68      * 
69      * Parameters:
70      * options - {Object} An optional object whose properties will be used
71      *     to extend the control.
72      */
73     initialize: function(options) {
74         OpenLayers.Control.prototype.initialize.apply(this, [options]);     
75     },
76
77     /**
78      * Method: draw
79      * 
80      * Returns:
81      * {DOMElement}
82      */
83     draw: function() {
84         OpenLayers.Control.prototype.draw.apply(this, arguments);
85         if (!this.eTop) {
86             this.div.style.display = "block";
87             this.div.style.position = "absolute";
88             
89             // stick in the top bar
90             this.eTop = document.createElement("div");
91             this.eTop.className = this.displayClass + "Top";
92             var theLen = this.topInUnits.length;
93             this.div.appendChild(this.eTop);
94             if((this.topOutUnits == "") || (this.topInUnits == "")) {
95                 this.eTop.style.visibility = "hidden";
96             } else {
97                 this.eTop.style.visibility = "visible";
98             }
99
100             // and the bottom bar
101             this.eBottom = document.createElement("div");
102             this.eBottom.className = this.displayClass + "Bottom";
103             this.div.appendChild(this.eBottom);
104             if((this.bottomOutUnits == "") || (this.bottomInUnits == "")) {
105                 this.eBottom.style.visibility = "hidden";
106             } else {
107                 this.eBottom.style.visibility = "visible";
108             }
109         }
110         this.map.events.register('moveend', this, this.update);
111         this.update();
112         return this.div;
113     },
114
115     /** 
116      * Method: getBarLen
117      * Given a number, round it down to the nearest 1,2,5 times a power of 10.
118      * That seems a fairly useful set of number groups to use.
119      * 
120      * Parameters:
121      * maxLen - {float}  the number we're rounding down from
122      * 
123      * Returns:
124      * {Float} the rounded number (less than or equal to maxLen)
125      */
126     getBarLen: function(maxLen) {
127         // nearest power of 10 lower than maxLen
128         var digits = parseInt(Math.log(maxLen) / Math.log(10));
129         var pow10 = Math.pow(10, digits);
130         
131         // ok, find first character
132         var firstChar = parseInt(maxLen / pow10);
133
134         // right, put it into the correct bracket
135         var barLen;
136         if(firstChar > 5) {
137             barLen = 5;
138         } else if(firstChar > 2) {
139             barLen = 2;
140         } else {
141             barLen = 1;
142         }
143
144         // scale it up the correct power of 10
145         return barLen * pow10;
146     },
147
148     /**
149      * Method: update
150      * Update the size of the bars, and the labels they contain.
151      */
152     update: function() {
153         var res = this.map.getResolution();
154         if (!res) {
155             return;
156         }
157
158         var curMapUnits = this.map.getUnits();
159         var inches = OpenLayers.INCHES_PER_UNIT;
160
161         // convert maxWidth to map units
162         var maxSizeData = this.maxWidth * res * inches[curMapUnits];  
163
164         // decide whether to use large or small scale units     
165         var topUnits;
166         var bottomUnits;
167         if(maxSizeData > 100000) {
168             topUnits = this.topOutUnits;
169             bottomUnits = this.bottomOutUnits;
170         } else {
171             topUnits = this.topInUnits;
172             bottomUnits = this.bottomInUnits;
173         }
174
175         // and to map units units
176         var topMax = maxSizeData / inches[topUnits];
177         var bottomMax = maxSizeData / inches[bottomUnits];
178
179         // now trim this down to useful block length
180         var topRounded = this.getBarLen(topMax);
181         var bottomRounded = this.getBarLen(bottomMax);
182
183         // and back to display units
184         topMax = topRounded / inches[curMapUnits] * inches[topUnits];
185         bottomMax = bottomRounded / inches[curMapUnits] * inches[bottomUnits];
186
187         // and to pixel units
188         var topPx = topMax / res;
189         var bottomPx = bottomMax / res;
190         
191         // now set the pixel widths
192         // and the values inside them
193         
194         if (this.eBottom.style.visibility == "visible"){
195             this.eBottom.style.width = Math.round(bottomPx) + "px"; 
196             this.eBottom.innerHTML = bottomRounded + " " + bottomUnits ;
197         }
198             
199         if (this.eTop.style.visibility == "visible"){
200             this.eTop.style.width = Math.round(topPx) + "px";
201             this.eTop.innerHTML = topRounded + " " + topUnits;
202         }
203         
204     }, 
205
206     CLASS_NAME: "OpenLayers.Control.ScaleLine"
207 });
208