public void TestRectangleF2DFitAndKeepAspectRatio() { double delta = 0.00001; RectangleF2D rectangle = new RectangleF2D(0, 0, 1, 1); PointF2D[] points = new PointF2D[] { new PointF2D(2, 2), new PointF2D(1, 1) }; RectangleF2D fitted = rectangle.FitAndKeepAspectRatio(points, 0); Assert.AreEqual(1, fitted.Width, delta); Assert.AreEqual(1, fitted.Height, delta); Assert.AreEqual(1, fitted.BottomLeft[0], delta); Assert.AreEqual(1, fitted.BottomLeft[1], delta); Assert.AreEqual(2, fitted.TopRight[0], delta); Assert.AreEqual(2, fitted.TopRight[1], delta); // this should create the exact same rectangle as in the other tests. rectangle = RectangleF2D.FromBoundsAndCenter(System.Math.Sqrt(2) * 2, System.Math.Sqrt(2) * 2, 0, 0, 45); fitted = rectangle.FitAndKeepAspectRatio(points, 0); Assert.AreEqual(System.Math.Sqrt(2), fitted.Width, delta); Assert.AreEqual(System.Math.Sqrt(2), fitted.Height, delta); Assert.AreEqual(0.5, fitted.BottomLeft[0], delta); Assert.AreEqual(1.5, fitted.BottomLeft[1], delta); Assert.AreEqual(2.5, fitted.TopRight[0], delta); Assert.AreEqual(1.5, fitted.TopRight[1], delta); }
/// <summary> /// Project on route and return the next entry index and coordinate. /// </summary> /// <param name="route"></param> /// <param name="coordinates"></param> /// <returns></returns> private KeyValuePair <int, GeoCoordinate> ProjectOn(Route route, GeoCoordinate coordinates) { double distance = double.MaxValue; GeoCoordinate closest = null; int closestIdx = -1; List <GeoCoordinate> points = route.GetPoints(); for (int idx = 0; idx < points.Count - 1; idx++) { GeoCoordinateLine line = new GeoCoordinateLine(points[idx], points[idx + 1], true, true); PointF2D projectedPoint = line.ProjectOn(coordinates); GeoCoordinate projected; double currentDistance; if (projectedPoint != null) { projected = new GeoCoordinate(projectedPoint[1], projectedPoint[0]); currentDistance = coordinates.Distance(projected); if (currentDistance < distance) { closest = projected; closestIdx = idx + 1; distance = currentDistance; } } projected = points[idx]; currentDistance = coordinates.Distance(projected); if (currentDistance < distance) { closest = projected; closestIdx = idx; distance = currentDistance; } } return(new KeyValuePair <int, GeoCoordinate>(closestIdx, closest)); }
/// <summary> /// Test if routes between resolved nodes are correctly calculated. /// /// 20--x---x--21---------16 /// </summary> protected void DoTestResolveCase2() { // initialize data. var interpreter = new OsmRoutingInterpreter(); IBasicRouterDataSource <TEdgeData> data = this.BuildData(interpreter, "OsmSharp.Test.Unittests.test_network.osm"); var vertex20 = new GeoCoordinate(51.0578532, 3.7192229); var vertex21 = new GeoCoordinate(51.0578518, 3.7195654); // var vertex16 = new GeoCoordinate(51.0577299, 3.719745); PointF2D point = vertex20 + ((vertex21 - vertex20) * 0.25); var vertex20211 = new GeoCoordinate(point[1], point[0]); point = vertex20 + ((vertex21 - vertex20) * 0.75); var vertex20212 = new GeoCoordinate(point[1], point[0]); // calculate route. IBasicRouter <TEdgeData> basicRouter = this.BuildBasicRouter(data); Router router = this.BuildRouter(data, interpreter, basicRouter); Route route = router.Calculate(Vehicle.Car, router.Resolve(Vehicle.Car, vertex20211), router.Resolve(Vehicle.Car, vertex20212)); Assert.AreEqual(2, route.Entries.Length); Assert.AreEqual(vertex20211.Latitude, route.Entries[0].Latitude, 0.0001); Assert.AreEqual(vertex20211.Longitude, route.Entries[0].Longitude, 0.0001); //Assert.AreEqual(vertex_21.Latitude, route.Entries[1].Latitude, 0.0001); //Assert.AreEqual(vertex_21.Longitude, route.Entries[1].Longitude, 0.0001); Assert.AreEqual(vertex20212.Latitude, route.Entries[1].Latitude, 0.0001); Assert.AreEqual(vertex20212.Longitude, route.Entries[1].Longitude, 0.0001); }
/// <summary> /// Zoom to the given makers list. /// </summary> /// <param name="marker"></param> public void ZoomToMarkers(List <MapMarker> markers, double percentage) { // float height = _rect.Height; // float width = _rect.Width; float width = this.Frame.Width; float height = this.Frame.Height; RectangleF rect = this.Frame; if (width > 0) { PointF2D[] points = new PointF2D[markers.Count]; for (int idx = 0; idx < markers.Count; idx++) { points[idx] = new PointF2D(this.Map.Projection.ToPixel(markers[idx].Location)); } View2D view = this.CreateView(rect); // View2D view = this.CreateView(this.Frame); View2D fittedView = view.Fit(points, percentage); float zoom = (float)this.Map.Projection.ToZoomLevel(fittedView.CalculateZoom( width, height)); GeoCoordinate center = this.Map.Projection.ToGeoCoordinates( fittedView.Center[0], fittedView.Center[1]); _mapCenter = center; this.MapZoom = zoom; this.Change(false); } }
/// <summary> /// Draws the image. /// </summary> /// <returns>The image.</returns> /// <param name="target">Target.</param> /// <param name="bounds">Bounds.</param> /// <param name="imageData">Image data.</param> /// <param name="tag">Tag.</param> protected override object DrawImage(Target2DWrapper <CGContextWrapper> target, RectangleF2D bounds, byte[] imageData, object tag) { target.Target.CGContext.SetAllowsFontSubpixelQuantization(true); target.Target.CGContext.SetAllowsFontSmoothing(true); target.Target.CGContext.SetAllowsAntialiasing(true); target.Target.CGContext.SetAllowsSubpixelPositioning(true); target.Target.CGContext.SetShouldAntialias(true); PointF2D bottomLeft = new PointF2D(this.Tranform(bounds.BottomLeft [0], bounds.BottomLeft [1])); PointF2D bottomRight = new PointF2D(this.Tranform(bounds.BottomRight [0], bounds.BottomRight [1])); PointF2D topLeft = new PointF2D(this.Tranform(bounds.TopLeft [0], bounds.TopLeft [1])); //PointF2D topRight = new PointF2D(this.Tranform (bounds.TopRight [0], bounds.TopRight [1])); RectangleF2D transformed = new RectangleF2D(bottomLeft, bottomLeft.Distance(bottomRight), bottomLeft.Distance(topLeft), topLeft - bottomLeft); target.Target.CGContext.SaveState(); target.Target.CGContext.TranslateCTM((float)transformed.BottomLeft [0], (float)transformed.BottomLeft [1]); target.Target.CGContext.RotateCTM(-(float)((Radian)transformed.Angle).Value); if (tag is CGImage) { CGImage image = tag as CGImage; target.Target.CGContext.DrawImage(new RectangleF(0, 0, (float)transformed.Width, (float)transformed.Height), image); } target.Target.CGContext.RestoreState(); return(tag); }
public static PointF2D RotateAroundPoint(Radian angle, PointF2D center, PointF2D point) { double num1 = System.Math.Sin(angle.Value); double num2 = System.Math.Cos(angle.Value); return(new PointF2D(center[0] + (num2 * (point[0] - center[0]) + num1 * (point[1] - center[1])), center[1] + (-num1 * (point[0] - center[0]) + num2 * (point[1] - center[1])))); }
/// <summary> /// Test if routes between resolved nodes are correctly calculated. /// /// 20----x----21----x----16 /// </summary> protected void DoTestResolveCase1() { // initialize data. var interpreter = new OsmRoutingInterpreter(); IRoutingAlgorithmData <TEdgeData> data = this.BuildData(interpreter, "OsmSharp.Test.Unittests.test_network.osm"); var vertex20 = new GeoCoordinate(51.0578532, 3.7192229); var vertex21 = new GeoCoordinate(51.0578518, 3.7195654); var vertex16 = new GeoCoordinate(51.0577299, 3.719745); PointF2D point = vertex20 + ((vertex21 - vertex20) * 0.5); var vertex2021 = new GeoCoordinate(point[1], point[0]); point = vertex21 + ((vertex16 - vertex21) * 0.5); var vertex2116 = new GeoCoordinate(point[1], point[0]); // calculate route. IRoutingAlgorithm <TEdgeData> basicRouter = this.BuildBasicRouter(data); Router router = this.BuildRouter(data, interpreter, basicRouter); Route route = router.Calculate(Vehicle.Car, router.Resolve(Vehicle.Car, vertex2021), router.Resolve(Vehicle.Car, vertex2116)); Assert.AreEqual(3, route.Segments.Length); Assert.AreEqual(vertex2021.Latitude, route.Segments[0].Latitude, 0.0001); Assert.AreEqual(vertex2021.Longitude, route.Segments[0].Longitude, 0.0001); Assert.AreEqual(vertex21.Latitude, route.Segments[1].Latitude, 0.0001); Assert.AreEqual(vertex21.Longitude, route.Segments[1].Longitude, 0.0001); Assert.AreEqual(vertex2116.Latitude, route.Segments[2].Latitude, 0.0001); Assert.AreEqual(vertex2116.Longitude, route.Segments[2].Longitude, 0.0001); }
/// <summary> /// Zooms to the given list of markers. /// </summary> /// <param name="markers"></param> /// <param name="percentage"></param> public void ZoomToMarkers(List <MapMarker> markers, double percentage) { float height = this.SurfaceHeight; float width = this.SurfaceWidth; if (width > 0) { PointF2D[] points = new PointF2D[markers.Count]; for (int idx = 0; idx < markers.Count; idx++) { points [idx] = new PointF2D(this.Map.Projection.ToPixel(markers [idx].Location)); } View2D view = this.CreateView(); View2D fittedView = view.Fit(points, percentage); float zoom = (float)this.Map.Projection.ToZoomLevel(fittedView.CalculateZoom( width, height)); GeoCoordinate center = this.Map.Projection.ToGeoCoordinates( fittedView.Center [0], fittedView.Center [1]); this.SetMapView(center, this.MapTilt, zoom); } else { _latestZoomCall = new MapViewMarkerZoomEvent() { Markers = markers, Percentage = percentage }; } }
/// <summary> /// Draws the image. /// </summary> /// <returns>The image.</returns> /// <param name="target">Target.</param> /// <param name="bounds">Bounds.</param> /// <param name="imageData">Image data.</param> /// <param name="tag">Tag.</param> protected override object DrawImage(Target2DWrapper <Canvas> target, RectangleF2D bounds, byte[] imageData, object tag) { global::Android.Graphics.Bitmap image = (tag as global::Android.Graphics.Bitmap); if (image == null) { image = global::Android.Graphics.BitmapFactory.DecodeByteArray( imageData, 0, imageData.Length); } PointF2D bottomLeft = new PointF2D(this.Tranform(bounds.BottomLeft [0], bounds.BottomLeft [1])); PointF2D bottomRight = new PointF2D(this.Tranform(bounds.BottomRight [0], bounds.BottomRight [1])); PointF2D topLeft = new PointF2D(this.Tranform(bounds.TopLeft [0], bounds.TopLeft [1])); //PointF2D topRight = new PointF2D(this.Tranform (bounds.TopRight [0], bounds.TopRight [1])); RectangleF2D transformed = new RectangleF2D(bottomLeft, bottomLeft.Distance(bottomRight), bottomLeft.Distance(topLeft), topLeft - bottomLeft); target.Target.Save(); target.Target.Translate((float)transformed.BottomLeft [0], (float)transformed.BottomLeft [1]); target.Target.Rotate(-(float)((Degree)transformed.Angle).Value); target.Target.DrawBitmap(image, new global::Android.Graphics.Rect(0, 0, image.Width, image.Height), new global::Android.Graphics.RectF(0, 0, (float)transformed.Width, (float)transformed.Height), null); target.Target.Restore(); return(tag); }
/// <summary> /// Draws the image. /// </summary> /// <returns>The image.</returns> /// <param name="target">Target.</param> /// <param name="bounds">Bounds.</param> /// <param name="nativeImage">Image data.</param> protected override void DrawImage(Target2DWrapper <Canvas> target, RectangleF2D bounds, INativeImage nativeImage) { var nativeAndroidImage = (nativeImage as NativeImage); global::Android.Graphics.Bitmap image = nativeAndroidImage.Image; this.Transform(bounds.BottomLeft [0], bounds.BottomLeft [1], _transformed1); PointF2D bottomLeft = new PointF2D(_transformed1[0], _transformed1[1]); this.Transform(bounds.BottomRight [0], bounds.BottomRight [1], _transformed1); PointF2D bottomRight = new PointF2D(_transformed1[0], _transformed1[1]); this.Transform(bounds.TopLeft [0], bounds.TopLeft [1], _transformed1); PointF2D topLeft = new PointF2D(_transformed1[0], _transformed1[1]); //PointF2D topRight = new PointF2D(this.Tranform (bounds.TopRight [0], bounds.TopRight [1])); var transformed = new RectangleF2D(bottomLeft, bottomLeft.Distance(bottomRight), bottomLeft.Distance(topLeft), topLeft - bottomLeft); _paint.AntiAlias = true; _paint.FilterBitmap = true; target.Target.Save(); target.Target.Translate((float)transformed.BottomLeft [0], (float)transformed.BottomLeft [1]); target.Target.Rotate(-(float)((Degree)transformed.Angle).Value); if (image != null) { target.Target.DrawBitmap(image, new global::Android.Graphics.Rect(0, 0, image.Width, image.Height), new global::Android.Graphics.RectF(0, 0, (float)transformed.Width, (float)transformed.Height), _paint); } target.Target.Restore(); }
/// <summary> /// Rotate the specified rotation. /// </summary> /// <param name="rotation">Rotation.</param> private void Rotate(UIRotationGestureRecognizer rotation) { RectangleF rect = this.Frame; if (this.MapAllowTilt && rect.Width > 0) { this.StopCurrentAnimation(); if (rotation.State == UIGestureRecognizerState.Ended) { this.NotifyMovementByInvoke();; _mapViewBefore = null; } else if (rotation.State == UIGestureRecognizerState.Began) { _mapViewBefore = this.CreateView(rect); } else { //_mapViewBefore = this.CreateView (_rect); View2D rotatedView = _mapViewBefore.RotateAroundCenter((Radian)rotation.Rotation); _mapTilt = (float)((Degree)rotatedView.Rectangle.Angle).Value; PointF2D sceneCenter = rotatedView.Rectangle.Center; _mapCenter = this.Map.Projection.ToGeoCoordinates( sceneCenter[0], sceneCenter[1]); this.NotifyMovementByInvoke(); } } }
public void LineDistance2DTest() { double delta = 0.000000000000001; // create the line to test. PointF2D a = new PointF2D(0, 0); PointF2D b = new PointF2D(1, 1); LineF2D line = new LineF2D(a, b); // calculate the results double sqrt_2 = (double)System.Math.Sqrt(2); double sqrt_2_div_2 = (double)System.Math.Sqrt(2) / 2.0f; // the point to test to. PointF2D c = new PointF2D(1, 0); Assert.AreEqual(line.Distance(c), sqrt_2_div_2, delta, string.Format("Point distance should be {0}f!", sqrt_2_div_2)); // the point to test to. c = new PointF2D(0, 1); Assert.AreEqual(line.Distance(c), sqrt_2_div_2, delta, string.Format("Point distance should be {0}f!", sqrt_2_div_2)); // the point to test to. c = new PointF2D(2, 2); Assert.AreEqual(line.Distance(c), 0.0f, delta, "Point distance should be 0.0f!"); // the point to test to. c = new PointF2D(2, 3); Assert.AreEqual(line.Distance(c), sqrt_2_div_2, delta, string.Format("Point distance should be {0}f!", sqrt_2_div_2)); // the point to test to. c = new PointF2D(3, 2); Assert.AreEqual(line.Distance(c), sqrt_2_div_2, delta, string.Format("Point distance should be {0}f!", sqrt_2_div_2)); // Segments tests. line = new LineF2D(a, b, true, true); // the point to test to. c = new PointF2D(1, 0); Assert.AreEqual(line.Distance(c), sqrt_2_div_2, delta, string.Format("Point distance should be {0}f!", sqrt_2_div_2)); // the point to test to. c = new PointF2D(0, 1); Assert.AreEqual(line.Distance(c), sqrt_2_div_2, delta, string.Format("Point distance should be {0}f!", sqrt_2_div_2)); // the point to test to. c = new PointF2D(2, 2); Assert.AreEqual(line.Distance(c), sqrt_2, delta, string.Format("Point distance should be {0}!", sqrt_2)); // the point to test to. c = new PointF2D(2, 1); Assert.AreEqual(line.Distance(c), 1, delta, string.Format("Point distance should be {0}f!", 1)); // the point to test to. c = new PointF2D(1, 2); Assert.AreEqual(line.Distance(c), 1, delta, string.Format("Point distance should be {0}f!", 1)); }
/// <summary> /// Try and find matching lines. /// </summary> /// <param name="lines"></param> /// <param name="points"></param> /// <returns></returns> private MatchPosition FindMatch(ILocatedObjectIndex <PointF2D, Scene2D.ScenePoints> linesIndex, Dictionary <Scene2D.ScenePoints, Scene2DStylesSet> lines, double[] x, double[] y, Scene2DStylesSet style, float epsilon, out Scene2D.ScenePoints found) { // build box. var box = new BoxF2D(x, y); box = box.ResizeWith(epsilon * 1.1); // get all geometries in this box. var potentialMatches = linesIndex.GetInside(box); // find a match in the potential matches list. PointF2D first = new PointF2D(x[0], y[0]); PointF2D last = new PointF2D(x[x.Length - 1], y[y.Length - 1]); MatchPosition position = MatchPosition.None; found = null; foreach (var line in potentialMatches) { // check first. PointF2D potentialFirst = new PointF2D(line.X[0], line.Y[0]); PointF2D potentialLast = new PointF2D(line.X[line.X.Length - 1], line.Y[line.Y.Length - 1]); if (first.Distance(potentialFirst) < epsilon) { found = line; position = MatchPosition.FirstFirst; } else if (last.Distance(potentialFirst) < epsilon) { found = line; position = MatchPosition.LastFirst; } else if (first.Distance(potentialLast) < epsilon) { found = line; position = MatchPosition.FirstLast; } else if (last.Distance(potentialLast) < epsilon) { found = line; position = MatchPosition.LastLast; } Scene2DStylesSet styleValue; if (position != MatchPosition.None && lines.TryGetValue(line, out styleValue) && styleValue.Equals(style)) { break; } else { position = MatchPosition.None; found = null; } } return(position); }
/// <summary> /// Rotates a point around another around point with a given angle clockwise. /// </summary> /// <returns>The around point.</returns> /// <param name="angle">Angle.</param> /// <param name="center">Center.</param> /// <param name="point">Point.</param> public static PointF2D RotateAroundPoint(Radian angle, PointF2D center, PointF2D point) { double sin = System.Math.Sin(angle.Value); double cos = System.Math.Cos(angle.Value); double newX = center [0] + (cos * (point [0] - center[0]) + sin * (point [1] - center [1])); double newY = center [1] + (-sin * (point [0] - center[0]) + cos * (point [1] - center [1])); return(new PointF2D(newX, newY)); }
public Meter DistanceReal(GeoCoordinate coordinate) { PointF2D point = this.ProjectOn((PointF2D)coordinate); if (point == (PointF2D)null) { return((Meter)double.MaxValue); } return(new GeoCoordinate(point).DistanceReal(coordinate)); }
/// <summary> /// Simplify the specified points using epsilon. /// </summary> /// <param name="points">Points.</param> /// <param name="epsilon">Epsilon.</param> /// <param name="first">First.</param> /// <param name="last">Last.</param> public static PointF2D[] SimplifyBetween(PointF2D[] points, double epsilon, int first, int last) { if (points == null) { throw new ArgumentNullException("points"); } if (epsilon <= 0) { throw new ArgumentOutOfRangeException("epsilon"); } if (first > last) { throw new ArgumentException(string.Format("first[{0}] must be smaller or equal than last[{1}]!", first, last)); } if (first + 1 != last) { // find point with the maximum distance. double maxDistance = 0; int foundIndex = -1; // create the line between first-last. LineF2D line = new LineF2D(points[first], points [last]); for (int idx = first + 1; idx < last; idx++) { double distance = line.Distance(points[idx]); if (distance > maxDistance) { // larger distance found. maxDistance = distance; foundIndex = idx; } } if (foundIndex > 0 && maxDistance > epsilon) // a point was found and it is far enough. { PointF2D[] before = SimplifyCurve.SimplifyBetween(points, epsilon, first, foundIndex); PointF2D[] after = SimplifyCurve.SimplifyBetween(points, epsilon, foundIndex, last); // build result. PointF2D[] result = new PointF2D[before.Length + after.Length - 1]; for (int idx = 0; idx < before.Length - 1; idx++) { result [idx] = before [idx]; } for (int idx = 0; idx < after.Length; idx++) { result [idx + before.Length - 1] = after [idx]; } return(result); } } return(new PointF2D[] { points[first], points[last] }); }
public static PointF2D[] SimplifyBetween(PointF2D[] points, double epsilon, int first, int last) { if (points == null) { throw new ArgumentNullException("points"); } if (epsilon <= 0.0) { throw new ArgumentOutOfRangeException("epsilon"); } if (first > last) { throw new ArgumentException(string.Format("first[{0}] must be smaller or equal than last[{1}]!", new object[2] { (object)first, (object)last })); } if (first + 1 != last) { double num1 = 0.0; int num2 = -1; LineF2D lineF2D = new LineF2D(points[first], points[last]); for (int index = first + 1; index < last; ++index) { double num3 = lineF2D.Distance(points[index]); if (num3 > num1) { num1 = num3; num2 = index; } } if (num2 > 0 && num1 > epsilon) { PointF2D[] pointF2DArray1 = SimplifyCurve.SimplifyBetween(points, epsilon, first, num2); PointF2D[] pointF2DArray2 = SimplifyCurve.SimplifyBetween(points, epsilon, num2, last); PointF2D[] pointF2DArray3 = new PointF2D[pointF2DArray1.Length + pointF2DArray2.Length - 1]; for (int index = 0; index < pointF2DArray1.Length - 1; ++index) { pointF2DArray3[index] = pointF2DArray1[index]; } for (int index = 0; index < pointF2DArray2.Length; ++index) { pointF2DArray3[index + pointF2DArray1.Length - 1] = pointF2DArray2[index]; } return(pointF2DArray3); } } return(new PointF2D[2] { points[first], points[last] }); }
public void LinePosition2DTest() { PointF2D a = new PointF2D(0, 0); PointF2D b = new PointF2D(1, 1); LineF2D line = new LineF2D(a, b); // test where the position lie. Assert.AreEqual(line.PositionOfPoint(new PointF2D(0, 0.5f)), LinePointPosition.Left, "Point position should be right!"); Assert.AreEqual(line.PositionOfPoint(new PointF2D(0.5f, 0.5f)), LinePointPosition.On, "Point position should be on!"); Assert.AreEqual(line.PositionOfPoint(new PointF2D(0.5f, 0)), LinePointPosition.Right, "Point position should be left!"); }
/// <summary> /// Expands this geo coordinate box with the given coordinate. /// </summary> /// <param name="coordinate"></param> public void ExpandWith(GeoCoordinate coordinate) { if (!this.Contains(coordinate)) { PointF2D[] newCorners = new PointF2D[3]; newCorners[0] = this.TopLeft; newCorners[1] = this.BottomRight; newCorners[2] = coordinate; this.Mutate(newCorners); } }
/// <summary> /// Encodes a bearing based on the list of coordinates and the BEARDIST parameter. /// </summary> /// <param name="coordinates"></param> /// <returns></returns> public static Degree EncodeBearing(List <GeoCoordinate> coordinates) { var distance = 0.0; var previous = coordinates[0]; PointF2D bearingPosition = null; for (int idx = 1; idx < coordinates.Count; idx++) { var current = new GeoCoordinate(coordinates[idx].Latitude, coordinates[idx].Longitude); var currentSegmentDistance = current.DistanceReal(previous).Value; 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 = previous + ((current - previous) * 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]; } // calculate offset. var offset = (bearingPosition - coordinates[0]); // convert offset to meters. var north = new VectorF2D(0, 1); // north. var xMeters = new GeoCoordinate(coordinates[0].Latitude, coordinates[0].Longitude + offset[0]).DistanceReal( coordinates[0]).Value; if (offset[0] < 0) { // invert offset. xMeters = -xMeters; } var yMeters = new GeoCoordinate(coordinates[0].Latitude + offset[1], coordinates[0].Longitude).DistanceReal( coordinates[0]).Value; if (offset[1] < 0) { // invert offset. yMeters = -yMeters; } var direction = new VectorF2D(xMeters, yMeters).Normalize(); return(direction.Angle(north)); }
public static IList <PointF2D> Calculate(IList <PointF2D> points) { if (points.Count < 3) { throw new ArgumentOutOfRangeException(string.Format("Cannot calculate the convex hull of {0} points!", (object)points.Count)); } PointF2D pointF2D1 = points[0]; foreach (PointF2D point in (IEnumerable <PointF2D>)points) { if (pointF2D1[0] > point[0]) { pointF2D1 = point; } else if (pointF2D1[0] == point[0] && pointF2D1[1] < point[1]) { pointF2D1 = point; } } PointF2D pointF2D2 = new PointF2D(new double[2] { pointF2D1[0], pointF2D1[1] - 10.0 }); VectorF2D vectorF2D = pointF2D1 - pointF2D2; List <PointF2D> pointF2DList = new List <PointF2D>(); PointF2D pointF2D3 = pointF2D1; pointF2DList.Add(pointF2D3); do { double num1 = double.MaxValue; PointF2D pointF2D4 = (PointF2D)null; foreach (PointF2D point in (IEnumerable <PointF2D>)points) { if (point != pointF2D3) { VectorF2D v = point - pointF2D3; double num2 = vectorF2D.Angle(v).Value; if (num2 < num1) { num1 = num2; pointF2D4 = point; } } } vectorF2D = pointF2D4 - pointF2D3; pointF2D3 = pointF2D4; pointF2DList.Add(pointF2D3); }while (pointF2D3 != pointF2D1); return((IList <PointF2D>)pointF2DList); }
public static PointF2D[] RotateAroundPoint(Radian angle, PointF2D center, PointF2D[] points) { double num1 = System.Math.Sin(angle.Value); double num2 = System.Math.Cos(angle.Value); PointF2D[] pointF2DArray = new PointF2D[points.Length]; for (int index = 0; index < points.Length; ++index) { double x = center[0] + (num2 * (points[index][0] - center[0]) + num1 * (points[index][1] - center[1])); double y = center[1] + (-num1 * (points[index][0] - center[0]) + num2 * (points[index][1] - center[1])); pointF2DArray[index] = new PointF2D(x, y); } return(pointF2DArray); }
/// <summary> /// Rotates a set of points around another around point with a given angle clockwise. /// </summary> /// <returns>The around point.</returns> /// <param name="angle">Angle.</param> /// <param name="center">Center.</param> /// <param name="points">Points.</param> public static PointF2D[] RotateAroundPoint(Radian angle, PointF2D center, PointF2D[] points) { double sin = System.Math.Sin(angle.Value); double cos = System.Math.Cos(angle.Value); PointF2D[] rotated = new PointF2D[points.Length]; for (int idx = 0; idx < points.Length; idx++) { double newX = center [0] + (cos * (points[idx] [0] - center[0]) + sin * (points[idx] [1] - center [1])); double newY = center [1] + (-sin * (points[idx] [0] - center[0]) + cos * (points[idx] [1] - center [1])); rotated[idx] = new PointF2D(newX, newY); } return(rotated); }
public void RotationSimpleTest() { double delta = 0.00001; PointF2D center = new PointF2D(1, 1); PointF2D point = new PointF2D(1, 2); PointF2D rotated = Rotation.RotateAroundPoint((Degree)90, center, point); Assert.AreEqual(2, rotated [0], delta); Assert.AreEqual(1, rotated [1], delta); rotated = Rotation.RotateAroundPoint((Degree)180, center, point); Assert.AreEqual(1, rotated [0], delta); Assert.AreEqual(0, rotated [1], delta); }
/// <summary> /// Try and find matching lines. /// </summary> /// <param name="lines"></param> /// <param name="points"></param> /// <returns></returns> private MatchPosition FindMatch(Dictionary <Scene2D.ScenePoints, Scene2DStylesSet> lines, double[] x, double[] y, Scene2DStylesSet style, out Scene2D.ScenePoints found) { PointF2D first = new PointF2D(x[0], y[0]); PointF2D last = new PointF2D(x[x.Length - 1], y[y.Length - 1]); MatchPosition position = MatchPosition.None; found = null; foreach (var line in lines) { if (line.Value.Equals(style)) { // check first. PointF2D potentialFirst = new PointF2D(line.Key.X[0], line.Key.Y[0]); if (first.Distance(potentialFirst) < _epsilon) { found = line.Key; position = MatchPosition.FirstFirst; break; } if (last.Distance(potentialFirst) < _epsilon) { found = line.Key; position = MatchPosition.LastFirst; break; } PointF2D potentialLast = new PointF2D(line.Key.X[line.Key.X.Length - 1], line.Key.Y[line.Key.Y.Length - 1]); if (first.Distance(potentialLast) < _epsilon) { found = line.Key; position = MatchPosition.FirstLast; break; } if (last.Distance(potentialLast) < _epsilon) { found = line.Key; position = MatchPosition.LastLast; break; } } } return(position); }
public static GeoCoordinate PositionAfter(this Route route, Meter m) { double num1 = 0.0; List <GeoCoordinate> points = route.GetPoints(); for (int index = 0; index < points.Count - 1; ++index) { double num2 = points[index].DistanceReal(points[index + 1]).Value; if (num1 + num2 >= m.Value) { double num3 = m.Value - num1; VectorF2D vectorF2D = ((PointF2D)points[index + 1] - (PointF2D)points[index]) * (num3 / num2); PointF2D pointF2D = (PointF2D)points[index] + vectorF2D; return(new GeoCoordinate(pointF2D[1], pointF2D[0])); } num1 += num2; } return((GeoCoordinate)null); }
/// <summary> /// Calculates the closest point on the route. /// </summary> /// <param name="coordinates"></param> /// <returns></returns> public GeoCoordinate ProjectOn(GeoCoordinate coordinates) { double distance = double.MaxValue; GeoCoordinate closests = null; List <GeoCoordinate> points = this.GetPoints(); for (int idx = 0; idx < points.Count - 1; idx++) { GeoCoordinateLine line = new GeoCoordinateLine(points[idx], points[idx + 1]); PointF2D projectedPoint = line.ProjectOn(coordinates); GeoCoordinate projected = new GeoCoordinate(projectedPoint[1], projectedPoint[0]); double currentDistance = coordinates.Distance(projected); if (currentDistance < distance) { closests = projected; distance = currentDistance; } } return(closests); }
/// <summary> /// Calculates the position on the route after the given distance from the starting point. /// </summary> /// <param name="m"></param> /// <returns></returns> public GeoCoordinate PositionAfter(Meter m) { double distanceMeter = 0; List <GeoCoordinate> points = this.GetPoints(); for (int idx = 0; idx < points.Count - 1; idx++) { double currentDistance = points[idx].DistanceReal(points[idx + 1]).Value; if (distanceMeter + currentDistance >= m.Value) { // the current distance should be in this segment. double segmentDistance = m.Value - distanceMeter; VectorF2D direction = points[idx + 1] - points[idx]; direction = direction * (segmentDistance / currentDistance); PointF2D position = points[idx] + direction; return(new GeoCoordinate(position[1], position[0])); } distanceMeter += currentDistance; } return(null); }
/// <summary> /// Draws an image on the target. /// </summary> /// <param name="target"></param> /// <param name="left"></param> /// <param name="top"></param> /// <param name="right"></param> /// <param name="bottom"></param> /// <param name="nativeImage"></param> /// <returns>The image.</returns> protected override void DrawImage(Target2DWrapper <CGContextWrapper> target, double left, double top, double right, double bottom, INativeImage nativeImage) { // get the native image. var iosNativeImage = (nativeImage as NativeImage); // get CGImage. CGImage image = iosNativeImage.Image; var bounds = new RectangleF2D(left, bottom, (left - right), (top - bottom)); target.Target.CGContext.SetAllowsFontSubpixelQuantization(true); target.Target.CGContext.SetAllowsFontSmoothing(true); target.Target.CGContext.SetAllowsAntialiasing(true); target.Target.CGContext.SetAllowsSubpixelPositioning(true); target.Target.CGContext.SetShouldAntialias(true); PointF2D bottomLeft = new PointF2D(this.Transform(bounds.BottomLeft[0], bounds.BottomLeft[1])); PointF2D bottomRight = new PointF2D(this.Transform(bounds.BottomRight[0], bounds.BottomRight[1])); PointF2D topLeft = new PointF2D(this.Transform(bounds.TopLeft[0], bounds.TopLeft[1])); //PointF2D topRight = new PointF2D(this.Tranform (bounds.TopRight [0], bounds.TopRight [1])); RectangleF2D transformed = new RectangleF2D(bottomLeft, bottomLeft.Distance(bottomRight), bottomLeft.Distance(topLeft), topLeft - bottomLeft); target.Target.CGContext.SaveState(); target.Target.CGContext.TranslateCTM((float)transformed.BottomLeft[0], (float)transformed.BottomLeft[1]); target.Target.CGContext.RotateCTM(-(float)((Radian)transformed.Angle).Value); target.Target.CGContext.ScaleCTM(-1, 1); // build rectangle. _rectangle.X = 0; _rectangle.Y = 0; _rectangle.Width = (float)transformed.Width; _rectangle.Height = (float)transformed.Height; target.Target.CGContext.DrawImage(_rectangle, image); target.Target.CGContext.RestoreState(); }
/// <summary> /// Test if routes between two resolved nodes are correctly calculated. /// </summary> protected void DoTestResolveBetweenClose() { // initialize data. var interpreter = new OsmRoutingInterpreter(); IBasicRouterDataSource <TEdgeData> data = this.BuildData(interpreter, "OsmSharp.Test.Unittests.test_network.osm"); var vertex20 = new GeoCoordinate(51.0578532, 3.7192229); var vertex21 = new GeoCoordinate(51.0578518, 3.7195654); var vertex16 = new GeoCoordinate(51.0577299, 3.719745); for (double position1 = 0.1; position1 < 0.91; position1 = position1 + 0.1) { PointF2D point = vertex20 + ((vertex21 - vertex20) * position1); var vertex2021 = new GeoCoordinate(point[1], point[0]); for (double position2 = 0.1; position2 < 0.91; position2 = position2 + 0.1) { point = vertex21 + ((vertex16 - vertex21) * position2); var vertex2116 = new GeoCoordinate(point[1], point[0]); // calculate route. IBasicRouter <TEdgeData> basicRouter = this.BuildBasicRouter(data); Router router = this.BuildRouter(data, interpreter, basicRouter); Route route = router.Calculate(Vehicle.Car, router.Resolve(Vehicle.Car, vertex2021), router.Resolve(Vehicle.Car, vertex2116)); Assert.AreEqual(3, route.Entries.Length); Assert.AreEqual(vertex2021.Latitude, route.Entries[0].Latitude, 0.0001); Assert.AreEqual(vertex2021.Longitude, route.Entries[0].Longitude, 0.0001); Assert.AreEqual(vertex21.Latitude, route.Entries[1].Latitude, 0.0001); Assert.AreEqual(vertex21.Longitude, route.Entries[1].Longitude, 0.0001); Assert.AreEqual(vertex2116.Latitude, route.Entries[2].Latitude, 0.0001); Assert.AreEqual(vertex2116.Longitude, route.Entries[2].Longitude, 0.0001); } } }