public void MakeBuildingWithStoreysTest() { // arrange var buildingHeight = 10; var storeys = new List <Storey>(); storeys.Add(new Storey() { From = 0, To = 5, Color = "#ff0000" }); storeys.Add(new Storey() { From = 5, To = 10, Color = "#D3D3D3" }); var bs = new BuildingStyle() { FloorColor = "#D3D3D3", RoofColor = "#ff0000", WallsColor = "#00ff00" }; bs.Storeys = storeys; // act var res = TesselateBuilding.MakeBuilding(footprint, 0, buildingHeight, bs); // assert var footprintTriangles = TesselateBuilding.Tesselate(footprint, height).Count; Assert.IsTrue(res.polygons.Count == footprintTriangles * 2 + (footprint.ExteriorRing.Points.Count - 1) * 2 * storeys.Count); }
public void TriangulateBuildingTest() { var bs = new BuildingStyle() { FloorColor = "#D3D3D3", RoofColor = "#ff0000", WallsColor = "#00ff00" }; var res = TesselateBuilding.MakeBuilding(footprint, 0, height, bs); var footprintTriangles = TesselateBuilding.Tesselate(footprint, height).Count; Assert.IsTrue(res.polygons.Count == footprintTriangles * 2 + (footprint.ExteriorRing.Points.Count - 1) * 2); }
static void Main(string[] args) { var version = Assembly.GetEntryAssembly().GetName().Version; Console.WriteLine($"Tool: Tesselate buildings {version}"); var stopWatch = new Stopwatch(); stopWatch.Start(); Parser.Default.ParseArguments <Options>(args).WithParsed(o => { o.User = string.IsNullOrEmpty(o.User) ? Environment.UserName : o.User; o.Database = string.IsNullOrEmpty(o.Database) ? Environment.UserName : o.Database; var outputProjection = (o.Format == "mapbox" ? 3857 : 4978); var connectionString = $"Host={o.Host};Username={o.User};Database={o.Database};Port={o.Port}"; var istrusted = TrustedConnectionChecker.HasTrustedConnection(connectionString); if (!istrusted) { Console.Write($"Password for user {o.User}: "); password = PasswordAsker.GetPassword(); connectionString += $";password={password}"; Console.WriteLine(); } var conn = new NpgsqlConnection(connectionString); SqlMapper.AddTypeHandler(new GeometryTypeHandler()); conn.Open(); var select = $"select ST_AsBinary({o.InputGeometryColumn}) as geometry, {o.HeightColumn} as height, style, {o.IdColumn} as id"; var sql = $"{select} from {o.Table}"; var buildings = conn.Query <Building>(sql); var i = 1; foreach (var building in buildings) { var polygon = (Polygon)building.Geometry; var wktFootprint = polygon.SerializeString <WktSerializer>(); var height = building.Height; var points = polygon.ExteriorRing.Points; var buildingZ = 0; //put everything on the ground var res = TesselateBuilding.MakeBuilding(polygon, buildingZ, height, building.BuildingStyle); var wkt = res.polyhedral.SerializeString <WktSerializer>(); var shaders = new ShaderColors(); shaders.PbrMetallicRoughnessColors = new PbrMetallicRoughnessColors() { BaseColors = res.colors }; var json = JsonConvert.SerializeObject(shaders, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); var updateSql = $"update {o.Table} set {o.OutputGeometryColumn} = ST_Transform(ST_Force3D(St_SetSrid(ST_GeomFromText('{wkt}'), 4326)), {outputProjection}) " + $", {o.ShadersColumn} = '{json}' where {o.IdColumn}={building.Id}"; conn.Execute(updateSql); var perc = Math.Round((double)i / buildings.AsList().Count * 100, 2); Console.Write($"\rProgress: {perc.ToString("F")}%"); i++; } conn.Close(); stopWatch.Stop(); Console.WriteLine(); Console.WriteLine($"Elapsed: {stopWatch.ElapsedMilliseconds / 1000} seconds"); Console.WriteLine("Program finished."); }); }