private static ReferenceLineIntersectionResult GetReferenceLineIntersectionsResult(IEnumerable <Segment2D> surfaceLineSegments,
                                                                                           IEnumerable <Segment2D> referenceLineSegments)
        {
            Point2D intersectionPoint = null;

            foreach (Segment2D surfaceLineSegment in surfaceLineSegments)
            {
                foreach (Segment2D referenceLineSegment in referenceLineSegments)
                {
                    Segment2DIntersectSegment2DResult result = Math2D.GetIntersectionBetweenSegments(surfaceLineSegment, referenceLineSegment);

                    if (result.IntersectionType == Intersection2DType.Intersects)
                    {
                        Point2D resultIntersectionPoint = result.IntersectionPoints[0];
                        if (intersectionPoint != null && !intersectionPoint.Equals(resultIntersectionPoint))
                        {
                            // Early exit as multiple intersections is a return result:
                            return(ReferenceLineIntersectionResult.CreateMultipleIntersectionsOrOverlapResult());
                        }

                        intersectionPoint = resultIntersectionPoint;
                    }

                    if (result.IntersectionType == Intersection2DType.Overlaps)
                    {
                        // Early exit as overlap is a return result:
                        return(ReferenceLineIntersectionResult.CreateMultipleIntersectionsOrOverlapResult());
                    }
                }
            }

            return(intersectionPoint != null
                       ? ReferenceLineIntersectionResult.CreateIntersectionResult(intersectionPoint)
                       : ReferenceLineIntersectionResult.CreateNoSingleIntersectionResult());
        }
        /// <summary>
        /// Finds out if there is an intersection of the <paramref name="surfaceLine"/> and
        /// the <paramref name="referenceLine"/>.
        /// </summary>
        /// <param name="surfaceLine">The surface line.</param>
        /// <param name="referenceLine">The reference line.</param>
        /// <returns>A new <see cref="ReferenceLineIntersectionResult"/> with a type of intersection and
        /// possibly an intersection point, if there was only one found.</returns>
        /// <exception cref="ArgumentNullException">Thrown when any parameter is <c>null</c>.</exception>
        /// <exception cref="ImportedDataTransformException">Thrown when the surface line:
        /// <list type="bullet">
        /// <item>has no intersections with the reference line;</item>
        /// <item>has more than one intersection with the reference line.</item>
        /// </list>
        /// </exception>
        public static Point2D GetSingleReferenceLineIntersection(this SurfaceLine surfaceLine, ReferenceLine referenceLine)
        {
            if (surfaceLine == null)
            {
                throw new ArgumentNullException(nameof(surfaceLine));
            }

            if (referenceLine == null)
            {
                throw new ArgumentNullException(nameof(referenceLine));
            }

            ReferenceLineIntersectionResult result = GetReferenceLineIntersections(referenceLine, surfaceLine);

            if (result.TypeOfIntersection == ReferenceLineIntersectionsResult.NoIntersections)
            {
                string message = string.Format(Resources.SurfaceLineExtensions_GetSingleReferenceLineIntersection_SurfaceLine_0_does_not_correspond_to_current_referenceline_Could_be_caused_coordinates_being_local_coordinate_system,
                                               surfaceLine.Name);
                throw new ImportedDataTransformException(message);
            }

            if (result.TypeOfIntersection == ReferenceLineIntersectionsResult.MultipleIntersectionsOrOverlap)
            {
                string message = string.Format(Resources.SurfaceLineExtensions_GetSingleReferenceLineIntersection_SurfaceLine_0_does_not_correspond_to_current_referenceline, surfaceLine.Name);
                throw new ImportedDataTransformException(message);
            }

            return(result.IntersectionPoint);
        }