/// <summary>
        /// Prepares the result of the operation.
        /// </summary>
        /// <returns>The resulting geometry.</returns>
        protected override ISpectralGeometry PrepareResult()
        {
            Dictionary <Segment, Dictionary <Int32, Int32> > segmentToClassDictionary = new Dictionary <Segment, Dictionary <Int32, Int32> >();
            Dictionary <Int32, Int32> classToIndexDictionary = new Dictionary <Int32, Int32>();

            IRaster referenceRaster = _referenceGeometry.Raster;
            Int32   sourceRowIndex, sourceColumnIndex;

            // map all values (and indices) to segments
            for (Int32 rowIndex = 0; rowIndex < referenceRaster.NumberOfRows; rowIndex++)
            {
                for (Int32 columnIndex = 0; columnIndex < referenceRaster.NumberOfColumns; columnIndex++)
                {
                    Int32 referenceHashCode = 0;

                    switch (referenceRaster.Format)
                    {
                    case RasterFormat.Floating:
                        Double[] referenceFloatValues = referenceRaster.GetFloatValues(rowIndex, columnIndex);
                        if (referenceFloatValues.All(value => value == 0))
                        {
                            continue;
                        }

                        referenceHashCode = referenceFloatValues.Select(value => value.GetHashCode()).Aggregate((x, y) => (x << 1) ^ y);
                        break;

                    case RasterFormat.Integer:

                        UInt32[] referenceValues = referenceRaster.GetValues(rowIndex, columnIndex);
                        if (referenceValues.All(value => value == 0))
                        {
                            continue;
                        }

                        referenceHashCode = referenceValues.Select(value => value.GetHashCode()).Aggregate((x, y) => (x << 1) ^ y);
                        break;
                    }

                    // match the source coordinates
                    if (!referenceRaster.IsMapped || !Source.Raster.IsMapped || Source.Raster.Coordinates.SequenceEqual(referenceRaster.Coordinates))
                    {
                        sourceColumnIndex = columnIndex;
                        sourceRowIndex    = rowIndex;
                    }
                    else
                    {
                        Coordinate coordinate = referenceRaster.Mapper.MapCoordinate(rowIndex, columnIndex);
                        Source.Raster.Mapper.MapRaster(coordinate, out sourceRowIndex, out sourceColumnIndex);
                    }

                    // check if the reference location is available in the source
                    if (sourceRowIndex < 0 || sourceRowIndex >= Source.Raster.NumberOfRows || sourceColumnIndex < 0 || sourceColumnIndex >= Source.Raster.NumberOfColumns)
                    {
                        continue;
                    }

                    Segment segment = _segmentCollection.GetSegment(sourceRowIndex, sourceColumnIndex);

                    // check if the segment was already mapped
                    if (!segmentToClassDictionary.ContainsKey(segment))
                    {
                        segmentToClassDictionary.Add(segment, new Dictionary <Int32, Int32>());
                    }

                    if (!segmentToClassDictionary[segment].ContainsKey(referenceHashCode))
                    {
                        segmentToClassDictionary[segment].Add(referenceHashCode, 0);
                    }

                    segmentToClassDictionary[segment][referenceHashCode]++;

                    if (!classToIndexDictionary.ContainsKey(referenceHashCode))
                    {
                        classToIndexDictionary.Add(referenceHashCode, rowIndex * referenceRaster.NumberOfColumns + columnIndex);
                    }
                }
            }

            _segmentToIndexDictionary = new Dictionary <Segment, Int32>();

            // filter indices for most frequent value
            foreach (Segment segment in segmentToClassDictionary.Keys)
            {
                Int32 maxValueHashCode = 0;

                foreach (Int32 referenceHashCode in segmentToClassDictionary[segment].Keys)
                {
                    if (maxValueHashCode == 0 || segmentToClassDictionary[segment][referenceHashCode] > segmentToClassDictionary[segment][maxValueHashCode])
                    {
                        maxValueHashCode = referenceHashCode;
                    }
                }

                _segmentToIndexDictionary.Add(segment, classToIndexDictionary[maxValueHashCode]);
            }

            SetResultProperties(_referenceGeometry.Raster.Format, _referenceGeometry.Raster.NumberOfBands, Source.Raster.NumberOfRows, Source.Raster.NumberOfColumns, _referenceGeometry.Raster.RadiometricResolution, Source.Raster.Mapper, _referenceGeometry.Presentation, _referenceGeometry.Imaging);

            return(base.PrepareResult());
        }
예제 #2
0
 /// <summary>
 /// Returns all spectral values at a specified row and column index.
 /// </summary>
 /// <param name="rowIndex">The zero-based row index of the values.</param>
 /// <param name="columnIndex">The zero-based column index of the values.</param>
 /// <returns>The array containing the spectral values for each band at the specified index.</returns>
 protected override Double[] ApplyGetFloatValues(Int32 rowIndex, Int32 columnIndex)
 {
     return(_source.GetFloatValues(_rowIndex + rowIndex, _columnIndex + columnIndex));
 }