public void TestAngle() { var offset = 0.001f; var center = new Coordinate(51.16917253319145f, 4.476456642150879f); var north = new Coordinate(center.Latitude + offset, center.Longitude); var northEast = new Coordinate(center.Latitude + offset, center.Longitude + offset); var east = new Coordinate(center.Latitude, center.Longitude + offset); var southEast = new Coordinate(center.Latitude - offset, center.Longitude + offset); var south = new Coordinate(center.Latitude - offset, center.Longitude); var southWest = new Coordinate(center.Latitude - offset, center.Longitude - offset); var west = new Coordinate(center.Latitude, center.Longitude - offset); var northWest = new Coordinate(center.Latitude + offset, center.Longitude - offset); var E = 1f; Assert.AreEqual(45, DirectionCalculator.Angle(south, center, southEast).ToDegrees(), E); Assert.AreEqual(90, DirectionCalculator.Angle(south, center, east).ToDegrees(), E); Assert.AreEqual(135, DirectionCalculator.Angle(south, center, northEast).ToDegrees(), E); Assert.AreEqual(180, DirectionCalculator.Angle(south, center, north).ToDegrees(), E); Assert.AreEqual(225, DirectionCalculator.Angle(south, center, northWest).ToDegrees(), E); Assert.AreEqual(270, DirectionCalculator.Angle(south, center, west).ToDegrees(), E); Assert.AreEqual(315, DirectionCalculator.Angle(south, center, southWest).ToDegrees(), E); Assert.AreEqual(180, DirectionCalculator.Angle( new Coordinate(50.84993f, 4.320437f), new Coordinate(50.85011f, 4.320471f), new Coordinate(50.85029f, 4.320505f)).ToDegrees(), E); }
/// <summary> /// Encodes a bearing based on the list of coordinates and the BEARDIST parameter. /// </summary> public static float EncodeBearing(List <OpenLR.Model.Coordinate> coordinates) { var distance = 0.0; var previous = coordinates[0]; OpenLR.Model.Coordinate bearingPosition = null; for (int idx = 1; idx < coordinates.Count; idx++) { var current = new OpenLR.Model.Coordinate() { Latitude = coordinates[idx].Latitude, Longitude = coordinates[idx].Longitude }; var currentSegmentDistance = Coordinate.DistanceEstimateInMeter((float)current.Latitude, (float)current.Longitude, (float)previous.Latitude, (float)previous.Longitude); var currentDistance = currentSegmentDistance + distance; if (currentDistance > Parameters.BEARDIST) { // the coordinate to calculate the beardist is in this segment! // calculate where. var relativeDistance = Parameters.BEARDIST - distance; var relativeOffset = relativeDistance / currentSegmentDistance; bearingPosition = new OpenLR.Model.Coordinate() { Latitude = (float)(previous.Latitude + ((current.Latitude - previous.Latitude) * relativeOffset)), Longitude = (float)(previous.Longitude + ((current.Longitude - previous.Longitude) * relativeOffset)) }; break; } distance = currentDistance; previous = current; } if (bearingPosition == null) { // use the toCoordinate as the last 'current'. // if edge is too short use target coordinate. bearingPosition = coordinates[coordinates.Count - 1]; } var north = new Coordinate((float)coordinates[0].Latitude + 1, (float)coordinates[0].Longitude); var angleRadians = DirectionCalculator.Angle(new Coordinate((float)bearingPosition.Latitude, (float)bearingPosition.Longitude), new Coordinate((float)coordinates[0].Latitude, (float)coordinates[0].Longitude), north); var angleDegrees = (float)(angleRadians * (180 / Math.PI)); return(angleDegrees); }
/// <summary> /// Encodes a bearing based on the list of coordinates and the BEARDIST parameter. /// </summary> public static float EncodeBearing(List <Coordinate> coordinates) { var distance = 0.0; var previous = coordinates[0]; Coordinate?bearingPosition = null; for (int idx = 1; idx < coordinates.Count; idx++) { var current = new Coordinate(coordinates[idx].Latitude, coordinates[idx].Longitude); var currentSegmentDistance = Coordinate.DistanceEstimateInMeter(current, previous); var currentDistance = currentSegmentDistance + distance; if (currentDistance > Parameters.BEARDIST) { // the coordinate to calculate the beardist is in this segment! // calculate where. var relativeDistance = Parameters.BEARDIST - distance; var relativeOffset = relativeDistance / currentSegmentDistance; bearingPosition = new Coordinate() { Latitude = (float)(previous.Latitude + ((current.Latitude - previous.Latitude) * relativeOffset)), Longitude = (float)(previous.Longitude + ((current.Longitude - previous.Longitude) * relativeOffset)) }; break; } distance = currentDistance; previous = current; } if (bearingPosition == null) { // use the toCoordinate as the last 'current'. // if edge is too short use target coordinate. bearingPosition = coordinates[coordinates.Count - 1]; } var north = new Coordinate(coordinates[0].Latitude + 1, coordinates[0].Longitude); var angleRadians = DirectionCalculator.Angle(bearingPosition.Value, coordinates[0], north); var angleDegrees = (float)(angleRadians * (180 / Math.PI)); if (System.Math.Round(angleDegrees) == 360) { // make sure any 360 degree angle is converted to 0, range allowed is [0, 360[ angleDegrees = 0; } return(angleDegrees); }
/// <summary> /// Calculates the angle in degress at the given routerpoint over a given distance. /// </summary> /// <param name="point">The router point.</param> /// <param name="network">The routing network.</param> /// <param name="distance">The distance to average over.</param> /// <returns>The angle relative to the meridians.</returns> public static float?Angle(this RouterPoint point, RoutingNetwork network, float distance = 100) { var edge = network.GetEdge(point.EdgeId); var edgeLength = edge.Data.Distance; var distanceOffset = (distance / edgeLength) * ushort.MaxValue; ushort offset1 = 0; ushort offset2 = ushort.MaxValue; if (distanceOffset <= ushort.MaxValue) { // not the entire edge. offset1 = (ushort)System.Math.Max(0, point.Offset - distanceOffset); offset2 = (ushort)System.Math.Min(ushort.MaxValue, point.Offset + distanceOffset); if (offset2 - offset1 == 0) { if (offset1 > 0) { offset1--; } if (offset2 < ushort.MaxValue) { offset2++; } } } // calculate the locations. var location1 = network.LocationOnNetwork(point.EdgeId, offset1); var location2 = network.LocationOnNetwork(point.EdgeId, offset2); if (Coordinate.DistanceEstimateInMeter(location1, location2) < .1) { // distance too small, edge to short. return(null); } // calculate and return angle. var toNorth = new Coordinate(location1.Latitude + 0.001f, location1.Longitude); var angleRadians = DirectionCalculator.Angle(location2, location1, toNorth); return((float)angleRadians.ToDegrees().NormalizeDegrees()); }