Within Europe, both imperial & metric measuring scales are used. Integrating both types of scalelines is fundamental to providing mapping applications when catering for the European market.
When using the OpenLayers map library to create an online map, adding both a metric and imperial scaleline to the same map is awkward, whereas using the Leaflet map library it is a default option.
I struggled to find a simple working example or any guidance online to achieve two scalelines with OpenLayers. After a fair amount of experimentation around how OpenLayers handles map controls & positioning, I got it working so I thought I would share.
Example
The map below is a working example of the effect; see the bottom left corner of the map as you use the zoom control, top left:
Let's code it
The concept is simple: Add a map, add two scalelines below the map, then style both scalelines upwards over the map.
The code below assumes you already have an HTML document. You can place all of this code together in the body element in the order presented. This is unlikely the optimum positioning for your build, but it will work to get you going...
Add some CSS to style the map. This CSS will also move the two scaleline div elements back up over the map:
<style>
#map{
height:180px;
width:100%;
z-index:0;
}
/* Move the scaleline div elements back up over the map */
.scaleline-external{
position: relative;
width: fit-content;
top: -47px;
padding-top:2px;
}
/* Override default OpenLayers absolute position behaviour */
.ol-scale-line{
position: relative;
}
</style>
Finally, add some Javascript to initiate the map and add both scalelines:
<script>
// Initiate the map
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.XYZ({
urls : [
"https://stamen-tiles-a.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.png",
"https://stamen-tiles-b.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.png",
"https://stamen-tiles-c.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.png",
"https://stamen-tiles-d.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.png"
]
})
})
],
view: new ol.View({
center: ol.proj.fromLonLat([-2.7, 51]),
zoom: 9
})
});
// Create the scalelines within the two div elements
var scaleLineMetric = new ol.control.ScaleLine({
units: ['metric'],
target: document.getElementById("scaleline-metric")
});
var scaleLineImperial = new ol.control.ScaleLine({
units: ['imperial'],
target: document.getElementById("scaleline-imperial")
});
// Add the scaleline controls to the map
map.addControl(scaleLineMetric);
map.addControl(scaleLineImperial);
</script>