Esempio n. 1
0
 /// <summary>
 /// The default indexing of a raster specifies the column and row
 /// values for accessing a particular value.
 /// </summary>
 /// <param name="Column"></param>
 /// <param name="Row"></param>
 /// <returns></returns>
 public object this[int Column, int Row]
 {
     get
     {
         return(m_Grid.get_Value(Column, Row));
     }
     set
     {
         m_Grid.set_Value(Column, Row, value);
     }
 }
 public object get_Value(int col, int row)
 {
     return(grid.get_Value(col, row));
 }
        // 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.");
            }
        }
        /// <summary>
        /// This creates a new shapefile that has Z values and follows along the same line segments.
        /// The boundaries for grid cells are marked with vertices and the segment is given a Z value
        /// that corresponds to the grid elevation it intersects.
        /// </summary>
        /// <param name="mwElevGrid">A MapWinGIS Grid that contains the elevations.</param>
        /// <param name="mwPolyLine">A MapWinGIS Shapefile that shows the pathways of the cross sections in the X-Y direction.</param>
        /// <param name="OutFileName">A string containing the full path of the desired output shapefile.  The extension should be *.shp</param>
        /// <param name="CrossSectionType">Clarifies the type of output.  default = PolyLineWithZ</param>
        /// <param name="ICallBack">A MapWinGIS.ICallback for progress messages. [Optional]</param>
        /// <remarks>This function throws Argument or Application exceptions on errors, so it's recommended that coders enclose it in a try catch block.</remarks>
        public static void GetCrossSection(MapWinGIS.Grid mwElevGrid, MapWinGIS.Shapefile mwPolyLine, string OutFileName, CrossSectionTypes CrossSectionType, MapWinGIS.ICallback ICallBack)
        {
            MapWinUtility.Logger.Dbg("GetCrossSection(mwElevGrid: " + Macro.ParamName(mwElevGrid) + ",\n" +
                                     "                mwPolyLine: " + Macro.ParamName(mwPolyLine) + ",\n" +
                                     "                OutFileName: " + OutFileName + ",\n" +
                                     "                CrossSectionType: " + CrossSectionType.ToString() + ",\n" +
                                     "                ICallback)");
            bool   res;
            int    Prog = 0;
            int    OldProg = 0;
            double dS, dX, dY, XllCenter, YllCenter;
            int    NumRows, NumCols, ElevField, IDField;

            ElevField = 1;
            IDField   = 0;
            // Test to be sure that the elevation grid and shapefile are not null
            if (mwElevGrid == null)
            {
                MapWinUtility.Logger.Dbg("Argument Exception: Elevation grid mwElevGrid can't be null.");
                throw new ArgumentException("Elevation grid mwElevGrid can't be null.");
            }
            if (mwPolyLine == null)
            {
                MapWinUtility.Logger.Dbg("Argument Exception: The shapefile of input cross sections mwPolyLine can't be null.");
                throw new ArgumentException("The shapefile of input cross sections mwPolyLine can't be null.");
            }

            // Clear any existing shapefile output filenames that might cause problems if they exist.
            string fn;

            if (System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(OutFileName)) == false)
            {
                System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(OutFileName));
            }
            if (System.IO.File.Exists(OutFileName))
            {
                System.IO.File.Delete(OutFileName);
            }
            fn = System.IO.Path.ChangeExtension(OutFileName, ".dbf");
            if (System.IO.File.Exists(fn))
            {
                System.IO.File.Delete(fn);
            }
            fn = System.IO.Path.ChangeExtension(OutFileName, ".shx");
            if (System.IO.File.Exists(fn))
            {
                System.IO.File.Delete(fn);
            }
            fn = System.IO.Path.ChangeExtension(OutFileName, ".prj");
            if (System.IO.File.Exists(fn))
            {
                System.IO.File.Delete(fn);
            }
            // Since we are given the lower left coordinate, just make sure dX and dY are positive
            dX = Math.Abs(mwElevGrid.Header.dX);
            if (dX == 0)
            {
                throw new ApplicationException("mwElevGrid.Header.dX cannot be 0.");
            }
            dY = Math.Abs(mwElevGrid.Header.dY);
            if (dY == 0)
            {
                throw new ApplicationException("mwElevGrid.Header.dY cannot be 0.");
            }

            // Determine the stepping distance from the grid coordintes
            dS = dX / 2;
            if (dY < dX)
            {
                dS = dY / 2;
            }


            XllCenter = mwElevGrid.Header.XllCenter;
            YllCenter = mwElevGrid.Header.YllCenter;
            NumRows   = mwElevGrid.Header.NumberRows;
            NumCols   = mwElevGrid.Header.NumberCols;

            // Test for intersection between the entire shapefile and the grid
            double left, right, top, bottom;

            left   = XllCenter - dX / 2;
            right  = XllCenter + NumCols * dX - dX / 2;
            bottom = YllCenter - dY / 2;
            top    = YllCenter + NumRows * dY - dY / 2;
            MapWinGeoProc.Topology2D.Envelope gExt = new MapWinGeoProc.Topology2D.Envelope(left, right, bottom, top);
            MapWinGeoProc.Topology2D.Envelope pExt = new MapWinGeoProc.Topology2D.Envelope(mwPolyLine.Extents);
            if (gExt.Intersects(pExt) == false)
            {
                MapWinUtility.Logger.Dbg("Application Exception: The shapefile doesn't overlap the grid, so no cross sections were found.");
                throw new ApplicationException("The shapefile doesn't overlap the grid, so no cross sections were found.");
            }


            // Setup the output shapefile and the basic shape objects
            MapWinGIS.Shape     mwShape;
            MapWinGIS.Shapefile sfOut = new MapWinGIS.Shapefile();
            sfOut.Projection = mwPolyLine.Projection;

            if (CrossSectionType == CrossSectionTypes.PointsWithZAndElevField)
            {
                res = sfOut.CreateNew(OutFileName, MapWinGIS.ShpfileType.SHP_POINTZ);
                if (res != true)
                {
                    MapWinUtility.Logger.Dbg("Application Exception: " + sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                }
                res = sfOut.StartEditingShapes(true, ICallBack);
                if (res != true)
                {
                    MapWinUtility.Logger.Dbg("Application Exception: " + sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                }
                MapWinGIS.Field ID = new MapWinGIS.Field();
                ID.Name = "ID";
                ID.Type = MapWinGIS.FieldType.INTEGER_FIELD;
                res     = sfOut.EditInsertField(ID, ref IDField, ICallBack);
                if (res != true)
                {
                    MapWinUtility.Logger.Dbg("Application Exception: " + sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                }
                MapWinGIS.Field Elev = new MapWinGIS.Field();
                Elev.Name = "Elevation";
                Elev.Type = MapWinGIS.FieldType.DOUBLE_FIELD;
                res       = sfOut.EditInsertField(Elev, ref ElevField, ICallBack);
                if (res != true)
                {
                    MapWinUtility.Logger.Dbg("Application Exception: " + sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                }
            }
            else
            {
                res = sfOut.CreateNew(OutFileName, MapWinGIS.ShpfileType.SHP_POLYLINEZ);
                if (res != true)
                {
                    MapWinUtility.Logger.Dbg("Application Exception: " + sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                }
                res = sfOut.StartEditingShapes(true, ICallBack);
                if (res != true)
                {
                    MapWinUtility.Logger.Dbg("Application Exception: " + sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                }
                MapWinGIS.Field ID = new MapWinGIS.Field();
                ID.Name = "ID";
                ID.Type = MapWinGIS.FieldType.INTEGER_FIELD;
                res     = sfOut.EditInsertField(ID, ref IDField, ICallBack);
                if (res != true)
                {
                    MapWinUtility.Logger.Dbg("Application Exception: " + sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                }
            }



            MapWinGIS.Shape mwOutShape;
            // Loop through all the shapes in the polyline shapefile
            int shIndx = -1;

            for (int shp = 0; shp < mwPolyLine.NumShapes; shp++)
            {
                mwShape = mwPolyLine.get_Shape(shp);

                // By turning multi-part polylines into multiple linestrings, we avoid the annoying multi-part logic
                MultiLineString MLS = GeometryFactory.CreateMultiLineString(mwShape);

                for (int ls = 0; ls < MLS.NumGeometries; ls++)
                {
                    LineString lsSource = MLS.GeometryN[ls] as LineString;
                    for (int pt = 0; pt < lsSource.Coordinates.Count - 1; pt++)
                    {
                        Coordinate start = lsSource.Coordinates[pt];
                        Coordinate end   = lsSource.Coordinates[pt + 1];

                        // Crop the parts of each segment that do not overlap with the grid.
                        if (start.X < left)
                        {
                            if (end.X < left)
                            {
                                // this segment is outside the grid
                                continue;
                            }
                            // crop this segment to only the portion on the grid
                            start.X = left;
                        }
                        if (end.X < left)
                        {
                            // crop this segment to only the portion on the grid
                            end.X = left;
                        }
                        if (start.X > right)
                        {
                            if (end.X > right)
                            {
                                // this segment is outside the grid
                                continue;
                            }
                            // crop to grid
                            start.X = right;
                        }
                        if (end.X > right)
                        {
                            // crop to the grid
                            end.X = right;
                        }


                        double length   = Math.Sqrt((end.X - start.X) * (end.X - start.X) + (end.Y - start.Y) * (end.Y - start.Y));
                        int    NumSteps = (int)Math.Floor(length / dS);
                        double segDx    = (end.X - start.X) / NumSteps;
                        double segDy    = (end.Y - start.Y) / NumSteps;
                        mwOutShape = new MapWinGIS.Shape();
                        if (CrossSectionType == CrossSectionTypes.PolyLineWithZ)
                        {
                            mwOutShape.Create(MapWinGIS.ShpfileType.SHP_POLYLINEZ);
                        }

                        // step by dS and get the grid value at that point at each step
                        int p = 0;
                        for (int I = 0; I < NumSteps; I++)
                        {
                            int    row, col;
                            object Elev;
                            double X = start.X + segDx * I;
                            double Y = start.Y + segDy * I;
                            mwElevGrid.ProjToCell(X, Y, out col, out row);
                            Elev = mwElevGrid.get_Value(col, row);
                            MapWinGIS.Point pnt = new MapWinGIS.Point();
                            pnt.x = X;
                            pnt.y = Y;
                            pnt.Z = (double)Elev;
                            if (CrossSectionType == CrossSectionTypes.PointsWithZAndElevField)
                            {
                                p          = 0;
                                mwOutShape = new MapWinGIS.Shape();
                                mwOutShape.Create(MapWinGIS.ShpfileType.SHP_POINTZ);
                                res = mwOutShape.InsertPoint(pnt, ref p);
                                if (res == false)
                                {
                                    throw new ApplicationException(mwOutShape.get_ErrorMsg(mwOutShape.LastErrorCode));
                                }
                                res = sfOut.EditInsertShape(mwOutShape, ref shIndx);
                                if (res != true)
                                {
                                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                                }
                                res = sfOut.EditCellValue(IDField, shIndx, shIndx);
                                if (res != true)
                                {
                                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                                }
                                res = sfOut.EditCellValue(ElevField, shIndx, Elev);
                                if (res != true)
                                {
                                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                                }
                                shIndx++;
                            }
                            else
                            {
                                res = mwOutShape.InsertPoint(pnt, ref p);
                                p++;
                                if (res == false)
                                {
                                    throw new ApplicationException(mwOutShape.get_ErrorMsg(mwOutShape.LastErrorCode));
                                }
                            }
                        }
                        if (CrossSectionType == CrossSectionTypes.PolyLineWithZ)
                        {
                            if (mwOutShape.numPoints > 0)
                            {
                                res = sfOut.EditInsertShape(mwOutShape, ref shIndx);
                                if (res != true)
                                {
                                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                                }
                                res = sfOut.EditCellValue(IDField, shIndx, shIndx);
                                if (res != true)
                                {
                                    throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                                }
                                shIndx++;
                            }
                        }
                    }
                }
                Prog = Convert.ToInt32(shp * 100 / mwPolyLine.NumShapes);
                if (Prog > OldProg)
                {
                    MapWinUtility.Logger.Progress("Evaluating Cross Section..." + Prog.ToString() + "% Complete.", Prog, OldProg);
                    OldProg = Prog;
                }
            }
            res = sfOut.StopEditingShapes(true, true, ICallBack);
            if (res != true)
            {
                MapWinUtility.Logger.Dbg("Application Exception: " + sfOut.get_ErrorMsg(sfOut.LastErrorCode));
                throw new ApplicationException(sfOut.get_ErrorMsg(sfOut.LastErrorCode));
            }
        }