diff --git a/GameRealisticMap.Arma3/Arma3LayerGeneratorCatalog.cs b/GameRealisticMap.Arma3/Arma3LayerGeneratorCatalog.cs index c11d7875..c6a4b950 100644 --- a/GameRealisticMap.Arma3/Arma3LayerGeneratorCatalog.cs +++ b/GameRealisticMap.Arma3/Arma3LayerGeneratorCatalog.cs @@ -1,6 +1,7 @@ using GameRealisticMap.Arma3.Assets; using GameRealisticMap.Arma3.ManMade; using GameRealisticMap.Arma3.ManMade.Farmlands; +using GameRealisticMap.Arma3.Nature.DefaultAreas; using GameRealisticMap.Arma3.Nature.Forests; using GameRealisticMap.Arma3.Nature.Lakes; using GameRealisticMap.Arma3.Nature.RockAreas; @@ -38,6 +39,7 @@ public Arma3LayerGeneratorCatalog(IProgressSystem progress, IArma3RegionAssets a Generators.Add(new TreeRowsGenerator(progress, assets)); Generators.Add(new WatercourseGenerator(progress, assets)); Generators.Add(new WatercourseRadialGenerator(progress, assets)); + Generators.Add(new DefaultAreasGenerator(progress, assets)); } public List Generators { get; } = new List(); diff --git a/GameRealisticMap.Arma3/Nature/BasicGeneratorBase.cs b/GameRealisticMap.Arma3/Nature/BasicGeneratorBase.cs index da053947..03b6031c 100644 --- a/GameRealisticMap.Arma3/Nature/BasicGeneratorBase.cs +++ b/GameRealisticMap.Arma3/Nature/BasicGeneratorBase.cs @@ -8,7 +8,7 @@ namespace GameRealisticMap.Arma3.Nature { - internal abstract class BasicGeneratorBase : GeneratorBase where TData : class, IBasicTerrainData + internal abstract class BasicGeneratorBase : GeneratorBase where TData : class, IPolygonTerrainData { public BasicGeneratorBase(IProgressSystem progress, IArma3RegionAssets assets) : base(progress, assets) diff --git a/GameRealisticMap.Arma3/Nature/ClusteredGeneratorBase.cs b/GameRealisticMap.Arma3/Nature/ClusteredGeneratorBase.cs index eee63b6d..e9bfc2f5 100644 --- a/GameRealisticMap.Arma3/Nature/ClusteredGeneratorBase.cs +++ b/GameRealisticMap.Arma3/Nature/ClusteredGeneratorBase.cs @@ -1,9 +1,7 @@ -using System.Numerics; -using GameRealisticMap.Algorithms; +using GameRealisticMap.Algorithms; using GameRealisticMap.Algorithms.Filling; using GameRealisticMap.Arma3.Assets; using GameRealisticMap.Arma3.Assets.Filling; -using GameRealisticMap.Arma3.TerrainBuilder; using GameRealisticMap.Geometries; using GameRealisticMap.Nature; using GameRealisticMap.Reporting; diff --git a/GameRealisticMap.Arma3/Nature/DefaultAreas/DefaultAreasGenerator.cs b/GameRealisticMap.Arma3/Nature/DefaultAreas/DefaultAreasGenerator.cs new file mode 100644 index 00000000..80654b1b --- /dev/null +++ b/GameRealisticMap.Arma3/Nature/DefaultAreas/DefaultAreasGenerator.cs @@ -0,0 +1,19 @@ +using GameRealisticMap.Arma3.Assets; +using GameRealisticMap.Arma3.Assets.Filling; +using GameRealisticMap.Nature.DefaultAreas; +using GameRealisticMap.Reporting; + +namespace GameRealisticMap.Arma3.Nature.DefaultAreas +{ + internal class DefaultAreasGenerator : BasicGeneratorBase + { + public DefaultAreasGenerator(IProgressSystem progress, IArma3RegionAssets assets) + : base(progress, assets) + { + } + + protected override bool ShouldGenerate => assets.GetBasicCollections(Id).Count > 0; + + protected override BasicCollectionId Id => BasicCollectionId.DefaultAreas; + } +} diff --git a/GameRealisticMap.Arma3/Nature/GeneratorBase.cs b/GameRealisticMap.Arma3/Nature/GeneratorBase.cs index 69178bbb..39191871 100644 --- a/GameRealisticMap.Arma3/Nature/GeneratorBase.cs +++ b/GameRealisticMap.Arma3/Nature/GeneratorBase.cs @@ -1,6 +1,5 @@ using System.Numerics; using GameRealisticMap.Algorithms; -using GameRealisticMap.Algorithms.Filling; using GameRealisticMap.Arma3.Assets; using GameRealisticMap.Arma3.TerrainBuilder; using GameRealisticMap.Geometries; @@ -10,7 +9,7 @@ namespace GameRealisticMap.Arma3.Nature { public abstract class GeneratorBase : ITerrainBuilderLayerGenerator - where TData : class, IBasicTerrainData + where TData : class, IPolygonTerrainData { protected readonly IProgressSystem progress; protected readonly IArma3RegionAssets assets; @@ -21,8 +20,15 @@ public GeneratorBase(IProgressSystem progress, IArma3RegionAssets assets) this.assets = assets; } + protected virtual bool ShouldGenerate => true; + public IEnumerable Generate(IArma3MapConfig config, IContext context) { + if (!ShouldGenerate) + { + return new List(0); + } + using var scope = progress.CreateScope(GetType().Name.Replace("Generator","")); var polygons = context.GetData().Polygons; diff --git a/GameRealisticMap/BuildContext.cs b/GameRealisticMap/BuildContext.cs index 2cfd643e..cb88e38b 100644 --- a/GameRealisticMap/BuildContext.cs +++ b/GameRealisticMap/BuildContext.cs @@ -1,4 +1,5 @@ -using GameRealisticMap.Osm; +using System.Diagnostics; +using GameRealisticMap.Osm; using GameRealisticMap.Reporting; using HugeImages.Storage; @@ -52,6 +53,11 @@ public T GetData() } } + public IEnumerable GetOfType() where T : class + { + return catalog.GetOfType(this); + } + public void SetData(T value) where T : class { diff --git a/GameRealisticMap/BuildersCatalog.cs b/GameRealisticMap/BuildersCatalog.cs index e4b47ec9..6b7637ac 100644 --- a/GameRealisticMap/BuildersCatalog.cs +++ b/GameRealisticMap/BuildersCatalog.cs @@ -8,6 +8,8 @@ using GameRealisticMap.ManMade.Railways; using GameRealisticMap.ManMade.Roads; using GameRealisticMap.ManMade.Roads.Libraries; +using GameRealisticMap.Nature; +using GameRealisticMap.Nature.DefaultAreas; using GameRealisticMap.Nature.Forests; using GameRealisticMap.Nature.Lakes; using GameRealisticMap.Nature.Ocean; @@ -57,6 +59,7 @@ public BuildersCatalog(IProgressSystem progress, IRoadTypeLibrary(IDataBuilder builder) diff --git a/GameRealisticMap/IContext.cs b/GameRealisticMap/IContext.cs index 006aa621..00d670c8 100644 --- a/GameRealisticMap/IContext.cs +++ b/GameRealisticMap/IContext.cs @@ -6,6 +6,8 @@ public interface IContext { T GetData() where T : class; + IEnumerable GetOfType() where T : class; + IHugeImageStorage HugeImageStorage { get; } } } diff --git a/GameRealisticMap/IO/ContextReader.cs b/GameRealisticMap/IO/ContextReader.cs index 4001095d..0fe6420a 100644 --- a/GameRealisticMap/IO/ContextReader.cs +++ b/GameRealisticMap/IO/ContextReader.cs @@ -1,4 +1,5 @@ -using HugeImages.Storage; +using System.Diagnostics; +using HugeImages.Storage; namespace GameRealisticMap.IO { @@ -31,6 +32,11 @@ public T GetData() where T : class return result; } + public IEnumerable GetOfType() where T : class + { + return catalog.GetOfType(this); + } + public async Task Visit(IDataBuilder builder) where TData : class { if (!cache.ContainsKey(typeof(TData))) diff --git a/GameRealisticMap/ManMade/Buildings/BuildingsData.cs b/GameRealisticMap/ManMade/Buildings/BuildingsData.cs index 4a810c49..2634443b 100644 --- a/GameRealisticMap/ManMade/Buildings/BuildingsData.cs +++ b/GameRealisticMap/ManMade/Buildings/BuildingsData.cs @@ -1,11 +1,12 @@ using System.Text.Json.Serialization; using GameRealisticMap.Geometries; +using GameRealisticMap.Nature; using GeoJSON.Text.Feature; using GeoJSON.Text.Geometry; namespace GameRealisticMap.ManMade.Buildings { - public class BuildingsData : IGeoJsonData + public class BuildingsData : IGeoJsonData, INonDefaultArea { [JsonConstructor] public BuildingsData(List buildings) @@ -15,6 +16,8 @@ public BuildingsData(List buildings) public List Buildings { get; } + IEnumerable INonDefaultArea.Polygons => Buildings.Select(b => b.Box.Polygon); + public IEnumerable ToGeoJson(Func project) { var entrance = new Dictionary() { diff --git a/GameRealisticMap/ManMade/CategoryAreaData.cs b/GameRealisticMap/ManMade/CategoryAreaData.cs index 0e9abe86..b4084026 100644 --- a/GameRealisticMap/ManMade/CategoryAreaData.cs +++ b/GameRealisticMap/ManMade/CategoryAreaData.cs @@ -1,8 +1,10 @@ -using GeoJSON.Text.Feature; +using GameRealisticMap.Geometries; +using GameRealisticMap.Nature; +using GeoJSON.Text.Feature; namespace GameRealisticMap.ManMade { - public class CategoryAreaData + public class CategoryAreaData : INonDefaultArea { public CategoryAreaData(List areas) { @@ -10,5 +12,7 @@ public CategoryAreaData(List areas) } public List Areas { get; } + + IEnumerable INonDefaultArea.Polygons => Areas.SelectMany(a => a.PolyList); } } diff --git a/GameRealisticMap/ManMade/Railways/RailwaysData.cs b/GameRealisticMap/ManMade/Railways/RailwaysData.cs index 701ee51e..306f3043 100644 --- a/GameRealisticMap/ManMade/Railways/RailwaysData.cs +++ b/GameRealisticMap/ManMade/Railways/RailwaysData.cs @@ -1,11 +1,12 @@ using System.Text.Json.Serialization; using GameRealisticMap.Geometries; +using GameRealisticMap.Nature; using GeoJSON.Text.Feature; using GeoJSON.Text.Geometry; namespace GameRealisticMap.ManMade.Railways { - public class RailwaysData : IGeoJsonData + public class RailwaysData : IGeoJsonData, INonDefaultArea { [JsonConstructor] public RailwaysData(List railways) @@ -15,6 +16,8 @@ public RailwaysData(List railways) public List Railways { get; } + IEnumerable INonDefaultArea.Polygons => Railways.SelectMany(x => x.ClearPolygons); + public IEnumerable ToGeoJson(Func project) { var properties = new Dictionary() { diff --git a/GameRealisticMap/ManMade/Roads/RoadsData.cs b/GameRealisticMap/ManMade/Roads/RoadsData.cs index 1e8f6a18..5a4b6537 100644 --- a/GameRealisticMap/ManMade/Roads/RoadsData.cs +++ b/GameRealisticMap/ManMade/Roads/RoadsData.cs @@ -1,11 +1,12 @@ using System.Text.Json.Serialization; using GameRealisticMap.Geometries; +using GameRealisticMap.Nature; using GeoJSON.Text.Feature; using GeoJSON.Text.Geometry; namespace GameRealisticMap.ManMade.Roads { - public class RoadsData : IGeoJsonData + public class RoadsData : IGeoJsonData, INonDefaultArea { [JsonConstructor] public RoadsData(List roads) @@ -15,6 +16,8 @@ public RoadsData(List roads) public List Roads { get; } + IEnumerable INonDefaultArea.Polygons => Roads.SelectMany(x => x.ClearPolygons); + public IEnumerable ToGeoJson(Func project) { return Roads.Select(r => new Feature(new MultiPolygon(r.Polygons.Select(p => p.ToGeoJson(project))), new Dictionary() { diff --git a/GameRealisticMap/Nature/DefaultAreas/DefaultAreasBuilder.cs b/GameRealisticMap/Nature/DefaultAreas/DefaultAreasBuilder.cs new file mode 100644 index 00000000..c22dff1e --- /dev/null +++ b/GameRealisticMap/Nature/DefaultAreas/DefaultAreasBuilder.cs @@ -0,0 +1,26 @@ +using GameRealisticMap.Geometries; +using GameRealisticMap.Reporting; + +namespace GameRealisticMap.Nature.DefaultAreas +{ + internal class DefaultAreasBuilder : IDataBuilder + { + private readonly IProgressSystem progress; + + public DefaultAreasBuilder(IProgressSystem progress) + { + this.progress = progress; + } + + public DefaultAreasData Build(IBuildContext context) + { + var allData = context.GetOfType().ToList(); + var allPolygons = allData.ProgressStep(progress, "Polygons") + .SelectMany(l => l.Polygons) + .ToList(); + using var report = progress.CreateStep("SubstractAll", 1); + var polygons = context.Area.TerrainBounds.SubstractAllSplitted(allPolygons).ToList(); + return new DefaultAreasData(polygons); + } + } +} diff --git a/GameRealisticMap/Nature/DefaultAreas/DefaultAreasData.cs b/GameRealisticMap/Nature/DefaultAreas/DefaultAreasData.cs new file mode 100644 index 00000000..ce634114 --- /dev/null +++ b/GameRealisticMap/Nature/DefaultAreas/DefaultAreasData.cs @@ -0,0 +1,24 @@ +using GameRealisticMap.Geometries; +using GeoJSON.Text.Feature; +using GeoJSON.Text.Geometry; + +namespace GameRealisticMap.Nature.DefaultAreas +{ + public class DefaultAreasData : IGeoJsonData, IPolygonTerrainData + { + public DefaultAreasData(List polygons) + { + Polygons = polygons; + } + + public List Polygons { get; } + + public IEnumerable ToGeoJson(Func project) + { + var properties = new Dictionary() { + {"type", "default" } + }; + return Polygons.Select(b => new Feature(b.ToGeoJson(project), properties)); + } + } +} diff --git a/GameRealisticMap/Nature/IBasicTerrainData.cs b/GameRealisticMap/Nature/IBasicTerrainData.cs index a7e6e299..f561e1bb 100644 --- a/GameRealisticMap/Nature/IBasicTerrainData.cs +++ b/GameRealisticMap/Nature/IBasicTerrainData.cs @@ -2,8 +2,10 @@ namespace GameRealisticMap.Nature { - public interface IBasicTerrainData : IGeoJsonData + public interface IBasicTerrainData : IGeoJsonData, INonDefaultArea, IPolygonTerrainData { - List Polygons { get; } + new List Polygons { get; } + + IEnumerable INonDefaultArea.Polygons => Polygons; } } diff --git a/GameRealisticMap/Nature/INonDefaultArea.cs b/GameRealisticMap/Nature/INonDefaultArea.cs new file mode 100644 index 00000000..1924e2f1 --- /dev/null +++ b/GameRealisticMap/Nature/INonDefaultArea.cs @@ -0,0 +1,9 @@ +using GameRealisticMap.Geometries; + +namespace GameRealisticMap.Nature +{ + public interface INonDefaultArea + { + IEnumerable Polygons { get; } + } +} diff --git a/GameRealisticMap/Nature/IPolygonTerrainData.cs b/GameRealisticMap/Nature/IPolygonTerrainData.cs new file mode 100644 index 00000000..beba30a1 --- /dev/null +++ b/GameRealisticMap/Nature/IPolygonTerrainData.cs @@ -0,0 +1,9 @@ +using GameRealisticMap.Geometries; + +namespace GameRealisticMap.Nature +{ + public interface IPolygonTerrainData + { + List Polygons { get; } + } +} diff --git a/GameRealisticMap/Preview/PreviewRender.cs b/GameRealisticMap/Preview/PreviewRender.cs index 7913914c..bf8bb3de 100644 --- a/GameRealisticMap/Preview/PreviewRender.cs +++ b/GameRealisticMap/Preview/PreviewRender.cs @@ -130,7 +130,7 @@ public async Task RenderHtml(IProgressTask progress, string targetFile) public static async Task RenderHtml(BuildContext context, string targetFile) { - await RenderHtml(new FeatureCollection(context.Catalog.GetOfType(context).SelectMany(b => b.ToGeoJson(p => p)).ToList()), targetFile); + await RenderHtml(new FeatureCollection(context.GetOfType().SelectMany(b => b.ToGeoJson(p => p)).ToList()), targetFile); } public static async Task RenderHtml(FeatureCollection collection, string targetFile) diff --git a/GameRealisticMap/Preview/grm-preview.html b/GameRealisticMap/Preview/grm-preview.html index 65990e0a..f78a6a0d 100644 --- a/GameRealisticMap/Preview/grm-preview.html +++ b/GameRealisticMap/Preview/grm-preview.html @@ -23,10 +23,12 @@ + diff --git a/GameRealisticMap/Preview/grm-preview.js b/GameRealisticMap/Preview/grm-preview.js index 8fb43828..93f79048 100644 --- a/GameRealisticMap/Preview/grm-preview.js +++ b/GameRealisticMap/Preview/grm-preview.js @@ -449,6 +449,8 @@ function InitPreview(geoJson) L.control.scale({ maxWidth: 200, imperial: false }).addTo(map); L.control.gridMousePosition().addTo(map); + var stripes = new L.StripePattern(); + stripes.addTo(map); L.geoJSON(geoJson, { style: function(feature) { @@ -483,6 +485,10 @@ function InitPreview(geoJson) case 'ocean': return { fillColor: 'RoyalBlue', fillOpacity: 0.5, stroke: true, weight: 3, color: 'RoyalBlue' }; case 'coastline': return { stroke: true, weight: 1, dashArray: [5, 5], color: 'yellow', fillOpacity: 0 }; + case 'orchard': return { fillColor: 'greenyellow', stroke: false, fillOpacity: 0.35 }; + case 'vineyard': return { fillColor: 'greenyellow', stroke: false, fillOpacity: 0.35 }; + case 'default': + return { fillPattern: stripes, stroke: false, fillOpacity: 0.2 }; } return { fillColor:'black', stroke: false, fillOpacity: 0.2 }; },