Exemple #1
0
        /// <summary>
        /// Converts a geodetic coordinate to a grid coordinate.
        /// </summary>
        /// <param name="coordinate">The geodetic coordinate to convert.</param>
        /// <param name="projection">The projection to use in the conversion.</param>
        /// <returns>The grid representation of the initial coordinate.</returns>
        public static GridCoordinate GeodeticToGrid(GeodeticCoordinate coordinate, Projection projection)
        {
            var gridCoordinate = new GridCoordinate {
                Projection = projection
            };

            double flattening = projection.Ellipsoid.Flattening;
            double axis       = projection.Ellipsoid.SemiMajorAxis;

            double eSquare = flattening * (2d - flattening);
            double n       = flattening / (2d - flattening);
            double a       = axis / (1d + n) * (1 + n * n / 4 + n * n * n * n / 64d);

            // ReSharper disable InconsistentNaming
            double A = eSquare;
            double B = (5d * eSquare * eSquare - eSquare * eSquare * eSquare) / 6d;
            double C = (104d * eSquare * eSquare * eSquare - 45d * eSquare * eSquare * eSquare * eSquare) / 120d;
            double D = (1237d * eSquare * eSquare * eSquare * eSquare) / 1260d;
            // ReSharper restore InconsistentNaming

            double beta1 = n / 2d - (2d * n * n) / 3d + (5d * n * n * n) / 16d + (41d * n * n * n * n) / 180d;
            double beta2 = (13d * n * n) / 48d - (3d * n * n * n) / 5d + (557d * n * n * n * n) / 1440d;
            double beta3 = (61d * n * n * n) / 240d - (103d * n * n * n * n) / 140d;
            double beta4 = (49561d * n * n * n * n) / 161280d;

            double radLat      = coordinate.Latitude.ToRadians();
            double radLon      = coordinate.Longitude.ToRadians();
            double radMeridian = projection.CentralMeridianLon.ToRadians();
            double radLonDelta = radLon - radMeridian;

            double conformalLatitude = radLat - Math.Sin(radLat) * Math.Cos(radLat) * (A + B * Math.Pow(Math.Sin(radLat), 2d) + C * Math.Pow(Math.Sin(radLat), 4d) + D * Math.Pow(Math.Sin(radLat), 6d));

            double xiPrime  = Math.Atan(Math.Tan(conformalLatitude) / Math.Cos(radLonDelta)); // Bad naming but there is no name defined for this in the specs
            double etaPrime = Atanh(Math.Cos(conformalLatitude) * Math.Sin(radLonDelta));     // Bad naming but there is no name defined for this in the specs

            gridCoordinate.X = projection.CentralMeridianScale * a * (xiPrime +
                                                                      beta1 * Math.Sin(2d * xiPrime) * Math.Cosh(2d * etaPrime) +
                                                                      beta2 * Math.Sin(4d * xiPrime) * Math.Cosh(4d * etaPrime) +
                                                                      beta3 * Math.Sin(6d * xiPrime) * Math.Cosh(6d * etaPrime) +
                                                                      beta4 * Math.Sin(8d * xiPrime) * Math.Cosh(8d * etaPrime)) + projection.FalseNorthing;

            gridCoordinate.Y = projection.CentralMeridianScale * a * (etaPrime +
                                                                      beta1 * Math.Cos(2d * xiPrime) * Math.Sinh(2d * etaPrime) +
                                                                      beta2 * Math.Cos(4d * xiPrime) * Math.Sinh(4d * etaPrime) +
                                                                      beta3 * Math.Cos(6d * xiPrime) * Math.Sinh(6d * etaPrime) +
                                                                      beta4 * Math.Cos(8d * xiPrime) * Math.Sinh(8d * etaPrime)) + projection.FalseEasting;

            return(gridCoordinate);
        }