|
/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for |
|
* full list of contributors). Published under the Clear BSD license. |
|
* See http://svn.openlayers.org/trunk/openlayers/license.txt for the |
|
* full text of the license. */ |
|
|
|
/** |
|
* @requires OpenLayers/Control.js |
|
*/ |
|
|
|
/** |
|
* Class: OpenLayers.Control.ScaleLine |
|
* The ScaleLine displays a small line indicator representing the current |
|
* map scale on the map. By default it is drawn in the lower left corner of |
|
* the map. |
|
* |
|
* Inherits from: |
|
* - <OpenLayers.Control> |
|
* |
|
* Is a very close copy of: |
|
* - <OpenLayers.Control.Scale> |
|
*/ |
|
OpenLayers.Control.ScaleLine = OpenLayers.Class(OpenLayers.Control, { |
|
|
|
/** |
|
* Property: maxWidth |
|
* {Integer} Maximum width of the scale line in pixels. Default is 100. |
|
*/ |
|
maxWidth: 100, |
|
|
|
/** |
|
* Property: topOutUnits |
|
* {String} Units for zoomed out on top bar. Default is km. |
|
*/ |
|
topOutUnits: "km", |
|
|
|
/** |
|
* Property: topInUnits |
|
* {String} Units for zoomed in on top bar. Default is m. |
|
*/ |
|
topInUnits: "m", |
|
|
|
/** |
|
* Property: bottomOutUnits |
|
* {String} Units for zoomed out on bottom bar. Default is mi. |
|
*/ |
|
bottomOutUnits: "mi", |
|
|
|
/** |
|
* Property: bottomInUnits |
|
* {String} Units for zoomed in on bottom bar. Default is ft. |
|
*/ |
|
bottomInUnits: "ft", |
|
|
|
/** |
|
* Property: eTop |
|
* {DOMElement} |
|
*/ |
|
eTop: null, |
|
|
|
/** |
|
* Property: eBottom |
|
* {DOMElement} |
|
*/ |
|
eBottom:null, |
|
|
|
/** |
|
* APIProperty: geodesic |
|
* {Boolean} Use geodesic measurement. Default is false. The recommended |
|
* setting for maps in EPSG:4326 is false, and true EPSG:900913. If set to |
|
* true, the scale will be calculated based on the horizontal size of the |
|
* pixel in the center of the map viewport. |
|
*/ |
|
geodesic: false, |
|
|
|
/** |
|
* Constructor: OpenLayers.Control.ScaleLine |
|
* Create a new scale line control. |
|
* |
|
* Parameters: |
|
* options - {Object} An optional object whose properties will be used |
|
* to extend the control. |
|
*/ |
|
initialize: function(options) { |
|
OpenLayers.Control.prototype.initialize.apply(this, [options]); |
|
}, |
|
|
|
/** |
|
* Method: draw |
|
* |
|
* Returns: |
|
* {DOMElement} |
|
*/ |
|
draw: function() { |
|
OpenLayers.Control.prototype.draw.apply(this, arguments); |
|
if (!this.eTop) { |
|
// stick in the top bar |
|
this.eTop = document.createElement("div"); |
|
this.eTop.className = this.displayClass + "Top"; |
|
var theLen = this.topInUnits.length; |
|
this.div.appendChild(this.eTop); |
|
if((this.topOutUnits == "") || (this.topInUnits == "")) { |
|
this.eTop.style.visibility = "hidden"; |
|
} else { |
|
this.eTop.style.visibility = "visible"; |
|
} |
|
|
|
// and the bottom bar |
|
this.eBottom = document.createElement("div"); |
|
this.eBottom.className = this.displayClass + "Bottom"; |
|
this.div.appendChild(this.eBottom); |
|
if((this.bottomOutUnits == "") || (this.bottomInUnits == "")) { |
|
this.eBottom.style.visibility = "hidden"; |
|
} else { |
|
this.eBottom.style.visibility = "visible"; |
|
} |
|
} |
|
this.map.events.register('moveend', this, this.update); |
|
this.update(); |
|
return this.div; |
|
}, |
|
|
|
/** |
|
* Method: getBarLen |
|
* Given a number, round it down to the nearest 1,2,5 times a power of 10. |
|
* That seems a fairly useful set of number groups to use. |
|
* |
|
* Parameters: |
|
* maxLen - {float} the number we're rounding down from |
|
* |
|
* Returns: |
|
* {Float} the rounded number (less than or equal to maxLen) |
|
*/ |
|
getBarLen: function(maxLen) { |
|
// nearest power of 10 lower than maxLen |
|
var digits = parseInt(Math.log(maxLen) / Math.log(10)); |
|
var pow10 = Math.pow(10, digits); |
|
|
|
// ok, find first character |
|
var firstChar = parseInt(maxLen / pow10); |
|
|
|
// right, put it into the correct bracket |
|
var barLen; |
|
if(firstChar > 5) { |
|
barLen = 5; |
|
} else if(firstChar > 2) { |
|
barLen = 2; |
|
} else { |
|
barLen = 1; |
|
} |
|
|
|
// scale it up the correct power of 10 |
|
return barLen * pow10; |
|
}, |
|
|
|
/** |
|
* Method: update |
|
* Update the size of the bars, and the labels they contain. |
|
*/ |
|
update: function() { |
|
var res = this.map.getResolution(); |
|
if (!res) { |
|
return; |
|
} |
|
|
|
var curMapUnits = this.map.getUnits(); |
|
var inches = OpenLayers.INCHES_PER_UNIT; |
|
|
|
// convert maxWidth to map units |
|
var maxSizeData = this.maxWidth * res * inches[curMapUnits]; |
|
var geodesicRatio = 1; |
|
if(this.geodesic === true) { |
|
var maxSizeGeodesic = (this.map.getGeodesicPixelSize().w || |
|
0.000001) * this.maxWidth; |
|
var maxSizeKilometers = maxSizeData / inches["km"]; |
|
geodesicRatio = maxSizeGeodesic / maxSizeKilometers; |
|
maxSizeData *= geodesicRatio; |
|
} |
|
|
|
// decide whether to use large or small scale units |
|
var topUnits; |
|
var bottomUnits; |
|
if(maxSizeData > 100000) { |
|
topUnits = this.topOutUnits; |
|
bottomUnits = this.bottomOutUnits; |
|
} else { |
|
topUnits = this.topInUnits; |
|
bottomUnits = this.bottomInUnits; |
|
} |
|
|
|
// and to map units units |
|
var topMax = maxSizeData / inches[topUnits]; |
|
var bottomMax = maxSizeData / inches[bottomUnits]; |
|
|
|
// now trim this down to useful block length |
|
var topRounded = this.getBarLen(topMax); |
|
var bottomRounded = this.getBarLen(bottomMax); |
|
|
|
// and back to display units |
|
topMax = topRounded / inches[curMapUnits] * inches[topUnits]; |
|
bottomMax = bottomRounded / inches[curMapUnits] * inches[bottomUnits]; |
|
|
|
// and to pixel units |
|
var topPx = topMax / res / geodesicRatio; |
|
var bottomPx = bottomMax / res / geodesicRatio; |
|
|
|
// now set the pixel widths |
|
// and the values inside them |
|
|
|
if (this.eBottom.style.visibility == "visible"){ |
|
this.eBottom.style.width = Math.round(bottomPx) + "px"; |
|
this.eBottom.innerHTML = bottomRounded + " " + bottomUnits ; |
|
} |
|
|
|
if (this.eTop.style.visibility == "visible"){ |
|
this.eTop.style.width = Math.round(topPx) + "px"; |
|
this.eTop.innerHTML = topRounded + " " + topUnits; |
|
} |
|
|
|
}, |
|
|
|
CLASS_NAME: "OpenLayers.Control.ScaleLine" |
|
}); |
|
|
|
|