public IVerifiedChange Verify(VerificationContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var problems = Problems.None; if (!context.View.Segments.TryGetValue(UpperSegmentId, out var upperSegment)) { problems = problems.UpperRoadSegmentMissing(); } if (!context.View.Segments.TryGetValue(LowerSegmentId, out var lowerSegment)) { problems = problems.LowerRoadSegmentMissing(); } if (upperSegment != null && lowerSegment != null) { if (!upperSegment.Geometry.Intersects(lowerSegment.Geometry)) { problems = problems.UpperAndLowerRoadSegmentDoNotIntersect(); } } if (problems.OfType <Error>().Any()) { return(new RejectedChange(this, problems)); } return(new AcceptedChange(this, problems)); }
public VerifiedChanges VerifyWith(RoadNetworkView view) { var context = new VerificationContext(view, this); return(_changes.Aggregate( VerifiedChanges.Empty, (verifiedChanges, requestedChange) => verifiedChanges.Append(requestedChange.Verify(context)))); }
public IVerifiedChange Verify(VerificationContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var problems = Problems.None; if (!context.View.Segments.ContainsKey(SegmentId)) { problems = problems.RoadSegmentMissing(TemporarySegmentId ?? SegmentId); } if (problems.OfType <Error>().Any()) { return(new RejectedChange(this, problems)); } return(new AcceptedChange(this, problems)); }
public IVerifiedChange Verify(VerificationContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var problems = Problems.None; if (Math.Abs(Geometry.Length) <= context.Tolerance) { problems = problems.RoadSegmentGeometryLengthIsZero(); } var byOtherSegment = context.View.Segments.Values.FirstOrDefault(segment => segment.Id != Id && segment.Geometry.EqualsExact(Geometry)); if (byOtherSegment != null) { problems = problems.RoadSegmentGeometryTaken( context.Translator.TranslateToTemporaryOrId(byOtherSegment.Id) ); } var line = Geometry.Geometries .OfType <LineString>() .Single(); if (!context.View.Nodes.TryGetValue(StartNodeId, out var startNode)) { problems = problems.RoadSegmentStartNodeMissing(); } else { if (line.StartPoint != null && !line.StartPoint.EqualsExact(startNode.Geometry)) { problems = problems.RoadSegmentStartPointDoesNotMatchNodeGeometry(); } } if (!context.View.Nodes.TryGetValue(EndNodeId, out var endNode)) { problems = problems.RoadSegmentEndNodeMissing(); } else { if (line.EndPoint != null && !line.EndPoint.EqualsExact(endNode.Geometry)) { problems = problems.RoadSegmentEndPointDoesNotMatchNodeGeometry(); } } if (line.SelfOverlaps()) { problems = problems.RoadSegmentGeometrySelfOverlaps(); } else if (line.SelfIntersects()) { problems = problems.RoadSegmentGeometrySelfIntersects(); } if (line.NumPoints > 0) { var previousPointMeasure = 0.0; for (var index = 0; index < line.CoordinateSequence.Count; index++) { var measure = line.CoordinateSequence.GetOrdinate(index, Ordinate.M); var x = line.CoordinateSequence.GetX(index); var y = line.CoordinateSequence.GetY(index); if (index == 0 && Math.Abs(measure) > context.Tolerance) { problems = problems.RoadSegmentStartPointMeasureValueNotEqualToZero(x, y, measure); } else if (index == line.CoordinateSequence.Count - 1 && Math.Abs(measure - line.Length) > context.Tolerance) { problems = problems.RoadSegmentEndPointMeasureValueNotEqualToLength(x, y, measure, line.Length); } else if (measure < 0.0 || measure > line.Length) { problems = problems.RoadSegmentPointMeasureValueOutOfRange(x, y, measure, 0.0, line.Length); } else { if (index != 0 && Math.Sign(measure - previousPointMeasure) <= 0) { problems = problems.RoadSegmentPointMeasureValueDoesNotIncrease(x, y, measure, previousPointMeasure); } else { previousPointMeasure = measure; } } } } RoadSegmentLaneAttribute previousLane = null; foreach (var lane in Lanes) { if (previousLane == null) { if (lane.From != RoadSegmentPosition.Zero) { problems = problems.RoadSegmentLaneAttributeFromPositionNotEqualToZero( lane.TemporaryId, lane.From); } } else { if (lane.From != previousLane.To) { problems = problems.RoadSegmentLaneAttributesNotAdjacent( previousLane.TemporaryId, previousLane.To, lane.TemporaryId, lane.From); } } previousLane = lane; } if (previousLane != null) { if (Math.Abs(previousLane.To.ToDouble() - line.Length) > context.Tolerance) { problems = problems.RoadSegmentLaneAttributeToPositionNotEqualToLength( previousLane.TemporaryId, previousLane.To, line.Length); } } RoadSegmentWidthAttribute previousWidth = null; foreach (var width in Widths) { if (previousWidth == null) { if (width.From != RoadSegmentPosition.Zero) { problems = problems.RoadSegmentWidthAttributeFromPositionNotEqualToZero( width.TemporaryId, width.From); } } else { if (width.From != previousWidth.To) { problems = problems.RoadSegmentWidthAttributesNotAdjacent( previousWidth.TemporaryId, previousWidth.To, width.TemporaryId, width.From); } } previousWidth = width; } if (previousWidth != null) { if (Math.Abs(previousWidth.To.ToDouble() - line.Length) > context.Tolerance) { problems = problems.RoadSegmentWidthAttributeToPositionNotEqualToLength( previousWidth.TemporaryId, previousWidth.To, line.Length); } } RoadSegmentSurfaceAttribute previousSurface = null; foreach (var surface in Surfaces) { if (previousSurface == null) { if (surface.From != RoadSegmentPosition.Zero) { problems = problems.RoadSegmentSurfaceAttributeFromPositionNotEqualToZero( surface.TemporaryId, surface.From); } } else { if (surface.From != previousSurface.To) { problems = problems.RoadSegmentSurfaceAttributesNotAdjacent( previousSurface.TemporaryId, previousSurface.To, surface.TemporaryId, surface.From); } } previousSurface = surface; } if (previousSurface != null) { if (Math.Abs(previousSurface.To.ToDouble() - line.Length) > context.Tolerance) { problems = problems.RoadSegmentSurfaceAttributeToPositionNotEqualToLength(previousSurface.TemporaryId, previousSurface.To, line.Length); } } if (problems.OfType <Error>().Any()) { return(new RejectedChange(this, problems)); } return(new AcceptedChange(this, problems)); }
public IVerifiedChange Verify(VerificationContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var problems = Problems.None; var byOtherNode = context.View.Nodes.Values.FirstOrDefault(n => n.Id != Id && n.Geometry.EqualsExact(Geometry)); if (byOtherNode != null) { problems = problems.RoadNodeGeometryTaken( context.Translator.TranslateToTemporaryOrId(byOtherNode.Id) ); } var node = context.View.Nodes[Id]; problems = context.View.Segments.Values .Where(s => !node.Segments.Contains(s.Id) && s.Geometry.IsWithinDistance(Geometry, VerificationContext.TooCloseDistance) ) .Aggregate( problems, (current, segment) => current.RoadNodeTooClose(context.Translator.TranslateToTemporaryOrId(segment.Id))); var connectedSegmentCount = node.Segments.Count; if (connectedSegmentCount == 0) { problems = problems.RoadNodeNotConnectedToAnySegment(); } else if (connectedSegmentCount == 1 && Type != RoadNodeType.EndNode) { problems = problems.RoadNodeTypeMismatch(connectedSegmentCount, Type, new [] { RoadNodeType.EndNode }); } else if (connectedSegmentCount == 2) { if (!Type.IsAnyOf(RoadNodeType.FakeNode, RoadNodeType.TurningLoopNode)) { problems = problems.RoadNodeTypeMismatch(connectedSegmentCount, Type, new [] { RoadNodeType.FakeNode, RoadNodeType.TurningLoopNode }); } else if (Type == RoadNodeType.FakeNode) { var segments = node.Segments.Select(segmentId => context.View.Segments[segmentId]) .ToArray(); var segment1 = segments[0]; var segment2 = segments[1]; if (segment1.AttributeHash.Equals(segment2.AttributeHash)) { problems = problems.FakeRoadNodeConnectedSegmentsDoNotDiffer( context.Translator.TranslateToTemporaryOrId(segment1.Id), context.Translator.TranslateToTemporaryOrId(segment2.Id) ); } } } else if (connectedSegmentCount > 2 && !Type.IsAnyOf(RoadNodeType.RealNode, RoadNodeType.MiniRoundabout)) { problems = problems.RoadNodeTypeMismatch(connectedSegmentCount, Type, new [] { RoadNodeType.RealNode, RoadNodeType.MiniRoundabout }); } if (problems.OfType <Error>().Any()) { return(new RejectedChange(this, problems)); } return(new AcceptedChange(this, problems)); }