public static async Task BuildForTile(uint tile, string folder, Func <uint, IEnumerable <OsmGeo> > getTile, Func <TagsCollectionBase, bool> isBarrier) { // wait until tile is removed from queue. while (true) { if (_tiles.ContainsKey(tile)) { await Task.Delay(200); } else { _tiles[tile] = tile; break; } } try { var file = Path.Combine(folder, $"{tile}.tile.graph.zip"); if (File.Exists(file)) { return; } // load data for tile. var graph = new TiledBarrierGraph(); graph.LoadForTile(tile, getTile, isBarrier); // run face assignment for the tile. var result = graph.AssignFaces(tile); while (!result.success) { // extra tiles need loading.- graph.AddTiles(result.missingTiles, getTile, isBarrier); // try again. result = graph.AssignFaces(tile); } // assign landuse. IEnumerable <(Polygon polygon, string type)> GetLanduse( ((double longitude, double latitude)topLeft, (double longitude, double latitude)bottomRight) box) { return(LandusePolygons.GetLandusePolygons(box, graph.Zoom, getTile, t => { if (DefaultMergeFactorCalculator.Landuses.TryCalculateValue(t, out var type)) { return type; } return null; })); } graph.AssignLanduse(tile, GetLanduse); await using var stream = File.Open(file, FileMode.Create); await using var compressedStream = new GZipStream(stream, CompressionLevel.Fastest); graph.WriteTileTo(compressedStream, tile); } finally { _tiles.Remove(tile, out _); } }