/// <summary> /// Utility method for ensuring a view stays within a bounding box of geo coordinated. /// </summary> /// <param name="center">The map center we want to move to.</param> /// <param name="boundingBox">A GeoCoordinateBox defining the bounding box.</param> /// <param name="view" The current view.</param> /// <returns>Returns a center geo coordinate that is corrected so the view stays within the bounding box.</returns> public GeoCoordinate EnsureViewWithinBoundingBox(GeoCoordinate center, GeoCoordinateBox boundingBox, View2D view) { double[] mapCenterSceneCoords = this.Projection.ToPixel(center); double[] mapCenterPixels = view.ToViewPort(view.Width, view.Height, mapCenterSceneCoords[0], mapCenterSceneCoords[1]); double[] topLeftSceneCoordinates = view.FromViewPort(view.Width, view.Height, mapCenterPixels[0] - (view.Width) / 2.0, mapCenterPixels[1] - (view.Height) / 2.0); GeoCoordinate topLeft = this.Projection.ToGeoCoordinates(topLeftSceneCoordinates[0], topLeftSceneCoordinates[1]); double[] bottomRightSceneCoordinates = view.FromViewPort(view.Width, view.Height, mapCenterPixels[0] + (view.Width) / 2.0, mapCenterPixels[1] + (view.Height) / 2.0); GeoCoordinate bottomRight = this.Projection.ToGeoCoordinates(bottomRightSceneCoordinates[0], bottomRightSceneCoordinates[1]); // Early exit when the view is inside the box. if (boundingBox.Contains(topLeft) && boundingBox.Contains(bottomRight)) { return(center); } double viewNorth = topLeft.Latitude; double viewEast = bottomRight.Longitude; double viewSouth = bottomRight.Latitude; double viewWest = topLeft.Longitude; double boxNorth = boundingBox.MaxLat; double boxEast = boundingBox.MaxLon; double boxSouth = boundingBox.MinLat; double boxWest = boundingBox.MinLon; //TODO: Check if the view acrually fits the bounding box, if not resize the view. // Correct all view bounds if neccecary. if (viewNorth > boxNorth) { viewSouth -= viewNorth - boxNorth; viewNorth = boxNorth; } if (viewEast > boxEast) { viewWest -= viewEast - boxEast; viewEast = boxEast; } if (viewSouth < boxSouth) { viewNorth += boxSouth - viewSouth; viewSouth = boxSouth; } if (viewWest < boxWest) { viewEast += boxWest - viewWest; viewWest = boxWest; } // Compute and return corrected map center return(new GeoCoordinate(viewSouth + (viewNorth - viewSouth) / 2.0f, viewWest + (viewEast - viewWest) / 2.0f)); }
/// <summary> /// Raises the mousemove event. /// </summary> /// <param name="e"></param> protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (this.MapAllowPan && e.Button == MouseButtons.Left && _draggingCoordinates != null) { var currentCoordinates = new double[] { e.X, e.Y }; var delta = new double[] { _draggingCoordinates[0] - currentCoordinates[0], (_draggingCoordinates[1] - currentCoordinates[1]) }; var newCenter = new double[] { this.Width / 2.0f + delta[0], this.Height / 2.0f + delta[1] }; this.MapCenter = _oldCenter; View2D view = _renderer.Create(this.Width, this.Height, this.Map, (float)this.Map.Projection.ToZoomFactor(this.MapZoom), this.MapCenter, false, true); double[] sceneCenter = view.FromViewPort(this.Width, this.Height, newCenter[0], newCenter[1]); // project to new center. this.MapCenter = this.Map.Projection.ToGeoCoordinates(sceneCenter[0], sceneCenter[1]); // notify the map. this.QueueNotifyMapViewChanged(); } }
/// <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> /// Raises the touch event. /// </summary> /// <param name="v">V.</param> /// <param name="e">E.</param> public bool OnTouch(global::Android.Views.View v, MotionEvent e) { _tagGestureDetector.OnTouchEvent(e); _scaleGestureDetector.OnTouchEvent(e); _rotateGestureDetector.OnTouchEvent(e); _moveGestureDetector.OnTouchEvent(e); if (_deltaX != 0 || _deltaY != 0 || // was there movement? _deltaScale != 1.0 || // was there scale? _deltaDegrees != 0) // was there rotation? { if (_deltaScale != 1.0) { // calculate the scale. double zoomFactor = this.Map.Projection.ToZoomFactor(this.MapZoom); zoomFactor = zoomFactor * _deltaScale; this.MapZoom = (float)this.Map.Projection.ToZoomLevel(zoomFactor); } // stop the animation. this.StopCurrentAnimation(); //OsmSharp.Logging.Log.TraceEvent("OsmSharp.Android.UI.MapView", System.Diagnostics.TraceEventType.Information, // string.Format("OnTouch:[{0},{1}] {2}s {3}d", _deltaX, _deltaY, _deltaScale, _deltaDegrees)); // recreate the view. View2D view = this.CreateView(); // calculate the new center in pixels. double centerXPixels = this.Width / 2.0f - _deltaX; double centerYPixles = this.Height / 2.0f - _deltaY; // calculate the new center from the view. double[] sceneCenter = view.FromViewPort(this.Width, this.Height, centerXPixels, centerYPixles); // convert to the projected center. this.MapCenter = this.Map.Projection.ToGeoCoordinates(sceneCenter [0], sceneCenter [1]); // do the rotation stuff around the new center. if (_deltaDegrees != 0) { View2D rotatedView = view.RotateAroundCenter((Degree)(-_deltaDegrees)); _mapTilt = (float)((Degree)rotatedView.Rectangle.Angle).Value; } _deltaScale = 1; _deltaDegrees = 0; _deltaX = 0; _deltaY = 0; // notify touch. _mapView.RaiseMapTouched(); this.NotifyMovement(); } return(true); }
/// <summary> /// Pan the specified some. /// </summary> /// <param name="some">Some.</param> private void Pan(UIPanGestureRecognizer pan) { if (_rect != null) { PointF offset = pan.TranslationInView(this); if (pan.State == UIGestureRecognizerState.Ended) { _beforePan = null; View2D view = this.CreateView(_rect); double centerXPixels = _rect.Width / 2.0f - offset.X; double centerYPixels = _rect.Height / 2.0f - offset.Y; double[] sceneCenter = view.FromViewPort(_rect.Width, _rect.Height, centerXPixels, centerYPixels); this.MapCenter = this.Map.Projection.ToGeoCoordinates( sceneCenter [0], sceneCenter [1]); this.Change(); // notifies change. } else if (pan.State == UIGestureRecognizerState.Began) { _beforePan = this.MapCenter; } else if (pan.State == UIGestureRecognizerState.Cancelled || pan.State == UIGestureRecognizerState.Failed) { _beforePan = null; } else if (_beforePan != null) { this.MapCenter = _beforePan; View2D view = this.CreateView(_rect); double centerXPixels = _rect.Width / 2.0f - offset.X; double centerYPixels = _rect.Height / 2.0f - offset.Y; double[] sceneCenter = view.FromViewPort(_rect.Width, _rect.Height, centerXPixels, centerYPixels); this.MapCenter = this.Map.Projection.ToGeoCoordinates( sceneCenter [0], sceneCenter [1]); this.InvokeOnMainThread(Test); } } }
/// <summary> /// Called when the map was single tapped at a certain location. /// </summary> /// <param name="tap">Tap.</param> private void SingleTap(UITapGestureRecognizer tap) { RectangleF rect = this.Frame; if (rect.Width > 0 && rect.Height > 0) { this.StopCurrentAnimation(); if (this.MapTapEvent != null) { View2D view = this.CreateView(rect); PointF location = tap.LocationInView(this); double[] sceneCoordinates = view.FromViewPort(rect.Width, rect.Height, location.X, location.Y); this.MapTapEvent(this.Map.Projection.ToGeoCoordinates(sceneCoordinates[0], sceneCoordinates[1])); } } }
/// <summary> /// Pan the specified some. /// </summary> /// <param name="some">Some.</param> private void Pan(UIPanGestureRecognizer pan) { OsmSharp.Logging.Log.TraceEvent("MapView", System.Diagnostics.TraceEventType.Error, string.Format("{0} ", pan.State.ToString())); //RectangleF2D rect = _rect; RectangleF rect = this.Frame; if (rect.Width > 0) { this.StopCurrentAnimation(); PointF offset = pan.TranslationInView(this); if (pan.State == UIGestureRecognizerState.Ended) { _beforePan = null; this.Change(true); // notifies change. } else if (pan.State == UIGestureRecognizerState.Began) { _beforePan = this.MapCenter; } else if (pan.State == UIGestureRecognizerState.Cancelled || pan.State == UIGestureRecognizerState.Failed) { _beforePan = null; } else if (pan.State == UIGestureRecognizerState.Changed) { _mapCenter = _beforePan; View2D view = this.CreateView(rect); double centerXPixels = rect.Width / 2.0f - offset.X; double centerYPixels = rect.Height / 2.0f - offset.Y; double[] sceneCenter = view.FromViewPort(rect.Width, rect.Height, centerXPixels, centerYPixels); _mapCenter = this.Map.Projection.ToGeoCoordinates( sceneCenter[0], sceneCenter[1]); this.InvokeOnMainThread(InvalidateMap); } } }
/// <summary> /// Called when a tab is detected. /// </summary> /// <param name="detector"></param> /// <returns></returns> public bool OnTap(TapGestureDetector detector) { // recreate the view. View2D view = this.CreateView(); // calculate the new center in pixels. double x = detector.X; double y = detector.Y; // calculate the new center from the view. double[] sceneCenter = view.FromViewPort(this.Width, this.Height, x, y); // convert to the projected center. _mapView.RaiseMapTapEvent(this.Map.Projection.ToGeoCoordinates(sceneCenter[0], sceneCenter[1])); return(true); }
/// <summary> /// Raises the touch event. /// </summary> /// <param name="v">V.</param> /// <param name="e">E.</param> public bool OnTouch(global::Android.Views.View v, MotionEvent e) { _scaleGestureDetector.OnTouchEvent(e); if (!_scaled) { _gestureDetector.OnTouchEvent(e); if (e.Action == MotionEventActions.Up) { // calculate event time. long time = e.EventTime - e.DownTime; if (time > 120) { this.NotifyMovement(); OsmSharp.Logging.Log.TraceEvent("OsmSharp.Android.UI.MapView", System.Diagnostics.TraceEventType.Information, string.Format("OnTouch:{0}ms", time)); this.Change(); } else // raise the map tap event here. { if (this.MapTapEvent != null) { // recreate the view. View2D view = this.CreateView(); // calculate the new center in pixels. double x = e.GetX(); double y = e.GetY(); // calculate the new center from the view. double[] sceneCenter = view.FromViewPort(this.Width, this.Height, x, y); // convert to the projected center. this.MapTapEvent(this.Map.Projection.ToGeoCoordinates(sceneCenter[0], sceneCenter[1])); } } } } _scaled = false; return(true); }
/// <summary> /// Pan the specified some. /// </summary> /// <param name="some">Some.</param> private void Pan(UIPanGestureRecognizer pan) { RectangleF rect = this.Frame; if (this.MapAllowPan && rect.Width > 0) { this.StopCurrentAnimation(); PointF offset = pan.TranslationInView(this); if (pan.State == UIGestureRecognizerState.Ended) { _beforePan = null; this.NotifyMovementByInvoke(); } else if (pan.State == UIGestureRecognizerState.Began) { _beforePan = this.MapCenter; } else if (pan.State == UIGestureRecognizerState.Cancelled || pan.State == UIGestureRecognizerState.Failed) { _beforePan = null; } else if (pan.State == UIGestureRecognizerState.Changed) { _mapCenter = _beforePan; View2D view = this.CreateView(rect); double centerXPixels = rect.Width / 2.0f - offset.X; double centerYPixels = rect.Height / 2.0f - offset.Y; double[] sceneCenter = view.FromViewPort(rect.Width, rect.Height, centerXPixels, centerYPixels); _mapCenter = this.Map.Projection.ToGeoCoordinates( sceneCenter[0], sceneCenter[1]); this.NotifyMovementByInvoke(); } } }
/// <summary> /// Raises the scroll event. /// </summary> /// <param name="e1">E1.</param> /// <param name="e2">E2.</param> /// <param name="distanceX">Distance x.</param> /// <param name="distanceY">Distance y.</param> public bool OnScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // recreate the view. View2D view = this.CreateView(); // calculate the new center in pixels. double centerXPixels = this.Width / 2.0f + distanceX; double centerYPixles = this.Height / 2.0f + distanceY; // calculate the new center from the view. double[] sceneCenter = view.FromViewPort(this.Width, this.Height, centerXPixels, centerYPixles); // convert to the projected center. this.MapCenter = this.Map.Projection.ToGeoCoordinates(sceneCenter[0], sceneCenter[1]); // _highQuality = false; this.NotifyMovement(); return(true); }
/// <summary> /// Raises the OnMapMouseClick event. /// </summary> /// <param name="e"></param> private void RaiseOnMapMouseClick(MouseEventArgs e) { if (this.Map != null) { View2D view = _renderer.Create(this.Width, this.Height, this.Map, (float)this.Map.Projection.ToZoomFactor(this.MapZoom), this.MapCenter, false, true); // get scene coordinates. double[] scenCoordinates = view.FromViewPort(this.Width, this.Height, e.X, e.Y); GeoCoordinate geoCoordinates = this.Map.Projection.ToGeoCoordinates(scenCoordinates[0], scenCoordinates[1]); // create map user control event args. MapControlEventArgs args = new MapControlEventArgs(e, geoCoordinates); this.OnMapMouseClick(args); if (MapMouseClick != null) { MapMouseClick(args); } } }
/// <summary> /// Transforms the y-coordinate to screen coordinates. /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> private double[] TransformReverse(double x, double y) { return(_view.FromViewPort(_target.Width, _target.Height, x, y)); }
public void View2DTestCreateFrom() { View2D view = View2D.CreateFrom(0, 0, 200, 200, 1, false, false); // test result. Assert.AreEqual(view.LeftTop[0], -100); Assert.AreEqual(view.RightTop[0], 100); Assert.AreEqual(view.RightBottom[1], -100); Assert.AreEqual(view.RightTop[1], 100); Assert.IsTrue(view.Contains(0, 0)); double[] topLeft = view.FromViewPort(1000, 1000, 0, 0); Assert.AreEqual(topLeft[0], -100); Assert.AreEqual(topLeft[1], -100); double[] bottomRight = view.FromViewPort(1000, 1000, 1000, 1000); Assert.AreEqual(bottomRight[0], 100); Assert.AreEqual(bottomRight[1], 100); double[] viewTopLeft = view.ToViewPort(1000, 1000, view.LeftTop[0], view.RightTop[1]); Assert.AreEqual(0, viewTopLeft[0]); Assert.AreEqual(1000, viewTopLeft[1]); double[] viewBottomRight = view.ToViewPort(1000, 1000, view.RightBottom[0], view.RightBottom[1]); Assert.AreEqual(1000, viewBottomRight[0]); Assert.AreEqual(0, viewBottomRight[1]); view = View2D.CreateFrom(0, 0, 200, 200, 1, true, false); // test result. Assert.AreEqual(view.LeftTop[0], 100); Assert.AreEqual(view.RightTop[0], -100); Assert.AreEqual(view.RightBottom[1], -100); Assert.AreEqual(view.RightTop[1], 100); Assert.IsTrue(view.Contains(0, 0)); topLeft = view.FromViewPort(1000, 1000, 0, 0); Assert.AreEqual(topLeft[0], 100); Assert.AreEqual(topLeft[1], -100); bottomRight = view.FromViewPort(1000, 1000, 1000, 1000); Assert.AreEqual(bottomRight[0], -100); Assert.AreEqual(bottomRight[1], 100); viewTopLeft = view.ToViewPort(1000, 1000, view.LeftTop[0], view.LeftTop[1]); Assert.AreEqual(0, viewTopLeft[0]); Assert.AreEqual(1000, viewTopLeft[1]); viewBottomRight = view.ToViewPort(1000, 1000, view.RightBottom[0], view.RightBottom[1]); Assert.AreEqual(1000, viewBottomRight[0]); Assert.AreEqual(0, viewBottomRight[1]); view = View2D.CreateFrom(0, 0, 200, 200, 1, false, true); // test result. Assert.AreEqual(view.LeftTop[0], -100); Assert.AreEqual(view.RightTop[0], 100); Assert.AreEqual(view.RightBottom[1], 100); Assert.AreEqual(view.RightTop[1], -100); Assert.IsTrue(view.Contains(0, 0)); topLeft = view.FromViewPort(1000, 1000, 0, 0); Assert.AreEqual(topLeft[0], -100); Assert.AreEqual(topLeft[1], 100); bottomRight = view.FromViewPort(1000, 1000, 1000, 1000); Assert.AreEqual(bottomRight[0], 100); Assert.AreEqual(bottomRight[1], -100); viewTopLeft = view.ToViewPort(1000, 1000, view.LeftTop[0], view.LeftTop[1]); Assert.AreEqual(0, viewTopLeft[0]); Assert.AreEqual(1000, viewTopLeft[1]); viewBottomRight = view.ToViewPort(1000, 1000, view.RightBottom[0], view.RightBottom[1]); Assert.AreEqual(1000, viewBottomRight[0]); Assert.AreEqual(0, viewBottomRight[1]); view = View2D.CreateFrom(0, 0, 200, 200, 1, true, true); // test result. Assert.AreEqual(view.LeftTop[0], 100); Assert.AreEqual(view.RightTop[0], -100); Assert.AreEqual(view.RightBottom[1], 100); Assert.AreEqual(view.RightTop[1], -100); Assert.IsTrue(view.Contains(0, 0)); topLeft = view.FromViewPort(1000, 1000, 0, 0); Assert.AreEqual(topLeft[0], 100); Assert.AreEqual(topLeft[1], 100); bottomRight = view.FromViewPort(1000, 1000, 1000, 1000); Assert.AreEqual(bottomRight[0], -100); Assert.AreEqual(bottomRight[1], -100); viewTopLeft = view.ToViewPort(1000, 1000, view.LeftTop[0], view.LeftTop[1]); Assert.AreEqual(0, viewTopLeft[0]); Assert.AreEqual(1000, viewTopLeft[1]); viewBottomRight = view.ToViewPort(1000, 1000, view.RightBottom[0], view.RightBottom[1]); Assert.AreEqual(1000, viewBottomRight[0]); Assert.AreEqual(0, viewBottomRight[1]); view = View2D.CreateFromBounds(100, -100, -100, 100); // test result. Assert.AreEqual(view.LeftTop[0], -100); Assert.AreEqual(view.RightTop[0], 100); Assert.AreEqual(view.RightBottom[1], -100); Assert.AreEqual(view.RightTop[1], 100); Assert.IsTrue(view.Contains(0, 0)); view = View2D.CreateFromBounds(-100, 100, 100, -100); // test result. Assert.AreEqual(view.LeftTop[0], 100); Assert.AreEqual(view.RightTop[0], -100); Assert.AreEqual(view.RightBottom[1], 100); Assert.AreEqual(view.RightTop[1], -100); Assert.IsTrue(view.Contains(0, 0)); }
public void View2DTestCreateFromWithDirection() { double delta = 0.000001; // create a new view that is tilted. View2D view = View2D.CreateFrom(0, 0, System.Math.Sqrt(2), System.Math.Sqrt(2), 1, false, false, 45); Assert.AreEqual(-1, view.LeftBottom[0], delta); Assert.AreEqual(0, view.LeftBottom[1], delta); Assert.AreEqual(0, view.RightBottom[0], delta); Assert.AreEqual(-1, view.RightBottom[1], delta); Assert.AreEqual(0, view.LeftTop[0], delta); Assert.AreEqual(1, view.LeftTop[1], delta); Assert.AreEqual(1, view.RightTop[0], delta); Assert.AreEqual(0, view.RightTop[1], delta); Assert.IsTrue(view.Contains(0, 0)); double[] bottomLeft = view.FromViewPort(1000, 1000, 0, 0); Assert.AreEqual(bottomLeft[0], view.LeftBottom[0], delta); Assert.AreEqual(bottomLeft[1], view.LeftBottom[1], delta); double[] topRight = view.FromViewPort(1000, 1000, 1000, 1000); Assert.AreEqual(topRight[0], view.RightTop[0], delta); Assert.AreEqual(topRight[1], view.RightTop[1], delta); double[] topLeft = view.FromViewPort(1000, 1000, 0, 1000); Assert.AreEqual(topLeft[0], view.LeftTop[0], delta); Assert.AreEqual(topLeft[1], view.LeftTop[1], delta); double[] bottomRight = view.FromViewPort(1000, 1000, 1000, 0); Assert.AreEqual(bottomRight[0], view.RightBottom[0], delta); Assert.AreEqual(bottomRight[1], view.RightBottom[1], delta); double[] viewBottomLeft = view.ToViewPort(1000, 1000, view.LeftBottom[0], view.LeftBottom[1]); Assert.AreEqual(view.LeftBottom[0], view.FromViewPort(1000, 1000, viewBottomLeft[0], viewBottomLeft[1])[0], delta); Assert.AreEqual(view.LeftBottom[1], view.FromViewPort(1000, 1000, viewBottomLeft[0], viewBottomLeft[1])[1], delta); double[] viewBottomRight = view.ToViewPort(1000, 1000, view.RightBottom[0], view.RightBottom[1]); Assert.AreEqual(view.RightBottom[0], view.FromViewPort(1000, 1000, viewBottomRight[0], viewBottomRight[1])[0], delta); Assert.AreEqual(view.RightBottom[1], view.FromViewPort(1000, 1000, viewBottomRight[0], viewBottomRight[1])[1], delta); double[] viewTopLeft = view.ToViewPort(1000, 1000, view.LeftTop[0], view.LeftTop[1]); Assert.AreEqual(view.LeftTop[0], view.FromViewPort(1000, 1000, viewTopLeft[0], viewTopLeft[1])[0], delta); Assert.AreEqual(view.LeftTop[1], view.FromViewPort(1000, 1000, viewTopLeft[0], viewTopLeft[1])[1], delta); double[] viewTopRight = view.ToViewPort(1000, 1000, view.RightTop[0], view.RightTop[1]); Assert.AreEqual(view.RightTop[0], view.FromViewPort(1000, 1000, viewTopRight[0], viewTopRight[1])[0], delta); Assert.AreEqual(view.RightTop[1], view.FromViewPort(1000, 1000, viewTopRight[0], viewTopRight[1])[1], delta); }
/// <summary> /// Raises the touch event. /// </summary> /// <param name="v">V.</param> /// <param name="e">E.</param> public bool OnTouch(global::Android.Views.View v, MotionEvent e) { try { if (!_renderingSuspended && this.Map != null && this.Map.Projection != null && this.MapCenter != null) { _tagGestureDetector.OnTouchEvent(e); _scaleGestureDetector.OnTouchEvent(e); _rotateGestureDetector.OnTouchEvent(e); _moveGestureDetector.OnTouchEvent(e); if (_deltaX != 0 || _deltaY != 0 || // was there movement? _deltaScale != 1.0 || // was there scale? _deltaDegrees != 0) { // was there rotation? bool movement = false; if (this.MapAllowZoom && _deltaScale != 1.0) { // calculate the scale. double zoomFactor = this.Map.Projection.ToZoomFactor(this.MapZoom); zoomFactor = zoomFactor * _deltaScale; this.MapZoom = (float)this.Map.Projection.ToZoomLevel(zoomFactor); movement = true; } if (this.MapAllowPan) { // stop the animation. this.StopCurrentAnimation(); // recreate the view. View2D view = this.CreateView(); // calculate the new center in pixels. double centerXPixels = this.SurfaceWidth / 2.0f - _deltaX; double centerYPixles = this.SurfaceHeight / 2.0f - _deltaY; // calculate the new center from the view. double[] sceneCenter = view.FromViewPort(this.SurfaceWidth, this.SurfaceHeight, centerXPixels, centerYPixles); // convert to the projected center. this.MapCenter = this.Map.Projection.ToGeoCoordinates(sceneCenter[0], sceneCenter[1]); movement = true; } // do the rotation stuff around the new center. if (this.MapAllowTilt && _deltaDegrees != 0) { // recreate the view. View2D view = this.CreateView(); View2D rotatedView = view.RotateAroundCenter((Degree)(-_deltaDegrees)); _mapTilt = (float)((Degree)rotatedView.Rectangle.Angle).Value; movement = true; } _deltaScale = 1; _deltaDegrees = 0; _deltaX = 0; _deltaY = 0; // notify touch. if (movement) { _mapView.RaiseMapTouched(); this.NotifyMovement(); } } } } catch (Exception ex) { OsmSharp.Logging.Log.TraceEvent("MapViewSurface.OnTouch", TraceEventType.Critical, string.Format("An unhandled exception occured:{0}", ex.ToString())); } return(true); }