How do I change the scale displayed in Google Maps API v3 to imperial (miles) units

I'm simply displaying a map, with no routing or directions. I can add the control with mapOptions = {...scaleControl: true,...} but I could find no documentation about changing the units of the scale to imperial.

Here's my code:

var mapOptions = {
    zoom: 4,
    mapTypeControl: false,
    center: new google.maps.LatLng(38.8282, -98.5795),
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    scaleControl: true,
    scaleControlOptions: {position: google.maps.ControlPosition.BOTTOM_LEFT}
};
google.maps.visualRefresh = true;

map = new google.maps.Map(document.getElementById('map'),mapOptions);   

Note: The ControlPosition appears not to work, always goes to bottom right.

Answers


Try this temp solution (here it is in a ready function):

var scaleInterval = setInterval(function() {
  var scale = $(".gm-style-cc:not(.gmnoprint):contains(' km')");
  if (scale.length) {
    scale.click();
    clearInterval(scaleInterval);
  }
}, 100);

The answer by Memory Leak does not work for all cases since at some zoom levels " m" is used instead of " km", requiring a RegExp treatment (and his solution requires jQuery). I was able to get the solution by Xion Dark to work after expanding the RegExp to (m|km) and changing to innerHTML - using innerText did not work for me in Firefox (and may explain why James Bell could not get that answer to work).

My complete solution (where I've hard-wired the required map id "map_canvas")

var scaleInterval = setInterval( function() {
  var spn = document.getElementById('map_canvas').getElementsByTagName('span');
  var pattern = /\d+\s+(m|km)/i;
  for(var i in spn) {
    if ( pattern.test(spn[i].innerHTML) ) {
      spn[i].click();
      clearInterval(scaleInterval);
    }
  }
}, 500);
setTimeout( function() { clearInterval(scaleInterval) }, 20000 );

This works in Firefox 31 and Chrome 37 and IE 10. The setTimeout is included to prevent it running indefinitely, since this is sort of a kludge and might stop working should GM change their scale html - and in case the scale units someday start out with the desired ft/mi units instead of the current metric units.

Note: when first testing this with IE 10 as a white box appeared in the scale area. I first thought that was due to my code but the same occurred when I removed the code. Finally I determined it was due to "Compatability View" (an IE 7 emulator which I'd not known about as I seldom use IE) being inadvertently turned on - for which, the scale bar does not display correctly. Using IE 10 in "standard" mode, the GM scale did display correctly (and my code did work). Just wanted to warn any others without much experience of IE who might run into the same thing and get confused, as I was


The scale control display shows both metric and imperial units (example from documentation)

The ScaleControl position will not be controllable with the visual refresh (google.maps.visualRefresh = true;)


I came here from the Google Issue Tracker https://issuetracker.google.com/issues/35825255

Here's an improved full example of the "click hack" from earlier posts:

  • uses just js (not Jquery)
  • regex to only match "km" and "m"
  • waits 1 second so Google Map can fully load first

#map {
  height: 100%;
}
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
<div id="map"></div>
<script>
  var map;
  function initMap() {
    map = new google.maps.Map(document.getElementById('map'), {
      center: { lat: 42.331534, lng: -83.046651 },
      zoom: 12,
      scaleControl: true
    });

    //START hack to set scale to miles/imperial instead of km/metric:
    window.setTimeout(function() {
      var spn = document.getElementById("map").getElementsByClassName("gm-style-cc");
      for (var i in spn) {
        //look for km or m in innerText via regex https://regexr.com/3hiqa
        if ((/\d\s?(km|(m\b))/g).test(spn[i].innerText)) {
          spn[i].click();
        }
      }
    }, 1000);
    //END hack to set scale to miles/imperial instead of km/metric

  }
</script>
<script src="https://maps.googleapis.com/maps/api/js?callback=initMap" async defer></script>

Ok so I came up with this BUT I would use this as a short term fix only.

function switchScale(mapId){
    var spn = document.getElementById(mapId).getElementsByTagName("span");
    for(var i in spn){ 
        if( (/\d+\s?(mi|km)/g).test(spn[i].innerText) ){ 
            spn[i].click(); 
        } 
    }
}

This worked in chrome but I've heard that '.click()' can cause issues in some browser that use '.onclick()' instead.


Need Your Help

How to emulate a Tap Event in Windows Phone?

c# windows-phone-8

How I can emulate a tap on a TimeSpanPicker(coding4fun) in code?

New Presentation Layer for Webapplication

asp.net-mvc silverlight presentation-layer

we've got an existing webapplication written in magic. But now we eventually want to exchange the existing web-presentation layer (maybe also rich client) to a server side presentation layer. What ...