mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2026-04-06 15:05:50 +00:00
Update map grids
This commit is contained in:
parent
80252cbfd0
commit
a7e7442d44
6 changed files with 113 additions and 52 deletions
|
|
@ -1,6 +1,7 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Documents;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Media;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
|
@ -80,8 +81,20 @@ namespace MapControl
|
|||
{
|
||||
var text = new FormattedText(label.Text,
|
||||
CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeface, FontSize, Foreground);
|
||||
var x = label.X + StrokeThickness / 2d + 2d;
|
||||
var y = label.Y - text.Height / 2d;
|
||||
var x = label.X +
|
||||
label.HorizontalAlignment switch
|
||||
{
|
||||
HorizontalAlignment.Left => 2d,
|
||||
HorizontalAlignment.Right => -text.Width - 2d,
|
||||
_ => -text.Width / 2d
|
||||
};
|
||||
var y = label.Y +
|
||||
label.VerticalAlignment switch
|
||||
{
|
||||
VerticalAlignment.Top => 0,
|
||||
VerticalAlignment.Bottom => -text.Height,
|
||||
_ => -text.Height / 2d
|
||||
};
|
||||
|
||||
if (label.Rotation != 0d)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@ using System.Linq;
|
|||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
#elif UWP
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Media;
|
||||
#elif WINUI
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
#elif AVALONIA
|
||||
using Avalonia;
|
||||
using Avalonia.Layout;
|
||||
using PathFigureCollection = Avalonia.Media.PathFigures;
|
||||
#endif
|
||||
|
||||
|
|
@ -74,6 +77,13 @@ namespace MapControl
|
|||
var p1 = ParentMap.LocationToView(lat, southWest.Longitude);
|
||||
var p2 = ParentMap.LocationToView(lat, northEast.Longitude);
|
||||
figures.Add(CreateLineFigure(p1, p2));
|
||||
|
||||
if (ParentMap.ViewTransform.Rotation == 0d)
|
||||
{
|
||||
var text = GetLatitudeLabelText(lat, labelFormat);
|
||||
labels.Add(new Label(text, p1.X, p1.Y, 0d, HorizontalAlignment.Left, VerticalAlignment.Bottom));
|
||||
labels.Add(new Label(text, p2.X, p2.Y, 0d, HorizontalAlignment.Right, VerticalAlignment.Bottom));
|
||||
}
|
||||
}
|
||||
|
||||
for (var lon = minLon; lon <= northEast.Longitude; lon += lineDistance)
|
||||
|
|
@ -82,9 +92,18 @@ namespace MapControl
|
|||
var p2 = ParentMap.LocationToView(northEast.Latitude, lon);
|
||||
figures.Add(CreateLineFigure(p1, p2));
|
||||
|
||||
for (var lat = minLat; lat <= northEast.Latitude; lat += lineDistance)
|
||||
if (ParentMap.ViewTransform.Rotation == 0d)
|
||||
{
|
||||
AddLabel(labels, labelFormat, lat, lon, ParentMap.LocationToView(lat, lon), 0d);
|
||||
var text = GetLongitudeLabelText(lon, labelFormat);
|
||||
labels.Add(new Label(text, p1.X, p1.Y, 0d, HorizontalAlignment.Left, VerticalAlignment.Bottom));
|
||||
labels.Add(new Label(text, p2.X, p2.Y, 0d, HorizontalAlignment.Left, VerticalAlignment.Top));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var lat = minLat; lat <= northEast.Latitude; lat += lineDistance)
|
||||
{
|
||||
AddLabel(labels, labelFormat, lat, lon, ParentMap.LocationToView(lat, lon), 0d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -125,8 +144,14 @@ namespace MapControl
|
|||
maxLon += lineDistance;
|
||||
}
|
||||
|
||||
minLat = Math.Ceiling(minLat / lineDistance) * lineDistance;
|
||||
maxLat = Math.Floor(maxLat / lineDistance) * lineDistance;
|
||||
if (pointDistance < lineDistance)
|
||||
{
|
||||
minLat = Math.Ceiling(minLat / lineDistance - 1e-6) * lineDistance;
|
||||
maxLat = Math.Floor(maxLat / lineDistance + 1e-6) * lineDistance;
|
||||
}
|
||||
|
||||
maxLat += 1e-6;
|
||||
maxLon += 1e-6;
|
||||
|
||||
for (var lat = minLat; lat <= maxLat; lat += lineDistance)
|
||||
{
|
||||
|
|
@ -209,27 +234,37 @@ namespace MapControl
|
|||
rotation -= 180d;
|
||||
}
|
||||
|
||||
var text = GetLabelText(lat, labelFormat, "NS") +
|
||||
"\n" + GetLabelText(Location.NormalizeLongitude(lon), labelFormat, "EW");
|
||||
var text = GetLatitudeLabelText(lat, labelFormat) +
|
||||
"\n" + GetLongitudeLabelText(lon, labelFormat);
|
||||
|
||||
labels.Add(new Label(text, position.X, position.Y, rotation));
|
||||
}
|
||||
}
|
||||
|
||||
static string GetLabelText(double value, string labelFormat, string hemispheres)
|
||||
private static string GetLatitudeLabelText(double value, string labelFormat)
|
||||
{
|
||||
return GetLabelText(value, labelFormat, "NS");
|
||||
}
|
||||
|
||||
private static string GetLongitudeLabelText(double value, string labelFormat)
|
||||
{
|
||||
return GetLabelText(Location.NormalizeLongitude(value), labelFormat, "EW");
|
||||
}
|
||||
|
||||
private static string GetLabelText(double value, string labelFormat, string hemispheres)
|
||||
{
|
||||
var hemisphere = hemispheres[0];
|
||||
|
||||
if (value < -1e-8) // ~1 mm
|
||||
{
|
||||
var hemisphere = hemispheres[0];
|
||||
|
||||
if (value < -1e-8) // ~1 mm
|
||||
{
|
||||
value = -value;
|
||||
hemisphere = hemispheres[1];
|
||||
}
|
||||
|
||||
var seconds = (int)Math.Round(value * 3600d);
|
||||
|
||||
return string.Format(CultureInfo.InvariantCulture,
|
||||
labelFormat, hemisphere, seconds / 3600, seconds / 60 % 60, seconds % 60);
|
||||
value = -value;
|
||||
hemisphere = hemispheres[1];
|
||||
}
|
||||
|
||||
var seconds = (int)Math.Round(value * 3600d);
|
||||
|
||||
return string.Format(CultureInfo.InvariantCulture,
|
||||
labelFormat, hemisphere, seconds / 3600, seconds / 60 % 60, seconds % 60);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ using Microsoft.UI.Xaml;
|
|||
using Microsoft.UI.Xaml.Media;
|
||||
#elif AVALONIA
|
||||
using Avalonia;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Media;
|
||||
using Brush = Avalonia.Media.IBrush;
|
||||
using PathFigureCollection = Avalonia.Media.PathFigures;
|
||||
|
|
@ -23,12 +24,16 @@ namespace MapControl
|
|||
/// </summary>
|
||||
public abstract partial class MapGrid
|
||||
{
|
||||
protected class Label(string text, double x, double y, double rotation)
|
||||
protected class Label(string text, double x, double y, double rotation,
|
||||
HorizontalAlignment horizontalAlignment = HorizontalAlignment.Left,
|
||||
VerticalAlignment verticalAlignment = VerticalAlignment.Center)
|
||||
{
|
||||
public string Text => text;
|
||||
public double X => x;
|
||||
public double Y => y;
|
||||
public double Rotation => rotation;
|
||||
public HorizontalAlignment HorizontalAlignment => horizontalAlignment;
|
||||
public VerticalAlignment VerticalAlignment => verticalAlignment;
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty MinLineDistanceProperty =
|
||||
|
|
|
|||
|
|
@ -4,11 +4,14 @@ using System.Collections.Generic;
|
|||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
#elif UWP
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Media;
|
||||
#elif WINUI
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
#elif AVALONIA
|
||||
using Avalonia;
|
||||
using Avalonia.Layout;
|
||||
using PathFigureCollection = Avalonia.Media.PathFigures;
|
||||
#endif
|
||||
|
||||
|
|
@ -43,6 +46,10 @@ namespace MapControl
|
|||
var p1 = ParentMap.ViewTransform.MapToView(new Point(x, mapRect.Y));
|
||||
var p2 = ParentMap.ViewTransform.MapToView(new Point(x, mapRect.Y + mapRect.Height));
|
||||
figures.Add(CreateLineFigure(p1, p2));
|
||||
|
||||
var text = string.Format("{0:F0}", x);
|
||||
labels.Add(new Label(text, p1.X, p1.Y, 0d, HorizontalAlignment.Left, VerticalAlignment.Bottom));
|
||||
labels.Add(new Label(text, p2.X, p2.Y, 0d, HorizontalAlignment.Left, VerticalAlignment.Top));
|
||||
}
|
||||
|
||||
for (var y = minY; y <= mapRect.Y + mapRect.Height; y += lineDistance)
|
||||
|
|
@ -51,33 +58,9 @@ namespace MapControl
|
|||
var p2 = ParentMap.ViewTransform.MapToView(new Point(mapRect.X + mapRect.Width, y));
|
||||
figures.Add(CreateLineFigure(p1, p2));
|
||||
|
||||
for (var x = minX; x <= mapRect.X + mapRect.Width; x += lineDistance)
|
||||
{
|
||||
AddLabel(labels, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddLabel(List<Label> labels, double x, double y)
|
||||
{
|
||||
var position = ParentMap.ViewTransform.MapToView(new Point(x, y));
|
||||
|
||||
if (ParentMap.InsideViewBounds(position))
|
||||
{
|
||||
var rotation = ParentMap.ViewTransform.Rotation;
|
||||
|
||||
if (rotation < -90d)
|
||||
{
|
||||
rotation += 180d;
|
||||
}
|
||||
else if (rotation > 90d)
|
||||
{
|
||||
rotation -= 180d;
|
||||
}
|
||||
|
||||
var text = string.Format("{0:F0}\n{1:F0}", y, x);
|
||||
|
||||
labels.Add(new Label(text, position.X, position.Y, rotation));
|
||||
var text = string.Format("{0:F0}", y);
|
||||
labels.Add(new Label(text, p1.X, p1.Y, 0d, HorizontalAlignment.Left, VerticalAlignment.Bottom));
|
||||
labels.Add(new Label(text, p2.X, p2.Y, 0d, HorizontalAlignment.Right, VerticalAlignment.Bottom));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,8 +74,20 @@ namespace MapControl
|
|||
{
|
||||
var text = new FormattedText(label.Text,
|
||||
CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeface, FontSize, Foreground, pixelsPerDip);
|
||||
var x = label.X + StrokeThickness / 2d + 2d;
|
||||
var y = label.Y - text.Height / 2d;
|
||||
var x = label.X +
|
||||
label.HorizontalAlignment switch
|
||||
{
|
||||
HorizontalAlignment.Left => 2d,
|
||||
HorizontalAlignment.Right => -text.Width - 2d,
|
||||
_ => -text.Width / 2d
|
||||
};
|
||||
var y = label.Y +
|
||||
label.VerticalAlignment switch
|
||||
{
|
||||
VerticalAlignment.Top => 0,
|
||||
VerticalAlignment.Bottom => -text.Height,
|
||||
_ => -text.Height / 2d
|
||||
};
|
||||
|
||||
if (label.Rotation != 0d)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -96,8 +96,21 @@ namespace MapControl
|
|||
textBlock.Text = label.Text;
|
||||
textBlock.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
|
||||
|
||||
var x = label.HorizontalAlignment switch
|
||||
{
|
||||
HorizontalAlignment.Left => 2d,
|
||||
HorizontalAlignment.Right => -textBlock.DesiredSize.Width - 2d,
|
||||
_ => -textBlock.DesiredSize.Width / 2d
|
||||
};
|
||||
var y = label.VerticalAlignment switch
|
||||
{
|
||||
VerticalAlignment.Top => 0d,
|
||||
VerticalAlignment.Bottom => -textBlock.DesiredSize.Height,
|
||||
_ => -textBlock.DesiredSize.Height / 2d,
|
||||
};
|
||||
|
||||
var matrix = new Matrix(1, 0, 0, 1, 0, 0);
|
||||
matrix.Translate(StrokeThickness / 2d + 2d, -textBlock.DesiredSize.Height / 2d);
|
||||
matrix.Translate(x, y);
|
||||
matrix.Rotate(label.Rotation);
|
||||
matrix.Translate(label.X, label.Y);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue