/// <summary> /// Creates a new feature layer for visualizing a map based of tiles. /// </summary> /// <param name="Id">The unique identification of the layer.</param> /// <param name="MapControl">The MapControl of the layer.</param> /// <param name="ZIndex">The Z-Index of the layer.</param> /// <param name="MapTilesProviders">A list of map providers. The first will be activated.</param> public TilesLayer(String Id, MapControl MapControl, Int32 ZIndex, params MapTilesProvider[] MapTilesProviders) : this(Id, ZIndex, MapControl) { if (MapTilesProviders != null) { foreach (var MapTilesProvider in MapTilesProviders) { TilesClient.Register(MapTilesProvider, Activate: false); } } // Mark the firt MapProvider as 'active' if (MapTilesProviders.Any()) { TilesClient.CurrentProvider = MapTilesProviders.First(); } TilesRefreshTimer = new Timer(TilesAutoRefresh, null, TimeSpan.Zero, TimeSpan.FromMilliseconds(100)); }
/// <summary> /// Paints the tiles layer. /// </summary> /// <returns>True if the map was repainted; false otherwise.</returns> public override void Redraw() { if (this.IsVisible && !DesignerProperties.GetIsInDesignMode(this)) { Interlocked.Increment(ref GlobalVersionCounter); var _NumberOfXTiles = 0; var _NumberOfYTiles = 0; var NumberOfXTiles = (Int32)Math.Floor(base.ActualWidth / 256) + 1; var NumberOfYTiles = (Int32)Math.Floor(base.ActualHeight / 256) + 1; var NumberOfTilesAtZoomLevel = (Int32)Math.Pow(2, this.MapControl.ZoomLevel); var LeftUpperTile = new Point(this.MapControl.ScreenOffset.X % (NumberOfTilesAtZoomLevel * 256) / 256, this.MapControl.ScreenOffset.Y % (NumberOfTilesAtZoomLevel * 256) / 256); var UselessTilesOnScreen = new List <Image>(); foreach (Image Tile in this.Children) { UselessTilesOnScreen.Add(Tile); } for (var CurrentX = 0; CurrentX < NumberOfXTiles + 1; CurrentX++) { for (var CurrentY = 0; CurrentY < NumberOfYTiles + 1; CurrentY++) { var NewPosition = new Point(this.MapControl.ScreenOffset.X % 256 + CurrentX * 256, this.MapControl.ScreenOffset.Y % 256 + CurrentY * 256); #region Is this tile already on the screen? var FoundAndHowOften = 0; foreach (Image Tile in this.Children) { if (NewPosition.X == Canvas.GetLeft(Tile) && NewPosition.Y == Canvas.GetTop(Tile)) { if (FoundAndHowOften == 0) { FoundAndHowOften = 1; UselessTilesOnScreen.Remove(Tile); } else { FoundAndHowOften++; } } } #endregion if (FoundAndHowOften == 0) { TilesClient.GetTile(this.MapControl.ZoomLevel, (UInt32)Normalize(CurrentX - LeftUpperTile.X, NumberOfTilesAtZoomLevel), (UInt32)Normalize(CurrentY - LeftUpperTile.Y, NumberOfTilesAtZoomLevel), new Tuple <Point, Int64>( NewPosition, GlobalVersionCounter)). ContinueWith(TileTask => PaintTile(TileTask.Result.Item1, (TileTask.Result.Item2 as Tuple <Point, Int64>).Item1, (TileTask.Result.Item2 as Tuple <Point, Int64>).Item2)); } } } Debug.WriteLine("Deleting tiles: " + UselessTilesOnScreen.Count); foreach (var Tile in UselessTilesOnScreen) { this.Children.Remove(Tile); } _NumberOfXTiles = (Normalize(LeftUpperTile.X, NumberOfTilesAtZoomLevel) == 0) ? NumberOfXTiles : NumberOfXTiles + 1; _NumberOfYTiles = (Normalize(LeftUpperTile.Y, NumberOfTilesAtZoomLevel) == 0) ? NumberOfYTiles : NumberOfYTiles + 1; Debug.WriteLine("Number of visible tiles: " + this.Children.Count + " (" + (_NumberOfXTiles * _NumberOfYTiles) + ")"); } // return true; }