The main idea
1. Use Goolge public map API - GlocalSearch (do not use GClientGeocoder, because GClientGeocoder doesn't support very well) to get the value in LanLong.
2. Use the following functions below to convert LanLong to value of easting and northing
A Javascript I wrote up to implement the mechanism
/***
The part of this script uses Google' map API, so it is necessary to apply a Google map Key before use it
***/
/*
* construct a LatLon object: arguments in numeric degrees
*
* note all LatLong methods expect & return numeric degrees (for lat/long & for bearings)
*/
function LatLon(lat, lon) {
this.lat = lat;
this.lon = lon;
}
// extend Number object with methods for converting degrees/radians
Number.prototype.toRad = function() { // convert degrees to radians
return this * Math.PI / 180;
}
Number.prototype.toLat = function() { // convert numeric degrees to deg/min/sec latitude
return this.toDMS().slice(1) + (this<0 ? 'S' : 'N'); // knock off initial '0' for lat!
}
/*
* pad a number with sufficient leading zeros to make it w chars wide
*/
Number.prototype.padLZ = function(w) {
var n = this.toString();
for (var i=0; i<w-n.length; i++) n = '0' + n;
return n;
}
function GetPointFromPostcode(postcode, callbackFunction) {
var localSearch = new GlocalSearch();
localSearch.setSearchCompleteCallback(null,
function() {
if (localSearch.results[0]) {
var resultLat = localSearch.results[0].lat;
var resultLng = localSearch.results[0].lng;
point = new LatLon(parseFloat(resultLat),parseFloat(resultLng));
var coor = gridrefNumeric(LatLongToOSGrid(point));
/********************************
TAKE YOUR COORDINATE HERE
coor[0] - EASTING
coor[1] - NORTHING
********************************/
callbackFunction(coor);
}else{
alert("Postcode not found!");
return false;
}
});
localSearch.execute(postcode + ", UK");
}
/*
* convert standard grid reference ('SU387148') to fully numeric ref ([438700,114800])
*
* note that northern-most grid squares will give 5-digit northings
* no error-checking is done on gridref (bad input will give bad results or NaN)
*/
function gridrefNumeric(gridref) {
// get numeric values of letter references, mapping A->0, B->1, C->2, etc:
var letE = gridref.toUpperCase().charCodeAt(0) - 'A'.charCodeAt(0);
var letN = gridref.toUpperCase().charCodeAt(1) - 'A'.charCodeAt(0);
// shuffle down letters after 'I' since 'I' is not used in grid:
if (letE > 7) letE -= 1;
if (letN > 7) letN -= 1;
// convert grid letters into 100km-square indexes from false origin (grid square SV):
var e = ((letE+3)%5)*5 + (letN%5);
var n = (19-Math.floor(letE/5)*5) - Math.floor(letN/5);
// skip grid letters to get numeric part of ref, stripping any spaces:
gridref = gridref.slice(2).replace(/ /g,'');
// append numeric part of references to grid index:
e += gridref.slice(0, gridref.length/2);
n += gridref.slice(gridref.length/2);
// normalise to 1m grid:
switch (gridref.length) {
case 6: e += '00'; n += '00'; break;
case 8: e += '0'; n += '0'; break;
// 10-digit refs are already 1m
}
return [e, n];
}
/*
* convert geodesic co-ordinates to OS grid reference
*/
function LatLongToOSGrid(p) {
var lat = p.lat.toRad(), lon = p.lon.toRad();
var a = 6377563.396, b = 6356256.910; // Airy 1830 major & minor semi-axes
var F0 = 0.9996012717; // NatGrid scale factor on central meridian
var lat0 = (49).toRad(), lon0 = (-2).toRad(); // NatGrid true origin
var N0 = -100000, E0 = 400000; // northing & easting of true origin, metres
var e2 = 1 - (b*b)/(a*a); // eccentricity squared
var n = (a-b)/(a+b), n2 = n*n, n3 = n*n*n;
var cosLat = Math.cos(lat), sinLat = Math.sin(lat);
var nu = a*F0/Math.sqrt(1-e2*sinLat*sinLat); // transverse radius of curvature
var rho = a*F0*(1-e2)/Math.pow(1-e2*sinLat*sinLat, 1.5); // meridional radius of curvature
var eta2 = nu/rho-1;
var Ma = (1 + n + (5/4)*n2 + (5/4)*n3) * (lat-lat0);
var Mb = (3*n + 3*n*n + (21/8)*n3) * Math.sin(lat-lat0) * Math.cos(lat+lat0);
var Mc = ((15/8)*n2 + (15/8)*n3) * Math.sin(2*(lat-lat0)) * Math.cos(2*(lat+lat0));
var Md = (35/24)*n3 * Math.sin(3*(lat-lat0)) * Math.cos(3*(lat+lat0));
var M = b * F0 * (Ma - Mb + Mc - Md); // meridional arc
var cos3lat = cosLat*cosLat*cosLat;
var cos5lat = cos3lat*cosLat*cosLat;
var tan2lat = Math.tan(lat)*Math.tan(lat);
var tan4lat = tan2lat*tan2lat;
var I = M + N0;
var II = (nu/2)*sinLat*cosLat;
var III = (nu/24)*sinLat*cos3lat*(5-tan2lat+9*eta2);
var IIIA = (nu/720)*sinLat*cos5lat*(61-58*tan2lat+tan4lat);
var IV = nu*cosLat;
var V = (nu/6)*cos3lat*(nu/rho-tan2lat);
var VI = (nu/120) * cos5lat * (5 - 18*tan2lat + tan4lat + 14*eta2 - 58*tan2lat*eta2);
var dLon = lon-lon0;
var dLon2 = dLon*dLon, dLon3 = dLon2*dLon, dLon4 = dLon3*dLon, dLon5 = dLon4*dLon, dLon6 = dLon5*dLon;
var N = I + II*dLon2 + III*dLon4 + IIIA*dLon6;
var E = E0 + IV*dLon + V*dLon3 + VI*dLon5;
//alert(E + ' : ' + N)
return gridrefNumToLet(E, N, 8);
}
/*
* convert numeric grid reference (in metres) to standard-form grid ref
*/
function gridrefNumToLet(e, n, digits) {
// get the 100km-grid indices
var e100k = Math.floor(e/100000), n100k = Math.floor(n/100000);
if (e100k<0 || e100k>6 || n100k<0 || n100k>12) return '';
// translate those into numeric equivalents of the grid letters
var l1 = (19-n100k) - (19-n100k)%5 + Math.floor((e100k+10)/5);
var l2 = (19-n100k)*5%25 + e100k%5;
// compensate for skipped 'I' and build grid letter-pairs
if (l1 > 7) l1++;
if (l2 > 7) l2++;
var letPair = String.fromCharCode(l1+'A'.charCodeAt(0), l2+'A'.charCodeAt(0));
// strip 100km-grid indices from easting & northing, and reduce precision
e = Math.floor((e%100000)/Math.pow(10,5-digits/2));
n = Math.floor((n%100000)/Math.pow(10,5-digits/2));
var gridRef = letPair + e.padLZ(digits/2) + n.padLZ(digits/2);
return gridRef;
}
Useful References
1.
Introducing Google's Geocoding Service2.
Introducing Google's Geocoding USNaviguide / Maps.Huge.Info Example Pages3.
Calculate distance and bearing between two OS National Grid Reference pointsLabels: coordinate, easting northing, google map api, javascript, lan, lon, postcode