Ejemplo n.º 1
0
        /// <summary>
        /// Given the position of the start of this leg, along with an initial bearing,
        /// project the end of the leg, along with an exit bearing.
        /// </summary>
        /// <param name="pos">The position at the start of the leg.</param>
        /// <param name="bearing">The initial bearing (e.g. if the previous leg was also
        /// a straight leg from A to B, the bearing is from A through B).</param>
        /// <param name="sfac">Scaling factor to apply. Default=1.0</param>
        internal override void Project(ref IPosition pos, ref double bearing, double sfac)
        {
            // Add on any initial angle
            bearing = AddStartAngle(bearing);

            // Get the total length of the leg.
            double length = PrimaryFace.GetTotal() * sfac;

            // Figure out shifts.
            double dE = length * Math.Sin(bearing);
            double dN = length * Math.Cos(bearing);

            // Define the end position.
            pos = new Position(pos.X + dE, pos.Y + dN);
        }
Ejemplo n.º 2
0
        /*
         * //	@mfunc	Create transient CeMiscText objects for any observed
         * //			angles that are part of this leg.
         * //
         * //			The caller is responsible for deleting the text
         * //			objects once done with them.
         * //
         * //	@parm	The point the observation must be made from.
         * //			Specify 0 for all points.
         * //	@parm	The operation this leg belongs to.
         * //	@parm	Scale factor to apply to the leg.
         * //	@parm	The position of a backsight prior to the BC (may
         * //			be undefined).
         * //	@parm	The position of the start of the leg.
         * //	@parm	The bearing to the start of the leg. Updated to
         * //			refer to the bearing to the end of the leg.
         * //	@parm	The position of the end of the leg.
         * //	@parm	List of pointers to created text objects (appended to).
         * //	@parm	Should lines be produced too?
         * //
         * //	@rdesc	TRUE if the specified from point was encountered (this
         * //			does not necessarily mean that any text needed to be
         * //			generated for it).
         *
         * LOGICAL CeStraightLeg::CreateAngleText ( const CePoint* const pFrom
         *                                                                 , const CeOperation& op
         *                                                                 , const FLOAT8 sfac
         *                                                                 , const CeVertex& bs
         *                                                                 , const CeVertex& from
         *                                                                 , FLOAT8& bearing
         *                                                                 , CeVertex& to
         *                                                                 , CPtrList& text
         *                                                                 , const LOGICAL wantLinesToo ) const {
         *
         * // Project to the end of the leg.
         * to = from;
         * this->Project(to,bearing,sfac);
         *
         * // If a from point has been specified, and this leg does
         * // not start at it, just return.
         * if ( pFrom && GetpStartPoint(op)!=pFrom ) return FALSE;
         *
         * // Return if this leg does not have an initial angle.
         * const FLOAT8 angle = fabs(m_StartAngle);
         * if ( angle<TINY ) return TRUE;
         *
         * // Return if the angle is real-close to a right angle
         * if ( fabs(angle-PIDIV2  )<0.000001 ||
         *       fabs(angle-PIMUL1P5)<0.000001 ) return TRUE;
         *
         * // Create the text.
         * MakeText(bs,from,to,m_StartAngle,text);
         *
         * return TRUE;
         *
         * } // end of CreateAngleText
         */

        /// <summary>
        /// Breaks this leg into two legs. The break must leave at least
        /// one distance in each of the resultant legs.
        /// </summary>
        /// <param name="index">The index of the span that should be at the
        /// start of the extra leg.</param>
        /// <returns>The extra leg (at the end of the original leg).</returns>
        internal StraightLeg Break(int index)
        {
            if (this.AlternateFace != null)
            {
                throw new InvalidOperationException("Cannot break a staggered leg");
            }

            // Can't break right at the start or end.
            int nTotal = PrimaryFace.Count;

            if (index <= 0 || index >= nTotal)
            {
                return(null);
            }

            // Create a new straight leg with the right number of spans.
            StraightLeg newLeg = new StraightLeg(PrimaryFace, index);

            // Retain the spans prior to that
            PrimaryFace.TruncateLeg(index);

            return(newLeg);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Obtains the geometry for spans along this leg.
        /// </summary>
        /// <param name="bc">The position for the start of the leg.
        /// <param name="bcBearing">The bearing on entry into the leg.</param>
        /// <param name="sfac">Scale factor to apply to distances.</param>
        /// <param name="spans">Information for the spans coinciding with this leg.</param>
        /// <returns>The sections along this leg</returns>
        internal override ILineGeometry[] GetSpanSections(IPosition bc, double bcBearing, double sfac, SpanInfo[] spans)
        {
            // Can't do anything if the leg radius isn't defined
            if (m_Metrics.ObservedRadius == null)
            {
                throw new InvalidOperationException("Cannot create sections for circular leg with undefined radius");
            }

            var result = new ILineGeometry[spans.Length];

            // Use supplied stuff to derive info on the center and EC.
            IPosition center;
            IPosition ec;
            double    bearingToBC;
            double    ecBearing;

            GetPositions(bc, bcBearing, sfac, out center, out bearingToBC, out ec, out ecBearing);

            // Define the underlying circle
            ICircleGeometry circle = new CircleGeometry(PointGeometry.Create(center), BasicGeom.Distance(center, bc));

            // Handle case where the leg is a cul-de-sac with no observed spans
            if (spans.Length == 1 && spans[0].ObservedDistance == null)
            {
                result[0] = new CircularArcGeometry(circle, bc, ec, m_Metrics.IsClockwise);
                return(result);
            }

            /// Initialize scaling factor for distances in cul-de-sacs (ratio of the length calculated from
            /// the CA & Radius, versus the observed distances that were actually specified). For curves that
            /// are not cul-de-sacs, this will be 1.0
            double culFactor = 1.0;

            if (m_Metrics.IsCulDeSac)
            {
                double obsv = PrimaryFace.GetTotal();
                if (obsv > MathConstants.TINY)
                {
                    culFactor = Length.Meters / obsv;
                }
            }

            IPosition sPos        = bc;
            IPosition ePos        = null;
            bool      isClockwise = m_Metrics.IsClockwise;
            double    radius      = RadiusInMeters;
            double    edist       = 0.0;

            for (int i = 0; i < result.Length; i++, sPos = ePos)
            {
                // Add on the unscaled distance
                edist += spans[i].ObservedDistance.Meters;

                // Get the angle subtended at the center of the circle. We use
                // unscaled values here, since the scale factors would cancel out.
                // However, we DO apply any cul-de-sac scaling factor, to account
                // for the fact that the distance may be inconsistent with the
                // curve length derived from the CA and radius. For example, it
                // is possible that the calculated curve length=200, although the
                // total of the observed spans is somehow only 100. In that case,
                // if the supplied distance is 50, we actually want to use a
                // value of 50 * (200/100) = 100.

                double angle = (edist * culFactor) / radius;

                // Get the bearing of the point with respect to the center of the circle.

                double bearing;

                if (isClockwise)
                {
                    bearing = bearingToBC + angle;
                }
                else
                {
                    bearing = bearingToBC - angle;
                }

                // Calculate the position using the scaled radius.
                ePos = Geom.Polar(center, bearing, radius * sfac);

                result[i] = new CircularArcGeometry(circle, sPos, ePos, isClockwise);
            }

            return(result);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Given the position of the start of this leg, along with an initial bearing, get
        /// other positions (and bearings) relating to the circle.
        /// </summary>
        /// <param name="bc">The position for the BC.</param>
        /// <param name="sbearing">The position for the BC.</param>
        /// <param name="sfac">Scale factor to apply to distances.</param>
        /// <param name="center">Position of the circle centre.</param>
        /// <param name="bear2bc">Bearing from the centre to the BC.</param>
        /// <param name="ec">Position of the EC.</param>
        /// <param name="ebearing">Exit bearing.</param>
        internal void GetPositions(IPosition bc, double sbearing, double sfac,
                                   out IPosition center, out double bear2bc, out IPosition ec, out double ebearing)
        {
            // Have we got a cul-de-sac?
            bool cul = m_Metrics.IsCulDeSac;

            // Remember reverse bearing if we have a cul-de-sac.
            double revbearing = sbearing + Math.PI;

            //	Initialize current bearing.
            double bearing = sbearing;

            // Counter-clockwise?
            bool ccw = (m_Metrics.IsClockwise == false);

            // Get radius in meters on the ground (and scale it).
            double radius = RadiusInMeters * sfac;

            // Get to the center (should really get to the P.I., but not sure
            // where that is when the curve is > half a circle -- need to
            // check some book).

            if (cul)
            {
                double halfAngle = m_Metrics.CentralAngle * 0.5;

                if (ccw)
                {
                    bearing -= halfAngle;
                }
                else
                {
                    bearing += halfAngle;
                }
            }
            else
            {
                double entryAngle = m_Metrics.EntryAngle;

                if (ccw)
                {
                    bearing -= (Math.PI - entryAngle);
                }
                else
                {
                    bearing += (Math.PI - entryAngle);
                }
            }

            double dE = radius * Math.Sin(bearing);
            double dN = radius * Math.Cos(bearing);

            double x = bc.X + dE;
            double y = bc.Y + dN;

            center = new Position(x, y);

            // Return the bearing from the center to the BC (the reverse
            // of the bearing we just used).
            bear2bc = bearing + Math.PI;

            // Now go out to the EC. For regular curves, figure out the
            // central angle by comparing the observed length of the curve
            // to the total circumference.
            if (cul)
            {
                double ca = m_Metrics.CentralAngle;

                if (ccw)
                {
                    bearing -= (Math.PI - ca);
                }
                else
                {
                    bearing += (Math.PI - ca);
                }
            }
            else
            {
                double length  = PrimaryFace.GetTotal() * sfac;
                double circumf = radius * MathConstants.PIMUL2;
                double ca      = MathConstants.PIMUL2 * (length / circumf);

                if (ccw)
                {
                    bearing += (Math.PI - ca);
                }
                else
                {
                    bearing -= (Math.PI - ca);
                }
            }

            // Define the position of the EC.
            x += (radius * Math.Sin(bearing));
            y += (radius * Math.Cos(bearing));
            ec = new Position(x, y);

            // Define the exit bearing. For cul-de-sacs, the exit bearing
            // is the reverse of the original bearing (lines are parallel).

            if (cul)
            {
                ebearing = revbearing;
            }
            else
            {
                // If we have a second angle, use that
                double angle = m_Metrics.ExitAngle;

                if (ccw)
                {
                    ebearing = bearing - (Math.PI - angle);
                }
                else
                {
                    ebearing = bearing + (Math.PI - angle);
                }
            }
        }