// console.log( "Loading Google AJAX loader ... " );
new ServCBRequest( "http://www.google.com/jsapi?callback=onGoogleAJAXLoad&key=" + gKey );
Proj4js.defs["EPSG:27700"]="+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_defs ";
function onOpenLayersLoad()
{
OpenLayers.scriptLocation=this.src.substr(0,this.src.lastIndexOf("/")+1);
OpenLayers._getScriptLocation=function()
{
return OpenLayers.scriptLocation;
};
OpenLayers.Layer.WMS.UKOS=OpenLayers.Class
(
OpenLayers.Layer.WMS,
{
initialize:function(options)
{
OpenLayers.Layer.WMS.prototype.initialize.apply
(
this,
[
"OpenSpace",
OSAPIServer+OSAPITiles,
{format:"image/png",key:OSAPIKey,url:document.URL},
OpenLayers.Util.extend
(
options,
{
attribution:"© Crown Copyright & Database Right 2008. All rights reserved.
"
+"End User License Agreement",
projection:new OpenLayers.Projection("EPSG:27700"),
maxExtent:new OpenLayers.Bounds(0,0,800000,1300000),
resolutions:new Array(2500,1000,500,200,100,50,25,10,5,2,1),
tile200:new OpenLayers.Size(200,200),
tile250:new OpenLayers.Size(250,250),
buffer:0
}
)
]
);
},
moveTo:function(bounds,zoomChanged,dragging)
{
if(zoomChanged)
{
var resolution=this.getResolution();
var nTileSize=resolution<=2?this.tile250:this.tile200;
if(nTileSize!=this.tileSize)
{
this.clearGrid();
this.tileSize=nTileSize;
this.setTileSize(nTileSize);
}
this.params.LAYERS=resolution;
}
OpenLayers.Layer.WMS.prototype.moveTo.apply(this,arguments);
},
CLASS_NAME:"OpenLayers.Layer.WMS.UKOS"
}
);
OLRdy=true;
tryStart();
}
new Request("http://openlayers.org/api/OpenLayers.js",onOpenLayersLoad);
function createMaps(OSDiv,GDiv1,GDiv2,GDiv3,aLon,aLat,aGZoom,anOSZoom)
{
var EPSG4326=new OpenLayers.Projection("EPSG:4326");
var EPSG900913=new OpenLayers.Projection("EPSG:900913");
var EPSG27700=new OpenLayers.Projection("EPSG:27700");
var oLL=new OpenLayers.LonLat(aLon,aLat);
var XY=oLL.clone().transform(EPSG4326,EPSG900913);
var EN=oLL.clone().transform(EPSG4326,EPSG27700);
var UKOSMap=new OpenLayers.Map
(
OSDiv,
{
controls:[
new OpenLayers.Control.KeyboardDefaults(),
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.PanZoom(),
new OpenLayers.Control.ScaleLine({geodesic:true}),
new OpenLayers.Control.Scale(),
new OpenLayers.Control.MousePosition({displayProjection:EPSG4326,separator:"°E, ",suffix:"°N"}),
new OpenLayers.Control.Attribution()
],
projection:EPSG27700
}
);
UKOSMap.addLayer(new OpenLayers.Layer.WMS.UKOS({"displayInLayerSwitcher":false}));
for(i in UKOSMap.controls)
{
var div=UKOSMap.controls[i].div;
if(UKOSMap.controls[i].CLASS_NAME=="OpenLayers.Control.ScaleLine")
{
div.style.position="absolute";
div.style.left="52px";
div.style.top="8px";
div.style.width="112px";
div.style.height="38px";
}
else if(UKOSMap.controls[i].CLASS_NAME=="OpenLayers.Control.Scale")
{
div.style.color="#00FF00";
div.style.position="absolute";
div.style.left="52px";
div.style.top="41px";
div.style.width="74px";
div.style.height="14px";
div.style.backgroundColor="#000000";
}
else if(UKOSMap.controls[i].CLASS_NAME=="OpenLayers.Control.MousePosition")
{
div.style.position="absolute";
div.style.left="52px";
div.style.top="56px";
div.style.width="138px";
div.style.height="30px";
}
}
UKOSMap.setCenter(EN,anOSZoom);
var GoogleMaps=[];
var GoogleScales=[
new OpenLayers.Control.Scale(),
new OpenLayers.Control.Scale({geodesic:true}),
new OpenLayers.Control.Scale(undefined,{geodesic:true})
];
for(var m=0;m<3;m++)
{
GoogleMaps[m]=new OpenLayers.Map
(
arguments[1+m],
{
layers:[
new OpenLayers.Layer.Google
(
"Google Satellite",
{type:google.maps.MapTypeId.SATELLITE,numZoomLevels:22}
)
],
controls:[
new OpenLayers.Control.KeyboardDefaults(),
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.PanZoom(),
new OpenLayers.Control.ScaleLine({geodesic:true}),
GoogleScales[m],
new OpenLayers.Control.MousePosition({displayProjection:EPSG4326,separator:"°E, ",suffix:"°N"})
],
projection:EPSG900913,
center:XY,
zoom:aGZoom
}
);
for(i in GoogleMaps[m].controls)
{
var div=GoogleMaps[m].controls[i].div;
if(GoogleMaps[m].controls[i].CLASS_NAME=="OpenLayers.Control.ScaleLine")
{
div.style.position="absolute";
div.style.left="52px";
div.style.top="8px";
div.style.width="112px";
div.style.height="38px";
}
else if(GoogleMaps[m].controls[i].CLASS_NAME=="OpenLayers.Control.Scale")
{
div.style.color=(m==2?"#00FF00":"#FF0000");
div.style.position="absolute";
div.style.left="52px";
div.style.top="41px";
div.style.width="74px";
div.style.height="15px";
div.style.backgroundColor="#000000";
}
else if(GoogleMaps[m].controls[i].CLASS_NAME=="OpenLayers.Control.MousePosition")
{
div.style.position="absolute";
div.style.left="52px";
div.style.top="56px";
div.style.width="138px";
div.style.height="30px";
}
}
}
}
function onDOMLoad()
{
DOMRdy=true;
tryStart();
}
function tryStart()
{
if(DOMRdy&&GMapsRdy&&OLRdy)
{
document.getElementById("OLVersion").innerHTML="v"
+(
OpenLayers.VERSION_NUMBER.indexOf("Release"==0)?
OpenLayers.VERSION_NUMBER.substring(8):
OpenLayers.VERSION_NUMBER
);
document.getElementById("GoogleVersion").innerHTML="v"+google.maps.version;
createMaps("UKOSMap","GoogleMap1","GoogleMap2","GoogleMap3",Lon,Lat,GZoom,OSZoom);
}
}
//-->
<a href="http://trac.openlayers.org/ticket/1890" title="Scale and ScaleLine in Google approx double correct figure at some resolutions">OpenLayers Ticket #1890</a> (link now dead) - Scale & ScaleLine Controls giving incorrect scales.
The Scale control prints the 1 : X
scale factor. The
ScaleLine control draws the scale measure that we are used to seeing in the legend for printed maps.
The apparent problem of them both giving incorrect scales occurs in Spherical Mercator projections
such as that used by Google Maps.
The controls have actually been fixed, but by default will still give incorrect scales. To get
them to display correctly, an extra parameter {geodesic:true}
is
required. With the ScaleLine control, this is trivially obvious how to do, but with the Scale
control things are a little more obscure, because the options parameter to the constructor is the
second parameter, not the first, so what should be given as the first parameter? See below for
how to get round this. The manner of having to declare the control to get it to
work is unfortunate, but at least it does now work.
The map on the left has the correct scale value (green).
The map on the right declares the Scale control as:
new OpenLayers.Control.Scale()
and thus it gives incorrect values (red).
Attempting to fix it, the map on the left breaks the Scale control by declaring it as:
new OpenLayers.Control.Scale( {geodesic:true} )
.
Successfully fixing it, The map on the right declares the working Scale control as:
new OpenLayers.Control.Scale( undefined, {geodesic:true} )
.
This demo uses the live APIs - OpenLayers API and Google Maps API .