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
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
map.addControl(new OpenLayers.Control.MouseToolbar());
|
map.addControl(new OpenLayers.Control.MouseToolbar());
|
||||||
map.addControl(new OpenLayers.Control.LayerSwitcher({'ascending':false}));
|
map.addControl(new OpenLayers.Control.LayerSwitcher({'ascending':false}));
|
||||||
map.addControl(new OpenLayers.Control.Permalink());
|
map.addControl(new OpenLayers.Control.Permalink());
|
||||||
|
map.addControl(new OpenLayers.Control.ScaleLine());
|
||||||
map.addControl(new OpenLayers.Control.Permalink('permalink'));
|
map.addControl(new OpenLayers.Control.Permalink('permalink'));
|
||||||
map.addControl(new OpenLayers.Control.MousePosition());
|
map.addControl(new OpenLayers.Control.MousePosition());
|
||||||
map.addControl(new OpenLayers.Control.OverviewMap());
|
map.addControl(new OpenLayers.Control.OverviewMap());
|
||||||
|
|||||||
@@ -149,6 +149,7 @@
|
|||||||
"OpenLayers/Control/ArgParser.js",
|
"OpenLayers/Control/ArgParser.js",
|
||||||
"OpenLayers/Control/Permalink.js",
|
"OpenLayers/Control/Permalink.js",
|
||||||
"OpenLayers/Control/Scale.js",
|
"OpenLayers/Control/Scale.js",
|
||||||
|
"OpenLayers/Control/ScaleLine.js",
|
||||||
"OpenLayers/Control/LayerSwitcher.js",
|
"OpenLayers/Control/LayerSwitcher.js",
|
||||||
"OpenLayers/Control/DrawFeature.js",
|
"OpenLayers/Control/DrawFeature.js",
|
||||||
"OpenLayers/Control/DragFeature.js",
|
"OpenLayers/Control/DragFeature.js",
|
||||||
|
|||||||
198
lib/OpenLayers/Control/ScaleLine.js
Normal file
198
lib/OpenLayers/Control/ScaleLine.js
Normal file
@@ -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:
|
||||||
|
* - <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,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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"
|
||||||
|
});
|
||||||
|
|
||||||
143
tests/Control/test_ScaleLine.html
Normal file
143
tests/Control/test_ScaleLine.html
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script src="../../lib/OpenLayers.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
function test_initialize(t) {
|
||||||
|
t.plan(2);
|
||||||
|
var control = new OpenLayers.Control.ScaleLine();
|
||||||
|
t.ok(control instanceof OpenLayers.Control.ScaleLine, "new OpenLayers.Control returns object" );
|
||||||
|
t.eq(control.displayClass, "olControlScaleLine", "displayClass is correct" );
|
||||||
|
control.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_initwithelem(t) {
|
||||||
|
t.plan(1);
|
||||||
|
var control = new OpenLayers.Control.ScaleLine({"div":OpenLayers.Util.getElement('ScaleLine')});
|
||||||
|
t.ok(true, "If this happens, then we passed. (FF throws an error above otherwise)");
|
||||||
|
control.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_calcDegrees(t) {
|
||||||
|
t.plan(5);
|
||||||
|
var control = new OpenLayers.Control.ScaleLine();
|
||||||
|
t.ok(control instanceof OpenLayers.Control.ScaleLine, "new OpenLayers.Control returns object" );
|
||||||
|
var map = new OpenLayers.Map('map');
|
||||||
|
var layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
|
||||||
|
map.addLayer(layer);
|
||||||
|
map.zoomTo(0);
|
||||||
|
map.addControl(control);
|
||||||
|
t.eq(control.div.firstChild.style.visibility, "visible", "top scale is present.");
|
||||||
|
t.eq(control.div.lastChild.style.visibility, "visible", "bottom scale is present.");
|
||||||
|
t.eq(control.div.firstChild.innerHTML, "10000 km", "top scale has correct text.");
|
||||||
|
t.eq(control.div.lastChild.innerHTML, "5000 mi", "bottom scale has correct text.");
|
||||||
|
map.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_calcsOther (t) {
|
||||||
|
t.plan(5);
|
||||||
|
var control = new OpenLayers.Control.ScaleLine();
|
||||||
|
t.ok(control instanceof OpenLayers.Control.ScaleLine, "new OpenLayers.Control returns object" );
|
||||||
|
var map = new OpenLayers.Map('map');
|
||||||
|
map.units = "mi";
|
||||||
|
var layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
|
||||||
|
map.addLayer(layer);
|
||||||
|
map.zoomTo(0);
|
||||||
|
map.addControl(control);
|
||||||
|
t.eq(control.div.firstChild.style.visibility, "visible", "top scale is present.");
|
||||||
|
t.eq(control.div.lastChild.style.visibility, "visible", "bottom scale is present.");
|
||||||
|
t.eq(control.div.firstChild.innerHTML, "100 km", "top scale has correct text.");
|
||||||
|
t.eq(control.div.lastChild.innerHTML, "100 mi", "bottom scale has correct text.");
|
||||||
|
map.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_calcMeters (t) {
|
||||||
|
t.plan(5);
|
||||||
|
// this example is taken from the projected-map.html OpenLayers example
|
||||||
|
var lat = 900863;
|
||||||
|
var lon = 235829;
|
||||||
|
var zoom = 6;
|
||||||
|
var map = new OpenLayers.Map( 'map' );
|
||||||
|
var basemap = new OpenLayers.Layer.WMS( "Boston",
|
||||||
|
"http://boston.freemap.in/cgi-bin/mapserv?",
|
||||||
|
{
|
||||||
|
map: '/www/freemap.in/boston/map/gmaps.map',
|
||||||
|
layers: 'border,water,roads,rapid_transit,buildings',
|
||||||
|
format: 'png',
|
||||||
|
transparent: 'off'
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656),
|
||||||
|
maxResolution: 296985/1024,
|
||||||
|
projection:"EPSG:2805", // Used in WMS/WFS requests.
|
||||||
|
units: "m" // Only neccesary for working with scales.
|
||||||
|
} );
|
||||||
|
|
||||||
|
map.addLayer(basemap);
|
||||||
|
map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
|
||||||
|
map.addControl(new OpenLayers.Control.LayerSwitcher());
|
||||||
|
var control = new OpenLayers.Control.ScaleLine();
|
||||||
|
t.ok( control instanceof OpenLayers.Control.ScaleLine, "new OpenLayers.Control returns object" );
|
||||||
|
map.addControl(control);
|
||||||
|
t.eq(control.div.firstChild.style.visibility, "visible", "top scale is present.");
|
||||||
|
t.eq(control.div.lastChild.style.visibility, "visible", "bottom scale is present.");
|
||||||
|
t.eq(control.div.firstChild.innerHTML, "20000 km", "top scale has correct text.");
|
||||||
|
t.eq(control.div.lastChild.innerHTML, "20000 mi", "bottom scale has correct text.");
|
||||||
|
map.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_useArguments (t) {
|
||||||
|
t.plan(5);
|
||||||
|
var control = new OpenLayers.Control.ScaleLine({topOutUnits: 'dd'} );
|
||||||
|
t.ok( control instanceof OpenLayers.Control.ScaleLine, "new OpenLayers.Control returns object" );
|
||||||
|
var map = new OpenLayers.Map('map');
|
||||||
|
var layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
|
||||||
|
map.addLayer(layer);
|
||||||
|
map.zoomTo(0);
|
||||||
|
map.addControl(control);
|
||||||
|
t.eq(control.div.firstChild.style.visibility, "visible", "top scale is present.");
|
||||||
|
t.eq(control.div.lastChild.style.visibility, "visible", "bottom scale is present.");
|
||||||
|
t.eq(control.div.firstChild.innerHTML, "100 dd", "top scale has correct text.");
|
||||||
|
t.eq(control.div.lastChild.innerHTML, "5000 mi", "bottom scale has correct text.");
|
||||||
|
map.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_respectZoom (t) {
|
||||||
|
t.plan(5);
|
||||||
|
|
||||||
|
// ok, switch the units we use for zoomed in values. This will test that we're both
|
||||||
|
// correctly respecting all specified parameters and that we're switching to the
|
||||||
|
// "in" units when zoomed in
|
||||||
|
var control = new OpenLayers.Control.ScaleLine({topOutUnits : "mi", bottomOutUnits: "km", topInUnits: 'ft', bottomInUnits: 'm'});
|
||||||
|
t.ok( control instanceof OpenLayers.Control.ScaleLine, "new OpenLayers.Control returns object" );
|
||||||
|
var map = new OpenLayers.Map('map');
|
||||||
|
var layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
|
||||||
|
map.addLayer(layer);
|
||||||
|
map.zoomTo(0);
|
||||||
|
map.addControl(control);
|
||||||
|
t.eq(control.div.firstChild.innerHTML, "5000 mi", "top scale respects constructor parameter.");
|
||||||
|
t.eq(control.div.lastChild.innerHTML, "10000 km", "bottom scale respects constructor parameter.");
|
||||||
|
map.zoomIn();
|
||||||
|
map.zoomIn();
|
||||||
|
map.zoomIn();
|
||||||
|
map.zoomIn();
|
||||||
|
map.zoomIn();
|
||||||
|
map.zoomIn();
|
||||||
|
map.zoomIn();
|
||||||
|
map.zoomIn();
|
||||||
|
map.zoomIn();
|
||||||
|
map.zoomIn();
|
||||||
|
map.zoomIn();
|
||||||
|
|
||||||
|
t.eq(control.div.firstChild.innerHTML, "10000 ft", "top scale zooms in & respects constructor parameter.");
|
||||||
|
t.eq(control.div.lastChild.innerHTML, "5000 m", "bottom scale zooms in & respects constructor parameter.");
|
||||||
|
map.destroy();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a id="ScaleLine" href="">ScaleLine</a> <br />
|
||||||
|
<div id="map" style="width: 1024px; height: 512px;"/>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -93,6 +93,7 @@
|
|||||||
<li>Control/test_PanZoomBar.html</li>
|
<li>Control/test_PanZoomBar.html</li>
|
||||||
<li>Control/test_Permalink.html</li>
|
<li>Control/test_Permalink.html</li>
|
||||||
<li>Control/test_Scale.html</li>
|
<li>Control/test_Scale.html</li>
|
||||||
|
<li>Control/test_ScaleLine.html</li>
|
||||||
<li>Control/test_SelectFeature.html</li>
|
<li>Control/test_SelectFeature.html</li>
|
||||||
<li>test_Handler.html</li>
|
<li>test_Handler.html</li>
|
||||||
<li>Handler/test_Click.html</li>
|
<li>Handler/test_Click.html</li>
|
||||||
|
|||||||
@@ -24,6 +24,23 @@ div.olLayerDiv {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
font-size: smaller;
|
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 {
|
.olControlPermalink {
|
||||||
right: 3px;
|
right: 3px;
|
||||||
bottom: 1.5em;
|
bottom: 1.5em;
|
||||||
|
|||||||
Reference in New Issue
Block a user