コード例 #1
0
        /// <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, "");
            }
        }
コード例 #2
0
        /// <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();
        }
コード例 #3
0
        /// <summary>
        /// Creates a new grid containing data from the input grid that
        /// falls within the polygon boundary.
        /// </summary>
        /// <param name="inputGF">Full path to the input grid file.</param>
        /// <param name="poly">The 2D polygon used for clipping the input grid.</param>
        /// <param name="resultGF">Full path to where the resulting grid will be saved.</param>
        /// <param name="clipToExtents">True if clipping to polygon extents rather than actual polygon shape.</param>
        /// <returns>True if clipping was successful, false if an error occurs.</returns>
        public static bool ClipGridWithPolygon(ref string inputGF, ref MapWinGIS.Shape poly, ref string resultGF, bool clipToExtents)
        {
            MapWinUtility.Logger.Dbg("ClipGridWithPolygon(inputGF: " + inputGF + ",\n" +
                                     "                    poly: " + Macro.ParamName(poly) + ",\n" +
                                     "                    resultGF: " + resultGF + ",\n" +
                                     "                    clipToExtents: " + clipToExtents.ToString());
            Error.ClearErrorLog();
            //			System.Diagnostics.PerformanceCounter ramCounter;
            //			ramCounter = new PerformanceCounter("Memory", "Available Bytes");
            //			float availableRAM = ramCounter.NextValue();
            bool inRAM = true;

            //open grid to get info and traverse through points
            MapWinGIS.Grid grid = new MapWinGIS.GridClass();

            //check memory availability
            //			availableRAM = ramCounter.NextValue();//amount of RAM in bytes
            //			Debug.WriteLine("available RAM: " + availableRAM.ToString() + " bytes");

            //			System.IO.FileInfo fileInfo = new FileInfo(inputGF);
            //			long fileSize = fileInfo.Length; //size of file in bytes
            //			Debug.WriteLine("file size: " + fileSize.ToString() + " bytes");
            //			if(fileSize*2 < availableRAM)
            //			{//go ahead and load grid into memory
            //				inRAM = true;
            //			}
            //			else
            //			{
            //				inRAM = false;
            //			}
            if (grid.Open(inputGF, MapWinGIS.GridDataType.UnknownDataType, inRAM, MapWinGIS.GridFileType.UseExtension, null) == false)
            {
                gErrorMsg = "Error occurred while trying to open grid: " + grid.get_ErrorMsg(grid.LastErrorCode);
                Error.SetErrorMsg(gErrorMsg);
                Debug.WriteLine(gErrorMsg);
                MapWinUtility.Logger.Dbg(gErrorMsg);
                return(false);
            }

            int    numCols    = grid.Header.NumberCols;
            int    numRows    = grid.Header.NumberRows;
            double cellWidth  = grid.Header.dX;
            double cellHeight = grid.Header.dY;
            double xllCenter  = grid.Header.XllCenter;
            double yllCenter  = grid.Header.YllCenter;
            //now calculate the UNCOMPRESSED grid file size:
            long inputGFSize = numCols * numRows * 8;

            //find the grid extents
            double minX, maxX, minY, maxY;

            minX = xllCenter - (cellWidth / 2);
            maxX = xllCenter + (cellWidth * (numCols - 1)) + (cellWidth / 2);
            minY = yllCenter - (cellHeight / 2);
            maxY = yllCenter + (cellHeight * (numRows - 1)) + (cellHeight / 2);

            //see if grid and poly extents cross:
            double polyMinX = poly.Extents.xMin;
            double polyMaxX = poly.Extents.xMax;
            double polyMinY = poly.Extents.yMin;
            double polyMaxY = poly.Extents.yMax;

            bool boundsIntersect = Globals.CheckBounds(minX, maxX, minY, maxY, polyMinX, polyMaxX, polyMinY, polyMaxY);

            if (boundsIntersect == false)
            {
                grid.Close();
                gErrorMsg = "Polygon and Grid boundaries do not overlap.";
                Error.SetErrorMsg(gErrorMsg);
                Debug.WriteLine(gErrorMsg);
                MapWinUtility.Logger.Dbg(gErrorMsg);
                return(false);
            }

            double newXll, newYll, firstXPt, firstYPt;
            int    newNumCols, newNumRows, firstCol, firstRow;

            //check if polygon extents are completely inside of grid extents
            if ((polyMinX >= minX && polyMinX <= maxX) && (polyMaxX >= minX && polyMaxX <= maxX) &&
                (polyMinY >= minY && polyMinY <= maxY) && (polyMaxY >= minY && polyMaxY <= maxY))
            {
                Debug.WriteLine("Poly extents are inside of grid extents.");
                minX = polyMinX;
                minY = polyMinY;
                maxX = polyMaxX;
                maxY = polyMaxY;

                //Find the new number of cols, rows, Xll and Yll values.
                int lastCol, lastRow;
                Globals.ProjToCell(minX, maxY, out firstCol, out firstRow, xllCenter, yllCenter, cellWidth, cellHeight, numRows);
                Globals.ProjToCell(maxX, minY, out lastCol, out lastRow, xllCenter, yllCenter, cellWidth, cellHeight, numRows);
                newNumCols = (lastCol - firstCol) + 1;
                newNumRows = (lastRow - firstRow) + 1;
                Debug.WriteLine("New numRows = " + newNumRows + " New numCols = " + newNumCols);
                Globals.CellToProj(firstCol, lastRow, out newXll, out newYll, xllCenter, yllCenter, cellWidth, cellHeight, numRows);
                Globals.CellToProj(firstCol, firstRow, out firstXPt, out firstYPt, xllCenter, yllCenter, cellWidth, cellHeight, numRows);
            }

            //check if grid extents are completely inside of polygon extents
            //note: there is really no purpose in this, as the new grid is the same
            //as the orgiginal grid....but we'll do it anyway.
            else if ((minX >= polyMinX && minX <= polyMaxX) && (maxX >= polyMinX && maxX <= polyMaxX) &&
                     (minY >= polyMinY && minY <= polyMaxY) && (maxY >= polyMinY && maxY <= polyMaxY))
            {
                Debug.WriteLine("Grid extents are inside of polygon extents.");
                //keep min and max values the same....no need to change them.
                newNumCols = numCols;
                newNumRows = numRows;
                newXll     = xllCenter;
                newYll     = yllCenter;
                firstCol   = 0;
                firstRow   = 0;
                Globals.CellToProj(0, 0, out firstXPt, out firstYPt, xllCenter, yllCenter, cellWidth, cellHeight, numRows);
            }
            else             //part of polygon lies outside of the grid, find intersecting boundary shape
            {
                Debug.WriteLine("Grid extents and polygon extents overlap.");
                //create a new shape out of the grid extents
                MapWinGIS.Shape gridEnvelope = new MapWinGIS.ShapeClass();
                gridEnvelope.Create(MapWinGIS.ShpfileType.SHP_POLYGON);
                MapWinGIS.Point pt = new MapWinGIS.PointClass();
                pt.x = minX;
                pt.y = maxY;
                int ptIndex = 0;
                gridEnvelope.InsertPoint(pt, ref ptIndex);
                pt      = new MapWinGIS.PointClass();
                pt.x    = maxX;
                pt.y    = maxY;
                ptIndex = 1;
                gridEnvelope.InsertPoint(pt, ref ptIndex);
                pt      = new MapWinGIS.PointClass();
                pt.x    = maxX;
                pt.y    = minY;
                ptIndex = 2;
                gridEnvelope.InsertPoint(pt, ref ptIndex);
                pt      = new MapWinGIS.PointClass();
                pt.x    = minX;
                pt.y    = minY;
                ptIndex = 3;
                gridEnvelope.InsertPoint(pt, ref ptIndex);
                pt      = new MapWinGIS.PointClass();
                pt.x    = minX;
                pt.y    = maxY;
                ptIndex = 4;
                gridEnvelope.InsertPoint(pt, ref ptIndex);

                //create the final bounding envelope which is
                //the intersection of the polygon and grid envelope:
                MapWinGIS.Shape envelope = new MapWinGIS.ShapeClass();
                envelope.Create(MapWinGIS.ShpfileType.SHP_POLYGON);
                envelope = SpatialOperations.Intersection(gridEnvelope, poly);
                if (envelope.numPoints == 0)
                {
                    gErrorMsg = "Problem creating the bounding envelope. Aborting ClipGrid().";
                    Error.SetErrorMsg(gErrorMsg);
                    Debug.WriteLine(gErrorMsg);
                    MapWinUtility.Logger.Dbg(gErrorMsg);
                    return(false);
                }

                //calculate how many rows and columns will exist within the new grid
                //that is: how many rows/cols fit within the bounding envelope.
                minX = envelope.Extents.xMin;
                minY = envelope.Extents.yMin;
                maxX = envelope.Extents.xMax;
                maxY = envelope.Extents.yMax;

                newNumCols = (int)(((maxX - minX) / cellWidth) + 0.5);
                newNumRows = (int)(((maxY - minY) / cellHeight) + 0.5);
                newXll     = minX + (cellWidth / 2);
                newYll     = minY + (cellHeight / 2);
                firstXPt   = newXll;
                firstYPt   = newYll + (cellHeight * (newNumRows - 1));
                Globals.ProjToCell(firstXPt, firstYPt, out firstCol, out firstRow, xllCenter, yllCenter, cellWidth, cellHeight, numRows);

                //done using COM objects, release them
                while (Marshal.ReleaseComObject(pt) != 0)
                {
                    ;
                }
                pt = null;
                while (Marshal.ReleaseComObject(gridEnvelope) != 0)
                {
                    ;
                }
                gridEnvelope = null;
                while (Marshal.ReleaseComObject(envelope) != 0)
                {
                    ;
                }
                envelope = null;
            }

            // Chris M 12/13/2006 for BugZilla 377
            // Below code:
            // The grid header cannot be copied right across like that! The first line creates
            // a new grid header; the second line deletes the newly created grid header and
            // copies a reference to the original grid's header. Both grids then are using
            // the same header; and when the last lines set the XllCenter and YllCenter,
            // BOTH grids are updated with that information! A classic example of pointers gone wrong.
            //MapWinGIS.GridHeader resultHeader = new MapWinGIS.GridHeaderClass();
            //resultHeader = grid.Header;
            //resultHeader.NodataValue = grid.Header.NodataValue;
            //resultHeader.NumberCols = newNumCols;
            //resultHeader.NumberRows = newNumRows;
            //resultHeader.XllCenter = newXll;
            //resultHeader.YllCenter = newYll;
            // The right way to do it:
            MapWinGIS.GridHeader resultHeader = new MapWinGIS.GridHeaderClass();
            resultHeader.CopyFrom(grid.Header);
            // Not really needed due to CopyFrom: resultHeader.NodataValue = grid.Header.NodataValue;
            resultHeader.NumberCols = newNumCols;
            resultHeader.NumberRows = newNumRows;
            resultHeader.XllCenter  = newXll;
            resultHeader.YllCenter  = newYll;
            // Not really needed due to CopyFrom: resultHeader.dX = grid.Header.dX;
            // Not really needed due to CopyFrom: resultHeader.dY = grid.Header.dY;
            // Not really needed due to CopyFrom: resultHeader.Projection = grid.Header.Projection;

            //create the new grid object
            MapWinGIS.Grid resultGrid = new MapWinGIS.GridClass();
            DataManagement.DeleteGrid(ref resultGF);

            //check memory availability
            //			availableRAM = ramCounter.NextValue();//amount of RAM in bytes
            //			Debug.WriteLine("available RAM: " + availableRAM.ToString() + " bytes");

            long resultGFSize = newNumCols * newNumRows * 8;             //projected size of grid in bytes

            //			if(resultGFSize * 2 < availableRAM)
            //			{//go ahead and load grid into memory
            //				inRAM = true;
            //			}
            //			else
            //			{
            //				inRAM = false;
            //			}

            if (resultGrid.CreateNew(resultGF, resultHeader, grid.DataType, grid.Header.NodataValue, inRAM, MapWinGIS.GridFileType.UseExtension, null) == false)
            {
                gErrorMsg = "Problem creating the result grid: " + resultGrid.get_ErrorMsg(resultGrid.LastErrorCode);
                Debug.WriteLine(gErrorMsg);
                Error.SetErrorMsg(gErrorMsg);
                MapWinUtility.Logger.Dbg(gErrorMsg);
                return(false);
            }
            //close the grids, we need to use the wrapper class now due to memory issues
            resultGrid.Save(resultGF, MapWinGIS.GridFileType.UseExtension, null);
            resultGrid.Close();
            while (Marshal.ReleaseComObject(resultGrid) != 0)
            {
                ;
            }
            resultGrid = null;
            grid.Close();
            while (Marshal.ReleaseComObject(grid) != 0)
            {
                ;
            }
            grid = null;

            //fill the result grid with values from the original grid
            try
            {
                Debug.WriteLine("newNumRows = " + newNumRows + " newNumCols = " + newNumCols);

                int rowClearCount = Globals.DetermineRowClearCount(newNumRows, newNumCols);

                Debug.WriteLine("Clearing COM resources every " + rowClearCount + " rows.");

                if (FillGrid(ref inputGF, ref resultGF, ref poly, newNumRows, newNumCols, rowClearCount, firstCol, firstRow, firstXPt, firstYPt, clipToExtents) == false)
                {
                    MapWinUtility.Logger.Dbg("Error running FillGrid\n");
                    return(false);
                }
            }            //end of try block
            catch (Exception e)
            {
                gErrorMsg = e.Message + e.ToString();
                Debug.WriteLine(gErrorMsg);
                Error.SetErrorMsg(gErrorMsg);
                MapWinUtility.Logger.Dbg(gErrorMsg);
                return(false);
            }


            //NOTE: The need for trimGrid has been removed from this function.
            //It will always return the smallest possible grid because we
            //build it based on the intersection boundary.

            DataManagement.CopyGridLegend(inputGF, resultGF);
            MapWinUtility.Logger.Dbg("Finished ClipGridWithPolygon");
            return(true);
        }