/// <summary> /// This function copies a two dimensional array of float values to the appropriate space in the grid. /// </summary> /// <param name="OutputArray">The two dimensional array of floats to save to the grid</param> /// <param name="mwGrid">The MapWinGIS.grid to save the float values to</param> /// <param name="ICallBack">A MapWinGIS.ICallback for status messages</param> public void SaveArrayToWindow(float[][] OutputArray, MapWinGIS.Grid mwGrid, MapWinGIS.ICallback ICallBack) { // Write values to the grid int numCols = this.Rectangle.Width; int numRows = this.Rectangle.Height; float[] Temp = new float[numCols * numRows]; //Organize the OutputArray into a single window if (ICallBack != null) { ICallBack.Progress("Status", 0, "Copying value to 1-D array."); } for (int row = 0; row < numRows; row++) { for (int col = 0; col < numCols; col++) { Temp[numCols * row + col] = OutputArray[row][col]; } } if (ICallBack != null) { ICallBack.Progress("Status", 0, "Saving window to grid"); } mwGrid.PutFloatWindow(this.Rectangle.Y, this.Rectangle.Bottom - 1, this.Rectangle.X, this.Rectangle.Right - 1, ref Temp[0]); return; }
private void MakeGrid(sFLTData FLTData, string InitialFile, MapWinGIS.ICallback Callback) { //根据.flt文件及其数据文件,创建一个grid网格对象 MapWinGIS.GridHeader h = new MapWinGIS.GridHeader(); int i, j; h.dX = FLTData.cellsize; h.dY = FLTData.cellsize; h.Notes = "Grid文件导入路径 " + System.IO.Path.GetFileName(InitialFile); h.NodataValue = FLTData.NODATA_value; h.NumberCols = FLTData.ncols; h.NumberRows = FLTData.nrows; h.XllCenter = FLTData.xllcenter; h.YllCenter = FLTData.yllcenter; base.Close(); base.CreateNew("", h, MapWinGIS.GridDataType.FloatDataType, -1, true, MapWinGIS.GridFileType.Binary); for (i = 0; i < FLTData.ncols; i++) { for (j = 0; j < FLTData.nrows; j++) { base.Value[i, j] = FLTData.Values[i, j]; } if (Callback != null) { Callback.Progress(base.Key, 50 + i / FLTData.ncols * 50, "创建 MapWinGIS grid"); } } }
}//End Write_Vertical #endregion #region Array - Grid Handling /// <summary> /// Converts a region of a grid into a 2D array of float values /// </summary> /// <param name="mwSourceGrid">The grid to read</param> /// <param name="ICallBack">A MapWinGIS.ICallback for status messages</param> /// <returns>float[][] the values from the grid</returns> public float[][] GetArrayFromWindow(MapWinGIS.Grid mwSourceGrid, MapWinGIS.ICallback ICallBack) { if (mwSourceGrid == null) { if (ICallBack != null) { ICallBack.Error("Error", "SourceGrid cannot be null."); } throw new ArgumentException("SourceGrid cannot be null."); } int numRows = this.Rectangle.Height; int numCols = this.Rectangle.Width; // Populate the Array by directly reading values from the grid float[][] SourceArray = new float[numRows][]; float[] Temp = new float[numRows * numCols]; // Read from the ocx once, rather than calling several times if (ICallBack != null) { ICallBack.Progress("Status", 0, " Loading Values"); } mwSourceGrid.GetFloatWindow(this.Rectangle.Y, this.Rectangle.Bottom - 1, this.Rectangle.X, this.Rectangle.Right - 1, ref Temp[0]); if (ICallBack != null) { ICallBack.Progress("Status", 0, "Copying Values"); } for (int row = 0; row < numRows; row++) { SourceArray[row] = new float[numCols]; // for (int col = 0; col < numCols; col++) { // copy the values into a 2D style array because it improves // handling speeds for some reason SourceArray[row][col] = Temp[row * numCols + col]; } } if (ICallBack != null) { ICallBack.Progress("Status", 0, "Finished copying values from grid."); } return(SourceArray); }// End GetArrayFromWindow
private static void CachePointsBrute(string InPointsPath, int InValueFieldIndex, out List <InterpolationPoint> PointsCache, out string Projection, out string ProjectionUnits, out MapWinGIS.Extents PointsExtents, MapWinGIS.ICallback callback) { int newperc = 0, oldperc = 0; MapWinGIS.Shapefile points = new MapWinGIS.Shapefile(); points.Open(InPointsPath, null); PointsExtents = points.Extents; Projection = points.Projection; if (Projection != null) { ProjectionUnits = Projection.Substring(Projection.IndexOf("units=") + 6); ProjectionUnits = ProjectionUnits.Substring(0, ProjectionUnits.IndexOf("+")).Trim(); } else { double tmpX = points.Extents.xMax; string tmpstr = Math.Floor(tmpX).ToString(); if (tmpstr.Length > 4) { ProjectionUnits = ""; } else { ProjectionUnits = "lat/long"; } } PointsCache = new List <InterpolationPoint>(); InterpolationPoint pt; MapWinGIS.Point currpt; int ns = points.NumShapes; for (int i = 0; i < ns; i++) { newperc = Convert.ToInt32((Convert.ToDouble(i) / Convert.ToDouble(ns)) * 100); if ((newperc > oldperc)) { if (callback != null) { callback.Progress("Status", newperc, "IDW Caching " + i.ToString()); } oldperc = newperc; } currpt = points.get_Shape(i).get_Point(0); pt = new InterpolationPoint(currpt.x, currpt.y, double.Parse(points.get_CellValue(InValueFieldIndex, i).ToString()), 0); PointsCache.Add(pt); } points.Close(); }
/// <summary> /// Converts all the values into a jagged array. /// The coordinates are stored [Y][X] in the resulting array. /// The index values range from 0 to NumCols - 1 for X and 0 to NumRows - 1 for Y /// </summary> /// <returns>A jagged array of float values organized as array[Y][X]</returns> public float[][] GetFloatValues() { MapWinUtility.Logger.Dbg("GetFloatValues()"); bool Result; int Prog = 0; int OldProg = 0; int NumRows, NumCols; NumRows = m_Grid.Header.NumberRows; NumCols = m_Grid.Header.NumberCols; float[][] Vals = new float[NumRows][]; for (int Y = 0; Y < NumRows; Y++) { Vals[Y] = new float[NumCols]; Result = m_Grid.GetRow(Y, ref Vals[Y][0]); if (Result == false) { MapWinUtility.Logger.Dbg("MapWinGIS.Grid.GetRow(" + Y.ToString() + ") threw an error."); throw new MapWinException(m_Grid.LastErrorCode); } Prog = (Y * 100) / NumRows; if (Prog > OldProg) { MapWinUtility.Logger.Progress("Getting Float Values..." + Prog.ToString() + "% Complete", Prog, OldProg); if (m_ICallBack != null) { m_ICallBack.Progress("Progress", Prog, "Getting Float Values..." + Prog.ToString() + "% Complete"); } OldProg = Prog; } } if (m_ICallBack != null) { m_ICallBack.Progress("Progress", 0, ""); } MapWinUtility.Logger.Progress("", 0, 0); MapWinUtility.Logger.Dbg("Finished GetFloatValues."); return(Vals); }
/// <summary> /// Writes a message to this dialog, and echos the message to the CallBack interface if one is specified. /// </summary> /// <param name="Message">A String message to be written to the dialog or callback</param> public void WriteMessage(string Message) { if (this.Visible == true) { richTextBox1.AppendText(Message); richTextBox1.SelectionStart = richTextBox1.Text.Length; Application.DoEvents(); } if (m_ICallBack != null) { m_ICallBack.Progress("Status", 0, Message); } }
private void ReadFLTData(sFLTData FLTData, string DataFile, MapWinGIS.ICallback Callback) { //读取.flt网格图层的数据文件 int i, j; FileStream fs = null; BinaryReader r; try { FLTData.Values = new float[FLTData.ncols - 1 + 1, FLTData.nrows - 1 + 1]; fs = File.Open(DataFile, FileMode.Open); r = new BinaryReader(fs); fs.Seek(0, SeekOrigin.Begin); for (j = 0; j < FLTData.nrows; j++) { for (i = 0; i < FLTData.ncols; i++) { FLTData.Values[i, j] = r.ReadSingle(); } if (Callback != null) { Callback.Progress(base.Key, j / FLTData.nrows * 50, "读取 FLT 数据"); } } } catch (System.Exception ex) { MapWinGIS.Utility.Logger.Message("读取.flt网格图层的数据文件出错: " + "\r\n" + ex.Message); } try { fs.Close(); } catch { } }
private void MakeGrid(sDEMData DEMData, MapWinGIS.ICallback Callback) { //根据.dem文件,生成一个网格文件对象 MapWinGIS.GridHeader h = new MapWinGIS.GridHeader(); int i; int j; int m; int n; h.dX = 30; h.dY = 30; h.Notes = "DEMData.Notes"; h.NodataValue = -1; h.NumberCols = DEMData.NumCols; h.NumberRows = System.Convert.ToInt32((DEMData.MaxY() - DEMData.MinY() / 30)) + 1; h.XllCenter = DEMData.MinX(); h.YllCenter = DEMData.MinY(); MapWinGIS.Utility.Logger.Dbg("根据.dem文件和其数据文件,生成一个网格文件对象"); base.Close(); MapWinGIS.Utility.Logger.Dbg("开始创建"); base.CreateNew("", h, MapWinGIS.GridDataType.ShortDataType, h.NodataValue, true, MapWinGIS.GridFileType.Binary); MapWinGIS.Utility.Logger.Dbg("只带header的新的grid网格文件创建了"); for (i = 0; i < DEMData.NumCols; i++) { for (j = 0; j < DEMData.NumElevs[i]; j++) { base.ProjToCell(DEMData.ColStarts[i].X, System.Convert.ToInt32(DEMData.ColStarts[i].Y) + (30 * j), out m, out n); base.Value[m, n] = DEMData.Values[i, j]; } MapWinGIS.Utility.Logger.Dbg("创建 MapWinGIS grid 对象. numCols: " + i.ToString()); if (Callback != null) { Callback.Progress(base.Key, 50 + i / DEMData.NumCols * 50, "创建 MapWinGIS grid 对象"); } } MapWinGIS.Utility.Logger.Dbg("生成一个网格文件对象完成"); }
private static void CachePoints(string InPointsPath, int InValueFieldIndex, out KDTreeDLL.KDTree PointsTree, out double[][] Points, out double[] PointVals, out string Projection, out string ProjectionUnits, out MapWinGIS.Extents PointsExtents, MapWinGIS.ICallback callback) { int newperc = 0, oldperc = 0; MapWinGIS.Shapefile pointsf = new MapWinGIS.Shapefile(); pointsf.Open(InPointsPath, null); PointsExtents = pointsf.Extents; Projection = pointsf.Projection; if (Projection != null) { ProjectionUnits = Projection.Substring(Projection.IndexOf("units=") + 6); ProjectionUnits = ProjectionUnits.Substring(0, ProjectionUnits.IndexOf("+")).Trim(); } else { double tmpX = pointsf.Extents.xMax; string tmpstr = Math.Floor(tmpX).ToString(); if (tmpstr.Length > 4) { ProjectionUnits = ""; } else { ProjectionUnits = "lat/long"; } } PointsTree = new KDTreeDLL.KDTree(2); MapWinGIS.Point currpt; int ns = pointsf.NumShapes; Points = new double[ns][]; PointVals = new double[ns]; int duplicates = 0; for (int i = 0; i < ns; i++) { Points[i] = new double[2]; newperc = Convert.ToInt32((Convert.ToDouble(i) / Convert.ToDouble(ns)) * 100); if ((newperc > oldperc)) { if (callback != null) { callback.Progress("Status", newperc, "IDW Caching " + i.ToString()); } oldperc = newperc; } currpt = pointsf.get_Shape(i).get_Point(0); Points[i][0] = currpt.x; Points[i][1] = currpt.y; PointVals[i] = double.Parse(pointsf.get_CellValue(InValueFieldIndex, i).ToString()); try { if (PointsTree.search(Points[i]) == null) { PointsTree.insert(Points[i], i); } } catch (KDTreeDLL.KeyDuplicateException) { duplicates++; } } pointsf.Close(); }
/// <summary> /// Inverse Distance Weighting Interpolation /// </summary> /// <param name="InPointsPath">Input point shapefile path to interpolate</param> /// <param name="InValueFieldIndex">Input field index where interpolation value is stored</param> /// <param name="OutGridPath">Output grid path where interpolation is stored</param> /// <param name="CellSize">Cell Size for output grid. Default lower of points extent height or width divided by 250</param> /// <param name="Power">Power variable for IDW algorithm. 0 lt p lt 1 will give sharp changes. >1 will give smoother. Default 2.</param> /// <param name="NeighborhoodType">Variable is a variable number of nearest points. Fixed is all points in a fixed distance</param> /// <param name="NeighborhoodCount">Variable Count is either number of nearest points to use. Fixed Count is minimum points needed to find valid interpolation</param> /// <param name="NeighborhoodDistance">Variable Distance is a maximum distance of nearest points. Fixed Distance is distance to use to select points</param> /// <param name="callback">A callback for progress information</param> public static void IDWBrute(string InPointsPath, int InValueFieldIndex, string OutGridPath, double CellSize, double Power, IDWNeighborhoodType NeighborhoodType, int NeighborhoodCount, double NeighborhoodDistance, MapWinGIS.ICallback callback) { int newperc = 0, oldperc = 0; List <InterpolationPoint> pointsCache; string proj, projUnits; MapWinGIS.Extents pointsExtents; CachePointsBrute(InPointsPath, InValueFieldIndex, out pointsCache, out proj, out projUnits, out pointsExtents, callback); MapWinGIS.Grid outGrid; DataManagement.DeleteGrid(ref OutGridPath); double NoDataValue = -32768; CreateGridFromExtents(pointsExtents, CellSize, proj, NoDataValue, OutGridPath, out outGrid); //Cycle grid and find interpolated value for each cell List <InterpolationPoint> neighbors; InterpolationPoint cellPoint; int nr = outGrid.Header.NumberRows; int nc = outGrid.Header.NumberCols; double sumWeight, sumWeightAndVal; newperc = 0; oldperc = 0; for (int row = 0; row < nr; row++) { newperc = Convert.ToInt32((Convert.ToDouble(row) / Convert.ToDouble(nr)) * 100); if (callback != null) { callback.Progress("Status", newperc, "IDW Row " + row); } newperc = 0; oldperc = 0; for (int col = 0; col < nc; col++) { newperc = Convert.ToInt32((Convert.ToDouble(col) / Convert.ToDouble(nc)) * 100); if ((newperc > oldperc)) { if (callback != null) { callback.Progress("Status", newperc, "IDW Row " + row.ToString() + " Col " + col.ToString()); } oldperc = newperc; } cellPoint = new InterpolationPoint(); outGrid.CellToProj(col, row, out cellPoint.X, out cellPoint.Y); GetIDWNeighborsBrute(cellPoint, ref pointsCache, out neighbors, NeighborhoodType, NeighborhoodCount, NeighborhoodDistance, projUnits); sumWeightAndVal = 0; sumWeight = 0; foreach (InterpolationPoint npoint in neighbors) { sumWeightAndVal += GetIDWeightBrute(cellPoint, npoint, projUnits, Power) * npoint.Value; sumWeight += GetIDWeightBrute(cellPoint, npoint, projUnits, Power); } outGrid.set_Value(col, row, (sumWeightAndVal / sumWeight)); } } outGrid.Save(OutGridPath, MapWinGIS.GridFileType.UseExtension, null); outGrid.Close(); }
/// <summary> /// This overload calculates the difference between files. THe number of rows and columns should be the same. /// </summary> /// <param name="SourceFile1">String filename of one grid to compare</param> /// <param name="SourceFile2">String filename of another grid to compare</param> /// <param name="DestFile">String filename of the output difference file</param> /// <param name="Overwrite">Boolean, true if you wish to overwrite an existing output /// file and delete the associated .bmp file. False raises a messagebox if the files exist.</param> /// <param name="ICallBack">A MapWinGIS.ICallBack for status messages</param> public static void Difference(string SourceFile1, string SourceFile2, string DestFile, bool Overwrite, MapWinGIS.ICallback ICallBack) { MapWinGIS.Grid Source1 = new MapWinGIS.Grid(); MapWinGIS.Grid Source2 = new MapWinGIS.Grid(); MapWinGIS.Grid Dest = new MapWinGIS.Grid(); bool res; // Open the source grids if (ICallBack != null) { ICallBack.Progress("Status", 0, "Opening Files..."); } res = Source1.Open(SourceFile1, MapWinGIS.GridDataType.UnknownDataType, true, MapWinGIS.GridFileType.UseExtension, ICallBack); if (res == false) { MapWinUtility.Logger.Dbg("Argument Exception: " + Source1.get_ErrorMsg(Source1.LastErrorCode)); throw new ArgumentException(Source1.get_ErrorMsg(Source1.LastErrorCode)); } res = Source2.Open(SourceFile2, MapWinGIS.GridDataType.UnknownDataType, true, MapWinGIS.GridFileType.UseExtension, ICallBack); if (res == false) { throw new ArgumentException(Source2.get_ErrorMsg(Source2.LastErrorCode)); } // Delete any existing files for our output grid if (System.IO.File.Exists(DestFile)) { string bmp = System.IO.Path.ChangeExtension(DestFile, "bmp"); string bpw = System.IO.Path.ChangeExtension(DestFile, "bpw"); string prj = System.IO.Path.ChangeExtension(DestFile, "prj"); string mwleg = System.IO.Path.ChangeExtension(DestFile, "mwleg"); if (Overwrite == false) { if (System.IO.File.Exists(bmp) || System.IO.File.Exists(bpw) || System.IO.File.Exists(prj) || System.IO.File.Exists(mwleg)) { if (MapWinUtility.Logger.Message("The output file exists, or associated files of the same name exist. Do you wish to delete the existing files?\n", "Output Files Exist", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Warning, System.Windows.Forms.DialogResult.No) == System.Windows.Forms.DialogResult.No) { return; } // This ensures mapwindow will recognize the new image as a new file. if (System.IO.File.Exists(bmp)) { System.IO.File.Delete(bmp); } if (System.IO.File.Exists(bpw)) { System.IO.File.Delete(bpw); } if (System.IO.File.Exists(prj)) { System.IO.File.Delete(prj); } if (System.IO.File.Exists(mwleg)) { System.IO.File.Delete(mwleg); } } else { if (MapWinUtility.Logger.Message("The output file already exists. Do you wish to delete it?", "Destination File Already Exists", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Warning, System.Windows.Forms.DialogResult.No) == System.Windows.Forms.DialogResult.No) { return; } } } else { if (System.IO.File.Exists(bmp)) { System.IO.File.Delete(bmp); } if (System.IO.File.Exists(bpw)) { System.IO.File.Delete(bpw); } if (System.IO.File.Exists(prj)) { System.IO.File.Delete(prj); } if (System.IO.File.Exists(mwleg)) { System.IO.File.Delete(mwleg); } } System.IO.File.Delete(DestFile); } // Create a new output grid MapWinGIS.GridHeader newHeader = new MapWinGIS.GridHeader(); newHeader.CopyFrom(Source1.Header); if (ICallBack != null) { MapWinUtility.Logger.Dbg("Creating Output File..."); ICallBack.Progress("Status", 0, "Creating Output File..."); } res = Dest.CreateNew(DestFile, newHeader, Source1.DataType, 0, true, MapWinGIS.GridFileType.UseExtension, ICallBack); if (res == false) { MapWinUtility.Logger.Dbg("Argument Exception: " + Dest.get_ErrorMsg(Dest.LastErrorCode)); throw new ArgumentException(Dest.get_ErrorMsg(Dest.LastErrorCode)); } // Calculate the differences Difference(Source1, Source2, Dest, ICallBack); // Close Source grids Source1.Close(); Source2.Close(); // Save and close the output grid res = Dest.Save(DestFile, MapWinGIS.GridFileType.UseExtension, ICallBack); if (res == false) { MapWinUtility.Logger.Dbg("Application Exception: " + Dest.get_ErrorMsg(Dest.LastErrorCode)); throw new ArgumentException(Dest.get_ErrorMsg(Dest.LastErrorCode)); } Dest.Close(); MapWinUtility.Logger.Dbg("Finished Difference"); }
/// <summary> /// Inverse Distance Weighting Interpolation /// </summary> /// <param name="InPointsPath">Input point shapefile path to interpolate</param> /// <param name="InValueFieldIndex">Input field index where interpolation value is stored</param> /// <param name="OutGridPath">Output grid path where interpolation is stored</param> /// <param name="CellSize">Cell Size for output grid. Default lower of points extent height or width divided by 250</param> /// <param name="Power">Power variable for IDW algorithm. 0 lt p lt 1 will give sharp changes. >1 will give smoother. Default 2.</param> /// <param name="NeighborhoodType">Variable is a variable number of nearest points. Fixed is all points in a fixed distance</param> /// <param name="NeighborhoodCount">Variable Count is either number of nearest points to use. Fixed Count is minimum points needed to find valid interpolation</param> /// <param name="NeighborhoodDistance">Variable Distance is a maximum distance of nearest points. Fixed Distance is distance to use to select points</param> /// <param name="callback">A callback for progress information</param> public static void IDW(string InPointsPath, int InValueFieldIndex, string OutGridPath, double CellSize, double Power, IDWNeighborhoodType NeighborhoodType, int NeighborhoodCount, double NeighborhoodDistance, MapWinGIS.ICallback callback) { int newperc = 0, oldperc = 0; KDTreeDLL.KDTree pointsTree; double[][] Points; double[] PointVals; string proj, projUnits; MapWinGIS.Extents pointsExtents; CachePoints(InPointsPath, InValueFieldIndex, out pointsTree, out Points, out PointVals, out proj, out projUnits, out pointsExtents, callback); MapWinGIS.Grid outGrid; DataManagement.DeleteGrid(ref OutGridPath); double NoDataValue = -32768; CreateGridFromExtents(pointsExtents, CellSize, proj, NoDataValue, OutGridPath, out outGrid); //Cycle grid and find interpolated value for each cell int nr = outGrid.Header.NumberRows; int nc = outGrid.Header.NumberCols; double sumWeight, sumWeightAndVal, projX, projY; int[] neighbors; double[] CellPoint; newperc = 0; oldperc = 0; for (int row = 0; row < nr; row++) { newperc = Convert.ToInt32((Convert.ToDouble(row) / Convert.ToDouble(nr)) * 100); if (callback != null) { callback.Progress("Status", newperc, "IDW Row " + row.ToString() + "/" + nr.ToString()); } oldperc = newperc; newperc = 0; oldperc = 0; for (int col = 0; col < nc; col++) { outGrid.CellToProj(col, row, out projX, out projY); CellPoint = new double[2]; CellPoint[0] = projX; CellPoint[1] = projY; if (GetIDWNeighbors(CellPoint, ref pointsTree, ref Points, out neighbors, NeighborhoodType, NeighborhoodCount, NeighborhoodDistance, projUnits) == 0) { sumWeightAndVal = 0; sumWeight = 0; for (int i = 0; i < neighbors.Length; i++) { sumWeightAndVal += GetIDWeight(CellPoint, Points[neighbors[i]], projUnits, Power) * PointVals[neighbors[i]]; sumWeight += GetIDWeight(CellPoint, Points[neighbors[i]], projUnits, Power); } outGrid.set_Value(col, row, (sumWeightAndVal / sumWeight)); } } } outGrid.Save(OutGridPath, MapWinGIS.GridFileType.UseExtension, null); outGrid.Close(); if (callback != null) { callback.Progress("Status", 0, ""); } }
// This is not a full fledged map algebra function! This cannot deal with // images of different sizes or cell spacings. This is only a quick function // that can tell if, for instance, a pitfilled image is different from the // version created in Arcview. It simply takes each cell and finds the difference // in values. #region "Difference" /// <summary> /// Calculates the difference values and stores them in the Dest grid. This only works if the grids /// have the same number of rows and columns. /// </summary> /// <param name="Source1">MapWinGIS.Grid representing one source grid</param> /// <param name="Source2">MapWinGIS.Grid to compare Source1 against</param> /// <param name="Dest">MapWinGIS.Grid where the output is to be saved</param> /// <param name="ICallBack">A MapWinGIS.ICallBack</param> /// <remarks>Uses ArgumentExceptions if the grids are different sizes</remarks> public static void Difference(MapWinGIS.Grid Source1, MapWinGIS.Grid Source2, MapWinGIS.Grid Dest, MapWinGIS.ICallback ICallBack) { // Log entrance as best as possible while preventing errors from a null reference string Source1File = "null"; string Source2File = "null"; string DestFile = "null"; if (Source1 != null) { Source1File = Source1.Filename; if (Source1File == null) { Source1File = "Unnamed"; } } if (Source2 != null) { Source2File = Source2.Filename; if (Source2File == null) { Source2File = "Unnamed"; } } if (Dest != null) { DestFile = Dest.Filename; if (DestFile == null) { DestFile = "Unnamed"; } } MapWinUtility.Logger.Dbg("Difference(Source1: " + Source1File + ",\n" + " Source2: " + Source2File + ",\n" + " Dest: " + DestFile + ",\n" + " ICallback"); if (Source1 == null) { MapWinUtility.Logger.Dbg("Argument Exception: Source1 cannot be null."); throw new ArgumentException("Source1 cannot be null."); } if (Source2 == null) { MapWinUtility.Logger.Dbg("Argument Exception: Source2 cannot be null."); throw new ArgumentException("Source2 cannot be null."); } if (Dest == null) { MapWinUtility.Logger.Dbg("Argument Exception: Dest cannot be null."); throw new ArgumentException("Dest cannot be null."); } int nX, nY; nX = Source1.Header.NumberCols; nY = Source1.Header.NumberRows; if (Source2.Header.NumberRows != nY) { MapWinUtility.Logger.Dbg("Argument Exception: The grids are not the same height."); throw new ArgumentException("The grids are not the same height."); } if (Source2.Header.NumberCols != nX) { MapWinUtility.Logger.Dbg("Argument Exception: The grids are not the same width!"); throw new ArgumentException("The grids are not the same width!"); } if (Dest.Header.NumberRows != nY) { MapWinUtility.Logger.Dbg("Argument Exception: The output grid is not the same height!"); throw new ArgumentException("The output grid is not the same height!"); } if (Dest.Header.NumberCols != nX) { MapWinUtility.Logger.Dbg("Argument Exception: The output grid is not the same width!"); throw new ArgumentException("The output grid is not the same width!"); } int OldProg = 0; int Prog = 0; if (ICallBack != null) { ICallBack.Progress("Status", 0, "Difference...0% Complete"); } MapWinUtility.Logger.Progress("Difference...0% Complete", Prog, OldProg); if (Source1.DataType != MapWinGIS.GridDataType.FloatDataType) { switch (Source1.DataType) { case MapWinGIS.GridDataType.DoubleDataType: for (int Y = 0; Y < nY; Y++) { for (int X = 0; X < nX; X++) { double val = (double)Source1.get_Value(X, Y) - (double)Source2.get_Value(X, Y); Dest.set_Value(X, Y, val); } if (ICallBack != null) { Prog = (int)(Y * 100 / nY); if (Prog > OldProg) { ICallBack.Progress("Status", Prog, "Difference..." + Prog.ToString() + "% Complete"); MapWinUtility.Logger.Progress("Difference..." + Prog.ToString() + "% Complete", Prog, OldProg); OldProg = Prog; } } } break; case MapWinGIS.GridDataType.UnknownDataType: for (int Y = 0; Y < nY; Y++) { for (int X = 0; X < nX; X++) { double val = (double)Source1.get_Value(X, Y) - (double)Source2.get_Value(X, Y); Dest.set_Value(X, Y, val); } if (ICallBack != null) { Prog = (int)(Y * 100 / nY); if (Prog > OldProg) { ICallBack.Progress("Status", Prog, "Difference..." + Prog.ToString() + "% Complete"); MapWinUtility.Logger.Progress("Difference..." + Prog.ToString() + "% Complete", Prog, OldProg); OldProg = Prog; } } } break; case MapWinGIS.GridDataType.LongDataType: for (int Y = 0; Y < nY; Y++) { for (int X = 0; X < nX; X++) { long val = (long)Source1.get_Value(X, Y) - (long)Source2.get_Value(X, Y); Dest.set_Value(X, Y, val); } if (ICallBack != null) { Prog = (int)(Y * 100 / nY); if (Prog > OldProg) { MapWinUtility.Logger.Progress("Difference..." + Prog.ToString() + "% Complete", Prog, OldProg); ICallBack.Progress("Status", Prog, "Difference..." + Prog.ToString() + "% Complete"); OldProg = Prog; } } } break; case MapWinGIS.GridDataType.ShortDataType: for (int Y = 0; Y < nY; Y++) { for (int X = 0; X < nX; X++) { int val = (int)Source1.get_Value(X, Y) - (int)Source2.get_Value(X, Y); Dest.set_Value(X, Y, val); } if (ICallBack != null) { Prog = (int)(Y * 100 / nY); if (Prog > OldProg) { MapWinUtility.Logger.Progress("Difference..." + Prog.ToString() + "% Complete", Prog, OldProg); ICallBack.Progress("Status", Prog, "Difference..." + Prog.ToString() + "% Complete"); OldProg = Prog; } } } break; default: MapWinUtility.Logger.Progress("The Datatype was not a valid numeric type.", Prog, OldProg); throw new ArgumentException("The Datatype was not a valid numeric type."); } } else { for (int Y = 0; Y < nY; Y++) { float[] Vals1 = new float[nX]; float[] Vals2 = new float[nX]; float[] Diff = new float[nX]; Source1.GetRow(Y, ref Vals1[0]); Source2.GetRow(Y, ref Vals2[0]); for (int X = 0; X < nX; X++) { Diff[X] = Vals1[X] - Vals2[X]; } Dest.PutRow(Y, ref Diff[0]); if (ICallBack != null) { Prog = (int)(Y * 100 / nY); if (Prog > OldProg) { MapWinUtility.Logger.Progress("Difference..." + Prog.ToString() + "% Complete", Prog, OldProg); ICallBack.Progress("Status", Prog, "Difference..." + Prog.ToString() + "% Complete"); OldProg = Prog; } } } } MapWinUtility.Logger.Dbg("Finished Difference"); if (ICallBack != null) { ICallBack.Progress("Status", 0, "Done."); } }
// False if the user canceled, true otherwise private static bool Do_ApplyFilter(MapWinGIS.Image SourceImage, ref MapWinGIS.Image DestImage, float[,] filter, bool ShowProgressDialog, MapWinGIS.ICallback ICallBack) { int Prog = 0; int OldProg = 0; // Report unnamed as differently from null string SourceFile = "null"; string DestFile = "null"; if (SourceImage != null) { SourceFile = SourceImage.Filename; if (SourceFile == null) { SourceFile = "Unnamed"; } } else { MapWinUtility.Logger.Dbg("Argument Exception: SourceImage cannot be null."); throw new ArgumentException("SourceImage cannot be null."); } if (DestImage != null) { DestFile = SourceImage.Filename; if (DestFile == null) { DestFile = "Unnamed"; } } else { MapWinUtility.Logger.Dbg("Argument Exception: DestImage cannot be null."); throw new ArgumentException("DestImage cannot be null."); } MapWinUtility.Logger.Dbg("Do_ApplyFilter(SourceImage: " + SourceImage.Filename + ",\n" + " DestImage: " + DestImage.Filename + ",\n" + " filter: [" + filter.GetUpperBound(0) + ", " + filter.GetUpperBound(1) + "],\n" + " ShowProgressDialog: " + ShowProgressDialog.ToString() + ",\n" + " ICallback)"); ProgressDialog MyProgress = new ProgressDialog(); if (filter.GetUpperBound(0) == 0 || filter.GetUpperBound(1) == 0) { MapWinUtility.Logger.Dbg("Argument Exception: Filter must have values."); throw new ArgumentException("Filter must have values."); } // Ensure the filter is smaller than the image. if (filter.GetUpperBound(0) > SourceImage.Height || filter.GetUpperBound(1) > SourceImage.Width) { throw new ArgumentException("The filter is too large for this image. In order for convolution to work, the image must be larger than the filter."); } // We are going to assume mirror handling of edges ExtHandler LocHandler = new ExtHandler(SourceImage.Height, SourceImage.Width); // convolve int R, G, B, color; int Xcor = 0, Ycor = 0; // Corrected X and Y locations to take into account mirror int fH, fW; // stores the values of half the height and width of the filter fH = (int)filter.GetUpperBound(0) / 2; fW = (int)filter.GetUpperBound(1) / 2; if (ICallBack == null) { MyProgress.Show(); MyProgress.WriteMessage("Applying Filter..."); MapWinUtility.Logger.Progress("Applying Filter...", Prog, OldProg); } for (int row = 0; row < SourceImage.Height; row++) { for (int col = 0; col < SourceImage.Width; col++) { float fR = 0; float fG = 0; float fB = 0; for (int Y = 0; Y <= filter.GetUpperBound(0); Y++) { for (int X = 0; X <= filter.GetUpperBound(1); X++) { // Read the color for this spot LocHandler.CorrectLocation(col + X - fW, row + Y - fH, ref Xcor, ref Ycor); color = SourceImage.get_Value(Ycor, Xcor); R = color % 256; G = (int)(color / 256) % 256; B = (int)(color / (256 * 256)); // convolve the values with the filter and add them to the accumulators fR += filter[Y, X] * R; fG += filter[Y, X] * G; fB += filter[Y, X] * B; } } // After convolution, write the combined value to the file R = (int)fR; if (R > 255) { R = 255; } G = (int)fG; if (G > 255) { G = 255; } B = (int)fB; if (B > 255) { B = 255; } color = (256 * 256) * B + 256 * G + R; DestImage.set_Value(row, col, color); } Prog = (100 * row) / SourceImage.Height; if (Prog > OldProg) { if (ICallBack != null) { ICallBack.Progress("Status", Prog, "Filtering Image..."); } if (ShowProgressDialog == true) { MyProgress.Progress = Prog; if (MyProgress.IsCanceled == true) { MapWinUtility.Logger.Message("Apply Filter was canceled.", "Process Canceled", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information, System.Windows.Forms.DialogResult.OK); return(false); } } MapWinUtility.Logger.Progress("Filtering Image..." + Prog.ToString() + "%Complete", Prog, OldProg); OldProg = Prog; } } MyProgress.Hide(); DestImage.dX = SourceImage.dX; DestImage.dY = SourceImage.dY; DestImage.SetProjection(SourceImage.GetProjection()); DestImage.Save(DestImage.Filename, true, MapWinGIS.ImageType.USE_FILE_EXTENSION, null); MapWinUtility.Logger.Dbg("Finsihed ApplyFilter"); return(true); }
private sDEMData ReadDEMData(Stream fileStream, MapWinGIS.ICallback Callback) { // 从USGS读取dem格式的数据文件(ASCII 文本) int i, j; int numElevs; int Elev = 0; int Off2; int Off3; int Inserts; sDEMData DEMData = new sDEMData(); string chunckResult; try { //获取header数据 DEMData.Notes = GetChunk(fileStream, 1, 144); DEMData.HorizUnits = System.Convert.ToInt32(GetChunk(fileStream, 529, 6)); DEMData.VertUnits = System.Convert.ToInt32(GetChunk(fileStream, 535, 6)); DEMData.Vertices = new sVertex[4]; for (i = 0; i <= 3; i++) { DEMData.Vertices[i].X = Fdbl(GetChunk(fileStream, 547 + (48 * i), 24)); DEMData.Vertices[i].Y = Fdbl(GetChunk(fileStream, 571 + (48 * i), 24)); } DEMData.Min = System.Convert.ToDouble(Fdbl(GetChunk(fileStream, 739, 24))); DEMData.Max = System.Convert.ToDouble(Fdbl(GetChunk(fileStream, 763, 24))); DEMData.NumCols = System.Convert.ToInt32((GetChunk(fileStream, 859, 6))); DEMData.Values = new int[DEMData.NumCols - 1 + 1, 1]; DEMData.NumElevs = new int[DEMData.NumCols - 1 + 1]; MapWinGIS.Utility.Logger.Dbg("DEM 的头(Header)信息:"); MapWinGIS.Utility.Logger.Dbg("DEMData.Notes: " + DEMData.Notes); MapWinGIS.Utility.Logger.Dbg("DEMData.HorizUnits: " + DEMData.HorizUnits.ToString()); MapWinGIS.Utility.Logger.Dbg("DEMData.VertUnits: " + DEMData.VertUnits.ToString()); MapWinGIS.Utility.Logger.Dbg("DEMData.Min: " + DEMData.Min.ToString()); MapWinGIS.Utility.Logger.Dbg("DEMData.Max: " + DEMData.Max.ToString()); MapWinGIS.Utility.Logger.Dbg("DEMData.NumCols: " + DEMData.NumCols.ToString()); //获取海拔(elevation)数据 Off2 = 1024; Inserts = 0; DEMData.ColStarts = new sVertex[DEMData.NumCols - 1 + 1]; MapWinGIS.Utility.Logger.Dbg("DEM Data"); for (i = 0; i < DEMData.NumCols; i++) { //读取elevs的数量, starting x 和 starting y numElevs = Convert.ToInt32(GetChunk(fileStream, Off2 + 13, 6)); DEMData.NumElevs[i] = numElevs; DEMData.ColStarts[i].X = Fdbl(GetChunk(fileStream, Off2 + 25, 24)); DEMData.ColStarts[i].Y = Fdbl(GetChunk(fileStream, Off2 + 49, 24)); //Information.UBound(DEMData.Values, 2) if (numElevs - 1 > DEMData.Values.GetLength(1)) { DEMData.Values = (int[, ])Microsoft.VisualBasic.CompilerServices.Utils.CopyArray((Array)DEMData.Values, new int[DEMData.NumCols, numElevs]); } for (j = 0; j < numElevs; j++) { Inserts = 0; if (j > 145) { Inserts = (int)((j - 145) / 171 + 1); } Off3 = Off2 + 145 + (j * 6) + Inserts * 4; //4 spaces between each extended group chunckResult = GetChunk(fileStream, Off3, 6); if (chunckResult.Trim() != string.Empty) { if (int.TryParse(chunckResult, out Elev) == false) { Elev = -1; MapWinGIS.Utility.Logger.Dbg("ReadDEMData Error. GetChunk returned non-integer:" + chunckResult); } } DEMData.Values[i, j] = Elev; } if (numElevs <= 146) { Off2 = Off2 + 1024; } else { Inserts = (int)((numElevs - 146) / 170 + 1); Off2 = Off2 + 1024 + Inserts * 1024; } if (Callback != null) { Callback.Progress(base.Key, i / DEMData.NumCols * 50, "读取 DEM 数据"); } } MapWinGIS.Utility.Logger.Dbg("读取 DEM 数据完成"); return(DEMData); } catch (System.Exception ex) { MapWinGIS.Utility.Logger.Msg("读取DEM数据出错 : " + ex.Message); } sDEMData a = new sDEMData(); return(a); }
/// <summary> /// Inserts shapes with the given indices in the specified table. /// </summary> /// <returns>Number of inserted shapes. -1 if the table doesn't exist.</returns> public int InsertShapes(MapWinGIS.Shapefile sf, string tableName, int[] indices) { this.CheckConnection(); int count = 0; using (DbTransaction dbTrans = m_connection.BeginTransaction()) { using (DbCommand cmd = this.CreateCommand()) { DbParameter param = this.CreateBinaryParameter(); param.SourceColumn = "Geometry"; param.ParameterName = "@Geometry"; cmd.Parameters.Add(param); // generating sql and parameters int fieldCount = sf.NumFields; string sql = "INSERT INTO [" + tableName + "] ([Geometry], "; string values = "VALUES (?, "; for (int j = 0; j < fieldCount; j++) { param = this.CreateParameter(); MapWinGIS.Field fld = sf.get_Field(j); switch (fld.Type) { case MapWinGIS.FieldType.STRING_FIELD: param.DbType = DbType.StringFixedLength; param.Size = fld.Width; break; case MapWinGIS.FieldType.INTEGER_FIELD: param.DbType = DbType.Int32; break; case MapWinGIS.FieldType.DOUBLE_FIELD: param.DbType = DbType.Double; break; } param.ParameterName = "@p" + j.ToString(); param.SourceColumn = fld.Name; cmd.Parameters.Add(param); sql += "[" + fld.Name + "]"; sql += (j == fieldCount - 1) ? ") " : ", "; values += (j == fieldCount - 1) ? "?)" : "?, "; } cmd.CommandText = sql + values; cmd.Transaction = dbTrans; cmd.Connection = m_connection; System.Diagnostics.Debug.Print(cmd.CommandText); // adding new records DbParameterCollection paramters = cmd.Parameters; MapWinGIS.Table table = sf.Table; int maxSize = 0; int percent = 0; for (int i = 0; i < sf.NumShapes; i++) { if (m_callback != null && m_showCallback) { int newPercent = (int)((double)i / (double)(sf.NumShapes - 1) * 100.0); if (newPercent != percent) { m_callback.Progress("", newPercent, "Exporting shapes..."); percent = newPercent; } } object data = null; MapWinGIS.Shape shape = sf.get_Shape(i); if (shape.ExportToBinary(ref data)) { if ((data as byte[]).Length > maxSize) { maxSize = (data as byte[]).Length; } paramters[0].Value = data as byte[]; for (int j = 0; j < fieldCount; j++) { paramters[j + 1].Value = table.get_CellValue(j, i); } if (cmd.ExecuteNonQuery() != 0) { count++; } } } if (m_callback != null && m_showCallback) { m_callback.Progress("", 100, ""); } } dbTrans.Commit(); } return(count); }
}// End GetArrayFromWindow /// <summary> /// Returns jagged array where the borders are read from the destination file but the central /// portion is set to be the maximum float value. /// </summary> /// <param name="mwSourceGrid">A MapWinGIS.Grid to read the frame borders that are on the very outside of the image</param> /// <param name="mwDestGrid">A MapWinGIS.Grid to read the frame borders on the interior edges already processed </param> /// <param name="ICallBack">A MapWinGIS.ICallback for messages (optional)</param> /// <returns>A float[][] array representing the destination values for an entire frame</returns> public float[][] GetBorders(MapWinGIS.Grid mwSourceGrid, MapWinGIS.Grid mwDestGrid, MapWinGIS.ICallback ICallBack) { if (mwSourceGrid == null || mwDestGrid == null) { if (ICallBack != null) { ICallBack.Error("Error", "SourceGrid cannot be null."); } throw new ArgumentException("SourceGrid cannot be null."); } int numRows = this.Rectangle.Height; int numCols = this.Rectangle.Width; // Populate the Array by directly reading values from the grid float[][] SourceArray = new float[numRows][]; // Read from the ocx once, rather than calling several times // Initialize the array to max values for (int row = 0; row < numRows; row++) { SourceArray[row] = new float[numCols]; for (int col = 0; col < numCols; col++) { SourceArray[row][col] = float.MaxValue; } } // If we need a dependency in a given direction, read it from the file. if (Y == 0) { mwSourceGrid.GetFloatWindow(this.Rectangle.Y, this.Rectangle.Y, this.Rectangle.X, this.Rectangle.Right - 1, ref SourceArray[0][0]); } else if (Parent.First_Time(X, Y - 1) == false) { mwDestGrid.GetFloatWindow(this.Rectangle.Y, this.Rectangle.Y, this.Rectangle.X, this.Rectangle.Right - 1, ref SourceArray[0][0]); } if (Y == Parent.NumFramesTall - 1) { mwSourceGrid.GetFloatWindow(this.Rectangle.Bottom - 1, this.Rectangle.Bottom - 1, this.Rectangle.X, this.Rectangle.Right - 1, ref SourceArray[numRows - 1][0]); } else if (Parent.First_Time(X, Y + 1) == false) { mwDestGrid.GetFloatWindow(this.Rectangle.Bottom - 1, this.Rectangle.Bottom - 1, this.Rectangle.X, this.Rectangle.Right - 1, ref SourceArray[numRows - 1][0]); } if (X == 0) { float[] Temp = new float[numRows]; mwSourceGrid.GetFloatWindow(this.Rectangle.Y, this.Rectangle.Bottom - 1, this.Rectangle.X, this.Rectangle.X, ref Temp[0]); for (int row = 0; row < numRows; row++) { SourceArray[row][0] = Temp[row]; } } else if (Parent.First_Time(X - 1, Y) == false) { float[] Temp = new float[numRows]; mwDestGrid.GetFloatWindow(this.Rectangle.Y, this.Rectangle.Bottom - 1, this.Rectangle.X, this.Rectangle.X, ref Temp[0]); for (int row = 0; row < numRows; row++) { SourceArray[row][0] = Temp[row]; } } if (X == Parent.NumFramesWide - 1) { float[] Temp = new float[numRows]; mwSourceGrid.GetFloatWindow(this.Rectangle.Y, this.Rectangle.Bottom - 1, this.Rectangle.Right - 1, this.Rectangle.Right - 1, ref Temp[0]); for (int row = 0; row < numRows; row++) { SourceArray[row][numCols - 1] = Temp[row]; } } else if (Parent.First_Time(X + 1, Y) == false) { float[] Temp = new float[numRows]; mwDestGrid.GetFloatWindow(this.Rectangle.Y, this.Rectangle.Bottom - 1, this.Rectangle.Right - 1, this.Rectangle.Right - 1, ref Temp[0]); for (int row = 0; row < numRows; row++) { SourceArray[row][numCols - 1] = Temp[row]; } } if (ICallBack != null) { ICallBack.Progress("Status", 0, "Finished copying values from grid."); } return(SourceArray); }
// Flood cells represent cells that were changed in the last iteration // initially this should be on the order of the perimeter in size but will get "larger" // as the "overwriting" takes over. Flood areas overwrite with lower values, spreading the // lowest value as much as possible private static void FloodFill(float[][] Source, ref float[][] Dest, int numRows, int numCols, List <mPoint> WetCells, MapWinGIS.ICallback ICallBack) { mPoint pt; List <mPoint> NewCells; List <mPoint> DryCells; int[] dirX = { 1, 1, 0, -1, -1, -1, 0, 1 }; int[] dirY = { 0, 1, 1, 1, 0, -1, -1, -1 }; long Count = 0; int Percent; int OldPercent = 0; int Cycles = 0; while (WetCells.Count > 0) { NewCells = new List <mPoint>(); for (int iCell = 0; iCell < WetCells.Count; iCell++) { pt = WetCells[iCell]; if (Dest[pt.Row][pt.Col] < pt.Z) { pt.Z = Dest[pt.Row][pt.Col]; } int X, Y; for (int dr = 0; dr < 8; dr++) { // ensure the neighbor is inside the image Y = pt.Row + dirY[dr]; if (Y < 0 || Y > numRows - 1) { continue; } X = pt.Col + dirX[dr]; if (X < 0 || X > numCols - 1) { continue; } // if our neighbor is dry, don't do anything if (Dest[Y][X] == Source[Y][X]) { continue; } // if our neighbor's water level is below ours, change us if (Dest[Y][X] < pt.Z) { // if we are wet, we might as well save time and drop our level to that level if (pt.Z > Source[pt.Row][pt.Col]) { // if our source is higher, dry us out if (Source[pt.Row][pt.Col] >= Dest[Y][X]) { Dest[pt.Row][pt.Col] = Source[pt.Row][pt.Col]; pt.Z = Source[pt.Row][pt.Col]; DryCells = new List <mPoint>(); DryCells.Add(pt); NewCells.AddRange(DryUpward(Source, ref Dest, numRows, numCols, DryCells, ICallBack)); //We don't need to consider this direction for spreading since it was dry } else { Dest[pt.Row][pt.Col] = Dest[Y][X]; pt.Z = Dest[pt.Row][pt.Col]; NewCells.Add(pt); break; } } // if we made it here, we don't have to update ourself, but we don't // change our neighbor either continue; } // if our neighbor's source is higher than the water level, dry our neighbor if (Source[Y][X] >= pt.Z) { Dest[Y][X] = Source[Y][X]; DryCells = new List <mPoint>(); DryCells.Add(new mPoint(Y, X, Source[Y][X])); NewCells.AddRange(DryUpward(Source, ref Dest, numRows, numCols, DryCells, ICallBack)); } else { if (Dest[Y][X] > pt.Z) { // if our neighbor's water level is higher than ours, lower it Dest[Y][X] = pt.Z; NewCells.Add(new mPoint(Y, X, pt.Z)); } else { // our neighbor's water level is the same as ours, so do nothing continue; } } // our neighbor was changed } } WetCells = NewCells; if (ICallBack != null) { // assume an average of 3*NumRows*NumCols Count += NewCells.Count; Cycles = NewCells.Count; Percent = Convert.ToInt32(100 * Count / (2 * numCols * numRows)); if (Percent > OldPercent + 3) { if (Percent < 100) { ICallBack.Progress("status", Percent, "Count: " + Count + ", Mem: " + Cycles); OldPercent = Percent; } else { ICallBack.Progress("status", 100, "Count: " + Count + ", Mem: " + Cycles); OldPercent = Percent; } } } } // We succeeded in completely filling this image so we never have to come back return; }// End FloodFill
/// <summary> /// Reprojects an image using the currently defined projective transform. /// Be sure to call Derive_Coefficients first. This loops through point by point /// so won't be very fast. /// </summary> /// <param name="SourceImage">A MapWinGIS.Image object to be transformed</param> /// <param name="resultImage">A string representing the destination filename</param> /// <param name="ICallBack">A MapWinGIS.ICallback interface for progress messages</param> /// <remarks>ArgumentExceptions should be trapped for user error, but other types should be reported as bugs</remarks> public void ProjectImage(MapWinGIS.Image SourceImage, string resultImage, MapWinGIS.ICallback ICallBack) { bool res; if (SourceImage == null) { throw new ArgumentException("Source Image cannot be null."); } if (resultImage == null) { resultImage = System.IO.Path.ChangeExtension(SourceImage.Filename, "_Projected" + System.IO.Path.GetExtension(SourceImage.Filename)); } if (Defined == false) { throw new ApplicationException("You first have to define the coefficients by calling Derive_Coefficients."); } MapWinGIS.Image DestImage = new MapWinGIS.Image(); try { res = DestImage.CreateNew(m_OutputWidth, m_OutputHeight); } catch { throw new ApplicationException("The current Image object crashes with images too large to fit in memory."); } if (res == false) { throw new ApplicationException("Application Exception when Creating New: " + DestImage.get_ErrorMsg(DestImage.LastErrorCode)); } if (res == false) { throw new ApplicationException("Image object is having trouble creating a new image."); } for (int Yprj = 0; Yprj < m_OutputHeight; Yprj++) { for (int Xprj = 0; Xprj < m_OutputWidth; Xprj++) { double X, Y; double X1, Y1; int Xorig = 0; int Yorig = 0; X1 = (double)Xprj; Y1 = (double)Yprj; X = -(b * Y1 - Y1 * h * c + e * c - X1 * e + f * X1 * h - f * b) / (X1 * h * d + b * Y1 * g - b * d - X1 * g * e + a * e - a * Y1 * h); Y = -(c * Y1 * g + X1 * d - a * Y1 - X1 * g * f - c * d + a * f) / (X1 * h * d + b * Y1 * g - b * d - X1 * g * e + a * e - a * Y1 * h); if (X < 0 || Y < 0 || X > m_InputWidth || Y > m_InputHeight) { continue; } // using nearest neighbors Xorig = rnd(X); Yorig = rnd(Y); int Rowo = (m_InputHeight - 1) - Yorig; int pVal = SourceImage.get_Value(Rowo, Xorig); int row = (m_OutputHeight - 1) - Yprj; DestImage.set_Value(row, Xprj, pVal); } if (ICallBack != null) { ICallBack.Progress("Status", (Yprj * 100) / m_OutputHeight, "Row: " + Yprj.ToString()); } } DestImage.dX = m_OutputCellWidth; DestImage.dY = m_OutputCellHeight; DestImage.XllCenter = m_XllCenter; DestImage.YllCenter = m_YllCenter; string dir = System.IO.Path.GetDirectoryName(resultImage); if (!System.IO.Directory.Exists(dir)) { System.IO.Directory.CreateDirectory(dir); } if (System.IO.Path.GetExtension(resultImage) == ".jpg") { resultImage = System.IO.Path.ChangeExtension(resultImage, ".bmp"); } res = DestImage.Save(resultImage, true, MapWinGIS.ImageType.USE_FILE_EXTENSION, ICallBack); if (res == false) { throw new ApplicationException(DestImage.get_ErrorMsg(DestImage.LastErrorCode)); } DestImage.SetProjection(SourceImage.GetProjection()); DestImage.Close(); if (ICallBack != null) { ICallBack.Progress("Status", 0, "Saved output as " + DestImage.Filename); } }