/// <summary> /// Called when the tap gesture recognizer detects a double tap. /// </summary> /// <param name="tap">Tap.</param> private void DoubleTap(UITapGestureRecognizer tap) { //RectangleF2D rect = _rect; RectangleF rect = this.Frame; if (rect.Width > 0 && rect.Height > 0) { this.StopCurrentAnimation(); View2D view = this.CreateView(rect); PointF location = tap.LocationInView(this); double[] sceneCoordinates = view.FromViewPort(rect.Width, rect.Height, location.X, location.Y); GeoCoordinate geoLocation = this.Map.Projection.ToGeoCoordinates(sceneCoordinates [0], sceneCoordinates [1]); if (this.DoubleMapTapEvent != null) { this.DoubleMapTapEvent(geoLocation); } else { // minimum zoom. float tapRequestZoom = (float)System.Math.Max(_mapZoom + 1, 19); _doubleTapAnimator.Start(geoLocation, tapRequestZoom, new TimeSpan(0, 0, 1)); } } }
/// <summary> /// Updates the tracker with the given location and angle. /// </summary> /// <param name="location">The measured location.</param> /// <param name="angle">The angle relative to the north measure clockwise.</param> public void Track(GeoCoordinate location, Degree angle) { if (location == null) { throw new ArgumentNullException("location"); } if (_lastTouch.HasValue) { // is tracking disabled now? TimeSpan timeFromLastTouch = new TimeSpan(DateTime.Now.Ticks - _lastTouch.Value); if (timeFromLastTouch.TotalSeconds >= this.RestartAfterTouch.Value) { // ok, the animator has waited long enough. _lastTouch = null; } else { // ok, the animator still has to wait for user-input. return; } } // check if the minimum gap between tracking events is respected. long now = DateTime.Now.Ticks; if (_lastTrack.HasValue) { if (_minimumTrackGap > now - _lastTrack.Value) { return; // too fast! } } _lastTrack = now; // animate the next step(s). TimeSpan lastTrackInterval = new TimeSpan(0, 0, 0, 0, 750); long ticks = DateTime.Now.Ticks; if (_lastTicks.HasValue) { // update the last track interval. lastTrackInterval = TimeSpan.FromTicks(ticks - _lastTicks.Value); } _lastTicks = ticks; OsmSharp.Logging.Log.TraceEvent("RouteTrackerAnimator", OsmSharp.Logging.TraceEventType.Information, "Interval: {0}ms", lastTrackInterval.TotalMilliseconds); // give location to the route tracker. _routeTracker.Track(location); // calculate all map view parameters (zoom, location, tilt) to display the route/direction correctly. float zoom = this.DefaultZoom; GeoCoordinate center = _routeTracker.PositionRoute; double nextDistance = 50; Degree tilt = _mapView.MapTilt; GeoCoordinate next = _routeTracker.PositionAfter(nextDistance); if (next != null) { IProjection projection = _mapView.Map.Projection; VectorF2D direction = new PointF2D(projection.ToPixel(next)) - new PointF2D(projection.ToPixel(center)); tilt = direction.Angle(new VectorF2D(0, -1)); } // overwrite calculated tilt with the given degrees. if (angle != null) { tilt = angle; } OsmSharp.Logging.Log.TraceEvent("RouteTrackerAnimator", OsmSharp.Logging.TraceEventType.Information, "Tracking Event: {0}, {1}, {2}", center, zoom, tilt); // animate to the given parameter (zoom, location, tilt). _animator.Stop(); _animator.Start(center, zoom, tilt, lastTrackInterval.Subtract(new TimeSpan(0, 0, 0, 0, 50))); }