/// <summary>
        /// Calculates the positions of the split point.
        /// </summary>
        /// <param name="line">The line being subdivided.</param>
        /// <param name="dist">The distance to the split point.</param>
        /// <param name="isFromEnd">Is the distance from the end of the line?</param>
        /// <returns>The calculated position (null if the distance is longer than the line being subdivided,
        /// or supplied information is incomplete)</returns>
        internal static IPosition Calculate(LineFeature line, Distance dist, bool isFromEnd)
        {
            // Can't calculate if there is insufficient data.
            if (line == null || dist == null)
            {
                return(null);
            }

            // The length must be defined.
            if (!dist.IsDefined)
            {
                return(null);
            }

            // Return if the observed distance is longer than the total
            // length of the line.
            double maxlen  = line.Length.Meters;
            double obsvlen = dist.Meters;

            if (obsvlen > maxlen)
            {
                return(null);
            }

            // Get the approximate position of the split point.
            IPosition    start, approx;
            LineGeometry g = line.LineGeometry;

            if (isFromEnd)
            {
                start = line.EndPoint;
                g.GetPosition(new Length(maxlen - obsvlen), out approx);
            }
            else
            {
                start = line.StartPoint;
                g.GetPosition(new Length(obsvlen), out approx);
            }

            // Get the distance to the approximate position on the mapping plane.
            ISpatialSystem sys     = CadastralMapModel.Current.SpatialSystem;
            double         planlen = dist.GetPlanarMetric(start, approx, sys);

            // Figure out the true position on the line.
            IPosition splitpos;

            if (isFromEnd)
            {
                g.GetPosition(new Length(maxlen - planlen), out splitpos);
            }
            else
            {
                g.GetPosition(new Length(planlen), out splitpos);
            }

            return(splitpos);
        }
        /// <summary>
        /// Performs the data processing associated with this face.
        /// </summary>
        /// <param name="parentLine">The line that is being subdivided</param>
        /// <param name="ctx">The context in which the geometry is being calculated.</param>
        internal void CalculateGeometry(LineFeature parentLine, EditingContext ctx)
        {
            // Get adjusted lengths for each section
            double[] adjray = GetAdjustedLengths(parentLine, m_Distances);

            double       edist    = 0.0; // Distance to end of section.
            PointFeature start    = parentLine.StartPoint;
            LineGeometry lineGeom = parentLine.LineGeometry;

            for (int i = 0; i < adjray.Length; i++)
            {
                // Calculate the position at the end of the span
                edist += adjray[i];
                IPosition to;
                if (!lineGeom.GetPosition(new Length(edist), out to))
                {
                    throw new Exception("Cannot adjust line section");
                }

                // Get the point feature at the end of the span
                LineFeature  line = m_Sections[i];
                PointFeature end  = line.EndPoint;

                // Assign the calculated position so long as we're not at
                // the end of the line
                if (end != parentLine.EndPoint)
                {
                    end.ApplyPointGeometry(ctx, PointGeometry.Create(to));
                }

                // The end of the current span is the start of the next one
                start = end;
            }
        }