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