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