Exemple #1
0
        internal static PolarGeoCoordinate Convert(PolarGeoCoordinate source, CoordinateSystems destination)
        {
            PolarGeoCoordinate retVal;

            if (source.CoordinateSystem == CoordinateSystems.OSGB36 && destination == CoordinateSystems.WGS84)
            {
                retVal = Convert(
                    source,
                    EllipseParameter.GetEllipseParameters(EllipseParameter.Ellipses.Airy1830),
                    HelmertTransform.GetTransform(HelmertTransform.HelmertTransformType.OSGB36toWGS84),
                    EllipseParameter.GetEllipseParameters(EllipseParameter.Ellipses.WGS84)
                    );
            }
            else if (source.CoordinateSystem == CoordinateSystems.WGS84 && destination == CoordinateSystems.OSGB36)
            {
                retVal = Convert(
                    source,
                    EllipseParameter.GetEllipseParameters(EllipseParameter.Ellipses.WGS84),
                    HelmertTransform.GetTransform(HelmertTransform.HelmertTransformType.WGS84toOSGB36),
                    EllipseParameter.GetEllipseParameters(EllipseParameter.Ellipses.Airy1830)
                    );
            }
            else
            {
                throw new NotImplementedException("Requested source and destination are not currently supported");
            }

            retVal.AlignSigFigs(source);
            return(retVal);
        }
Exemple #2
0
        private static PolarGeoCoordinate Convert(
            PolarGeoCoordinate originalCoord, EllipseParameter e1, HelmertTransform t, EllipseParameter e2)
        {
            // -- convert polar to cartesian coordinates (using ellipse 1)
            PolarGeoCoordinate p1 = PolarGeoCoordinate.ChangeUnits(originalCoord, AngleUnit.Radians);

            double sinPhi    = Math.Sin(p1.Lat);
            double cosPhi    = Math.Cos(p1.Lat);
            double sinLambda = Math.Sin(p1.Lon);
            double cosLambda = Math.Cos(p1.Lon);

            double H = p1.Height;

            double eSq = (Math.Pow(e1.SemimajorAxis, 2) - Math.Pow(e1.SemiMinorAxis, 2)) / Math.Pow(e1.SemimajorAxis, 2);
            double nu  = e1.SemimajorAxis / Math.Sqrt(1 - eSq * sinPhi * sinPhi);

            double x1 = (nu + H) * cosPhi * cosLambda;
            double y1 = (nu + H) * cosPhi * sinLambda;
            double z1 = ((1 - eSq) * nu + H) * sinPhi;

            // -- apply helmert transform using appropriate params
            double tx = t.tx, ty = t.ty, tz = t.tz;
            double rx = t.rx / 3600 * Math.PI / 180; // normalise seconds to radians
            double ry = t.ry / 3600 * Math.PI / 180;
            double rz = t.rz / 3600 * Math.PI / 180;
            double s1 = t.s / 1e6 + 1; // normalise ppm to (s+1)

            // apply transform
            double x2 = tx + x1 * s1 - y1 * rz + z1 * ry;
            double y2 = ty + x1 * rz + y1 * s1 - z1 * rx;
            double z2 = tz - x1 * ry + y1 * rx + z1 * s1;

            // -- convert cartesian to polar coordinates (using ellipse 2)
            double a = e2.SemimajorAxis;

            double precision = 4 / e2.SemimajorAxis; // results accurate to around 4 metres

            eSq = (Math.Pow(e2.SemimajorAxis, 2) - Math.Pow(e2.SemiMinorAxis, 2)) / Math.Pow(e2.SemimajorAxis, 2);
            double p = Math.Sqrt(x2 * x2 + y2 * y2);
            double phi = Math.Atan2(z2, p * (1 - eSq)), 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);
            }

            double lambda = Math.Atan2(y2, x2);

            H = p / Math.Cos(phi) - nu;

            return(new PolarGeoCoordinate(
                       RadToDeg(phi), RadToDeg(lambda), H, AngleUnit.Degrees, t.outputCoordinateSystem));
        }
        private static PolarGeoCoordinate Convert(
            PolarGeoCoordinate originalCoord, EllipseParameter e1, HelmertTransform t, EllipseParameter e2)
        {
            // -- convert polar to cartesian coordinates (using ellipse 1)
            PolarGeoCoordinate p1 = PolarGeoCoordinate.ChangeUnits(originalCoord, AngleUnit.Radians);

            double sinPhi = Math.Sin(p1.Lat);
            double cosPhi = Math.Cos(p1.Lat);
            double sinLambda = Math.Sin(p1.Lon);
            double cosLambda = Math.Cos(p1.Lon);

            double H = p1.Height;

            double eSq = (Math.Pow(e1.SemimajorAxis, 2) - Math.Pow(e1.SemiMinorAxis, 2)) / Math.Pow(e1.SemimajorAxis, 2);
            double nu = e1.SemimajorAxis / Math.Sqrt(1 - eSq * sinPhi * sinPhi);

            double x1 = (nu + H) * cosPhi * cosLambda;
            double y1 = (nu + H) * cosPhi * sinLambda;
            double z1 = ((1 - eSq) * nu + H) * sinPhi;

            // -- apply helmert transform using appropriate params
            double tx = t.tx, ty = t.ty, tz = t.tz;
            double rx = t.rx / 3600 * Math.PI / 180; // normalise seconds to radians
            double ry = t.ry / 3600 * Math.PI / 180;
            double rz = t.rz / 3600 * Math.PI / 180;
            double s1 = t.s / 1e6 + 1; // normalise ppm to (s+1)

            // apply transform
            double x2 = tx + x1 * s1 - y1 * rz + z1 * ry;
            double y2 = ty + x1 * rz + y1 * s1 - z1 * rx;
            double z2 = tz - x1 * ry + y1 * rx + z1 * s1;

            // -- convert cartesian to polar coordinates (using ellipse 2)
            double a = e2.SemimajorAxis;

            double precision = 4 / e2.SemimajorAxis; // results accurate to around 4 metres

            eSq = (Math.Pow(e2.SemimajorAxis, 2) - Math.Pow(e2.SemiMinorAxis, 2)) / Math.Pow(e2.SemimajorAxis, 2);
            double p = Math.Sqrt(x2 * x2 + y2 * y2);
            double phi = Math.Atan2(z2, p * (1 - eSq)), 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);
            }

            double lambda = Math.Atan2(y2, x2);
            H = p / Math.Cos(phi) - nu;

            return new PolarGeoCoordinate(
                RadToDeg(phi), RadToDeg(lambda), H, AngleUnit.Degrees, t.outputCoordinateSystem);
        }