public bool SetBounds(MapProjection projection, Size viewportSize) { // bounds in tile pixels from viewport size // var bounds = projection.GetTileBounds(TileMatrix.Scale, TileMatrix.TopLeft, viewportSize); // tile column and row index bounds // var xMin = (int)Math.Floor(bounds.X / TileMatrix.TileWidth); var yMin = (int)Math.Floor(bounds.Y / TileMatrix.TileHeight); var xMax = (int)Math.Floor((bounds.X + bounds.Width) / TileMatrix.TileWidth); var yMax = (int)Math.Floor((bounds.Y + bounds.Height) / TileMatrix.TileHeight); xMin = Math.Max(xMin, 0); yMin = Math.Max(yMin, 0); xMax = Math.Min(Math.Max(xMax, 0), TileMatrix.MatrixWidth - 1); yMax = Math.Min(Math.Max(yMax, 0), TileMatrix.MatrixHeight - 1); if (XMin == xMin && YMin == yMin && XMax == xMax && YMax == yMax) { return(false); } XMin = xMin; YMin = yMin; XMax = xMax; YMax = yMax; return(true); }
/// <summary> /// Changes the Center property according to the specified map translation in viewport coordinates. /// </summary> public void TranslateMap(Point translation) { if (transformCenter != null) { ResetTransformCenter(); UpdateTransform(); } if (translation.X != 0d || translation.Y != 0d) { if (Heading != 0d) { var cos = Math.Cos(Heading / 180d * Math.PI); var sin = Math.Sin(Heading / 180d * Math.PI); translation = new Point( translation.X * cos + translation.Y * sin, translation.Y * cos - translation.X * sin); } translation.X = -translation.X; translation.Y = -translation.Y; Center = MapProjection.TranslateLocation(Center, translation); } }
private void TargetCenterPropertyChanged(Location targetCenter) { if (!internalPropertyChange) { AdjustCenterProperty(TargetCenterProperty, ref targetCenter); if (!targetCenter.Equals(Center)) { if (centerAnimation != null) { centerAnimation.Completed -= CenterAnimationCompleted; } // animate private CenterPoint property by PointAnimation centerAnimation = new PointAnimation { From = MapProjection.LocationToPoint(Center), To = MapProjection.LocationToPoint(new Location( targetCenter.Latitude, Location.NearestLongitude(targetCenter.Longitude, Center.Longitude))), Duration = AnimationDuration, EasingFunction = AnimationEasingFunction }; centerAnimation.Completed += CenterAnimationCompleted; this.BeginAnimation(CenterPointProperty, centerAnimation); } } }
/// <summary> /// Changes the Center, Heading and ZoomLevel properties according to the specified /// viewport coordinate translation, rotation and scale delta values. Rotation and scaling /// is performed relative to the specified center point in viewport coordinates. /// </summary> public void TransformMap(Point center, Vector translation, double rotation, double scale) { if (rotation != 0d || scale != 1d) { transformCenter = MapProjection.ViewportPointToLocation(center); viewportCenter = center + translation; if (rotation != 0d) { var heading = (((Heading + rotation) % 360d) + 360d) % 360d; SetValueInternal(HeadingProperty, heading); SetValueInternal(TargetHeadingProperty, heading); } if (scale != 1d) { var zoomLevel = Math.Min(Math.Max(ZoomLevel + Math.Log(scale, 2d), MinZoomLevel), MaxZoomLevel); SetValueInternal(ZoomLevelProperty, zoomLevel); SetValueInternal(TargetZoomLevelProperty, zoomLevel); } UpdateTransform(true); } else { TranslateMap(translation); // more precise } }
public void SetRenderTransform(MapProjection projection) { // tile grid origin in pixels // var tileGridOrigin = new Point(TileMatrix.TileWidth * XMin, TileMatrix.TileHeight * YMin); ((MatrixTransform)RenderTransform).Matrix = projection.CreateTileLayerTransform(TileMatrix.Scale, TileMatrix.TopLeft, tileGridOrigin); }
/// <summary> /// Sets the TargetZoomLevel and TargetCenter properties so that the specified bounding box /// fits into the current view. The TargetHeading property is set to zero. /// </summary> public void ZoomToBounds(BoundingBox boundingBox) { var rect = MapProjection.BoundingBoxToRect(boundingBox); var center = new Point(rect.X + rect.Width / 2d, rect.Y + rect.Height / 2d); var scale = Math.Min(RenderSize.Width / rect.Width, RenderSize.Height / rect.Height); TargetZoomLevel = ViewTransform.ScaleToZoomLevel(scale); TargetCenter = MapProjection.MapToLocation(center); TargetHeading = 0d; }
private void CenterPointPropertyChanged(Point centerPoint) { if (!internalPropertyChange) { var center = MapProjection.PointToLocation(centerPoint); center.Longitude = Location.NormalizeLongitude(center.Longitude); InternalSetValue(CenterProperty, center); UpdateTransform(); } }
/// <summary> /// Sets the TargetZoomLevel and TargetCenter properties so that the specified bounding box /// fits into the current viewport. The TargetHeading property is set to zero. /// </summary> public void ZoomToBounds(BoundingBox boundingBox) { var rect = MapProjection.BoundingBoxToRect(boundingBox); var center = new Point(rect.X + rect.Width / 2d, rect.Y + rect.Height / 2d); var scale = Math.Min(RenderSize.Width / rect.Width, RenderSize.Height / rect.Height) * MapProjection.TrueScale / MapProjection.PixelPerDegree; TargetZoomLevel = Math.Log(scale, 2d); TargetCenter = MapProjection.PointToLocation(center); TargetHeading = 0d; }
private void CenterAnimationCompleted(object sender, object e) { if (centerAnimation != null) { centerAnimation.Completed -= CenterAnimationCompleted; centerAnimation = null; InternalSetValue(CenterProperty, TargetCenter); InternalSetValue(CenterPointProperty, MapProjection.LocationToPoint(TargetCenter)); UpdateTransform(); } }
private void DrawCylindricalGraticule(DrawingContext drawingContext, MapProjection projection, double lineDistance, string labelFormat) { var boundingBox = projection.ViewportRectToBoundingBox(new Rect(ParentMap.RenderSize)); if (boundingBox.HasValidBounds) { var latLabelStart = Math.Ceiling(boundingBox.South / lineDistance) * lineDistance; var lonLabelStart = Math.Ceiling(boundingBox.West / lineDistance) * lineDistance; var latLabels = new List <Label>((int)((boundingBox.North - latLabelStart) / lineDistance) + 1); var lonLabels = new List <Label>((int)((boundingBox.East - lonLabelStart) / lineDistance) + 1); var typeface = new Typeface(FontFamily, FontStyle, FontWeight, FontStretch); var pixelsPerDpi = VisualTreeHelper.GetDpi(this).PixelsPerDip; var pen = CreatePen(); for (var lat = latLabelStart; lat <= boundingBox.North; lat += lineDistance) { latLabels.Add(new Label(lat, new FormattedText( GetLabelText(lat, labelFormat, "NS"), CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeface, FontSize, Foreground, pixelsPerDpi))); drawingContext.DrawLine(pen, projection.LocationToViewportPoint(new Location(lat, boundingBox.West)), projection.LocationToViewportPoint(new Location(lat, boundingBox.East))); } for (var lon = lonLabelStart; lon <= boundingBox.East; lon += lineDistance) { lonLabels.Add(new Label(lon, new FormattedText( GetLabelText(Location.NormalizeLongitude(lon), labelFormat, "EW"), CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeface, FontSize, Foreground, pixelsPerDpi))); drawingContext.DrawLine(pen, projection.LocationToViewportPoint(new Location(boundingBox.South, lon)), projection.LocationToViewportPoint(new Location(boundingBox.North, lon))); } foreach (var latLabel in latLabels) { foreach (var lonLabel in lonLabels) { var position = projection.LocationToViewportPoint(new Location(latLabel.Position, lonLabel.Position)); drawingContext.PushTransform(new RotateTransform(ParentMap.Heading, position.X, position.Y)); drawingContext.DrawText(latLabel.Text, new Point(position.X + StrokeThickness / 2d + 2d, position.Y - StrokeThickness / 2d - latLabel.Text.Height)); drawingContext.DrawText(lonLabel.Text, new Point(position.X + StrokeThickness / 2d + 2d, position.Y + StrokeThickness / 2d)); drawingContext.Pop(); } } } }
private void SetRenderTransform() { var tileScale = (double)(1 << TileGrid.ZoomLevel); var scale = Math.Pow(2d, parentMap.ZoomLevel) / tileScale; var tileCenter = new Point(tileScale * (0.5 + parentMap.Center.Longitude / 360d), tileScale * (0.5 - WebMercatorProjection.LatitudeToY(parentMap.Center.Latitude) / 360d)); var tileOrigin = new Point(MapProjection.TileSize * (tileCenter.X - TileGrid.XMin), MapProjection.TileSize * (tileCenter.Y - TileGrid.YMin)); var viewCenter = new Point(parentMap.RenderSize.Width / 2d, parentMap.RenderSize.Height / 2d); ((MatrixTransform)RenderTransform).Matrix = MapProjection.CreateTransformMatrix(tileOrigin, scale, parentMap.Heading, viewCenter); }
/// <summary> /// Changes the Center property according to the specified translation in viewport coordinates. /// </summary> public void TranslateMap(Vector translation) { if (transformCenter != null) { ResetTransformCenter(); UpdateTransform(); } if (translation.X != 0d || translation.Y != 0d) { Center = MapProjection.ViewportPointToLocation(viewportCenter - translation); } }
private void CenterPropertyChanged(Location center) { if (!internalPropertyChange) { AdjustCenterProperty(CenterProperty, ref center); UpdateTransform(); if (centerAnimation == null) { InternalSetValue(TargetCenterProperty, center); InternalSetValue(CenterPointProperty, MapProjection.LocationToPoint(center)); } } }
/// <summary> /// Transforms a Rect in view coordinates to a BoundingBox in geographic coordinates. /// </summary> public BoundingBox ViewRectToBoundingBox(Rect rect) { var p1 = ViewTransform.ViewToMap(new Point(rect.X, rect.Y)); var p2 = ViewTransform.ViewToMap(new Point(rect.X, rect.Y + rect.Height)); var p3 = ViewTransform.ViewToMap(new Point(rect.X + rect.Width, rect.Y)); var p4 = ViewTransform.ViewToMap(new Point(rect.X + rect.Width, rect.Y + rect.Height)); rect.X = Math.Min(p1.X, Math.Min(p2.X, Math.Min(p3.X, p4.X))); rect.Y = Math.Min(p1.Y, Math.Min(p2.Y, Math.Min(p3.Y, p4.Y))); rect.Width = Math.Max(p1.X, Math.Max(p2.X, Math.Max(p3.X, p4.X))) - rect.X; rect.Height = Math.Max(p1.Y, Math.Max(p2.Y, Math.Max(p3.Y, p4.Y))) - rect.Y; return(MapProjection.RectToBoundingBox(rect)); }
/// <summary> /// Sets the TargetZoomLevel and TargetCenter properties so that the specified bounding box /// fits into the current viewport. The TargetHeading property is set to zero. /// </summary> public void ZoomToBounds(BoundingBox boundingBox) { if (boundingBox != null && boundingBox.HasValidBounds) { var rect = MapProjection.BoundingBoxToRect(boundingBox); var center = new Point(rect.X + rect.Width / 2d, rect.Y + rect.Height / 2d); var scale0 = 1d / MapProjection.GetViewportScale(0d); var lonScale = scale0 * RenderSize.Width / rect.Width; var latScale = scale0 * RenderSize.Height / rect.Height; var lonZoom = Math.Log(lonScale, 2d); var latZoom = Math.Log(latScale, 2d); TargetZoomLevel = Math.Min(lonZoom, latZoom); TargetCenter = MapProjection.PointToLocation(center); TargetHeading = 0d; } }
private ImageSource GetImage(MapProjection projection, IEnumerable <IMapDrawingItem> items) { var scale = ParentMap.ViewTransform.Scale; var rotation = ParentMap.ViewTransform.Rotation; var mapRect = projection.BoundingBoxToRect(BoundingBox); var imageRect = new Rect(0, 0, scale * mapRect.Width, scale * mapRect.Height); var drawings = new DrawingGroup(); foreach (var item in items) { var positions = item.Locations.Select(l => projection.LocationToMap(l)).ToList(); if (positions.Any(p => mapRect.Contains(p))) { for (int i = 0; i < positions.Count; i++) { positions[i] = new Point(scale * (positions[i].X - mapRect.X), imageRect.Height - scale * (positions[i].Y - mapRect.Y)); } drawings.Children.Add(item.GetDrawing(positions, scale, rotation)); } } var drawingBrush = new DrawingBrush { Drawing = drawings, ViewboxUnits = BrushMappingMode.Absolute, Viewbox = imageRect, }; var drawing = new GeometryDrawing { Geometry = new RectangleGeometry(imageRect), Brush = drawingBrush }; var image = new DrawingImage(drawing); image.Freeze(); return(image); }
private TileGrid GetTileGrid() { var tileZoomLevel = Math.Max(0, (int)Math.Round(parentMap.ZoomLevel + ZoomLevelOffset)); var tileScale = (double)(1 << tileZoomLevel); var scale = tileScale / (Math.Pow(2d, parentMap.ZoomLevel) * MapProjection.TileSize); var tileCenter = new Point(tileScale * (0.5 + parentMap.Center.Longitude / 360d), tileScale * (0.5 - WebMercatorProjection.LatitudeToY(parentMap.Center.Latitude) / 360d)); var viewCenter = new Point(parentMap.RenderSize.Width / 2d, parentMap.RenderSize.Height / 2d); var transform = new MatrixTransform { Matrix = MapProjection.CreateTransformMatrix(viewCenter, scale, -parentMap.Heading, tileCenter) }; var bounds = transform.TransformBounds(new Rect(0d, 0d, parentMap.RenderSize.Width, parentMap.RenderSize.Height)); return(new TileGrid(tileZoomLevel, (int)Math.Floor(bounds.X), (int)Math.Floor(bounds.Y), (int)Math.Floor(bounds.X + bounds.Width), (int)Math.Floor(bounds.Y + bounds.Height))); }
private double GetLineDistance() { var minDistance = MinLineDistance / MapProjection.DegreesToViewportScale(ParentMap.ZoomLevel); var scale = 1d; if (minDistance < 1d) { scale = minDistance < 1d / 60d ? 3600d : 60d; minDistance *= scale; } var lineDistances = new double[] { 1d, 2d, 5d, 10d, 15d, 30d, 60d }; var i = 0; while (i < lineDistances.Length - 1 && lineDistances[i] < minDistance) { i++; } return(lineDistances[i] / scale); }
/// <summary> /// Sets a temporary center point in viewport coordinates for scaling and rotation transformations. /// This center point is automatically reset when the Center property is set by application code. /// </summary> public void SetTransformCenter(Point center) { transformCenter = MapProjection.ViewportPointToLocation(center); viewportCenter = center; }
/// <summary> /// Transforms a Point in viewport coordinates to a Location in geographic coordinates. /// </summary> public Location ViewportPointToLocation(Point point) { return(MapProjection.ViewportPointToLocation(point)); }
/// <summary> /// Transforms a Location in geographic coordinates to a Point in viewport coordinates. /// </summary> public Point LocationToViewportPoint(Location location) { return(MapProjection.LocationToViewportPoint(location)); }
/// <summary> /// Transforms a Location in geographic coordinates to a Point in view coordinates. /// </summary> public Point LocationToView(Location location) { return(ViewTransform.MapToView(MapProjection.LocationToMap(location))); }
/// <summary> /// Transforms a Point in view coordinates to a Location in geographic coordinates. /// </summary> public Location ViewToLocation(Point point) { return(MapProjection.MapToLocation(ViewTransform.ViewToMap(point))); }
protected virtual string GetBboxParam(MapProjection projection, Rect mapRect) { return("BBOX=" + projection.GetBboxValue(mapRect)); }
protected virtual string GetCrsParam(MapProjection projection) { return("CRS=" + projection.GetCrsValue()); }
/// <summary> /// Gets the horizontal and vertical scaling factors from cartesian map coordinates to view /// coordinates at the specified location, i.e. pixels per meter. /// </summary> public Vector GetScale(Location location) { var projectionScale = MapProjection.GetRelativeScale(location); return(ViewTransform.Scale * projectionScale); }
/// <summary> /// Gets the horizontal and vertical scaling factors from cartesian map coordinates to view /// coordinates at the specified location, i.e. pixels per meter. /// </summary> public Vector GetScale(Location location) { return(ViewTransform.Scale * MapProjection.GetRelativeScale(location)); }