Fixed ScaleLine when geodesic option is set to true and the map center is beyond the poles. Also added geodesic option to the Scale control. r=tschaub (closes #2600)
git-svn-id: http://svn.openlayers.org/trunk/openlayers@10657 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
@@ -23,6 +23,15 @@ OpenLayers.Control.Scale = OpenLayers.Class(OpenLayers.Control, {
|
|||||||
*/
|
*/
|
||||||
element: null,
|
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
|
* Constructor: OpenLayers.Control.Scale
|
||||||
*
|
*
|
||||||
@@ -56,7 +65,19 @@ OpenLayers.Control.Scale = OpenLayers.Class(OpenLayers.Control, {
|
|||||||
* Method: updateScale
|
* Method: updateScale
|
||||||
*/
|
*/
|
||||||
updateScale: function() {
|
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) {
|
if (!scale) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,10 @@ OpenLayers.Control.ScaleLine = OpenLayers.Class(OpenLayers.Control, {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* APIProperty: geodesic
|
* 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,
|
geodesic: false,
|
||||||
|
|
||||||
@@ -165,7 +168,8 @@ OpenLayers.Control.ScaleLine = OpenLayers.Class(OpenLayers.Control, {
|
|||||||
var maxSizeData = this.maxWidth * res * inches[curMapUnits];
|
var maxSizeData = this.maxWidth * res * inches[curMapUnits];
|
||||||
var geodesicRatio = 1;
|
var geodesicRatio = 1;
|
||||||
if(this.geodesic === true) {
|
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"];
|
var maxSizeKilometers = maxSizeData / inches["km"];
|
||||||
geodesicRatio = maxSizeGeodesic / maxSizeKilometers;
|
geodesicRatio = maxSizeGeodesic / maxSizeKilometers;
|
||||||
maxSizeData *= geodesicRatio;
|
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"
|
CLASS_NAME: "OpenLayers.Control.ScaleLine"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -2288,6 +2288,39 @@ OpenLayers.Map = OpenLayers.Class({
|
|||||||
px.y = Math.round(px.y);
|
px.y = Math.round(px.y);
|
||||||
return px;
|
return px;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: getGeodesicPixelSize
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* px - {<OpenLayers.Pixel>} The pixel to get the geodesic length for. If
|
||||||
|
* not provided, the center pixel of the map viewport will be used.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* {<OpenLayers.Size>} 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)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user