/// <summary> /// Creates instance of 3D shifted transformation. /// </summary> /// <param name="Tx"></param> /// <param name="Ty"></param> /// <param name="Tz"></param> public Helmert(double Tx, double Ty, double Tz) { _matrix = new[, ] { { 0, 1, 0, Tx }, { 0, 1, 0, Ty }, { 0, 0, 1, Tz }, { 0, 0, 0, 1 } }; _para = new TransParameters(null, null, Tx, Ty, Tz, 0, 0, 0, 0); }
/// <summary> /// /// </summary> /// <param name="Tx"></param> /// <param name="Ty"></param> /// <param name="Tz"></param> /// <param name="S"></param> public BursaWolf(double Tx, double Ty, double Tz, double S = 0) : base(Tx, Ty, Tz) { for (int i = 0; i < 3; i++) { _matrix[i, i] *= 1 + S * 1E-6; } _para = new TransParameters(null, null, Tx, Ty, Tz, S, 0, 0, 0); }
/// <summary> /// Molodensky-Badekas transformations /// </summary> /// <param name="point">space rectangular point</param> /// <param name="para">(7+3) parameters</param> /// <returns>space point in new datum</returns> public static SpaceRectangularCoord Transform(SpaceRectangularCoord point, TransParameters para) { // the last three is special double dX = point.X - para.GetValue("Px"); double dY = point.Y - para.GetValue("Py"); double dZ = point.Z - para.GetValue("Pz"); double X, Y, Z; // formula is from https://en.wikipedia.org/wiki/Geographic_coordinate_conversion X = point.X + para.Tx + (dX - para.Rz * dY + para.Ry * dZ) + para.S * 1E-6 * dX; Y = point.Y + para.Ty + (para.Rz * dX + dY - para.Rx * dZ) + para.S * 1E-6 * dY; Z = point.Z + para.Tz + (-para.Ry * dX + para.Rx * dY + dZ) + para.S * 1E-6 * dZ; return(new SpaceRectangularCoord(X, Y, Z)); }
/// <summary> /// Creates instance of 3D rotational and shifted transformation. /// </summary> /// <param name="para"></param> public Helmert(TransParameters para) { _matrix = new[, ] { { 1, -para.Rz, para.Ry, para.Tx }, { para.Rz, 1, -para.Rx, para.Ty }, { -para.Ry, para.Rx, 1, para.Tz }, { 0, 0, 0, 1 } }; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { _matrix[i, j] *= (1 + para.S * 1E-6); } } _para = para; }
/// <summary> /// transform the geodetic datum /// </summary> /// <param name="point">geodetic point</param> /// <param name="from">source ellipsoid</param> /// <param name="to">target ellipsoid</param> /// <param name="para">three translation parameters</param> /// <returns>geodetic point in new datum</returns> public static GeodeticCoord Transform(GeodeticCoord point, Ellipsoid from, Ellipsoid to, TransParameters para) { double B = point.Latitude.Radians; double L = point.Longitude.Radians; double H = point.Height; double sinB = Math.Sin(B); double cosB = Math.Cos(B); double sinL = Math.Sin(L); double cosL = Math.Cos(L); double a = from.SemiMajorAxis; double b_a = 1 - from.Flattening; double da = to.SemiMajorAxis - from.SemiMajorAxis; double df = to.Flattening - from.Flattening; double ee = from.ee; double w = 1.0 - ee * sinB * sinB; double Rm = a * (1.0 - ee) / Math.Pow(w, 1.5); double Rn = a / Math.Sqrt(w); // formula is from http://earth-info.nga.mil/GandG/coordsys/datums/standardmolodensky.html double dB = (-para.Tx * sinB * cosL - para.Ty * sinB * sinL + para.Tz * cosB + da * (Rn * ee * sinB * cosB) / a + df * (Rm / b_a + Rn * b_a) * sinB * cosB) / (Rm + H); double dL = (-para.Tx * sinL + para.Ty * cosL) / ((Rn + H) * cosB); double dH = para.Tx * cosB * cosL + para.Ty * cosB * sinL + para.Tz * sinB - da * a / Rn + df * Rn * b_a * sinB * sinB; return(new GeodeticCoord(Latitude.FromRadians(B + dB), Longitude.FromRadians(L + dL), H + dH)); }
/// <summary> /// Creates instance of 2D rotational and shifted transformation. /// </summary> /// <param name="theta"></param> /// <param name="Tx"></param> /// <param name="Ty"></param> public Helmert(Angle theta, double Tx = 0, double Ty = 0) : base(theta, Tx, Ty) { _para = null; }
/// <summary> /// /// </summary> /// <param name="para"></param> public BursaWolf(TransParameters para) : base(para) { _para = para; }