diff --git a/ExtLibs/GMap.NET.WindowsForms/GMap.NET.WindowsForms/TilePrefetcher.cs b/ExtLibs/GMap.NET.WindowsForms/GMap.NET.WindowsForms/TilePrefetcher.cs
index 2c490e5074..576a863e92 100644
--- a/ExtLibs/GMap.NET.WindowsForms/GMap.NET.WindowsForms/TilePrefetcher.cs
+++ b/ExtLibs/GMap.NET.WindowsForms/GMap.NET.WindowsForms/TilePrefetcher.cs
@@ -1,383 +1,380 @@
-
-namespace GMap.NET
-{
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Windows.Forms;
- using GMap.NET.Internals;
- using System;
- using GMap.NET.MapProviders;
- using System.Threading;
- using GMap.NET.WindowsForms;
- using GMap.NET.WindowsForms.Markers;
- using System.Drawing;
- using System.Threading.Tasks;
-
- ///
- /// form helping to prefetch tiles on local db
- ///
- public partial class TilePrefetcher : Form
- {
- BackgroundWorker worker = new BackgroundWorker();
- List list;
- int zoom;
- GMapProvider provider;
- int sleep;
- int all;
- public bool ShowCompleteMessage = false;
- RectLatLng area;
- GMap.NET.GSize maxOfTiles;
- public GMapOverlay Overlay;
- int retry;
- public bool Shuffle = true;
-
- public TilePrefetcher()
- {
- InitializeComponent();
-
- GMaps.Instance.OnTileCacheComplete += new TileCacheComplete(OnTileCacheComplete);
- GMaps.Instance.OnTileCacheStart += new TileCacheStart(OnTileCacheStart);
- GMaps.Instance.OnTileCacheProgress += new TileCacheProgress(OnTileCacheProgress);
-
- worker.WorkerReportsProgress = true;
- worker.WorkerSupportsCancellation = true;
- worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
- worker.DoWork += new DoWorkEventHandler(worker_DoWork);
- worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
-
- UserAborted = false;
- }
-
- readonly AutoResetEvent done = new AutoResetEvent(true);
-
- void OnTileCacheComplete()
- {
- if(!IsDisposed)
- {
- done.Set();
-
- MethodInvoker m = delegate
- {
- label2.Text = "all tiles saved";
- };
- try
- {
- Invoke(m);
- }
- catch
- {
- }
- }
- }
-
- void OnTileCacheStart()
- {
- if(!IsDisposed)
- {
- done.Reset();
-
- MethodInvoker m = delegate
- {
- label2.Text = "saving tiles...";
- };
- try
- {
- Invoke(m);
- }
- catch
- {
- }
- }
- }
-
- void OnTileCacheProgress(int left)
- {
- if(!IsDisposed)
- {
- MethodInvoker m = delegate
- {
- label2.Text = left + " tile to save...";
- };
- try
- {
- Invoke(m);
- }
- catch
- {
- }
- }
- }
-
- public void Start(RectLatLng area, int zoom, GMapProvider provider, int sleep, int retry)
- {
- if(!worker.IsBusy)
- {
- this.label1.Text = "...";
- this.progressBarDownload.Value = 0;
-
- this.area = area;
- this.zoom = zoom;
- this.provider = provider;
- this.sleep = sleep;
- this.retry = retry;
-
- GMaps.Instance.UseMemoryCache = false;
- GMaps.Instance.CacheOnIdleRead = false;
- GMaps.Instance.BoostCacheEngine = true;
-
- if (Overlay != null)
- {
- Overlay.Markers.Clear();
- }
-
- worker.RunWorkerAsync();
-
- this.ShowDialog();
- }
- }
-
- public void Stop()
- {
- GMaps.Instance.OnTileCacheComplete -= new TileCacheComplete(OnTileCacheComplete);
- GMaps.Instance.OnTileCacheStart -= new TileCacheStart(OnTileCacheStart);
- GMaps.Instance.OnTileCacheProgress -= new TileCacheProgress(OnTileCacheProgress);
-
- done.Set();
-
- if(worker.IsBusy)
- {
- worker.CancelAsync();
- }
-
- GMaps.Instance.CancelTileCaching();
-
- done.Close();
- }
-
- public bool UserAborted{get;private set;}
-
- void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
- {
- if(ShowCompleteMessage)
- {
- if(!e.Cancelled)
- {
- MessageBox.Show(this, "Prefetch Complete! => " + ((int)e.Result).ToString() + " of " + all);
- }
- else
- {
- MessageBox.Show(this, "Prefetch Canceled! => " + ((int)e.Result).ToString() + " of " + all);
- }
- }
-
- list.Clear();
-
- GMaps.Instance.UseMemoryCache = true;
- GMaps.Instance.CacheOnIdleRead = true;
- GMaps.Instance.BoostCacheEngine = false;
-
- worker.Dispose();
-
- this.Close();
- }
-
- bool CacheTiles(int zoom, GPoint p)
- {
- foreach(var pr in provider.Overlays)
- {
- Exception ex;
- 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);
- }
-
- if(img != null)
- {
- img.Dispose();
- img = null;
- }
- else
- {
- return false;
- }
- }
- return true;
- }
-
- public readonly Queue CachedTiles = new Queue();
-
- void worker_DoWork(object sender, DoWorkEventArgs e)
- {
- while (!IsHandleCreated)
- Thread.Sleep(100);
-
- if(list != null)
- {
- list.Clear();
- list = null;
- }
- list = provider.Projection.GetAreaTileList(area, zoom, 0);
- maxOfTiles = provider.Projection.GetTileMatrixMaxXY(zoom);
- all = list.Count;
-
- int countOk = 0;
- int retryCount = 0;
- int count = 0;
-
- if(Shuffle)
- {
- Stuff.Shuffle(list);
- }
-
- lock(this)
- {
- CachedTiles.Clear();
- }
-
- Parallel.For(0, all, (i, state)=>
- {
- if(worker.CancellationPending)
- state.Break();
-
- GPoint p = list[i];
- {
- if(CacheTiles(zoom, p))
- {
- if (Overlay != null)
- {
- lock (this)
- {
- CachedTiles.Enqueue(p);
- }
- }
- countOk++;
- retryCount = 0;
- }
- else
- {
- if(++retryCount <= retry) // retry only one
- {
- i--;
- System.Threading.Thread.Sleep(1111);
- return;
- }
- else
- {
- retryCount = 0;
- }
- }
- }
- count++;
- worker.ReportProgress((int)((count + 1) * 100 / all), count + 1);
-
- if (sleep > 0)
- {
- System.Threading.Thread.Sleep(sleep);
- }
- });
-
- e.Result = countOk;
-
- if(!IsDisposed)
- {
- try
- {
- done.WaitOne();
- }
- catch { }
- }
- }
-
- 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() + "%";
- int percent = Math.Max(0, Math.Min(100, e.ProgressPercentage));
- this.progressBarDownload.Value = percent;
-
- if (Overlay != null)
- {
- GPoint? l = null;
-
- lock (this)
- {
- if (CachedTiles.Count > 0)
- {
- l = CachedTiles.Dequeue();
- }
- }
-
- if (l.HasValue)
- {
- var px = Overlay.Control.MapProvider.Projection.FromTileXYToPixel(l.Value);
- var p = Overlay.Control.MapProvider.Projection.FromPixelToLatLng(px, zoom);
-
- var r1 = Overlay.Control.MapProvider.Projection.GetGroundResolution(zoom, p.Lat);
- var r2 = Overlay.Control.MapProvider.Projection.GetGroundResolution((int)Overlay.Control.Zoom, p.Lat);
- var sizeDiff = r2 / r1;
-
- GMapMarkerTile m = new GMapMarkerTile(p, (int)(Overlay.Control.MapProvider.Projection.TileSize.Width / sizeDiff));
- Overlay.Markers.Add(m);
- }
- }
- }
- catch (Exception)
- {
- }
- }
-
- private void Prefetch_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
- {
- if (e.KeyCode == Keys.Escape)
- ConfirmUserAbort();
- }
-
- private void Prefetch_FormClosed(object sender, FormClosedEventArgs e)
- {
- this.Stop();
- }
-
- private void buttonCancel_Click(object sender, EventArgs e)
- {
- ConfirmUserAbort();
- }
-
- private void ConfirmUserAbort()
- {
- if (MessageBox.Show("Are you sure you want to abort the pre-fetch process?", "Confirm Abort", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == System.Windows.Forms.DialogResult.Yes)
- {
- UserAborted = true;
- this.Close();
- }
- }
- }
-
- class GMapMarkerTile : GMapMarker
- {
- static Brush Fill = new SolidBrush(Color.FromArgb(155, Color.Blue));
-
- public GMapMarkerTile(PointLatLng p, int size) : base(p)
- {
- Size = new System.Drawing.Size(size, size);
- }
-
- public override void OnRender(IGraphics g)
- {
- g.FillRectangle(Fill, new System.Drawing.Rectangle(LocalPosition.X, LocalPosition.Y, Size.Width, Size.Height));
- }
- }
-}
+
+namespace GMap.NET
+{
+ using System.Collections.Generic;
+ using System.ComponentModel;
+ using System.Windows.Forms;
+ using GMap.NET.Internals;
+ using System;
+ using GMap.NET.MapProviders;
+ using System.Threading;
+ using GMap.NET.WindowsForms;
+ using System.Drawing;
+
+ ///
+ /// form helping to prefetch tiles on local db
+ ///
+ public partial class TilePrefetcher : Form
+ {
+ BackgroundWorker worker = new BackgroundWorker();
+ List list;
+ int zoom;
+ GMapProvider provider;
+ int sleep;
+ int all;
+ public bool ShowCompleteMessage = false;
+ RectLatLng area;
+ GMap.NET.GSize maxOfTiles;
+ public GMapOverlay Overlay;
+ int retry;
+ public bool Shuffle = true;
+
+ public TilePrefetcher()
+ {
+ InitializeComponent();
+
+ GMaps.Instance.OnTileCacheComplete += new TileCacheComplete(OnTileCacheComplete);
+ GMaps.Instance.OnTileCacheStart += new TileCacheStart(OnTileCacheStart);
+ GMaps.Instance.OnTileCacheProgress += new TileCacheProgress(OnTileCacheProgress);
+
+ worker.WorkerReportsProgress = true;
+ worker.WorkerSupportsCancellation = true;
+ worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
+ worker.DoWork += new DoWorkEventHandler(worker_DoWork);
+ worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
+
+ UserAborted = false;
+ }
+
+ readonly AutoResetEvent done = new AutoResetEvent(true);
+
+ void OnTileCacheComplete()
+ {
+ if(!IsDisposed)
+ {
+ done.Set();
+
+ MethodInvoker m = delegate
+ {
+ label2.Text = "all tiles saved";
+ };
+ try
+ {
+ Invoke(m);
+ }
+ catch
+ {
+ }
+ }
+ }
+
+ void OnTileCacheStart()
+ {
+ if(!IsDisposed)
+ {
+ done.Reset();
+
+ MethodInvoker m = delegate
+ {
+ label2.Text = "saving tiles...";
+ };
+ try
+ {
+ Invoke(m);
+ }
+ catch
+ {
+ }
+ }
+ }
+
+ void OnTileCacheProgress(int left)
+ {
+ if(!IsDisposed)
+ {
+ MethodInvoker m = delegate
+ {
+ label2.Text = left + " tile to save...";
+ };
+ try
+ {
+ Invoke(m);
+ }
+ catch
+ {
+ }
+ }
+ }
+
+ public void Start(RectLatLng area, int zoom, GMapProvider provider, int sleep, int retry)
+ {
+ if(!worker.IsBusy)
+ {
+ this.label1.Text = "...";
+ this.progressBarDownload.Value = 0;
+
+ this.area = area;
+ this.zoom = zoom;
+ this.provider = provider;
+ this.sleep = sleep;
+ this.retry = retry;
+
+ GMaps.Instance.UseMemoryCache = false;
+ GMaps.Instance.CacheOnIdleRead = false;
+ GMaps.Instance.BoostCacheEngine = true;
+
+ if (Overlay != null)
+ {
+ Overlay.Markers.Clear();
+ }
+
+ worker.RunWorkerAsync();
+
+ this.ShowDialog();
+ }
+ }
+
+ public void Stop()
+ {
+ GMaps.Instance.OnTileCacheComplete -= new TileCacheComplete(OnTileCacheComplete);
+ GMaps.Instance.OnTileCacheStart -= new TileCacheStart(OnTileCacheStart);
+ GMaps.Instance.OnTileCacheProgress -= new TileCacheProgress(OnTileCacheProgress);
+
+ done.Set();
+
+ if(worker.IsBusy)
+ {
+ worker.CancelAsync();
+ }
+
+ GMaps.Instance.CancelTileCaching();
+
+ done.Close();
+ }
+
+ public bool UserAborted{get;private set;}
+
+ void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
+ {
+ if(ShowCompleteMessage)
+ {
+ if(!e.Cancelled)
+ {
+ MessageBox.Show(this, "Prefetch Complete! => " + ((int)e.Result).ToString() + " of " + all);
+ }
+ else
+ {
+ MessageBox.Show(this, "Prefetch Canceled! => " + ((int)e.Result).ToString() + " of " + all);
+ }
+ }
+
+ list.Clear();
+
+ GMaps.Instance.UseMemoryCache = true;
+ GMaps.Instance.CacheOnIdleRead = true;
+ GMaps.Instance.BoostCacheEngine = false;
+
+ worker.Dispose();
+
+ this.Close();
+ }
+
+ bool CacheTiles(int zoom, GPoint p)
+ {
+ foreach(var pr in provider.Overlays)
+ {
+ Exception ex;
+ 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);
+ }
+
+ if(img != null)
+ {
+ img.Dispose();
+ img = null;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public readonly Queue CachedTiles = new Queue();
+
+ void worker_DoWork(object sender, DoWorkEventArgs e)
+ {
+ while (!IsHandleCreated)
+ Thread.Sleep(100);
+
+ if(list != null)
+ {
+ list.Clear();
+ list = null;
+ }
+ list = provider.Projection.GetAreaTileList(area, zoom, 0);
+ maxOfTiles = provider.Projection.GetTileMatrixMaxXY(zoom);
+ all = list.Count;
+
+ int countOk = 0;
+ int retryCount = 0;
+ int count = 0;
+
+ if(Shuffle)
+ {
+ Stuff.Shuffle(list);
+ }
+
+ lock(this)
+ {
+ CachedTiles.Clear();
+ }
+
+ for (int i = 0; i < all; i++)
+ {
+ if(worker.CancellationPending)
+ break;
+
+ GPoint p = list[i];
+ {
+ if(CacheTiles(zoom, p))
+ {
+ if (Overlay != null)
+ {
+ lock (this)
+ {
+ CachedTiles.Enqueue(p);
+ }
+ }
+ countOk++;
+ retryCount = 0;
+ }
+ else
+ {
+ if(++retryCount <= retry) // retry only one
+ {
+ i--;
+ System.Threading.Thread.Sleep(1111);
+ continue;
+ }
+ else
+ {
+ retryCount = 0;
+ }
+ }
+ }
+ worker.ReportProgress((int)((i + 1) * 100 / all), i + 1);
+
+ if (sleep > 0)
+ {
+ System.Threading.Thread.Sleep(sleep);
+ }
+ }
+
+ e.Result = countOk;
+
+ if(!IsDisposed)
+ {
+ try
+ {
+ done.WaitOne();
+ }
+ catch { }
+ }
+ }
+
+ 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() + "%";
+ int percent = Math.Max(0, Math.Min(100, e.ProgressPercentage));
+ this.progressBarDownload.Value = percent;
+
+ if (Overlay != null)
+ {
+ GPoint? l = null;
+
+ lock (this)
+ {
+ if (CachedTiles.Count > 0)
+ {
+ l = CachedTiles.Dequeue();
+ }
+ }
+
+ if (l.HasValue)
+ {
+ var px = Overlay.Control.MapProvider.Projection.FromTileXYToPixel(l.Value);
+ var p = Overlay.Control.MapProvider.Projection.FromPixelToLatLng(px, zoom);
+
+ var r1 = Overlay.Control.MapProvider.Projection.GetGroundResolution(zoom, p.Lat);
+ var r2 = Overlay.Control.MapProvider.Projection.GetGroundResolution((int)Overlay.Control.Zoom, p.Lat);
+ var sizeDiff = r2 / r1;
+
+ GMapMarkerTile m = new GMapMarkerTile(p, (int)(Overlay.Control.MapProvider.Projection.TileSize.Width / sizeDiff));
+ Overlay.Markers.Add(m);
+ }
+ }
+ }
+ catch (Exception)
+ {
+ }
+ }
+
+ private void Prefetch_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
+ {
+ if (e.KeyCode == Keys.Escape)
+ ConfirmUserAbort();
+ }
+
+ private void Prefetch_FormClosed(object sender, FormClosedEventArgs e)
+ {
+ this.Stop();
+ }
+
+ private void buttonCancel_Click(object sender, EventArgs e)
+ {
+ ConfirmUserAbort();
+ }
+
+ private void ConfirmUserAbort()
+ {
+ if (MessageBox.Show("Are you sure you want to abort the pre-fetch process?", "Confirm Abort", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == System.Windows.Forms.DialogResult.Yes)
+ {
+ UserAborted = true;
+ this.Close();
+ }
+ }
+ }
+
+ class GMapMarkerTile : GMapMarker
+ {
+ static Brush Fill = new SolidBrush(Color.FromArgb(155, Color.Blue));
+
+ public GMapMarkerTile(PointLatLng p, int size) : base(p)
+ {
+ Size = new System.Drawing.Size(size, size);
+ }
+
+ public override void OnRender(IGraphics g)
+ {
+ g.FillRectangle(Fill, new System.Drawing.Rectangle(LocalPosition.X, LocalPosition.Y, Size.Width, Size.Height));
+ }
+ }
+}