예제 #1
0
        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);
        }
예제 #2
0
        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();
                }
            }
        }
예제 #3
0
        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();
        }