text: // constants
  var TAU = 2 * Math.PI;
  var EQUATORIAL_RADIUS = 6356752.314245179;
  var POLAR_RADIUS = 6378137.0;
  
  
  export function geoLatToMeters(dLat) {
      return dLat * (TAU * POLAR_RADIUS / 360);
  }
  
  
  export function geoLonToMeters(dLon, atLat) {
      return Math.abs(atLat) >= 90 ? 0 :
          dLon * (TAU * EQUATORIAL_RADIUS / 360) * Math.abs(Math.cos(atLat * (Math.PI / 180)));
  }
  
  
  export function geoMetersToLat(m) {
      return m / (TAU * POLAR_RADIUS / 360);
  }
  
  
  export function geoMetersToLon(m, atLat) {
      return Math.abs(atLat) >= 90 ? 0 :
          m / (TAU * EQUATORIAL_RADIUS / 360) / Math.abs(Math.cos(atLat * (Math.PI / 180)));
  }
  
  
  export function geoMetersToOffset(meters, tileSize) {
      tileSize = tileSize || 256;
      return [
          meters[0] * tileSize / (TAU * EQUATORIAL_RADIUS),
          -meters[1] * tileSize / (TAU * POLAR_RADIUS)
      ];
  }
  
  
  export function geoOffsetToMeters(offset, tileSize) {
      tileSize = tileSize || 256;
      return [
          offset[0] * TAU * EQUATORIAL_RADIUS / tileSize,
          -offset[1] * TAU * POLAR_RADIUS / tileSize
      ];
  }
  
  
  // Equirectangular approximation of spherical distances on Earth
  export function geoSphericalDistance(a, b) {
      var x = geoLonToMeters(a[0] - b[0], (a[1] + b[1]) / 2);
      var y = geoLatToMeters(a[1] - b[1]);
      return Math.sqrt((x * x) + (y * y));
  }
  
  
  // scale to zoom
  export function geoScaleToZoom(k, tileSize) {
      tileSize = tileSize || 256;
      var log2ts = Math.log(tileSize) * Math.LOG2E;
      return Math.log(k * TAU) / Math.LN2 - log2ts;
  }
  
  
  // zoom to scale
  export function geoZoomToScale(z, tileSize) {
      tileSize = tileSize || 256;
      return tileSize * Math.pow(2, z) / TAU;
  }
  
  
  
  