/// <summary> /// Fills up the pyramid of tiles above the specified level. /// </summary> /// <param name="level"> /// Base level of zoom. /// </param> /// <param name="boundary"> /// Bounding coordinates of the region. /// </param> public void BuildParentLevels(int level, Boundary boundary) { if (boundary == null) { throw new ArgumentNullException("boundary"); } if (this.tileCreator.ProjectionType == ProjectionTypes.Toast) { this.toastProjectionCoordinates = ToastHelper.ComputeTileCoordinates(boundary, level); foreach (int k in Enumerable.Range(1, level).Select(i => level - i)) { Trace.TraceInformation("{0}: Filling up pyramid at level {1}..", DateTime.Now.TimeOfDay.ToString(@"hh\:mm\:ss", CultureInfo.InvariantCulture), k); CurrentLevel = k; Parallel.ForEach( this.toastProjectionCoordinates[k], this.ParallelOptions, tile => { this.tileCreator.CreateParent(k, tile.X, tile.Y); Interlocked.Increment(ref this.tilesProcessed); this.ParallelOptions.CancellationToken.ThrowIfCancellationRequested(); }); } } else { int tileXMin, tileXMax, tileYMin, tileYMax; foreach (int k in Enumerable.Range(1, level).Select(i => level - i)) { CurrentLevel = k; tileXMin = Helper.GetMercatorXTileFromLongitude(boundary.Left, k); tileXMax = Helper.GetMercatorXTileFromLongitude(boundary.Right, k); tileYMin = Helper.GetMercatorYTileFromLatitude(boundary.Bottom, k); tileYMax = Helper.GetMercatorYTileFromLatitude(boundary.Top, k); BuildParentLevels(k, tileXMin, tileXMax, tileYMin, tileYMax); } } }