Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions GameRealisticMap.Arma3.Test/ContextMock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ internal class ContextMock : Dictionary<Type, object>, IContext, IDisposable

IHugeImageStorage IContext.HugeImageStorage => HugeImageStorage;

public ITerrainArea Area { get; }

public ContextMock(ITerrainArea? area = null)
{
Area = area ?? new TerrainAreaUTM(new CoordinateSharp.UniversalTransverseMercator("Q", 14, 581943.5, 2111989.8), 1000, 1000);
}

public void Dispose()
{
HugeImageStorage.Dispose();
Expand Down
4 changes: 4 additions & 0 deletions GameRealisticMap.Arma3/Arma3MapConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ public Arma3MapConfig(Arma3MapConfigJson arma3MapConfigJson)

Satellite = arma3MapConfigJson.Satellite ?? new SatelliteImageOptions();

IsPersisted = arma3MapConfigJson.IsPersisted;

Arma3ConfigHelper.ValidatePboPrefix(PboPrefix);
Arma3ConfigHelper.ValidateWorldName(WorldName);
}
Expand Down Expand Up @@ -129,5 +131,7 @@ public static string GetAutomaticTargetModDirectory(string worldName)
public int IdMapMultiplier { get; }

public ISatelliteImageOptions Satellite { get; }

public bool IsPersisted { get; }
}
}
2 changes: 2 additions & 0 deletions GameRealisticMap.Arma3/Arma3MapConfigJson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public class Arma3MapConfigJson

public SatelliteImageOptions? Satellite { get; set; }

public bool IsPersisted { get; set; } = true;

public Arma3MapConfig ToArma3MapConfig()
{
return new Arma3MapConfig(this);
Expand Down
2 changes: 1 addition & 1 deletion GameRealisticMap.Arma3/Arma3MapGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public Arma3MapGenerator(IArma3RegionAssets assets, ProjectDrive projectDrive, I
protected virtual BuildContext CreateBuildContext(IProgressScope progress, Arma3MapConfig a3config, IOsmDataSource osmSource, IHugeImageStorage? hugeImageStorage = null)
{
var builders = new BuildersCatalog(assets, sources);
return new BuildContext(builders, progress, a3config.TerrainArea, osmSource, a3config.Imagery, hugeImageStorage);
return new BuildContext(builders, progress, a3config.TerrainArea, osmSource, a3config.Imagery, hugeImageStorage, PackageHelper.GetPackageWriter(a3config, projectDrive));
}

[SupportedOSPlatform("windows")]
Expand Down
6 changes: 3 additions & 3 deletions GameRealisticMap.Arma3/Arma3TerrainBuilderGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
using GameRealisticMap.ManMade.Roads;
using GameRealisticMap.Osm;
using GameRealisticMap.Preview;
using Pmad.Cartography;
using Pmad.Cartography.DataCells.FileFormats;
using Pmad.HugeImages;
using Pmad.HugeImages.Processing;
using Pmad.HugeImages.Storage;
using Pmad.Cartography;
using Pmad.Cartography.DataCells.FileFormats;
using Pmad.ProgressTracking;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
Expand All @@ -42,7 +42,7 @@ public Arma3TerrainBuilderGenerator(IArma3RegionAssets assets, ProjectDrive proj
private BuildContext CreateBuildContext(IProgressScope progress, Arma3MapConfig a3config, IOsmDataSource osmSource, IHugeImageStorage? hugeImageStorage = null)
{
var builders = new BuildersCatalog(assets, sources);
return new BuildContext(builders, progress, a3config.TerrainArea, osmSource, a3config.Imagery, hugeImageStorage);
return new BuildContext(builders, progress, a3config.TerrainArea, osmSource, a3config.Imagery, hugeImageStorage, PackageHelper.GetPackageWriter(a3config, projectDrive));
}

public async Task<string?> GenerateTerrainBuilderFiles(IProgressScope progress, Arma3MapConfig a3config, string targetDirectory)
Expand Down
17 changes: 17 additions & 0 deletions GameRealisticMap.Arma3/PackageHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using GameRealisticMap.Arma3.IO;
using GameRealisticMap.IO;

namespace GameRealisticMap.Arma3
{
internal static class PackageHelper
{
internal static IPackageWriter? GetPackageWriter(Arma3MapConfig a3config, ProjectDrive projectDrive)
{
if (a3config.IsPersisted)
{
return new FileSystemPackage(Path.Combine(projectDrive.GetFullPath(a3config.PboPrefix), ".grm"));
}
return null;
}
}
}
4 changes: 4 additions & 0 deletions GameRealisticMap.Generic/GenericMapConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public GenericMapConfig(GenericMapConfigJson genericMapConfigJson)
PrivateServiceRoadThreshold = genericMapConfigJson.PrivateServiceRoadThreshold ?? MapProcessingOptions.Default.PrivateServiceRoadThreshold;

Satellite = genericMapConfigJson.Satellite ?? new SatelliteImageOptions();

IsPersisted = genericMapConfigJson.IsPersisted;
}

public TerrainAreaUTM TerrainArea { get; }
Expand All @@ -47,6 +49,8 @@ public GenericMapConfig(GenericMapConfigJson genericMapConfigJson)

public ISatelliteImageOptions Satellite { get; }

public bool IsPersisted { get; } = false;

public static string GetAutomaticName(ITerrainArea area)
{
var coordinate = area.TerrainPointToLatLng(new TerrainPoint(area.SizeInMeters / 2, area.SizeInMeters / 2));
Expand Down
2 changes: 2 additions & 0 deletions GameRealisticMap.Generic/GenericMapConfigJson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public class GenericMapConfigJson

public SatelliteImageOptions? Satellite { get; set; }

public bool IsPersisted { get; set; }

public GenericMapConfig ToMapConfig()
{
return new GenericMapConfig(this);
Expand Down
13 changes: 11 additions & 2 deletions GameRealisticMap.Generic/GenericMapGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using GameRealisticMap.Configuration;
using GameRealisticMap.Generic.Exporters;
using GameRealisticMap.Generic.Profiles;
using GameRealisticMap.IO;
using GameRealisticMap.Osm;
using GameRealisticMap.Reporting;
using Pmad.HugeImages.Storage;
using Pmad.ProgressTracking;

Expand Down Expand Up @@ -38,10 +38,19 @@ protected virtual async Task<IOsmDataSource> LoadOsmData(IProgressScope progress
return CreateBuildContext(progress, config, osmSource, hugeImageStorage);
}

internal IPackageWriter? GetPackageWriter(GenericMapConfig config)
{
if (config.IsPersisted)
{
return new FileSystemPackage(Path.Combine(config.TargetDirectory, ".grm"));
}
return null;
}

protected virtual BuildContext CreateBuildContext(IProgressScope progress, GenericMapConfig config, IOsmDataSource osmSource, IHugeImageStorage? hugeImageStorage = null)
{
var builders = new BuildersCatalog(new DefaultBuildersConfig(), sources);
return new BuildContext(builders, progress, config.TerrainArea, osmSource, config, hugeImageStorage);
return new BuildContext(builders, progress, config.TerrainArea, osmSource, config, hugeImageStorage, GetPackageWriter(config));
}

public async Task Generate(IProgressScope progress, GenericMapConfig config)
Expand Down
23 changes: 19 additions & 4 deletions GameRealisticMap/BuildContext.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using GameRealisticMap.Osm;
using GameRealisticMap.IO;
using GameRealisticMap.Osm;
using Pmad.HugeImages.Storage;
using Pmad.ProgressTracking;

Expand All @@ -17,6 +18,7 @@ public class BuildContext : IBuildContext
private readonly Dictionary<Type, Task> datas = new Dictionary<Type, Task>();
private readonly IProgressScope rootScope;
private readonly IBuidersCatalog catalog;
private readonly IPackageWriter? writer;

/// <summary>
/// Initialises a new <see cref="BuildContext"/> with all required inputs.
Expand All @@ -27,10 +29,11 @@ public class BuildContext : IBuildContext
/// <param name="source">The OSM data source pre-loaded for the terrain area.</param>
/// <param name="imagery">Processing options (resolution, road thresholds, satellite settings).</param>
/// <param name="his">Optional huge-image storage; defaults to a temporary disk-backed store.</param>
public BuildContext(IBuidersCatalog catalog, IProgressScope rootScope, ITerrainArea area, IOsmDataSource source, IMapProcessingOptions imagery, IHugeImageStorage? his = null)
public BuildContext(IBuidersCatalog catalog, IProgressScope rootScope, ITerrainArea area, IOsmDataSource source, IMapProcessingOptions imagery, IHugeImageStorage? his = null, IPackageWriter? writer = null)
{
this.rootScope = rootScope;
this.catalog = catalog;
this.writer = writer;
Area = area;
OsmSource = source;
Options = imagery;
Expand Down Expand Up @@ -101,13 +104,25 @@ private Task<T> CreateDataTask<T>(IProgressScope? parentScope) where T : class
var builder = catalog.Get<T>();
return Task.Run(async () =>
{
var name = builder.GetType().Name.Replace("Builder", "");

using (var scope = (parentScope ?? rootScope).CreateScope(builder.GetType().Name.Replace("Builder", "")))
{
T value;
if (builder is IDataBuilderAsync<T> asyncBuilder)
{
return await asyncBuilder.BuildAsync(this, scope).ConfigureAwait(false);
value = await asyncBuilder.BuildAsync(this, scope).ConfigureAwait(false);
}
else
{
value = builder.Build(this, scope);
}
if (writer != null)
{
var serializer = ContextSerializer.GetSerializer(builder);
await serializer.Write(writer, value).ConfigureAwait(false);
}
return builder.Build(this, scope);
return value;
}
});
}
Expand Down
2 changes: 1 addition & 1 deletion GameRealisticMap/Conditions/ConditionEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class ConditionEvaluator : IConditionEvaluator
internal const float MaxRoadBoxSearch = 75f;
internal const float MaxRoadDistance = MaxRoadBoxSearch * 1.414f; // MaxRoadBoxSearch * sqrt(2)

public ConditionEvaluator(IBuildContext context)
public ConditionEvaluator(IContext context)
{
this.areas = context.GetData<CategoryAreaData>();
this.cities = context.GetData<CitiesData>();
Expand Down
15 changes: 13 additions & 2 deletions GameRealisticMap/Conditions/ConditionEvaluatorBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
using Pmad.ProgressTracking;
using GameRealisticMap.IO;
using Pmad.ProgressTracking;

namespace GameRealisticMap.Conditions
{
internal class ConditionEvaluatorBuilder : IDataBuilder<ConditionEvaluator>
internal class ConditionEvaluatorBuilder : IDataBuilder<ConditionEvaluator>, IDataSerializer<ConditionEvaluator>
{
public ConditionEvaluator Build(IBuildContext context, IProgressScope scope)
{
return new ConditionEvaluator(context);
}

public ValueTask<ConditionEvaluator> Read(IPackageReader package, IContext context)
{
return ValueTask.FromResult(new ConditionEvaluator(context));
}

public Task Write(IPackageWriter package, ConditionEvaluator data)
{
return Task.CompletedTask;
}
}
}
16 changes: 13 additions & 3 deletions GameRealisticMap/ElevationModel/ElevationWithLakesBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using GeoJSON.Text.Geometry;
using Pmad.Cartography;
using Pmad.Cartography.Contours;
using Pmad.Cartography.DataCells;
using Pmad.Geometry;
using Pmad.Geometry.Shapes;
using Pmad.ProgressTracking;
Expand Down Expand Up @@ -311,12 +312,21 @@ public async ValueTask<ElevationWithLakesData> Read(IPackageReader package, ICon
{
var lakes = await package.ReadJson<List<LakeWithElevation>>("LakesElevation.json");

return new ElevationWithLakesData(context.GetData<ElevationData>().Elevation, lakes);
using var stream = package.ReadFile("ElevationWithLakes.ddc");

var grid = new ElevationGrid(DemDataCell.Load(stream).To<float>().AsPixelIsPoint());

return new ElevationWithLakesData(grid, lakes);
}

public Task Write(IPackageWriter package, ElevationWithLakesData data)
public async Task Write(IPackageWriter package, ElevationWithLakesData data)
{
return package.WriteJson("LakesElevation.json", data.Lakes);
await package.WriteJson("LakesElevation.json", data.Lakes);

using (var stream = package.CreateFile("ElevationWithLakes.ddc"))
{
data.Elevation.ToDataCell().Save(stream);
}
}
}
}
18 changes: 14 additions & 4 deletions GameRealisticMap/ElevationModel/RawElevationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,24 @@ private static LatLngBounds CreateOutOfBounds(IBuildContext context)
return new LatLngBounds(context.Area, wantedView.Shell);
}

public ValueTask<RawElevationData> Read(IPackageReader package, IContext context)
public async ValueTask<RawElevationData> Read(IPackageReader package, IContext context)
{
return ValueTask.FromResult<RawElevationData>(new RawElevationData(context.GetData<ElevationData>().Elevation, new List<string>(), new ElevationMinMax[0]));
using var stream = package.ReadFile("RawElevation.ddc");

var grid = new ElevationGrid(DemDataCell.Load(stream).To<float>().AsPixelIsPoint());

var json = await package.ReadJson<RawElevationJson>("RawElevation.json");

return new RawElevationData(grid, json.Credits, json.OutOfBounds);
}

public Task Write(IPackageWriter package, RawElevationData data)
public async Task Write(IPackageWriter package, RawElevationData data)
{
return Task.CompletedTask;
using (var stream = package.CreateFile("RawElevation.ddc"))
{
data.RawElevation.ToDataCell().Save(stream);
}
await package.WriteJson("RawElevation.json", new RawElevationJson(data.Credits, data.OutOfBounds));
}
}
}
15 changes: 15 additions & 0 deletions GameRealisticMap/ElevationModel/RawElevationJson.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace GameRealisticMap.ElevationModel
{
public sealed class RawElevationJson
{
public RawElevationJson(List<string> credits, ElevationMinMax[] outOfBounds)
{
Credits = credits;
OutOfBounds = outOfBounds;
}

public List<string> Credits { get; }

public ElevationMinMax[] OutOfBounds { get; }
}
}
7 changes: 0 additions & 7 deletions GameRealisticMap/IBuildContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@ namespace GameRealisticMap
/// </summary>
public interface IBuildContext : IContext
{
/// <summary>
/// The geographic area being processed. Provides coordinate conversion between
/// WGS-84 lat/lng and local terrain space (<see cref="Geometries.TerrainPoint"/>),
/// and exposes the terrain grid dimensions.
/// </summary>
ITerrainArea Area { get; }

/// <summary>
/// The OpenStreetMap data source containing all OSM features (nodes, ways, relations)
/// clipped to the terrain area. Used by all OSM-based builders.
Expand Down
7 changes: 7 additions & 0 deletions GameRealisticMap/IContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ namespace GameRealisticMap
/// </summary>
public interface IContext
{
/// <summary>
/// The geographic area being processed. Provides coordinate conversion between
/// WGS-84 lat/lng and local terrain space (<see cref="Geometries.TerrainPoint"/>),
/// and exposes the terrain grid dimensions.
/// </summary>
ITerrainArea Area { get; }

/// <summary>
/// Gets or builds data of type <typeparamref name="T"/> synchronously.
/// If the data has already been built, returns the cached result.
Expand Down
2 changes: 2 additions & 0 deletions GameRealisticMap/IO/ContextReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ internal class ContextReader : IContext, IDataBuilderVisitor<Task>

public IHugeImageStorage HugeImageStorage => throw new NotImplementedException();

public ITerrainArea Area => throw new NotImplementedException();

public ContextReader(IPackageReader package, IBuidersCatalog catalog)
{
this.package = package;
Expand Down
24 changes: 1 addition & 23 deletions GameRealisticMap/IO/ContextSerializer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System.IO.Compression;

namespace GameRealisticMap.IO
namespace GameRealisticMap.IO
{
public class ContextSerializer
{
Expand All @@ -16,26 +14,6 @@ internal static IDataSerializer<TData> GetSerializer<TData>(IDataBuilder<TData>
return (builder as IDataSerializer<TData>) ?? new DefaultDataSerializer<TData>();
}

public async Task Write(IPackageWriter writer, IContext context)
{
foreach(var step in catalog.VisitAll(new ContextWriter(writer, context)))
{
await step;
}
}

public Task WriteToDirectory(string path, IContext context)
{
return Write(new FileSystemPackage(path), context);
}

public async Task WriteToZip(string path, IContext context)
{
using var archive = new ZipArchive(File.Create(path), ZipArchiveMode.Create);

await Write(new ZipPackageWriter(archive), context);
}

public IContext ReadLazy(IPackageReader reader)
{
return new ContextReader(reader, catalog);
Expand Down
Loading
Loading