protected override void OnRender(DrawingContext drawingContext) { if (ParentMap != null) { var x1 = Padding.Left + StrokeThickness / 2d; var x2 = size.Width - Padding.Right - StrokeThickness / 2d; var y1 = size.Height / 2d; var y2 = size.Height - Padding.Bottom - StrokeThickness / 2d; var text = length >= 1000d ? string.Format("{0:0} km", length / 1000d) : string.Format("{0:0} m", length); drawingContext.DrawRectangle(Background ?? ParentMap.Background, null, new Rect(size)); drawingContext.DrawLine(Pen, new Point(x1, y1), new Point(x1, y2)); drawingContext.DrawLine(Pen, new Point(x2, y1), new Point(x2, y2)); drawingContext.DrawLine(Pen, new Point(x1, y2), new Point(x2, y2)); drawingContext.DrawGlyphRun(Foreground, GlyphRunText.Create(text, Typeface, FontSize, new Vector(size.Width / 2d, y1 - StrokeThickness - 1d))); } }
protected override void OnRender(DrawingContext drawingContext) { if (ParentMap != null) { var bounds = ParentMap.ViewportTransform.Inverse.TransformBounds(new Rect(ParentMap.RenderSize)); var start = ParentMap.MapTransform.Transform(new Point(bounds.X, bounds.Y)); var end = ParentMap.MapTransform.Transform(new Point(bounds.X + bounds.Width, bounds.Y + bounds.Height)); var minSpacing = MinLineSpacing * 360d / (Math.Pow(2d, ParentMap.ZoomLevel) * TileSource.TileSize); var spacing = LineSpacings[LineSpacings.Length - 1]; if (spacing >= minSpacing) { spacing = LineSpacings.FirstOrDefault(s => s >= minSpacing); } var labelFormat = spacing < 1d ? "{0} {1}°{2:00}'" : "{0} {1}°"; var labelStart = new Location( Math.Ceiling(start.Latitude / spacing) * spacing, Math.Ceiling(start.Longitude / spacing) * spacing); var latLabels = new List <Label>((int)((end.Latitude - labelStart.Latitude) / spacing) + 1); var lonLabels = new List <Label>((int)((end.Longitude - labelStart.Longitude) / spacing) + 1); for (var lat = labelStart.Latitude; lat <= end.Latitude; lat += spacing) { latLabels.Add(new Label(lat, CoordinateString(lat, labelFormat, "NS"))); drawingContext.DrawLine(Pen, ParentMap.LocationToViewportPoint(new Location(lat, start.Longitude)), ParentMap.LocationToViewportPoint(new Location(lat, end.Longitude))); } for (var lon = labelStart.Longitude; lon <= end.Longitude; lon += spacing) { lonLabels.Add(new Label(lon, CoordinateString(Location.NormalizeLongitude(lon), labelFormat, "EW"))); drawingContext.DrawLine(Pen, ParentMap.LocationToViewportPoint(new Location(start.Latitude, lon)), ParentMap.LocationToViewportPoint(new Location(end.Latitude, lon))); } if (Foreground != null && Foreground != Brushes.Transparent && latLabels.Count > 0 && lonLabels.Count > 0) { var latLabelOrigin = new Point(StrokeThickness / 2d + 2d, -StrokeThickness / 2d - FontSize / 4d); var lonLabelOrigin = new Point(StrokeThickness / 2d + 2d, StrokeThickness / 2d + FontSize); var transform = Matrix.Identity; transform.Rotate(ParentMap.Heading); foreach (var latLabel in latLabels) { foreach (var lonLabel in lonLabels) { GlyphRun latGlyphRun; GlyphRun lonGlyphRun; if (!glyphRuns.TryGetValue(latLabel.Text, out latGlyphRun)) { latGlyphRun = GlyphRunText.Create(latLabel.Text, Typeface, FontSize, latLabelOrigin); glyphRuns.Add(latLabel.Text, latGlyphRun); } if (!glyphRuns.TryGetValue(lonLabel.Text, out lonGlyphRun)) { lonGlyphRun = GlyphRunText.Create(lonLabel.Text, Typeface, FontSize, lonLabelOrigin); glyphRuns.Add(lonLabel.Text, lonGlyphRun); } var position = ParentMap.LocationToViewportPoint(new Location(latLabel.Position, lonLabel.Position)); drawingContext.PushTransform(new MatrixTransform( transform.M11, transform.M12, transform.M21, transform.M22, position.X, position.Y)); drawingContext.DrawGlyphRun(Foreground, latGlyphRun); drawingContext.DrawGlyphRun(Foreground, lonGlyphRun); drawingContext.Pop(); } } var removeKeys = glyphRuns.Keys.Where(k => !latLabels.Any(l => l.Text == k) && !lonLabels.Any(l => l.Text == k)); foreach (var key in removeKeys.ToList()) { glyphRuns.Remove(key); } } else { glyphRuns.Clear(); } } }