/// <summary> /// Generates the indices of the segment. /// </summary> /// <param name="parentMortonCode">The Morton code of the parent segment.</param> /// <param name="startRowIndex">Start row index.</param> /// <param name="endRowIndex">End row index.</param> /// <param name="startColumnIndex">Start column index.</param> /// <param name="endColumnIndex">End column index.</param> /// <param name="step">The step number.</param> private void GenerateIndices(Double parentMortonCode, Int32 startRowIndex, Int32 endRowIndex, Int32 startColumnIndex, Int32 endColumnIndex, Int32 step) { Double[] spectralValues; List <Int32> indices = new List <Int32>(); Segment segment = new Segment(Raster.NumberOfBands, Statistics); for (Int32 rowIndex = startRowIndex; rowIndex <= endRowIndex; rowIndex++) { for (Int32 columnIndex = startColumnIndex; columnIndex <= endColumnIndex; columnIndex++) { indices.Add(rowIndex * Raster.NumberOfColumns + columnIndex); spectralValues = new Double[Raster.NumberOfBands]; spectralValues = Raster.GetFloatValues(rowIndex, columnIndex); segment.AddFloatValues(spectralValues); } } if (indices.Count != 0) { segment.MortonCode = parentMortonCode * 10 + step; _segmentToIndexDictionary.Add(segment, indices); foreach (Int32 index in indices) { _indexToSegmentDictionary[index] = segment; } } Count = _segmentToIndexDictionary.Count; }
/// <summary> /// Initializes a new instance of the <see cref="SegmentCollection" /> class. /// </summary> /// <param name="other">The other segment collection.</param> /// <param name="statistics">The spectral statistics.</param> /// <exception cref="System.ArgumentNullException">The other segment collection is null.</exception> public SegmentCollection(SegmentCollection other, SpectralStatistics statistics) { if (other == null) { throw new ArgumentNullException("other", "The other segment collection is null."); } Raster = other.Raster; Count = other.Count; Statistics = other.Statistics | statistics; _indexToSegmentDictionary = new Dictionary <Int32, Segment>(); _segmentToIndexDictionary = new Dictionary <Segment, List <Int32> >(); foreach (Segment otherSegment in other._segmentToIndexDictionary.Keys) { List <Int32> otherIndices = other._segmentToIndexDictionary[otherSegment]; Segment segment; if (Statistics == other.Statistics) { segment = new Segment(otherSegment); otherIndices.ForEach(x => _indexToSegmentDictionary.Add(x, segment)); } else { Int32 rowIndex = otherIndices[0] / Raster.NumberOfColumns; Int32 columnIndex = otherIndices[0] % Raster.NumberOfColumns; if (Raster.Format == RasterFormat.Integer) { segment = new Segment(Raster.GetValues(rowIndex, columnIndex), Statistics); for (Int32 i = 0; i < other._segmentToIndexDictionary[otherSegment].Count; i++) { _indexToSegmentDictionary.Add(otherIndices[i], segment); rowIndex = otherIndices[i] / Raster.NumberOfColumns; columnIndex = otherIndices[i] % Raster.NumberOfColumns; segment.AddValues(Raster.GetValues(rowIndex, columnIndex)); } } else { segment = new Segment(Raster.GetFloatValues(rowIndex, columnIndex), Statistics); for (Int32 i = 0; i < other._segmentToIndexDictionary[otherSegment].Count; i++) { _indexToSegmentDictionary.Add(otherIndices[i], segment); rowIndex = otherIndices[i] / Raster.NumberOfColumns; columnIndex = otherIndices[i] % Raster.NumberOfColumns; segment.AddFloatValues(Raster.GetFloatValues(rowIndex, columnIndex)); } } } _segmentToIndexDictionary.Add(segment, new List <Int32>(otherIndices)); } }
/// <summary> /// Merges the specified segments. /// </summary> /// <param name="segment">The segment.</param> /// <param name="rowIndex">The row index.</param> /// <param name="columnIndex">The column index.</param> private void ApplyMergeSegments(Segment segment, Int32 index) { segment.AddFloatValues(Raster.GetFloatValues(index / Raster.NumberOfColumns, index % Raster.NumberOfColumns)); _indexToSegmentDictionary[index] = segment; _segmentToIndexDictionary[segment].Add(index); Count--; }
/// <summary> /// Merges the segments at the specified indices. /// </summary> /// <param name="firstRowIndex">The first row index.</param> /// <param name="firstColumnIndex">The first column index.</param> /// <param name="secondRowIndex">The second row index.</param> /// <param name="secondColumnIndex">The second column index.</param> /// <exception cref="System.ArgumentOutOfRangeException"> /// The first row index is less than 0. /// or /// The first row index is equal to or greater than the number of rows. /// or /// The first column index is less than 0. /// or /// The first column index is equal to or greater than the number of columns. /// or /// The second row index is less than 0. /// or /// The second row index is equal to or greater than the number of rows. /// or /// The second column index is less than 0. /// or /// The second column index is equal to or greater than the number of columns. /// </exception> public virtual void MergeSegments(Int32 firstRowIndex, Int32 firstColumnIndex, Int32 secondRowIndex, Int32 secondColumnIndex) { if (firstRowIndex < 0) { throw new ArgumentOutOfRangeException("firstRowIndex", "The first row index is less than 0."); } if (firstRowIndex >= Raster.NumberOfRows) { throw new ArgumentOutOfRangeException("firstRowIndex", "The first row index is equal to or greater than the number of rows."); } if (firstColumnIndex < 0) { throw new ArgumentOutOfRangeException("firstColumnIndex", "The first column index is less than 0."); } if (firstColumnIndex >= Raster.NumberOfColumns) { throw new ArgumentOutOfRangeException("firstColumnIndex", "The first column index is equal to or greater than the number of columns."); } if (secondRowIndex < 0) { throw new ArgumentOutOfRangeException("secondRowIndex", "The second row index is less than 0."); } if (secondRowIndex >= Raster.NumberOfRows) { throw new ArgumentOutOfRangeException("secondRowIndex", "The second row index is equal to or greater than the number of rows."); } if (secondColumnIndex < 0) { throw new ArgumentOutOfRangeException("secondColumnIndex", "The second column index is less than 0."); } if (secondColumnIndex >= Raster.NumberOfColumns) { throw new ArgumentOutOfRangeException("secondColumnIndex", "The second column index is equal to or greater than the number of columns."); } // query the sets Int32 firstIndex = firstRowIndex * Raster.NumberOfColumns + firstColumnIndex; Int32 secondIndex = secondRowIndex * Raster.NumberOfColumns + secondColumnIndex; if (firstIndex == secondIndex) { return; } // apply merge on the available set if (!_indexToSegmentDictionary.ContainsKey(firstIndex)) { if (!_indexToSegmentDictionary.ContainsKey(secondIndex)) { Segment segment = new Segment(Raster.GetFloatValues(firstRowIndex, firstColumnIndex), Statistics); segment.AddFloatValues(Raster.GetFloatValues(secondRowIndex, secondColumnIndex)); _indexToSegmentDictionary.Add(firstIndex, segment); _indexToSegmentDictionary.Add(secondIndex, segment); _segmentToIndexDictionary.Add(segment, new List <Int32> { firstIndex, secondIndex }); Count--; } else { ApplyMergeSegments(_indexToSegmentDictionary[secondIndex], firstIndex); } } else if (!_indexToSegmentDictionary.ContainsKey(secondIndex)) { ApplyMergeSegments(_indexToSegmentDictionary[firstIndex], secondIndex); } else // or merge the sets { Segment firstSegment = _indexToSegmentDictionary[firstIndex]; Segment secondSegment = _indexToSegmentDictionary[secondIndex]; if (firstSegment == secondSegment) { return; } if (firstSegment.Count > secondSegment.Count) { ApplyMergeSegments(firstSegment, secondSegment); } else { ApplyMergeSegments(secondSegment, firstSegment); } } }