From db77398339bcfea0314734b51d1502741e1dabd4 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Sat, 9 Feb 2008 19:39:12 +0000 Subject: [PATCH] Thanks Ian Mayo for this nice ScaleLine control. Give your maps a dualie scale line control customizable with CSS. r=crschmidt (closes #1089) git-svn-id: http://svn.openlayers.org/trunk/openlayers@6177 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf --- examples/controls.html | 1 + lib/OpenLayers.js | 1 + lib/OpenLayers/Control/ScaleLine.js | 198 ++++++++++++++++++++++++++++ tests/Control/test_ScaleLine.html | 143 ++++++++++++++++++++ tests/list-tests.html | 1 + theme/default/style.css | 17 +++ 6 files changed, 361 insertions(+) create mode 100644 lib/OpenLayers/Control/ScaleLine.js create mode 100644 tests/Control/test_ScaleLine.html diff --git a/examples/controls.html b/examples/controls.html index 560cede428..5f2367d96a 100644 --- a/examples/controls.html +++ b/examples/controls.html @@ -20,6 +20,7 @@ map.addControl(new OpenLayers.Control.MouseToolbar()); map.addControl(new OpenLayers.Control.LayerSwitcher({'ascending':false})); map.addControl(new OpenLayers.Control.Permalink()); + map.addControl(new OpenLayers.Control.ScaleLine()); map.addControl(new OpenLayers.Control.Permalink('permalink')); map.addControl(new OpenLayers.Control.MousePosition()); map.addControl(new OpenLayers.Control.OverviewMap()); diff --git a/lib/OpenLayers.js b/lib/OpenLayers.js index b8e47cfb83..1cfa636cff 100644 --- a/lib/OpenLayers.js +++ b/lib/OpenLayers.js @@ -149,6 +149,7 @@ "OpenLayers/Control/ArgParser.js", "OpenLayers/Control/Permalink.js", "OpenLayers/Control/Scale.js", + "OpenLayers/Control/ScaleLine.js", "OpenLayers/Control/LayerSwitcher.js", "OpenLayers/Control/DrawFeature.js", "OpenLayers/Control/DragFeature.js", diff --git a/lib/OpenLayers/Control/ScaleLine.js b/lib/OpenLayers/Control/ScaleLine.js new file mode 100644 index 0000000000..33a0e7e384 --- /dev/null +++ b/lib/OpenLayers/Control/ScaleLine.js @@ -0,0 +1,198 @@ +/* Copyright (c) 2006-2007 MetaCarta, Inc., published under a modified BSD license. + * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt + * for the full text of the license. */ + +/** + * @requires OpenLayers/Control.js + * + * Class: OpenLayers.Control.ScaleLine + * Display a small line indicator representing the current map scale on the map. + * + * Inherits from: + * - + * + * Is a very close copy of: + * - + */ +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, + + /** + * Constructor: OpenLayers.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) { + this.div.className = this.displayClass; + this.div.style.display = "block"; + this.div.style.position = "absolute"; + + // 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; + } + + // convert maxWidth to map units + var maxSizeData = this.maxWidth * res; + + // decide whether to use large or small scale units + var topUnits; + var bottomUnits; + if(maxSizeData > 0.1) { + topUnits = this.topOutUnits; + bottomUnits = this.bottomOutUnits; + } else { + topUnits = this.topInUnits; + bottomUnits = this.bottomInUnits; + } + + // and to map units units + var curMapUnits = this.map.units; + var inches = OpenLayers.INCHES_PER_UNIT; + var topMax = maxSizeData * inches[curMapUnits] / inches[topUnits]; + var bottomMax = maxSizeData * inches[curMapUnits] / 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; + var bottomPx = bottomMax / res; + + // now set the pixel widths + this.eTop.style.width = Math.round(topPx) + "px"; + this.eBottom.style.width = Math.round(bottomPx) + "px"; + + // and the values inside them + this.eTop.innerHTML = topRounded + " " + topUnits; + this.eBottom.innerHTML = bottomRounded + " " + bottomUnits ; + }, + + CLASS_NAME: "OpenLayers.Control.ScaleLine" +}); + diff --git a/tests/Control/test_ScaleLine.html b/tests/Control/test_ScaleLine.html new file mode 100644 index 0000000000..f5b5705fca --- /dev/null +++ b/tests/Control/test_ScaleLine.html @@ -0,0 +1,143 @@ + + + + + + + ScaleLine
+
+ + diff --git a/tests/list-tests.html b/tests/list-tests.html index b947ff9a55..158c2ddb4e 100644 --- a/tests/list-tests.html +++ b/tests/list-tests.html @@ -93,6 +93,7 @@
  • Control/test_PanZoomBar.html
  • Control/test_Permalink.html
  • Control/test_Scale.html
  • +
  • Control/test_ScaleLine.html
  • Control/test_SelectFeature.html
  • test_Handler.html
  • Handler/test_Click.html
  • diff --git a/theme/default/style.css b/theme/default/style.css index a0e92093e4..702d97a20f 100644 --- a/theme/default/style.css +++ b/theme/default/style.css @@ -24,6 +24,23 @@ div.olLayerDiv { position: absolute; font-size: smaller; } +.olControlScaleLine { + left: 10px; + bottom: 15px; + font-size: xx-small; +} +.olControlScaleLineBottom { + border: solid 2px black; + border-bottom: none; + margin-top:-2px; + text-align: center; +} +.olControlScaleLineTop { + border: solid 2px black; + border-top: none; + text-align: center; +} + .olControlPermalink { right: 3px; bottom: 1.5em;