I need my OpenLayers application to be able to determine the current scale. This is not for display (there is already the scale line for that). This is because I have a scale-dependent style function, to display styles differently at different scales. I need to be able to do it according to scales, not resolutions, because the styles and their respective scales, are configured by the user, and the user enters scale values similar to how they would in a GIS for layer display constraints. (Ie, although scales are not great for on-screen, they are what users are used to using to constrain styles/layers to specific resolutions).

This is all working well in my app, changing styles as I zoom in and out. Except that my calculation of the current scale is incorrect. For testing purposes, I've simply calculating the scale (incorrectly) as:

resolution * DPI

I think that the correct way to calculate the scale would be:

resolution * meters-per-map-unit * inches-per-metre * DPI

The only part of this I cannot figure out is the metres-per-map-unit. there is the ol.proj.METERS_PER_UNIT lookup, but I can't use it because I don't know what the current unit is. My users may have swapped in any map of any projection in the application, so I need to be able to determine the current unit dynamically.

How can I get the current map unit from OpenLayers?

Or can I get it from proj4.js for the current projection? (and if so, is that the same thing?)

3 Answers 3


The units are within the projection of the view. From a map object, you can get it using:

var units = map.getView().getProjection().getUnits();

See also the API documentation of the ol.proj.Projection#getUnits method.

Here's also an example method to get the scale from a given resolution:

  'm': 39.37,
  'dd': 4374754
var DOTS_PER_INCH = 72;

 * @param {number} resolution Resolution.
 * @param {string} units Units
 * @param {boolean=} opt_round Whether to round the scale or not.
 * @return {number} Scale
var getScaleFromResolution = function(resolution, units, opt_round) {
  var scale = INCHES_PER_UNIT[units] * DOTS_PER_INCH * resolution;
  if (opt_round) {
    scale = Math.round(scale);
  return scale;
  • Thanks for this. I did actually search the documentation, but obviously not thoroughly enough. I will post the solution I ended up using as a seperate answer, as it is a littrle different to yours. But your answer was the basis of it, so I've accepted your answer. Jun 3, 2017 at 2:16
  • 1
    Why DOTS_PER_INCH = 72 ? Nov 28, 2018 at 10:07
  • Was inspired by the code back in OL2, see: github.com/openlayers/ol2/blob/release-2.13.1/lib/OpenLayers/… Nov 28, 2018 at 14:27
  • For anyone finding this several years later, and using Openlayers and Geoserver, note that Geoserver by default generates tiles at dpi of 90 not 72. I started with 72 and noticed it was not correct and did more research to find this detail when using WMS: The OGC standard output resolution is 90 DPI.
    – Brian B
    9 hours ago

Inspired by @Alexandre's answer, I came up with something a little different that suits my use-case better. In this case, I know that I have a map with a view and projection, and from that I can derive everything else required to calculate the scale except for the DPI. In my app, DPI cannot be hard-coded because the app runs on mobile devices with screens of variable resolutions. So DPI is the only parameter I pass in to my function.

This could all be done on one line, but I added the 3 var lines in order to make it more human readable.

This is what I've ended up using:

function mapScale (dpi) {
    var unit = map.getView().getProjection().getUnits();
    var resolution = map.getView().getResolution();
    var inchesPerMetre = 39.37;

    return resolution * ol.proj.METERS_PER_UNIT[unit] * inchesPerMetre * dpi;

I combined 2 answers that already exist and this is the result.

import Units, { METERS_PER_UNIT } from 'ol/proj/Units';

const DOTS_PER_INCH = 72;
const INCHES_PER_METRE = 39.37;

function inchesPreUnit(unit: Units): number {

function mapRatioScale({ map, toRound = true }): number {
    const resolution = map.getView().getResolution();
    const unit = map.getView().getProjection().getUnits();

    let scale = resolution * inchesPreUnit(unit) * DOTS_PER_INCH;
    return toRound ? Math.round(scale) : scale;

// usage
const scale = mapRatioScale({ map });

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.