/** * Convert lat/lon point in WGS84 to OSGB36 * * @param {LatLon} pWGS84: lat/lon in WGS84 reference frame * @return {LatLon} lat/lon point in OSGB36 reference frame */ private LatLong ConvertOSGB36ToWGS84(double northing, double easting) { LatLong LatLongOSGB36 = OSGB36GridToLatLong(northing, easting); return(ConvertEllipsoidOSGB36ToWGS84(LatLongOSGB36)); }
/** * Convert lat/lon from one ellipsoidal model to another * * q.v. Ordnance Survey 'A guide to coordinate systems in Great Britain' Section 6 * www.ordnancesurvey.co.uk/oswebsite/gps/docs/A_Guide_to_Coordinate_Systems_in_Great_Britain.pdf * * @private * @param {LatLon} point: lat/lon in source reference frame * @param {Number[]} sourceEllipse: source ellipse parameters * @param {Number[]} t: Helmert transform parameters * @param {Number[]} targetEllipse: target ellipse parameters * @return {Coord} lat/lon in target reference frame */ private LatLong ConvertEllipsoidOSGB36ToWGS84(LatLong point) { var t = TransformFromOSGB36ToWGS84; var sourceEllipse = Ellipse[EllipseEnum.Airy1830]; var targetEllipse = Ellipse[EllipseEnum.WGS84]; // -- 1: convert polar to Cartesian coordinates (using ellipse 1) var lat = ToRadian(point.Lat); var lon = ToRadian(point.Long); var a = sourceEllipse.A; var b = sourceEllipse.B; var sinPhi = Math.Sin(lat); var cosPhi = Math.Cos(lat); var sinLambda = Math.Sin(lon); var cosLambda = Math.Cos(lon); var h = 24.7; // for the moment var eSq = (a * a - b * b) / (a * a); var nu = a / Math.Sqrt(1 - eSq * sinPhi * sinPhi); var x1 = (nu + h) * cosPhi * cosLambda; var y1 = (nu + h) * cosPhi * sinLambda; var z1 = ((1 - eSq) * nu + h) * sinPhi; // -- 2: apply Helmert transform using appropriate params var tx = t.Tx; var ty = t.Ty; var tz = t.Tz; var rx = ToRadian(t.Rx / 3600); // normalise seconds to radians var ry = ToRadian(t.Ry / 3600); var rz = ToRadian(t.Rz / 3600); var s1 = t.S / 1e6 + 1; // normalise ppm to (s+1) // apply transform var x2 = tx + x1 * s1 - y1 * rz + z1 * ry; var y2 = ty + x1 * rz + y1 * s1 - z1 * rx; var z2 = tz - x1 * ry + y1 * rx + z1 * s1; // -- 3: convert Cartesian to polar coordinates (using ellipse 2) a = targetEllipse.A; b = targetEllipse.B; var precision = 4 / a; // results accurate to around 4 metres eSq = (a * a - b * b) / (a * a); var p = Math.Sqrt(x2 * x2 + y2 * y2); var phi = Math.Atan2(z2, p * (1 - eSq)); var phiP = 2 * Math.PI; while (Math.Abs(phi - phiP) > precision) { nu = a / Math.Sqrt(1 - eSq * Math.Sin(phi) * Math.Sin(phi)); phiP = phi; phi = Math.Atan2(z2 + eSq * nu * Math.Sin(phi), p); } var lambda = Math.Atan2(y2, x2); h = p / Math.Cos(phi) - nu; return new LatLong(ToDegree(phi), ToDegree(lambda), h); }
/** * Convert lat/lon from one ellipsoidal model to another * * q.v. Ordnance Survey 'A guide to coordinate systems in Great Britain' Section 6 * www.ordnancesurvey.co.uk/oswebsite/gps/docs/A_Guide_to_Coordinate_Systems_in_Great_Britain.pdf * * @private * @param {LatLon} point: lat/lon in source reference frame * @param {Number[]} sourceEllipse: source ellipse parameters * @param {Number[]} t: Helmert transform parameters * @param {Number[]} targetEllipse: target ellipse parameters * @return {Coord} lat/lon in target reference frame */ private LatLong ConvertEllipsoidOSGB36ToWGS84(LatLong point) { var t = TransformFromOSGB36ToWGS84; var sourceEllipse = Ellipse[EllipseEnum.Airy1830]; var targetEllipse = Ellipse[EllipseEnum.WGS84]; // -- 1: convert polar to Cartesian coordinates (using ellipse 1) var lat = ToRadian(point.Lat); var lon = ToRadian(point.Long); var a = sourceEllipse.A; var b = sourceEllipse.B; var sinPhi = Math.Sin(lat); var cosPhi = Math.Cos(lat); var sinLambda = Math.Sin(lon); var cosLambda = Math.Cos(lon); var h = 24.7; // for the moment var eSq = (a * a - b * b) / (a * a); var nu = a / Math.Sqrt(1 - eSq * sinPhi * sinPhi); var x1 = (nu + h) * cosPhi * cosLambda; var y1 = (nu + h) * cosPhi * sinLambda; var z1 = ((1 - eSq) * nu + h) * sinPhi; // -- 2: apply Helmert transform using appropriate params var tx = t.Tx; var ty = t.Ty; var tz = t.Tz; var rx = ToRadian(t.Rx / 3600); // normalise seconds to radians var ry = ToRadian(t.Ry / 3600); var rz = ToRadian(t.Rz / 3600); var s1 = t.S / 1e6 + 1; // normalise ppm to (s+1) // apply transform var x2 = tx + x1 * s1 - y1 * rz + z1 * ry; var y2 = ty + x1 * rz + y1 * s1 - z1 * rx; var z2 = tz - x1 * ry + y1 * rx + z1 * s1; // -- 3: convert Cartesian to polar coordinates (using ellipse 2) a = targetEllipse.A; b = targetEllipse.B; var precision = 4 / a; // results accurate to around 4 metres eSq = (a * a - b * b) / (a * a); var p = Math.Sqrt(x2 * x2 + y2 * y2); var phi = Math.Atan2(z2, p * (1 - eSq)); var phiP = 2 * Math.PI; while (Math.Abs(phi - phiP) > precision) { nu = a / Math.Sqrt(1 - eSq * Math.Sin(phi) * Math.Sin(phi)); phiP = phi; phi = Math.Atan2(z2 + eSq * nu * Math.Sin(phi), p); } var lambda = Math.Atan2(y2, x2); h = p / Math.Cos(phi) - nu; return(new LatLong(ToDegree(phi), ToDegree(lambda), h)); }