/// <summary>
        /// Accurate Clip Polygon with Line
        /// </summary>
        /// <param name="polygon"></param>
        /// <param name="line"></param>
        /// <param name="resultFeatureSet"></param>
        /// <returns></returns>
        public static bool Accurate_ClipPolygonWithLine(
            ref IFeature polygon, ref IFeature line, ref IFeatureSet resultFeatureSet)
        {
            if (polygon != null && line != null)
            {
                bool boundsIntersect = line.Crosses(polygon);
                if (boundsIntersect == false)
                {
                    return false;
                }

                // find if all of the line is inside, outside, or part in and out of polygon
                // line might intersect polygon mutliple times
                int numPoints = line.NumPoints;
                bool[] ptsInside = new bool[numPoints];
                int numInside = 0;
                int numOutside = 0;
                int numParts = polygon.NumPoints;
                if (numParts == 0)
                {
                    numParts = 1;
                }

                Coordinate[][] polyVertArray = new Coordinate[numParts][];
                ConvertPolyToVertexArray(ref polygon, ref polyVertArray);

                // check each point in the line to see if the entire line is either
                // inside of the polygon or outside of it (we know it's inside polygon bounding box).
                for (int i = 0; i <= numPoints - 1; i++)
                {
                    Point currPt = new Point(line.Coordinates[i]);
                    if (polygon.Covers(currPt))
                    {
                        ptsInside[i] = true;
                        numInside += 1;
                    }
                    else
                    {
                        ptsInside[i] = false;
                        numOutside += 1;
                    }
                }

                if (numInside == numPoints)
                {
                    // case: all points are inside polygon - check for possible intersections
                    if (ProcessAllInside(ref line, ref polygon, ref resultFeatureSet) == false)
                    {
                        return false;
                    }
                }
                else if (numOutside == numPoints)
                {
                    // case: all points are outside of the polygon - check for possible intersections
                    if (ProcessAllOutside(ref line, ref polygon, ref resultFeatureSet) == false)
                    {
                        return false;
                    }
                }
                else
                {
                    // case: part of line is inside and part is outside - find inside segments.
                    if (ProcessPartInAndOut(ref ptsInside, ref line, ref polygon, ref resultFeatureSet) == false)
                    {
                        return false;
                    }
                }
            }
            else
            {
                return false;
            }

            return true;
        }
        /// <summary>
        /// For faster clipping of polygons with lines. Limits the finding of intersections to
        /// outside->inside or inside->outside 2pt segments. Assumes only one intersections exists
        /// per segment, that a segment of two inside points or two outside points will not intersect
        /// the polygon.
        /// </summary>
        /// <param name="polygon">The polygon that will be sectioned by the line.</param>
        /// <param name="line">The line that will clip the polygon into multiple parts.</param>
        /// <param name="resultFeatureSet">The in-memory shapefile where the polygon sections will be saved.</param>
        /// <returns>False if errors are encountered, true otherwise.</returns>
        public static bool Fast_ClipPolygonWithLine(
            ref IFeature polygon, ref IFeature line, ref IFeatureSet resultFeatureSet)
        {
            IFeatureSet resultFile = new FeatureSet(FeatureType.Polygon);
            if (polygon != null && line != null)
            {
                // make sure we are dealing with a valid shapefile type
                if (polygon.FeatureType == FeatureType.Polygon)
                {
                    // create the result shapefile if it does not already exist
                    if (!polygon.Overlaps(line))
                    {
                        resultFeatureSet = resultFile;
                        return false;
                    }

                    // find if all of the line is inside, outside, or part in and out of polygon
                    // line might intersect polygon mutliple times
                    int numPoints = line.NumPoints;
                    bool[] ptsInside = new bool[numPoints];

                    int numInside = 0;
                    int numOutside = 0;

                    int numParts = polygon.NumGeometries;
                    if (numParts == 0)
                    {
                        numParts = 1;
                    }

                    Coordinate[][] polyVertArray = new Coordinate[numParts][];
                    ConvertPolyToVertexArray(ref polygon, ref polyVertArray);

                    // check each point in the line to see if the entire line is either
                    // inside of the polygon or outside of it (we know it's inside polygon bounding box).
                    for (int i = 0; i <= numPoints - 1; i++)
                    {
                        Point currPt = new Point(line.Coordinates[i]);

                        if (polygon.Covers(currPt))
                        {
                            ptsInside[i] = true;
                            numInside += 1;
                        }
                        else
                        {
                            ptsInside[i] = false;
                            numOutside += 1;
                        }
                    }

                    // case: all points are inside polygon - check for possible intersections
                    if (numInside == numPoints)
                    {
                        // assume no intersections exist in fast version
                    }
                    else if (numOutside == numPoints)
                    {
                        // case: all points are outside of the polygon - check for possible intersections
                        // assume no intersections exist in fast version
                    }
                    else
                    {
                        // case: part of line is inside and part is outside - find inside segments.
                        if (Fast_ProcessPartInAndOut(ptsInside, line, polygon, resultFile) == false)
                        {
                            resultFeatureSet = resultFile;
                            return false;
                        }
                    }

                    // resultSF result file, do not save to disk.
                    resultFeatureSet = resultFile;
                }
                else
                {
                    resultFeatureSet = resultFile;
                    return false;
                }
            }
            else
            {
                // polygon or line is invalid
                resultFeatureSet = resultFile;
                return false;
            }

            return true;
        }
Esempio n. 3
0
        /// <summary>
        /// Finds the average slope in the given polygons.
        /// </summary>
        /// <param name="ras">The dem Raster(Grid file).</param>
        /// <param name="zFactor">The scaler factor</param>
        /// <param name="poly">The flow poly shapefile path.</param>
        /// <param name="output">The resulting DEM of slopes</param>
        /// <param name="cancelProgressHandler">The progress handler.</param>
        public bool Execute(
            IRaster ras,
            double zFactor,
            IFeatureSet poly,
            IFeatureSet output,
            ICancelProgressHandler cancelProgressHandler)
        {
            // Validates the input and output data
            if (ras == null || poly == null || output == null)
            {
                return(false);
            }

            output.FeatureType = poly.FeatureType;
            foreach (IFeature f in poly.Features)
            {
                output.Features.Add(f);
            }

            output.DataTable.Columns.Add("FID", typeof(int));
            output.DataTable.Columns.Add(TextStrings.AveSlope, typeof(Double));

            IRaster slopeGrid = new Raster {
                DataType = ras.DataType, Bounds = ras.Bounds
            };

            // FeatureSet polyShape = new FeatureSet();
            int previous = 0;

            if (Slope(ref ras, zFactor, false, ref slopeGrid, cancelProgressHandler) == false)
            {
                return(false);
            }

            int shapeCount = output.Features.Count;

            int[]    areaCount = new int[shapeCount];
            double[] areaTotal = new double[shapeCount];
            double[] areaAve   = new double[shapeCount];
            double   dxHalf    = slopeGrid.CellWidth / 2;
            double   dyHalf    = slopeGrid.CellHeight / 2;

            // check whether those two envelope are intersect
            if (ras.Extent.Intersects(output.Extent) == false)
            {
                return(false);
            }

            RcIndex start = slopeGrid.ProjToCell(output.Extent.MinX, output.Extent.MaxY);
            RcIndex stop  = slopeGrid.ProjToCell(output.Extent.MaxX, output.Extent.MinY);

            int rowStart = start.Row;
            int colStart = start.Column;
            int rowStop  = stop.Row;
            int colStop  = stop.Column;

            for (int row = rowStart - 1; row < rowStop + 1; row++)
            {
                int current = Convert.ToInt32((row - rowStart + 1) * 100.0 / (rowStop + 1 - rowStart + 1));

                // only update when increment in percentage
                if (current > previous + 5)
                {
                    cancelProgressHandler.Progress(string.Empty, current, current + TextStrings.progresscompleted);
                    previous = current;
                }

                for (int col = colStart - 1; col < colStop + 1; col++)
                {
                    Coordinate cent  = slopeGrid.CellToProj(row, col);
                    double     xCent = cent.X;
                    double     yCent = cent.Y;
                    for (int shpindx = 0; shpindx < output.Features.Count; shpindx++)
                    {
                        IFeature tempFeat = output.Features[shpindx];
                        Point    pt1      = new Point(xCent, yCent);
                        Point    pt2      = new Point(xCent - dxHalf, yCent - dyHalf);
                        Point    pt3      = new Point(xCent + dxHalf, yCent - dyHalf);
                        Point    pt4      = new Point(xCent + dxHalf, yCent + dyHalf);
                        Point    pt5      = new Point(xCent - dxHalf, yCent + dyHalf);
                        if ((((!tempFeat.Covers(pt1) && !tempFeat.Covers(pt2)) && !tempFeat.Covers(pt3)) &&
                             !tempFeat.Covers(pt4)) && !tempFeat.Covers(pt5))
                        {
                            continue;
                        }

                        areaCount[shpindx]++;
                        areaTotal[shpindx] += slopeGrid.Value[row, col] / 100;

                        if (cancelProgressHandler.Cancel)
                        {
                            return(false);
                        }
                    }
                }
            }

            for (int shpindx = 0; shpindx < output.Features.Count; shpindx++)
            {
                if (areaCount[shpindx] == 0)
                {
                    areaAve[shpindx] = 0;
                }
                else
                {
                    areaAve[shpindx] = areaTotal[shpindx] / areaCount[shpindx];
                }

                output.Features[shpindx].DataRow["FID"] = shpindx;
                output.Features[shpindx].DataRow[TextStrings.AveSlope] = areaAve[shpindx];
            }

            poly.Close();
            slopeGrid.Close();
            output.SaveAs(output.Filename, true);
            return(true);
        }