/// <summary>
        /// Constructor used to combine a series of <c>IntersectResult</c> objects. This
        /// implementation is used to obtain a results object for a new topological line
        /// that has just been intersected against the map.
        /// </summary>
        /// <param name="xsect">The result of intersecting a line with the map</param>
        internal IntersectionResult(IntersectionFinder xsect)
        {
            m_IntersectedObject = xsect.Intersector;
            m_Geom = m_IntersectedObject.LineGeometry;
            m_Data = null;

            // Get the total number of intersections that were found (there's one
            // InteresectionResult for each intersected line)
            IList<IntersectionResult> results = xsect.Intersections;
            int nData = 0;
            foreach (IntersectionResult r in results)
                nData += r.m_Data.Count;

            // Return if no intersections.
            if (nData==0)
                return;

            // Copy over the info
            m_Data = new List<IntersectionData>(nData);
            foreach (IntersectionResult r in results)
            {
                List<IntersectionData> data = r.Intersections;
                foreach (IntersectionData d in data)
                    m_Data.Add(d);
            }

            // Reverse all context codes.
            foreach (IntersectionData d in m_Data)
                d.ReverseContext();
        }
Exemple #2
0
        /// <summary>
        /// Confirms that a potential link is valid. For a link to be valid, the
        /// midpoint of the link must fall inside the specified polygon, and the
        /// line connecting the 2 points cannot intersect anything.
        /// </summary>
        /// <param name="other">The end of the proposed point to link to.</param>
        /// <param name="pol">The polygon the link must fall completely inside.</param>
        /// <returns>True if link is valid.</returns>
        internal bool IsLinkValid(PolygonLink other, Polygon pol)
        {
            // 22-MAR-00 There may be no point at a corner.
            if (m_Point == null || other.Point == null)
            {
                return(false);
            }

            // Get the midpoint of the link.
            IPosition mid = Geom.MidPoint(m_Point, other.Point);

            // Confirm the midpoint falls inside the right polygon.
            if (!pol.IsRingEnclosing(mid))
            {
                return(false);
            }

            // Locate any intersections formed by the proposed link (considering
            // only the currently active theme).
            LineGeometry       seg   = new SegmentGeometry(m_Point, other.m_Point);
            IntersectionFinder xsect = new IntersectionFinder(seg, true);

            // The proposed link is not valid if it intersects anything
            // along the length of the segment, or has any grazes.
            if (xsect.IsGrazing || xsect.IsSplitNeeded)
            {
                return(false);
            }

            return(true);
        }
Exemple #3
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;
            }
        }
Exemple #4
0
        /// <summary>
        /// Constructor used to combine a series of <c>IntersectResult</c> objects. This
        /// implementation is used to obtain a results object for a new topological line
        /// that has just been intersected against the map.
        /// </summary>
        /// <param name="xsect">The result of intersecting a line with the map</param>
        internal IntersectionResult(IntersectionFinder xsect)
        {
            m_IntersectedObject = xsect.Intersector;
            m_Geom = m_IntersectedObject.LineGeometry;
            m_Data = null;

            // Get the total number of intersections that were found (there's one
            // InteresectionResult for each intersected line)
            IList <IntersectionResult> results = xsect.Intersections;
            int nData = 0;

            foreach (IntersectionResult r in results)
            {
                nData += r.m_Data.Count;
            }

            // Return if no intersections.
            if (nData == 0)
            {
                return;
            }

            // Copy over the info
            m_Data = new List <IntersectionData>(nData);
            foreach (IntersectionResult r in results)
            {
                List <IntersectionData> data = r.Intersections;
                foreach (IntersectionData d in data)
                {
                    m_Data.Add(d);
                }
            }

            // Reverse all context codes.
            foreach (IntersectionData d in m_Data)
            {
                d.ReverseContext();
            }
        }
        /// <summary>
        /// Do any splits needed upon addition of a new line.
        /// </summary>
        /// <param name="arePolygonsBuilt">Has polygon topology been built (false if the split
        /// is being done as part of the initial load).</param>
        /// <param name="retrims">Intersecting lines that were split on the invisible
        /// portion of a trimmed line. The lines in this list will need to be re-trimmed.
        /// </param>
        /// <remarks>
        /// 15-NOV-99: This function used to be called all over the place. It should now
        /// be called ONLY by <see cref="CadastralMapModel.Intersect"/>. To indicate that
        /// a line needs to be intersected, set the <see cref="IsMoved"/> property to
        /// true.
        /// </remarks>
        internal void Split(bool arePolygonsBuilt, List<LineFeature> retrims)
        {
            // No need to split lines that aren't topological.
            if (!IsTopological)
                return;

            if (m_Topology==null)
                throw new Exception("LineFeature.Split - topology hasn't been initialized");

            // This method should only be called for complete lines (with no pre-existing
            // topological sections)
            if (!(m_Topology is LineTopology))
            {
                string msg = String.Format("LineFeature.Split - Line {0} is associated with the wrong type of topology ({1})",
                    InternalId, m_Topology.GetType().Name);
                throw new Exception(msg);
            }
            LineTopology lineTop = (LineTopology)m_Topology;

            // Intersect this line with the map (ignoring end to end intersects).
            IntersectionFinder xf = new IntersectionFinder(this, false);

            // Return if no intersections.
            IList<IntersectionResult> intersectedDividers = xf.Intersections;
            if (intersectedDividers.Count==0)
                return;

            // Cut up the things that were intersected, making grazing portions non-topological.
            // Each result object should be associated with an IDivider.
            foreach (IntersectionResult r in intersectedDividers)
                Cut(arePolygonsBuilt, r, retrims);

            // Combine the results and get the splitter to cut itself up.
            IntersectionResult xres = new IntersectionResult(xf);

            if (arePolygonsBuilt)
            {
                // If there is a graze at the start of this line, ensure
                // that all polygons incident on the start location have
                // been marked for deletion. Same for the end.
                if (xres.IsStartGrazing)
                    Topology.MarkPolygons(StartPoint);

                if (xres.IsEndGrazing)
                    Topology.MarkPolygons(EndPoint);
            }

            // Modify the intersection results so that the exit point
            // of each graze will be treated as a simple intersection.
            // While at it, ensure there are no duplicates, and ensure
            // we don't have any intersections at the end of the line.
            if (xres.Simplify()==0)
                return;

            // Create divider sections. We should make at least ONE split.
            Cut(arePolygonsBuilt, xres, retrims);
        }
Exemple #6
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;
            }
        }