public void ClipRasterWithPolygonTest() { if (DotSpatial.Data.DataManager.DefaultDataManager.PreferredProviders.Count == 0) { DotSpatial.Data.Rasters.GdalExtension.GdalRasterProvider lGdalRasterProvider = new DotSpatial.Data.Rasters.GdalExtension.GdalRasterProvider(); } String path = AppDomain.CurrentDomain.BaseDirectory; String shapeFilePath = System.IO.Path.Combine(path, "Data", "elbe_watershed1.shp"); String rasterFilePath = System.IO.Path.Combine(path, "Data", "kriging.bgd" ); String resultFilePath = System.IO.Path.Combine(path, "Data", "clipResult.bgd" ); DotSpatial.Data.Shapefile lClipPolygon = DotSpatial.Data.Shapefile.OpenFile(shapeFilePath); DotSpatial.Data.IRaster lGridToClip = DotSpatial.Data.Raster.OpenFile(rasterFilePath, false); DotSpatial.Data.Raster lGridAfterClip = new DotSpatial.Data.Raster(); lGridAfterClip.Filename = resultFilePath; DotSpatial.Analysis.ClipRaster.ClipRasterWithPolygon(lClipPolygon.Features[0], lGridToClip, lGridAfterClip.Filename); IRaster ras2 = Raster.Open(lGridAfterClip.Filename); Assert.AreEqual(lGridToClip.NoDataValue, ras2.NoDataValue); }
public void ClipRasterWithPolygonTest() { if (DotSpatial.Data.DataManager.DefaultDataManager.PreferredProviders.Count == 0) { DotSpatial.Data.Rasters.GdalExtension.GdalRasterProvider lGdalRasterProvider = new DotSpatial.Data.Rasters.GdalExtension.GdalRasterProvider(); } DotSpatial.Data.Shapefile lClipPolygon = DotSpatial.Data.Shapefile.OpenFile(@"C:\Users\Jiri\Desktop\berounka.shp"); DotSpatial.Data.IRaster lGridToClip = DotSpatial.Data.Raster.OpenFile(@"C:\Users\Jiri\Desktop\kriging2.bgd", false); DotSpatial.Data.Raster lGridAfterClip = new DotSpatial.Data.Raster(); lGridAfterClip.Filename = @"C:\Users\Jiri\Desktop\kriging2.bgd"; DotSpatial.Analysis.ClipRaster.ClipRasterWithPolygon(lClipPolygon.Features[0], lGridToClip, lGridAfterClip.Filename); IRaster ras2 = Raster.Open(lGridAfterClip.Filename); Assert.AreEqual(lGridAfterClip.NoDataValue, ras2.NoDataValue); }
// ------------------------------------------FROM AND TO IN RAM ONLY ----------------- /// <summary> /// This creates a completely new raster from the windowed domain on the original raster. This new raster /// will not have a source file, and values like NumRowsInFile will correspond to the in memory version. /// All the values will be copied to the new source file. InRam must be true at this level. /// </summary> /// <param name="fileName"></param> /// <param name="startRow">The 0 based integer index of the top row to copy from this raster. If this raster is itself a window, 0 represents the startRow from the file.</param> /// <param name="endRow">The integer index of the bottom row to copy from this raster. The largest allowed value is NumRows - 1.</param> /// <param name="startColumn">The 0 based integer index of the leftmost column to copy from this raster. If this raster is a window, 0 represents the startColumn from the file.</param> /// <param name="endColumn">The 0 based integer index of the rightmost column to copy from this raster. The largest allowed value is NumColumns - 1</param> /// <param name="copyValues">If this is true, the values are saved to the file. If this is false and the data can be loaded into Ram, no file handling is done. Otherwise, a file of NoData values is created.</param> /// <param name="inRam">Boolean. If this is true and the window is small enough, a copy of the values will be loaded into memory.</param> /// <returns>An implementation of IRaster</returns> public IRaster CopyWindow(string fileName, int startRow, int endRow, int startColumn, int endColumn, bool copyValues, bool inRam) { if (inRam == false || (endColumn - startColumn + 1) * (endRow - startRow + 1) > 64000000) { throw new ArgumentException(DataStrings.RasterRequiresCast); } if (IsInRam == false) { throw new ArgumentException(DataStrings.RasterRequiresCast); } int numCols = endColumn - startColumn + 1; int numRows = endRow - startRow + 1; var result = new Raster <T>(numRows, numCols); result.Projection = Projection; // The affine coefficients defining the world file are the same except that they are translated over. Only the position of the // upper left corner changes. Everything else is the same as the previous raster. result.Bounds.AffineCoefficients = new AffineTransform(Bounds.AffineCoefficients).TransfromToCorner(startColumn, startRow); ProgressMeter pm = new ProgressMeter(ProgressHandler, DataStrings.CopyingValues, numRows); // copy values directly using both data structures for (int row = 0; row < numRows; row++) { for (int col = 0; col < numCols; col++) { result.Data[row][col] = Data[startRow + row][startColumn + col]; } pm.CurrentValue = row; } pm.Reset(); result.Value = new ValueGrid <T>(result); return(result); }
/// <summary> /// Constructing an ObjectGrid this way assumes the values are not in ram and will /// simply buffer 3 rows. /// </summary> /// <param name="sourceRaster"></param> public ValueGrid(Raster <T> sourceRaster) { _sourceRaster = sourceRaster; _topRow = 0; _rowBuffer = new T[3][]; }
/// <summary> /// This open method is only called if this plugin has been given priority for one /// of the file extensions supported in the DialogReadFilter property supplied by /// this control. Failing to provide a DialogReadFilter will result in this plugin /// being added to the list of DataProviders being supplied under the Add Other Data /// option in the file menu. /// </summary> /// <param name="fileName">A string specifying the complete path and extension of the file to open.</param> /// <returns>An IDataSet to be added to the Map. These can also be groups of datasets.</returns> public virtual IRaster Open(string fileName) { RasterDataType fileDataType = GetDataType(fileName); Raster raster = null; switch (fileDataType) { case RasterDataType.BYTE: raster = new BgdRaster <byte> { ProgressHandler = ProgressHandler, Filename = fileName }; break; case RasterDataType.SHORT: raster = new BgdRaster <short> { ProgressHandler = ProgressHandler, Filename = fileName }; break; case RasterDataType.INTEGER: raster = new BgdRaster <int> { ProgressHandler = ProgressHandler, Filename = fileName }; break; case RasterDataType.LONG: raster = new BgdRaster <long> { ProgressHandler = ProgressHandler, Filename = fileName }; break; case RasterDataType.SINGLE: raster = new BgdRaster <float> { ProgressHandler = ProgressHandler, Filename = fileName }; break; case RasterDataType.DOUBLE: raster = new BgdRaster <double> { ProgressHandler = ProgressHandler, Filename = fileName }; break; case RasterDataType.SBYTE: raster = new BgdRaster <sbyte> { ProgressHandler = ProgressHandler, Filename = fileName }; break; case RasterDataType.USHORT: raster = new BgdRaster <ushort> { ProgressHandler = ProgressHandler, Filename = fileName }; break; case RasterDataType.UINTEGER: raster = new BgdRaster <uint> { ProgressHandler = ProgressHandler, Filename = fileName }; break; case RasterDataType.ULONG: raster = new BgdRaster <ulong> { ProgressHandler = ProgressHandler, Filename = fileName }; break; case RasterDataType.BOOL: raster = new BgdRaster <bool> { ProgressHandler = ProgressHandler, Filename = fileName }; break; } raster?.Open(); return(raster); }
/// <summary> /// Copies the contents from the specified sourceRaster into this sourceRaster. If both rasters are InRam, this does not affect the files. /// </summary> /// <param name="sourceRaster">The raster of values to paste into this raster. If the CellWidth and CellHeight values do not match between the files, /// an exception will be thrown. If the sourceRaster overlaps with the edge of this raster, only the intersecting region will be /// pasted.</param> /// <param name="startRow">Specifies the row in this raster where the top row of the sourceRaster will be pasted </param> /// <param name="startColumn">Specifies the column in this raster where the left column of the sourceRaster will be pasted.</param> public void PasteRaster(Raster <T> sourceRaster, int startRow, int startColumn) { int byteSize = ByteSize; if (sourceRaster.DataType != typeof(int)) { throw new ArgumentException( DataStrings.ArgumentOfWrongType_S1_S2.Replace("%S1", "sourceRaster").Replace("%S2", "BinaryRaster")); } if (startRow + sourceRaster.NumRows <= 0) { return; // sourceRaster is above this raster } if (startColumn + sourceRaster.NumColumns <= 0) { return; // sourceRaster is left of this raster } if (startRow > NumRows) { return; // sourceRaster is below this raster } if (startColumn > NumColumns) { return; // sourceRaster is to the right of this raster } if (sourceRaster.CellWidth != CellWidth || sourceRaster.CellHeight != CellHeight) { throw new ArgumentException(DataStrings.RastersNeedSameCellSize); } // These are specified in coordinates that match the source raster int sourceStartColumn = 0; int sourceStartRow = 0; int destStartColumn = startColumn; int destStartRow = startRow; int numPasteColumns = sourceRaster.NumColumns; int numPasteRows = sourceRaster.NumRows; // adjust range to cover only the overlapping sections if (startColumn < 0) { sourceStartColumn = -startColumn; destStartColumn = 0; } if (startRow < 0) { sourceStartRow = -startRow; destStartRow = 0; } if (numPasteRows + destStartRow > NumRows) { numPasteRows = (NumRows - destStartRow); } if (numPasteColumns + destStartColumn > NumColumns) { numPasteColumns = (NumColumns - destStartRow); } if (IsInRam) { // ---------------------- RAM BASED ------------------------------------------------------ if (sourceRaster.IsInRam) { // both members are inram, so directly copy values. for (int row = 0; row < numPasteRows; row++) { for (int col = 0; col < numPasteColumns; col++) { // since we are copying direct, we don't have to do a type check on T Data[destStartRow + row][destStartColumn + col] = sourceRaster.Data[sourceStartRow + row][sourceStartColumn + col]; } } } else { FileStream fs = new FileStream(sourceRaster.Filename, FileMode.Open, FileAccess.Write, FileShare.None, (numPasteColumns) * byteSize); ProgressMeter pm = new ProgressMeter(ProgressHandler, DataStrings.ReadingValuesFrom_S.Replace("%S", sourceRaster. Filename), numPasteRows); fs.Seek(HeaderSize, SeekOrigin.Begin); // Position the binary reader at the top of the "sourceRaster" fs.Seek(sourceStartRow * sourceRaster.NumColumnsInFile * byteSize, SeekOrigin.Current); BinaryReader br = new BinaryReader(fs); for (int row = 0; row < numPasteRows; row++) { // Position the binary reader at the beginning of the sourceRaster fs.Seek(byteSize * sourceStartColumn, SeekOrigin.Current); for (int col = 0; col < numPasteColumns; col++) { Data[destStartRow + row][destStartColumn + col] = br.Read <T>(); } pm.CurrentValue = row; fs.Seek(byteSize * (NumColumnsInFile - sourceStartColumn - numPasteColumns), SeekOrigin.Current); } br.Close(); } // The statistics will have changed with the newly pasted data involved GetStatistics(); } else { // ----------------------------------------- FILE BASED --------------------------------- FileStream writefs = new FileStream(Filename, FileMode.Open, FileAccess.Write, FileShare.None, NumColumns * byteSize); BinaryWriter bWriter = new BinaryWriter(writefs); ProgressMeter pm = new ProgressMeter(ProgressHandler, DataStrings.WritingValues_S.Replace("%S", Filename), numPasteRows); writefs.Seek(HeaderSize, SeekOrigin.Begin); writefs.Seek(destStartRow * NumColumnsInFile * byteSize, SeekOrigin.Current); // advance to top of paste window area if (sourceRaster.IsInRam) { // we can just write values for (int row = 0; row < numPasteColumns; row++) { // Position the binary reader at the beginning of the sourceRaster writefs.Seek(byteSize * destStartColumn, SeekOrigin.Current); for (int col = 0; col < numPasteColumns; col++) { T val = sourceRaster.Data[sourceStartRow + row][sourceStartColumn + col]; bWriter.Write(val); } pm.CurrentValue = row; writefs.Seek(byteSize * (NumColumnsInFile - destStartColumn - numPasteColumns), SeekOrigin.Current); } } else { // Since everything is handled from a file, we don't have to type check. Just copy the bytes. FileStream readfs = new FileStream(sourceRaster.Filename, FileMode.Open, FileAccess.Read, FileShare.Read, numPasteColumns * byteSize); BinaryReader bReader = new BinaryReader(readfs); readfs.Seek(HeaderSize, SeekOrigin.Begin); readfs.Seek(sourceStartRow * sourceRaster.NumColumnsInFile * byteSize, SeekOrigin.Current); // advances to top of paste window area for (int row = 0; row < numPasteRows; row++) { readfs.Seek(sourceStartColumn * byteSize, SeekOrigin.Current); writefs.Seek(destStartColumn * byteSize, SeekOrigin.Current); byte[] rowData = bReader.ReadBytes(numPasteColumns * byteSize); bWriter.Write(rowData); readfs.Seek(sourceRaster.NumColumnsInFile - sourceStartColumn - numPasteColumns, SeekOrigin.Current); writefs.Seek(NumColumnsInFile - destStartColumn - numPasteColumns, SeekOrigin.Current); } bReader.Close(); } bWriter.Close(); } }
// ----------------------------------- FROM AND TO IN RAM ONLY --------------------------------- /// <summary> /// This creates an IN MEMORY ONLY window from the in-memory window of this raster. If, however, the requested range /// is outside of what is contained in the in-memory portions of this raster, an appropriate cast /// is required to ensure that you have the correct File handling, like a BinaryRaster etc. /// </summary> /// <param name="startRow">The 0 based integer index of the top row to get from this raster. If this raster is itself a window, 0 represents the startRow from the file.</param> /// <param name="endRow">The integer index of the bottom row to get from this raster. The largest allowed value is NumRows - 1.</param> /// <param name="startColumn">The 0 based integer index of the leftmost column to get from this raster. If this raster is a window, 0 represents the startColumn from the file.</param> /// <param name="endColumn">The 0 based integer index of the rightmost column to get from this raster. The largest allowed value is NumColumns - 1</param> /// <param name="inRam">Boolean. If this is true and the window is small enough, a copy of the values will be loaded into memory.</param> /// <returns>An implementation of IRaster</returns> public IRaster GetWindow(int startRow, int endRow, int startColumn, int endColumn, bool inRam) { if (IsInRam == false) { throw new ArgumentException(DataStrings.RasterRequiresCast); } if (startRow < StartRow || endRow > EndRow || StartColumn < startColumn || EndColumn > endColumn) { // the requested extents are outside of the extents that have been windowed into ram. File Handling is required. throw new ArgumentException(DataStrings.RasterRequiresCast); } int numCols = endColumn - startColumn + 1; int numRows = endRow - startRow + 1; Raster <T> result = new Raster <T>(numRows, numCols); result.Filename = Filename; result.Projection = Projection; result.DataType = typeof(int); result.NumRows = numRows; result.NumColumns = numCols; result.NumRowsInFile = NumRowsInFile; result.NumColumnsInFile = NumColumnsInFile; result.NoDataValue = NoDataValue; result.StartColumn = startColumn; result.StartRow = startRow; result.EndColumn = endColumn; result.EndRow = EndRow; result.FileType = FileType; // Reposition the new "raster" so that it matches the specified window, not the whole raster // X = [0] + [1] * column + [2] * row; // Y = [3] + [4] * column + [5] * row; result.Bounds.AffineCoefficients = new double[6]; result.Bounds.AffineCoefficients[0] = Bounds.AffineCoefficients[0] + Bounds.AffineCoefficients[1] * startColumn + Bounds.AffineCoefficients[2] * startRow; result.Bounds.AffineCoefficients[1] = Bounds.AffineCoefficients[1]; result.Bounds.AffineCoefficients[2] = Bounds.AffineCoefficients[2]; result.Bounds.AffineCoefficients[3] = Bounds.AffineCoefficients[3] + Bounds.AffineCoefficients[4] * startColumn + Bounds.AffineCoefficients[5] * startRow; result.Bounds.AffineCoefficients[4] = Bounds.AffineCoefficients[4]; result.Bounds.AffineCoefficients[5] = Bounds.AffineCoefficients[5]; // Now we can copy any values currently in memory. ProgressMeter pm = new ProgressMeter(ProgressHandler, DataStrings.CopyingValues, endRow); pm.StartValue = startRow; // copy values directly using both data structures for (int row = 0; row < numRows; row++) { for (int col = 0; col < numCols; col++) { result.Data[row][col] = Data[startRow + row][startColumn + col]; } pm.CurrentValue = row; } pm.Reset(); result.Value = new ValueGrid <T>(result); return(result); }