예제 #1
0
        /// <summary>
        /// Updates info on the longest horizontal span that crosses this polygon (used
        /// by <see cref="GetLabelPosition"/>)
        /// </summary>
        /// <param name="y">The Y-value of the scan line.</param>
        /// <param name="minx">The X-value for the western end of the scan line.</param>
        /// <param name="maxx">The X-value for the eastern end of the scan line.</param>
        /// <param name="weight">Weighting factor to use when comparing span lengths versus
        /// the initial best length.</param>
        /// <param name="beststart">The position of the start of the best span.</param>
        /// <param name="bestend">The position of the end of the best span.</param>
        /// <param name="bestlen">The weighted length of the best span. This is what defines
        /// the meaning of "best".</param>
        void GetLabelSpan(double y, double minx, double maxx, double weight,
                          ref IPosition beststart, ref IPosition bestend, ref double bestlen)
        {
            // Define scan line.
            ITerminal       sloc = new FloatingTerminal(minx, y);
            ITerminal       eloc = new FloatingTerminal(maxx, y);
            SegmentGeometry seg  = new SegmentGeometry(sloc, eloc);

            // Intersect with the map
            IntersectionFinder xseg = new IntersectionFinder(seg, true);

            // Arrange intersections along the scan line.
            IntersectionResult xres = new IntersectionResult(xseg);

            xres.Sort(true);

            // Define start of the first span
            IPosition start = sloc;
            IPosition end   = null;

            // Go through each successive intersection, to locate spans
            // that run through the interior of the polygon.
            foreach (IntersectionData d in xres.Intersections)
            {
                // If the intersection is a graze
                if (d.IsGraze)
                {
                    // Just define the end of the graze as the end point (there's
                    // no point in trying to locate a label along the graze).
                    end = d.P2;
                }
                else
                {
                    // Simple intersection...

                    // Get the next intersection
                    end = d.P1;

                    // Get the midpoint of the span.
                    IPosition mid = Position.CreateMidpoint(start, end);

                    // If the midpoint really falls inside this polygon, see whether the span
                    // length is bigger than what we already have (if anything).

                    if (this.IsEnclosing(mid))
                    {
                        double len = (end.X - start.X) / weight;
                        if (len > bestlen)
                        {
                            bestlen   = len;
                            beststart = start;
                            bestend   = end;
                        }
                    }
                }

                start = end;
            }
        }
예제 #2
0
        /// <summary>
        /// Updates info on the longest horizontal span that crosses this polygon (used
        /// by <see cref="GetLabelPosition"/>)
        /// </summary>
        /// <param name="y">The Y-value of the scan line.</param>
        /// <param name="minx">The X-value for the western end of the scan line.</param>
        /// <param name="maxx">The X-value for the eastern end of the scan line.</param>
        /// <param name="weight">Weighting factor to use when comparing span lengths versus
        /// the initial best length.</param>
        /// <param name="beststart">The position of the start of the best span.</param>
        /// <param name="bestend">The position of the end of the best span.</param>
        /// <param name="bestlen">The weighted length of the best span. This is what defines
        /// the meaning of "best".</param>
        void GetLabelSpan(double y, double minx, double maxx, double weight,
            ref IPosition beststart, ref IPosition bestend, ref double bestlen)
        {
            // Define scan line.
            ITerminal sloc = new FloatingTerminal(minx, y);
            ITerminal eloc = new FloatingTerminal(maxx, y);
            SegmentGeometry seg = new SegmentGeometry(sloc, eloc);

            // Intersect with the map
            IntersectionFinder xseg = new IntersectionFinder(seg, true);

            // Arrange intersections along the scan line.
            IntersectionResult xres = new IntersectionResult(xseg);
            xres.Sort(true);

            // Define start of the first span
            IPosition start = sloc;
            IPosition end = null;

            // Go through each successive intersection, to locate spans
            // that run through the interior of the polygon.
            foreach (IntersectionData d in xres.Intersections)
            {
                // If the intersection is a graze
                if (d.IsGraze)
                {
                    // Just define the end of the graze as the end point (there's
                    // no point in trying to locate a label along the graze).
                    end = d.P2;
                }
                else
                {
                    // Simple intersection...

                    // Get the next intersection
                    end = d.P1;

                    // Get the midpoint of the span.
                    IPosition mid = Position.CreateMidpoint(start, end);

                    // If the midpoint really falls inside this polygon, see whether the span
                    // length is bigger than what we already have (if anything).

                    if (this.IsEnclosing(mid))
                    {
                        double len = (end.X - start.X)/weight;
                        if (len>bestlen)
                        {
                            bestlen = len;
                            beststart = start;
                            bestend = end;
                        }
                    }
                }

                start = end;
            }
        }
예제 #3
0
        /// <summary>
        /// Intersects this multi-segment with itself. Only SIMPLE intersections will be
        /// found. There are no special checks for multi-segments that graze themselves.
        /// </summary>
        /// <param name="xsect">The intersection results.</param>
        /// <returns>The number of self-intersections found.</returns>
        uint SelfIntersect(IntersectionResult xsect)
        {
            uint nx = 0;

            // Get an array of cumulative distances for each segment.
            IPointGeometry[] data    = this.Data;
            double[]         cumdist = GetCumDist(data);

            // Note start of initial segment (treat as the end of some imaginary line prior to the start).
            double xs;
            double ys;
            double xe = data[0].X;
            double ye = data[0].Y;

            // How many line segments have we got?
            int nseg = data.Length - 1;

            // Loop through each segment, intersecting it with all subsequent
            // segments, except for the one that immediately follows.
            for (int iseg = 1; iseg <= (nseg - 2); iseg++)
            {
                // The start of this segment is the end of the previous one.
                xs = xe;
                ys = ye;

                // Get the position of the end of the test segment
                xe = data[iseg].X;
                ye = data[iseg].Y;

                // Compare against subsequent segments (except the next one)
                for (int jseg = iseg + 2; jseg <= nseg; jseg++)
                {
                    IPointGeometry start = data[jseg - 1];
                    IPointGeometry end = data[jseg];
                    double         xi, yi;

                    if (Geom.CalcIntersect(start.X, start.Y, end.X, end.Y, xs, ys, xe, ye, out xi, out yi, true) != 0)
                    {
                        // Define distance to the intersection on the i-segment
                        double dx   = xi - xs;
                        double dy   = yi - ys;
                        double ilen = cumdist[iseg - 1] + Math.Sqrt(dx * dx + dy * dy);

                        // Likewise for the j-segment
                        dx = xi - start.X;
                        dy = yi - start.Y;
                        double jlen = cumdist[jseg - 1] + Math.Sqrt(dx * dx + dy * dy);

                        // Append TWO intersections.
                        xsect.Append(xi, yi, ilen);
                        xsect.Append(xi, yi, jlen);
                        nx += 2;
                    }
                }
            }

            // Sort the intersections (DON'T set new sort values).
            xsect.Sort(false);

            // Return the number of intersections
            return(nx);
        }
        /// <summary>
        /// Intersects this multi-segment with itself. Only SIMPLE intersections will be
        /// found. There are no special checks for multi-segments that graze themselves.
        /// </summary>
        /// <param name="xsect">The intersection results.</param>
        /// <returns>The number of self-intersections found.</returns>
        uint SelfIntersect(IntersectionResult xsect)
        {
            uint nx = 0;

            // Get an array of cumulative distances for each segment.
            IPointGeometry[] data = this.Data;
            double[] cumdist = GetCumDist(data);

            // Note start of initial segment (treat as the end of some imaginary line prior to the start).
            double xs;
            double ys;
            double xe = data[0].X;
            double ye = data[0].Y;

            // How many line segments have we got?
            int nseg = data.Length-1;

            // Loop through each segment, intersecting it with all subsequent
            // segments, except for the one that immediately follows.
            for (int iseg=1; iseg<=(nseg-2); iseg++)
            {
                // The start of this segment is the end of the previous one.
                xs = xe;
                ys = ye;

                // Get the position of the end of the test segment
                xe = data[iseg].X;
                ye = data[iseg].Y;

                // Compare against subsequent segments (except the next one)
                for (int jseg=iseg+2; jseg<=nseg; jseg++)
                {
                    IPointGeometry start = data[jseg-1];
                    IPointGeometry end = data[jseg];
                    double xi, yi;

                    if (Geom.CalcIntersect(start.X, start.Y, end.X, end.Y, xs, ys, xe, ye, out xi, out yi, true)!=0)
                    {
                        // Define distance to the intersection on the i-segment
                        double dx = xi-xs;
                        double dy = yi-ys;
                        double ilen = cumdist[iseg-1] + Math.Sqrt(dx*dx + dy*dy);

                        // Likewise for the j-segment
                        dx = xi - start.X;
                        dy = yi - start.Y;
                        double jlen = cumdist[jseg-1] + Math.Sqrt(dx*dx + dy*dy);

                        // Append TWO intersections.
                        xsect.Append(xi, yi, ilen);
                        xsect.Append(xi, yi, jlen);
                        nx += 2;
                    }
                }
            }

            // Sort the intersections (DON'T set new sort values).
            xsect.Sort(false);

            // Return the number of intersections
            return nx;
        }