Example #1
0
        public override void Run()
        {
            base.Run();

            var patch = TerrainPatch.FromId(147, 72);

            Console.WriteLine(@"Generating safe havens");
            var safe_haven_gen = new SafeHavenGenerator {
                Region = patch.Bounds, WriteHorizons = false
            };

            safe_haven_gen.WriteSafeHavenGeotiffs(OutputPath);

            Console.WriteLine(@"Generating average Earth and average Sun patches");
            var(start, stop, step) = StudyInterval.SiteStudyPeriod.GetInterval();
            var gen = new TileLightingProductManager
            {
                //MainWindow = MainWindow,
                Selection               = patch.Bounds,
                IntervalStart           = start,
                IntervalStop            = stop,
                IntervalStep            = step,
                ObserverHeightInMeters  = 0,
                EarthMultipathThreshold = 2f,
                GenerateAverageSun      = true,
                GenerateAverageEarth    = true
            };

            gen.GenerateAverageSunEarthPatches();

            Console.WriteLine(@"Finished.");
        }
Example #2
0
        public TerrainPatch ToTerrainPatch()
        {
            var tp = TerrainPatch.FromId(Id);

            tp.Step = Step;
            return(tp);
        }
Example #3
0
        public override void Run()
        {
            base.Run();
            var patch          = TerrainPatch.FromId(147, 72);
            var safe_haven_gen = new SafeHavenGenerator {
                Region = patch.Bounds, WriteHorizons = true
            };

            safe_haven_gen.WriteSafeHavenGeotiffs(OutputPath);
        }
Example #4
0
        public void Test1()
        {
            To   = TerrainPatch.FromId(new Point(103, 138));
            From = TerrainPatch.FromId(new Point(103, 139));

            To.FillPointsAndMatrices(Terrain);
            From.FillPoints(Terrain);
            To.UpdateHorizonBugHunt(From);
            Console.WriteLine(@"Test1 finished.");
        }
Example #5
0
        public override void Run()
        {
            base.Run();
            var patch = TerrainPatch.FromId(147, 72);
            var queue = new List <TerrainPatch> {
                patch
            };
            var gpu = new GPUHorizons {
                Terrain = ViperEnvironment.Terrain
            };

            Console.WriteLine("Running the queue");
            gpu.RunQueue(queue, unloadHorizons: false, writeHorizons: false);
            Console.WriteLine("Finished running the queue");
        }
 public void GetHorizonBoxes(List <Point> ids, Action <List <Rectangle> > callback) =>
 Task.Run(() =>
 {
     var gpuProcessor = MainWindow.Processor as GPUProcessor;
     var rectangles   = new List <Rectangle>();
     foreach (var id in ids)
     {
         gpuProcessor.RunQueue(new List <TerrainPatch> {
             TerrainPatch.FromId(id)
         }, null, writeHorizons: false);
         if (gpuProcessor.BoundingBox.HasValue)
         {
             rectangles.Add(gpuProcessor.BoundingBox.Value);
         }
     }
     callback(rectangles);
 });
Example #7
0
 public TerrainPatch GetPatch(Point id)
 {
     lock (this)
     {
         if (_patches.TryGetValue(id, out TerrainPatch patch))
         {
             return(patch);
         }
         patch = TerrainPatch.FromId(id);
         var horizons_path = patch.DefaultPath;
         if (!System.IO.File.Exists(horizons_path))
         {
             return(null);
         }
         patch.Read(horizons_path);
         patch.FillMatrices(LunarHorizon.Terrain);
         _patches.Add(id, patch);
         return(patch);
     }
 }
 public TerrainPatch GetPatch(Point id, int observer = 0)
 {
     lock (this)
     {
         if (_patches.TryGetValue((id.X, id.Y, observer), out TerrainPatch patch))
         {
             return(patch);
         }
         patch = TerrainPatch.FromId(id);
         var horizons_path = patch.Path;
         if (!File.Exists(horizons_path))
         {
             return(null);
         }
         patch.Read(horizons_path);
         patch.FillMatrices(ViperEnvironment.Terrain);
         _patches.Add((id.X, id.Y, observer), patch);
         return(patch);
     }
 }
        TerrainPatch GetPatchWithHorizons(Point id, int observer_height)
        {
            var patch = TerrainPatch.FromId(id, observer_height);

            if (File.Exists(patch.Path))
            {
                patch.Load();
                return(patch);
            }
            lock (this)
            {
                var gpuProcessor = ViperEnvironment.Processor as GPUHorizons;
                var queue        = new List <TerrainPatch>()
                {
                    patch
                };
                gpuProcessor.RunQueue(queue, writeHorizons: WriteHorizons, unloadHorizons: false);
                return(patch);
            }
        }
        public override void OnMouseDown(Object sender, MouseEventArgs e)
        {
            var map = sender as MapView;

            if (map == null)
            {
                return;
            }
            var maploc = map.Transform.MouseToMap(e.Location);
            var x      = (int)(map.Transform.MouseToMapX(e.X) / TerrainPatch.DefaultSize);
            var y      = (int)(map.Transform.MouseToMapY(e.Y) / TerrainPatch.DefaultSize);
            var id     = new Point(x, y);
            var patch  = TerrainPatch.FromId(id);

            map.ProcessingPatches = new List <TerrainPatch> {
                patch
            };
            var surrounding = patch.SurroundingPatches(1).Concat(patch.SurroundingPatches(3)).ToList();

            map.SelectedPatches = surrounding;
            map.Invalidate();
        }
        // Cache by id
        private bool HorizonsHaveBeenCalculated(ConsolidatedLine consolidated)
        {
            var pixel = consolidated.Pixel;
            var id    = TerrainPatch.LineSampleToId(pixel.Y, pixel.X);

            lock (_precache)
            {
                if (_precache.TryGetValue(id, out bool hasHorizons))
                {
                    return(hasHorizons);
                }
                var patch         = TerrainPatch.FromId(id);
                var horizons_path = patch.Path;
                var result        = File.Exists(horizons_path);
                if (result)
                {
                    _cache.Add(id, patch);
                }
                _precache.Add(id, result);
                return(result);
            }
        }
        public void GenerateRiseHeight(string path, Rectangle region)
        {
            var queue = TerrainPatch.EnumerateIds(TerrainPatch.CoveringIdRectangle(region)).Select(id => TerrainPatch.FromId(id)).ToList();
            var pairs = GenerateRiseHeightPatches(queue);
            var ary   = new float[region.Height, region.Width];

            var region_width  = region.Width;
            var region_height = region.Height;

            foreach (var(patch, data) in pairs)
            {
                var xoffset = patch.Sample - region.Left;
                var yoffset = patch.Line - region.Top;
                for (var row_src = 0; row_src < TerrainPatch.DefaultSize; row_src++)
                {
                    var row_dst = row_src + yoffset;
                    if (row_dst >= region_height || row_dst < 0)
                    {
                        continue;
                    }
                    for (var col_src = 0; col_src < TerrainPatch.DefaultSize; col_src++)
                    {
                        var col_dst = col_src + xoffset;
                        if (col_dst >= region_width || col_dst < 0)
                        {
                            continue;                                          // This can be faster if I don't clip per pixel.  Later.
                        }
                        ary[row_dst, col_dst] = data[row_src * TerrainPatch.DefaultSize + col_src];
                    }
                }
            }

            GeotiffHelper.WriteArrayAsGeotiff(ary, region, path);
        }
        public override void RunQueue(List <TerrainPatch> queue, Action <List <TerrainPatch> > queue_saver = null, int spread = -1, bool overHorizonCheck = true, bool centerOnly = false, bool center = true, bool unloadHorizons = true, bool writeHorizons = true)
        {
            var stopwatch2 = new Stopwatch();

            stopwatch2.Start();
            LunarHorizon.Singleton?.SetStatus(true);
            Debug.Assert(Terrain != null);
            centerOnly |= NearHorizonsOnly;
            if (queue == null)
            {
                queue = ReadShadowCalculationQueue();
            }
            var initial_count = queue.Count;

            if (spread < 0)
            {
                spread = MaxSpread;
            }

            var patchDictionary = new Dictionary <Point, TerrainPatch>();

            BoundingBox = null;

            while (queue.Count > 0)
            {
                var patch = queue[0];
                Console.WriteLine($"Starting [{patch.Line},{patch.Sample}] ...");
                try
                {
                    var stopwatch = new Stopwatch();
                    stopwatch.Start();

                    var far_field = new List <TerrainPatch>();
                    if (MapView != null)
                    {
                        MapView.ProcessingPatches = new List <TerrainPatch> {
                            patch
                        }
                    }
                    ;

                    // GPU version.  Horizons will be slope, not angles
                    if (center)
                    {
                        AddNearHorizon(patch);
                    }

                    Console.WriteLine($"  near horizon calculated or loaded in {stopwatch.Elapsed}");

                    patch.Matrices = null;      // Force the matrices to be regenerated so they're not left over from the near horizon
                    patch.FillPoints(Terrain);  // Should be a no op
                    patch.FillMatricesRelativeToPoint(Terrain, patch.Points[0][0]);

                    if (true)
                    {
                        var options = new ParallelOptions {
                            MaxDegreeOfParallelism = MaxDegreeOfParallelism
                        };
                        for (var i = 1; i < spread; i++)
                        {
                            // Fetch the surrounding patches from a cache
                            var other1 = patch.SurroundingIds(i).Select(id =>
                            {
                                if (patchDictionary.TryGetValue(id, out TerrainPatch r))
                                {
                                    return(r);
                                }
                                r = TerrainPatch.FromId(id);
                                patchDictionary.Add(id, r);
                                return(r);
                            }).ToList();
                            Parallel.ForEach(other1, options, o => o.FillPoints(Terrain));
                            var other2 = overHorizonCheck ? other1.Where(o => patch.IsOverHorizon(o, patch.Points[0][0])).ToList() : other1;
                            if (MapView != null)
                            {
                                far_field.AddRange(other2);
                                MapView.FarPatches = far_field;
                                MapView.Invalidate();
                            }

                            foreach (var p in other2)
                            {
                                var r = new Rectangle(p.Id, new Size(1, 1));
                                if (BoundingBox.HasValue)
                                {
                                    BoundingBox = Rectangle.Union(BoundingBox.Value, r);
                                }
                                else
                                {
                                    BoundingBox = r;
                                }
                            }

                            if (patch.Horizons == null)
                            {
                                patch.InitializeHorizons();
                            }

                            // Old code - Parallel.ForEach(other2, options, o => patch.UpdateHorizon(o));

                            // Here is the GPU Call
                            UpdateHorizons(patch, other2);
                        }
                    }
                    if (writeHorizons)
                    {
                        patch.Write();               // This converts the horizon format to angles
                    }
                    if (unloadHorizons)
                    {
                        patch.InitializeHorizons();  // Unload the horizon data (100MB)
                    }
                    stopwatch.Stop();
                    var seconds_per_patch = far_field.Count == 0 ? 0f : (stopwatch.ElapsedMilliseconds / 1000f) / far_field.Count;
                    Console.WriteLine($"  Finished [{patch.Line},{patch.Sample}] time={stopwatch.Elapsed}.  sec/patch={seconds_per_patch}");

                    // Update queue on disk
                    queue.RemoveAt(0);
                    queue_saver?.Invoke(queue);
                }
                catch (Exception e1)
                {
                    Console.WriteLine(e1);
                    Console.WriteLine(e1.StackTrace);
                }
                Console.WriteLine(@"Finished queue with GPU.");
                LunarHorizon.Singleton?.SetStatus(false);
            }
            Console.WriteLine($"Finished queue.  time={stopwatch2.Elapsed}.");
        }
        public void WriteSafeHavenGeotiffs(string path)
        {
            var outer_start = Start.AddDays(-28);
            var outer_stop  = Stop.AddDays(28);

            GetLowEarthTimes(outer_start, outer_stop, out List <DateTime> times_start_to_stop, out List <int> indices_of_minima_earth_elevation);

            for (var i = 0; i < indices_of_minima_earth_elevation.Count; i++)
            {
                Console.WriteLine($"i={i} index={indices_of_minima_earth_elevation[i]} time={times_start_to_stop[indices_of_minima_earth_elevation[i]]}");
            }
            var region_width  = Region.Width;
            var region_height = Region.Height;

            var combined     = new float[region_height, region_width];
            var month_images = Enumerable.Range(0, indices_of_minima_earth_elevation.Count).Select(i => new float[region_height, region_width]).ToList();

            var sun_vectors   = times_start_to_stop.Select(time => CSpice.SunPosition(time)).ToList();
            var earth_vectors = times_start_to_stop.Select(time => CSpice.EarthPosition(time)).ToList();

            // Get the indexes in the time and vector arrays of Start and Stop
            var first_inside = times_start_to_stop.Select((time, index) => (time, index)).Where(pair => pair.time >= Start).Select(pair => pair.index).First();
            var last_inside  = -1;

            for (var i = times_start_to_stop.Count - 1; i >= 0; i--)
            {
                if (times_start_to_stop[i] <= Stop)
                {
                    last_inside = i;
                    break;
                }
            }

            //var debugpt = new Point(Region.Left + 545, Region.Top + 490);
            //debugpt = new Point(Region.Left + 494, Region.Top + 438);
            var ids = TerrainPatch.EnumerateIds(TerrainPatch.CoveringIdRectangle(Region)).ToList();

            {
                var not_generated = ids.Where(id => !File.Exists(TerrainPatch.FromId(id, ObserverHeightInMeters).Path)).ToList();
                Console.WriteLine($"{not_generated.Count} patches haven't been generated yet.  Generating them.");
                var gpuProcessor = ViperEnvironment.Processor as CPUHorizons;
                var queue        = not_generated.Select(id => TerrainPatch.FromId(id)).ToList();
                gpuProcessor.RunQueue(queue, writeHorizons: WriteHorizons, unloadHorizons: true);
            }

            Parallel.ForEach(ids,
                             new ParallelOptions {
                MaxDegreeOfParallelism = ViperEnvironment.MaxDegreeOfParallelism
            },
                             id =>
            {
                var patch = GetPatchWithHorizons(id, ObserverHeightInMeters);
                for (var row = 0; row < TerrainPatch.DefaultSize; row++)
                {
                    var region_row = (patch.Line + row) - Region.Y;
                    if (region_row < 0 || region_row >= region_height)
                    {
                        continue;
                    }
                    for (var col = 0; col < TerrainPatch.DefaultSize; col++)
                    {
                        //if ((patch.Line + row) != debugpt.Y || (patch.Sample + col) != debugpt.X)
                        //    continue;
                        var region_col = patch.Sample + col - Region.X;
                        if (region_col < 0 || region_col >= region_width)
                        {
                            continue;
                        }
                        var has_sun     = patch.GetLightCurve(row, col, sun_vectors).Select(sun => sun >= SafeHavenSunThreshold).ToList();
                        var has_comm    = patch.GetEarthOverHorizonCurve(row, col, earth_vectors).Select(rise => rise >= EarthMultipathThreshold).ToList();
                        var month_steps = MaxShadowWithoutComm2(indices_of_minima_earth_elevation, has_sun, has_comm);
                        combined[region_row, region_col] = 2f * month_steps.Max();
                        for (var i = 0; i < month_steps.Count; i++)
                        {
                            month_images[i][region_row, region_col] = 2f * month_steps[i];
                        }
                    }
                }
            });

            {
                var path_combined = LandingSiteDataset.AppendToFilename(path, "_combined");
                GeotiffHelper.WriteArrayAsGeotiff(combined, Region, path_combined);
                WriteSafeHavenOverlay(combined, path_combined);
            }

            for (var i = 0; i < month_images.Count; i++)
            {
                var time  = times_start_to_stop[indices_of_minima_earth_elevation[i]];
                var path1 = LandingSiteDataset.AppendToFilename(path, "_" + time.ToString("yyyy-MM-dd"));
                GeotiffHelper.WriteArrayAsGeotiff(month_images[i], Region, path1);
                WriteSafeHavenOverlay(month_images[i], path1);
            }
        }