Changeset 10110

Show
Ignore:
Timestamp:
03/18/10 06:26:02 (2 years ago)
Author:
ahocevar
Message:

Give the ScaleLine control a geodesic option. Setting this to true will provide an accurate scale bar in Spherical Mercator maps. r=bartvde (closes #1890)

Location:
trunk/openlayers
Files:
1 added
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/openlayers/lib/OpenLayers/Control/ScaleLine.js

    r10070 r10110  
    6262     */ 
    6363    eBottom:null, 
     64     
     65    /** 
     66     * APIProperty: geodesic 
     67     * {Boolean} Use geodesic measurement. Default is false. 
     68     */ 
     69    geodesic: false, 
    6470 
    6571    /** 
     
    157163 
    158164        // convert maxWidth to map units 
    159         var maxSizeData = this.maxWidth * res * inches[curMapUnits];   
     165        var maxSizeData = this.maxWidth * res * inches[curMapUnits]; 
     166        var geodesicRatio = 1; 
     167        if(this.geodesic === true) { 
     168            var maxSizeGeodesic = this.getGeodesicLength(this.maxWidth); 
     169            var maxSizeKilometers = maxSizeData / inches["km"]; 
     170            geodesicRatio = maxSizeGeodesic / maxSizeKilometers; 
     171            maxSizeData *= geodesicRatio; 
     172        } 
    160173 
    161174        // decide whether to use large or small scale units      
     
    183196 
    184197        // and to pixel units 
    185         var topPx = topMax / res; 
    186         var bottomPx = bottomMax / res; 
     198        var topPx = topMax / res / geodesicRatio; 
     199        var bottomPx = bottomMax / res / geodesicRatio; 
    187200         
    188201        // now set the pixel widths 
     
    201214    },  
    202215 
     216    /** 
     217     * Method: getGeodesicLength 
     218     *  
     219     * Parameters: 
     220     * pixels - {Number} the pixels to get the geodesic length in meters for. 
     221     */ 
     222    getGeodesicLength: function(pixels) { 
     223        var map = this.map; 
     224        var centerPx = map.getPixelFromLonLat(map.getCenter()); 
     225        var bottom = map.getLonLatFromPixel(centerPx.add(0, -pixels / 2)); 
     226        var top = map.getLonLatFromPixel(centerPx.add(0, pixels / 2)); 
     227        var source = map.getProjectionObject(); 
     228        var dest = new OpenLayers.Projection("EPSG:4326"); 
     229        if(!source.equals(dest)) { 
     230            bottom.transform(source, dest); 
     231            top.transform(source, dest); 
     232        } 
     233        return OpenLayers.Util.distVincenty(bottom, top); 
     234    }, 
     235 
    203236    CLASS_NAME: "OpenLayers.Control.ScaleLine" 
    204237});