Пример #1
0
        private byte[] TryRequestTileData(TileInfo tileInfo)
        {
            byte[] result = null;
            try
            {
                openTileRequests.TryAdd(tileInfo.Index, 1);
                result = provider.GetTile(tileInfo);
            }
            catch
            {
                // Nothing has to be done with the exception.
                // Result should stay null
            }

            //Try at least once again
            if (result == null)
            {
                try
                {
                    result = provider.GetTile(tileInfo);
                }
                catch
                {
                    // Nothing has to be done with the exception.
                    // Result should stay null
                }
            }

            return(result);
        }
Пример #2
0
        private void GetTileOnThread(object parameter)
        {
            object[] parameters = (object[])parameter;
            if (parameters.Length != 4)
            {
                throw new ArgumentException("Four parameters expected");
            }
            ITileProvider        tileProvider   = (ITileProvider)parameters[0];
            TileInfo             tileInfo       = (TileInfo)parameters[1];
            MemoryCache <byte[]> bitmaps        = (MemoryCache <byte[]>)parameters[2];
            AutoResetEvent       autoResetEvent = (AutoResetEvent)parameters[3];

            byte[] bytes;
            try
            {
                bitmaps.Add(tileInfo.Key, tileProvider.GetTile(tileInfo));
            }
            catch (Exception ex)
            {
                //todo: log and use other ways to report to user.
            }
            finally
            {
                autoResetEvent.Set();
            }
        }
Пример #3
0
        private void GetTileOnThread(object parameter)
        {
            object[] parameters = (object[])parameter;
            if (parameters.Length != 5)
            {
                throw new ArgumentException("Five parameters expected");
            }
            ITileProvider tileProvider = (ITileProvider)parameters[0];
            TileInfo      tileInfo     = (TileInfo)parameters[1];
            //MemoryCache<Bitmap> bitmaps = (MemoryCache<Bitmap>)parameters[2];
            Dictionary <TileIndex, Bitmap> bitmaps = (Dictionary <TileIndex, Bitmap>)parameters[2];
            AutoResetEvent autoResetEvent          = (AutoResetEvent)parameters[3];
            bool           retry = (bool)parameters[4];

            var setEvent = true;

            try
            {
                byte[] bytes  = tileProvider.GetTile(tileInfo);
                Bitmap bitmap = new Bitmap(new MemoryStream(bytes));
                bitmaps.Add(tileInfo.Index, bitmap);
                if (_fileCache != null)
                {
                    AddImageToFileCache(tileInfo, bitmap);
                }
            }
            catch (WebException ex)
            {
                if (retry)
                {
                    GetTileOnThread(new object[] { tileProvider, tileInfo, bitmaps, autoResetEvent, false });
                    setEvent = false;
                    return;
                }
                if (_showErrorInTile)
                {
                    //an issue with this method is that one an error tile is in the memory cache it will stay even
                    //if the error is resolved. PDD.
                    var bitmap = new Bitmap(_source.Schema.Width, _source.Schema.Height);
                    using (var graphics = Graphics.FromImage(bitmap))
                    {
                        graphics.DrawString(ex.Message, new Font(FontFamily.GenericSansSerif, 12),
                                            new SolidBrush(Color.Black),
                                            new RectangleF(0, 0, _source.Schema.Width, _source.Schema.Height));
                    }
                    bitmaps.Add(tileInfo.Index, bitmap);
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message);
            }
            finally
            {
                if (setEvent)
                {
                    autoResetEvent.Set();
                }
            }
        }
Пример #4
0
        private static bool EqualTileProviders(ITileProvider tp1, ITileProvider tp2, out string message)
        {
            if (!ReferenceEquals(tp1, tp2))
            {
                if (tp1 == null)
                {
                    message = "The reference tile provider is null!";
                    return(false);
                }
                if (tp2 == null)
                {
                    message = "One of the tile providers is null, and the other not";
                    return(false);
                }

                if (tp1.GetType() != tp2.GetType())
                {
                    message = "Tile providers are of different type";
                    return(false);
                }

                for (var i = 0; i < 8; i++)
                {
                    TileInfo ti = null;
                    try
                    {
                        ti = RandomTileInfo();
                        var t1 = tp1.GetTile(ti);
                        var t2 = tp2.GetTile(ti);
                        if (!TilesEqual(t1, t2))
                        {
                            message = "Request builders produce different results for same tile request";
                            return(false);
                        }
                    }
                    catch (WebException ex)
                    {
                        if (ti == null)
                        {
                            Console.WriteLine("No tile info!");
                        }
                        else
                        {
                            Console.WriteLine("TileInfo: {0}, {1}, {2}\n{3}\n{4}", ti.Index.Level, ti.Index.Col, ti.Index.Row,
                                              ex.Message, ex.Response.ResponseUri);
                        }
                    }
                }
            }

            message = "Tile providers appear to be equal";
            return(true);
        }
Пример #5
0
        public byte[] GetTile(TileInfo tileInfo)
        {
            byte[] bytes = cache.Find(tileInfo.Index);

            if (bytes == null)
            {
                bytes = provider.GetTile(tileInfo);
                if (bytes != null)
                {
                    cache.Add(tileInfo.Index, bytes);
                }
            }
            return(bytes);
        }
Пример #6
0
        private void GetTileOnThread(object parameter)
        {
            object[] parameters = (object[])parameter;
            if (parameters.Length != 4)
            {
                throw new ArgumentException("Four parameters expected");
            }
            ITileProvider       tileProvider   = (ITileProvider)parameters[0];
            TileInfo            tileInfo       = (TileInfo)parameters[1];
            ITileCache <byte[]> bitmaps        = (ITileCache <byte[]>)parameters[2];
            AutoResetEvent      autoResetEvent = (AutoResetEvent)parameters[3];

            try
            {
                byte[] bytes  = tileProvider.GetTile(tileInfo);
                Bitmap bitmap = new Bitmap(new MemoryStream(bytes));
                bitmaps.Add(tileInfo.Index, bytes);
            }
            catch (WebException ex)
            {
                if (ShowErrorInTile)
                {
                    //an issue with this method is that one an error tile is in the memory cache it will stay even
                    //if the error is resolved. PDD.
                    var      width    = TileSource.Schema.GetTileWidth(tileInfo.Index.Level);
                    var      height   = TileSource.Schema.GetTileHeight(tileInfo.Index.Level);
                    Bitmap   bitmap   = new Bitmap(width, height);
                    Graphics graphics = Graphics.FromImage(bitmap);
                    graphics.DrawString(ex.Message, new Font(FontFamily.GenericSansSerif, 12), new SolidBrush(Color.Black),
                                        new RectangleF(0, 0, width, height));
                    graphics.Dispose();

                    using (MemoryStream m = new MemoryStream())
                    {
                        bitmap.Save(m, ImageFormat.Png);
                        bitmaps.Add(tileInfo.Index, m.ToArray());
                    }
                }
            }
            catch (Exception ex)
            {
                StackFrame CallStack = new StackFrame(1, true);
                Trace.WriteLine("Error: " + ex.Message + ", File: " + CallStack.GetFileName() + ", Line: " + CallStack.GetFileLineNumber());
            }
            finally
            {
                autoResetEvent.Set();
            }
        }
Пример #7
0
        private void GetTileOnThread(object parameter)
        {
            object[] parameters = (object[])parameter;
            if (parameters.Length != 4)
            {
                throw new ArgumentException("Three parameters expected");
            }
            ITileProvider        tileProvider   = (ITileProvider)parameters[0];
            TileInfo             tileInfo       = (TileInfo)parameters[1];
            MemoryCache <Bitmap> bitmaps        = (MemoryCache <Bitmap>)parameters[2];
            AutoResetEvent       autoResetEvent = (AutoResetEvent)parameters[3];


            byte[] bytes;
            try
            {
                bytes = tileProvider.GetTile(tileInfo);
                Bitmap bitmap = new Bitmap(new MemoryStream(bytes));
                bitmaps.Add(tileInfo.Index, bitmap);
                if (_fileCache != null)
                {
                    AddImageToFileCache(tileInfo, bitmap);
                }
            }
            catch (WebException ex)
            {
                if (_showErrorInTile)
                {
                    //an issue with this method is that one an error tile is in the memory cache it will stay even
                    //if the error is resolved. PDD.
                    Bitmap   bitmap   = new Bitmap(_source.Schema.Width, _source.Schema.Height);
                    Graphics graphics = Graphics.FromImage(bitmap);
                    graphics.DrawString(ex.Message, new Font(FontFamily.GenericSansSerif, 12), new SolidBrush(Color.Black),
                                        new RectangleF(0, 0, _source.Schema.Width, _source.Schema.Height));
                    bitmaps.Add(tileInfo.Index, bitmap);
                }
            }
            catch (Exception ex)
            {
                //todo: log and use other ways to report to user.
            }
            finally
            {
                autoResetEvent.Set();
            }
        }
Пример #8
0
        public void FetchTile()
        {
            Exception error = null;

            byte[] image = null;

            try
            {
                if (_tileProvider != null)
                {
                    image = _tileProvider.GetTile(_tileInfo);
                }
            }
            catch (Exception ex) // On this worker thread exceptions will not fall through to the caller so catch and pass in callback
            {
                error = ex;
            }
            _fetchTileCompleted(this, new FetchTileCompletedEventArgs(error, false, _tileInfo, image));
        }
Пример #9
0
        public void FetchTile(object state)
        {
            Exception error = null;

            byte[] image = null;

            try
            {
                if (_tileProvider != null)
                {
                    image = _tileProvider.GetTile(_tileInfo);
                }
            }
            catch (Exception ex) //This may seem a bit weird. We catch the exception to pass it as an argument. This is because we are on a worker thread here, we cannot just let it fall through.
            {
                error = ex;
            }
            _fetchTileCompleted(this, new FetchTileCompletedEventArgs(error, false, _tileInfo, image));
        }
Пример #10
0
 /// <summary>
 /// Gets the image content of the tile
 /// </summary>
 public byte[] GetTile(TileInfo tileInfo)
 {
     return(_provider.GetTile(tileInfo));
 }
Пример #11
0
        private static bool EqualTileProviders(ITileSchema schema, ITileProvider tp1, ITileProvider tp2, out string message)
        {
            if (!ReferenceEquals(tp1, tp2))
            {
                if (tp1 == null)
                {
                    message = "The reference tile provider is null!";
                    return(false);
                }
                if (tp2 == null)
                {
                    message = "One of the tile providers is null, and the other not";
                    return(false);
                }

                if (tp1.GetType() != tp2.GetType())
                {
                    message = "Tile providers are of different type";
                    return(false);
                }

                var keys   = schema.Resolutions.Keys.ToArray();
                var minkey = GetIndex(keys[0]);
                var maxKey = GetIndex(keys[keys.Length - 1]);
                var prefix = GetPrefix(keys[0]);
                for (var i = 0; i < 3; i++)
                {
                    TileInfo ti = null;
                    try
                    {
                        ti = RandomTileInfo(prefix + "{0}", minkey, Math.Min(maxKey, 12));
                        var req1 = tp1 as IRequest;
                        var req2 = tp2 as IRequest;
                        if (req1 != null && req2 != null)
                        {
                            if (req1.GetUri(ti) != req2.GetUri(ti))
                            {
                                message = "Request builders produce different uris for the same request";
                                return(false);
                            }
                        }
                        else
                        {
                            var t1 = tp1.GetTile(ti);
                            var t2 = tp2.GetTile(ti);
                            if (!TilesEqual(t1, t2))
                            {
                                message = "Request builders produce different results for same tile request";
                                return(false);
                            }
                        }
                    }
                    catch (TimeoutException ex)
                    {
                        System.Diagnostics.Trace.WriteLine(string.Format(
                                                               "TileInfo({4}): {0}, {1}, {2}\n{3}",
                                                               ti.Index.Level, ti.Index.Col, ti.Index.Row, ex.Message, i));
                    }
                    catch (WebException ex)
                    {
                        if (ti == null)
                        {
                            System.Diagnostics.Trace.WriteLine("No tile info!");
                        }
                        else
                        {
                            System.Diagnostics.Trace.WriteLine(string.Format(
                                                                   "TileInfo({5}): {0}, {1}, {2}\n{3}\n{4}",
                                                                   ti.Index.Level, ti.Index.Col, ti.Index.Row,
                                                                   ex.Message, ex.Response.ResponseUri, i));
                        }
                    }
                }
            }

            message = "Tile providers appear to be equal";
            return(true);
        }
Пример #12
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="cancelToken"></param>
        /// <param name="tileProvider"></param>
        /// <param name="tileInfo"></param>
        /// <param name="bitmaps"></param>
        /// <param name="retry"></param>
        /// <returns>true if thread finished without getting cancellation signal, false = cancelled</returns>
        private bool GetTileOnThread(CancellationToken cancelToken, ITileProvider tileProvider, TileInfo tileInfo, MemoryCache <Bitmap> bitmaps, bool retry)
        {
            byte[] bytes;
            try
            {
                if (cancelToken.IsCancellationRequested)
                {
                    cancelToken.ThrowIfCancellationRequested();
                }


                //We may have gotten the tile from another thread now..
                if (bitmaps.Find(tileInfo.Index) != null)
                {
                    return(true);
                }

                if (Logger.IsDebugEnabled)
                {
                    Logger.DebugFormat("Calling gettile on provider for tile {0},{1},{2}", tileInfo.Index.Level, tileInfo.Index.Col, tileInfo.Index.Row);
                }

                bytes = tileProvider.GetTile(tileInfo);
                if (cancelToken.IsCancellationRequested)
                {
                    cancelToken.ThrowIfCancellationRequested();
                }

                using (var ms = new MemoryStream(bytes))
                {
                    Bitmap bitmap = new Bitmap(ms);
                    bitmaps.Add(tileInfo.Index, bitmap);
                    if (_fileCache != null && !_fileCache.Exists(tileInfo.Index))
                    {
                        AddImageToFileCache(tileInfo, bitmap);
                    }


                    if (cancelToken.IsCancellationRequested)
                    {
                        cancelToken.ThrowIfCancellationRequested();
                    }
                    OnMapNewTileAvaliable(tileInfo, bitmap);
                }
                return(true);
            }
            catch (WebException ex)
            {
                if (Logger.IsDebugEnabled)
                {
                    Logger.DebugFormat("Exception downloading tile {0},{1},{2} {3}", tileInfo.Index.Level, tileInfo.Index.Col, tileInfo.Index.Row, ex.Message);
                }

                if (retry)
                {
                    return(GetTileOnThread(cancelToken, tileProvider, tileInfo, bitmaps, false));
                }
                else
                {
                    if (_showErrorInTile)
                    {
                        var tileWidth  = _source.Schema.GetTileWidth(tileInfo.Index.Level);
                        var tileHeight = _source.Schema.GetTileHeight(tileInfo.Index.Level);
                        //an issue with this method is that one an error tile is in the memory cache it will stay even
                        //if the error is resolved. PDD.
                        var bitmap = new Bitmap(tileWidth, tileHeight);
                        using (var graphics = Graphics.FromImage(bitmap))
                        {
                            graphics.DrawString(ex.Message, new Font(FontFamily.GenericSansSerif, 12), new SolidBrush(Color.Black),
                                                new RectangleF(0, 0, tileWidth, tileHeight));
                        }
                        //Draw the Timeout Tile
                        OnMapNewTileAvaliable(tileInfo, bitmap);
                        //With timeout we don't add to the internal cache
                        //bitmaps.Add(tileInfo.Index, bitmap);
                    }
                    return(true);
                }
            }
            catch (System.OperationCanceledException tex)
            {
                if (Logger.IsInfoEnabled)
                {
                    Logger.InfoFormat("TileAsyncLayer - Thread aborting: {0}", Thread.CurrentThread.Name);
                    Logger.InfoFormat(tex.Message);
                }
                return(false);
            }
            catch (Exception ex)
            {
                Logger.Warn("TileAsyncLayer - GetTileOnThread Exception", ex);
                //This is not due to cancellation so return true
                return(true);
            }
        }
Пример #13
0
        private void GetTileOnThread(CancellationToken cancelToken, ITileProvider tileProvider, TileInfo tileInfo, MemoryCache <Bitmap> bitmaps, bool retry)
        {
            byte[] bytes;
            try
            {
                if (cancelToken.IsCancellationRequested)
                {
                    cancelToken.ThrowIfCancellationRequested();
                }

                bytes = tileProvider.GetTile(tileInfo);
                if (cancelToken.IsCancellationRequested)
                {
                    cancelToken.ThrowIfCancellationRequested();
                }

                Bitmap bitmap = new Bitmap(new MemoryStream(bytes));
                bitmaps.Add(tileInfo.Index, bitmap);
                if (_fileCache != null && !_fileCache.Exists(tileInfo.Index))
                {
                    AddImageToFileCache(tileInfo, bitmap);
                }

                if (cancelToken.IsCancellationRequested)
                {
                    cancelToken.ThrowIfCancellationRequested();
                }
                OnMapNewTileAvaliable(tileInfo, bitmap);
            }
            catch (WebException ex)
            {
                if (retry)
                {
                    GetTileOnThread(cancelToken, tileProvider, tileInfo, bitmaps, false);
                }
                else
                {
                    if (_showErrorInTile)
                    {
                        //an issue with this method is that one an error tile is in the memory cache it will stay even
                        //if the error is resolved. PDD.
                        var bitmap = new Bitmap(_source.Schema.Width, _source.Schema.Height);
                        using (var graphics = Graphics.FromImage(bitmap))
                        {
                            graphics.DrawString(ex.Message, new Font(FontFamily.GenericSansSerif, 12), new SolidBrush(Color.Black),
                                                new RectangleF(0, 0, _source.Schema.Width, _source.Schema.Height));
                        }
                        //Draw the Timeout Tile
                        OnMapNewTileAvaliable(tileInfo, bitmap);

                        //With timeout we don't add to the internal cache
                        //bitmaps.Add(tileInfo.Index, bitmap);
                    }
                }
            }
            catch (ThreadAbortException tex)
            {
                if (Logger.IsInfoEnabled)
                {
                    Logger.InfoFormat("TileAsyncLayer - Thread aborting: {0}", Thread.CurrentThread.Name);
                    Logger.InfoFormat(tex.Message);
                }
            }
            catch (Exception ex)
            {
                Logger.Warn("TileAsyncLayer - GetTileOnThread Exception", ex);
            }
        }
Пример #14
0
        private void GetTileOnThread(CancellationToken cancelToken, ITileProvider tileProvider, TileInfo tileInfo, MemoryCache<Bitmap> bitmaps, bool retry)
        {
            byte[] bytes;
            try
            {
                if (cancelToken.IsCancellationRequested)
                    cancelToken.ThrowIfCancellationRequested();

                bytes = tileProvider.GetTile(tileInfo);
                if (cancelToken.IsCancellationRequested)
                    cancelToken.ThrowIfCancellationRequested();

                Bitmap bitmap = new Bitmap(new MemoryStream(bytes));
                bitmaps.Add(tileInfo.Index, bitmap);
                if (_fileCache != null && !_fileCache.Exists(tileInfo.Index))
                {
                    AddImageToFileCache(tileInfo, bitmap);
                }

                if (cancelToken.IsCancellationRequested)
                    cancelToken.ThrowIfCancellationRequested();
                OnMapNewTileAvaliable(tileInfo, bitmap);
            }
            catch (WebException ex)
            {
                if (retry)
                {
                    GetTileOnThread(cancelToken, tileProvider, tileInfo, bitmaps, false);
                }
                else
                {
                    if (_showErrorInTile)
                    {
                        //an issue with this method is that one an error tile is in the memory cache it will stay even
                        //if the error is resolved. PDD.
                        var bitmap = new Bitmap(_source.Schema.Width, _source.Schema.Height);
                        using (var graphics = Graphics.FromImage(bitmap))
                        {
                            graphics.DrawString(ex.Message, new Font(FontFamily.GenericSansSerif, 12), new SolidBrush(Color.Black),
                                new RectangleF(0, 0, _source.Schema.Width, _source.Schema.Height));
                        }
                        //Draw the Timeout Tile
                        OnMapNewTileAvaliable(tileInfo, bitmap);

                        //With timeout we don't add to the internal cache
                        //bitmaps.Add(tileInfo.Index, bitmap);
                    }
                }
            }
            catch (ThreadAbortException tex)
            {
                if (Logger.IsInfoEnabled)
                {
                    Logger.InfoFormat("TileAsyncLayer - Thread aborting: {0}", Thread.CurrentThread.Name);
                    Logger.InfoFormat(tex.Message);
                }
            }
            catch (Exception ex)
            {
                Logger.Warn("TileAsyncLayer - GetTileOnThread Exception", ex);
            }
        }
Пример #15
0
        /*
         * private void OnMapNewtileAvailableHelper(object parameter)
         * {
         *  //this is to wait for the main UI thread to finalize rendering ... (buggy code here)...
         *  System.Threading.Thread.Sleep(100);
         *  object[] parameters = (object[])parameter;
         *  if (parameters.Length != 2) throw new ArgumentException("Two parameters expected");
         *  TileInfo tileInfo = (TileInfo)parameters[0];
         *  Bitmap bm = (Bitmap)parameters[1];
         *  OnMapNewTileAvaliable(tileInfo, bm);
         * }
         */

        private void GetTileOnThread(BackgroundWorker worker, object parameter)
        {
            Thread.Sleep(50 + (_r.Next(5) * 10));
            object[] parameters = (object[])parameter;
            if (parameters.Length != 4)
            {
                throw new ArgumentException("Four parameters expected");
            }
            ITileProvider        tileProvider = (ITileProvider)parameters[0];
            TileInfo             tileInfo     = (TileInfo)parameters[1];
            MemoryCache <Bitmap> bitmaps      = (MemoryCache <Bitmap>)parameters[2];
            bool retry = (bool)parameters[3];


            byte[] bytes;
            try
            {
                if (worker.CancellationPending)
                {
                    return;
                }
                bytes = tileProvider.GetTile(tileInfo);
                if (worker.CancellationPending)
                {
                    return;
                }
                Bitmap bitmap = new Bitmap(new MemoryStream(bytes));
                bitmaps.Add(tileInfo.Index, bitmap);
                if (_fileCache != null && !_fileCache.Exists(tileInfo.Index))
                {
                    AddImageToFileCache(tileInfo, bitmap);
                }

                if (worker.CancellationPending)
                {
                    return;
                }
                OnMapNewTileAvaliable(tileInfo, bitmap);
                //if (worker.CancellationPending)
                //    return;
            }
            catch (WebException ex)
            {
                if (retry)
                {
                    parameters[3] = false;
                    GetTileOnThread(worker, parameters);
                }
                else
                {
                    if (_showErrorInTile)
                    {
                        //an issue with this method is that one an error tile is in the memory cache it will stay even
                        //if the error is resolved. PDD.
                        var bitmap = new Bitmap(_source.Schema.Width, _source.Schema.Height);
                        using (var graphics = Graphics.FromImage(bitmap))
                        {
                            graphics.DrawString(ex.Message, new Font(FontFamily.GenericSansSerif, 12), new SolidBrush(Color.Black),
                                                new RectangleF(0, 0, _source.Schema.Width, _source.Schema.Height));
                        }
                        //Draw the Timeout Tile
                        OnMapNewTileAvaliable(tileInfo, bitmap);

                        //With timeout we don't add to the internal cache
                        //bitmaps.Add(tileInfo.Index, bitmap);
                    }
                }
            }
            catch (ThreadAbortException tex)
            {
                if (Logger.IsInfoEnabled)
                {
                    Logger.InfoFormat("TileAsyncLayer - Thread aborting: {0}", Thread.CurrentThread.Name);
                    Logger.InfoFormat(tex.Message);
                }
            }
            catch (Exception ex)
            {
                Logger.Warn("TileAsyncLayer - GetTileOnThread Exception", ex);
            }
        }
Пример #16
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="cancelToken"></param>
        /// <param name="tileProvider"></param>
        /// <param name="tileInfo"></param>
        /// <param name="bitmaps"></param>
        /// <param name="retry"></param>
        /// <returns>true if thread finished without getting cancellation signal, false = cancelled</returns>
        private bool GetTileOnThread(CancellationToken cancelToken, ITileProvider tileProvider, TileInfo tileInfo, MemoryCache<Bitmap> bitmaps, bool retry)
        {
            byte[] bytes;
            try
            {
                if (cancelToken.IsCancellationRequested)
                    cancelToken.ThrowIfCancellationRequested();


                //We may have gotten the tile from another thread now..
                if (bitmaps.Find(tileInfo.Index) != null)
                {
                    return true;
                }

                if (Logger.IsDebugEnabled)
                    Logger.DebugFormat("Calling gettile on provider for tile {0},{1},{2}", tileInfo.Index.Level, tileInfo.Index.Col, tileInfo.Index.Row);

                bytes = tileProvider.GetTile(tileInfo);
                if (cancelToken.IsCancellationRequested)
                    cancelToken.ThrowIfCancellationRequested();

                using (var ms = new MemoryStream(bytes))
                {
                    Bitmap bitmap = new Bitmap(ms);
                    bitmaps.Add(tileInfo.Index, bitmap);
                    if (_fileCache != null && !_fileCache.Exists(tileInfo.Index))
                    {
                        AddImageToFileCache(tileInfo, bitmap);
                    }


                    if (cancelToken.IsCancellationRequested)
                        cancelToken.ThrowIfCancellationRequested();
                    OnMapNewTileAvaliable(tileInfo, bitmap);
                }
                return true;
            }
            catch (WebException ex)
            {
                if (Logger.IsDebugEnabled)
                    Logger.DebugFormat("Exception downloading tile {0},{1},{2} {3}", tileInfo.Index.Level, tileInfo.Index.Col, tileInfo.Index.Row, ex.Message);
                
                if (retry)
                {
                    return GetTileOnThread(cancelToken, tileProvider, tileInfo, bitmaps, false);
                }
                else
                {
                    if (_showErrorInTile)
                    {
                        var tileWidth = _source.Schema.GetTileWidth(tileInfo.Index.Level);
                        var tileHeight = _source.Schema.GetTileHeight(tileInfo.Index.Level);
                        //an issue with this method is that one an error tile is in the memory cache it will stay even
                        //if the error is resolved. PDD.
                        var bitmap = new Bitmap(tileWidth, tileHeight);
                        using (var graphics = Graphics.FromImage(bitmap))
                        {
                            graphics.DrawString(ex.Message, new Font(FontFamily.GenericSansSerif, 12), new SolidBrush(Color.Black),
                                new RectangleF(0, 0, tileWidth, tileHeight));
                        }
                        //Draw the Timeout Tile
                        OnMapNewTileAvaliable(tileInfo, bitmap);
                        //With timeout we don't add to the internal cache
                        //bitmaps.Add(tileInfo.Index, bitmap);
                    }
                    return true;
                }
            }
            catch (System.OperationCanceledException tex)
            {
                if (Logger.IsInfoEnabled)
                {
                    Logger.InfoFormat("TileAsyncLayer - Thread aborting: {0}", Thread.CurrentThread.Name);
                    Logger.InfoFormat(tex.Message);
                }
                return false;
            }
            catch (Exception ex)
            {
                Logger.Warn("TileAsyncLayer - GetTileOnThread Exception", ex);
                //This is not due to cancellation so return true
                return true;
            }
        }
Пример #17
0
        /// <summary>
        /// Method to actually get the tile from the <see cref="_provider"/>.
        /// </summary>
        /// <param name="parameter">The parameter, usually a <see cref="TileInfo"/> and a <see cref="AutoResetEvent"/></param>
        private void GetTileOnThread(object parameter)
        {
            var @params  = (object[])parameter;
            var tileInfo = (TileInfo)@params[0];

            byte[] result = null;

            //Try get the tile
            try
            {
                _openTileRequests.TryAdd(tileInfo.Index, 1);
                result = _provider.GetTile(tileInfo);
            }
// ReSharper disable once EmptyGeneralCatchClause
            catch
            {
            }

            //Try at least once again
            if (result == null)
            {
                try
                {
                    result = _provider.GetTile(tileInfo);
                }
                catch
                {
                    if (!AsyncMode)
                    {
                        var are = (AutoResetEvent)@params[1];
                        are.Set();
                    }
                }
            }

            //Remove the tile info request
            int one;

            if (!_activeTileRequests.TryRemove(tileInfo.Index, out one))
            {
                //try again
                _activeTileRequests.TryRemove(tileInfo.Index, out one);
            }
            if (!_openTileRequests.TryRemove(tileInfo.Index, out one))
            {
                //try again
                _openTileRequests.TryRemove(tileInfo.Index, out one);
            }


            if (result != null)
            {
                //Add to the volatile cache
                _volatileCache.Add(tileInfo.Index, result);
                //Add to the perma cache
                _permaCache.Add(tileInfo.Index, result);

                if (AsyncMode)
                {
                    //Raise the event
                    OnTileReceived(new TileReceivedEventArgs(tileInfo, result));
                }
                else
                {
                    var are = (AutoResetEvent)@params[1];
                    are.Set();
                }
            }
        }
Пример #18
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="cancelToken"></param>
        /// <param name="tileProvider"></param>
        /// <param name="tileInfo"></param>
        /// <param name="bitmaps"></param>
        /// <param name="retry"></param>
        /// <returns><c>true</c> if task finished without getting a cancellation signal, otherwise <c>false</c></returns>
        private bool GetTileOnThread(CancellationToken cancelToken, ITileProvider tileProvider, TileInfo tileInfo, ITileCache <Bitmap> bitmaps, bool retry)
        {
            try
            {
                if (cancelToken.IsCancellationRequested)
                {
                    cancelToken.ThrowIfCancellationRequested();
                }

                //We may have gotten the tile from another thread now.
                if (bitmaps.Find(tileInfo.Index) != null)
                {
                    return(true);
                }

                if (Logger.IsDebugEnabled)
                {
                    Logger.DebugFormat("Calling ITileProvider.GetTile for tile {0},{1},{2}", tileInfo.Index.Level, tileInfo.Index.Col, tileInfo.Index.Row);
                }

                byte[] bytes = tileProvider.GetTile(tileInfo);
                if (bytes == null)
                {
                    return(true);
                }

                if (cancelToken.IsCancellationRequested)
                {
                    cancelToken.ThrowIfCancellationRequested();
                }

                using (var ms = new MemoryStream(bytes))
                {
                    var bitmap = new Bitmap(ms);
                    bitmaps.Add(tileInfo.Index, bitmap);
                    if (_fileCache != null && !_fileCache.Exists(tileInfo.Index))
                    {
                        AddImageToFileCache(tileInfo, bitmap);
                    }

                    if (cancelToken.IsCancellationRequested)
                    {
                        cancelToken.ThrowIfCancellationRequested();
                    }

                    OnMapNewTileAvailable(tileInfo, bitmap);
                }
                return(true);
            }
            catch (WebException ex)
            {
                if (Logger.IsDebugEnabled)
                {
                    Logger.DebugFormat("Exception downloading tile {0},{1},{2} {3}", tileInfo.Index.Level, tileInfo.Index.Col, tileInfo.Index.Row, ex.Message);
                }

                if (retry)
                {
                    return(GetTileOnThread(cancelToken, tileProvider, tileInfo, bitmaps, false));
                }

                if (!_showErrorInTile)
                {
                    var index = tileInfo.Index;
                    Logger.Debug(fmh => fmh("Failed to get tile ({0},{1},{2}), returning true anyway", index.Level, index.Col, index.Row));
                    return(true);
                }

                // create the timeout tile
                int tileWidth  = _source.Schema.GetTileWidth(tileInfo.Index.Level);
                int tileHeight = _source.Schema.GetTileHeight(tileInfo.Index.Level);
                var bitmap     = new Bitmap(tileWidth, tileHeight);
                using (var graphics = Graphics.FromImage(bitmap))
                {
                    graphics.DrawString(ex.Message, new Font(FontFamily.GenericSansSerif, 12), new SolidBrush(Color.Black),
                                        new RectangleF(0, 0, tileWidth, tileHeight));
                }

                //Draw the Timeout Tile
                OnMapNewTileAvailable(tileInfo, bitmap);
                return(true);
            }
            catch (OperationCanceledException tex)
            {
                if (Logger.IsInfoEnabled)
                {
                    Logger.InfoFormat("TileAsyncLayer - Thread aborting: {0}", Thread.CurrentThread.Name);
                    Logger.InfoFormat(tex.Message);
                }
                return(false);
            }
            catch (Exception ex)
            {
                Logger.Warn("TileAsyncLayer - GetTileOnThread Exception", ex);
                //This is not due to cancellation so return true
                return(true);
            }
        }