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);
            }
        }