/// <summary> /// Calculates the ViewPortTransfrom for the Current Heading and ViewPortCenter. /// Invalidates the ViewPort to schedule a redraw. /// </summary> protected virtual void UpdateViewPortTransform() { if (ViewPortTransform == null) { return; } double scaleFactor = ViewPortProjection.GetZoomFactor(ZoomLevel); double w2 = ActualWidth / 2d; double h2 = ActualHeight / 2d; MatrixDouble vpCenterTranslation = MatrixDouble.CreateTranslation(w2, h2); MatrixDouble scale = MatrixDouble.CreateScale(scaleFactor); MatrixDouble mapCenterTranslation = MatrixDouble.CreateTranslation(-ViewPortCenter.X, -ViewPortCenter.Y); double heading = Heading * Math.PI / 180.0; Point center = new Point(ViewPortCenter.X, ViewPortCenter.Y); MatrixDouble mapRotation = MatrixDouble.CreateRotation(heading, center); MatrixDouble objectRotation = MatrixDouble.CreateRotation(heading); ViewPortTransform.Matrix = (mapRotation * mapCenterTranslation * scale * vpCenterTranslation).ToXamlMatrix(); ScaleRotateTransform.Matrix = (objectRotation * scale).ToXamlMatrix(); ScaleTransform.Matrix = scale.ToXamlMatrix(); RotateTransform.Matrix = objectRotation.ToXamlMatrix(); TranslationTransform.Matrix = (mapCenterTranslation * vpCenterTranslation).ToXamlMatrix(); InvalidateArrange(); OnViewPortChangedEvent(); }
protected virtual void OnMapCenterChanged(ILocation newCenter) { MapCenterChangedEvent?.Invoke(this, newCenter); if (ViewPortProjection != null) { _viewPortCenter = ViewPortProjection.ToCartesian(MapCenter); UpdateViewPortTransform(); } }
public CartesianPoint GetCartesianFromPoint(Point point) { double zoomFactor = 1 / ViewPortProjection.GetZoomFactor(ZoomLevel); double x = (point.X - RenderSize.Width / 2d) * zoomFactor + ViewPortCenter.X; double y = (point.Y - RenderSize.Height / 2d) * zoomFactor + ViewPortCenter.Y; MatrixDouble reverseRotationMatrix = MatrixDouble.CreateRotation(-TransformHelper.DegToRad(Heading), ViewPortCenter.ToPoint()); return(new CartesianPoint(reverseRotationMatrix.Transform(new Point(x, y)))); }
/// <summary> /// This Method can be use to convert a Point on the Map to a Location (in the current Projection). /// </summary> /// <param name="point">A Position on the MapControl (such as the MousePointer)</param> /// <returns>The location in the current Projection.</returns> public ILocation GetLocationFromPoint(Point point) { try { Point cartesianLocation = ViewPortTransform.Inverse.TransformPoint(point); ILocation position = ViewPortProjection.ToLocation(new CartesianPoint(cartesianLocation)); return(position); } catch (COMException) { //Inverse Matrix does not exist... return(new Wgs84Location()); } }
/// <summary> /// This function calculates the smallest axis-aligned bounding box possible for the current ViewPort. /// This means that if the current Map has a Heading that is not a multiple of 90° /// this function will a bounding box that is bigger than the actual ViewPort. /// </summary> public virtual Rect GetViewportBounds() { double zoomFactor = ViewPortProjection.GetZoomFactor(ZoomLevel); double halfHeight = RenderSize.Height / (2 * zoomFactor); double halfWidth = RenderSize.Width / (2 * zoomFactor); Point topLeft = new Point(ViewPortCenter.X - halfWidth, ViewPortCenter.Y - halfHeight); Point bottomRight = new Point(ViewPortCenter.X + halfWidth, ViewPortCenter.Y + halfHeight); RotateTransform rotation = new RotateTransform { Angle = Heading, CenterY = ViewPortCenter.Y, CenterX = ViewPortCenter.X }; Rect rect = new Rect(topLeft, bottomRight); rect = rotation.TransformBounds(rect); return(rect); }