There are actually two problems in one here:
1) Coverting between NGR and Easting/Northing
2) Coverting between Easting/Northing and Lat/Lon
Here are some possibilities ...
1) This is relatively simple JavaScript. Here are two methods I've
devised:
i) Doesn't convert Irish or CI NGRs:
// UK Ordnance Survey 100km grid square designations
grid100 = new Array
(
"SV", "SW", "SX", "SY", "SZ", "TV", "TW",
"SQ", "SR", "SS", "ST", "SU", "TQ", "TR",
"SL", "SM", "SN", "SO", "SP", "TL", "TM",
"SF", "SG", "SH", "SJ", "SK", "TF", "TG",
"SA", "SB", "SC", "SD", "SE", "TA", "TB",
"NV", "NW", "NX", "NY", "NZ", "OV", "OW",
"NQ", "NR", "NS", "NT", "NU", "OQ", "OR",
"NL", "NM", "NN", "NO", "NP", "OL", "OM",
"NF", "NG", "NH", "NJ", "NK", "OF", "OG",
"NA", "NB", "NC", "ND", "NE", "OA", "OB",
"HV", "HW", "HX", "HY", "HZ", "JV", "JW",
"HQ", "HR", "HS", "HT", "HU", "JQ", "JR",
"HL", "HM", "HN", "HO", "HP", "JL", "JM"
);
// Convert Easting, Northing to 100km Grid Reference
function ENToGridRef( anEast, aNorth )
{
var result = null;
with( Math )
result = grid100[ floor(anEast/100000) + 7*floor(aNorth/100000)
] +
floor( (anEast%100000) / 100 ).pad(3) + floor( (aNorth%100000) /
100 ).pad(3);
return result;
}
// Convert 100km Grid Reference to Easting, Northing
function GridRefToEN( aGridRef )
{
var easting = null;
var northing = null;
var result = null;
switch( aGridRef ? aGridRef.length : 0 )
{
case 4: easting = parseInt( aGridRef.substr(2,1), 10
)*10000;
northing = parseInt(
aGridRef.substr(3,1), 10 )*10000;
break;
case 6: easting = parseInt( aGridRef.substr(2,2), 10
)*1000;
northing = parseInt(
aGridRef.substr(4,2), 10 )*1000;
break;
case 8: easting = parseInt( aGridRef.substr(2,3), 10
)*100;
northing = parseInt(
aGridRef.substr(5,3), 10 )*100;
break;
case 10: easting = parseInt( aGridRef.substr(2,4), 10
)*10;
northing = parseInt(
aGridRef.substr(6,4), 10 )*10;
break;
case 12: easting = parseInt( aGridRef.substr(2,5), 10 );
northing = parseInt(
aGridRef.substr(7,5), 10 );
break;
}
if( easting!= null )
for( var i = 0; (result == null) && (i < grid100.length); i++ )
if( aGridRef.substr(0, 2).toUpperCase() == grid100[i] )
{
easting += (i % 7)*100000;
northing += Math.floor(i / 7)*100000;
result = { "x":easting, "y": northing };
}
return result;
}
ii) This one does cope with Irish and CI NGRs
function ENToGridRef( anEast, aNorth, irish, numDigits )
{
var result = "";
try
{
with( Math )
{
var pow10 = 100000;
if( !irish )
{
anEast += 10*pow10;
aNorth += 5*pow10;
}
var anEastH = floor( anEast / pow10 );
var aNorthH = floor( aNorth / pow10 );
var anEastL = floor( anEast % pow10 );
var aNorthL = floor( aNorth % pow10 );
var nDig = irish ? 1 : 2;
nDig = numDigits ? min( nDig,
numDigits ) : nDig;
for( var i = 0; i < nDig; i++ )
{
var eSq, nSq;
if( (i == 0) && !irish )
{
eSq = floor( anEastH / 5 );
nSq = floor( aNorthH / 5 );
}
else
{
eSq = anEastH % 5;
nSq = aNorthH % 5;
}
var square = (5*( 4 - nSq ) + eSq)
% 25;
if( square > 7 )
square ++;
result += String.fromCharCode( 65 +
square );
}
nDig = numDigits ? max( 0, (numDigits - 2)/2
) : 3;
pow10 = pow( 10, 5 - nDig );
if( nDig )
result += floor( anEastL / pow10
).pad(nDig) + "" + floor
( aNorthL / pow10 ).pad(nDig);
}
}
catch(e){}
return result;
}
function GridRefToEN( aGridRef, irish )
{
var result = null;
try
{
with( Math )
{
var east = 0;
var north = 0;
var nDig = min( 2, aGridRef.length );
var pow10 = 100000;
for( var i = 0; i < nDig; i++ )
{
if( (aGridRef.charAt(i) >= "A") &&
(aGridRef.charAt(i) <= "Z") )
{
if( aGridRef.charAt(i) != "I" )
{
var square =
aGridRef.substr(i, 1).charCodeAt( 0 ) -
"A".charCodeAt( 0 );
if( square > 7 )
square = square
- 1;
var eSq =
floor(square % 5);
var nSq = 4 -
floor(square / 5);
if( (i == 0) && !irish )
{
eSq = (eSq -
2)*5;
nSq = (nSq -
1)*5;
}
east += eSq*pow10;
north += nSq*pow10;
}
else
irish = (i == 0);
}
else
throw "Invalid British Isles
Grid Reference";
}
nDig = max( 0, (aGridRef.length - 2)/2 );
pow10 = pow( 10, 5 - nDig );
east += nDig ? parseInt(
aGridRef.substr(2,nDig), 10 )*pow10 : 0;
north += nDig ? parseInt(
aGridRef.substr(2+nDig,nDig), 10 )
*pow10 : 0;
result = { "x":east, "y": north };
}
}
catch(e){}
return result;
}
2) Converting between EN and LL is more tricky (and note that it's Lon-
Lat in most geo systems, but Lat-Lng in Google):
i) As I am using Open Layers to load Ordnance Survey Maps ...
http://www.macfh.co.uk/JavaJive/AudioVisualTV/SatelliteTV/SatelliteCalculator.html
... (the intended rather complex final use, but here's a simpler demo
somewhat easier on the digestion) ...
http://www.macfh.co.uk/Test/UKOrdnance_Survey_with_OpenLayers.html
... I achieve conversion as follows:
<!-- Required javascript APIs -->
<script type="text/javascript" src="http://openlayers.org/api/
OpenLayers.js"></script>
<script type="text/javascript" src="http://proj4js.org/lib/proj4js-
compressed.js"></script>
...
// UK OS National Grid
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 ";
// Irish Grid
Proj4js.defs["EPSG:29902"] = "+proj=tmerc +lat_0=53.5 +lon_0=-8
+k=1.000035 +x_0=200000 +y_0=250000 +a=6377340.189
+b=6356034.447938534 +units=m +no_defs ";
...
// Calculate Latitude and Longitude from Easting and Northing
function cLatLonFromEastNorth( anEast, aNorth, irish )
{
var en = new OpenLayers.LonLat( anEast, aNorth );
var ll = null;
if( irish )
ll = en.transform( new
OpenLayers.Projection("EPSG:29902"),
EPSG4326 );
else
ll = en.transform( new
OpenLayers.Projection("EPSG:27700"),
EPSG4326 );
return ll;
}
// Calculate Easting and Northing from Latitude and Longitude
function cEastNorthFromLatLon( aLon, aLat, irish )
{
var ll = new OpenLayers.LonLat( aLon, aLat );
var en = null;
if( irish )
en = ll.transform( EPSG4326, new
OpenLayers.Projection("EPSG:
29902") );
else
en = ll.transform( EPSG4326, new
OpenLayers.Projection("EPSG:
27700") );
return en;
}
ii) Alternatively, OS maps can be loaded directly using Ordnance
Survey's Open Space API (which is an extension of OL) ...
http://www.macfh.co.uk/Test/UKOrdnance_Survey_with_OpenSpace.html
... and then the EN-LL conversion is somewhat simpler (but can't cope
with the Irish problem):
<!-- Required javascript API, note that the parameter 'v=0.8.0' will
not be required after June 12th 2009>
<script type="text/javascript" src="http://
openspace.ordnancesurvey.co.uk/osmapapi/openspace.js?
v=0.8.0&key=<Your own OS API Key>"></script>
...
var gridProjection = new OpenSpace.GridProjection();
...
// Calculate Latitude and Longitude from Easting and Northing
function cLatLonFromEastNorth( anEast, aNorth )
{
var en = new OpenLayers.LonLat( anEast, aNorth );
var ll = gridProjection.getLonLatFromMapPoint( en );
return ll;
}
// Calculate Easting and Northing from Latitude and Longitude
function cEastNorthFromLatLon( aLon, aLat )
{
var ll = new OpenLayers.LonLat( aLon, aLat );
var en = gridProjection.getMapPointFromLonLat( ll )
return en;
}
iii) As OpenSpace is built upon OL, and OL uses Proj4js, you can
apparently do the conversion using Proj4js directly, though I have not
needed to do this, so have no direct experience of this method:
http://trac.osgeo.org/proj4js/wiki/UserGuide
On Jun 10, 10:38 am, Tom Cavanagh <[email protected]> wrote:
> Hi
>
> I need to be able to convert UK Grid Reference points to long/lat so
> that i can use them with google maps can anyone suggest the best way
> to do this?
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Google Maps API" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/Google-Maps-API?hl=en
-~----------~----~----~----~------~----~------~--~---