diff --git a/TileBakeLibrary/CityJSONParsing/CityJSON.cs b/TileBakeLibrary/CityJSONParsing/CityJSON.cs index 3d18dad..5e13218 100644 --- a/TileBakeLibrary/CityJSONParsing/CityJSON.cs +++ b/TileBakeLibrary/CityJSONParsing/CityJSON.cs @@ -44,12 +44,14 @@ public class CityJSON public Vector3Double TransformOffset { get => transformOffset; } private int minHoleVertices = 3; + private float minHoleSize = 1; - public CityJSON(string filepath, bool applyTransformScale = true, bool applyTransformOffset = true, int minHoleVertices = 3) + public CityJSON(string filepath, bool applyTransformScale = true, bool applyTransformOffset = true, int minHoleVertices = 3, float minHoleSize = 1) { sourceFilePath = filepath; cityJsonNode = JSON.StreamParse(filepath); this.minHoleVertices = minHoleVertices; + this.minHoleSize = minHoleSize; if (cityJsonNode == null || cityJsonNode["CityObjects"] == null) { @@ -390,6 +392,9 @@ private Surface ReadSurfaceVectors(JSONNode surfacenode, CityObject sourceCityOb if(!createInnerRings) return surf; + + Vector3Double v1; + Vector3Double v2; for (int i = 1; i < surfacenode.Count; i++) { verts = new List(); @@ -398,12 +403,27 @@ private Surface ReadSurfaceVectors(JSONNode surfacenode, CityObject sourceCityOb verts.Add(vertices[vectornode.AsInt]); } - //Only more than triangle as holes + //Skip certain holes if they are too small, of dont have enough vertices if(verts.Count < minHoleVertices) { sourceCityObject.holeWarnings += $"- Found a hole with less than {minHoleVertices} vertices, skipping this hole.\n"; } - else{ + else + { + //Calculate the area of the hole + double holeSize = 0; + for (int j = 0; j < verts.Count; j++) + { + v1 = verts[j]; + v2 = verts[(j + 1) % verts.Count]; + holeSize += (v1.X * v2.Z - v1.Z * v2.X); + } + if(holeSize < minHoleSize) + { + sourceCityObject.holeWarnings += $"- Found a hole with an area size of {holeSize}, skipping this hole.\n"; + continue; + } + surf.innerRings.Add(verts); } } diff --git a/TileBakeLibrary/CityJSONToTileConverter.cs b/TileBakeLibrary/CityJSONToTileConverter.cs index c85610c..0c9fee7 100644 --- a/TileBakeLibrary/CityJSONToTileConverter.cs +++ b/TileBakeLibrary/CityJSONToTileConverter.cs @@ -60,6 +60,7 @@ public class CityJSONToTileConverter private float spikeFloor = 0; private int minHoleVertices = 3; + private float minHoleSize = 0.0001f; private int filecounter = 0; private int totalFiles = 0; @@ -87,9 +88,22 @@ public void SetClipSpikes(bool setFunction, float ceiling, float floor) spikeFloor = floor; } - public void SetMinHoleVertices(int minVertices) + /// + /// Sets the minimum amount of vertices a hole should have to be considered a hole + /// + /// Min vertex count of the hole loop. Defaults to 3 ( a triangle ) + public void SetMinHoleVertices(int minHoleVertices) + { + this.minHoleVertices = minHoleVertices; + } + + /// + /// Sets the minimum size of a hole in square meters + /// + /// Hole min size in square meters + public void SetMinHoleSize(float minHoleSize) { - minHoleVertices = minVertices; + this.minHoleSize = minHoleSize; } /// @@ -217,7 +231,7 @@ public void Convert() totalFiles = sourceFiles.Length; if (sourceFiles.Length > 0) { - cityJson = new CityJSON(sourceFiles[0], true, true, minHoleVertices); + cityJson = new CityJSON(sourceFiles[0], true, true, minHoleVertices, minHoleSize); } for (int i = 0; i < sourceFiles.Length; i++) { @@ -229,7 +243,7 @@ public void Convert() nextJsonID = i; } Thread thread; - thread = new Thread(() => { nextCityJSON = new CityJSON(sourceFiles[nextJsonID], true, true, minHoleVertices); }); + thread = new Thread(() => { nextCityJSON = new CityJSON(sourceFiles[nextJsonID], true, true, minHoleVertices, minHoleSize); }); thread.Start(); //Start reading current CityJSON diff --git a/TileBakeLibrary/Config/ConfigFile.cs b/TileBakeLibrary/Config/ConfigFile.cs index b13a9c5..c1dde1c 100644 --- a/TileBakeLibrary/Config/ConfigFile.cs +++ b/TileBakeLibrary/Config/ConfigFile.cs @@ -33,6 +33,7 @@ public class ConfigFile public int tileSize { get; set; } = 1000; public float mergeVerticesBelowAngle { get; set; } = 5; public int minHoleVertices { get; set; } = 3; + public float minHoleSize { get; set; } = 0; public bool brotliCompression { get; set; } = false; public bool removeSpikes { get; set; } = false; public float removeSpikesAbove { get; set; } = 25;