/// <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; }
/// <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); }