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. */
6 * @requires OpenLayers/Control.js
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
16 * - <OpenLayers.Control>
18 * Is a very close copy of:
19 * - <OpenLayers.Control.Scale>
21 OpenLayers.Control.ScaleLine = OpenLayers.Class(OpenLayers.Control, {
25 * {Integer} Maximum width of the scale line in pixels. Default is 100.
30 * Property: topOutUnits
31 * {String} Units for zoomed out on top bar. Default is km.
36 * Property: topInUnits
37 * {String} Units for zoomed in on top bar. Default is m.
42 * Property: bottomOutUnits
43 * {String} Units for zoomed out on bottom bar. Default is mi.
48 * Property: bottomInUnits
49 * {String} Units for zoomed in on bottom bar. Default is ft.
66 * Constructor: OpenLayers.Control.ScaleLine
67 * Create a new scale line control.
70 * options - {Object} An optional object whose properties will be used
71 * to extend the control.
73 initialize: function(options) {
74 OpenLayers.Control.prototype.initialize.apply(this, [options]);
84 OpenLayers.Control.prototype.draw.apply(this, arguments);
86 this.div.style.display = "block";
87 this.div.style.position = "absolute";
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";
97 this.eTop.style.visibility = "visible";
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";
107 this.eBottom.style.visibility = "visible";
110 this.map.events.register('moveend', this, this.update);
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.
121 * maxLen - {float} the number we're rounding down from
124 * {Float} the rounded number (less than or equal to maxLen)
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);
131 // ok, find first character
132 var firstChar = parseInt(maxLen / pow10);
134 // right, put it into the correct bracket
138 } else if(firstChar > 2) {
144 // scale it up the correct power of 10
145 return barLen * pow10;
150 * Update the size of the bars, and the labels they contain.
153 var res = this.map.getResolution();
158 var curMapUnits = this.map.getUnits();
159 var inches = OpenLayers.INCHES_PER_UNIT;
161 // convert maxWidth to map units
162 var maxSizeData = this.maxWidth * res * inches[curMapUnits];
164 // decide whether to use large or small scale units
167 if(maxSizeData > 100000) {
168 topUnits = this.topOutUnits;
169 bottomUnits = this.bottomOutUnits;
171 topUnits = this.topInUnits;
172 bottomUnits = this.bottomInUnits;
175 // and to map units units
176 var topMax = maxSizeData / inches[topUnits];
177 var bottomMax = maxSizeData / inches[bottomUnits];
179 // now trim this down to useful block length
180 var topRounded = this.getBarLen(topMax);
181 var bottomRounded = this.getBarLen(bottomMax);
183 // and back to display units
184 topMax = topRounded / inches[curMapUnits] * inches[topUnits];
185 bottomMax = bottomRounded / inches[curMapUnits] * inches[bottomUnits];
187 // and to pixel units
188 var topPx = topMax / res;
189 var bottomPx = bottomMax / res;
191 // now set the pixel widths
192 // and the values inside them
194 if (this.eBottom.style.visibility == "visible"){
195 this.eBottom.style.width = Math.round(bottomPx) + "px";
196 this.eBottom.innerHTML = bottomRounded + " " + bottomUnits ;
199 if (this.eTop.style.visibility == "visible"){
200 this.eTop.style.width = Math.round(topPx) + "px";
201 this.eTop.innerHTML = topRounded + " " + topUnits;
206 CLASS_NAME: "OpenLayers.Control.ScaleLine"