feat(sources): add multiple sources

This commit is contained in:
vl.arkhangelskii
2026-09-21 04:51:23 +03:00
parent 1c187ed56b
commit 946b77540f
18 changed files with 1494 additions and 110 deletions
@@ -131,6 +131,74 @@ public sealed class StyleServiceTests
Assert.Contains("token=ts_abc", tile, StringComparison.Ordinal);
}
[Fact]
public void Bind_MultipleExtracts_AddsSourcesAndClonesLayers()
{
var central = SampleExtract("central-fed-district", 37.6, 55.7);
var volga = SampleExtract("volga-fed-district", 45, 57);
var template = new JsonObject
{
["version"] = 8,
["sources"] = new JsonObject
{
["openmaptiles"] = new JsonObject { ["type"] = "vector" }
},
["layers"] = new JsonArray
{
new JsonObject
{
["id"] = "background",
["type"] = "background",
["paint"] = new JsonObject { ["background-color"] = "#000" }
},
new JsonObject
{
["id"] = "water",
["type"] = "fill",
["source"] = "openmaptiles",
["source-layer"] = "water"
}
}
};
var service = new StyleService(
new MemoryStyleCatalog(template),
new MemoryExtractCatalog(central, volga),
new MemoryTileStore(SampleMetadata(central)),
Options.Create(new TileServerOptions()));
var style = service.Bind(template, [
new BoundExtract(central.Id, "https://tile-server.ru/u/alice/tiles/central-fed-district/{z}/{x}/{y}.pbf?token=ts"),
new BoundExtract(volga.Id, "https://tile-server.ru/u/alice/tiles/volga-fed-district/{z}/{x}/{y}.pbf?token=ts")
]);
var sources = style["sources"]!.AsObject();
Assert.True(sources.ContainsKey("openmaptiles"));
Assert.True(sources.ContainsKey("openmaptiles__volga-fed-district"));
Assert.Contains("volga-fed-district", sources["openmaptiles__volga-fed-district"]!["tiles"]![0]!.GetValue<string>(), StringComparison.Ordinal);
var layers = style["layers"]!.AsArray();
Assert.Equal(3, layers.Count);
Assert.Equal("water__volga-fed-district", layers[2]!["id"]!.GetValue<string>());
Assert.Equal("openmaptiles__volga-fed-district", layers[2]!["source"]!.GetValue<string>());
Assert.Null(layers[0]!["source"]);
}
private static Extract SampleExtract(string id, double lon, double lat)
=> new()
{
Id = id,
Name = id,
Url = new Uri($"https://download.geofabrik.de/russia/{id}-latest.osm.pbf"),
CenterLon = lon,
CenterLat = lat,
MinZoom = 0,
MaxZoom = 14
};
private static TilesetMetadata SampleMetadata(Extract extract)
=> new(extract.Id, extract.Name, "pbf", 0, 0, 1, 1, 0, 0, 5, 0, 14, []);
private sealed class MemoryStyleCatalog(JsonObject style) : IStyleCatalog
{
public IReadOnlyList<MapStyleInfo> List() => [new("osm-bright", DateTimeOffset.UnixEpoch)];
@@ -143,11 +211,11 @@ public sealed class StyleServiceTests
public Task SeedDefaultsAsync(CancellationToken ct) => Task.CompletedTask;
}
private sealed class MemoryExtractCatalog(Extract extract) : IExtractCatalog
private sealed class MemoryExtractCatalog(params Extract[] extracts) : IExtractCatalog
{
public IReadOnlyList<Extract> GetAll() => [extract];
public IReadOnlyList<Extract> GetAll() => extracts;
public Extract? Find(string id) => id == extract.Id ? extract : null;
public Extract? Find(string id) => extracts.FirstOrDefault(item => item.Id == id);
public Extract GetRequired(string id)
=> Find(id) ?? throw new InvalidOperationException(id);