예제 #1
0
        /// <summary>
        /// <param name="locations">A 2D map of locations on the surface of earth. </param>
        /// </summary>
        public void FillElevationData(ref LatLonAlt[,] locations)
        {
            CultureInfo ci = new CultureInfo("en-US");
            List<string> loc = new List<string>();
            for (int J = 0; J < locations.GetLength(0); J++)
            {
                for (int I = 0; I < locations.GetLength(1); I++)
                {
                    loc.Add(String.Format(ci, "{0:0.0000},{1:0.0000}", locations[I, J].Latitude, locations[I, J].Longitude));
                }
            }
            var url = String.Format("http://maps.googleapis.com/maps/api/elevation/xml?sensor=false&locations={0}", loc.Aggregate((i, j) => i + "|" + j));

            Console.WriteLine("Fetching elevation data from maps.googleapis.com...");
            XmlDocument elevationData = new XmlDocument();
            elevationData.Load(url);

            XmlNodeList xmlNodeList = elevationData.SelectNodes("/ElevationResponse/result/elevation");

            var di = 0; // A local counter
            int x = 0; // the I-index of the matrix
            int y = 0; // the J-index of the matrix.
            foreach (XmlNode xmlNode in xmlNodeList)
            {
                // Update locations directly as we're spinning through all XML nodes.
                locations[x, y].Altitude = double.Parse(xmlNode.InnerText, ci.NumberFormat);
                di++;
                x = di % locations.GetLength(0);
                if (x == 0) y++;
            }
        }
예제 #2
0
        static void Main(string[] args)
        {
            try
            {
                // Set the Culture Info for the entire main thread.
                Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");

                // Using the "Command Line Parser Library" from CodePlex
                // The MIT License (MIT)
                // Copyright (c) 2005 - 2012 Giacomo Stelluti Scala
                var options = new Options();
                ICommandLineParser parser = new CommandLineParser();

                /// Example
                /// elevation --dms-latitude 61:53:37.20 --dms-longitude 9:51:43.92 --num-cells-I 10 --num-cells-J 10 --distance-ew 2000.0 --distance-ns 2000.0 --output rondane.stl
                if (parser.ParseArguments(args, options))
                {
                    // consume Options type properties
                    var lat    = options.dmsLatitude;
                    var lon    = options.dmsLongitude;
                    var ni     = options.NI;
                    var nj     = options.NJ;
                    var distSN = options.distNS;
                    var distEW = options.distEW;

                    // Generate a surface, i.e. a map of LatLonAlt types surrounding the initial
                    // central location given by the user.
                    var surface   = new Surface(new LatLonAlt(lat, lon), distSN, distEW);
                    var locations = new LatLonAlt[ni, nj];
                    surface.GenerateSurface(ref locations);

                    // Fetch elevation data from Google
                    var service = new GoogleElevationService();
                    service.FillElevationData(ref locations);

                    // Generate a matrix of vertices using cartesian coordinates with
                    // the point of interest in the center (0,0)
                    var vertices = GenerateVerticesMatrix(ref locations, ni, nj, distEW, distSN);

                    // Write the map to an STL output file
                    var fileName = options.Output;
                    //var vertices = Vertex.ToVertex(ref locations);
                    var stl = new Stereolithography(vertices); // vertices);
                    stl.Write(fileName);

                    Console.WriteLine(String.Format("Output written to {0}", fileName));
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("{0} Exception Error", e);
            }
        }
예제 #3
0
        /// <summary>
        /// Calculates the end-point from a given source at a given range (meters) and bearing (degrees).
        /// This methods uses simple geometry equations to calculate the end-point.
        /// </summary>
        /// <param name="source">Point of origin</param>
        /// <param name="range">Range in meters</param>
        /// <param name="bearing">Bearing in degrees</param>
        /// <returns>End-point from the source given the desired range and bearing.</returns>
        ///
        public static LatLonAlt CalculateDerivedPosition(LatLonAlt source, double distance, double bearing)
        {
            double latA            = source.Latitude * DegreesToRadians;
            double lonA            = source.Longitude * DegreesToRadians;
            double angularDistance = distance / EarthRadius;
            double trueCourse      = bearing * DegreesToRadians;

            double lat  = Math.Asin(Math.Sin(latA) * Math.Cos(angularDistance) + Math.Cos(latA) * Math.Sin(angularDistance) * Math.Cos(trueCourse));
            double dlon = Math.Atan2(Math.Sin(trueCourse) * Math.Sin(angularDistance) * Math.Cos(latA),
                                     Math.Cos(angularDistance) - Math.Sin(latA) * Math.Sin(lat));
            double lon = ((lonA + dlon + Math.PI) % (Math.PI * 2.0)) - Math.PI;

            return(new LatLonAlt(lat * RadiansToDegrees, lon * RadiansToDegrees, source.Altitude));
        }
예제 #4
0
        /// <summary>
        /// Calculates the end-point from a given source at a given range (meters) and bearing (degrees).
        /// This methods uses simple geometry equations to calculate the end-point.
        /// </summary>
        /// <param name="source">Point of origin</param>
        /// <param name="range">Range in meters</param>
        /// <param name="bearing">Bearing in degrees</param>
        /// <returns>End-point from the source given the desired range and bearing.</returns>
        /// 
        public static LatLonAlt CalculateDerivedPosition(LatLonAlt source, double distance, double bearing)
        {
            double latA = source.Latitude * DegreesToRadians;
            double lonA = source.Longitude * DegreesToRadians;
            double angularDistance = distance / EarthRadius;
            double trueCourse = bearing * DegreesToRadians;

            double lat = Math.Asin(Math.Sin(latA) * Math.Cos(angularDistance) + Math.Cos(latA) * Math.Sin(angularDistance) * Math.Cos(trueCourse));
            double dlon = Math.Atan2(Math.Sin(trueCourse) * Math.Sin(angularDistance) * Math.Cos(latA),
                                          Math.Cos(angularDistance) - Math.Sin(latA) * Math.Sin(lat));
            double lon = ((lonA + dlon + Math.PI) % (Math.PI * 2.0)) - Math.PI;

            return new LatLonAlt(lat * RadiansToDegrees, lon * RadiansToDegrees, source.Altitude);
        }
예제 #5
0
        /// <summary>
        /// Generates a cartesian mesh by inserting relative X and Y coordinates based on the given distance
        /// and Z (elevation) based on a locations map.
        /// </summary>
        /// <param name="locations">Location data containing elevation information</param>
        /// <param name="ni">Number of horizontal (X) grid cells</param>
        /// <param name="nj">Number of vertical (Y) grid cells</param>
        /// <param name="distEW">Total horizontal distance</param>
        /// <param name="distSN">Total vertical distance</param>
        /// <returns></returns>
        private static Vertex[,] GenerateVerticesMatrix(ref LatLonAlt[,] locations, int ni, int nj, double distEW, double distSN)
        {
            var x0 = -distEW / 2F;
            var y0 = -distSN / 2F;

            var y = y0;
            double dx = distEW / (double)ni;
            double dy = distSN / (double)nj;
            var vertices = new Vertex[ni, nj];

            for (var j = 0; j < nj; j++)
            {
                var x = x0;
                for (var i = 0; i < ni; i++)
                {
                    vertices[i, j] = new Vertex(x, y, locations[i, j].Altitude);
                    x += dx;
                }
                y += dy;
            }
            return vertices;
        }
예제 #6
0
        public static Vertex[,] ToVertex(ref LatLonAlt[,] pos)
        {
            var vertex = new Vertex[pos.GetLength(0), pos.GetLength(1)];
            for (var j = 0; j < pos.GetLength(1); j++)
            {
                for (var i = 0; i < pos.GetLength(1); i++)
                {
                    vertex[i, j] = ToVertex(pos[i, j]);
                }
            }

            return vertex;
        }
예제 #7
0
 public static Vertex ToVertex(LatLonAlt pos)
 {
     var vertex = new Vertex(pos.Latitude, pos.Longitude, pos.Altitude);
     return vertex;
 }
예제 #8
0
        public static Vertex ToVertex(LatLonAlt pos)
        {
            var vertex = new Vertex(pos.Latitude, pos.Longitude, pos.Altitude);

            return(vertex);
        }
예제 #9
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="center">The center of the map</param>
 /// <param name="distanceNS">Length of the map from South to North (in meters)</param>
 /// <param name="distanceEW">Length of the map from East to West (in meters)</param>
 /// <param name="ni">Number of grid cells in I - direction (EW)</param>
 /// <param name="nj">Number of grid cells in J - direction (NS)</param>
 /// <author>Thomas F. Hagelien</author>
 public Surface(LatLonAlt center, double distanceNS, double distanceEW)
 {
     Center     = center;
     DistanceNS = distanceNS;
     DistanceEW = distanceEW;
 }
예제 #10
0
 /// <summary>
 /// Constructor using default settings (10x10 grid, 100m bearing)
 /// </summary>
 /// <param name="center">The center of the map</param>
 public Surface(LatLonAlt center)
 {
     Center     = center;
     DistanceEW = 100.0;
     DistanceNS = 100.0;
 }
예제 #11
0
        public void GenerateSurface(ref LatLonAlt [,] locations)
        {
            var west = Geometry.CalculateDerivedPosition(Center, DistanceNS / 2.0, 180.0);
            var southWest = Geometry.CalculateDerivedPosition(west, DistanceEW / 2.0, 240.0);

            var ni = locations.GetLength(0);
            var nj = locations.GetLength(1);

            double dNS = DistanceNS / (double)ni;
            double dEW = DistanceEW / (double)nj;

            // Fill in the geographics from southWest up to northEast.
            var position = southWest;
            for (int J = 0; J < nj; ++J)
            {
                position = Geometry.CalculateDerivedPosition(position, dEW * (double)J, 90.0);
                locations[0, J] = position;

                for (int I = 1; I < ni; I++)
                {
                    locations[I, J] = Geometry.CalculateDerivedPosition(position, dNS * (double)I, 0.0);
                }
            }
        }
예제 #12
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="center">The center of the map</param>
 /// <param name="distanceNS">Length of the map from South to North (in meters)</param>
 /// <param name="distanceEW">Length of the map from East to West (in meters)</param>
 /// <param name="ni">Number of grid cells in I - direction (EW)</param>
 /// <param name="nj">Number of grid cells in J - direction (NS)</param>
 /// <author>Thomas F. Hagelien</author>
 public Surface(LatLonAlt center, double distanceNS, double distanceEW)
 {
     Center = center;
     DistanceNS = distanceNS;
     DistanceEW = distanceEW;
 }
예제 #13
0
 /// <summary>
 /// Constructor using default settings (10x10 grid, 100m bearing)
 /// </summary>
 /// <param name="center">The center of the map</param>
 public Surface(LatLonAlt center)
 {
     Center = center;
     DistanceEW = 100.0;
     DistanceNS = 100.0;
 }
예제 #14
0
        static void Main(string[] args)
        {
            try
            {
                // Set the Culture Info for the entire main thread.
                Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");

                // Using the "Command Line Parser Library" from CodePlex
                // The MIT License (MIT)
                // Copyright (c) 2005 - 2012 Giacomo Stelluti Scala
                var options = new Options();
                ICommandLineParser parser = new CommandLineParser();

                /// Example
                /// elevation --dms-latitude 61:53:37.20 --dms-longitude 9:51:43.92 --num-cells-I 10 --num-cells-J 10 --distance-ew 2000.0 --distance-ns 2000.0 --output rondane.stl
                if (parser.ParseArguments(args, options))
                {
                    // consume Options type properties
                    var lat = options.dmsLatitude;
                    var lon = options.dmsLongitude;
                    var ni = options.NI;
                    var nj = options.NJ;
                    var distSN = options.distNS;
                    var distEW = options.distEW;

                    // Generate a surface, i.e. a map of LatLonAlt types surrounding the initial
                    // central location given by the user.
                    var surface = new Surface(new LatLonAlt(lat, lon), distSN, distEW);
                    var locations = new LatLonAlt[ni, nj];
                    surface.GenerateSurface(ref locations);

                    // Fetch elevation data from Google
                    var service = new GoogleElevationService();
                    service.FillElevationData(ref locations);

                    // Generate a matrix of vertices using cartesian coordinates with
                    // the point of interest in the center (0,0)
                    var vertices = GenerateVerticesMatrix(ref locations, ni, nj, distEW, distSN);

                    // Write the map to an STL output file
                    var fileName = options.Output;
                    //var vertices = Vertex.ToVertex(ref locations);
                    var stl = new Stereolithography(vertices); // vertices);
                    stl.Write(fileName);

                    Console.WriteLine(String.Format("Output written to {0}", fileName));
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("{0} Exception Error", e);
            }
        }