< Summary

Information
Class: Morpho25.IO.Inx
Assembly: Morpho25
File(s): D:\a\Morpho\Morpho\project\Morpho\Morpho25\IO\Inx.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 232
Coverable lines: 232
Total lines: 333
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 52
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
get_Model()100%10%
get_TerrainMatrix()100%10%
get_SoilMatrix()100%10%
.ctor(...)100%10%
.ctor(...)0%20%
IsASCIIcorrect(...)0%60%
WriteInx(...)0%440%

File(s)

D:\a\Morpho\Morpho\project\Morpho\Morpho25\IO\Inx.cs

#LineLine coverage
 1using System;
 2using System.Linq;
 3using System.Xml;
 4using System.Text;
 5using Morpho25.Utility;
 6using Morpho25.Settings;
 7using Morpho25.Geometry;
 8using System.Collections.Generic;
 9using System.Data;
 10
 11namespace Morpho25.IO
 12{
 13    /// <summary>
 14    /// INX File class.
 15    /// </summary>
 16    public class Inx
 17    {
 18        const char NEWLINE = '\n';
 19        const string VERSION = "404";
 20        const string CHECK_SUM = "6104088";
 21        /// <summary>
 22        /// Model.
 23        /// </summary>
 024        public Model Model { get; }
 25        /// <summary>
 26        /// Matrix 2D of the terrain.
 27        /// </summary>
 028        public string TerrainMatrix { get; private set; }
 29        /// <summary>
 30        /// Matrix 2D of the soils.
 31        /// </summary>
 032        public string SoilMatrix { get; set; }
 33
 34        /// <summary>
 35        /// Create a new INX File.
 36        /// </summary>
 37        /// <param name="model">Model.</param>
 038        public Inx(Model model)
 039        {
 040            Model = model;
 041            TerrainMatrix = EnvimetUtility.GetASCIImatrix(
 042                Model.EnvimetMatrix["terrainMatrix"]);
 043            SoilMatrix = EnvimetUtility.GetASCIImatrix(
 044                Model.EnvimetMatrix["soilMatrix"]);
 045        }
 46        /// <summary>
 47        /// Create a new INX File. 2.5D only.
 48        /// </summary>
 49        /// <param name="model">Model.</param>
 50        /// <param name="ASCIIterrain">ASCII matrix for DEM.</param>
 051        public Inx(Model model, string ASCIIterrain)
 052        {
 053            Model = model;
 054            if (IsASCIIcorrect(ASCIIterrain))
 055                TerrainMatrix = ASCIIterrain;
 056            SoilMatrix = EnvimetUtility.GetASCIImatrix(
 057                Model.EnvimetMatrix["soilMatrix"]);
 58            // 2D only
 059            Model.IsDetailed = false;
 060        }
 61
 62        private bool IsASCIIcorrect(string ASCIImatrix)
 063        {
 64            // ASCII envimet matrix are made by integers. I
 65            // do not add validation for now.
 66
 067            string[] yDirection = ASCIImatrix.Split('\n');
 068            if (yDirection.Length != Model.Grid.Size.NumY)
 069                throw new ArgumentOutOfRangeException(
 070                    $"{nameof(ASCIImatrix)} must contain {Model.Grid.Size.NumY} elements in Y.");
 071            foreach (string y in yDirection)
 072            {
 073                string[] xDirection = y.Split(',');
 074                if (xDirection.Length != Model.Grid.Size.NumX)
 075                    throw new ArgumentOutOfRangeException(
 076                        $"{nameof(ASCIImatrix)} must contain {Model.Grid.Size.NumX} elements in X.");
 077            }
 078            return true;
 079        }
 80
 81        /// <summary>
 82        /// Write INX file
 83        /// </summary>
 84        /// <param name="fullPath">Full path of INX file to save</param>
 85        public void WriteInx(string fullPath = null)
 086        {
 087            var now = DateTime.Now;
 088            string revisionDate = now.ToString("yyyy-MM-dd HH:mm:ss");
 89
 90            // get objects
 091            Grid grid = Model.Grid;
 092            Location location = Model.Location;
 093            List<Terrain> terrains = Model.TerrainObjects;
 094            List<Building> buildings = Model.BuildingObjects;
 095            List<Plant3d> plant3d = Model.Plant3dObjects;
 096            List<Receptor> receptors = Model.ReceptorObjects;
 97
 98            // Is 3D?
 099            var is3D = Model.IsDetailed;
 0100            var shiftVoxels = Model.ShiftEachVoxel;
 101
 102            // get ascii matrix
 0103            string topMatrix = EnvimetUtility.GetASCIImatrix(Model.EnvimetMatrix["topMatrix"]);
 0104            string bottomMatrix = EnvimetUtility.GetASCIImatrix(Model.EnvimetMatrix["bottomMatrix"]);
 0105            string IDmatrix = EnvimetUtility.GetASCIImatrix(Model.EnvimetMatrix["idMatrix"]);
 0106            string zeroMatrix = EnvimetUtility.GetASCIImatrix(new Matrix2d(grid.Size.NumX, grid.Size.NumY, "0"));
 107
 0108            if (fullPath == null && Model.Workspace == null)
 0109            {
 0110                throw new Exception("Provide a full path of the INX file to save or add Workspace to Model.");
 111            }
 112
 113            // start with xml
 0114            XmlTextWriter xWriter = new XmlTextWriter(fullPath ?? Model.Workspace.ModelPath, Encoding.UTF8);
 0115            xWriter.WriteStartElement("ENVI-MET_Datafile");
 0116            xWriter.WriteString(NEWLINE + " ");
 117
 0118            string[] empty = { };
 119
 0120            string headerTitle = "Header";
 0121            string[] headerTag = new string[] { "filetype", "version", "revisiondate", "remark", "checksum", "encryption
 0122            string[] headerValue = new string[] { "INPX ENVI-met Area Input File", VERSION, revisionDate, "Created with 
 0123            Util.CreateXmlSection(xWriter, headerTitle, headerTag, headerValue, 0, empty);
 124
 0125            string baseDataTitle = "baseData";
 0126            string[] baseDataTag = new string[] { "modelDescription", "modelAuthor", "modelcopyright" };
 0127            string[] baseDataValue = new string[] { " A brave new area ", " Grasshopper envimet ", "The creator or distr
 0128            Util.CreateXmlSection(xWriter, baseDataTitle, baseDataTag, baseDataValue, 0, empty);
 129
 0130            string useSplitting = null;
 0131            string verticalStretch = null;
 0132            string startStretch = null;
 0133            string gridsZ = (grid.IsSplitted)
 0134                ? (grid.Size.NumZ - 4).ToString()
 0135                : grid.Size.NumZ.ToString();
 0136            string useTelescoping = null;
 0137            string gridsI = (grid.Size.NumX).ToString();
 0138            string gridsJ = (grid.Size.NumY).ToString();
 0139            string[] attribute2dElements = { "matrix-data", gridsI, gridsJ };
 0140            string dx = grid.Size.DimX.ToString("n5");
 0141            string dy = grid.Size.DimY.ToString("n5");
 0142            string dz = grid.Size.DimZ.ToString("n5");
 143
 0144            if (grid.Telescope > 0)
 0145            {
 0146                useTelescoping = "1";
 0147                useSplitting = "0";
 0148                verticalStretch = grid.Telescope.ToString("n5");
 0149                startStretch = grid.StartTelescopeHeight.ToString("n5");
 0150                if (grid.CombineGridType)
 0151                    useSplitting = "1";
 0152            }
 153            else
 0154            {
 0155                useTelescoping = "0";
 0156                useSplitting = "1";
 0157                verticalStretch = "0";
 0158                startStretch = "0";
 0159            }
 160
 0161            string modelGeometryTitle = "modelGeometry";
 0162            string[] modelGeometryTag = new string[] { "grids-I", "grids-J", "grids-Z", "dx", "dy", "dz-base", "useTeles
 0163            string[] modelGeometryValue = new string[] { gridsI, gridsJ, gridsZ, dx, dy, dz, useTelescoping, useSplittin
 0164            Util.CreateXmlSection(xWriter, modelGeometryTitle, modelGeometryTag, modelGeometryValue, 0, empty);
 165
 0166            string nestingAreaTitle = "nestingArea";
 0167            string[] nestingAreaTag = new string[] { "numberNestinggrids", "soilProfileA", "soilProfileB" };
 0168            string[] nestingAreaValue = new string[] { grid.NestingGrids.NumberOfCells.ToString(), grid.NestingGrids.Fir
 0169            Util.CreateXmlSection(xWriter, nestingAreaTitle, nestingAreaTag, nestingAreaValue, 0, empty);
 170
 0171            string locationDataTitle = "locationData";
 172
 0173            string utmZone = " ", realworldLowerLeftX = Location.REALWORLD_POINT, realworldLowerLeftY = Location.REALWOR
 174
 0175            if (location.UTM != null)
 0176            {
 0177                utmZone = location.UTM.UTMzone;
 0178                realworldLowerLeftX = location.UTM.UTMesting.ToString();
 0179                realworldLowerLeftY = location.UTM.UTMnorthing.ToString();
 0180            }
 181
 0182            string[] locationDataTag = new string[] { "modelRotation", "projectionSystem", "UTMZone", "realworldLowerLef
 0183            string[] locationDataValue = new string[] { location.ModelRotation.ToString("n5"), Location.PROJECTION_SYSTE
 0184            Util.CreateXmlSection(xWriter, locationDataTitle, locationDataTag, locationDataValue, 0, empty);
 185
 0186            string defaultSettingsTitle = "defaultSettings";
 0187            string[] defaultSettingsTag = new string[] { "commonWallMaterial", "commonRoofMaterial" };
 0188            string[] defaultSettingsValue = new string[] { Material.DEFAULT_WALL, Material.DEFAULT_ROOF };
 0189            Util.CreateXmlSection(xWriter, defaultSettingsTitle, defaultSettingsTag, defaultSettingsValue, 0, empty);
 190
 0191            string buildings2DTitle = "buildings2D";
 0192            string[] buildings2DTag = new string[] { "zTop", "zBottom", "buildingNr", "fixedheight" };
 0193            string[] buildings2DValue = new string[] { NEWLINE + topMatrix, NEWLINE + bottomMatrix, NEWLINE + IDmatrix, 
 0194            Util.CreateXmlSection(xWriter, buildings2DTitle, buildings2DTag, buildings2DValue, 1, attribute2dElements);
 195
 0196            if (Model.Plant2dObjects.Count > 0)
 0197            {
 0198                string plantMatrix = EnvimetUtility.GetASCIImatrix(Model.EnvimetMatrix["plantMatrix"]);
 0199                string simpleplants2DTitle = "simpleplants2D";
 0200                string[] simpleplants2DTag = new string[] { "ID_plants1D" };
 0201                string[] simpleplants2DValue = new string[] { NEWLINE + plantMatrix };
 0202                Util.CreateXmlSection(xWriter, simpleplants2DTitle, simpleplants2DTag, simpleplants2DValue, 1, attribute
 0203            }
 204
 0205            if (plant3d.Count > 0)
 0206            {
 0207                foreach (Plant3d plant in plant3d)
 0208                {
 0209                    string plants3DTitle = "3Dplants";
 0210                    string[] plants3DTag = new string[] { "rootcell_i", "rootcell_j", "rootcell_k", "plantID", "name", "
 0211                    string[] plants3DValue = new string[] { plant.Pixel.I.ToString(), plant.Pixel.J.ToString(), plant.Pi
 0212                    Util.CreateXmlSection(xWriter, plants3DTitle, plants3DTag, plants3DValue, 0, empty);
 0213                }
 0214            }
 215
 0216            if (receptors.Count > 0)
 0217            {
 0218                foreach (Receptor receptor in receptors)
 0219                {
 0220                    string receptorsTitle = "Receptors";
 0221                    string[] receptorsTag = new string[] { "cell_i", "cell_j", "name" };
 0222                    string[] receptorsValue = new string[] { receptor.Pixel.I.ToString(), receptor.Pixel.J.ToString(), r
 0223                    Util.CreateXmlSection(xWriter, receptorsTitle, receptorsTag, receptorsValue, 0, empty);
 0224                }
 0225            }
 226
 0227            string soils2DTitle = "soils2D";
 0228            string[] soils2DTag = new string[] { "ID_soilprofile" };
 0229            string[] soils2DValue = new string[] { NEWLINE + SoilMatrix };
 0230            Util.CreateXmlSection(xWriter, soils2DTitle, soils2DTag, soils2DValue, 1, attribute2dElements);
 231
 0232            string demTitle = "dem";
 0233            string[] demDTag = new string[] { "terrainheight" };
 0234            string[] demValue = new string[] { NEWLINE + TerrainMatrix };
 0235            Util.CreateXmlSection(xWriter, demTitle, demDTag, demValue, 1, attribute2dElements);
 236
 0237            if (Model.SourceObjects.Count > 0)
 0238            {
 0239                string sourceMatrix = EnvimetUtility.GetASCIImatrix(Model.EnvimetMatrix["sourceMatrix"]);
 0240                string sources2DTitle = "sources2D";
 0241                string[] sources2DTag = new string[] { "ID_sources" };
 0242                string[] sources2DValue = new string[] { NEWLINE + sourceMatrix };
 0243                Util.CreateXmlSection(xWriter, sources2DTitle, sources2DTag, sources2DValue, 1, attribute2dElements);
 0244            }
 245
 0246            if (buildings.Count > 0)
 0247            {
 0248                foreach (Building building in buildings)
 0249                {
 0250                    string bps = building.ObserveBPS ? "1" : "0";
 251
 0252                    string buildinginfoTitle = "Buildinginfo";
 0253                    string[] buildinginfoTag = new string[] { "BuildingInternalNr", "BuildingName", "BuildingWallMateria
 0254                    string[] buildinginfoValue = new string[] { building.ID.ToString(), building.Name, building.Material
 0255                    Util.CreateXmlSection(xWriter, buildinginfoTitle, buildinginfoTag, buildinginfoValue, 0, empty);
 0256                }
 0257            }
 258
 0259            if (!is3D)
 0260            {
 0261                xWriter.WriteEndElement();
 0262                xWriter.Close();
 0263                return;
 264            }
 265
 266            // 3D part
 0267            var gridsK = grid.Size.NumZ.ToString();
 0268            string[] attribute3dElements = { "sparematrix-3D", gridsI, gridsJ, gridsK, "" };
 0269            string[] attribute3dBuildings3D = { "sparematrix-3D", gridsI, gridsJ, gridsK, "0" };
 0270            string[] attribute3dDem3D = { "sparematrix-3D", gridsI, gridsJ, gridsK, "0.00000" };
 271
 0272            string modelGeometry3DTitle = "modelGeometry3D";
 0273            string[] modelGeometry3DTag = new string[] { "grids3D-I", "grids3D-J", "grids3D-K" };
 0274            string[] modelGeometry3DValue = new string[] { gridsI, gridsJ, gridsK };
 0275            Util.CreateXmlSection(xWriter, modelGeometry3DTitle, modelGeometry3DTag, modelGeometry3DValue, 0, empty);
 276
 277            // 3D ID
 0278            var terrainPixels = terrains.SelectMany(_ => _.Pixels)
 0279                .ToList();
 0280            if (!terrainPixels.Any()) terrainPixels = null;
 281
 0282            var idMatrix = new List<string>() { string.Empty };
 0283            var wallMatrix = new List<string>() { string.Empty };
 0284            var greenMatrix = new List<string>() { string.Empty };
 285
 0286            foreach (var building in buildings)
 0287            {
 0288                building.SetMatrix3d(grid, terrainPixels, shiftVoxels);
 0289                idMatrix.AddRange(building.BuildingIDrows);
 0290                wallMatrix.AddRange(building.BuildingWallRows);
 0291                greenMatrix.AddRange(building.BuildingGreenWallRows);
 0292            }
 0293            idMatrix.Add(string.Empty);
 0294            wallMatrix.Add(string.Empty);
 0295            greenMatrix.Add(string.Empty);
 296
 0297            string buildings3DTitle = "buildings3D";
 0298            string[] buildings3DTag = new string[] { "buildingFlagAndNr" };
 0299            string[] buildings3DValue = new string[] { String.Join("\n", idMatrix) };
 0300            Util.CreateXmlSection(xWriter, buildings3DTitle, buildings3DTag, buildings3DValue, 2, attribute3dBuildings3D
 301
 0302            var demMatrix = new List<string>() { string.Empty };
 0303            foreach (var terrain in terrains)
 0304            {
 0305                demMatrix.AddRange(terrain.TerrainIDrows);
 0306            }
 0307            demMatrix.Add(string.Empty);
 308
 0309            string dem3DTitle = "dem3D";
 0310            string[] dem3DTag = new string[] { "terrainflag" };
 0311            string[] dem3DValue = new string[] { String.Join("\n", demMatrix) };
 0312            Util.CreateXmlSection(xWriter, dem3DTitle, dem3DTag, dem3DValue, 2, attribute3dDem3D);
 313
 0314            string wallDBTitle = "WallDB";
 0315            string[] wallDBTag = new string[] { "ID_wallDB" };
 0316            string[] wallDBValue = new string[] { String.Join("\n", wallMatrix) };
 0317            Util.CreateXmlSection(xWriter, wallDBTitle, wallDBTag, wallDBValue, 2, attribute3dElements);
 318
 0319            string singleWallDBTitle = "SingleWallDB";
 0320            string[] singleWallDBTag = new string[] { "ID_singlewallDB" };
 0321            string[] singleWallDBValue = new string[] { "\n" };
 0322            Util.CreateXmlSection(xWriter, singleWallDBTitle, singleWallDBTag, singleWallDBValue, 2, attribute3dElements
 323
 0324            string greeningDBTitle = "GreeningDB";
 0325            string[] greeningDBTag = new string[] { "ID_GreeningDB" };
 0326            string[] greeningDBValue = new string[] { String.Join("\n", greenMatrix) };
 0327            Util.CreateXmlSection(xWriter, greeningDBTitle, greeningDBTag, greeningDBValue, 2, attribute3dElements);
 328
 0329            xWriter.WriteEndElement();
 0330            xWriter.Close();
 0331        }
 332    }
 333}