Exemple #1
0
        /// <summary>
        /// Checks if a divider is a dangle, floating, or a bridge.
        /// </summary>
        /// <param name="d">The divider to check</param>
        /// <returns>Bit mask of the check(s) the divider failed.</returns>
        static CheckType CheckNeighbours(IDivider d)
        {
            Debug.Assert(!d.IsOverlap);

            // Return if the divider has different polygons on both sides.
            if (d.Left != d.Right)
            {
                return(CheckType.Null);
            }

            bool sDangle = Topology.IsDangle(d, d.From);
            bool eDangle = Topology.IsDangle(d, d.To);

            if (sDangle && eDangle)
            {
                return(CheckType.Floating);
            }

            if (sDangle || eDangle)
            {
                return(CheckType.Dangle);
            }

            return(CheckType.Bridge);
        }
Exemple #2
0
        /// <summary>
        /// Gets the side code for a horizontal segment which is incident on a node,
        /// given any one the boundaries incident on the node.
        /// </summary>
        /// <param name="id">The divider we know about (incident on node).</param>
        /// <param name="isStart">True if it's the start of <c>ib</c>.</param>
        /// <param name="od">The divider the returned side refers to</param>
        /// <returns>Side.Left if the segment is to the left of <c>ob</c>, Side.Right
        /// if segment to the right.</returns>
        internal Side GetSide(IDivider id, bool isStart, out IDivider od)
        {
            ConnectionFinder connect = new ConnectionFinder(id, isStart, this);

            od = connect.Next;
            return(connect.IsStart ? Side.Right : Side.Left);
        }
Exemple #3
0
        /// <summary>
        /// Determines whether the sections in this list can be trimmed using the
        /// <see cref="TrimLineOperation"/>
        /// </summary>
        /// <returns>True if either end dangles, and we would be left with something
        /// after the trim.</returns>
        internal bool CanTrim()
        {
            // Can't trim if we don't have at least two sections
            if (m_Sections.Count < 2)
            {
                return(false);
            }

            // Get the sections at the ends.
            IDivider s = this.FirstDivider;
            IDivider e = this.LastDivider;

            Debug.Assert(s != e);

            // Return if neither end is dangling
            bool sDangle = Topology.IsDangle(s, s.From);
            bool eDangle = Topology.IsDangle(e, e.To);

            if (!(sDangle || eDangle))
            {
                return(false);
            }

            // Can't process if both ends are dangling and the common point is coincident
            if (sDangle && eDangle && s.To.IsCoincident(e.From))
            {
                return(false);
            }

            return(true);
        }
Exemple #4
0
        /// <summary>
        /// Performs checks on the supplied divider.
        /// </summary>
        /// <param name="d">The divider to check.</param>
        /// <returns>The problem(s) that were found.</returns>
        internal static CheckType Check(IDivider d)
        {
            // Ignore invisible dividers (the result of trimming dangling lines)
            if (!d.IsVisible)
            {
                return(CheckType.Null);
            }

            CheckType types = CheckType.Null;

            // Is the divider extremely small (smaller than 1mm on the mapping plane)?

            double len = d.LineGeometry.Length.Meters;

            if (len < 0.001)
            {
                types |= CheckType.SmallLine;
            }

            // Always flag overlaps. For all other dividers, check if
            // dangling, floating, or a bridge.

            if (d.IsOverlap)
            {
                types |= CheckType.Overlap;
            }
            else
            {
                types |= CheckNeighbours(d);
            }

            return(types);
        }
Exemple #5
0
 public ArithmeticCalculator(IAdder <T> adder, ISubtractor <T> subtractor, IMultiplier <T> multiplier, IDivider <T> divider)
 {
     _adder      = adder;
     _subtractor = subtractor;
     _multiplier = multiplier;
     _divider    = divider;
 }
Exemple #6
0
        /// <summary>
        /// Constructor used by <c>Ring.Create</c>.
        /// </summary>
        /// <param name="edge">The dividers that define the perimeter of the ring</param>
        protected Ring(RingMetrics metrics, List <Face> edge)
            : base(metrics)
        {
            m_Edge = new IDivider[edge.Count];
            m_Flag = 0;

            for (int i = 0; i < m_Edge.Length; i++)
            {
                Face     face = edge[i];
                IDivider d    = face.Divider;

                // Check for a divider that's already marked as being totally built.
                if (Topology.IsBuilt(d))
                {
                    throw new Exception("Polygon - Wrong build status for component divider");
                }

                // Remember the divider and update polygon geometry
                m_Edge[i] = d;

                if (face.IsLeft)
                {
                    d.Left = this;
                }
                else
                {
                    d.Right = this;
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// Creates a new <c>RingMetrics</c> object for the supplied faces.
        /// </summary>
        /// <param name="edge">The faces defining a ring</param>
        internal RingMetrics(List <Face> edge)
        {
            m_Area   = 0.0;
            m_Window = new Window();

            foreach (Face face in edge)
            {
                IDivider d      = face.Divider;
                bool     isLeft = face.IsLeft;

                double  area, length;
                IWindow awin;
                d.LineGeometry.GetGeometry(out awin, out area, out length);
                m_Window.Union(awin);

                if (face.IsLeft)
                {
                    m_Area -= area;
                }
                else
                {
                    m_Area += area;
                }
            }
        }
Exemple #8
0
 public Calculator(IQueryParser queryParser, IMultiplier multipler, IAdder adder, ISubtractor subtractor, IDivider divider)
 {
     _queryParser = queryParser;
     _multiplier  = multipler;
     _adder       = adder;
     _subtractor  = subtractor;
     _divider     = divider;
 }
        /// <summary>
        /// Creates a new <c>DividerObject</c> that wraps the supplied divider.
        /// </summary>
        /// <param name="d">The divider to wrap</param>
        internal DividerObject(IDivider d)
        {
            if (d==null)
                throw new ArgumentNullException();

            m_Divider = d;
            m_Geom = m_Divider.LineGeometry;
        }
 /// <summary>
 /// Default constructor
 /// </summary>
 internal PolygonFace()
 {
     m_Polygon = null;
     m_Divider = null;
     m_Begin = null;
     m_End = null;
     m_ExtraPoints = null;
 }
Exemple #11
0
 /// <summary>
 /// Default constructor
 /// </summary>
 internal PolygonFace()
 {
     m_Polygon     = null;
     m_Divider     = null;
     m_Begin       = null;
     m_End         = null;
     m_ExtraPoints = null;
 }
 public Calculator(IAdder adder, ISubtractor subtractor, IDivider divider, IMultiplier multiplier, IExponenter exponenter)
 {
     this.adder      = adder;
     this.subtractor = subtractor;
     this.divider    = divider;
     this.multiplier = multiplier;
     this.exponenter = exponenter;
 }
        /// <summary>
        /// Creates a new <c>DividerCheck</c> that relates to the specified divider.
        /// </summary>
        /// <param name="divider">The divider the check relates to (not null).</param>
        /// <param name="types">The type(s) of check this item corresponds to</param>
        /// <exception cref="ArgumentNullException">If <paramref name="divider"/> is null</exception>
        internal DividerCheck(IDivider divider, CheckType types)
            : base(types)
        {
            if (divider==null)
                throw new ArgumentNullException();

            m_Divider = divider;
        }
Exemple #14
0
        // .cctor
        static DivideManager()
        {
            // Create new classic divider instance
            IDivider classicDivider = new ClassicDivider();

            // Fill publicity visible divider fields
            ClassicDivider    = classicDivider;
            AutoNewtonDivider = new AutoNewtonDivider(classicDivider);
        }
Exemple #15
0
        // .cctor
        static DivideManager()
        {
            // Create new classic divider instance
            IDivider classicDivider = new ClassicDivider();

            // Fill publicity visible divider fields
            ClassicDivider = classicDivider;
            AutoNewtonDivider = new AutoNewtonDivider(classicDivider);
        }
        public Decomposed Execute(
            Factor factors,
            IDivider divider,
            dynamic algorithm,
            IUserAlgorithmStrategyProvider strategtProvider
            )
        {
            factors = Normalize(factors);
            var decomposed = new Decomposed();

            decomposed.Factors.Add(factors);

            var continueFlag = true;

            while (continueFlag)
            {
                continueFlag = false;
                var freeTermFactors = (List <int>)GetNumberFactors(decomposed.Factors.Last().Terms.Where(x => x.SymbolsPower == 0).Select(term => term.Number).FirstOrDefault(),
                                                                   algorithm,
                                                                   strategtProvider
                                                                   );

                freeTermFactors.ForEach(coefficent =>
                {
                    var dividedPart = divider.Divide(decomposed.Factors.Last(), -coefficent);

                    if (dividedPart != null)
                    {
                        Console.WriteLine(decomposed);

                        var newdividerFactor   = new Factor();
                        newdividerFactor.Terms = new List <Term>()
                        {
                            new Term
                            {
                                Number       = 1,
                                Sign         = Sign.Plus,
                                Symbol       = 'x',
                                SymbolsPower = 1
                            },
                            new Term
                            {
                                Number       = Math.Abs(coefficent),
                                Sign         = (coefficent >= 0) ? Sign.Minus : Sign.Plus,
                                SymbolsPower = 1
                            }
                        };

                        decomposed.Factors.Insert(0, newdividerFactor);
                        decomposed.Factors[decomposed.Factors.Count() - 1] = dividedPart;
                        continueFlag = true;
                    }
                });
            }
            return(decomposed);
        }
Exemple #17
0
        /// <summary>
        /// Creates a new <c>DividerCheck</c> that relates to the specified divider.
        /// </summary>
        /// <param name="divider">The divider the check relates to (not null).</param>
        /// <param name="types">The type(s) of check this item corresponds to</param>
        /// <exception cref="ArgumentNullException">If <paramref name="divider"/> is null</exception>
        internal DividerCheck(IDivider divider, CheckType types)
            : base(types)
        {
            if (divider == null)
            {
                throw new ArgumentNullException();
            }

            m_Divider = divider;
        }
Exemple #18
0
        /// <summary>
        /// Creates a new <c>DividerObject</c> that wraps the supplied divider.
        /// </summary>
        /// <param name="d">The divider to wrap</param>
        internal DividerObject(IDivider d)
        {
            if (d == null)
            {
                throw new ArgumentNullException();
            }

            m_Divider = d;
            m_Geom    = m_Divider.LineGeometry;
        }
Exemple #19
0
        /// <summary>
        /// This function loops through the items of the collection of values and performs the division or attemps to divide.
        /// The result returned will be displayed by the print delegate, which is set by the caller.
        /// </summary>
        /// <param name="divider"></param>
        /// <param name="print"></param>
        public void RunDivider(IDivider divider, Delegates.DisplayDelegate display)
        {
            string returnResult;

            display("There are " + _nObjects.Count() + " elements in the collection.");

            foreach (NObject nObject in _nObjects)
            {
                returnResult = divider.Divide(nObject);
                display(returnResult);
            }
        }
Exemple #20
0
        public IDivider[] IncidentDividers()
        {
            List <IDivider> result = new List <IDivider>(4); // 4 is frequently the number in the result

            foreach (IFeatureDependent fd in Dependents)
            {
                if (fd is LineFeature)
                {
                    LineFeature line = (fd as LineFeature);
                    Topology    t    = line.Topology;

                    if (t != null)
                    {
                        // Could have a situation where BOTH start and end of the line end
                        // at the same point (e.g. a multisegment that loops back on itself).

                        bool sMatch = line.StartPoint.IsCoincident(this);
                        bool eMatch = line.EndPoint.IsCoincident(this);

                        if (sMatch)
                        {
                            IDivider d = t.FirstDivider;
                            if (!d.IsOverlap)
                            {
                                result.Add(d);
                            }
                        }

                        if (eMatch)
                        {
                            // The result could conceivably contain the divider already (case where a multi-segment
                            // closes on itself)
                            IDivider d = t.LastDivider;
                            if (!d.IsOverlap && !result.Contains(d))
                            {
                                result.Add(d);
                            }
                        }

                        if (!(sMatch || eMatch))
                        {
                            // Cover a situation where this point is referenced to a line that
                            // passes through (intersection).
                            Debug.Assert(t is SectionTopologyList);
                            SectionTopologyList sections = (t as SectionTopologyList);
                            sections.AddIncidentDividers(result, this);
                        }
                    }
                }
            }

            return(result.ToArray());
        }
Exemple #21
0
        /// <summary>
        /// Replaces topology associated with this instance. This gets called when the
        /// topology is getting cut up at intersections.
        /// </summary>
        /// <param name="oldDivider">The divider that's being replaced</param>
        /// <param name="newDividers">The dividers to insert in place of <paramref name="oldDivider"/></param>
        /// <exception cref="ArgumentException">If <paramref name="oldDivider"/> is not
        /// part of this list</exception>
        internal void ReplaceDivider(IDivider oldDivider, List <IDivider> newDividers)
        {
            int index = m_Sections.IndexOf(oldDivider);

            if (index < 0)
            {
                throw new ArgumentException("SectionTopologyList.ReplaceDivider - Cannot locate topological section");
            }

            m_Sections.RemoveAt(index);
            m_Sections.InsertRange(index, newDividers);
        }
Exemple #22
0
        /// <summary>
        /// One-time definition of the topological divider that this face corresponds to.
        /// </summary>
        /// <param name="pol">The polygon this face is part of</param>
        /// <param name="line">The topological line that acts as the primary face for
        /// some portion of the polygon boundary</param>
        /// <returns>The number of points for this face (one for the start of the face,
        /// plus any intermediate points along the face).</returns>
        internal uint SetDivider(Polygon pol, IDivider line)
        {
            // Expect that this method should only ever get called once in the
            // lifetime of an instance
            Debug.Assert(m_ExtraPoints == null);

            // Define any extra points
            m_Polygon = pol;
            m_Divider = line;
            int nExtra = SetExtraPoints();

            return((uint)(1 + nExtra));
        }
Exemple #23
0
        /// <summary>
        /// Will a divider associated with this topology be drawn by the <see cref="RenderTrimmed"/>
        /// method?
        /// </summary>
        /// <param name="d">One of the dividers in this list</param>
        /// <returns>True if the divider coincides with a dangling portion of the line.</returns>
        internal bool IsVisible(IDivider d)
        {
            if (Object.ReferenceEquals(d, FirstDivider))
            {
                return(!Line.IsStartDangle());
            }

            if (Object.ReferenceEquals(d, LastDivider))
            {
                return(!Line.IsEndDangle());
            }

            return(true);
        }
        /// <summary>
        /// Creates new <c>Orientation</c> for one end of a divider
        /// </summary>
        /// <param name="d">The divider we are interested in (not null)</param>
        /// <param name="isStart">At start of the divider?</param>
        /// <exception cref="ArgumentNullException">If <paramref name="d"/> is null</exception>
        internal Orientation(IDivider d, bool isStart)
        {
            if (d==null)
                throw new ArgumentNullException("Divider cannot be null");

            m_Divider = d;
            m_IsStart = isStart;

            // Get orientation point for the divider
            IPosition orient = d.LineGeometry.GetOrient(isStart, 0.0);

            // Set the orientation info.
            SetOrient(orient);
        }
Exemple #25
0
        /// <summary>
        /// Checks whether this selection refers to the same spatial objects as
        /// another selection, and has the same reference position.
        /// </summary>
        /// <param name="that">The selection to compare with</param>
        /// <returns>True if the two selections refer to the same spatial objects (not
        /// necessarily in the same order)</returns>
        public bool Equals(ISpatialSelection that)
        {
            // The same spatial objects have to be involved
            if (!SpatialSelection.Equals(this, that))
                return false;

            // If both selections refer to the same divider (or null), they're the same
            Selection other = (that as Selection);
            if (other == null)
                return false;

            IDivider d1 = (this.m_Section == null ? null : this.m_Section.Divider);
            IDivider d2 = (other.m_Section == null ? null : other.m_Section.Divider);
            return Object.ReferenceEquals(d1, d2);
        }
Exemple #26
0
        /// <summary>
        /// Creates new <c>Orientation</c> for one end of a divider
        /// </summary>
        /// <param name="d">The divider we are interested in (not null)</param>
        /// <param name="isStart">At start of the divider?</param>
        /// <exception cref="ArgumentNullException">If <paramref name="d"/> is null</exception>
        internal Orientation(IDivider d, bool isStart)
        {
            if (d == null)
            {
                throw new ArgumentNullException("Divider cannot be null");
            }

            m_Divider = d;
            m_IsStart = isStart;

            // Get orientation point for the divider
            IPosition orient = d.LineGeometry.GetOrient(isStart, 0.0);

            // Set the orientation info.
            SetOrient(orient);
        }
Exemple #27
0
        /// <summary>
        /// Returns the name of a derived entity type associated with a line.
        /// If an entity file has been loaded, this may be based on the entity
        /// types of the adjacent polygons. Failing that, the result will be
        /// the same as the name of the line's "normal" entity type.
        /// </summary>
        /// <param name="line">The line to process.</param>
        /// <param name="layer">The layer of interest.</param>
        /// <returns>The name of the derived entity type (may be blank)</returns>
        internal static string GetDerivedType(IDivider line, ILayer layer)
        {
            // If we have an entity file, and it can return a derived type,
            // that's us done.
            if (s_EntityFile != null)
            {
                string dervEntName = s_EntityFile.GetDerivedType(line, layer);
                if (dervEntName != null)
                {
                    return(dervEntName);
                }
            }

            // Get the line's entity type (if any).
            IEntity lineEnt = line.Line.EntityType;

            return(lineEnt == null ? String.Empty : lineEnt.Name);
        }
Exemple #28
0
        /// <summary>
        /// Merges divider sections that are incident on the specified intersection. This gets
        /// called when one of the lines causing an intersection is being removed (deactivated).
        /// </summary>
        /// <param name="x">An intersection that is being removed</param>
        /// <returns>The number of sections after the merge</returns>
        internal override int MergeSections(Intersection x)
        {
            for (int i = 0; i < (m_Sections.Count - 1); i++)
            {
                IDivider a = m_Sections[i];
                if (a.To == x)
                {
                    IDivider b = m_Sections[i + 1];

                    // If either divider is an overlap, it would be BAD to merge
                    if (a is SectionDivider && b is SectionDivider)
                    {
                        m_Sections.RemoveAt(i + 1);
                        m_Sections[i] = new SectionDivider(Line, a.From, b.To);
                    }
                }
            }

            return(m_Sections.Count);
        }
Exemple #29
0
        /// <summary>
        /// Creates new <c>Orientation</c> based on the supplied horizontal ray.
        /// </summary>
        /// <param name="hr"></param>
        internal Orientation(HorizontalRay hr)
        {
            // Remember the stuff we were supplied (since we are not starting
            // with a divider, it has to be null).

            m_Divider = null;
            m_IsStart = false;

            // The horizontal segment is ALWAYS at the very start of the
            // north-west quadrant.
            m_Quadrant = Quadrant.NW;

            // Convert the deltas into the IJ coordinate system for the
            // north-west quadrant (the angle defined with I/J should
            // evaluate to zero, since the horizontal segment is at the
            // start of the quadrant).

            m_DeltaI = 0.0;
            m_DeltaJ = hr.EndX - hr.StartX;
        }
Exemple #30
0
        /// <summary>
        /// Returns the style for the specified line
        /// </summary>
        /// <param name="line">The feature to get the style for</param>
        /// <param name="layer">The editing layer</param>
        /// <returns>The corresponding style (never null)</returns>
        internal static Style GetStyle(IDivider line, ILayer layer)
        {
            if (s_StyleFile == null)
            {
                return(s_BlackStyle);
            }

            // Get the name of the (possibly derived) entity type
            string entName = GetDerivedType(line, layer);

            // Nothing at all means we should have a construction
            // line, which is always symbolized as a black dotted line.
            if (entName.Length == 0)
            {
                return(s_BlackDottedLineStyle);
            }

            // Try to get a style using the name of the derived
            // entity type.
            Style style = s_StyleFile.GetStyle(entName);

            if (style != null)
            {
                return(style);
            }

            /*
             * // If we didn't get anything, look for a style that
             * // refers to the line's base theme.
             * ILayer t = line.Line.BaseLayer;
             * if (t != null)
             * {
             *  style = s_StyleFile.GetStyle(t.Name);
             *  if (style != null)
             *      return style;
             * }
             */

            // Return the default style
            return(s_BlackStyle);
        }
Exemple #31
0
        /// <summary>
        /// Tries to return the name of a derived entity type for a specific line.
        /// </summary>
        /// <param name="line">The line to process.</param>
        /// <param name="layer">The layer of interest (in the same address space as
        /// the map that contains the line).</param>
        /// <returns>The name of the derived entity type (null if not found).</returns>
        internal string GetDerivedType(IDivider line, ILayer layer)
        {
            // Return if the line does not have an entity type (it SHOULD do)
            IEntity ent = line.Line.EntityType;

            if (ent == null)
            {
                return(null);
            }

            // Get the translation block (if any) that refers to the line's entity type.
            string      entName = ent.Name;
            string      lyrName = layer.Name;
            EntityBlock block   = Array.Find <EntityBlock>(m_Blocks, eb => eb.IsMatch(entName, lyrName));

            // Return if the line's entity type is not associated with a translation.
            if (block == null)
            {
                return(null);
            }

            // Get the polygons on either side of the line (the REAL
            // user-perceived polygons, not phantoms).
            Polygon leftPol  = (line.Left == null ? null : line.Left.RealPolygon);
            Polygon rightPol = (line.Right == null ? null : line.Right.RealPolygon);

            // Get the entity types for the adjacent polygons (if any).
            IEntity leftEnt  = (leftPol == null ? null : leftPol.EntityType);
            IEntity rightEnt = (rightPol == null ? null : rightPol.EntityType);

            if (leftEnt != null || rightEnt != null)
            {
                string e1 = (leftEnt == null ? String.Empty : leftEnt.Name);
                string e2 = (rightEnt == null ? String.Empty : rightEnt.Name);

                return(block.GetDerivedType(e1, e2));
            }

            return(null);
        }
Exemple #32
0
        /// <summary>
        /// Locates the divider that is closest to the specified position.
        /// </summary>
        /// <param name="p">The position of interest</param>
        /// <returns>The closest section (null if there are no sections in this list)</returns>
        internal IDivider FindClosestSection(IPosition p)
        {
            if (m_Sections.Count == 0)
            {
                return(null);
            }

            IDivider result  = m_Sections[0];
            double   minDist = result.LineGeometry.Distance(p).Meters;

            for (int i = 1; i < m_Sections.Count; i++)
            {
                double d = m_Sections[i].LineGeometry.Distance(p).Meters;
                if (d < minDist)
                {
                    minDist = d;
                    result  = m_Sections[i];
                }
            }

            return(result);
        }
Exemple #33
0
        /// <summary>
        /// Creates a new <c>Selection</c> that contains a single item (or nothing).
        /// </summary>
        /// <param name="so">The object to remember as part of this selection (if null, it
        /// will not be added to the selection)</param>
        /// <param name="searchPosition">A position associated with the selection (null
        /// if a specific position isn't relevant). This is used to determine whether a
        /// topological section is relevant when a line is selected.</param>
        public Selection(ISpatialObject so, IPosition searchPosition)
        {
            m_Items = new List<ISpatialObject>(1);
            if (so!=null)
                m_Items.Add(so);

            // If we're dealing with a single line that's been topologically sectioned,
            // determine which divider we're closest to.

            m_Section = null;

            if (searchPosition != null)
            {
                LineFeature line = (so as LineFeature);
                if (line != null && line.Topology is SectionTopologyList)
                {
                    SectionTopologyList sections = (line.Topology as SectionTopologyList);
                    IDivider d = sections.FindClosestSection(searchPosition);
                    if (d != null)
                        m_Section = new DividerObject(d);
                }
            }
        }
Exemple #34
0
        /// <summary>
        /// Draws sections on the specified display, excluding dangling ends.
        /// </summary>
        /// <param name="display">The display to draw to</param>
        /// <param name="style">The drawing style</param>
        internal void RenderTrimmed(ISpatialDisplay display, IDrawStyle style)
        {
            // If we're highlighting, dangling portions should be drawn dotted
            IDrawStyle dangleStyle = (style is HighlightStyle ? new DottedStyle(Color.Red) : null);

            bool sDangle = Line.IsStartDangle();
            bool eDangle = Line.IsEndDangle();

            int last = m_Sections.Count - 1;

            for (int i = 0; i <= last; i++)
            {
                if ((i == 0 && !sDangle) || (i > 0 && i < last) || (i == last && !eDangle))
                {
                    IDivider d = m_Sections[i];
                    d.Line.RenderDivider(d, display, style);
                }
                else if (dangleStyle != null && ((i == 0 && sDangle) || (i == last && eDangle)))
                {
                    IDivider d = m_Sections[i];
                    d.Line.RenderDivider(d, display, dangleStyle);
                }
            }
        }
        /// <summary>
        /// Performs checks on the supplied divider.
        /// </summary>
        /// <param name="d">The divider to check.</param>
        /// <returns>The problem(s) that were found.</returns>
        internal static CheckType Check(IDivider d)
        {
            // Ignore invisible dividers (the result of trimming dangling lines)
            if (!d.IsVisible)
                return CheckType.Null;

            CheckType types = CheckType.Null;

            // Is the divider extremely small (smaller than 1mm on the mapping plane)?

            double len = d.LineGeometry.Length.Meters;
            if (len < 0.001)
                types |= CheckType.SmallLine;

            // Always flag overlaps. For all other dividers, check if
            // dangling, floating, or a bridge.

            if (d.IsOverlap)
                types |= CheckType.Overlap;
            else
                types |= CheckNeighbours(d);

            return types;
        }
        /// <summary>
        /// Checks if a divider is a dangle, floating, or a bridge.
        /// </summary>
        /// <param name="d">The divider to check</param>
        /// <returns>Bit mask of the check(s) the divider failed.</returns>
        static CheckType CheckNeighbours(IDivider d)
        {
            Debug.Assert(!d.IsOverlap);

            // Return if the divider has different polygons on both sides.
            if (d.Left != d.Right)
                return CheckType.Null;

            bool sDangle = Topology.IsDangle(d, d.From);
            bool eDangle = Topology.IsDangle(d, d.To);

            if (sDangle && eDangle)
                return CheckType.Floating;

            if (sDangle || eDangle)
                return CheckType.Dangle;

            return CheckType.Bridge;
        }
        /// <summary>
        /// Creates new <c>Orientation</c> based on the supplied horizontal ray.
        /// </summary>
        /// <param name="hr"></param>
        internal Orientation(HorizontalRay hr)
        {
            // Remember the stuff we were supplied (since we are not starting
            // with a divider, it has to be null).

            m_Divider = null;
            m_IsStart = false;

            // The horizontal segment is ALWAYS at the very start of the
            // north-west quadrant.
            m_Quadrant = Quadrant.NW;

            // Convert the deltas into the IJ coordinate system for the
            // north-west quadrant (the angle defined with I/J should
            // evaluate to zero, since the horizontal segment is at the
            // start of the quadrant).

            m_DeltaI = 0.0;
            m_DeltaJ = hr.EndX - hr.StartX;
        }
 /// <summary>
 /// Is a divider associated with this line visible?
 /// </summary>
 /// <param name="d">One of the dividers associated with the topology for this line</param>
 /// <returns>False if this line is marked as trimmed, and the specified divider is not
 /// currently drawn.</returns>
 internal bool IsVisible(IDivider d)
 {
     // The logic here should mimic that of RenderTopologicalLine above.
     if (IsTrimmed && (m_Topology is SectionTopologyList))
         return (m_Topology as SectionTopologyList).IsVisible(d);
     else
         return true;
 }
Exemple #39
0
        /// <summary>
        /// Returns the style for the specified line
        /// </summary>
        /// <param name="line">The feature to get the style for</param>
        /// <param name="layer">The editing layer</param>
        /// <returns>The corresponding style (never null)</returns>
        internal static Style GetStyle(IDivider line, ILayer layer)
        {
            if (s_StyleFile == null)
                return s_BlackStyle;

            // Get the name of the (possibly derived) entity type
            string entName = GetDerivedType(line, layer);

            // Nothing at all means we should have a construction
            // line, which is always symbolized as a black dotted line.
            if (entName.Length == 0)
                return s_BlackDottedLineStyle;

            // Try to get a style using the name of the derived
            // entity type.
            Style style = s_StyleFile.GetStyle(entName);
            if (style != null)
                return style;

            /*
            // If we didn't get anything, look for a style that
            // refers to the line's base theme.
            ILayer t = line.Line.BaseLayer;
            if (t != null)
            {
                style = s_StyleFile.GetStyle(t.Name);
                if (style != null)
                    return style;
            }
            */

            // Return the default style
            return s_BlackStyle;
        }
Exemple #40
0
        /// <summary>
        /// Returns the name of a derived entity type associated with a line.
        /// If an entity file has been loaded, this may be based on the entity
        /// types of the adjacent polygons. Failing that, the result will be
        /// the same as the name of the line's "normal" entity type.
        /// </summary>
        /// <param name="line">The line to process.</param>
        /// <param name="layer">The layer of interest.</param>
        /// <returns>The name of the derived entity type (may be blank)</returns>
        internal static string GetDerivedType(IDivider line, ILayer layer)
        {
            // If we have an entity file, and it can return a derived type,
            // that's us done.
            if (s_EntityFile != null)
            {
                string dervEntName = s_EntityFile.GetDerivedType(line, layer);
                if (dervEntName != null)
                    return dervEntName;
            }

            // Get the line's entity type (if any).
            IEntity lineEnt = line.Line.EntityType;
            return (lineEnt == null ? String.Empty : lineEnt.Name);
        }
        /// <summary>
        /// Replaces topology associated with this instance. This gets called when the
        /// topology is getting cut up at intersections.
        /// </summary>
        /// <param name="oldDivider">The divider that's being replaced</param>
        /// <param name="newDividers">The dividers to insert in place of <paramref name="oldDivider"/></param>
        /// <exception cref="ArgumentException">If <paramref name="oldDivider"/> is not
        /// part of this list</exception>
        internal void ReplaceDivider(IDivider oldDivider, List<IDivider> newDividers)
        {
            int index = m_Sections.IndexOf(oldDivider);
            if (index<0)
                throw new ArgumentException("SectionTopologyList.ReplaceDivider - Cannot locate topological section");

            m_Sections.RemoveAt(index);
            m_Sections.InsertRange(index, newDividers);
        }
        /// <summary>
        /// Will a divider associated with this topology be drawn by the <see cref="RenderTrimmed"/>
        /// method?
        /// </summary>
        /// <param name="d">One of the dividers in this list</param>
        /// <returns>True if the divider coincides with a dangling portion of the line.</returns>
        internal bool IsVisible(IDivider d)
        {
            if (Object.ReferenceEquals(d, FirstDivider))
                return !Line.IsStartDangle();

            if (Object.ReferenceEquals(d, LastDivider))
                return !Line.IsEndDangle();

            return true;
        }
        /// <summary>
        /// Cuts up a divider that covers this line (or a portion of this 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="div">The divider covering the line (or a portion of this line)</param>
        /// <param name="xres">The places where intersections have been detected on
        /// the divider</param>
        /// <param name="retrims">Lines that need to be re-trimmed (the line associated
        /// with the divider will be appended if an intersection is made on an invisible
        /// portion of the divider). Not currently used.</param>
        void Cut(bool arePolygonsBuilt, IDivider div, IntersectionResult xres, List<LineFeature> retrims)
        {
            Debug.Assert(div.Line == this);

            // Should never need to cut anything that represents an overlap (they're
            // supposed to be treated as non-topological)
            Debug.Assert(!div.IsOverlap);

            // Return if nothing to do
            List<IntersectionData> data = xres.Intersections;
            if (data == null || data.Count == 0)
                return;

            // Ensure that any polygons known to this boundary have been
            // marked for deletion (need to do this in case the intersects
            // we have are only at the line end points, in which case we
            // wouldn't actually change anything).
            if (arePolygonsBuilt)
                Topology.MarkPolygons(div);

            // We'll need the map for creating intersection points
            CadastralMapModel map = CadastralMapModel.Current;

            // Create list of resultant sections
            List<IDivider> result = new List<IDivider>();
            ITerminal from, to;
            from = to = div.From;

            for (int i = 0; i < data.Count; i++, from = to)
            {
                // Get the intersection data.
                IntersectionData x = data[i];

                if (x.IsGraze)
                {
                    // There are 4 sorts of graze to deal with:
                    // 1. The graze covers the complete line.
                    // 2. The graze is at the start of the line.
                    // 3. The graze is along some interior portion of the line.
                    // 4. The graze is at the end of the line.

                    // If it's a total graze, there should only be ONE intersection.
                    if (x.IsTotalGraze)
                    {
                        Debug.Assert(data.Count == 1);
                        if (data.Count != 1)
                            throw new Exception("LineFeature.Cut - Multiple overlaps detected");

                        // Mark all polygons incident on the terminals.
                        Topology.MarkPolygons(div.From);
                        Topology.MarkPolygons(div.To);

                        // Define overlap for the entire divider
                        if (div is LineTopology)
                            result.Add(new LineOverlap(div.Line));
                        else
                            result.Add(new SectionOverlap(this, div.From, div.To));

                        to = div.To;
                    }
                    else if (x.IsStartGraze)
                    {
                        Debug.Assert(i == 0);
                        Debug.Assert(from == div.From);

                        // Mark all polygons incident at the start terminal
                        if (arePolygonsBuilt)
                            Topology.MarkPolygons(div.From);

                        // Create an overlap at the start of this divider
                        to = map.GetTerminal(x.P2);
                        if (from != to)
                            result.Add(new SectionOverlap(this, from, to));
                    }
                    else if (x.IsInteriorGraze)
                    {
                        // Add a section from the current tail to the start of the graze
                        // 05-APR-2003 (somehow got a simple x-sect followed by a graze, so ensure we don't add a null section)
                        to = map.GetTerminal(x.P1);
                        if (from != to)
                            result.Add(new SectionDivider(this, from, to));

                        // Add the overlap
                        from = to;
                        to = map.GetTerminal(x.P2);
                        if (from != to)
                            result.Add(new SectionOverlap(this, from, to));
                    }
                    else if (x.IsEndGraze)
                    {
                        // Mark all polygons incident on the end terminal
                        if (arePolygonsBuilt)
                            Topology.MarkPolygons(div.To);

                        // Add a topological section up to the start of the graze
                        to = map.GetTerminal(x.P1);
                        if (from != to)
                            result.Add(new SectionDivider(this, from, to));

                        // Add overlap all the way to the end of this divider
                        from = to;
                        to = div.To;
                        if (from != to)
                            result.Add(new SectionOverlap(this, from, to));

                        // That should be the LAST cut.
                        Debug.Assert((i + 1) == data.Count);
                    }
                    else
                    {
                        throw new Exception("LineFeature.Cut - Unexpected graze");
                    }
                }
                else if (!x.IsEnd)
                {
                    // If the intersection is not at either end of the
                    // divider, make a split (both portions topological).

                    to = map.GetTerminal(x.P1);
                    if (from != to)
                        result.Add(new SectionDivider(this, from, to));
                }
            }

            // Add the last section if we're not already at the end (we'll be at the end if
            // an overlap ran to the end)
            from = to;
            to = div.To;
            if (from != to)
            {
                // Just return if the terminals correspond to the two ends of this line. This
                // is intended to cover the case where we have a single interesection at the
                // start or end of the line.
                if (from.IsCoincident(StartPoint) && to.IsCoincident(EndPoint))
                {
                    Debug.Assert(result.Count==0);
                    return;
                }

                result.Add(new SectionDivider(this, from, to));
            }

            // Refer the associated line to the new sections
            if (result.Count > 0)
            {
                if (m_Topology is LineTopology)
                    m_Topology = new SectionTopologyList(this, result);
                else
                {
                    SectionTopologyList container = (SectionTopologyList)m_Topology;
                    container.ReplaceDivider(div, result);
                }
            }
        }
        /// <summary>
        /// One-time definition of the topological divider that this face corresponds to.
        /// </summary>
        /// <param name="pol">The polygon this face is part of</param>
        /// <param name="line">The topological line that acts as the primary face for
        /// some portion of the polygon boundary</param>
        /// <returns>The number of points for this face (one for the start of the face,
        /// plus any intermediate points along the face).</returns>
        internal uint SetDivider(Polygon pol, IDivider line)
        {
            // Expect that this method should only ever get called once in the
            // lifetime of an instance
            Debug.Assert(m_ExtraPoints==null);

            // Define any extra points
            m_Polygon = pol;
            m_Divider = line;
            int nExtra = SetExtraPoints();
            return (uint)(1+nExtra);
        }
Exemple #45
0
        IDivider _classicDivider;         // divider to use if Newton approach is unapplicatible

        #endregion Private fields

        #region Constructor

        /// <summary>
        /// Creates new <see cref="AutoNewtonDivider" /> instance.
        /// </summary>
        /// <param name="classicDivider">Divider to use if Newton approach is unapplicatible.</param>
        public AutoNewtonDivider(IDivider classicDivider)
        {
            _classicDivider = classicDivider;
        }
        IDivider _classicDivider; // divider to use if Newton approach is unapplicatible

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Creates new <see cref="AutoNewtonDivider" /> instance.
        /// </summary>
        /// <param name="classicDivider">Divider to use if Newton approach is unapplicatible.</param>
        public AutoNewtonDivider(IDivider classicDivider)
        {
            _classicDivider = classicDivider;
        }
Exemple #47
0
        /// <summary>
        /// Tries to return the name of a derived entity type for a specific line.
        /// </summary>
        /// <param name="line">The line to process.</param>
        /// <param name="layer">The layer of interest (in the same address space as
        /// the map that contains the line).</param>
        /// <returns>The name of the derived entity type (null if not found).</returns>
        internal string GetDerivedType(IDivider line, ILayer layer)
        {
            // Return if the line does not have an entity type (it SHOULD do)
            IEntity ent = line.Line.EntityType;
            if (ent==null)
                return null;

            // Get the translation block (if any) that refers to the line's entity type.
            string entName = ent.Name;
            string lyrName = layer.Name;
            EntityBlock block = Array.Find<EntityBlock>(m_Blocks, eb => eb.IsMatch(entName, lyrName));

            // Return if the line's entity type is not associated with a translation.
            if (block==null)
                return null;

            // Get the polygons on either side of the line (the REAL
            // user-perceived polygons, not phantoms).
            Polygon leftPol = (line.Left==null ? null : line.Left.RealPolygon);
            Polygon rightPol = (line.Right==null ? null : line.Right.RealPolygon);

            // Get the entity types for the adjacent polygons (if any).
            IEntity leftEnt = (leftPol==null ? null : leftPol.EntityType);
            IEntity rightEnt = (rightPol==null ? null : rightPol.EntityType);

            if (leftEnt!=null || rightEnt!=null)
            {
                string e1 = (leftEnt==null ? String.Empty : leftEnt.Name);
                string e2 = (rightEnt==null ? String.Empty : rightEnt.Name);

                return block.GetDerivedType(e1, e2);
            }

            return null;
        }
 /// <summary>
 /// Gets the side code for a horizontal segment which is incident on a node,
 /// given any one the boundaries incident on the node.
 /// </summary>
 /// <param name="id">The divider we know about (incident on node).</param>
 /// <param name="isStart">True if it's the start of <c>ib</c>.</param>
 /// <param name="od">The divider the returned side refers to</param>
 /// <returns>Side.Left if the segment is to the left of <c>ob</c>, Side.Right
 /// if segment to the right.</returns>
 internal Side GetSide(IDivider id, bool isStart, out IDivider od)
 {
     ConnectionFinder connect = new ConnectionFinder(id, isStart, this);
     od = connect.Next;
     return (connect.IsStart ? Side.Right : Side.Left);
 }
        /// <summary>
        /// Draws a portion of this topological line on the specified display
        /// </summary>
        /// <param name="d">The divider that corresponds to a portion of this line (could
        /// be the entire line)</param>
        /// <param name="display">The display to draw to</param>
        /// <param name="style">The drawing style</param>
        internal void RenderDivider(IDivider d, ISpatialDisplay display, IDrawStyle style)
        {
            // If we're highlightling, don't attempt to pick up any other display color
            if (style is HighlightStyle || style.IsFixed)
            {
                d.LineGeometry.Render(display, style);
                return;
            }

            Style s = EntityUtil.GetStyle(d, EditingController.Current.ActiveLayer);
            Pen oldPen = style.Pen;

            try
            {
                ScaleSpecificPen ssPen = s.GetPen(display);
                style.Pen = ssPen.Pen;
                d.LineGeometry.Render(display, style);
            }

            finally
            {
                style.Pen = oldPen;
            }
        }