/// <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())); }
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(); } } }