Exemplo n.º 1
0
        /// <summary>
        /// Find the intersection points of lines that cross a polygon
        /// </summary>
        /// <param name="lineFeatureSet">The line features</param>
        /// <param name="polygon">The polygon feature</param>
        /// <param name="intersectsPerLineSeg">Output array of intersection counts</param>
        /// <param name="intersectionPts">Output array of intersection points</param>
        /// <param name="polyIntersectLocs">Output array of intersection locations in reference to polygon vertex indices</param>
        /// <returns></returns>
        public static int FindIntersections(
            IFeatureSet lineFeatureSet,
            IFeature polygon,
            out int[] intersectsPerLineSeg,
            out Point[][] intersectionPts,
            out int[][] polyIntersectLocs)
        {
            int numSignChanges = 0; // tracks number of determinant sign changes
            int numLines = lineFeatureSet.Features.Count;
            int numVerticies = polygon.NumPoints;
            int[][] detSigns = new int[numLines][];
            bool[][] signChanges = new bool[numLines][]; // keeps track of where sign changes occur
            int[][] changeLocations = new int[numLines][];
            int[] intersectsPerLine = new int[numLines];
            Point[][] intersectPts = new Point[numLines][];

            IList<Coordinate> coorPoly = polygon.Coordinates;

            // ICoordinate[] secCoor = new ICoordinate[2];
            for (int lineNo = 0; lineNo <= numLines - 1; lineNo++)
            {
                IFeature line = lineFeatureSet.Features[lineNo];
                IList<Coordinate> coorLine = line.Coordinates;
                int numChangesPerLine = 0;
                detSigns[lineNo] = new int[numVerticies];
                signChanges[lineNo] = new bool[numVerticies];
                intersectPts[lineNo] = new Point[numVerticies];
                changeLocations[lineNo] = new int[numVerticies];

                for (int vertNo = 0; vertNo <= numVerticies - 1; vertNo++)
                {
                    intersectPts[lineNo][vertNo] = new Point();
                    Point intersectPt = new Point();

                    // Calculate the determinant (3x3 square matrix)
                    double si = TurboDeterm(
                        coorPoly[vertNo].X,
                        coorLine[0].X,
                        coorLine[1].X,
                        coorPoly[vertNo].Y,
                        coorLine[0].Y,
                        coorLine[1].Y);

                    // Check the determinant result
                    switch (vertNo)
                    {
                        case 0:
                            if (Math.Abs(si) <= FindIntersectionTolerance)
                            {
                                detSigns[lineNo][vertNo] = 0; // we have hit a vertex
                            }
                            else if (si > 0)
                            {
                                detSigns[lineNo][vertNo] = 1; // +'ve
                            }
                            else if (si < 0)
                            {
                                detSigns[lineNo][vertNo] = -1; // -'ve
                            }

                            signChanges[lineNo][0] = false; // First element will NEVER be a sign change
                            break;
                        default:
                            if (Math.Abs(si) <= FindIntersectionTolerance)
                            {
                                detSigns[lineNo][vertNo] = 0;
                            }
                            else if (si > 0)
                            {
                                detSigns[lineNo][vertNo] = 1;
                            }
                            else if (si < 0)
                            {
                                detSigns[lineNo][vertNo] = -1;
                            }

                            // Check for sign change
                            if (detSigns[lineNo][vertNo - 1] != detSigns[lineNo][vertNo])
                            {
                                IList<Coordinate> secCoor = new List<Coordinate>
                                                                {
                                                                    coorPoly[vertNo - 1], coorPoly[vertNo]
                                                                };

                                // calculate the actual intercept point
                                LineString polyTestLine1 = new LineString(secCoor);
                                secCoor = new List<Coordinate> { coorLine[0], coorLine[1] };
                                LineString polyTestLine2 = new LineString(secCoor);
                                bool validIntersect = polyTestLine1.Intersects(polyTestLine2);
                                IGeometry inPt = polyTestLine1.Intersection(polyTestLine2);
                                if (inPt.Coordinates.Count == 1)
                                {
                                    intersectPt = new Point(inPt.Coordinate);
                                }

                                if (validIntersect)
                                {
                                    signChanges[lineNo][vertNo] = true;
                                    numSignChanges += 1;
                                    numChangesPerLine += 1;
                                    intersectsPerLine[lineNo] = numChangesPerLine;

                                    // we want to store the valid intersect pts at the
                                    // beginning of the array so we don't have to search for them
                                    intersectPts[lineNo][numChangesPerLine - 1] = intersectPt;

                                    // keep track of where the intersect occurs in reference to polygon
                                    changeLocations[lineNo][numChangesPerLine - 1] = vertNo;

                                    // intersect pt occurs between vertNo-1 and vertNo
                                }
                                else
                                {
                                    signChanges[lineNo][vertNo] = false;
                                }
                            }
                            else
                            {
                                signChanges[lineNo][vertNo] = false;
                            }

                            break;
                    }
                    // end of switch
                }
            }

            polyIntersectLocs = changeLocations;
            intersectionPts = intersectPts;
            intersectsPerLineSeg = intersectsPerLine;
            return numSignChanges;
        }