Exemplo n.º 1
0
        /// <summary>
        /// Forms a table by filling it with supplied data
        /// </summary>
        /// <param name="boundaries">including the "outer boundaries" of bounding layer</param>
        /// <param name="samples">All samples in the project</param>
        /// <returns></returns>
        public static ReportTable GenerateTableContents(
            Intervals.BoreIntervalVM[] intervals,
            LayerBoundary[] boundaries,
            LayerDescrition[] layers,
            string[] rankNames,
            Sample[] samples,
            AnnotationDirection annotationDirection)
        {
            //asserting intervals
            //lower - upper bounds order
            //intersection check
            List <KeyValuePair <double, int> > intBounds = new List <KeyValuePair <double, int> >();

            for (int i = 0; i < intervals.Length; i++)
            {
                Intervals.BoreIntervalVM interval = intervals[i];
                if (interval.LowerDepth < interval.UpperDepth)
                {
                    throw new ArgumentException("The upper bound is lower than lower bound");
                }
                intBounds.Add(new KeyValuePair <double, int>(interval.UpperDepth, 1));  // +1 opens the interval
                intBounds.Add(new KeyValuePair <double, int>(interval.LowerDepth, -1)); // -1 closes the interval
            }
            // detecting intervals with touching bounds; removing these bounds
            double[] keys = intBounds.Select(kvp => kvp.Key).ToArray();
            foreach (int key in keys)
            {
                int curKeyValsSum = intBounds.Where(kvp => kvp.Key == key).Sum(kvp => kvp.Value);
                if (curKeyValsSum == 0)
                {
                    intBounds = intBounds.Where(kvp => kvp.Key != key).ToList();
                }
            }

            int[] events = intBounds.OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value).ToArray();
            int   sum    = 0;

            for (int i = 0; i < events.Length; i++)
            {
                sum += events[i];
                if (Math.Abs(sum) > 1)
                {
                    throw new InvalidOperationException("You've passed intersecting intervals");
                }
            }


            List <ReportRow> rows = new List <ReportRow>();

            if (boundaries.Length - 1 != layers.Length)
            {
                throw new ArgumentException("Layers count must be exactly one more than boundary count");
            }

            string directionString = string.Empty;

            switch (annotationDirection)
            {
            case AnnotationDirection.UpToBottom:
                directionString = "сверху вниз";
                break;

            case AnnotationDirection.BottomToUp:
                directionString = "снизу вверх";
                break;
            }

            ReportRow header = new ReportRow(
                new TextCell[] {
                new TextCell(
                    string.Format("Описание керна {0}.\nИнтервал / выход керна в м.", directionString),
                    LeftColWidth, horizontalAlignement: TextAlignement.Centered, isBold: true),
                new TextCell("место отбора от начала керна, м; описание", RightcolWidth, horizontalAlignement: TextAlignement.Centered, isBold: true)
            });

            rows.Add(header);

            int reportedInIndex;
            int inIndex;
            int laIndex;
            int layerOrderNum;

            //for now works with increasing depths order
            switch (annotationDirection)
            {
            case AnnotationDirection.UpToBottom:
                intervals = intervals.OrderBy(i => i.UpperDepth).ToArray();
                for (int i = 0; i < boundaries.Length - 1; i++)
                {
                    if (boundaries[i + 1].Depth < boundaries[i].Depth)
                    {
                        throw new NotSupportedException("Boundary depths must increase");
                    }
                }

                reportedInIndex = -1;
                inIndex         = 0;
                laIndex         = 0;
                layerOrderNum   = 1;
                while (inIndex < intervals.Length && laIndex < layers.Length)
                {
                    if (reportedInIndex != inIndex)
                    {
                        //adding row depicting interval start
                        rows.Add(GetIntervalRow(intervals[inIndex].UpperDepth, intervals[inIndex].LowerDepth, intervals[inIndex].ExtractedLength));
                        reportedInIndex = inIndex;
                    }
                    LayerBoundary upperLabound  = boundaries[laIndex];
                    double        curLaUpper    = upperLabound.Depth;
                    double        curLaLower    = boundaries[laIndex + 1].Depth; //boundraies array always contains one more element than layers
                    double        curIntUpper   = intervals[inIndex].UpperDepth;
                    double        curIntLower   = intervals[inIndex].UpperDepth + intervals[inIndex].ExtractedLength;
                    bool          doInInc       = false;
                    bool          doLaInc       = false;
                    bool          skipReporting = false;

                    //analysing the relative position of the interval and the layer
                    if (curIntLower >= curLaLower)
                    {
                        //the interval includes the end of the layer or interval is entirly below the layer
                        if (curIntUpper > curLaLower)
                        {
                            //the entire interal is below the layer
                            skipReporting = true;     //the layer is not reported
                        }
                        else
                        {
                            if (curIntUpper > curLaUpper)
                            {
                                //coersing layer upper bound to match interval
                                curLaUpper = curIntUpper;
                            }
                        }
                        doLaInc = true;
                    }
                    else
                    {
                        //the layer includes the end of the interval
                        curLaLower = curIntLower;     //coersing layer lower bound to match interval
                        if (curIntUpper > curLaUpper)
                        {
                            //coersing layer upper bound to match interval
                            curLaUpper = curIntUpper;
                        }

                        doInInc = true;
                    }

                    if (!skipReporting)
                    {
                        if (upperLabound.Rank > 0)
                        {
                            //we need to add rank row
                            for (int rank = upperLabound.Rank; rank > 0; rank--)
                            {
                                double length = 0.0;
                                //calculating total length. starting from cur bound till the next bound of the same rank or higher
                                for (int i = laIndex + 1; i < boundaries.Length; i++)
                                {
                                    int curRank = boundaries[i].Rank;
                                    length += boundaries[i].Depth - boundaries[i - 1].Depth;
                                    if (curRank >= rank)
                                    {
                                        break;
                                    }
                                }

                                length = Math.Min(length, curIntLower - upperLabound.Depth);
                                rows.Add(GetRankDescrRow(upperLabound.OrderNumbers[rank], rankNames[rank], length));
                            }
                            layerOrderNum = 1;     //ranks higher than 0 reset the numbering of layers
                        }
                        var layerSamples = samples.Where(s => (s.Depth > curLaUpper) && (s.Depth < curLaLower)).ToArray();
                        rows.Add(GetLayerDescrRow(layerOrderNum++, curLaLower - curLaUpper, layers[laIndex], layerSamples));
                    }
                    if (doLaInc)
                    {
                        laIndex++;
                    }
                    if (doInInc)
                    {
                        inIndex++;
                    }
                }
                break;

            case AnnotationDirection.BottomToUp:
                intervals = intervals.OrderBy(i => i.UpperDepth).ToArray();
                for (int i = boundaries.Length - 2; i >= 0; i--)
                {
                    if (boundaries[i + 1].Depth < boundaries[i].Depth)
                    {
                        throw new NotSupportedException("Boundary depths must increase");
                    }
                }

                reportedInIndex = intervals.Length;
                inIndex         = intervals.Length - 1;
                laIndex         = layers.Length - 1;
                layerOrderNum   = 1;
                //while (inIndex < intervals.Length && laIndex < layers.Length)
                while (inIndex >= 0 && laIndex >= 0)
                {
                    if (reportedInIndex != inIndex)
                    {
                        //adding row depicting interval start
                        rows.Add(GetIntervalRow(intervals[inIndex].UpperDepth, intervals[inIndex].LowerDepth, intervals[inIndex].ExtractedLength));
                        reportedInIndex = inIndex;
                    }
                    LayerBoundary upperLabound  = boundaries[laIndex];
                    LayerBoundary lowerLaBound  = boundaries[laIndex + 1];
                    double        curLaUpper    = upperLabound.Depth;
                    double        curLaLower    = boundaries[laIndex + 1].Depth; //boundraies array always contains one more element than layers
                    double        curIntUpper   = intervals[inIndex].UpperDepth;
                    double        curIntLower   = intervals[inIndex].UpperDepth + intervals[inIndex].ExtractedLength;
                    bool          doInDec       = false;
                    bool          doLaDec       = false;
                    bool          skipReporting = false;

                    //analysing the relative position of the interval and the layer
                    //if (curIntLower >= curLaLower)
                    if (curIntUpper <= curLaUpper)
                    {
                        //the interval includes the end of the layer or interval is entirly alte the layer

                        //if (curIntUpper > curLaLower)
                        if (curIntLower < curLaUpper)
                        {
                            //the entire interal is after the layer
                            skipReporting = true;     //the layer is not reported
                        }
                        else
                        {
                            //if (curIntUpper > curLaUpper)
                            if (curIntLower < curLaLower)
                            {
                                //coersing layer lower bound to match interval

                                //curLaUpper = curIntUpper;
                                curLaLower = curIntLower;
                            }
                        }
                        doLaDec = true;
                    }
                    else
                    {
                        //the layer includes the end of the interval
                        //curLaLower = curIntLower; //coersing layer lower bound to match interval
                        curLaUpper = curIntUpper;     //coersing layer upper bound to match interval
                        //if (curIntUpper > curLaUpper)
                        if (curIntLower < curLaLower)
                        {
                            //coersing layer lower bound to match interval

                            //curLaUpper = curIntUpper;
                            curLaLower = curIntLower;
                        }

                        doInDec = true;
                    }

                    if (!skipReporting)
                    {
                        //if (upperLabound.Rank > 0)
                        if (lowerLaBound.Rank > 0)
                        {
                            //we need to add rank row
                            for (int rank = lowerLaBound.Rank; rank > 0; rank--)
                            {
                                double length = 0.0;
                                //calculating total length. starting from cur bound till the next bound of the same rank or higher
                                //for (int i = laIndex + 1; i < boundaries.Length; i++)
                                for (int i = laIndex; i >= 0; i--)
                                {
                                    int curRank = boundaries[i].Rank;
                                    //length += boundaries[i].Depth - boundaries[i - 1].Depth;
                                    length += boundaries[i + 1].Depth - boundaries[i].Depth;
                                    if (curRank >= rank)
                                    {
                                        break;
                                    }
                                }

                                //length = Math.Min(length, curIntLower - upperLabound.Depth);
                                length = Math.Min(length, lowerLaBound.Depth - curIntUpper);
                                if (rank == lowerLaBound.Rank)
                                {
                                    //as the lower boundary contains passed order number, we need to repot the next numbe (incremented by one)
                                    rows.Add(GetRankDescrRow(lowerLaBound.OrderNumbers[rank] + 1, rankNames[rank], length));
                                }
                                else
                                {
                                    //passing hight rank bundary means that lower rank numberings reset
                                    rows.Add(GetRankDescrRow(1, rankNames[rank], length));
                                }
                            }
                            layerOrderNum = 1;     //ranks higher than 0 reset the numbering of layers
                        }
                        var layerSamples = samples.Where(s => (s.Depth > curLaUpper) && (s.Depth < curLaLower)).ToArray();
                        rows.Add(GetLayerDescrRow(layerOrderNum++, curLaLower - curLaUpper, layers[laIndex], layerSamples));
                    }
                    if (doLaDec)
                    {
                        laIndex--;
                    }
                    if (doInDec)
                    {
                        inIndex--;
                    }
                }
                break;

            default:
                throw new NotSupportedException();
                break;
            }

            return(new ReportTable(rows.ToArray()));
        }
        /// <summary>
        /// Forms a table by filling it with supplied data
        /// </summary>
        /// <param name="intervals"></param>
        /// <param name="boundaries">including the "outer boundaries" of bounding layer</param>
        /// <param name="layers"></param>
        /// <param name="isDepthIncreases">true if depth increases (other parameter arrays are sorted so the depth increases)</param>
        /// <param name="samples">All samples in the project</param>
        /// <returns></returns>
        public static CSV.ReportTable GenerateCVSTableContents(
            Intervals.BoreIntervalVM[] intervals,
            RTF.LayerBoundary[] boundaries,
            RTF.LayerDescrition[] layers,
            string[] rankNames,
            RTF.Sample[] samples,
            AnnotationDirection annotationDirection,
            AnnotationPlane.Template.Property[] allProperties,
            string[] genRankNames
            )
        {
            List <KeyValuePair <double, int> > intBounds = new List <KeyValuePair <double, int> >();

            for (int i = 0; i < intervals.Length; i++)
            {
                Intervals.BoreIntervalVM interval = intervals[i];
                if (interval.LowerDepth < interval.UpperDepth)
                {
                    throw new ArgumentException("The upper bound is lower than lower bound");
                }
                intBounds.Add(new KeyValuePair <double, int>(interval.UpperDepth, 1));
                intBounds.Add(new KeyValuePair <double, int>(interval.LowerDepth, -1));
            }
            double[] keys = intBounds.Select(kvp => kvp.Key).ToArray();
            foreach (int key in keys)
            {
                int curKeyValsSum = intBounds.Where(kvp => kvp.Key == key).Sum(kvp => kvp.Value);
                if (curKeyValsSum == 0)
                {
                    intBounds = intBounds.Where(kvp => kvp.Key != key).ToList();
                }
            }

            int[] events = intBounds.OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value).ToArray();
            int   sum    = 0;

            for (int i = 0; i < events.Length; i++)
            {
                sum += events[i];
                if (Math.Abs(sum) > 1)
                {
                    throw new InvalidOperationException("You've passed intersecting intervals");
                }
            }


            List <CSV.ReportRow> rows = new List <CSV.ReportRow>();

            if (boundaries.Length - 1 != layers.Length)
            {
                throw new ArgumentException("Layers count must be exactly one more than boundary count");
            }

            string directionString = string.Empty;

            switch (annotationDirection)
            {
            case AnnotationDirection.UpToBottom:
                directionString = "сверху вниз";
                break;

            case AnnotationDirection.BottomToUp:
                directionString = "снизу вверх";
                break;
            }

            List <string> allColumnsList = new List <string>();

            allColumnsList.Add("№ " + genRankNames[0]);
            allColumnsList.Add("№ " + genRankNames[1]);
            allColumnsList.Add("№ " + genRankNames[2]);
            allColumnsList.Add("Верхняя граница слоя (м)");
            allColumnsList.Add("Нижняя граница слоя (м)");

            foreach (AnnotationPlane.Template.Property prop in allProperties)
            {
                allColumnsList.Add(string.IsNullOrEmpty(prop.Name) ? prop.Name : prop.ID);
            }

            CSV.ReportRow header = new CSV.ReportRow(allColumnsList.ToArray());
            rows.Add(header);

            int reportedInIndex;
            int inIndex;
            int laIndex;
            int layerOrderNum;
            int group_number = 1;
            int pack_number  = 1;

            switch (annotationDirection)
            {
            case AnnotationDirection.UpToBottom:
                intervals = intervals.OrderBy(i => i.UpperDepth).ToArray();
                for (int i = 0; i < boundaries.Length - 1; i++)
                {
                    if (boundaries[i + 1].Depth < boundaries[i].Depth)
                    {
                        throw new NotSupportedException("Boundary depths must increase");
                    }
                }

                reportedInIndex = -1;
                inIndex         = 0;
                laIndex         = 0;
                layerOrderNum   = 1;
                while (inIndex < intervals.Length && laIndex < layers.Length)
                {
                    if (reportedInIndex != inIndex)
                    {
                        reportedInIndex = inIndex;
                    }
                    RTF.LayerBoundary upperLabound = boundaries[laIndex];
                    double            curLaUpper   = upperLabound.Depth;
                    double            curLaLower   = boundaries[laIndex + 1].Depth;
                    double            curIntUpper  = intervals[inIndex].UpperDepth;
                    double            curIntLower  = intervals[inIndex].UpperDepth + intervals[inIndex].ExtractedLength;
                    bool doInInc       = false;
                    bool doLaInc       = false;
                    bool skipReporting = false;

                    if (curIntLower >= curLaLower)
                    {
                        if (curIntUpper > curLaLower)
                        {
                            skipReporting = true;
                        }
                        else
                        {
                            if (curIntUpper > curLaUpper)
                            {
                                curLaUpper = curIntUpper;
                            }
                        }
                        doLaInc = true;
                    }
                    else
                    {
                        curLaLower = curIntLower;
                        if (curIntUpper > curLaUpper)
                        {
                            curLaUpper = curIntUpper;
                        }

                        doInInc = true;
                    }

                    List <int> group_pack = GetGroupPackNumbersForUpperLaBound(upperLabound, laIndex, boundaries, curIntLower, rankNames);

                    switch (upperLabound.Rank)
                    {
                    case 2:
                        group_number  = group_pack[0];
                        pack_number   = 1;
                        layerOrderNum = 1;
                        break;

                    case 1:
                        pack_number   = group_pack[0];
                        layerOrderNum = 1;
                        break;

                    default:
                        break;
                    }

                    if (!skipReporting)
                    {
                        var layerSamples = samples.Where(s => (s.Depth > curLaUpper) && (s.Depth < curLaLower)).ToArray();
                        rows.Add(GetLayerDescrRow(layerOrderNum++, curLaLower, curLaUpper, layers[laIndex], layerSamples, group_number, pack_number, allProperties));
                    }
                    if (doLaInc)
                    {
                        laIndex++;
                    }
                    if (doInInc)
                    {
                        inIndex++;
                    }
                }
                break;

            case AnnotationDirection.BottomToUp:
                intervals = intervals.OrderBy(i => i.UpperDepth).ToArray();
                for (int i = boundaries.Length - 2; i >= 0; i--)
                {
                    if (boundaries[i + 1].Depth < boundaries[i].Depth)
                    {
                        throw new NotSupportedException("Boundary depths must increase");
                    }
                }

                reportedInIndex = intervals.Length;
                inIndex         = intervals.Length - 1;
                laIndex         = layers.Length - 1;
                layerOrderNum   = 1;
                while (inIndex >= 0 && laIndex >= 0)
                {
                    if (reportedInIndex != inIndex)
                    {
                        reportedInIndex = inIndex;
                    }
                    RTF.LayerBoundary upperLabound = boundaries[laIndex];
                    RTF.LayerBoundary lowerLaBound = boundaries[laIndex + 1];
                    double            curLaUpper   = upperLabound.Depth;
                    double            curLaLower   = boundaries[laIndex + 1].Depth;
                    double            curIntUpper  = intervals[inIndex].UpperDepth;
                    double            curIntLower  = intervals[inIndex].UpperDepth + intervals[inIndex].ExtractedLength;
                    bool doInDec       = false;
                    bool doLaDec       = false;
                    bool skipReporting = false;

                    if (curIntUpper <= curLaUpper)
                    {
                        if (curIntLower < curLaUpper)
                        {
                            skipReporting = true;
                        }
                        else
                        {
                            if (curIntLower < curLaLower)
                            {
                                curLaLower = curIntLower;
                            }
                        }
                        doLaDec = true;
                    }
                    else
                    {
                        curLaUpper = curIntUpper;
                        if (curIntLower < curLaLower)
                        {
                            curLaLower = curIntLower;
                        }

                        doInDec = true;
                    }

                    if (!skipReporting)
                    {
                        List <int> group_pack = GetGroupPackNumbersForLowerLaBound(lowerLaBound, laIndex, boundaries, curIntUpper, rankNames);

                        switch (lowerLaBound.Rank)
                        {
                        case 2:
                            group_number  = group_pack[0];
                            pack_number   = group_pack[1];
                            layerOrderNum = 1;
                            break;

                        case 1:
                            pack_number   = group_pack[0];
                            layerOrderNum = 1;
                            break;

                        default:
                            break;
                        }

                        var layerSamples = samples.Where(s => (s.Depth > curLaUpper) && (s.Depth < curLaLower)).ToArray();
                        rows.Add(GetLayerDescrRow(layerOrderNum++, curLaLower, curLaUpper, layers[laIndex], layerSamples, group_number, pack_number, allProperties));
                    }
                    if (doLaDec)
                    {
                        laIndex--;
                    }
                    if (doInDec)
                    {
                        inIndex--;
                    }
                }
                break;

            default:
                throw new NotSupportedException();
            }

            return(new CSV.ReportTable(rows.ToArray()));
        }
Exemplo n.º 3
0
        public static void Generate(string fileName, SamplesColumnVM samplesCol, Intervals.BoreIntervalVM[] intervals, Layer[] layers, string[] propNames)
        {
            using (StreamWriter textWriter = new StreamWriter(File.Open(fileName, FileMode.Create), Encoding.UTF8))
            {
                var csv = new CsvWriter(textWriter);

                //writing header
                csv.WriteField("Глубина (м)");
                csv.WriteField("Описание");
                csv.WriteField("Верх интервала (м)");
                csv.WriteField("Низ интервала (м)");
                for (int j = 0; j < propNames.Length; j++)
                {
                    csv.WriteField(propNames[j]);
                }
                csv.NextRecord();


                for (int i = 0; i < samplesCol.Samples.Length; i++)
                {
                    SampleVM sVM = samplesCol.Samples[i];

                    //searching for correspondence
                    Intervals.BoreIntervalVM containingInterval = null;
                    for (int j = 0; j < intervals.Length; j++)
                    {
                        var int1 = intervals[j];
                        if (sVM.Depth > int1.UpperDepth && sVM.Depth < int1.LowerDepth)
                        {
                            containingInterval = int1;
                            break;
                        }
                    }

                    Layer containingLayer = null;
                    for (int j = 0; j < layers.Length; j++)
                    {
                        Layer l = layers[j];
                        if (sVM.Depth > l.TopDepth && sVM.Depth < l.BottomDepth)
                        {
                            containingLayer = l;
                            break;
                        }
                    }

                    //fields to write
                    string   depth     = string.Format("{0:0.##}", sVM.Depth);
                    string   name      = string.Format("{0}", sVM.Comment);
                    string   intTop    = (containingInterval == null) ? "" : string.Format("{0:0.##}", containingInterval.UpperDepth);
                    string   intBottom = (containingInterval == null) ? "" : string.Format("{0:0.##}", containingInterval.LowerDepth);
                    string[] props     = null;
                    if (containingLayer == null)
                    {
                        props = Enumerable.Repeat("", propNames.Length).ToArray();
                    }
                    else
                    {
                        props = new string[propNames.Length];
                        for (int j = 0; j < containingLayer.Classifications.Length; j++)
                        {
                            ClassificationLayerVM clVM = containingLayer.Classifications[j];

                            SingleClassificationLayerVM sclVM = clVM as SingleClassificationLayerVM;
                            if (sclVM != null)
                            {
                                if (sclVM.CurrentClass != null)
                                {
                                    props[j] = ClassToString(sclVM.CurrentClass);
                                }
                            }
                            MultiClassificationLayerVM mclVM = clVM as MultiClassificationLayerVM;
                            if (mclVM != null)
                            {
                                if (mclVM.CurrentClasses != null)
                                {
                                    props[j] = string.Join(", ", mclVM.CurrentClasses.Select(c => ClassToString(c)).ToArray());
                                }
                            }
                        }
                    }

                    //writing fields
                    csv.WriteField(depth);
                    csv.WriteField(name);
                    csv.WriteField(intTop);
                    csv.WriteField(intBottom);
                    for (int j = 0; j < props.Length; j++)
                    {
                        csv.WriteField(props[j]);
                    }
                    csv.NextRecord();
                }
            }
        }