ray ray - 3 months ago 8
HTML Question

Javacript VAR from form text box

I have found a script that converts Northings and Eastings to Longitude and Latitude, currently the Northings and Eastings are variables(N & E) hard coded in to the script. I would like them to come from two textboxes.

Currently this conversion happens when the page is loaded, the ideal would be that when Northings and Eastings are entered this automatically converts and enters the longitude and Latitude into separate textboxes ready to upload to a database.

Thanks in advance, any help would be appreciated as javascript is not my strongpoint.

http://jsfiddle.net/De6HP/7/

// Original by Chris Veness http://www.movable-type.co.uk/scripts/latlong-gridref.html
Number.prototype.toRad = function() {
return this * Math.PI / 180;
}

Number.prototype.toDeg = function() {
return this * 180 / Math.PI;
}

var E = 657177
var N = 172273

var a = 6377563.396, b = 6356256.909; // Airy 1830 major & minor semi-axes
var F0 = 0.9996012717; // NatGrid scale factor on central meridian
var lat0 = 49*Math.PI/180, lon0 = -2*Math.PI/180; // 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 lat=lat0, M=0;
do {
lat = (N-N0-M)/(a*F0) + lat;

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));
M = b * F0 * (Ma - Mb + Mc - Md); // meridional arc

} while (N-N0-M >= 0.00001); // ie until < 0.01mm

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 tanLat = Math.tan(lat);
var tan2lat = tanLat*tanLat, tan4lat = tan2lat*tan2lat, tan6lat = tan4lat*tan2lat;
var secLat = 1/cosLat;
var nu3 = nu*nu*nu, nu5 = nu3*nu*nu, nu7 = nu5*nu*nu;
var VII = tanLat/(2*rho*nu);
var VIII = tanLat/(24*rho*nu3)*(5+3*tan2lat+eta2-9*tan2lat*eta2);
var IX = tanLat/(720*rho*nu5)*(61+90*tan2lat+45*tan4lat);
var X = secLat/nu;
var XI = secLat/(6*nu3)*(nu/rho+2*tan2lat);
var XII = secLat/(120*nu5)*(5+28*tan2lat+24*tan4lat);
var XIIA = secLat/(5040*nu7)*(61+662*tan2lat+1320*tan4lat+720*tan6lat);

var dE = (E-E0), dE2 = dE*dE, dE3 = dE2*dE, dE4 = dE2*dE2, dE5 = dE3*dE2, dE6 = dE4*dE2, dE7 = dE5*dE2;
lat = lat - VII*dE2 + VIII*dE4 - IX*dE6;
var lon = lon0 + X*dE - XI*dE3 + XII*dE5 - XIIA*dE7;

Math.PI/180

window.onclick = function() {
document.getElementById('result').innerHTML = 'longditude: ' + lon.toDeg();
document.getElementById('result1').innerHTML = 'Latitude: ' + lat.toDeg();
}

Answer

You're on the right path, by adding event listeners to textboxes on the blur event you can have it automatically calculate the lat/long when they're properly updated. Your lat/long code is a bit messy so I didn't change much there, I just wrapped it in a function with two inputs.

What you see I did in my code in the top is add the event listeners for blur which call validateInputs() to make sure that you have two valid inputs in the textboxes, which if you do will update the span.

document.getElementById('txtInputN').addEventListener('blur', validateInputs);
document.getElementById('txtInputE').addEventListener('blur', validateInputs);

function validateInputs() {
  const valN = document.getElementById('txtInputN').value;
  const valE = document.getElementById('txtInputE').value;

  document.getElementById('result').innerHTML = ''; //Clear the textbox since we might not have valid input

  if (valN && valE) { //Make sure we have values
    if (valN >= 0 && valE >= 0) { //Due to implicit conversions, if it's text this won't pass
      calcResult(valN, valN) //We have valid inputs, so pass them here.
    }
  }
}

// Original by Chris Veness http://www.movable-type.co.uk/scripts/latlong-gridref.html
Number.prototype.toRad = function() {
  return this * Math.PI / 180;
}

function calcResult(inputN, inputE) {

  Number.prototype.toDeg = function() {
    return this * 180 / Math.PI;
  }

  var E = 657177
  var N = 172273

  var a = 6377563.396,
    b = 6356256.909; // Airy 1830 major & minor semi-axes
  var F0 = 0.9996012717; // NatGrid scale factor on central meridian
  var lat0 = 49 * Math.PI / 180,
    lon0 = -2 * Math.PI / 180; // 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 lat = lat0,
    M = 0;
  do {
    lat = (N - N0 - M) / (a * F0) + lat;

    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));
    M = b * F0 * (Ma - Mb + Mc - Md); // meridional arc

  } while (N - N0 - M >= 0.00001); // ie until < 0.01mm

  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 tanLat = Math.tan(lat);
  var tan2lat = tanLat * tanLat,
    tan4lat = tan2lat * tan2lat,
    tan6lat = tan4lat * tan2lat;
  var secLat = 1 / cosLat;
  var nu3 = nu * nu * nu,
    nu5 = nu3 * nu * nu,
    nu7 = nu5 * nu * nu;
  var VII = tanLat / (2 * rho * nu);
  var VIII = tanLat / (24 * rho * nu3) * (5 + 3 * tan2lat + eta2 - 9 * tan2lat * eta2);
  var IX = tanLat / (720 * rho * nu5) * (61 + 90 * tan2lat + 45 * tan4lat);
  var X = secLat / nu;
  var XI = secLat / (6 * nu3) * (nu / rho + 2 * tan2lat);
  var XII = secLat / (120 * nu5) * (5 + 28 * tan2lat + 24 * tan4lat);
  var XIIA = secLat / (5040 * nu7) * (61 + 662 * tan2lat + 1320 * tan4lat + 720 * tan6lat);

  var dE = (E - E0),
    dE2 = dE * dE,
    dE3 = dE2 * dE,
    dE4 = dE2 * dE2,
    dE5 = dE3 * dE2,
    dE6 = dE4 * dE2,
    dE7 = dE5 * dE2;
  lat = lat - VII * dE2 + VIII * dE4 - IX * dE6;
  var lon = lon0 + X * dE - XI * dE3 + XII * dE5 - XIIA * dE7;

  Math.PI / 180
  document.getElementById('result').innerHTML = 'Latitude: ' + lat.toDeg() + '<br /> Longitude: ' + lon.toDeg();
}
Result is:
<div id="result"></div>
<br />
<span>N: </span>
<input type="text" id="txtInputN" />
<br />
<span>E: </span>
<input type="text" id="txtInputE" />

Comments