From 982232df2f2547d9c35973d7f21f5320b4c9004b Mon Sep 17 00:00:00 2001 From: Geoffroy Arenou Date: Mon, 10 Jun 2024 16:29:46 +0200 Subject: [PATCH] FlightPlanner : When prefetching, do not download tile if file already exist Add minZoom input in prefetch (like maxZoom) Use Parallel.For instead of For to get tiles faster ! --- ExtLibs/GMap.NET.Core/GMap.NET/GMaps.cs | 25 +++++++++++++++ .../GMap.NET.Core/GMap.NET/PureImageCache.cs | 9 ++++++ .../GMap.NET.WindowsForms/TilePrefetcher.cs | 31 ++++++++++++++----- ExtLibs/Maps/MyImageCache.cs | 31 +++++++++++++++++++ GCSViews/FlightPlanner.cs | 27 +++++++++++++++- 5 files changed, 114 insertions(+), 9 deletions(-) diff --git a/ExtLibs/GMap.NET.Core/GMap.NET/GMaps.cs b/ExtLibs/GMap.NET.Core/GMap.NET/GMaps.cs index 86f179612c..c349e635a2 100644 --- a/ExtLibs/GMap.NET.Core/GMap.NET/GMaps.cs +++ b/ExtLibs/GMap.NET.Core/GMap.NET/GMaps.cs @@ -817,6 +817,31 @@ public PureImage GetImageFrom(GMapProvider provider, GPoint pos, int zoom, out E readonly Exception noDataException = new Exception("No data in local tile cache..."); + public bool CheckImageExist(GMapProvider provider, GPoint pos, int zoom, out Exception result) + { + result = null; + try + { + if (Mode != AccessMode.ServerOnly && !provider.BypassCache) + { + if (PrimaryCache != null) + { + return PrimaryCache.CheckImageFromCache(provider.DbId, pos, zoom); + } + + if (SecondaryCache != null) + { + return SecondaryCache.CheckImageFromCache(provider.DbId, pos, zoom); + } + } + } + catch (Exception ex) + { + Debug.WriteLine("CheckImageExist: " + ex.ToString()); + } + return false; + } + #if !PocketPC TileHttpHost host; diff --git a/ExtLibs/GMap.NET.Core/GMap.NET/PureImageCache.cs b/ExtLibs/GMap.NET.Core/GMap.NET/PureImageCache.cs index 540b5b3fe6..e84d8a7cf9 100644 --- a/ExtLibs/GMap.NET.Core/GMap.NET/PureImageCache.cs +++ b/ExtLibs/GMap.NET.Core/GMap.NET/PureImageCache.cs @@ -35,5 +35,14 @@ public interface PureImageCache /// provider dbid or null to use all providers /// The number of deleted tiles. int DeleteOlderThan(DateTime date, int ? type); + + /// + /// check if image exist on db + /// + /// + /// + /// + /// True if Image Exist, false otherwise + bool CheckImageFromCache(int type, GPoint pos, int zoom); } } diff --git a/ExtLibs/GMap.NET.WindowsForms/GMap.NET.WindowsForms/TilePrefetcher.cs b/ExtLibs/GMap.NET.WindowsForms/GMap.NET.WindowsForms/TilePrefetcher.cs index 9eefa5a169..2c490e5074 100644 --- a/ExtLibs/GMap.NET.WindowsForms/GMap.NET.WindowsForms/TilePrefetcher.cs +++ b/ExtLibs/GMap.NET.WindowsForms/GMap.NET.WindowsForms/TilePrefetcher.cs @@ -11,6 +11,7 @@ namespace GMap.NET using GMap.NET.WindowsForms; using GMap.NET.WindowsForms.Markers; using System.Drawing; + using System.Threading.Tasks; /// /// form helping to prefetch tiles on local db @@ -185,15 +186,21 @@ bool CacheTiles(int zoom, GPoint p) foreach(var pr in provider.Overlays) { Exception ex; - PureImage img; + PureImage img = null; // tile number inversion(BottomLeft -> TopLeft) if(pr.InvertedAxisY) { + if (GMaps.Instance.CheckImageExist(pr, new GPoint(p.X, maxOfTiles.Height - p.Y), zoom, out ex)) + return true; + else img = GMaps.Instance.GetImageFrom(pr, new GPoint(p.X, maxOfTiles.Height - p.Y), zoom, out ex); } else // ok { + if (GMaps.Instance.CheckImageExist(pr, p, zoom, out ex)) + return true; + else img = GMaps.Instance.GetImageFrom(pr, p, zoom, out ex); } @@ -228,6 +235,7 @@ void worker_DoWork(object sender, DoWorkEventArgs e) int countOk = 0; int retryCount = 0; + int count = 0; if(Shuffle) { @@ -239,10 +247,10 @@ void worker_DoWork(object sender, DoWorkEventArgs e) CachedTiles.Clear(); } - for(int i = 0; i < all; i++) + Parallel.For(0, all, (i, state)=> { if(worker.CancellationPending) - break; + state.Break(); GPoint p = list[i]; { @@ -264,7 +272,7 @@ void worker_DoWork(object sender, DoWorkEventArgs e) { i--; System.Threading.Thread.Sleep(1111); - continue; + return; } else { @@ -272,14 +280,14 @@ void worker_DoWork(object sender, DoWorkEventArgs e) } } } - - worker.ReportProgress((int)((i + 1) * 100 / all), i + 1); + count++; + worker.ReportProgress((int)((count + 1) * 100 / all), count + 1); if (sleep > 0) { System.Threading.Thread.Sleep(sleep); } - } + }); e.Result = countOk; @@ -295,8 +303,11 @@ void worker_DoWork(object sender, DoWorkEventArgs e) void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) { + try + { this.label1.Text = "Fetching tile at zoom (" + zoom + "): " + ((int)e.UserState).ToString() + " of " + all + ", complete: " + e.ProgressPercentage.ToString() + "%"; - this.progressBarDownload.Value = e.ProgressPercentage; + int percent = Math.Max(0, Math.Min(100, e.ProgressPercentage)); + this.progressBarDownload.Value = percent; if (Overlay != null) { @@ -324,6 +335,10 @@ void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) } } } + catch (Exception) + { + } + } private void Prefetch_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) { diff --git a/ExtLibs/Maps/MyImageCache.cs b/ExtLibs/Maps/MyImageCache.cs index 6049e41d59..5404ddec05 100644 --- a/ExtLibs/Maps/MyImageCache.cs +++ b/ExtLibs/Maps/MyImageCache.cs @@ -183,6 +183,37 @@ int PureImageCache.DeleteOlderThan(DateTime date, int? type) return affectedRows; } + public bool CheckImageFromCache(int type, GPoint pos, int zoom) + { + bool ret = false; + if (Created) + { + try + { + string file = CacheLocation + Path.DirectorySeparatorChar + GMapProviders.TryGetProvider(type).Name + + Path.DirectorySeparatorChar + zoom + Path.DirectorySeparatorChar + pos.Y + + Path.DirectorySeparatorChar + pos.X + ".jpg"; + if (File.Exists(file)) + { + ret = true; + } + else + { + ret = false; + } + } + catch (Exception ex) + { +#if MONO + Console.WriteLine("CheckImageFromCache: " + ex.ToString()); +#endif + Debug.WriteLine("CheckImageFromCache: " + ex.ToString()); + ret = false; + } + } + return ret; + } + #endregion } } \ No newline at end of file diff --git a/GCSViews/FlightPlanner.cs b/GCSViews/FlightPlanner.cs index 60f6c1898e..e81b4ce3b1 100644 --- a/GCSViews/FlightPlanner.cs +++ b/GCSViews/FlightPlanner.cs @@ -5016,7 +5016,28 @@ public void prefetchToolStripMenuItem_Click(object sender, EventArgs e) maxzoom = Math.Min(maxzoom, MainMap.MaxZoom); - for (int i = 1; i <= maxzoom; i++) + string minzoomstring = "1"; + if (InputBox.Show("min zoom", "Enter the min zoom to prefetch to.", ref minzoomstring) != + DialogResult.OK) + return; + + int minzoom = 20; + if (!int.TryParse(minzoomstring, out minzoom)) + { + CustomMessageBox.Show(Strings.InvalidNumberEntered, Strings.ERROR); + return; + } + minzoom = Math.Max(minzoom, MainMap.MinZoom); + + if (minzoom > maxzoom) + { + CustomMessageBox.Show(Strings.InvalidNumberEntered, Strings.ERROR); + return; + } + + for (int i = minzoom; i <= maxzoom; i++) + { + try { TilePrefetcher obj = new TilePrefetcher(); ThemeManager.ApplyThemeTo(obj); @@ -5031,6 +5052,10 @@ public void prefetchToolStripMenuItem_Click(object sender, EventArgs e) obj.Dispose(); } + catch + { + } + } } else {