public void TestRestrictZoom() { // arrange var viewport = new Viewport { Center = new Point(0, 0), Width = 100, Height = 100, Resolution = 1 }; // viewport.Center is (0, 0) at this point var restrictTo = new BoundingBox(20, 40, 120, 140); // Minimal X value is 20, Minimal Y value is 40 // act ViewportLimiter.LimitExtent(viewport, PanMode.KeepCenterWithinExtents, restrictTo, viewport.Extent); // assert Assert.AreEqual(viewport.Center.X, 20); Assert.AreEqual(viewport.Center.Y, 40); }
public void TestRestrictZoom() { // arrange var viewport = new Viewport { CenterX = 0, CenterY = 0, Width = 100, Height = 100, Resolution = 1 }; // viewport.Center is (0, 0) at this point var limiter = new ViewportLimiter { PanLimits = new MRect(20, 40, 120, 140) // Minimal X value is 20, Minimal Y value is 40 }; // act limiter.LimitExtent(viewport, viewport.Extent); // assert Assert.AreEqual(viewport.Center.X, 20); Assert.AreEqual(viewport.Center.Y, 40); }
public void MapView_Touch(object sender, TouchEventArgs args) { if (_gestureDetector.OnTouchEvent(args.Event)) { return; } var touchPoints = GetMapPositions(args.Event, this); switch (args.Event.Action) { case MotionEventActions.Up: InvalidateCanvas(); _mode = TouchMode.None; _map.ViewChanged(true); break; case MotionEventActions.Down: case MotionEventActions.Pointer1Down: case MotionEventActions.Pointer2Down: case MotionEventActions.Pointer3Down: if (touchPoints.Count >= 2) { (_previousCenter, _previousRadius, _previousAngle) = GetPinchValues(touchPoints); _mode = TouchMode.Zooming; _innerRotation = _map.Viewport.Rotation; } else { _mode = TouchMode.Dragging; _previousCenter = touchPoints.First(); } break; case MotionEventActions.Pointer1Up: case MotionEventActions.Pointer2Up: case MotionEventActions.Pointer3Up: // Remove the touchPoint that was released from the locations to reset the // starting points of the move and rotation touchPoints.RemoveAt(args.Event.ActionIndex); if (touchPoints.Count >= 2) { (_previousCenter, _previousRadius, _previousAngle) = GetPinchValues(touchPoints); _mode = TouchMode.Zooming; _innerRotation = _map.Viewport.Rotation; } else { _mode = TouchMode.Dragging; _previousCenter = touchPoints.First(); } break; case MotionEventActions.Move: switch (_mode) { case TouchMode.Dragging: { if (touchPoints.Count != 1) { return; } var touchPosition = touchPoints.First(); if (_previousCenter != null && !_previousCenter.IsEmpty()) { _map.Viewport.Transform(touchPosition.X, touchPosition.Y, _previousCenter.X, _previousCenter.Y); ViewportLimiter.LimitExtent(_map.Viewport, _map.PanMode, _map.PanLimits, _map.Envelope); InvalidateCanvas(); } _previousCenter = touchPosition; } break; case TouchMode.Zooming: { if (touchPoints.Count < 2) { return; } var(prevCenter, prevRadius, prevAngle) = (_previousCenter, _previousRadius, _previousAngle); var(center, radius, angle) = GetPinchValues(touchPoints); double rotationDelta = 0; if (RotationLock) { _innerRotation += angle - prevAngle; _innerRotation %= 360; if (_innerRotation > 180) { _innerRotation -= 360; } else if (_innerRotation < -180) { _innerRotation += 360; } if (_map.Viewport.Rotation == 0 && Math.Abs(_innerRotation) >= Math.Abs(UnSnapRotationDegrees)) { rotationDelta = _innerRotation; } else if (_map.Viewport.Rotation != 0) { if (Math.Abs(_innerRotation) <= Math.Abs(ReSnapRotationDegrees)) { rotationDelta = -_map.Viewport.Rotation; } else { rotationDelta = _innerRotation - _map.Viewport.Rotation; } } } _map.Viewport.Transform(center.X, center.Y, prevCenter.X, prevCenter.Y, radius / prevRadius, rotationDelta); (_previousCenter, _previousRadius, _previousAngle) = (center, radius, angle); ViewportLimiter.Limit(_map.Viewport, _map.ZoomMode, _map.ZoomLimits, _map.Resolutions, _map.PanMode, _map.PanLimits, _map.Envelope); InvalidateCanvas(); } break; } break; } }
public override void TouchesMoved(NSSet touches, UIEvent evt) { base.TouchesMoved(touches, evt); if (evt.AllTouches.Count == 1) { if (touches.AnyObject is UITouch touch) { var currentPos = touch.LocationInView(this); var previousPos = touch.PreviousLocationInView(this); _map.Viewport.Transform(currentPos.X, currentPos.Y, previousPos.X, previousPos.Y); ViewportLimiter.LimitExtent(_map.Viewport, _map.PanMode, _map.PanLimits, _map.Envelope); RefreshGraphics(); } } else if (evt.AllTouches.Count >= 2) { var prevLocations = evt.AllTouches.Select(t => ((UITouch)t).PreviousLocationInView(this)) .Select(p => new Point(p.X, p.Y)).ToList(); var locations = evt.AllTouches.Select(t => ((UITouch)t).LocationInView(this)) .Select(p => new Point(p.X, p.Y)).ToList(); var(prevCenter, prevRadius, prevAngle) = GetPinchValues(prevLocations); var(center, radius, angle) = GetPinchValues(locations); double rotationDelta = 0; if (AllowPinchRotation) { _innerRotation += angle - prevAngle; _innerRotation %= 360; if (_innerRotation > 180) { _innerRotation -= 360; } else if (_innerRotation < -180) { _innerRotation += 360; } if (_map.Viewport.Rotation == 0 && Math.Abs(_innerRotation) >= Math.Abs(UnSnapRotationDegrees)) { rotationDelta = _innerRotation; } else if (_map.Viewport.Rotation != 0) { if (Math.Abs(_innerRotation) <= Math.Abs(ReSnapRotationDegrees)) { rotationDelta = -_map.Viewport.Rotation; } else { rotationDelta = _innerRotation - _map.Viewport.Rotation; } } } _map.Viewport.Transform(center.X, center.Y, prevCenter.X, prevCenter.Y, radius / prevRadius, rotationDelta); ViewportLimiter.Limit(_map.Viewport, _map.ZoomMode, _map.ZoomLimits, _map.Resolutions, _map.PanMode, _map.PanLimits, _map.Envelope); RefreshGraphics(); } }
public void MapView_Touch(object sender, TouchEventArgs args) { var x = (int)args.Event.RawX; var y = (int)args.Event.RawY; switch (args.Event.Action) { case MotionEventActions.Down: _previousMap = null; _mode = Dragging; break; case MotionEventActions.Up: _previousMap = null; _canvas.Invalidate(); _mode = None; _map.ViewChanged(true); Map.InvokeInfo(GetScreenPosition(args.Event), _scale, _renderer.SymbolCache); break; case MotionEventActions.Pointer2Down: _previousMap = null; _oldDist = Spacing(args.Event); MidPoint(_currentMid, args.Event); _previousMid = _currentMid; if (AllowPinchRotation) { _previousAngle = Angle(args.Event); } _mode = Zoom; break; case MotionEventActions.Pointer2Up: _previousMap = null; _previousMid = null; _mode = Dragging; break; case MotionEventActions.Move: switch (_mode) { case Dragging: _currentMap = new PointF(x, y); if (_previousMap != null) { _map.Viewport.Transform( _currentMap.X / _scale, _currentMap.Y / _scale, _previousMap.X / _scale, _previousMap.Y / _scale); ViewportLimiter.LimitExtent(_map.Viewport, _map.PanMode, _map.PanLimits, _map.Envelope); _canvas.Invalidate(); } _previousMap = _currentMap; break; case Zoom: { if (args.Event.PointerCount < 2) { return; } var newDist = Spacing(args.Event); var scale = newDist / _oldDist; _oldDist = Spacing(args.Event); _previousMid = new PointF(_currentMid.X, _currentMid.Y); MidPoint(_currentMid, args.Event); _map.Viewport.Transform( _currentMid.X / _scale, _currentMid.Y / _scale, _previousMid.X / _scale, _previousMid.Y / _scale, scale); if (AllowPinchRotation) { var angle = Angle(args.Event); _map.Viewport.Rotation += angle - _previousAngle; _previousAngle = angle; } ViewportLimiter.Limit(_map.Viewport, _map.ZoomMode, _map.ZoomLimits, _map.Resolutions, _map.PanMode, _map.PanLimits, _map.Envelope); _canvas.Invalidate(); } break; } break; } }
public void MapView_Touch(object sender, TouchEventArgs args) { var x = (int)args.Event.GetX(0); var y = (int)args.Event.GetY(0); switch (args.Event.Action) { case MotionEventActions.Down: _previousTouchPosition = null; _touchDownPosition = new PointF(x, y); _mode = Dragging; break; case MotionEventActions.Up: _canvas.Invalidate(); _mode = None; _map.ViewChanged(true); var position = GetScreenPosition(args.Event); Map.InvokeInfo(position, _touchDownPosition.ToMapsui(), _scale, _renderer.SymbolCache, WidgetTouch); break; case MotionEventActions.Pointer2Down: _previousTouchPosition = null; _oldDist = Spacing(args.Event); _touchCenter = GetTouchCenter(args.Event); _previousTouchCenter = _touchCenter; if (AllowPinchRotation) { _previousAngle = Angle(args.Event); } _touchDownPosition = _touchCenter; _mode = Zoom; break; case MotionEventActions.Pointer2Up: _previousTouchPosition = null; _previousTouchCenter = null; _mode = Dragging; break; case MotionEventActions.Move: switch (_mode) { case Dragging: _touchPosition = new PointF(x, y); if (_previousTouchPosition != null) { _map.Viewport.Transform( _touchPosition.X / _scale, _touchPosition.Y / _scale, _previousTouchPosition.X / _scale, _previousTouchPosition.Y / _scale); ViewportLimiter.LimitExtent(_map.Viewport, _map.PanMode, _map.PanLimits, _map.Envelope); _canvas.Invalidate(); } _previousTouchPosition = _touchPosition; break; case Zoom: { if (args.Event.PointerCount < 2) { return; } var newDist = Spacing(args.Event); var scale = newDist / _oldDist; _oldDist = Spacing(args.Event); _previousTouchCenter = new PointF(_touchCenter.X, _touchCenter.Y); _touchCenter = GetTouchCenter(args.Event); _map.Viewport.Transform( _touchCenter.X / _scale, _touchCenter.Y / _scale, _previousTouchCenter.X / _scale, _previousTouchCenter.Y / _scale, scale); if (AllowPinchRotation) { var angle = Angle(args.Event); _map.Viewport.Rotation += angle - _previousAngle; _previousAngle = angle; } ViewportLimiter.Limit(_map.Viewport, _map.ZoomMode, _map.ZoomLimits, _map.Resolutions, _map.PanMode, _map.PanLimits, _map.Envelope); _canvas.Invalidate(); } break; } break; } }
public void MapView_Touch(object sender, TouchEventArgs args) { switch (args.Event.Action) { case MotionEventActions.Down: _previousTouchPosition = null; _touchDownPosition = GetScreenPosition(args.Event, this); _mode = Dragging; break; case MotionEventActions.Up: _canvas.Invalidate(); _mode = None; _map.ViewChanged(true); var position = GetScreenPosition(args.Event, this); Map.InvokeInfo(position, _touchDownPosition, _scale, _renderer.SymbolCache, WidgetTouch); break; case MotionEventActions.Pointer2Down: _previousTouchPosition = null; _previousDistance = DistanceBetweenTouches(args.Event); _touchCenter = GetTouchCenter(args.Event, this); _previousTouchCenter = _touchCenter; if (AllowPinchRotation) { _previousAngle = Angle(args.Event); _innerRotation = _map.Viewport.Rotation; } _touchDownPosition = _touchCenter; _mode = Zoom; break; case MotionEventActions.Pointer2Up: _previousTouchPosition = null; _previousTouchCenter = null; _mode = Dragging; break; case MotionEventActions.Move: switch (_mode) { case Dragging: _touchPosition = GetScreenPosition(args.Event, this); if (_previousTouchPosition != null) { _map.Viewport.Transform( _touchPosition.X / _scale, _touchPosition.Y / _scale, _previousTouchPosition.X / _scale, _previousTouchPosition.Y / _scale); ViewportLimiter.LimitExtent(_map.Viewport, _map.PanMode, _map.PanLimits, _map.Envelope); _canvas.Invalidate(); } _previousTouchPosition = _touchPosition; break; case Zoom: { if (args.Event.PointerCount < 2) { return; } var distance = DistanceBetweenTouches(args.Event); var scale = distance / _previousDistance; _previousDistance = distance; _previousTouchCenter = _touchCenter; _touchCenter = GetTouchCenter(args.Event, this); _map.Viewport.Transform( _touchCenter.X / _scale, _touchCenter.Y / _scale, _previousTouchCenter.X / _scale, _previousTouchCenter.Y / _scale, scale); if (AllowPinchRotation) { var angle = Angle(args.Event); _innerRotation += angle - _previousAngle; _innerRotation %= 360; if (_innerRotation > 180) { _innerRotation -= 360; } else if (_innerRotation < -180) { _innerRotation += 360; } if (_map.Viewport.Rotation == 0 && Math.Abs(_innerRotation) >= Math.Abs(UnSnapRotationDegrees)) { _map.Viewport.Rotation = _innerRotation; } else if (_map.Viewport.Rotation != 0) { if (Math.Abs(_innerRotation) <= Math.Abs(ReSnapRotationDegrees)) { _map.Viewport.Rotation = 0; } else { _map.Viewport.Rotation = _innerRotation; } } _previousAngle = angle; } ViewportLimiter.Limit(_map.Viewport, _map.ZoomMode, _map.ZoomLimits, _map.Resolutions, _map.PanMode, _map.PanLimits, _map.Envelope); _canvas.Invalidate(); } break; } break; } }
/// <summary> /// Called, when mouse/finger/pen moves over map /// </summary> /// <param name="touchPoints">List of all touched points</param> private bool OnTouchMove(List <Geometries.Point> touchPoints) { var args = new TouchedEventArgs(touchPoints); TouchMove?.Invoke(this, args); if (args.Handled) { return(true); } switch (_mode) { case TouchMode.Dragging: { if (touchPoints.Count != 1) { return(false); } var touchPosition = touchPoints.First(); if (_previousCenter != null && !_previousCenter.IsEmpty()) { _map.Viewport.Transform(touchPosition.X, touchPosition.Y, _previousCenter.X, _previousCenter.Y); ViewportLimiter.LimitExtent(_map.Viewport, _map.PanMode, _map.PanLimits, _map.Envelope); InvalidateCanvas(); } _previousCenter = touchPosition; } break; case TouchMode.Zooming: { if (touchPoints.Count < 2) { return(false); } var(prevCenter, prevRadius, prevAngle) = (_previousCenter, _previousRadius, _previousAngle); var(center, radius, angle) = GetPinchValues(touchPoints); double rotationDelta = 0; if (RotationLock) { _innerRotation += angle - prevAngle; _innerRotation %= 360; if (_innerRotation > 180) { _innerRotation -= 360; } else if (_innerRotation < -180) { _innerRotation += 360; } if (_map.Viewport.Rotation == 0 && Math.Abs(_innerRotation) >= Math.Abs(UnSnapRotationDegrees)) { rotationDelta = _innerRotation; } else if (_map.Viewport.Rotation != 0) { if (Math.Abs(_innerRotation) <= Math.Abs(ReSnapRotationDegrees)) { rotationDelta = -_map.Viewport.Rotation; } else { rotationDelta = _innerRotation - _map.Viewport.Rotation; } } } _map.Viewport.Transform(center.X, center.Y, prevCenter.X, prevCenter.Y, radius / prevRadius, rotationDelta); (_previousCenter, _previousRadius, _previousAngle) = (center, radius, angle); ViewportLimiter.Limit(_map.Viewport, _map.ZoomMode, _map.ZoomLimits, _map.Resolutions, _map.PanMode, _map.PanLimits, _map.Envelope); InvalidateCanvas(); } break; } return(true); }
public void MapView_Touch(object sender, TouchEventArgs args) { try { if (_gestureDetector.OnTouchEvent(args.Event)) { return; } } catch (ObjectDisposedException e) { System.Diagnostics.Debug.WriteLine(e.Message); _gestureDetector = new GestureDetector(Context, new GestureDetector.SimpleOnGestureListener()); _gestureDetector.SingleTapConfirmed += OnSingleTapped; _gestureDetector.DoubleTap += OnDoubleTapped; Invalidate(); } var touchPoints = GetScreenPositions(args.Event, this); switch (args.Event.Action) { case MotionEventActions.Up: if (_mode == TouchMode.FeatureDrag) { StopFeatureDrag(args.Event); } RefreshGraphics(); _mode = TouchMode.None; RefreshData(); break; case MotionEventActions.Down: case MotionEventActions.Pointer1Down: case MotionEventActions.Pointer2Down: case MotionEventActions.Pointer3Down: if (_mode != TouchMode.FeatureDrag) { if (touchPoints.Count >= 2) { (_previousCenter, _previousRadius, _previousAngle) = GetPinchValues(touchPoints); _mode = TouchMode.Zooming; _innerRotation = Viewport.Rotation; } else { var mapInfoArgs = CheckStartDragHandled(args.Event); if (mapInfoArgs.Handled) { System.Diagnostics.Debug.WriteLine("Drag consumed!!"); _draggedFeature = mapInfoArgs.MapInfo.Feature; _mode = TouchMode.FeatureDrag; } else { _mode = TouchMode.Dragging; _previousCenter = touchPoints.First(); } } } break; case MotionEventActions.Pointer1Up: case MotionEventActions.Pointer2Up: case MotionEventActions.Pointer3Up: if (_mode != TouchMode.FeatureDrag) { // Remove the touchPoint that was released from the locations to reset the // starting points of the move and rotation touchPoints.RemoveAt(args.Event.ActionIndex); if (touchPoints.Count >= 2) { (_previousCenter, _previousRadius, _previousAngle) = GetPinchValues(touchPoints); _mode = TouchMode.Zooming; _innerRotation = Viewport.Rotation; } else { _mode = TouchMode.Dragging; _previousCenter = touchPoints.First(); } } break; case MotionEventActions.Move: switch (_mode) { case TouchMode.FeatureDrag: DragFeatureTo(args.Event); break; case TouchMode.Dragging: { if (touchPoints.Count != 1) { return; } var touchPosition = touchPoints.First(); if (_previousCenter != null && !_previousCenter.IsEmpty()) { _viewport.Transform(touchPosition.X, touchPosition.Y, _previousCenter.X, _previousCenter.Y); ViewportLimiter.LimitExtent(_viewport, _map.Limits.PanMode, _map.Limits.PanLimits, _map.Envelope); RefreshGraphics(); } _previousCenter = touchPosition; } break; case TouchMode.Zooming: { if (touchPoints.Count < 2) { return; } var(prevCenter, prevRadius, prevAngle) = (_previousCenter, _previousRadius, _previousAngle); var(center, radius, angle) = GetPinchValues(touchPoints); double rotationDelta = 0; if (!RotationLock) { _innerRotation += angle - prevAngle; _innerRotation %= 360; if (_innerRotation > 180) { _innerRotation -= 360; } else if (_innerRotation < -180) { _innerRotation += 360; } if (Viewport.Rotation == 0 && Math.Abs(_innerRotation) >= Math.Abs(UnSnapRotationDegrees)) { rotationDelta = _innerRotation; } else if (Viewport.Rotation != 0) { if (Math.Abs(_innerRotation) <= Math.Abs(ReSnapRotationDegrees)) { rotationDelta = -Viewport.Rotation; } else { rotationDelta = _innerRotation - Viewport.Rotation; } } } _viewport.Transform(center.X, center.Y, prevCenter.X, prevCenter.Y, radius / prevRadius, rotationDelta); (_previousCenter, _previousRadius, _previousAngle) = (center, radius, angle); ViewportLimiter.Limit(_viewport, _map.Limits.ZoomMode, _map.Limits.ZoomLimits, _map.Resolutions, _map.Limits.PanMode, _map.Limits.PanLimits, _map.Envelope); RefreshGraphics(); } break; } break; } }