diff --git a/lib/OpenLayers/Control/Scale.js b/lib/OpenLayers/Control/Scale.js index 3d5141a257..6066e62693 100644 --- a/lib/OpenLayers/Control/Scale.js +++ b/lib/OpenLayers/Control/Scale.js @@ -23,6 +23,15 @@ OpenLayers.Control.Scale = OpenLayers.Class(OpenLayers.Control, { */ element: null, + /** + * APIProperty: geodesic + * {Boolean} Use geodesic measurement. Default is false. The recommended + * setting for maps in EPSG:4326 is false, and true EPSG:900913. If set to + * true, the scale will be calculated based on the horizontal size of the + * pixel in the center of the map viewport. + */ + geodesic: false, + /** * Constructor: OpenLayers.Control.Scale * @@ -56,7 +65,19 @@ OpenLayers.Control.Scale = OpenLayers.Class(OpenLayers.Control, { * Method: updateScale */ updateScale: function() { - var scale = this.map.getScale(); + var scale; + if(this.geodesic === true) { + var units = this.map.getUnits(); + if(!units) { + return; + } + var inches = OpenLayers.INCHES_PER_UNIT; + scale = (this.map.getGeodesicPixelSize().w || 0.000001) * + inches["km"] * OpenLayers.DOTS_PER_INCH; + } else { + scale = this.map.getScale(); + } + if (!scale) { return; } diff --git a/lib/OpenLayers/Control/ScaleLine.js b/lib/OpenLayers/Control/ScaleLine.js index b62dff90f0..919fb48f03 100644 --- a/lib/OpenLayers/Control/ScaleLine.js +++ b/lib/OpenLayers/Control/ScaleLine.js @@ -64,7 +64,10 @@ OpenLayers.Control.ScaleLine = OpenLayers.Class(OpenLayers.Control, { /** * APIProperty: geodesic - * {Boolean} Use geodesic measurement. Default is false. + * {Boolean} Use geodesic measurement. Default is false. The recommended + * setting for maps in EPSG:4326 is false, and true EPSG:900913. If set to + * true, the scale will be calculated based on the horizontal size of the + * pixel in the center of the map viewport. */ geodesic: false, @@ -165,7 +168,8 @@ OpenLayers.Control.ScaleLine = OpenLayers.Class(OpenLayers.Control, { var maxSizeData = this.maxWidth * res * inches[curMapUnits]; var geodesicRatio = 1; if(this.geodesic === true) { - var maxSizeGeodesic = this.getGeodesicLength(this.maxWidth); + var maxSizeGeodesic = (this.map.getGeodesicPixelSize().w || + 0.000001) * this.maxWidth; var maxSizeKilometers = maxSizeData / inches["km"]; geodesicRatio = maxSizeGeodesic / maxSizeKilometers; maxSizeData *= geodesicRatio; @@ -213,26 +217,6 @@ OpenLayers.Control.ScaleLine = OpenLayers.Class(OpenLayers.Control, { }, - /** - * Method: getGeodesicLength - * - * Parameters: - * pixels - {Number} the pixels to get the geodesic length in meters for. - */ - getGeodesicLength: function(pixels) { - var map = this.map; - var centerPx = map.getPixelFromLonLat(map.getCenter()); - var bottom = map.getLonLatFromPixel(centerPx.add(0, -pixels / 2)); - var top = map.getLonLatFromPixel(centerPx.add(0, pixels / 2)); - var source = map.getProjectionObject(); - var dest = new OpenLayers.Projection("EPSG:4326"); - if(!source.equals(dest)) { - bottom.transform(source, dest); - top.transform(source, dest); - } - return OpenLayers.Util.distVincenty(bottom, top); - }, - CLASS_NAME: "OpenLayers.Control.ScaleLine" }); diff --git a/lib/OpenLayers/Map.js b/lib/OpenLayers/Map.js index 18e980ded7..9ed75ebe6f 100644 --- a/lib/OpenLayers/Map.js +++ b/lib/OpenLayers/Map.js @@ -2288,6 +2288,39 @@ OpenLayers.Map = OpenLayers.Class({ px.y = Math.round(px.y); return px; }, + + /** + * Method: getGeodesicPixelSize + * + * Parameters: + * px - {} The pixel to get the geodesic length for. If + * not provided, the center pixel of the map viewport will be used. + * + * Returns: + * {} The geodesic size of the pixel in kilometers. + */ + getGeodesicPixelSize: function(px) { + var lonlat = px ? this.getLonLatFromPixel(px) : (this.getCenter() || + new OpenLayers.LonLat(0, 0)); + var res = this.getResolution(); + var left = lonlat.add(-res / 2, 0); + var right = lonlat.add(res / 2, 0); + var bottom = lonlat.add(0, -res / 2); + var top = lonlat.add(0, res / 2); + var dest = new OpenLayers.Projection("EPSG:4326"); + var source = this.getProjectionObject() || dest; + if(!source.equals(dest)) { + left.transform(source, dest); + right.transform(source, dest); + bottom.transform(source, dest); + top.transform(source, dest); + } + + return new OpenLayers.Size( + OpenLayers.Util.distVincenty(left, right), + OpenLayers.Util.distVincenty(bottom, top) + ); + },