Beispiel #1
0
        /// <summary>
        /// enqueueens tile to cache
        /// </summary>
        /// <param name="task"></param>
        void EnqueueCacheTask(CacheQueueItem task)
        {
            lock (tileCacheQueue)
            {
                if (!tileCacheQueue.Contains(task))
                {
                    Debug.WriteLine("EnqueueCacheTask: " + task);

                    tileCacheQueue.Enqueue(task);

                    if (CacheEngine != null && CacheEngine.IsAlive)
                    {
                        WaitForCache.Set();
                    }
#if PocketPC
                    else if (CacheEngine == null || CacheEngine.State == ThreadState.Stopped || CacheEngine.State == ThreadState.Unstarted)
#else
                    else if (CacheEngine == null || CacheEngine.ThreadState == System.Threading.ThreadState.Stopped || CacheEngine.ThreadState == System.Threading.ThreadState.Unstarted)
#endif
                    {
                        CacheEngine = null;
                        CacheEngine = new Thread(new ThreadStart(CacheEngineLoop))
                        {
                            Name         = "CacheEngine",
                            IsBackground = false,
                            Priority     = ThreadPriority.Lowest
                        };

                        abortCacheLoop = false;
                        CacheEngine.Start();
                    }
                }
            }
        }
Beispiel #2
0
 /// <summary>
 /// Creates our event thread that will receive native events
 /// </summary>
 private void CreateGpsEventThread()
 {
     // we only want to create the thread if we don't have one created already
     // and we have opened the gps device
     if (gpsEventThread == null && gpsHandle != IntPtr.Zero)
     {
         // Create and start thread to listen for GPS events
         gpsEventThread = new Thread(new System.Threading.ThreadStart(WaitForGpsEvents));
         gpsEventThread.IsBackground = false;
         gpsEventThread.Name         = "GMap.NET GpsEvents";
         gpsEventThread.Start();
     }
 }
Beispiel #3
0
        /// <summary>
        /// starts loader threads if needed
        /// </summary>
        void EnsureLoaderThreads()
        {
#if !PocketPC
            while (GThreadPool.Count < 5)
#else
            while (GThreadPool.Count < 2)
#endif
            {
                Thread t = new Thread(new ThreadStart(ProcessLoadTask));
                {
                    t.Name         = "GMap.NET TileLoader: " + GThreadPool.Count;
                    t.IsBackground = true;
                    t.Priority     = ThreadPriority.BelowNormal;
                }
                GThreadPool.Add(t);

                Debug.WriteLine("add " + t.Name + " to GThreadPool");

                t.Start();
            }
        }
Beispiel #4
0
 public Task ReloadMapAsync()
 {
     ReloadMap();
     return(Task.Factory.StartNew(() =>
     {
         bool wait;
         do
         {
             Thread.Sleep(100);
             Monitor.Enter(TileLoadQueue);
             try
             {
                 wait = TileLoadQueue.Any();
             }
             finally
             {
                 Monitor.Exit(TileLoadQueue);
             }
         } while (wait);
     }));
 }
Beispiel #5
0
        /// <summary>
        /// Closes the gps device.
        /// </summary>
        public void Close()
        {
            if (gpsHandle != IntPtr.Zero)
            {
                GPSCloseDevice(gpsHandle);
                gpsHandle = IntPtr.Zero;
            }

            // Set our native stop event so we can exit our event thread.
            if (stopHandle != IntPtr.Zero)
            {
                Win32.EventModify(stopHandle, (int)Win32.EventFlags.SET);
            }

            // wait exit
            if (gpsEventThread != null)
            {
                quit.WaitOne();
                gpsEventThread = null;
            }
        }
Beispiel #6
0
        /// <summary>
        /// updates map bounds
        /// </summary>
        void UpdateBounds()
        {
            if (MapType == NET.MapType.None)
            {
                return;
            }

            lock (tileLoadQueue)
            {
                tileDrawingListLock.AcquireWriterLock();
                try
                {
                    #region -- find tiles around --
                    tileDrawingList.Clear();

                    for (int i = -sizeOfMapArea.Width; i <= sizeOfMapArea.Width; i++)
                    {
                        for (int j = -sizeOfMapArea.Height; j <= sizeOfMapArea.Height; j++)
                        {
                            Point p = centerTileXYLocation;
                            p.X += i;
                            p.Y += j;

#if ContinuesMap
                            // ----------------------------
                            if (p.X < minOfTiles.Width)
                            {
                                p.X += (maxOfTiles.Width + 1);
                            }

                            if (p.X > maxOfTiles.Width)
                            {
                                p.X -= (maxOfTiles.Width + 1);
                            }
                            // ----------------------------
#endif

                            if (p.X >= minOfTiles.Width && p.Y >= minOfTiles.Height && p.X <= maxOfTiles.Width && p.Y <= maxOfTiles.Height)
                            {
                                if (!tileDrawingList.Contains(p))
                                {
                                    tileDrawingList.Add(p);
                                }
                            }
                        }
                    }

                    if (GMaps.Instance.ShuffleTilesOnLoad)
                    {
                        Stuff.Shuffle <Point>(tileDrawingList);
                    }
                    #endregion

                    foreach (Point p in tileDrawingList)
                    {
                        LoadTask task = new LoadTask(p, Zoom);
                        {
                            if (!tileLoadQueue.Contains(task))
                            {
                                tileLoadQueue.Enqueue(task);
                            }
                        }
                    }
                }
                finally
                {
                    tileDrawingListLock.ReleaseWriterLock();
                }

                #region -- starts loader threads if needed --
#if !PocketPC
                while (GThreadPool.Count < GThreadPoolSize)
#else
                while (GThreadPool.Count < GThreadPoolSize)
#endif
                {
                    Thread t = new Thread(new ThreadStart(ProcessLoadTask));
                    {
                        t.Name         = "GMap.NET TileLoader: " + GThreadPool.Count;
                        t.IsBackground = true;
                        t.Priority     = ThreadPriority.BelowNormal;
                    }
                    GThreadPool.Add(t);

                    Debug.WriteLine("add " + t.Name + " to GThreadPool");

                    t.Start();
                }
                #endregion

                lock (LastTileLoadStartEndLock)
                {
                    LastTileLoadStart = DateTime.Now;
                    Debug.WriteLine("OnTileLoadStart - at zoom " + Zoom + ", time: " + LastTileLoadStart.TimeOfDay);
                }

                loadWaitCount = 0;

#if !PocketPC
                Monitor.PulseAll(tileLoadQueue);
#else
                wait.PulseAll();
#endif
            }

            if (OnTileLoadStart != null)
            {
                OnTileLoadStart();
            }
        }
Beispiel #7
0
        void Dispose(bool disposing)
        {
            if (IsStarted)
            {
                if (invalidator != null)
                {
                    invalidator.CancelAsync();
                    invalidator.DoWork -= new DoWorkEventHandler(invalidatorWatch);
                    invalidator.Dispose();
                    invalidator = null;
                }

                if (Refresh != null)
                {
                    Refresh.Set();
                    Refresh.Close();
                    Refresh = null;
                }

                int x = Interlocked.Decrement(ref instances);
                Debug.WriteLine("OnMapClose: " + x);

                CancelAsyncTasks();
                IsStarted = false;

                if (Matrix != null)
                {
                    Matrix.Dispose();
                    Matrix = null;
                }

                if (FailedLoads != null)
                {
                    lock (FailedLoads)
                    {
                        FailedLoads.Clear();
                        RaiseEmptyTileError = false;
                    }
                    FailedLoads = null;
                }

                // cancel waiting loaders
                Monitor.Enter(tileLoadQueue);
                try
                {
                    Monitor.PulseAll(tileLoadQueue);
                    tileDrawingList.Clear();
                }
                finally
                {
                    Monitor.Exit(tileLoadQueue);
                }

                lock (GThreadPool)
                {
#if PocketPC
                    Debug.WriteLine("waiting until loaders are stopped...");
                    while (GThreadPool.Count > 0)
                    {
                        var t = GThreadPool[0];

                        if (t.State != ThreadState.Stopped)
                        {
                            var tr = t.Join(1111);

                            Debug.WriteLine(t.Name + ", " + t.State);

                            if (!tr)
                            {
                                continue;
                            }
                            else
                            {
                                GThreadPool.Remove(t);
                            }
                        }
                        else
                        {
                            GThreadPool.Remove(t);
                        }
                    }
                    Thread.Sleep(1111);
#endif
                }

                if (tileDrawingListLock != null)
                {
                    tileDrawingListLock.Dispose();
                    tileDrawingListLock = null;
                    tileDrawingList     = null;
                }

                if (x == 0)
                {
#if DEBUG
                    GMaps.Instance.CancelTileCaching();
#endif
                    GMaps.Instance.noMapInstances = true;
                    GMaps.Instance.WaitForCache.Set();
                    if (disposing)
                    {
                        GMaps.Instance.MemoryCache.Clear();
                    }
                }
            }
        }
Beispiel #8
0
        // tile consumer thread
        void ProcessLoadTask()
        {
            LoadTask?task = null;
            long     lastTileLoadTimeMs;
            bool     stop = false;

#if !PocketPC
            Thread ct   = Thread.CurrentThread;
            string ctid = "Thread[" + ct.ManagedThreadId + "]";
#else
            int ctid = 0;
#endif
            while (!stop && IsStarted)
            {
                task = null;

                Monitor.Enter(tileLoadQueue);
                try
                {
                    while (tileLoadQueue.Count == 0)
                    {
                        Debug.WriteLine(ctid + " - Wait " + loadWaitCount + " - " + DateTime.Now.TimeOfDay);

                        if (++loadWaitCount >= GThreadPoolSize)
                        {
                            loadWaitCount = 0;

                            #region -- last thread takes action --

                            {
                                LastTileLoadEnd    = DateTime.Now;
                                lastTileLoadTimeMs = (long)(LastTileLoadEnd - LastTileLoadStart).TotalMilliseconds;
                            }

                            #region -- clear stuff--
                            if (IsStarted)
                            {
                                GMaps.Instance.MemoryCache.RemoveOverload();

                                tileDrawingListLock.AcquireReaderLock();
                                try
                                {
                                    Matrix.ClearLevelAndPointsNotIn(Zoom, tileDrawingList);
                                }
                                finally
                                {
                                    tileDrawingListLock.ReleaseReaderLock();
                                }
                            }
                            #endregion

                            UpdateGroundResolution();
#if UseGC
                            GC.Collect();
                            GC.WaitForPendingFinalizers();
                            GC.Collect();
#endif

                            Debug.WriteLine(ctid + " - OnTileLoadComplete: " + lastTileLoadTimeMs + "ms, MemoryCacheSize: " + GMaps.Instance.MemoryCache.Size + "MB");

                            if (OnTileLoadComplete != null)
                            {
                                OnTileLoadComplete(lastTileLoadTimeMs);
                            }
                            #endregion
                        }

                        if (!IsStarted || false == Monitor.Wait(tileLoadQueue, WaitForTileLoadThreadTimeout, false) || !IsStarted)
                        {
                            stop = true;
                            break;
                        }
                    }

                    if (IsStarted && !stop || tileLoadQueue.Count > 0)
                    {
                        task = tileLoadQueue.Pop();
                    }
                }
                finally
                {
                    Monitor.Exit(tileLoadQueue);
                }

                if (task.HasValue && IsStarted)
                {
                    try
                    {
                        #region -- execute --

                        var m = Matrix.GetTileWithReadLock(task.Value.Zoom, task.Value.Pos);
                        if (!m.NotEmpty)
                        {
                            Debug.WriteLine(ctid + " - try load: " + task);

                            Tile t = new Tile(task.Value.Zoom, task.Value.Pos);

                            foreach (var tl in provider.Overlays)
                            {
                                int retry = 0;
                                do
                                {
                                    PureImage img = null;
                                    Exception ex  = null;

                                    if (!provider.MaxZoom.HasValue || task.Value.Zoom <= provider.MaxZoom)
                                    {
                                        if (skipOverZoom == 0 || task.Value.Zoom <= skipOverZoom)
                                        {
                                            // tile number inversion(BottomLeft -> TopLeft)
                                            if (tl.InvertedAxisY)
                                            {
                                                img = GMaps.Instance.GetImageFrom(tl, new GPoint(task.Value.Pos.X, maxOfTiles.Height - task.Value.Pos.Y), task.Value.Zoom, out ex);
                                            }
                                            else // ok
                                            {
                                                img = GMaps.Instance.GetImageFrom(tl, task.Value.Pos, task.Value.Zoom, out ex);
                                            }
                                        }
                                    }

                                    if (img != null && ex == null)
                                    {
                                        if (okZoom < task.Value.Zoom)
                                        {
                                            okZoom       = task.Value.Zoom;
                                            skipOverZoom = 0;
                                            Debug.WriteLine("skipOverZoom disabled, okZoom: " + okZoom);
                                        }
                                    }
                                    else if (ex != null)
                                    {
                                        if (skipOverZoom != okZoom)
                                        {
                                            if (ex.Message.Contains("(404) Not Found"))
                                            {
                                                skipOverZoom = okZoom;
                                                Debug.WriteLine("skipOverZoom enabled: " + skipOverZoom);
                                            }
                                        }
                                    }

                                    // check for parent tiles if not found
                                    if (img == null && okZoom > 0 && fillEmptyTiles && Provider.Projection is MercatorProjection)
                                    {
                                        int    zoomOffset = task.Value.Zoom > okZoom ? task.Value.Zoom - okZoom : 1;
                                        long   Ix         = 0;
                                        GPoint parentTile = GPoint.Empty;

                                        while (img == null && zoomOffset < task.Value.Zoom)
                                        {
                                            Ix         = (long)Math.Pow(2, zoomOffset);
                                            parentTile = new GMap.NET.GPoint((task.Value.Pos.X / Ix), (task.Value.Pos.Y / Ix));
                                            img        = GMaps.Instance.GetImageFrom(tl, parentTile, task.Value.Zoom - zoomOffset++, out ex);
                                        }

                                        if (img != null)
                                        {
                                            // offsets in quadrant
                                            long Xoff = Math.Abs(task.Value.Pos.X - (parentTile.X * Ix));
                                            long Yoff = Math.Abs(task.Value.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 (FailedLoads)
                                            {
                                                if (!FailedLoads.ContainsKey(task.Value))
                                                {
                                                    FailedLoads.Add(task.Value, ex);

                                                    if (OnEmptyTileError != null)
                                                    {
                                                        if (!RaiseEmptyTileError)
                                                        {
                                                            RaiseEmptyTileError = true;
                                                            OnEmptyTileError(task.Value.Zoom, task.Value.Pos);
                                                        }
                                                    }
                                                }
                                            }
                                        }

                                        if (RetryLoadTile > 0)
                                        {
                                            Debug.WriteLine(ctid + " - ProcessLoadTask: " + task + " -> empty tile, retry " + retry);
                                            {
                                                Thread.Sleep(1111);
                                            }
                                        }
                                    }
                                }while(++retry < RetryLoadTile);
                            }

                            if (t.HasAnyOverlays && IsStarted)
                            {
                                Matrix.SetTile(t);
                            }
                            else
                            {
                                t.Dispose();
                            }
                        }

                        #endregion
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ctid + " - ProcessLoadTask: " + ex.ToString());
                    }
                    finally
                    {
                        if (Refresh != null)
                        {
                            Refresh.Set();
                        }
                    }
                }
            }

#if !PocketPC
            Monitor.Enter(tileLoadQueue);
            try
            {
                Debug.WriteLine("Quit - " + ct.Name);
                lock (GThreadPool)
                {
                    GThreadPool.Remove(ct);
                }
            }
            finally
            {
                Monitor.Exit(tileLoadQueue);
            }
#endif
        }
Beispiel #9
0
        /// <summary>
        /// Method used to listen for native events from the GPS.
        /// </summary>
        private void WaitForGpsEvents()
        {
            //lock (this)
            {
                bool listening = true;
                // allocate 3 handles worth of memory to pass to WaitForMultipleObjects
                IntPtr handles = Utils.LocalAlloc(12);

                // write the three handles we are listening for.
                Marshal.WriteInt32(handles, 0, stopHandle.ToInt32());
                Marshal.WriteInt32(handles, 4, deviceStateChangedHandle.ToInt32());
                Marshal.WriteInt32(handles, 8, newLocationHandle.ToInt32());

                while (listening)
                {
                    int obj = WaitForMultipleObjects(3, handles, 0, -1);
                    if (obj != waitFailed)
                    {
                        switch (obj)
                        {
                        case 0:
                            // we've been signalled to stop
                            listening = false;
                            break;

                        case 1:
                            // device state has changed
                            if (deviceStateChanged != null)
                            {
                                deviceStateChanged(this, GetDeviceState());
                            }
                            break;

                        case 2:
                            // location has changed
                            if (locationChanged != null)
                            {
                                locationChanged(this, GetPosition());
                            }
                            break;
                        }
                    }
                }

                // free the memory we allocated for the native handles
                Utils.LocalFree(handles);

                if (newLocationHandle != IntPtr.Zero)
                {
                    CloseHandle(newLocationHandle);
                    newLocationHandle = IntPtr.Zero;
                }

                if (deviceStateChangedHandle != IntPtr.Zero)
                {
                    CloseHandle(deviceStateChangedHandle);
                    deviceStateChangedHandle = IntPtr.Zero;
                }

                if (stopHandle != IntPtr.Zero)
                {
                    CloseHandle(stopHandle);
                    stopHandle = IntPtr.Zero;
                }

                // clear our gpsEventThread so that we can recreate this thread again
                // if the events are hooked up again.
                gpsEventThread = null;

                Debug.WriteLine("gps device stopped...");
            }
        }
Beispiel #10
0
        /// <summary>
        /// updates map bounds
        /// </summary>
        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 ContinuesMap
                        // ----------------------------
                        if (p.X < minOfTiles.Width)
                        {
                            p.X += (maxOfTiles.Width + 1);
                        }

                        if (p.X > maxOfTiles.Width)
                        {
                            p.X -= (maxOfTiles.Width + 1);
                        }
                        // ----------------------------
#endif

                        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();
            }

            Monitor.Enter(tileLoadQueue);
            try
            {
                tileDrawingListLock.AcquireReaderLock();
                try
                {
                    foreach (DrawTile p in tileDrawingList)
                    {
                        LoadTask task = new LoadTask(p.PosXY, Zoom);
                        {
                            if (!tileLoadQueue.Contains(task))
                            {
                                tileLoadQueue.Push(task);
                            }
                        }
                    }
                }
                finally
                {
                    tileDrawingListLock.ReleaseReaderLock();
                }

                #region -- starts loader threads if needed --

                lock (GThreadPool)
                {
                    while (GThreadPool.Count < GThreadPoolSize)
                    {
                        Thread t = new Thread(new ThreadStart(ProcessLoadTask));
                        {
                            t.Name         = "TileLoader: " + GThreadPool.Count;
                            t.IsBackground = true;
                            t.Priority     = ThreadPriority.BelowNormal;
                        }
                        GThreadPool.Add(t);

                        Debug.WriteLine("add " + t.Name + " to GThreadPool");

                        t.Start();
                    }
                }
                #endregion

                {
                    LastTileLoadStart = DateTime.Now;
                    Debug.WriteLine("OnTileLoadStart - at zoom " + Zoom + ", time: " + LastTileLoadStart.TimeOfDay);
                }

                loadWaitCount = 0;
                Monitor.PulseAll(tileLoadQueue);
            }
            finally
            {
                Monitor.Exit(tileLoadQueue);
            }

            updatingBounds = false;

            if (OnTileLoadStart != null)
            {
                OnTileLoadStart();
            }
        }
Beispiel #11
0
        /// <summary>
        /// Method used to listen for native events from the GPS. 
        /// </summary>
        private void WaitForGpsEvents()
        {
            //lock (this)
             {
            bool listening = true;
            // allocate 3 handles worth of memory to pass to WaitForMultipleObjects
            IntPtr handles = Utils.LocalAlloc(12);

            // write the three handles we are listening for.
            Marshal.WriteInt32(handles, 0, stopHandle.ToInt32());
            Marshal.WriteInt32(handles, 4, deviceStateChangedHandle.ToInt32());
            Marshal.WriteInt32(handles, 8, newLocationHandle.ToInt32());

            while(listening)
            {
               int obj = WaitForMultipleObjects(3, handles, 0, -1);
               if(obj != waitFailed)
               {
                  switch(obj)
                  {
                     case 0:
                     // we've been signalled to stop
                     listening = false;
                     break;

                     case 1:
                     // device state has changed
                     if(deviceStateChanged != null)
                     {
                        deviceStateChanged(this, GetDeviceState());
                     }
                     break;

                     case 2:
                     // location has changed
                     if(locationChanged != null)
                     {
                        locationChanged(this, GetPosition());
                     }
                     break;
                  }
               }
            }

            // free the memory we allocated for the native handles
            Utils.LocalFree(handles);

            if(newLocationHandle != IntPtr.Zero)
            {
               CloseHandle(newLocationHandle);
               newLocationHandle = IntPtr.Zero;
            }

            if(deviceStateChangedHandle != IntPtr.Zero)
            {
               CloseHandle(deviceStateChangedHandle);
               deviceStateChangedHandle = IntPtr.Zero;
            }

            if(stopHandle != IntPtr.Zero)
            {
               CloseHandle(stopHandle);
               stopHandle = IntPtr.Zero;
            }

            // clear our gpsEventThread so that we can recreate this thread again
            // if the events are hooked up again.
            gpsEventThread = null;

            Debug.WriteLine("gps device stopped...");
             }
        }
Beispiel #12
0
        /// <summary>
        ///     updates map bounds
        /// </summary>
        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++)
                    {
                        var p = CenterTileXYLocation;
                        p.X += i;
                        p.Y += j;

#if ContinuesMap
                        // ----------------------------
                        if (p.X < minOfTiles.Width)
                        {
                            p.X += (maxOfTiles.Width + 1);
                        }

                        if (p.X > maxOfTiles.Width)
                        {
                            p.X -= (maxOfTiles.Width + 1);
                        }
                        // ----------------------------
#endif

                        if (p.X >= _minOfTiles.Width && p.Y >= _minOfTiles.Height && p.X <= _maxOfTiles.Width &&
                            p.Y <= _maxOfTiles.Height)
                        {
                            var 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(TileDrawingList);
                }
                else
                {
                    TileDrawingList.Sort();
                }

                #endregion
            }
            finally
            {
                TileDrawingListLock.ReleaseWriterLock();
            }

#if NET40
            Interlocked.Exchange(ref _loadWaitCount, 0);
#else
            Monitor.Enter(TileLoadQueue);
            try
            {
#endif
            TileDrawingListLock.AcquireReaderLock();
            try
            {
                foreach (var p in TileDrawingList)
                {
                    var task = new LoadTask(p.PosXY, Zoom, this);
#if NET40
                    AddLoadTask(task);
#else
                    {
                        if (!TileLoadQueue.Contains(task))
                        {
                            TileLoadQueue.Push(task);
                        }
                    }
#endif
                }
            }
            finally
            {
                TileDrawingListLock.ReleaseReaderLock();
            }

#if !NET40
            #region -- starts loader threads if needed --

            lock (_gThreadPool)
            {
                while (_gThreadPool.Count < GThreadPoolSize)
                {
                    var t = new Thread(TileLoadThread);
                    {
                        t.Name         = "TileLoader: " + _gThreadPool.Count;
                        t.IsBackground = true;
                        t.Priority     = ThreadPriority.BelowNormal;
                    }

                    _gThreadPool.Add(t);

                    Debug.WriteLine("add " + t.Name + " to GThreadPool");

                    t.Start();
                }
            }
            #endregion
#endif
            {
                _lastTileLoadStart = DateTime.Now;
                Debug.WriteLine("OnTileLoadStart - at zoom " + Zoom + ", time: " + _lastTileLoadStart.TimeOfDay);
            }
#if !NET40
            _loadWaitCount = 0;
            Monitor.PulseAll(TileLoadQueue);
        }

        finally
        {
            Monitor.Exit(TileLoadQueue);
        }
#endif
            UpdatingBounds = false;

            if (OnTileLoadStart != null)
            {
                OnTileLoadStart();
            }
        }
Beispiel #13
0
      /// <summary>
      /// Closes the gps device.
      /// </summary>
      public void Close()
      {
         if(gpsHandle != IntPtr.Zero)
         {
            GPSCloseDevice(gpsHandle);
            gpsHandle = IntPtr.Zero;
         }

         // Set our native stop event so we can exit our event thread.
         if(stopHandle != IntPtr.Zero)
         {
             Win32.EventModify(stopHandle, (int)Win32.EventFlags.SET);            
         }

         // wait exit
         if (gpsEventThread != null)
         {
             quit.WaitOne();
             gpsEventThread = null;
         }
      }
Beispiel #14
0
 /// <summary>
 /// Creates our event thread that will receive native events
 /// </summary>
 private void CreateGpsEventThread()
 {
     // we only want to create the thread if we don't have one created already
      // and we have opened the gps device
      if(gpsEventThread == null && gpsHandle != IntPtr.Zero)
      {
     // Create and start thread to listen for GPS events
     gpsEventThread = new Thread(new System.Threading.ThreadStart(WaitForGpsEvents));
     gpsEventThread.IsBackground = false;
     gpsEventThread.Name = "GMap.NET GpsEvents";
     gpsEventThread.Start();
      }
 }
Beispiel #15
0
        /// <summary>
        /// live for cache ;}
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void CacheEngineLoop()
        {
            Debug.WriteLine("CacheEngine: start");
            int left = 0;

            OnTileCacheStart?.Invoke();

            bool startEvent = false;

            while (!abortCacheLoop)
            {
                try
                {
                    CacheQueueItem?task = null;

                    lock (tileCacheQueue)
                    {
                        left = tileCacheQueue.Count;
                        if (left > 0)
                        {
                            task = tileCacheQueue.Dequeue();
                        }
                    }

                    if (task.HasValue)
                    {
                        if (startEvent)
                        {
                            startEvent = false;

                            OnTileCacheStart?.Invoke();
                        }

                        OnTileCacheProgress?.Invoke(left);

                        #region -- save --
                        // check if stream wasn't disposed somehow
                        if (task.Value.Img != null)
                        {
                            Debug.WriteLine("CacheEngine[" + left + "]: storing tile " + task.Value + ", " + task.Value.Img.Length / 1024 + "kB...");

                            if ((task.Value.CacheType & CacheUsage.First) == CacheUsage.First && PrimaryCache != null)
                            {
                                if (cacheOnIdleRead)
                                {
                                    while (Interlocked.Decrement(ref readingCache) > 0)
                                    {
                                        Thread.Sleep(1000);
                                    }
                                }
                                PrimaryCache.PutImageToCache(task.Value.Img, task.Value.Tile.Type, task.Value.Tile.Pos, task.Value.Tile.Zoom);
                            }

                            if ((task.Value.CacheType & CacheUsage.Second) == CacheUsage.Second && SecondaryCache != null)
                            {
                                if (cacheOnIdleRead)
                                {
                                    while (Interlocked.Decrement(ref readingCache) > 0)
                                    {
                                        Thread.Sleep(1000);
                                    }
                                }
                                SecondaryCache.PutImageToCache(task.Value.Img, task.Value.Tile.Type, task.Value.Tile.Pos, task.Value.Tile.Zoom);
                            }

                            task.Value.Clear();

                            if (!boostCacheEngine)
                            {
#if PocketPC
                                Thread.Sleep(3333);
#else
                                Thread.Sleep(333);
#endif
                            }
                        }
                        else
                        {
                            Debug.WriteLine("CacheEngineLoop: skip, tile disposed to early -> " + task.Value);
                        }
                        task = null;
                        #endregion
                    }
                    else
                    {
                        if (!startEvent)
                        {
                            startEvent = true;

                            OnTileCacheComplete?.Invoke();
                        }

                        if (abortCacheLoop || noMapInstances || !WaitForCache.WaitOne(33333, false) || noMapInstances)
                        {
                            break;
                        }
                    }
                }
#if !PocketPC
                catch (AbandonedMutexException)
                {
                    break;
                }
#endif
                catch (Exception ex)
                {
                    Debug.WriteLine("CacheEngineLoop: " + ex.ToString());
                }
            }
            Debug.WriteLine("CacheEngine: stop");

            if (!startEvent)
            {
                OnTileCacheComplete?.Invoke();
            }
        }
Beispiel #16
0
        static void ProcessLoadTask(LoadTask task, string ctid)
        {
            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, out ex);
                                    }
                                    else // ok
                                    {
                                        img = GMaps.Instance.GetImageFrom(tl, task.Pos, task.Zoom, 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 GMap.NET.GPoint((task.Pos.X / Ix), (task.Pos.Y / Ix));
                                    img        = GMaps.Instance.GetImageFrom(tl, parentTile, task.Zoom - zoomOffset++, 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();
                }
            }
        }
Beispiel #17
0
        void tileLoadThread()
        {
            LoadTask?task = null;
            bool     stop = false;

#if !PocketPC
            Thread ct   = Thread.CurrentThread;
            string ctid = "Thread[" + ct.ManagedThreadId + "]";
#else
            int ctid = 0;
#endif
            while (!stop && IsStarted)
            {
                task = null;

                Monitor.Enter(tileLoadQueue);
                try
                {
                    while (tileLoadQueue.Count == 0)
                    {
                        Debug.WriteLine(ctid + " - Wait " + loadWaitCount + " - " + DateTime.Now.TimeOfDay);

                        if (++loadWaitCount >= GThreadPoolSize)
                        {
                            loadWaitCount = 0;
                            OnLoadComplete(ctid);
                        }

                        if (!IsStarted || false == Monitor.Wait(tileLoadQueue, WaitForTileLoadThreadTimeout, false) || !IsStarted)
                        {
                            stop = true;
                            break;
                        }
                    }

                    if (IsStarted && !stop || tileLoadQueue.Count > 0)
                    {
                        task = tileLoadQueue.Pop();
                    }
                }
                finally
                {
                    Monitor.Exit(tileLoadQueue);
                }

                if (task.HasValue && IsStarted)
                {
                    ProcessLoadTask(task.Value, ctid);
                }
            }

#if !PocketPC
            Monitor.Enter(tileLoadQueue);
            try
            {
                Debug.WriteLine("Quit - " + ct.Name);
                lock (GThreadPool)
                {
                    GThreadPool.Remove(ct);
                }
            }
            finally
            {
                Monitor.Exit(tileLoadQueue);
            }
#endif
        }
Beispiel #18
0
        /// <summary>
        /// live for cache ;}
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void CacheEngineLoop()
        {
            int left = 0;

            if (OnTileCacheStart != null)
            {
                OnTileCacheStart();
            }

            bool startEvent = false;

            while (!abortCacheLoop)
            {
                try
                {
                    CacheQueueItem?task = null;

                    lock (tileCacheQueue)
                    {
                        left = tileCacheQueue.Count;
                        if (left > 0)
                        {
                            task = tileCacheQueue.Dequeue();
                        }
                    }

                    if (task.HasValue)
                    {
                        if (startEvent)
                        {
                            startEvent = false;

                            if (OnTileCacheStart != null)
                            {
                                OnTileCacheStart();
                            }
                        }

                        if (OnTileCacheProgress != null)
                        {
                            OnTileCacheProgress(left);
                        }

                        #region -- save --
                        // check if stream wasn't disposed somehow
                        if (task.Value.Img != null)
                        {
                            if ((task.Value.CacheType & CacheUsage.First) == CacheUsage.First && PrimaryCache != null)
                            {
                                if (cacheOnIdleRead)
                                {
                                    while (Interlocked.Decrement(ref readingCache) > 0)
                                    {
                                        Thread.Sleep(1000);
                                    }
                                }
                                PrimaryCache.PutImageToCache(task.Value.Img, task.Value.Tile.Type, task.Value.Tile.Pos, task.Value.Tile.Zoom);
                            }

                            if ((task.Value.CacheType & CacheUsage.Second) == CacheUsage.Second && SecondaryCache != null)
                            {
                                if (cacheOnIdleRead)
                                {
                                    while (Interlocked.Decrement(ref readingCache) > 0)
                                    {
                                        Thread.Sleep(1000);
                                    }
                                }
                                SecondaryCache.PutImageToCache(task.Value.Img, task.Value.Tile.Type, task.Value.Tile.Pos, task.Value.Tile.Zoom);
                            }

                            task.Value.Clear();

                            if (!boostCacheEngine)
                            {
#if PocketPC
                                Thread.Sleep(3333);
#else
                                Thread.Sleep(333);
#endif
                            }
                        }
                        else
                        {
                        }
                        task = null;
                        #endregion
                    }
                    else
                    {
                        if (!startEvent)
                        {
                            startEvent = true;

                            if (OnTileCacheComplete != null)
                            {
                                OnTileCacheComplete();
                            }
                        }

                        if (abortCacheLoop || noMapInstances || !WaitForCache.WaitOne(33333, false) || noMapInstances)
                        {
                            break;
                        }
                    }
                }
#if !PocketPC
                catch (AbandonedMutexException)
                {
                    break;
                }
#endif
                catch
                {
                }
            }

            if (!startEvent)
            {
                if (OnTileCacheComplete != null)
                {
                    OnTileCacheComplete();
                }
            }
        }
Beispiel #19
0
      /// <summary>
      /// updates map bounds
      /// </summary>
      void UpdateBounds()
      {
         if(MapType == NET.MapType.None)
         {
            return;
         }

         lock(tileLoadQueue)
         {
            tileDrawingListLock.AcquireWriterLock();
            try
            {
               #region -- find tiles around --
               tileDrawingList.Clear();

               for(int i = -sizeOfMapArea.Width; i <= sizeOfMapArea.Width; i++)
               {
                  for(int j = -sizeOfMapArea.Height; j <= sizeOfMapArea.Height; j++)
                  {
                     Point p = centerTileXYLocation;
                     p.X += i;
                     p.Y += j;

#if ContinuesMap
               // ----------------------------
               if(p.X < minOfTiles.Width)
               {
                  p.X += (maxOfTiles.Width + 1);
               }

               if(p.X > maxOfTiles.Width)
               {
                  p.X -= (maxOfTiles.Width + 1);
               }
               // ----------------------------
#endif

                     if(p.X >= minOfTiles.Width && p.Y >= minOfTiles.Height && p.X <= maxOfTiles.Width && p.Y <= maxOfTiles.Height)
                     {
                        if(!tileDrawingList.Contains(p))
                        {
                           tileDrawingList.Add(p);
                        }
                     }
                  }
               }

               if(GMaps.Instance.ShuffleTilesOnLoad)
               {
                  Stuff.Shuffle<Point>(tileDrawingList);
               }
               #endregion

               foreach(Point p in tileDrawingList)
               {
                  LoadTask task = new LoadTask(p, Zoom);
                  {
                     if(!tileLoadQueue.Contains(task))
                     {
                        tileLoadQueue.Enqueue(task);
                     }
                  }
               }
            }
            finally
            {
               tileDrawingListLock.ReleaseWriterLock();
            }

            #region -- starts loader threads if needed --
#if !PocketPC
            while(GThreadPool.Count < GThreadPoolSize)
#else
            while(GThreadPool.Count < GThreadPoolSize)
#endif
            {
               Thread t = new Thread(new ThreadStart(ProcessLoadTask));
               {
                  t.Name = "GMap.NET TileLoader: " + GThreadPool.Count;
                  t.IsBackground = true;
                  t.Priority = ThreadPriority.BelowNormal;
               }
               GThreadPool.Add(t);

               Debug.WriteLine("add " + t.Name + " to GThreadPool");

               t.Start();
            }
            #endregion

            lock(LastTileLoadStartEndLock)
            {
               LastTileLoadStart = DateTime.Now;
               Debug.WriteLine("OnTileLoadStart - at zoom " + Zoom + ", time: " + LastTileLoadStart.TimeOfDay);
            }

            loadWaitCount = 0;

#if !PocketPC
            Monitor.PulseAll(tileLoadQueue);
#else
            wait.PulseAll();
#endif
         }

         if(OnTileLoadStart != null)
         {
            OnTileLoadStart();
         }
      }
      /// <summary>
      /// updates map bounds
      /// </summary>
      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 ContinuesMap
               // ----------------------------
               if(p.X < minOfTiles.Width)
               {
                  p.X += (maxOfTiles.Width + 1);
               }

               if(p.X > maxOfTiles.Width)
               {
                  p.X -= (maxOfTiles.Width + 1);
               }
               // ----------------------------
#endif

                  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();
         }

         Monitor.Enter(tileLoadQueue);
         try
         {
            tileDrawingListLock.AcquireReaderLock();
            try
            {
               foreach(DrawTile p in tileDrawingList)
               {
                  LoadTask task = new LoadTask(p.PosXY, Zoom);
                  {
                     if(!tileLoadQueue.Contains(task))
                     {
                        tileLoadQueue.Push(task);
                     }
                  }
               }
            }
            finally
            {
               tileDrawingListLock.ReleaseReaderLock();
            }

            #region -- starts loader threads if needed --

            lock(GThreadPool)
            {
               while(GThreadPool.Count < GThreadPoolSize)
               {
                  Thread t = new Thread(new ThreadStart(ProcessLoadTask));
                  {
                     t.Name = "TileLoader: " + GThreadPool.Count;
                     t.IsBackground = true;
                     t.Priority = ThreadPriority.BelowNormal;
                  }
                  GThreadPool.Add(t);

                  Debug.WriteLine("add " + t.Name + " to GThreadPool");

                  t.Start();
               }
            }
            #endregion

            {
               LastTileLoadStart = DateTime.Now;
               Debug.WriteLine("OnTileLoadStart - at zoom " + Zoom + ", time: " + LastTileLoadStart.TimeOfDay);
            }

            loadWaitCount = 0;
            Monitor.PulseAll(tileLoadQueue);
         }
         finally
         {
            Monitor.Exit(tileLoadQueue);
         }

         updatingBounds = false;

         if(OnTileLoadStart != null)
         {
            OnTileLoadStart();
         }
      }
Beispiel #21
0
        void ProcessLoadTask()
        {
            bool     invalidate = false;
            LoadTask?task       = null;
            long     lastTileLoadTimeMs;
            bool     stop = false;

#if !PocketPC
            Thread ct   = Thread.CurrentThread;
            string ctid = "Thread[" + ct.ManagedThreadId + "]";
#else
            int ctid = 0;
#endif
            while (!stop)
            {
                invalidate = false;
                task       = null;

                lock (tileLoadQueue)
                {
                    while (tileLoadQueue.Count == 0)
                    {
                        Debug.WriteLine(ctid + " - Wait " + loadWaitCount + " - " + DateTime.Now.TimeOfDay);

                        if (++loadWaitCount >= GThreadPoolSize)
                        {
                            loadWaitCount = 0;

                            lock (LastInvalidationLock)
                            {
                                LastInvalidation = DateTime.Now;
                            }

                            if (OnNeedInvalidation != null)
                            {
                                OnNeedInvalidation();
                            }

                            lock (LastTileLoadStartEndLock)
                            {
                                LastTileLoadEnd    = DateTime.Now;
                                lastTileLoadTimeMs = (long)(LastTileLoadEnd - LastTileLoadStart).TotalMilliseconds;
                            }

                            #region -- clear stuff--
                            {
                                GMaps.Instance.kiberCacheLock.AcquireWriterLock();
                                try
                                {
                                    GMaps.Instance.TilesInMemory.RemoveMemoryOverload();
                                }
                                finally
                                {
                                    GMaps.Instance.kiberCacheLock.ReleaseWriterLock();
                                }

                                tileDrawingListLock.AcquireReaderLock();
                                try
                                {
                                    Matrix.ClearLevelAndPointsNotIn(Zoom, tileDrawingList);
                                }
                                finally
                                {
                                    tileDrawingListLock.ReleaseReaderLock();
                                }
                            }
                            #endregion

                            UpdateGroundResolution();
#if UseGC
                            GC.Collect();
                            GC.WaitForPendingFinalizers();
                            GC.Collect();
#endif

                            Debug.WriteLine(ctid + " - OnTileLoadComplete: " + lastTileLoadTimeMs + "ms, MemoryCacheSize: " + GMaps.Instance.MemoryCacheSize + "MB");

                            if (OnTileLoadComplete != null)
                            {
                                OnTileLoadComplete(lastTileLoadTimeMs);
                            }
                        }
#if !PocketPC
                        if (false == Monitor.Wait(tileLoadQueue, WaitForTileLoadThreadTimeout, false))
                        {
                            stop = true;
                            break;
                        }
#else
                        wait.Wait();
#endif
                    }

                    if (!stop || tileLoadQueue.Count > 0)
                    {
                        task = tileLoadQueue.Dequeue();
                    }
                }

                if (task.HasValue)
                {
                    try
                    {
                        #region -- execute --
                        var m = Matrix.GetTileWithReadLock(task.Value.Zoom, task.Value.Pos);

                        if (m == null || m.Overlays.Count == 0)
                        {
                            Debug.WriteLine(ctid + " - Fill empty TileMatrix: " + task);

                            Tile t      = new Tile(task.Value.Zoom, task.Value.Pos);
                            var  layers = GMaps.Instance.GetAllLayersOfType(MapType);

                            foreach (MapType tl in layers)
                            {
                                int retry = 0;
                                do
                                {
                                    PureImage img;
                                    Exception ex;

                                    // tile number inversion(BottomLeft -> TopLeft) for pergo maps
                                    if (tl == MapType.PergoTurkeyMap)
                                    {
                                        img = GMaps.Instance.GetImageFrom(tl, new Point(task.Value.Pos.X, maxOfTiles.Height - task.Value.Pos.Y), task.Value.Zoom, out ex);
                                    }
                                    else // ok
                                    {
                                        img = GMaps.Instance.GetImageFrom(tl, task.Value.Pos, task.Value.Zoom, out ex);
                                    }

                                    if (img != null)
                                    {
                                        lock (t.Overlays)
                                        {
                                            t.Overlays.Add(img);
                                        }
                                        break;
                                    }
                                    else
                                    {
                                        if (ex != null)
                                        {
                                            lock (FailedLoads)
                                            {
                                                if (!FailedLoads.ContainsKey(task.Value))
                                                {
                                                    FailedLoads.Add(task.Value, ex);

                                                    if (OnEmptyTileError != null)
                                                    {
                                                        if (!RaiseEmptyTileError)
                                                        {
                                                            RaiseEmptyTileError = true;
                                                            OnEmptyTileError(task.Value.Zoom, task.Value.Pos);
                                                        }
                                                    }
                                                }
                                            }
                                        }

                                        if (RetryLoadTile > 0)
                                        {
                                            Debug.WriteLine(ctid + " - ProcessLoadTask: " + task + " -> empty tile, retry " + retry);
                                            {
                                                Thread.Sleep(1111);
                                            }
                                        }
                                    }
                                }while(++retry < RetryLoadTile);
                            }

                            if (t.Overlays.Count > 0)
                            {
                                Matrix.SetTile(t);
                            }
                            else
                            {
                                t.Clear();
                                t = null;
                            }

                            layers = null;
                        }
                        #endregion
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ctid + " - ProcessLoadTask: " + ex.ToString());
                    }
                    finally
                    {
                        lock (LastInvalidationLock)
                        {
                            invalidate = ((DateTime.Now - LastInvalidation).TotalMilliseconds > 111);
                            if (invalidate)
                            {
                                LastInvalidation = DateTime.Now;
                            }
                        }

                        if (invalidate)
                        {
                            if (OnNeedInvalidation != null)
                            {
                                OnNeedInvalidation();
                            }
                        }
#if DEBUG
                        //else
                        //{
                        //   lock(LastInvalidationLock)
                        //   {
                        //      Debug.WriteLine(ctid + " - SkipInvalidation, Delta: " + (DateTime.Now - LastInvalidation).TotalMilliseconds + "ms");
                        //   }
                        //}
#endif
                    }
                }
            }

#if !PocketPC
            lock (tileLoadQueue)
            {
                Debug.WriteLine("Quit - " + ct.Name);
                GThreadPool.Remove(ct);
            }
#endif
        }