public ZippedImagePyramidDataSource(string worldFilePyramidFileName, Func <int, int, int, string> fileNameRule = null, Func <string, TileInfo> inverseFunction = null) { if (!System.IO.File.Exists(worldFilePyramidFileName)) { throw new NotImplementedException(); } _archive = System.IO.Compression.ZipFile.OpenRead(worldFilePyramidFileName); if (fileNameRule == null) { //_fileNameRule = (z, r, c) => System.IO.Path.Combine(z.ToString(), $"{z}, {r}, {c}.jpg"); _fileNameRule = _defaultFileNameRule; } else { _fileNameRule = fileNameRule; } if (inverseFunction == null) { _inverseFunction = _defaultInverseFunction; } else { _inverseFunction = inverseFunction; } var extentString = ZipFileHelper.ReadAsString(_archive, _extentFileName); if (extentString == null || extentString.Contains("NaN")) { _archive.Dispose(); _archive = System.IO.Compression.ZipFile.Open(worldFilePyramidFileName, System.IO.Compression.ZipArchiveMode.Update); var lastPyramid = _archive.Entries.Max(e => { var folder = e.FullName.Replace($"\\{e.Name}", string.Empty); int zoom = -1; int.TryParse(folder, out zoom); return(zoom); } ); this.Extent = BoundingBox.GetMergedBoundingBox( _archive.Entries.Where(e => e.FullName.StartsWith(lastPyramid.ToString())) .Select(e => _inverseFunction(e.FullName).WebMercatorExtent), true); ZipFileHelper.WriteString(_archive, Newtonsoft.Json.JsonConvert.SerializeObject(Extent), _extentFileName); _archive.Dispose(); _archive = System.IO.Compression.ZipFile.OpenRead(worldFilePyramidFileName); } else { this.Extent = JsonHelper.ParseFromJson <BoundingBox>(extentString); } }