Пример #1
0
        // IGH -> MSTS Tile
        public static TileCoordinate ConvertToTile(IghCoordinate coordinates, out double x, out double z)
        {
            var coord = ConvertToTile(coordinates);

            x = coord.X;
            z = coord.Z;
            return(coord);
        }
Пример #2
0
        // IGH -> MSTS Precise Tile
        public static PreciseTileCoordinate ConvertToTile(IghCoordinate coordinates)
        {
            var tileX = coordinates.Sample / 2048;
            var tileZ = coordinates.Line / 2048;
            var x     = tileX - Math.Floor(tileX);
            var z     = tileZ - Math.Floor(tileZ);

            Debug.Assert(z >= 0, "tileZ is off the top");
            Debug.Assert(z <= 1, "tileZ is off the bottom");
            Debug.Assert(x >= 0, "tileX is off the left");
            Debug.Assert(x <= 1, "tileX is off the right");
            return(new PreciseTileCoordinate((int)Math.Floor(tileX) - 16384, 16384 - (int)Math.Floor(tileZ) - 1, x, z));
        }
Пример #3
0
        // Lat/Lon -> MSTS IGH
        public static IghCoordinate ConvertToIgh(LatitudeLongitudeCoordinate coordinates)
        {
            // Latitude/Longitude -> Line/Sample Algorithm
            // Based on C code provided by the USGS, available at ftp://edcftp.cr.usgs.gov/pub/software/misc/gihll2ls.c.
            // By D. Steinwand, HSTX/EROS Data Center, June, 1993.

            Debug.Assert(coordinates.Latitude >= -90, "latitude is off the bottom");
            Debug.Assert(coordinates.Latitude <= 90, "latitude is off the top");
            Debug.Assert(coordinates.Longitude >= -180, "longitude is off the left");
            Debug.Assert(coordinates.Longitude <= 180, "longitude is off the right");

            double lat = coordinates.Latitude * Math.PI / 180;
            double lon = coordinates.Longitude * Math.PI / 180;

            int region = -1;

            if (lat >= IghParallel41)                             /* If on or above 40 44' 11.8" */
            {
                if (lon <= -IghMeridian40)                        /* If to the left of -40 */
                {
                    region = 0;
                }
                else
                {
                    region = 2;
                }
            }
            else if (lat >= 0.0)                               /* Between 0.0 and 40 44' 11.8" */
            {
                if (lon <= -IghMeridian40)                     /* If to the left of -40 */
                {
                    region = 1;
                }
                else
                {
                    region = 3;
                }
            }
            else if (lat >= -IghParallel41)                       /* Between 0.0 & -40 44' 11.8" */
            {
                if (lon <= -IghMeridian100)                       /* If between -180 and -100 */
                {
                    region = 4;
                }
                else if (lon <= -IghMeridian20)                       /* If between -100 and -20 */
                {
                    region = 5;
                }
                else if (lon <= IghMeridian80)                        /* If between -20 and 80 */
                {
                    region = 8;
                }
                else                                               /* If between 80 and 180 */
                {
                    region = 9;
                }
            }
            else                                               /* Below -40 44' 11.8" */
            {
                if (lon <= -IghMeridian100)                    /* If between -180 and -100 */
                {
                    region = 6;
                }
                else if (lon <= -IghMeridian20)                       /* If between -100 and -20 */
                {
                    region = 7;
                }
                else if (lon <= IghMeridian80)                        /* If between -20 and 80 */
                {
                    region = 10;
                }
                else                                               /* If between 80 and 180 */
                {
                    region = 11;
                }
            }

            double y = 0;
            double x = 0;

            if ((region == 1) || (region == 3) || (region == 4) || (region == 5) || (region == 8) || (region == 9))
            {
                var delta_lon = adjust_lon(lon - IghLongitudeCenter[region]);
                y = lat;
                x = IghLongitudeCenter[region] + delta_lon * Math.Cos(lat);
            }
            else
            {
                var delta_lon = adjust_lon(lon - IghLongitudeCenter[region]);
                var theta     = lat;
                var constant  = Math.PI * Math.Sin(lat);

                /* Iterate using the Newton-Raphson method to find theta
                 * -----------------------------------------------------*/
                for (var i = 0; ; i++)
                {
                    var delta_theta = -(theta + Math.Sin(theta) - constant) / (1.0 + Math.Cos(theta));
                    theta += delta_theta;
                    if (Math.Abs(delta_theta) < 0.00000000001)
                    {
                        break;
                    }
                    if (i >= 30)
                    {
                        //giherror("Iteration failed to converge", "Goode-forward");
                        return(null);
                    }
                }
                theta /= 2.0;
                y      = 1.4142135623731 * Math.Sin(theta) - 0.0528035274542 * Math.Sign(lat);
                x      = IghLongitudeCenter[region] + 0.900316316158 * delta_lon * Math.Cos(theta);
            }

            Debug.Assert(y >= -Math.PI / 2, "y is off the bottom");
            Debug.Assert(y <= +Math.PI / 2, "y is off the top");
            Debug.Assert(x >= -Math.PI, "x is off the left");
            Debug.Assert(x <= +Math.PI, "x is off the right");

            var igh = new IghCoordinate(IghImageTop - y * IghRadius, x * IghRadius - IghImageLeft);

            Debug.Assert(igh.Line >= 0, "line is off the top");
            Debug.Assert(igh.Line <= IghImageHeight, "line is off the bottom");
            Debug.Assert(igh.Sample >= 0, "line is off the left");
            Debug.Assert(igh.Sample <= IghImageWidth, "line is off the right");

            return(igh);
        }
Пример #4
0
        const double IghMeridian100 = 100d / 180 * Math.PI;                                // 100deg

        // IGH -> Lat/Lon
        public static LatitudeLongitudeCoordinate ConvertToLatLon(IghCoordinate coordinates)
        {
            // Line/Sample -> Latitude/Longitude Algorithm
            // Based on C code provided by the USGS, available at ftp://edcftp.cr.usgs.gov/pub/software/misc/gihll2ls.c.
            // By D. Steinwand, HSTX/EROS Data Center, June, 1993.

            Debug.Assert(coordinates.Line >= 0, "line is off the top");
            Debug.Assert(coordinates.Line <= IghImageHeight, "line is off the bottom");
            Debug.Assert(coordinates.Sample >= 0, "line is off the left");
            Debug.Assert(coordinates.Sample <= IghImageWidth, "line is off the right");

            double y = (IghImageTop - coordinates.Line) / IghRadius;
            double x = (IghImageLeft + coordinates.Sample) / IghRadius;

            Debug.Assert(y >= -Math.PI / 2, "y is off the bottom");
            Debug.Assert(y <= +Math.PI / 2, "y is off the top");
            Debug.Assert(x >= -Math.PI, "x is off the left");
            Debug.Assert(x <= +Math.PI, "x is off the right");

            int region = -1;

            if (y >= IghParallel41)                               /* If on or above 40 44' 11.8" */
            {
                if (x <= -IghMeridian40)                          /* If to the left of -40 */
                {
                    region = 0;
                }
                else
                {
                    region = 2;
                }
            }
            else if (y >= 0.0)                                 /* Between 0.0 and 40 44' 11.8" */
            {
                if (x <= -IghMeridian40)                       /* If to the left of -40 */
                {
                    region = 1;
                }
                else
                {
                    region = 3;
                }
            }
            else if (y >= -IghParallel41)                         /* Between 0.0 & -40 44' 11.8" */
            {
                if (x <= -IghMeridian100)                         /* If between -180 and -100 */
                {
                    region = 4;
                }
                else if (x <= -IghMeridian20)                         /* If between -100 and -20 */
                {
                    region = 5;
                }
                else if (x <= IghMeridian80)                          /* If between -20 and 80 */
                {
                    region = 8;
                }
                else                                               /* If between 80 and 180 */
                {
                    region = 9;
                }
            }
            else                                               /* Below -40 44' 11.8" */
            {
                if (x <= -IghMeridian100)                      /* If between -180 and -100 */
                {
                    region = 6;
                }
                else if (x <= -IghMeridian20)                         /* If between -100 and -20 */
                {
                    region = 7;
                }
                else if (x <= IghMeridian80)                          /* If between -20 and 80 */
                {
                    region = 10;
                }
                else                                               /* If between 80 and 180 */
                {
                    region = 11;
                }
            }
            x = x - IghLongitudeCenter[region];

            double lat = 0;
            double lon = 0;

            if ((region == 1) || (region == 3) || (region == 4) || (region == 5) || (region == 8) || (region == 9))
            {
                lat = y;
                if (Math.Abs(lat) > Math.PI / 2)
                {
                    // giherror("Input data error", "Goode-inverse");
                    return(null);
                }
                double temp = Math.Abs(lat) - Math.PI / 2;
                if (Math.Abs(temp) > double.Epsilon)
                {
                    temp = IghLongitudeCenter[region] + x / Math.Cos(lat);
                    lon  = adjust_lon(temp);
                }
                else
                {
                    lon = IghLongitudeCenter[region];
                }
            }
            else
            {
                double arg = (y + 0.0528035274542 * Math.Sign(y)) / 1.4142135623731;
                if (Math.Abs(arg) > 1.0)
                {
                    return(null);
                }
                double theta = Math.Asin(arg);
                lon = IghLongitudeCenter[region] + (x / (0.900316316158 * Math.Cos(theta)));
                if (lon < -Math.PI)
                {
                    return(null);
                }
                arg = (2.0 * theta + Math.Sin(2.0 * theta)) / Math.PI;
                if (Math.Abs(arg) > 1.0)
                {
                    return(null);
                }
                lat = Math.Asin(arg);
            }

            ///////////////////////////////////////////////////////////////////

            return(new LatitudeLongitudeCoordinate(lat * 180 / Math.PI, lon * 180 / Math.PI));
        }