Пример #1
0
        /// <summary>
        /// Creates a raster mapper from the transformation.
        /// </summary>
        /// <param name="mode">The raster mapping mode.</param>
        /// <param name="translation">The translation coordinate.</param>
        /// <param name="scale">The scale vector.</param>
        /// <returns>The raster mapper based on the specified transformation.</returns>
        /// <exception cref="System.ArgumentException">
        /// The translation is invalid.
        /// or
        /// The scale is invalid.
        /// or
        /// The scale of the X dimension is equal to 0.
        /// or
        /// The scale of the Y dimension is equal to 0.
        /// </exception>
        public static RasterMapper FromTransformation(RasterMapMode mode, Coordinate translation, CoordinateVector scale)
        {
            if (!translation.IsValid)
            {
                throw new ArgumentException("The translation is invalid.", "translation");
            }
            if (!scale.IsValid)
            {
                throw new ArgumentException("The scale is invalid.", "scale");
            }
            if (scale.X == 0)
            {
                throw new ArgumentException("The scale of the X dimension is equal to 0.", "scale");
            }
            if (scale.Y == 0)
            {
                throw new ArgumentException("The scale of the Y dimension is equal to 0.", "scale");
            }

            Matrix transformation = new Matrix(4, 4);

            transformation[0, 0] = scale.X;
            transformation[1, 1] = scale.Y;
            transformation[2, 2] = scale.Z;
            transformation[0, 3] = translation.X;
            transformation[1, 3] = translation.Y;
            transformation[2, 3] = translation.Z;
            transformation[3, 3] = 1;

            return(new RasterMapper(mode, transformation));
        }
Пример #2
0
        /// <summary>
        /// Creates a raster mapper from raster coordinates.
        /// </summary>
        /// <param name="mode">The raster mapping mode.</param>
        /// <param name="coordinates">The array of coordinates.</param>
        /// <returns>The raster mapper created by linear interpolation of the coordinates.</returns>
        /// <exception cref="System.ArgumentNullException">The array of coordinates is null.</exception>
        /// <exception cref="System.ArgumentException">
        /// The number of coordinates with distinct column index is less than 2.
        /// or
        /// The number of coordinates with distinct row index is less than 2.
        /// </exception>
        public static RasterMapper FromCoordinates(RasterMapMode mode, params RasterCoordinate[] coordinates)
        {
            if (coordinates == null)
            {
                throw new ArgumentNullException("The array of coordinates is null.", "coordinates");
            }

            return(FromCoordinates(mode, coordinates as IList <RasterCoordinate>));
        }
Пример #3
0
        /// <summary>
        /// Creates a raster mapper from raster coordinates.
        /// </summary>
        /// <param name="mode">The raster mapping mode.</param>
        /// <param name="coordinates">The list of coordinates.</param>
        /// <returns>The raster mapper created by linear interpolation of the coordinates.</returns>
        /// <exception cref="System.ArgumentNullException">The array of coordinates is null.</exception>
        /// <exception cref="System.ArgumentException">
        /// The number of coordinates with distinct column index is less than 2.
        /// or
        /// The number of coordinates with distinct row index is less than 2.
        /// </exception>
        public static RasterMapper FromCoordinates(RasterMapMode mode, IList <RasterCoordinate> coordinates)
        {
            if (coordinates == null)
            {
                throw new ArgumentNullException("The list of coordinates is null.", "coordinates");
            }
            if (coordinates.Select(coordinate => coordinate.ColumnIndex).Distinct().Count() < 2)
            {
                throw new ArgumentException("The number of coordinates with distinct column index is less than 2.", "coordinates");
            }
            if (coordinates.Select(coordinate => coordinate.RowIndex).Distinct().Count() < 2)
            {
                throw new ArgumentException("The number of coordinates with distinct row index is less than 2.", "coordinates");
            }

            // compute linear equation system in both dimensions

            Int32[] columnIndices = coordinates.Select(coordinate => coordinate.ColumnIndex).Distinct().ToArray();
            Int32[] rowIndices    = coordinates.Select(coordinate => coordinate.ColumnIndex).Distinct().ToArray();

            Matrix matrix  = new Matrix(coordinates.Count, 3);
            Vector vectorX = new Vector(coordinates.Count);
            Vector vectorY = new Vector(coordinates.Count);

            for (Int32 coordinateIndex = 0; coordinateIndex < coordinates.Count; coordinateIndex++)
            {
                matrix[coordinateIndex, 0] = coordinates[coordinateIndex].ColumnIndex;
                matrix[coordinateIndex, 1] = coordinates[coordinateIndex].RowIndex;
                matrix[coordinateIndex, 2] = 1;

                vectorX[coordinateIndex] = coordinates[coordinateIndex].Coordinate.X;
                vectorY[coordinateIndex] = coordinates[coordinateIndex].Coordinate.Y;
            }

            // solve equation using least squares method
            Vector resultX = LUDecomposition.SolveEquation(matrix.Transpone() * matrix, matrix.Transpone() * vectorX);
            Vector resultY = LUDecomposition.SolveEquation(matrix.Transpone() * matrix, matrix.Transpone() * vectorY);

            // merge the results into a matrix
            Matrix transformation = new Matrix(4, 4);

            transformation[0, 0] = resultX[0];
            transformation[0, 1] = resultX[1];
            transformation[0, 3] = resultX[2];
            transformation[1, 0] = resultY[0];
            transformation[1, 1] = resultY[1];
            transformation[1, 3] = resultY[2];
            transformation[3, 3] = 1;

            return(new RasterMapper(mode, transformation));
        }
Пример #4
0
        /// <summary>
        /// Maps the coordinate at a specified row and column index.
        /// </summary>
        /// <param name="rowIndex">The zero-based row index of the coordinate.</param>
        /// <param name="columnIndex">The zero-based column index of the coordinate.</param>
        /// <param name="mode">The mapping mode.</param>
        /// <returns>The coordinate located at the specified index with respect to the specified mode.</returns>
        /// <exception cref="System.InvalidOperationException">The mapping of the raster is not defined.</exception>
        public Coordinate MapCoordinate(Double rowIndex, Double columnIndex, RasterMapMode mode)
        {
            if (mode == Mode)
            {
                return(MapCoordinate(rowIndex, columnIndex));
            }
            else
            {
                switch (mode)
                {
                case RasterMapMode.ValueIsArea:
                    return(MapCoordinate(rowIndex - 0.5, columnIndex - 0.5));

                default:     // ValueIsCoordinate
                    return(MapCoordinate(rowIndex + 0.5, columnIndex + 0.5));
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="RasterMapper" /> class.
        /// </summary>
        /// <param name="mode">The raster mapping mode.</param>
        /// <param name="transformation">The transformation from raster space to geometry space.</param>
        /// <exception cref="System.ArgumentNullException">The transformation is null.</exception>
        /// <exception cref="System.ArgumentException">
        /// The number of columns in the transformation is not equal to 4.
        /// or
        /// The number of rows in the transformation is not equal to 4.
        /// or
        /// The transformation contains invalid values.
        /// </exception>
        /// <exception cref="System.NotSupportedException">The specified transformation is not supported.</exception>
        public RasterMapper(RasterMapMode mode, Matrix transformation)
        {
            if (transformation == null)
            {
                throw new ArgumentNullException("transformation", "The transformation is null.");
            }
            if (transformation.NumberOfColumns != 4)
            {
                throw new ArgumentException("The number of columns in the transformation is not equal to 4.", "transformation");
            }
            if (transformation.NumberOfRows != 4)
            {
                throw new ArgumentException("The number of rows in the transformation is not equal to 4.", "transformation");
            }

            // check for invalid values
            if (transformation.Any(value => Double.IsNaN(value) || Double.IsInfinity(value)))
            {
                throw new ArgumentException("The transformation contains invalid values.", "transformation");
            }
            if (transformation[3, 0] != 0 || transformation[3, 1] != 0 || transformation[3, 2] != 0 || transformation[3, 3] != 1)
            {
                throw new ArgumentException("The transformation contains invalid values.", "transformation");
            }

            // check for unsupported transformation
            if (transformation[0, 0] == 0 || transformation[1, 1] == 0 ||
                transformation[2, 0] != 0 || transformation[2, 1] != 0 ||
                transformation[0, 2] != 0 || transformation[1, 2] != 0)
            {
                throw new NotSupportedException("The specified transformation is not supported.");
            }

            _isLinearTransformation = (transformation[0, 1] == 0 && transformation[1, 0] == 0); // rotation is not specified

            Mode = mode;
            GeometryTransformation = transformation;

            if (!_isLinearTransformation)
            {
                _rasterTransformation = transformation.Invert();
            }
        }
Пример #6
0
        /// <summary>
        /// Creates a raster mapper from the transformation.
        /// </summary>
        /// <param name="mode">The raster mapping mode.</param>
        /// <param name="translationX">The translation in X dimension.</param>
        /// <param name="translationY">The translation in Y dimension.</param>
        /// <param name="translationZ">The translation in Z dimension.</param>
        /// <param name="scaleX">The scale in X dimension.</param>
        /// <param name="scaleY">The scale in Y dimension.</param>
        /// <param name="scaleZ">The scale in Z dimension.</param>
        /// <returns>The raster mapper based on the specified transformation.</returns>
        /// <exception cref="System.ArgumentException">
        /// The translation of the X dimension is not a number.
        /// or
        /// The translation of the Y dimension is not a number.
        /// or
        /// The translation of the Z dimension is not a number.
        /// or
        /// The scale of the X dimension is not a number or is equal to 0.
        /// or
        /// The scale of the Y dimension is not a number or is equal to 0.
        /// or
        /// The scale of the Z dimension is not a number.
        /// </exception>
        public static RasterMapper FromTransformation(RasterMapMode mode, Double translationX, Double translationY, Double translationZ, Double scaleX, Double scaleY, Double scaleZ)
        {
            if (Double.IsNaN(translationX))
            {
                throw new ArgumentException("The translation of the X dimension is not a number.", "translationX");
            }
            if (Double.IsNaN(translationY))
            {
                throw new ArgumentException("The translation of the Y dimension is not a number.", "translationY");
            }
            if (Double.IsNaN(translationZ))
            {
                throw new ArgumentException("The translation of the Z dimension is not a number.", "translationZ");
            }
            if (Double.IsNaN(scaleX) || scaleX == 0)
            {
                throw new ArgumentException("The scale of the X dimension is not a number or is equal to 0.", "scaleX");
            }
            if (Double.IsNaN(scaleY) || scaleY == 0)
            {
                throw new ArgumentException("The scale of the Y dimension is not a number or is equal to 0.", "scaleY");
            }
            if (Double.IsNaN(scaleZ))
            {
                throw new ArgumentException("The scale of the Z dimension is not a number.", "scaleZ");
            }

            Matrix transformation = new Matrix(4, 4);

            transformation[0, 0] = scaleX;
            transformation[1, 1] = scaleY;
            transformation[2, 2] = scaleZ;
            transformation[0, 3] = translationX;
            transformation[1, 3] = translationY;
            transformation[2, 3] = translationZ;
            transformation[3, 3] = 1;

            return(new RasterMapper(mode, transformation));
        }
Пример #7
0
        /// <summary>
        /// Maps the raster row and column index at the specified coordinate.
        /// </summary>
        /// <param name="coordinate">The coordinate.</param>
        /// <param name="mode">The mapping mode.</param>
        /// <param name="rowIndex">The zero-based column index of the value.</param>
        /// <param name="columnIndex">The zero-based row index of the value.</param>
        public void MapRaster(Coordinate coordinate, RasterMapMode mode, out Double rowIndex, out Double columnIndex)
        {
            if (mode == Mode)
            {
                MapRaster(coordinate, out rowIndex, out columnIndex);
            }
            else
            {
                switch (mode)
                {
                case RasterMapMode.ValueIsArea:
                    MapRaster(coordinate, out rowIndex, out columnIndex);
                    rowIndex    += 0.5;
                    columnIndex += 0.5;
                    break;

                default:     // ValueIsCoordinate
                    MapRaster(coordinate, out rowIndex, out columnIndex);
                    rowIndex    -= 0.5;
                    columnIndex -= 0.5;
                    break;
                }
            }
        }
Пример #8
0
        /// <summary>
        /// Reads the mapping from model space to raster space.
        /// </summary>
        /// <returns>The mapping from model space to raster space.</returns>
        protected RasterMapper ComputeRasterToModelSpaceMapping()
        {
            if (!_currentGeoKeys.ContainsKey(GeoKey.RasterType))
            {
                return(null);
            }

            RasterMapMode mode = Convert.ToInt16(_currentGeoKeys[GeoKey.RasterType]) == 1 ? RasterMapMode.ValueIsArea : RasterMapMode.ValueIsCoordinate;

            Double[] modelTiePointsArray      = null;
            Double[] modelPixelScaleArray     = null;
            Double[] modelTransformationArray = null;

            // gather information from tags
            if (_imageFileDirectories[_currentImageIndex].ContainsKey(TiffTag.ModelTiepointTag))
            {
                modelTiePointsArray = _imageFileDirectories[_currentImageIndex][TiffTag.ModelTiepointTag].Select(value => Convert.ToDouble(value)).ToArray();
            }
            if (_imageFileDirectories[_currentImageIndex].ContainsKey(TiffTag.ModelPixelScaleTag))
            {
                modelPixelScaleArray = _imageFileDirectories[_currentImageIndex][TiffTag.ModelPixelScaleTag].Select(value => Convert.ToDouble(value)).ToArray();
            }
            if (_imageFileDirectories[_currentImageIndex].ContainsKey(TiffTag.ModelTransformationTag))
            {
                modelTransformationArray = _imageFileDirectories[_currentImageIndex][TiffTag.ModelTransformationTag].Select(value => Convert.ToDouble(value)).ToArray();
            }

            // for GeoTIFF 0.2, IntergraphMatrixTag (33920) may contain the transformation values
            if (modelTransformationArray == null && _imageFileDirectories[_currentImageIndex].ContainsKey(TiffTag.IntergraphMatrixTag))
            {
                modelTransformationArray = _imageFileDirectories[_currentImageIndex][TiffTag.IntergraphMatrixTag].Select(value => Convert.ToDouble(value)).ToArray();
            }

            // compute with model tie points
            if (modelTiePointsArray != null && (modelTiePointsArray.Length > 6 || (modelTiePointsArray.Length == 6 && modelPixelScaleArray.Length == 3)))
            {
                if (modelTiePointsArray.Length > 6) // transformation is specified by tie points
                {
                    RasterCoordinate[] coordinates = new RasterCoordinate[modelTiePointsArray.Length / 6];

                    for (Int32 i = 0; i < modelTiePointsArray.Length; i += 6)
                    {
                        coordinates[i / 6] = new RasterCoordinate(Convert.ToInt32(modelTiePointsArray[i]), Convert.ToInt32(modelTiePointsArray[i + 1]), new Coordinate(modelTiePointsArray[i + 3], modelTiePointsArray[i + 4], modelTiePointsArray[i + 5]));
                    }

                    return(RasterMapper.FromCoordinates(mode, coordinates));
                }
                else // transformation is specified by single tie point and scale
                {
                    Coordinate rasterSpaceCoordinate = new Coordinate(modelTiePointsArray[0], modelTiePointsArray[1], modelTiePointsArray[2]);
                    Coordinate modelSpaceCoordinate  = new Coordinate(modelTiePointsArray[3], modelTiePointsArray[4], modelTiePointsArray[5]);
                    Double     scaleX = modelPixelScaleArray[0];
                    Double     scaleY = -modelPixelScaleArray[1];
                    Double     scaleZ = modelPixelScaleArray[2];

                    return(RasterMapper.FromTransformation(mode,
                                                           modelSpaceCoordinate.X - rasterSpaceCoordinate.X * scaleX,
                                                           modelSpaceCoordinate.Y + rasterSpaceCoordinate.Y * scaleY,
                                                           modelSpaceCoordinate.Z - rasterSpaceCoordinate.Z * scaleZ,
                                                           scaleX, scaleY, scaleZ));
                }
            }

            // compute with transformation values
            if (modelTransformationArray != null)
            {
                Matrix transformation = new Matrix(4, 4);
                for (Int32 i = 0; i < 4; i++)
                {
                    for (Int32 j = 0; j < 4; j++)
                    {
                        transformation[i, j] = modelTransformationArray[i * 4 + j];
                    }
                }
                return(RasterMapper.FromTransformation(mode, transformation));
            }

            // nothing is available
            return(null);
        }
Пример #9
0
 /// <summary>
 /// Creates a raster mapper from the transformation.
 /// </summary>
 /// <param name="mode">The raster mapping mode.</param>
 /// <param name="transformation">The transformation from raster space to geometry space.</param>
 /// <returns>The raster mapper based on the specified transformation.</returns>
 /// <exception cref="System.ArgumentNullException">The transformation is null.</exception>
 /// <exception cref="System.ArgumentException">
 /// The number of columns in the transformation is not equal to 4.
 /// or
 /// The number of rows in the transformation is not equal to 4.
 /// or
 /// The transformation contains invalid values.
 /// </exception>
 /// <exception cref="System.NotSupportedException">The specified transformation is not supported.</exception>
 public static RasterMapper FromTransformation(RasterMapMode mode, Matrix transformation)
 {
     return(new RasterMapper(mode, transformation));
 }