void AddLoadTask(LoadTask t) { if (tileLoadQueue4Tasks == null) { lock (tileLoadQueue4) { if (tileLoadQueue4Tasks == null) { tileLoadQueue4Tasks = new List <Task>(); while (tileLoadQueue4Tasks.Count < GThreadPoolSize) { Debug.WriteLine("creating ProcessLoadTask: " + tileLoadQueue4Tasks.Count); tileLoadQueue4Tasks.Add(Task.Factory.StartNew(delegate() { string ctid = "ProcessLoadTask[" + Thread.CurrentThread.ManagedThreadId + "]"; Thread.CurrentThread.Name = ctid; Debug.WriteLine(ctid + ": started"); do { if (tileLoadQueue4.Count == 0) { Debug.WriteLine(ctid + ": ready"); if (Interlocked.Increment(ref loadWaitCount) >= GThreadPoolSize) { Interlocked.Exchange(ref loadWaitCount, 0); OnLoadComplete(ctid); } } ProcessLoadTask(tileLoadQueue4.Take(), ctid); }while (!tileLoadQueue4.IsAddingCompleted); Debug.WriteLine(ctid + ": exit"); }, TaskCreationOptions.LongRunning)); } } } } tileLoadQueue4.Add(t); }
static void ProcessLoadTask(LoadTask task, string ctid) { GPoint mousepos = task.Core.PositionPixel; //task.Core.Provider.Projection.FromLatLngToPixel(task.Core.newPoint, task.Core.Zoom);// GPoint corepos1 = new GPoint(mousepos.X / 256, mousepos.Y / 256); //6461,3361807,420 task.Core.corepos = corepos1; GPoint corepos2 = new GPoint(corepos1.X, corepos1.Y - 1); GPoint corepos3 = new GPoint(corepos1.X + 1, corepos1.Y - 1); GPoint corepos4 = new GPoint(corepos1.X + 1, corepos1.Y); try { #region -- execute -- var m = task.Core.Matrix.GetTileWithReadLock(task.Zoom, task.Pos); if (!m.NotEmpty) { Debug.WriteLine(ctid + " - try load: " + task); Tile t = new Tile(task.Zoom, task.Pos); foreach (var tl in task.Core.provider.Overlays) { int retry = 0; do { PureImage img = null; Exception ex = null; if (task.Zoom >= task.Core.provider.MinZoom && (!task.Core.provider.MaxZoom.HasValue || task.Zoom <= task.Core.provider.MaxZoom)) { if (task.Core.skipOverZoom == 0 || task.Zoom <= task.Core.skipOverZoom) { // tile number inversion(BottomLeft -> TopLeft) if (tl.InvertedAxisY) { img = GMaps.Instance.GetImageFrom(tl, new GPoint(task.Pos.X, task.Core.maxOfTiles.Height - task.Pos.Y), task.Zoom, corepos1, out ex); } else // ok { img = GMaps.Instance.GetImageFrom(tl, task.Pos, task.Zoom, corepos1, out ex); } } } if (img != null && ex == null) { if (task.Core.okZoom < task.Zoom) { task.Core.okZoom = task.Zoom; task.Core.skipOverZoom = 0; Debug.WriteLine("skipOverZoom disabled, okZoom: " + task.Core.okZoom); } } else if (ex != null) { if ((task.Core.skipOverZoom != task.Core.okZoom) && (task.Zoom > task.Core.okZoom)) { if (ex.Message.Contains("(404) Not Found")) { task.Core.skipOverZoom = task.Core.okZoom; Debug.WriteLine("skipOverZoom enabled: " + task.Core.skipOverZoom); } } } // check for parent tiles if not found if (img == null && task.Core.okZoom > 0 && task.Core.fillEmptyTiles && task.Core.Provider.Projection is MercatorProjection) { int zoomOffset = task.Zoom > task.Core.okZoom ? task.Zoom - task.Core.okZoom : 1; long Ix = 0; GPoint parentTile = GPoint.Empty; while (img == null && zoomOffset < task.Zoom) { Ix = (long)Math.Pow(2, zoomOffset); parentTile = new GPoint((task.Pos.X / Ix), (task.Pos.Y / Ix)); img = GMaps.Instance.GetImageFrom(tl, parentTile, task.Zoom - zoomOffset++, corepos1, out ex); } if (img != null) { // offsets in quadrant long Xoff = Math.Abs(task.Pos.X - (parentTile.X * Ix)); long Yoff = Math.Abs(task.Pos.Y - (parentTile.Y * Ix)); img.IsParent = true; img.Ix = Ix; img.Xoff = Xoff; img.Yoff = Yoff; // wpf //var geometry = new RectangleGeometry(new Rect(Core.tileRect.X + 0.6, Core.tileRect.Y + 0.6, Core.tileRect.Width + 0.6, Core.tileRect.Height + 0.6)); //var parentImgRect = new Rect(Core.tileRect.X - Core.tileRect.Width * Xoff + 0.6, Core.tileRect.Y - Core.tileRect.Height * Yoff + 0.6, Core.tileRect.Width * Ix + 0.6, Core.tileRect.Height * Ix + 0.6); // gdi+ //System.Drawing.Rectangle dst = new System.Drawing.Rectangle((int)Core.tileRect.X, (int)Core.tileRect.Y, (int)Core.tileRect.Width, (int)Core.tileRect.Height); //System.Drawing.RectangleF srcRect = new System.Drawing.RectangleF((float)(Xoff * (img.Img.Width / Ix)), (float)(Yoff * (img.Img.Height / Ix)), (img.Img.Width / Ix), (img.Img.Height / Ix)); } } if (img != null) { Debug.WriteLine(ctid + " - tile loaded: " + img.Data.Length / 1024 + "KB, " + task); { t.AddOverlay(img); } break; } else { if (ex != null) { lock (task.Core.FailedLoads) { if (!task.Core.FailedLoads.ContainsKey(task)) { task.Core.FailedLoads.Add(task, ex); if (task.Core.OnEmptyTileError != null) { if (!task.Core.RaiseEmptyTileError) { task.Core.RaiseEmptyTileError = true; task.Core.OnEmptyTileError(task.Zoom, task.Pos); } } } } } if (task.Core.RetryLoadTile > 0) { Debug.WriteLine(ctid + " - ProcessLoadTask: " + task + " -> empty tile, retry " + retry); { Thread.Sleep(1111); } } } }while (++retry < task.Core.RetryLoadTile); } if (t.HasAnyOverlays && task.Core.IsStarted) { task.Core.Matrix.SetTile(t); } else { t.Dispose(); } } #endregion } catch (Exception ex) { Debug.WriteLine(ctid + " - ProcessLoadTask: " + ex.ToString()); } finally { if (task.Core.Refresh != null) { task.Core.Refresh.Set(); } } }
public void UpdateBounds()//////////////////////////// { if (!IsStarted || Provider.Equals(EmptyProvider.Instance)) { return; } updatingBounds = true; tileDrawingListLock.AcquireWriterLock(); try { #region -- find tiles around -- tileDrawingList.Clear(); for (long i = (int)Math.Floor(-sizeOfMapArea.Width * scaleX), countI = (int)Math.Ceiling(sizeOfMapArea.Width * scaleX); i <= countI; i++) { for (long j = (int)Math.Floor(-sizeOfMapArea.Height * scaleY), countJ = (int)Math.Ceiling(sizeOfMapArea.Height * scaleY); j <= countJ; j++) { GPoint p = centerTileXYLocation; p.X += i; p.Y += j; if (p.X >= minOfTiles.Width && p.Y >= minOfTiles.Height && p.X <= maxOfTiles.Width && p.Y <= maxOfTiles.Height) { DrawTile dt = new DrawTile() { PosXY = p, PosPixel = new GPoint(p.X * tileRect.Width, p.Y * tileRect.Height), DistanceSqr = (centerTileXYLocation.X - p.X) * (centerTileXYLocation.X - p.X) + (centerTileXYLocation.Y - p.Y) * (centerTileXYLocation.Y - p.Y) }; if (!tileDrawingList.Contains(dt)) { tileDrawingList.Add(dt); } } } } if (GMaps.Instance.ShuffleTilesOnLoad) { Stuff.Shuffle <DrawTile>(tileDrawingList); } else { tileDrawingList.Sort(); } #endregion } finally { tileDrawingListLock.ReleaseWriterLock(); } Interlocked.Exchange(ref loadWaitCount, 0); tileDrawingListLock.AcquireReaderLock(); try { foreach (DrawTile p in tileDrawingList) { LoadTask task = new LoadTask(p.PosXY, Zoom, this); AddLoadTask(task); } } finally { tileDrawingListLock.ReleaseReaderLock(); } { LastTileLoadStart = DateTime.Now; Debug.WriteLine("OnTileLoadStart - at zoom " + Zoom + ", time: " + LastTileLoadStart.TimeOfDay); } updatingBounds = false; OnTileLoadStart?.Invoke(); }