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."); }
public TerrainPatch ToTerrainPatch() { var tp = TerrainPatch.FromId(Id); tp.Step = Step; return(tp); }
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); }
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."); }
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); });
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); } }