private static RectangleShape GetTileSphericalMercatorBoundingBox(long tileX, long tileY, int zoomLevel, int tileSize = 256) { SphericalMercatorZoomLevelSet zoomLevelSet = new SphericalMercatorZoomLevelSet(); double currentScale = GetZoomLevelSetScale(zoomLevelSet, zoomLevel); var tileMatrix = TileMatrix.GetDefaultMatrix(currentScale, 512, 512, GeographyUnit.Meter); RectangleShape bbox = tileMatrix.GetCell(tileX, tileY).BoundingBox; return(new RectangleShape(bbox.UpperLeftPoint.X, bbox.UpperLeftPoint.Y, bbox.LowerRightPoint.X, bbox.LowerRightPoint.Y)); }
private async static Task Process(ShapeFileFeatureLayer shapeFile, string targetMbtiles, CancellationToken cancellationToken, int minZoom, int maxZoom, int tileSize, List <string> includedAttributes = null) { Console.Out.WriteLine("Processing tiles. StartZoom:{0}, EndZoom:{1}", minZoom, maxZoom); RectangleShape shapeFileBounds = shapeFile.GetBoundingBox(); shapeFile.Close(); ThinkGeoMBTilesLayer.CreateDatabase(targetMbtiles); var targetDBConnection = new SqliteConnection($"Data Source={targetMbtiles}"); targetDBConnection.Open(); // Meta Table var targetMetadata = new MetadataTable(targetDBConnection); PointShape centerPoint = shapeFileBounds.GetCenterPoint(); string center = $"{centerPoint.X},{centerPoint.Y},{maxZoom}"; string bounds = $"{shapeFileBounds.UpperLeftPoint.X},{shapeFileBounds.UpperLeftPoint.Y},{shapeFileBounds.LowerRightPoint.X},{shapeFileBounds.LowerRightPoint.Y}"; List <MetadataEntry> Entries = new List <MetadataEntry>(); Entries.Add(new MetadataEntry() { Name = "name", Value = "ThinkGeo World Streets" }); Entries.Add(new MetadataEntry() { Name = "format", Value = "pbf" }); Entries.Add(new MetadataEntry() { Name = "bounds", Value = bounds }); //"-96.85310250357627,33.10809235525063,-96.85260897712004,33.107616047247156" Entries.Add(new MetadataEntry() { Name = "center", Value = center }); // "-96.85285574034816,33.1078542012489,14" Entries.Add(new MetadataEntry() { Name = "minzoom", Value = $"{minZoom}" }); Entries.Add(new MetadataEntry() { Name = "maxzoom", Value = $"{maxZoom}" }); Entries.Add(new MetadataEntry() { Name = "attribution", Value = "Copyright @2020 ThinkGeo LLC.All rights reserved." }); Entries.Add(new MetadataEntry() { Name = "description", Value = "ThinkGeo World Street Vector Tile Data in EPSG:3857" }); Entries.Add(new MetadataEntry() { Name = "version", Value = "2.0" }); Entries.Add(new MetadataEntry() { Name = "json", Value = "" }); targetMetadata.Insert(Entries); // Tile Table var targetMap = new TilesTable(targetDBConnection); List <TilesEntry> entries = new List <TilesEntry>(); string targetFolder = Path.Combine(Path.GetDirectoryName(targetMbtiles), Path.GetFileNameWithoutExtension(targetMbtiles), "-tmp"); if (!Directory.Exists(targetFolder)) { Directory.CreateDirectory(targetFolder); } SphericalMercatorZoomLevelSet zoomLevelSet = new SphericalMercatorZoomLevelSet(); double currentScale = GetZoomLevelIndex(zoomLevelSet, minZoom); var tileMatrix = TileMatrix.GetDefaultMatrix(currentScale, tileSize, tileSize, GeographyUnit.Meter); var tileRange = tileMatrix.GetIntersectingRowColumnRange(shapeFileBounds); List <Task> tasks = new List <Task>(); for (long tileY = tileRange.MinRowIndex; tileY <= tileRange.MaxRowIndex && !cancellationToken.IsCancellationRequested; ++tileY) { for (long tileX = tileRange.MinColumnIndex; tileX <= tileRange.MaxColumnIndex && !cancellationToken.IsCancellationRequested; ++tileX) { Task task = ProcessTileRecursive(shapeFile, (int)tileY, (int)tileX, minZoom, maxZoom, cancellationToken, targetFolder, includedAttributes); tasks.Add(task); } } foreach (var task in tasks) { await task; } await Task.Run(() => { long index = 0; string[] files = Directory.GetFiles(targetFolder, "*.mvt"); foreach (string file in files) { string fileName = Path.GetFileNameWithoutExtension(file); string[] NameValues = fileName.Split('_'); byte[] bytes = File.ReadAllBytes(file); TilesEntry newEntry = new TilesEntry(); int zoomLevel = int.Parse(NameValues[0]); newEntry.ZoomLevel = zoomLevel; long row = long.Parse(NameValues[1]); row = (long)Math.Pow(2, zoomLevel) - row - 1; newEntry.TileRow = row; newEntry.TileColumn = long.Parse(NameValues[2]); newEntry.TileId = index++; newEntry.TileData = bytes; File.Delete(file); entries.Add(newEntry); if (index % 1000 == 0) { targetMap.Insert(entries); entries.Clear(); continue; } } targetMap.Insert(entries); }); targetDBConnection.Close(); }