chrisveness / geodesy

Libraries of geodesy functions implemented in JavaScript
http://www.movable-type.co.uk/scripts/geodesy-library.html
MIT License
1.17k stars 202 forks source link

Further possible conversion bugs #9

Closed davegurnell closed 9 years ago

davegurnell commented 9 years ago

Hi Chris,

It looks like there are still bugs in some of the NGR <-> GridRef and OSGB36 <-> WGS84 conversions. This round-trip test fails:

test('round trip conversions (NGR <-> WGS84)', function(assert) {
  var LatLonE = require('./latlon-ellipsoid.js');
  var OsGridRef = require('./osgridref.js');

  // The steps in this test are:
  //  - parse an NGR
  //  - convert to easting/northing
  //  - convert to OSGB36
  //  - convert to WGS84
  //  - convert back to OSGB36
  //  - convert back to easting/northing
  //  - convert back to NGR

  var ngr = "TQ 44359 80653";

  var grid = OsGridRef.parse(ngr);
  assert.equal(grid.easting, 544359, "grid.easting");
  assert.equal(grid.northing, 180653, "grid.northing");

  var osgb = OsGridRef.osGridToLatLon(grid);
  console.log('osgb', osgb);
  assert.equal(osgb.lat.toFixed(5), '51.50587', "osgb.lat");
  assert.equal(osgb.lon.toFixed(5), '0.08030', "osgb.lon");

  var wgs = osgb.convertDatum(LatLonE.datum.WGS84);
  console.log('wgs', wgs);
  assert.equal(wgs.lat.toFixed(5), '51.31876', "wgs.lat");
  assert.equal(wgs.lon.toFixed(5), '0.07867', "wgs.lon");

  // Problem 1: `wgs` doesn't have a convertDatum method...
  // I guess there are several types of coordinate in the geodesy library:
  var wgs2 = new LatLonE(wgs.lat, wgs.lon, LatLonE.datum.WGS84);

  // Problem 2: this conversion comes out wrong...
  // Latitude goes down instead of up as I'd expect:
  var osgb2 = wgs2.convertDatum(LatLonE.datum.OSGB36);
  console.log('osgb2', osgb2);
  assert.equal(osgb2.lat.toFixed(5), osgb.lat.toFixed(5), "osgb2.lat"); // error: expected: '51.50587', actual: '51.13099'
  assert.equal(osgb2.lon.toFixed(5), osgb.lon.toFixed(5), "osgb2.lon"); // error: expected: '0.08030', actual: '0.08029'

  // Problem 3: this conversion fails with the following error:
  // "Can only convert OSGB36 point to OsGrid"
  var grid2 = OsGridRef.latLonToOsGrid(osgb2);
  console.log('grid2', grid2);
  assert.equal(grid2.easting, grid.easting, "grid2.easting");
  assert.equal(grid2.northing, grid.northing, "grid2.northing");

  var ngr2 = grid2.toPrecision(10);
  assert.equal(ngr2, ngr, "ngr2");

  assert.end();
});

Apologies if the errors are due to me mis-using the code or the expected accuracy of the conversions involved. Happy to help with the fixes if I can.

Best regards,

Dave

chrisveness commented 9 years ago

I have reorganised the libraries into a more rational structure, which I hope addresses these issues (I also improved the accuracy of the datum conversion, #ddde271). I've added a test which round-trips TQ 44359 80653 through OSGB36 to WGS84 and back, which completes successfully.

davegurnell commented 9 years ago

Hi Chris,

This looks great! Thanks very much -- I'll try it out ASAP.

Cheers,

Dave

On 1 Feb 2015, at 22:31, Chris Veness notifications@github.com wrote:

I have reorganised the libraries into a more rational structure, which I hope addresses these issues (I also improved the accuracy of the datum conversion, #ddde271 https://github.com/chrisveness/geodesy/commit/ddde271a16c06f9c0696c76a989e04140c2790f5). I've added a test https://github.com/chrisveness/geodesy/commit/162afc6827b2d8dd1e681e296ba294b2fe69e757 which round-trips TQ 44359 80653 through OSGB36 to WGS84 and back, which completes successfully.

— Reply to this email directly or view it on GitHub https://github.com/chrisveness/geodesy/issues/9#issuecomment-72388472.