Ejemplo n.º 1
0
        /// <summary>
        /// Extract sub-area of dfsu (2D) file to a new dfsu file
        /// </summary>
        /// <param name="sourceFilename">Name of source file, i.e. OresundHD.dfsu test file</param>
        /// <param name="outputFilename">Name of output file</param>
        /// <param name="x1">Lower left x coordinate of sub area</param>
        /// <param name="y1">Lower left y coordinate of sub area</param>
        /// <param name="x2">upper right x coordinate of sub area</param>
        /// <param name="y2">upper right y coordinate of sub area</param>
        public static void ExtractSubareaDfsu2D(string sourceFilename, string outputFilename, double x1, double y1, double x2, double y2)
        {
            DfsuFile dfsu = DfsFileFactory.DfsuFileOpen(sourceFilename);

            // Node coordinates
            double[] X    = dfsu.X;
            double[] Y    = dfsu.Y;
            float[]  Z    = dfsu.Z;
            int[]    Code = dfsu.Code;

            // Loop over all elements, and all its nodes: If one node is inside
            // region, element (and nodes) are to be included in new mesh
            List <int> elmtsIncluded = new List <int>();

            bool[] nodesIncluded = new bool[dfsu.NumberOfNodes];
            for (int i = 0; i < dfsu.NumberOfElements; i++)
            {
                // Nodes of element
                int[] nodes = dfsu.ElementTable[i];

                // Check if one of the nodes of the element is inside region
                bool elmtIncluded = false;
                for (int j = 0; j < nodes.Length; j++)
                {
                    int node = nodes[j] - 1;
                    if (x1 <= X[node] && X[node] <= x2 && y1 <= Y[node] && Y[node] <= y2)
                    {
                        elmtIncluded = true;
                    }
                }

                if (elmtIncluded)
                {
                    // Add element to list of included elements
                    elmtsIncluded.Add(i);
                    // Mark all nodes of element as included
                    for (int j = 0; j < nodes.Length; j++)
                    {
                        int node = nodes[j] - 1;
                        nodesIncluded[node] = true;
                    }
                }
            }

            // array containing numbers of existing nodes in new mesh (indices)
            int[] renumber = new int[dfsu.NumberOfNodes];

            // new mesh nodes
            List <double> X2      = new List <double>();
            List <double> Y2      = new List <double>();
            List <float>  Z2      = new List <float>();
            List <int>    Code2   = new List <int>();
            List <int>    nodeIds = new List <int>();

            int i2 = 0;

            for (int i = 0; i < dfsu.NumberOfNodes; i++)
            {
                if (nodesIncluded[i])
                {
                    X2.Add(X[i]);
                    Y2.Add(Y[i]);
                    Z2.Add(Z[i]);
                    Code2.Add(Code[i]);
                    nodeIds.Add(dfsu.NodeIds[i]);
                    // Node with index i will get index i2 in new mesh
                    renumber[i] = i2;
                    i2++;
                }
            }

            // New mesh elements
            List <int[]> elmttable2 = new List <int[]>();
            List <int>   elmtIds    = new List <int>();

            for (int i = 0; i < elmtsIncluded.Count; i++)
            {
                // Add new element
                int   elmt  = elmtsIncluded[i];
                int[] nodes = dfsu.ElementTable[elmt];
                // newNodes must be renumbered
                int[] newNodes = new int[nodes.Length];
                for (int j = 0; j < nodes.Length; j++)
                {
                    // Do the renumbering of nodes from existing mesh to new mesh
                    newNodes[j] = renumber[nodes[j] - 1] + 1;
                }
                elmttable2.Add(newNodes);
                elmtIds.Add(dfsu.ElementIds[i]);
            }

            // Create 2D dfsu file
            DfsuBuilder builder = DfsuBuilder.Create(DfsuFileType.Dfsu2D);

            // Setup header and geometry
            builder.SetNodes(X2.ToArray(), Y2.ToArray(), Z2.ToArray(), Code2.ToArray());
            //builder.SetNodeIds(nodeIds.ToArray());
            builder.SetElements(elmttable2.ToArray());
            builder.SetElementIds(elmtIds.ToArray()); // retain original element id's
            builder.SetProjection(dfsu.Projection);
            builder.SetTimeInfo(dfsu.StartDateTime, dfsu.TimeStepInSeconds);
            if (dfsu.ZUnit == eumUnit.eumUUnitUndefined)
            {
                builder.SetZUnit(eumUnit.eumUmeter);
            }
            else
            {
                builder.SetZUnit(dfsu.ZUnit);
            }

            // Add dynamic items, copying from source
            for (int i = 0; i < dfsu.ItemInfo.Count; i++)
            {
                IDfsSimpleDynamicItemInfo itemInfo = dfsu.ItemInfo[i];
                builder.AddDynamicItem(itemInfo.Name, itemInfo.Quantity);
            }

            // Create new file
            DfsuFile dfsuOut = builder.CreateFile(outputFilename);

            // Add new data
            float[] data2 = new float[elmtsIncluded.Count];
            for (int i = 0; i < dfsu.NumberOfTimeSteps; i++)
            {
                for (int j = 0; j < dfsu.ItemInfo.Count; j++)
                {
                    // Read data from existing dfsu
                    IDfsItemData <float> itemData = (IDfsItemData <float>)dfsu.ReadItemTimeStep(j + 1, i);
                    // Extract value for elements in new mesh
                    for (int k = 0; k < elmtsIncluded.Count; k++)
                    {
                        data2[k] = itemData.Data[elmtsIncluded[k]];
                    }
                    // write data
                    dfsuOut.WriteItemTimeStepNext(itemData.Time, data2);
                }
            }
            dfsuOut.Close();
            dfsu.Close();
        }