Пример #1
0
        public void TileFetcherWithFailingFetchesShouldTryAgain()
        {
            // Arrange
            var tileProvider    = new FailingTileProvider();
            var tileSchema      = new GlobalSphericalMercator();
            var tileSource      = new TileSource(tileProvider, tileSchema);
            var cache           = new MemoryCache <Feature>();
            var fetchDispatcher = new TileFetchDispatcher(cache, tileSource.Schema, (tileInfo) => TileToFeature(tileSource, tileInfo));
            var tileMachine     = new FetchMachine(fetchDispatcher);
            var level           = "3";
            var tilesInLevel    = 64;

            // Act
            fetchDispatcher.SetViewport(tileSchema.Extent.ToBoundingBox(), tileSchema.Resolutions[level].UnitsPerPixel);
            tileMachine.Start();
            while (fetchDispatcher.Busy)
            {
            }
            // do it again
            fetchDispatcher.SetViewport(tileSchema.Extent.ToBoundingBox(), tileSchema.Resolutions[level].UnitsPerPixel);
            tileMachine.Start();
            while (fetchDispatcher.Busy)
            {
            }

            // Assert
            Assert.AreEqual(tilesInLevel * 2, tileProvider.TotalCount); // tried all tiles twice
        }
Пример #2
0
        public void TileFetcherShouldRequestAllTilesJustOnes()
        {
            // Arrange
            var tileProvider    = new CountingTileProvider();
            var tileSchema      = new GlobalSphericalMercator();
            var tileSource      = new TileSource(tileProvider, tileSchema);
            var cache           = new MemoryCache <Feature>();
            var fetchDispatcher = new TileFetchDispatcher(cache, tileSource.Schema, (tileInfo) => TileToFeature(tileSource, tileInfo));
            var tileMachine     = new FetchMachine(fetchDispatcher);
            var level           = "4";
            var expextedTiles   = 256;

            // Act
            // Get all tiles of level 3
            fetchDispatcher.SetViewport(tileSchema.Extent.ToBoundingBox(), tileSchema.Resolutions[level].UnitsPerPixel);
            tileMachine.Start();
            // Assert
            while (fetchDispatcher.Busy)
            {
            }

            Assert.AreEqual(expextedTiles, tileProvider.CountByTile.Keys.Count);
            Assert.AreEqual(expextedTiles, tileProvider.CountByTile.Values.Sum());
            Assert.AreEqual(expextedTiles, tileProvider.TotalCount);
        }
Пример #3
0
        public void TileRequestThatReturnsNullShouldNotBeRequestedAgain()
        {
            // Arrange
            var tileProvider    = new NullTileProvider();
            var tileSchema      = new GlobalSphericalMercator();
            var tileSource      = new TileSource(tileProvider, tileSchema);
            var cache           = new MemoryCache <Feature>();
            var fetchDispatcher = new TileFetchDispatcher(cache, tileSource.Schema, (tileInfo) => TileToFeature(tileSource, tileInfo));
            var tileMachine     = new FetchMachine(fetchDispatcher);
            var level           = "3";
            var tilesInLevel    = 64;

            // Act
            fetchDispatcher.SetViewport(tileSchema.Extent.ToBoundingBox(), tileSchema.Resolutions[level].UnitsPerPixel);
            tileMachine.Start();
            while (fetchDispatcher.Busy)
            {
            }
            // do it again
            fetchDispatcher.SetViewport(tileSchema.Extent.ToBoundingBox(), tileSchema.Resolutions[level].UnitsPerPixel);
            tileMachine.Start();
            while (fetchDispatcher.Busy)
            {
                Thread.Sleep(1);
            }

            // Assert
            Assert.AreEqual(tilesInLevel, tileProvider.TotalCount);
        }
Пример #4
0
        public void TileFetcherShouldRequestAllTilesJustOnes()
        {
            // Arrange
            var tileProvider = new CountingTileProvider();
            var tileSchema   = new GlobalSphericalMercator();
            var tileSource   = new TileSource(tileProvider, tileSchema);

            using var cache = new MemoryCache <IFeature?>();
            var fetchDispatcher = new TileFetchDispatcher(cache, tileSource.Schema, async tileInfo => await TileToFeatureAsync(tileSource, tileInfo));
            var tileMachine     = new FetchMachine(fetchDispatcher);
            var level           = 3;
            var expectedTiles   = 64;

            var fetchInfo = new FetchInfo(tileSchema.Extent.ToMRect(), tileSchema.Resolutions[level].UnitsPerPixel);

            // Act
            // Get all tiles of level 3
            fetchDispatcher.SetViewport(fetchInfo);
            tileMachine.Start();
            // Assert
            while (fetchDispatcher.Busy)
            {
                Thread.Sleep(1);
            }

            Assert.AreEqual(expectedTiles, tileProvider.CountByTile.Keys.Count);
            Assert.AreEqual(expectedTiles, tileProvider.CountByTile.Values.Sum());
            Assert.AreEqual(expectedTiles, tileProvider.TotalCount);
        }
Пример #5
0
        public void RepeatedRestartsShouldNotCauseInfiniteLoop()
        {
            // Arrange
            var tileProvider     = new CountingTileProvider();
            var tileSchema       = new GlobalSphericalMercator();
            var tileSource       = new TileSource(tileProvider, tileSchema);
            var cache            = new MemoryCache <Feature>();
            var fetchDispatcher  = new TileFetchDispatcher(cache, tileSource.Schema, (tileInfo) => TileToFeature(tileSource, tileInfo));
            var tileMachine      = new FetchMachine(fetchDispatcher);
            var numberOfWorkers  = 8;
            var numberOfRestarts = 3;

            // Act
            for (int i = 0; i < numberOfRestarts; i++)
            {
                fetchDispatcher.SetViewport(tileSchema.Extent.ToBoundingBox(), tileSchema.Resolutions["3"].UnitsPerPixel);
                tileMachine.Start();
                while (fetchDispatcher.Busy)
                {
                }
            }

            // Assert
            Assert.Greater(numberOfWorkers * numberOfRestarts, FetchWorker.RestartCounter);
        }
Пример #6
0
 /// <summary>
 /// Create tile layer for given tile source
 /// </summary>
 /// <param name="source">Tile source to use for this layer</param>
 /// <param name="minTiles">Minimum number of tiles to cache</param>
 /// <param name="maxTiles">Maximum number of tiles to cache</param>
 /// <param name="maxRetries">Unused</param>
 /// <param name="dataFetchStrategy">Strategy to get list of tiles for given extent</param>
 /// <param name="renderFetchStrategy"></param>
 /// <param name="minExtraTiles">Number of minimum extra tiles for memory cache</param>
 /// <param name="maxExtraTiles">Number of maximum extra tiles for memory cache</param>
 // ReSharper disable once UnusedParameter.Local // Is public and won't break this now
 public TileLayer(ITileSource source = null, int minTiles = 200, int maxTiles = 300,
                  IDataFetchStrategy dataFetchStrategy = null, IRenderFetchStrategy renderFetchStrategy = null,
                  int minExtraTiles = -1, int maxExtraTiles = -1, Func <TileInfo, Feature> fetchTileAsFeature = null)
 {
     MemoryCache = new MemoryCache <Feature>(minTiles, maxTiles);
     Style       = new VectorStyle {
         Outline = { Color = Color.FromArgb(0, 0, 0, 0) }
     };                                                                            // initialize with transparent outline
     _tileSource = source;
     if (_tileSource != null)
     {
         if (Attribution == null)
         {
             Attribution = new Hyperlink();
         }
         Attribution.Text = _tileSource.Attribution?.Text;
         Attribution.Url  = _tileSource.Attribution?.Url;
     }
     _envelope                             = _tileSource?.Schema?.Extent.ToBoundingBox();
     dataFetchStrategy                     = dataFetchStrategy ?? new DataFetchStrategy(3);
     _renderFetchStrategy                  = renderFetchStrategy ?? new RenderFetchStrategy();
     _minExtraTiles                        = minExtraTiles;
     _maxExtraTiles                        = maxExtraTiles;
     _tileFetchDispatcher                  = new TileFetchDispatcher(MemoryCache, source.Schema, fetchTileAsFeature ?? ToFeature, dataFetchStrategy);
     _tileFetchDispatcher.DataChanged     += TileFetchDispatcherOnDataChanged;
     _tileFetchDispatcher.PropertyChanged += TileFetchDispatcherOnPropertyChanged;
 }
Пример #7
0
        public void RepeatedRestartsShouldNotCauseInfiniteLoop()
        {
            // Arrange
            var tileProvider = new CountingTileProvider();
            var tileSchema   = new GlobalSphericalMercator();
            var tileSource   = new TileSource(tileProvider, tileSchema);

            using var cache = new MemoryCache <IFeature?>();
            var fetchDispatcher  = new TileFetchDispatcher(cache, tileSource.Schema, async tileInfo => await TileToFeatureAsync(tileSource, tileInfo));
            var tileMachine      = new FetchMachine(fetchDispatcher);
            var numberOfWorkers  = 8;
            var numberOfRestarts = 3;
            var fetchInfo        = new FetchInfo(tileSchema.Extent.ToMRect(), tileSchema.Resolutions[3].UnitsPerPixel);

            // Act
            for (var i = 0; i < numberOfRestarts; i++)
            {
                fetchDispatcher.SetViewport(fetchInfo);
                tileMachine.Start();
                while (fetchDispatcher.Busy)
                {
                    Thread.Sleep(1);
                }
            }

            // Assert
            Assert.Greater(numberOfWorkers * numberOfRestarts, FetchWorker.RestartCounter);
        }
Пример #8
0
        public void TileFetcherWithFailingFetchesShouldTryAgain()
        {
            // Arrange
            var tileProvider = new FailingTileProvider();
            var tileSchema   = new GlobalSphericalMercator();
            var tileSource   = new TileSource(tileProvider, tileSchema);

            using var cache = new MemoryCache <IFeature?>();
            var fetchDispatcher = new TileFetchDispatcher(cache, tileSource.Schema, async tileInfo => await TileToFeatureAsync(tileSource, tileInfo));
            var tileMachine     = new FetchMachine(fetchDispatcher);
            var level           = 3;
            var tilesInLevel    = 64;
            var fetchInfo       = new FetchInfo(tileSchema.Extent.ToMRect(), tileSchema.Resolutions[level].UnitsPerPixel);

            // Act
            fetchDispatcher.SetViewport(fetchInfo);
            tileMachine.Start();
            while (fetchDispatcher.Busy)
            {
                Thread.Sleep(1);
            }

            // Act again
            fetchDispatcher.SetViewport(fetchInfo);
            tileMachine.Start();
            while (fetchDispatcher.Busy)
            {
                Thread.Sleep(1);
            }

            // Assert
            Assert.AreEqual(tilesInLevel * 2, tileProvider.TotalCount); // tried all tiles twice
        }
Пример #9
0
 /// <summary>
 /// Create tile layer for given tile source
 /// </summary>
 /// <param name="source">Tile source to use for this layer</param>
 /// <param name="minTiles">Minimum number of tiles to cache</param>
 /// <param name="maxTiles">Maximum number of tiles to cache</param>
 /// <param name="maxRetries">Unused</param>
 /// <param name="fetchStrategy">Strategy to get list of tiles for given extent</param>
 /// <param name="renderFetchStrategy"></param>
 /// <param name="minExtraTiles">Number of minimum extra tiles for memory cache</param>
 /// <param name="maxExtraTiles">Number of maximum extra tiles for memory cache</param>
 // ReSharper disable once UnusedParameter.Local // Is public and won't break this now
 public TileLayer(ITileSource source = null, int minTiles = 200, int maxTiles = 300, int maxRetries = 2, IFetchStrategy fetchStrategy = null,
     IRenderGetStrategy renderFetchStrategy = null, int minExtraTiles = -1, int maxExtraTiles = -1)
 {
     MemoryCache = new MemoryCache<Feature>(minTiles, maxTiles);
     Style = new VectorStyle { Outline = { Color = Color.FromArgb(0, 0, 0, 0) } }; // initialize with transparent outline
     var fetchStrategy1 = fetchStrategy ?? new FetchStrategy(3);
     _renderStrategy = renderFetchStrategy ?? new RenderGetStrategy();
     _minExtraTiles = minExtraTiles;
     _maxExtraTiles = maxExtraTiles;
     _tileFetchDispatcher = new TileFetchDispatcher(MemoryCache, fetchStrategy1);
     _tileFetchDispatcher.DataChanged += TileFetchDispatcherOnDataChanged;
     _tileFetchDispatcher.PropertyChanged += TileFetchDispatcherOnPropertyChanged;
     _fetchMachine = new FetchMachine(_tileFetchDispatcher);
     SetTileSource(source);
 }
Пример #10
0
 /// <summary>
 /// Create tile layer for given tile source
 /// </summary>
 /// <param name="tileSource">Tile source to use for this layer</param>
 /// <param name="minTiles">Minimum number of tiles to cache</param>
 /// <param name="maxTiles">Maximum number of tiles to cache</param>
 /// <param name="dataFetchStrategy">Strategy to get list of tiles for given extent</param>
 /// <param name="renderFetchStrategy"></param>
 /// <param name="minExtraTiles">Number of minimum extra tiles for memory cache</param>
 /// <param name="maxExtraTiles">Number of maximum extra tiles for memory cache</param>
 /// <param name="fetchTileAsFeature">Fetch tile as feature</param>
 // ReSharper disable once UnusedParameter.Local // Is public and won't break this now
 public TileLayer(ITileSource tileSource, int minTiles = 200, int maxTiles = 300,
                  IDataFetchStrategy?dataFetchStrategy = null, IRenderFetchStrategy?renderFetchStrategy = null,
                  int minExtraTiles = -1, int maxExtraTiles = -1, Func <TileInfo, Task <IFeature?> >?fetchTileAsFeature = null)
 {
     _tileSource      = tileSource ?? throw new ArgumentException($"{tileSource} can not null");
     MemoryCache      = new MemoryCache <IFeature?>(minTiles, maxTiles);
     Style            = new RasterStyle();
     Attribution.Text = _tileSource.Attribution?.Text;
     Attribution.Url  = _tileSource.Attribution?.Url;
     _extent          = _tileSource.Schema?.Extent.ToMRect();
     dataFetchStrategy ??= new DataFetchStrategy(3);
     _renderFetchStrategy                  = renderFetchStrategy ?? new RenderFetchStrategy();
     _minExtraTiles                        = minExtraTiles;
     _maxExtraTiles                        = maxExtraTiles;
     _tileFetchDispatcher                  = new TileFetchDispatcher(MemoryCache, _tileSource.Schema, fetchTileAsFeature ?? ToFeatureAsync, dataFetchStrategy);
     _tileFetchDispatcher.DataChanged     += TileFetchDispatcherOnDataChanged;
     _tileFetchDispatcher.PropertyChanged += TileFetchDispatcherOnPropertyChanged;
 }
Пример #11
0
 /// <summary>
 /// Create tile layer for given tile source
 /// </summary>
 /// <param name="source">Tile source to use for this layer</param>
 /// <param name="minTiles">Minimum number of tiles to cache</param>
 /// <param name="maxTiles">Maximum number of tiles to cache</param>
 /// <param name="maxRetries">Unused</param>
 /// <param name="fetchStrategy">Strategy to get list of tiles for given extent</param>
 /// <param name="renderGetStrategy"></param>
 /// <param name="minExtraTiles">Number of minimum extra tiles for memory cache</param>
 /// <param name="maxExtraTiles">Number of maximum extra tiles for memory cache</param>
 // ReSharper disable once UnusedParameter.Local // Is public and won't break this now
 public TileLayer(ITileSource source           = null, int minTiles = 200, int maxTiles = 300,
                  IFetchStrategy fetchStrategy = null, IRenderGetStrategy renderGetStrategy = null,
                  int minExtraTiles            = -1, int maxExtraTiles = -1, Func <TileInfo, Feature> fetchTileAsFeature = null)
 {
     MemoryCache = new MemoryCache <Feature>(minTiles, maxTiles);
     Style       = new VectorStyle {
         Outline = { Color = Color.FromArgb(0, 0, 0, 0) }
     };                                                                            // initialize with transparent outline
     _tileSource                           = source;
     _envelope                             = _tileSource?.Schema?.Extent.ToBoundingBox();
     fetchStrategy                         = fetchStrategy ?? new FetchStrategy(3);
     _renderGetStrategy                    = renderGetStrategy ?? new RenderGetStrategy();
     _minExtraTiles                        = minExtraTiles;
     _maxExtraTiles                        = maxExtraTiles;
     _tileFetchDispatcher                  = new TileFetchDispatcher(MemoryCache, source.Schema, fetchTileAsFeature ?? ToFeature, fetchStrategy);
     _tileFetchDispatcher.DataChanged     += TileFetchDispatcherOnDataChanged;
     _tileFetchDispatcher.PropertyChanged += TileFetchDispatcherOnPropertyChanged;
 }
Пример #12
0
 /// <summary>
 /// Create tile layer for given tile source
 /// </summary>
 /// <param name="tileSource">Tile source to use for this layer</param>
 /// <param name="minTiles">Minimum number of tiles to cache</param>
 /// <param name="maxTiles">Maximum number of tiles to cache</param>
 /// <param name="dataFetchStrategy">Strategy to get list of tiles for given extent</param>
 /// <param name="renderFetchStrategy"></param>
 /// <param name="minExtraTiles">Number of minimum extra tiles for memory cache</param>
 /// <param name="maxExtraTiles">Number of maximum extra tiles for memory cache</param>
 /// <param name="fetchTileAsFeature">Fetch tile as feature</param>
 // ReSharper disable once UnusedParameter.Local // Is public and won't break this now
 public TileLayer(ITileSource tileSource, int minTiles = 200, int maxTiles = 300,
                  IDataFetchStrategy?dataFetchStrategy = null, IRenderFetchStrategy?renderFetchStrategy = null,
                  int minExtraTiles = -1, int maxExtraTiles = -1, Func <TileInfo, IFeature?>?fetchTileAsFeature = null)
 {
     _tileSource = tileSource ?? throw new ArgumentException($"{tileSource} can not null");
     MemoryCache = new MemoryCache <IFeature?>(minTiles, maxTiles);
     Style       = new VectorStyle {
         Outline = { Color = Color.FromArgb(0, 0, 0, 0) }
     };                                                                            // initialize with transparent outline
     Attribution.Text = _tileSource.Attribution?.Text;
     Attribution.Url  = _tileSource.Attribution?.Url;
     _extent          = _tileSource.Schema?.Extent.ToMRect();
     dataFetchStrategy ??= new DataFetchStrategy(3);
     _renderFetchStrategy                  = renderFetchStrategy ?? new RenderFetchStrategy();
     _minExtraTiles                        = minExtraTiles;
     _maxExtraTiles                        = maxExtraTiles;
     _tileFetchDispatcher                  = new TileFetchDispatcher(MemoryCache, _tileSource.Schema, fetchTileAsFeature ?? ToFeature, dataFetchStrategy);
     _tileFetchDispatcher.DataChanged     += TileFetchDispatcherOnDataChanged;
     _tileFetchDispatcher.PropertyChanged += TileFetchDispatcherOnPropertyChanged;
 }
Пример #13
0
        public void TilesFetchedShouldNotBeFetchAgain()
        {
            // Arrange
            var tileProvider = new CountingTileProvider();
            var tileSchema   = new GlobalSphericalMercator();
            var tileSource   = new TileSource(tileProvider, tileSchema);

            using var cache = new MemoryCache <IFeature?>();
            var fetchDispatcher = new TileFetchDispatcher(cache, tileSource.Schema, tileInfo => TileToFeature(tileSource, tileInfo));
            var tileMachine     = new FetchMachine(fetchDispatcher);
            var level           = 3;
            var expectedTiles   = 64;
            var fetchInfo       = new FetchInfo(tileSchema.Extent.ToMRect(), tileSchema.Resolutions[level].UnitsPerPixel);

            // Act
            fetchDispatcher.SetViewport(fetchInfo);
            tileMachine.Start();
            while (fetchDispatcher.Busy)
            {
                Thread.Sleep(1);
            }
            var countAfterFirstTry = tileProvider.CountByTile.Keys.Count;

            // do it again
            fetchDispatcher.SetViewport(fetchInfo);
            tileMachine.Start();
            while (fetchDispatcher.Busy)
            {
                Thread.Sleep(1);
            }

            // Assert
            Assert.AreEqual(countAfterFirstTry, tileProvider.CountByTile.Values.Sum());
            Assert.AreEqual(expectedTiles, tileProvider.CountByTile.Keys.Count);
            Assert.AreEqual(expectedTiles, tileProvider.CountByTile.Values.Sum());
            Assert.AreEqual(expectedTiles, tileProvider.TotalCount);
        }
Пример #14
0
        public void TileFetcherWithSometimesFailingFetchesShouldTryAgain()
        {
            // Arrange
            var tileProvider = new SometimesFailingTileProvider();
            var tileSchema   = new GlobalSphericalMercator();
            var tileSource   = new TileSource(tileProvider, tileSchema);

            using var cache = new MemoryCache <IFeature?>();
            var fetchDispatcher = new TileFetchDispatcher(cache, tileSource.Schema, tileInfo => TileToFeature(tileSource, tileInfo));
            var tileMachine     = new FetchMachine(fetchDispatcher);
            var level           = 3;
            var tilesInLevel    = 64;
            var fetchInfo       = new FetchInfo(tileSchema.Extent.ToMRect(), tileSchema.Resolutions[level].UnitsPerPixel);

            // Act
            fetchDispatcher.SetViewport(fetchInfo);
            tileMachine.Start();
            while (fetchDispatcher.Busy)
            {
                Thread.Sleep(1);
            }

            var tileCountAfterFirstBatch = tileProvider.TotalCount;

            // Act again
            fetchDispatcher.SetViewport(fetchInfo);
            tileMachine.Start();
            while (fetchDispatcher.Busy)
            {
                Thread.Sleep(1);
            }

            // Assert
            Assert.GreaterOrEqual(tileProvider.TotalCount, tileCountAfterFirstBatch);
            Assert.GreaterOrEqual(tileProvider.CountByTile.Values.Sum(), tilesInLevel);
        }