/// <summary> /// Transforms the target using the specified view. /// </summary> /// <param name="target"></param> /// <param name="view">View.</param> protected override void Transform(Target2DWrapper <RenderContext> target, View2D view) { _view = view; _target = target; _toView = _view.CreateToViewPort(target.Width, target.Height); }
/// <summary> /// Transforms the canvas to the coordinate system of the view. /// </summary> /// <param name="view"></param> /// <param name="target"></param> protected override void Transform(Target2DWrapper <global::Android.Graphics.Canvas> target, View2D view) { _view = view; _target = target; _toViewPort = _view.CreateToViewPort(_target.Width, _target.Height); _fromViewPort = _view.CreateFromViewPort(_target.Width, _target.Height); }
/// <summary> /// Sets the layout. /// </summary> /// <param name="pixelsWidth">Pixels width.</param> /// <param name="pixelsHeight">Pixels height.</param> /// <param name="view">View.</param> /// <param name="projection">Projection.</param> internal override bool SetLayout(double pixelsWidth, double pixelsHeight, View2D view, IProjection projection) { base.SetLayout(pixelsWidth, pixelsHeight, view, projection); if (this.MoveWithMap) { // keep location the same and move with map. if (this.Location != null && _popupView != null) { // only set layout if there is a location set. var projected = projection.ToPixel(this.Location); var toView = view.CreateToViewPort(pixelsWidth, pixelsHeight); double locationPixelX, locationPixelY; // var locationPixel = view.ToViewPort(pixelsWidth, pixelsHeight, projected[0], projected[1]); toView.Apply(projected[0], projected[1], out locationPixelX, out locationPixelY); // set the new location depending on the size of the image and the alignment parameter. double leftPopupMargin = locationPixelX; double topPopupMargin = locationPixelY; leftPopupMargin = locationPixelX - (_popupView.LayoutParameters as FrameLayout.LayoutParams).Width / 2.0; switch (this.Alignment) { case MapControlAlignmentType.Center: topPopupMargin = locationPixelY - (this.View.LayoutParameters as FrameLayout.LayoutParams).Height / 2.0 - (_popupView.LayoutParameters as FrameLayout.LayoutParams).Height; break; case MapControlAlignmentType.CenterTop: topPopupMargin = locationPixelY - (_popupView.LayoutParameters as FrameLayout.LayoutParams).Height; break; case MapControlAlignmentType.CenterBottom: topPopupMargin = locationPixelY - (this.View.LayoutParameters as FrameLayout.LayoutParams).Height - (_popupView.LayoutParameters as FrameLayout.LayoutParams).Height; break; } // add offsets. leftPopupMargin = leftPopupMargin + _popupXOffset; topPopupMargin = topPopupMargin + _popupYOffset; (_popupView.LayoutParameters as FrameLayout.LayoutParams).LeftMargin = (int)leftPopupMargin; (_popupView.LayoutParameters as FrameLayout.LayoutParams).TopMargin = (int)topPopupMargin; _popupLayoutSet = true; } } return(true); }
/// <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); var toViewPort = view.CreateToViewPort(view.Width, view.Height); double mapCenterPixelsX, mapCenterPixelsY; toViewPort.Apply(mapCenterSceneCoords[0], mapCenterSceneCoords[1], out mapCenterPixelsX, out mapCenterPixelsY); //double[] mapCenterPixels = view.ToViewPort(view.Width, view.Height, mapCenterSceneCoords[0], mapCenterSceneCoords[1]); var fromViewPort = view.CreateFromViewPort(view.Height, view.Width); double leftScene, topScene, rightScene, bottomScene; fromViewPort.Apply(mapCenterPixelsX - (view.Width) / 2.0, mapCenterPixelsY - (view.Height) / 2.0, out leftScene, out topScene); //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(leftScene, topScene); //GeoCoordinate topLeft = this.Projection.ToGeoCoordinates(topLeftSceneCoordinates[0], topLeftSceneCoordinates[1]); fromViewPort.Apply(mapCenterPixelsX + (view.Width) / 2.0, mapCenterPixelsY + (view.Height) / 2.0, out rightScene, out bottomScene); //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(rightScene, bottomScene); // 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> /// Notifies the current view has changed. /// </summary> public override void NotifyChange(View2D view, double zoom) { lock (this) { _currentView = view; _currentZoom = zoom; // reset the timer. if (_timer == null) { // create the timer. _timer = new System.Threading.Timer(this.StaticDetectionCallback, null, StaticDetectionTriggerMillis, System.Threading.Timeout.Infinite); } else { // change the timer. _timer.Change(StaticDetectionTriggerMillis, System.Threading.Timeout.Infinite); } // no rendering was successful up until now, only start invalidating after first successful render. if (_latestTriggeredView == null) { return; } // detect changes by % of view pan. var toView = _latestTriggeredView.CreateToViewPort(100, 100); double newCenterX, newCenterY; toView.Apply(view.Center[0], view.Center[1], out newCenterX, out newCenterY); //double[] newCenter = _latestTriggeredView.ToViewPort(100, 100, view.Center[0], view.Center[1]); newCenterX = System.Math.Abs(newCenterX - 50.0); newCenterY = System.Math.Abs(newCenterY - 50.0); if (newCenterX > PanPercentage || newCenterY > PanPercentage) { // the pan percentage change was detected. if (this.LatestRenderingFinished || !_latestTriggeredView.Rectangle.Overlaps(view.Rectangle)) { // the last rendering was finished or the latest triggered view does not overlap with the current rendering. OsmSharp.Logging.Log.TraceEvent("DefaultTrigger", Logging.TraceEventType.Information, "Rendering triggered: Pan detection."); this.Render(); } return; } // detect changes by angle offset. double angleDifference = System.Math.Abs(_latestTriggeredView.Angle.SmallestDifference(view.Angle)); if (angleDifference > DegreeOffset) { // the angle difference change was detected. if (this.LatestRenderingFinished || !_latestTriggeredView.Rectangle.Overlaps(view.Rectangle)) { // the last rendering was finished or the latest triggered view does not overlap with the current rendering. OsmSharp.Logging.Log.TraceEvent("DefaultTrigger", Logging.TraceEventType.Information, "Rendering triggered: Angle detection."); this.Render(); } return; } // detect changes by zoom offset. double zoomDifference = System.Math.Abs(_latestTriggeredZoom - _currentZoom); if (zoomDifference > ZoomOffset) { // the zoom difference change was detected. if (this.LatestRenderingFinished || !_latestTriggeredView.Rectangle.Overlaps(view.Rectangle)) { // the last rendering was finished or the latest triggered view does not overlap with the current rendering. OsmSharp.Logging.Log.TraceEvent("DefaultTrigger", Logging.TraceEventType.Information, "Rendering triggered: Zoom detection."); this.Render(); } return; } } }