mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2025-12-06 07:12:04 +01:00
Version 2.6.0: -replaced static fields by static properties and dependency properties
- improved class TileLayer - MapGraticule with arc seconds
This commit is contained in:
parent
43e87f26ba
commit
bc30e1d9ca
|
|
@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyCompany("Clemens Fischer")]
|
||||
[assembly: AssemblyCopyright("© 2015 Clemens Fischer")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyVersion("2.5.1")]
|
||||
[assembly: AssemblyFileVersion("2.5.1")]
|
||||
[assembly: AssemblyVersion("2.6.0")]
|
||||
[assembly: AssemblyFileVersion("2.6.0")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyCompany("Clemens Fischer")]
|
||||
[assembly: AssemblyCopyright("© 2015 Clemens Fischer")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyVersion("2.5.1")]
|
||||
[assembly: AssemblyFileVersion("2.5.1")]
|
||||
[assembly: AssemblyVersion("2.6.0")]
|
||||
[assembly: AssemblyFileVersion("2.6.0")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyCompany("Clemens Fischer")]
|
||||
[assembly: AssemblyCopyright("© 2015 Clemens Fischer")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyVersion("2.5.1")]
|
||||
[assembly: AssemblyFileVersion("2.5.1")]
|
||||
[assembly: AssemblyVersion("2.6.0")]
|
||||
[assembly: AssemblyFileVersion("2.6.0")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyCompany("Clemens Fischer")]
|
||||
[assembly: AssemblyCopyright("© 2015 Clemens Fischer")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyVersion("2.5.1")]
|
||||
[assembly: AssemblyFileVersion("2.5.1")]
|
||||
[assembly: AssemblyVersion("2.6.0")]
|
||||
[assembly: AssemblyFileVersion("2.6.0")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
// XAML Map Control - http://xamlmapcontrol.codeplex.com/
|
||||
// © 2015 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
public struct Int32Rect
|
||||
{
|
||||
public Int32Rect(int x, int y, int width, int height)
|
||||
: this()
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
|
||||
public int X { get; set; }
|
||||
public int Y { get; set; }
|
||||
public int Width { get; set; }
|
||||
public int Height { get; set; }
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return X ^ Y ^ Width ^ Height;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is Int32Rect && (Int32Rect)obj == this;
|
||||
}
|
||||
|
||||
public static bool operator ==(Int32Rect rect1, Int32Rect rect2)
|
||||
{
|
||||
return rect1.X == rect2.X && rect1.Y == rect2.Y && rect1.Width == rect2.Width && rect1.Height == rect2.Height;
|
||||
}
|
||||
|
||||
public static bool operator !=(Int32Rect rect1, Int32Rect rect2)
|
||||
{
|
||||
return !(rect1 == rect2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,31 +20,32 @@ namespace MapControl
|
|||
public partial class MapBase
|
||||
{
|
||||
public static readonly DependencyProperty ForegroundProperty = DependencyProperty.Register(
|
||||
"Foreground", typeof(Brush), typeof(MapBase), new PropertyMetadata(new SolidColorBrush(Colors.Black)));
|
||||
"Foreground", typeof(Brush), typeof(MapBase),
|
||||
new PropertyMetadata(new SolidColorBrush(Colors.Black)));
|
||||
|
||||
public static readonly DependencyProperty CenterProperty = DependencyProperty.Register(
|
||||
"Center", typeof(Location), typeof(MapBase), new PropertyMetadata(new Location(),
|
||||
(o, e) => ((MapBase)o).CenterPropertyChanged((Location)e.NewValue)));
|
||||
"Center", typeof(Location), typeof(MapBase),
|
||||
new PropertyMetadata(new Location(), (o, e) => ((MapBase)o).CenterPropertyChanged((Location)e.NewValue)));
|
||||
|
||||
public static readonly DependencyProperty TargetCenterProperty = DependencyProperty.Register(
|
||||
"TargetCenter", typeof(Location), typeof(MapBase), new PropertyMetadata(new Location(),
|
||||
(o, e) => ((MapBase)o).TargetCenterPropertyChanged((Location)e.NewValue)));
|
||||
"TargetCenter", typeof(Location), typeof(MapBase),
|
||||
new PropertyMetadata(new Location(), (o, e) => ((MapBase)o).TargetCenterPropertyChanged((Location)e.NewValue)));
|
||||
|
||||
public static readonly DependencyProperty ZoomLevelProperty = DependencyProperty.Register(
|
||||
"ZoomLevel", typeof(double), typeof(MapBase), new PropertyMetadata(1d,
|
||||
(o, e) => ((MapBase)o).ZoomLevelPropertyChanged((double)e.NewValue)));
|
||||
"ZoomLevel", typeof(double), typeof(MapBase),
|
||||
new PropertyMetadata(1d, (o, e) => ((MapBase)o).ZoomLevelPropertyChanged((double)e.NewValue)));
|
||||
|
||||
public static readonly DependencyProperty TargetZoomLevelProperty = DependencyProperty.Register(
|
||||
"TargetZoomLevel", typeof(double), typeof(MapBase), new PropertyMetadata(1d,
|
||||
(o, e) => ((MapBase)o).TargetZoomLevelPropertyChanged((double)e.NewValue)));
|
||||
"TargetZoomLevel", typeof(double), typeof(MapBase),
|
||||
new PropertyMetadata(1d, (o, e) => ((MapBase)o).TargetZoomLevelPropertyChanged((double)e.NewValue)));
|
||||
|
||||
public static readonly DependencyProperty HeadingProperty = DependencyProperty.Register(
|
||||
"Heading", typeof(double), typeof(MapBase), new PropertyMetadata(0d,
|
||||
(o, e) => ((MapBase)o).HeadingPropertyChanged((double)e.NewValue)));
|
||||
"Heading", typeof(double), typeof(MapBase),
|
||||
new PropertyMetadata(0d, (o, e) => ((MapBase)o).HeadingPropertyChanged((double)e.NewValue)));
|
||||
|
||||
public static readonly DependencyProperty TargetHeadingProperty = DependencyProperty.Register(
|
||||
"TargetHeading", typeof(double), typeof(MapBase), new PropertyMetadata(0d,
|
||||
(o, e) => ((MapBase)o).TargetHeadingPropertyChanged((double)e.NewValue)));
|
||||
"TargetHeading", typeof(double), typeof(MapBase),
|
||||
new PropertyMetadata(0d, (o, e) => ((MapBase)o).TargetHeadingPropertyChanged((double)e.NewValue)));
|
||||
|
||||
partial void Initialize()
|
||||
{
|
||||
|
|
@ -67,7 +68,7 @@ namespace MapControl
|
|||
private void SetViewportTransform(Location origin)
|
||||
{
|
||||
MapOrigin = mapTransform.Transform(origin);
|
||||
ViewportScale = Math.Pow(2d, ZoomLevel) * TileSource.TileSize / 360d;
|
||||
ViewportScale = Math.Pow(2d, ZoomLevel) * (double)TileSource.TileSize / 360d;
|
||||
|
||||
viewportTransform.Matrix =
|
||||
new Matrix(1d, 0d, 0d, 1d, -MapOrigin.X, -MapOrigin.Y)
|
||||
|
|
|
|||
|
|
@ -46,10 +46,10 @@ namespace MapControl
|
|||
|
||||
static MapBase()
|
||||
{
|
||||
UIElement.ClipToBoundsProperty.OverrideMetadata(
|
||||
ClipToBoundsProperty.OverrideMetadata(
|
||||
typeof(MapBase), new FrameworkPropertyMetadata(true));
|
||||
|
||||
Panel.BackgroundProperty.OverrideMetadata(
|
||||
BackgroundProperty.OverrideMetadata(
|
||||
typeof(MapBase), new FrameworkPropertyMetadata(Brushes.Transparent));
|
||||
}
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ namespace MapControl
|
|||
private void SetViewportTransform(Location origin)
|
||||
{
|
||||
MapOrigin = mapTransform.Transform(origin);
|
||||
ViewportScale = Math.Pow(2d, ZoomLevel) * TileSource.TileSize / 360d;
|
||||
ViewportScale = Math.Pow(2d, ZoomLevel) * (double)TileSource.TileSize / 360d;
|
||||
|
||||
var transform = new Matrix(1d, 0d, 0d, 1d, -MapOrigin.X, -MapOrigin.Y);
|
||||
transform.Scale(ViewportScale, -ViewportScale);
|
||||
|
|
|
|||
|
|
@ -30,28 +30,37 @@ namespace MapControl
|
|||
{
|
||||
private const double MaximumZoomLevel = 22d;
|
||||
|
||||
public static TimeSpan AnimationDuration = TimeSpan.FromSeconds(0.3);
|
||||
public static EasingFunctionBase AnimationEasingFunction = new QuadraticEase { EasingMode = EasingMode.EaseOut };
|
||||
|
||||
public static readonly DependencyProperty TileLayerProperty = DependencyProperty.Register(
|
||||
"TileLayer", typeof(TileLayer), typeof(MapBase), new PropertyMetadata(null,
|
||||
(o, e) => ((MapBase)o).TileLayerPropertyChanged((TileLayer)e.NewValue)));
|
||||
"TileLayer", typeof(TileLayer), typeof(MapBase),
|
||||
new PropertyMetadata(null, (o, e) => ((MapBase)o).TileLayerPropertyChanged((TileLayer)e.NewValue)));
|
||||
|
||||
public static readonly DependencyProperty TileLayersProperty = DependencyProperty.Register(
|
||||
"TileLayers", typeof(IList<TileLayer>), typeof(MapBase), new PropertyMetadata(null,
|
||||
(o, e) => ((MapBase)o).TileLayersPropertyChanged((IList<TileLayer>)e.OldValue, (IList<TileLayer>)e.NewValue)));
|
||||
"TileLayers", typeof(IList<TileLayer>), typeof(MapBase),
|
||||
new PropertyMetadata(null, (o, e) => ((MapBase)o).TileLayersPropertyChanged((IList<TileLayer>)e.OldValue, (IList<TileLayer>)e.NewValue)));
|
||||
|
||||
public static readonly DependencyProperty MinZoomLevelProperty = DependencyProperty.Register(
|
||||
"MinZoomLevel", typeof(double), typeof(MapBase), new PropertyMetadata(1d,
|
||||
(o, e) => ((MapBase)o).MinZoomLevelPropertyChanged((double)e.NewValue)));
|
||||
"MinZoomLevel", typeof(double), typeof(MapBase),
|
||||
new PropertyMetadata(1d, (o, e) => ((MapBase)o).MinZoomLevelPropertyChanged((double)e.NewValue)));
|
||||
|
||||
public static readonly DependencyProperty MaxZoomLevelProperty = DependencyProperty.Register(
|
||||
"MaxZoomLevel", typeof(double), typeof(MapBase), new PropertyMetadata(19d,
|
||||
(o, e) => ((MapBase)o).MaxZoomLevelPropertyChanged((double)e.NewValue)));
|
||||
"MaxZoomLevel", typeof(double), typeof(MapBase),
|
||||
new PropertyMetadata(19d, (o, e) => ((MapBase)o).MaxZoomLevelPropertyChanged((double)e.NewValue)));
|
||||
|
||||
public static readonly DependencyProperty AnimationDurationProperty = DependencyProperty.Register(
|
||||
"AnimationDuration", typeof(TimeSpan), typeof(MapBase),
|
||||
new PropertyMetadata(TimeSpan.FromSeconds(0.3)));
|
||||
|
||||
public static readonly DependencyProperty AnimationEasingFunctionProperty = DependencyProperty.Register(
|
||||
"AnimationEasingFunction", typeof(EasingFunctionBase), typeof(MapBase),
|
||||
new PropertyMetadata(new QuadraticEase { EasingMode = EasingMode.EaseOut }));
|
||||
|
||||
public static readonly DependencyProperty TileFadeDurationProperty = DependencyProperty.Register(
|
||||
"TileFadeDuration", typeof(TimeSpan), typeof(MapBase),
|
||||
new PropertyMetadata(Tile.FadeDuration, (o, e) => Tile.FadeDuration = (TimeSpan)e.NewValue));
|
||||
|
||||
internal static readonly DependencyProperty CenterPointProperty = DependencyProperty.Register(
|
||||
"CenterPoint", typeof(Point), typeof(MapBase), new PropertyMetadata(new Point(),
|
||||
(o, e) => ((MapBase)o).CenterPointPropertyChanged((Point)e.NewValue)));
|
||||
"CenterPoint", typeof(Point), typeof(MapBase),
|
||||
new PropertyMetadata(new Point(), (o, e) => ((MapBase)o).CenterPointPropertyChanged((Point)e.NewValue)));
|
||||
|
||||
private readonly PanelBase tileLayerPanel = new PanelBase();
|
||||
private readonly MapTransform mapTransform = new MercatorTransform();
|
||||
|
|
@ -138,6 +147,7 @@ namespace MapControl
|
|||
/// <summary>
|
||||
/// Gets or sets the minimum value of the ZoomLevel and TargetZommLevel properties.
|
||||
/// Must be greater than or equal to zero and less than or equal to MaxZoomLevel.
|
||||
/// The default value is 1.
|
||||
/// </summary>
|
||||
public double MinZoomLevel
|
||||
{
|
||||
|
|
@ -148,6 +158,7 @@ namespace MapControl
|
|||
/// <summary>
|
||||
/// Gets or sets the maximum value of the ZoomLevel and TargetZommLevel properties.
|
||||
/// Must be greater than or equal to MinZoomLevel and less than or equal to 20.
|
||||
/// The default value is 19.
|
||||
/// </summary>
|
||||
public double MaxZoomLevel
|
||||
{
|
||||
|
|
@ -191,6 +202,36 @@ namespace MapControl
|
|||
set { SetValue(TargetHeadingProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Duration of the Center, ZoomLevel and Heading animations.
|
||||
/// The default value is 0.3 seconds.
|
||||
/// </summary>
|
||||
public TimeSpan AnimationDuration
|
||||
{
|
||||
get { return (TimeSpan)GetValue(AnimationDurationProperty); }
|
||||
set { SetValue(AnimationDurationProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the EasingFunction of the Center, ZoomLevel and Heading animations.
|
||||
/// The default value is a QuadraticEase with EasingMode.EaseOut.
|
||||
/// </summary>
|
||||
public EasingFunctionBase AnimationEasingFunction
|
||||
{
|
||||
get { return (EasingFunctionBase)GetValue(AnimationEasingFunctionProperty); }
|
||||
set { SetValue(AnimationEasingFunctionProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Duration of the Tile Opacity animation.
|
||||
/// The default value is 0.2 seconds.
|
||||
/// </summary>
|
||||
public TimeSpan TileFadeDuration
|
||||
{
|
||||
get { return (TimeSpan)GetValue(TileFadeDurationProperty); }
|
||||
set { SetValue(TileFadeDurationProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the transformation from geographic coordinates to cartesian map coordinates.
|
||||
/// </summary>
|
||||
|
|
@ -247,7 +288,7 @@ namespace MapControl
|
|||
public double GetMapScale(Location location)
|
||||
{
|
||||
return mapTransform.RelativeScale(location) *
|
||||
Math.Pow(2d, ZoomLevel) * TileSource.TileSize / (TileSource.MetersPerDegree * 360d);
|
||||
Math.Pow(2d, ZoomLevel) * (double)TileSource.TileSize / (TileSource.MetersPerDegree * 360d);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -364,8 +405,8 @@ namespace MapControl
|
|||
{
|
||||
var p1 = mapTransform.Transform(southWest);
|
||||
var p2 = mapTransform.Transform(northEast);
|
||||
var lonScale = RenderSize.Width / (p2.X - p1.X) * 360d / TileSource.TileSize;
|
||||
var latScale = RenderSize.Height / (p2.Y - p1.Y) * 360d / TileSource.TileSize;
|
||||
var lonScale = RenderSize.Width / (p2.X - p1.X) * 360d / (double)TileSource.TileSize;
|
||||
var latScale = RenderSize.Height / (p2.Y - p1.Y) * 360d / (double)TileSource.TileSize;
|
||||
var lonZoom = Math.Log(lonScale, 2d);
|
||||
var latZoom = Math.Log(latScale, 2d);
|
||||
|
||||
|
|
@ -764,17 +805,12 @@ namespace MapControl
|
|||
|
||||
private void UpdateTransform(bool resetTransformOrigin = false)
|
||||
{
|
||||
Location center;
|
||||
var center = transformOrigin ?? Center;
|
||||
|
||||
if (transformOrigin == null)
|
||||
{
|
||||
center = Center;
|
||||
SetViewportTransform(center);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetViewportTransform(transformOrigin);
|
||||
SetViewportTransform(center);
|
||||
|
||||
if (transformOrigin != null)
|
||||
{
|
||||
center = ViewportPointToLocation(new Point(RenderSize.Width / 2d, RenderSize.Height / 2d));
|
||||
center.Longitude = Location.NormalizeLongitude(center.Longitude);
|
||||
|
||||
|
|
@ -799,7 +835,7 @@ namespace MapControl
|
|||
}
|
||||
}
|
||||
|
||||
CenterScale = ViewportScale * mapTransform.RelativeScale(center) / TileSource.MetersPerDegree; // pixels per meter at center latitude
|
||||
CenterScale = ViewportScale * mapTransform.RelativeScale(center) / TileSource.MetersPerDegree;
|
||||
scaleTransform.ScaleX = CenterScale;
|
||||
scaleTransform.ScaleY = CenterScale;
|
||||
rotateTransform.Angle = Heading;
|
||||
|
|
|
|||
|
|
@ -74,7 +74,6 @@
|
|||
<Compile Include="HyperlinkText.cs" />
|
||||
<Compile Include="ImageTileSource.Silverlight.WinRT.cs" />
|
||||
<Compile Include="IMapElement.cs" />
|
||||
<Compile Include="Int32Rect.cs" />
|
||||
<Compile Include="ITileImageLoader.cs" />
|
||||
<Compile Include="Location.cs" />
|
||||
<Compile Include="LocationCollection.cs" />
|
||||
|
|
@ -107,6 +106,7 @@
|
|||
<Compile Include="Pushpin.Silverlight.WinRT.cs" />
|
||||
<Compile Include="Tile.cs" />
|
||||
<Compile Include="Tile.Silverlight.WinRT.cs" />
|
||||
<Compile Include="TileGrid.cs" />
|
||||
<Compile Include="TileImageLoader.Silverlight.cs" />
|
||||
<Compile Include="TileLayer.cs" />
|
||||
<Compile Include="TileLayer.Silverlight.WinRT.cs" />
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@
|
|||
<Compile Include="Pushpin.WPF.cs" />
|
||||
<Compile Include="Tile.cs" />
|
||||
<Compile Include="Tile.WPF.cs" />
|
||||
<Compile Include="TileGrid.cs" />
|
||||
<Compile Include="TileImageLoader.WPF.cs" />
|
||||
<Compile Include="TileLayer.cs" />
|
||||
<Compile Include="TileLayer.WPF.cs" />
|
||||
|
|
|
|||
|
|
@ -57,29 +57,23 @@ namespace MapControl
|
|||
var bounds = ParentMap.ViewportTransform.Inverse.TransformBounds(new Rect(new Point(), 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) * 256d);
|
||||
var spacing = LineSpacings[LineSpacings.Length - 1];
|
||||
|
||||
if (spacing >= minSpacing)
|
||||
{
|
||||
spacing = LineSpacings.FirstOrDefault(s => s >= minSpacing);
|
||||
}
|
||||
var lineDistance = GetLineDistance();
|
||||
|
||||
var labelStart = new Location(
|
||||
Math.Ceiling(start.Latitude / spacing) * spacing,
|
||||
Math.Ceiling(start.Longitude / spacing) * spacing);
|
||||
Math.Ceiling(start.Latitude / lineDistance) * lineDistance,
|
||||
Math.Ceiling(start.Longitude / lineDistance) * lineDistance);
|
||||
|
||||
var labelEnd = new Location(
|
||||
Math.Floor(end.Latitude / spacing) * spacing,
|
||||
Math.Floor(end.Longitude / spacing) * spacing);
|
||||
Math.Floor(end.Latitude / lineDistance) * lineDistance,
|
||||
Math.Floor(end.Longitude / lineDistance) * lineDistance);
|
||||
|
||||
var lineStart = new Location(
|
||||
Math.Min(Math.Max(labelStart.Latitude - spacing, -ParentMap.MapTransform.MaxLatitude), ParentMap.MapTransform.MaxLatitude),
|
||||
labelStart.Longitude - spacing);
|
||||
Math.Min(Math.Max(labelStart.Latitude - lineDistance, -ParentMap.MapTransform.MaxLatitude), ParentMap.MapTransform.MaxLatitude),
|
||||
labelStart.Longitude - lineDistance);
|
||||
|
||||
var lineEnd = new Location(
|
||||
Math.Min(Math.Max(labelEnd.Latitude + spacing, -ParentMap.MapTransform.MaxLatitude), ParentMap.MapTransform.MaxLatitude),
|
||||
labelEnd.Longitude + spacing);
|
||||
Math.Min(Math.Max(labelEnd.Latitude + lineDistance, -ParentMap.MapTransform.MaxLatitude), ParentMap.MapTransform.MaxLatitude),
|
||||
labelEnd.Longitude + lineDistance);
|
||||
|
||||
if (!lineStart.Equals(graticuleStart) || !lineEnd.Equals(graticuleEnd))
|
||||
{
|
||||
|
|
@ -90,7 +84,7 @@ namespace MapControl
|
|||
geometry.Figures.Clear();
|
||||
geometry.Transform = ParentMap.ViewportTransform;
|
||||
|
||||
for (var lat = labelStart.Latitude; lat <= end.Latitude; lat += spacing)
|
||||
for (var lat = labelStart.Latitude; lat <= end.Latitude; lat += lineDistance)
|
||||
{
|
||||
var figure = new PathFigure
|
||||
{
|
||||
|
|
@ -107,7 +101,7 @@ namespace MapControl
|
|||
geometry.Figures.Add(figure);
|
||||
}
|
||||
|
||||
for (var lon = labelStart.Longitude; lon <= end.Longitude; lon += spacing)
|
||||
for (var lon = labelStart.Longitude; lon <= end.Longitude; lon += lineDistance)
|
||||
{
|
||||
var figure = new PathFigure
|
||||
{
|
||||
|
|
@ -124,12 +118,12 @@ namespace MapControl
|
|||
geometry.Figures.Add(figure);
|
||||
}
|
||||
|
||||
var labelFormat = GetLabelFormat(lineDistance);
|
||||
var childIndex = 1; // 0 for Path
|
||||
var format = spacing < 1d ? "{0} {1}°{2:00}'" : "{0} {1}°";
|
||||
|
||||
for (var lat = labelStart.Latitude; lat <= end.Latitude; lat += spacing)
|
||||
for (var lat = labelStart.Latitude; lat <= end.Latitude; lat += lineDistance)
|
||||
{
|
||||
for (var lon = labelStart.Longitude; lon <= end.Longitude; lon += spacing)
|
||||
for (var lon = labelStart.Longitude; lon <= end.Longitude; lon += lineDistance)
|
||||
{
|
||||
TextBlock label;
|
||||
|
||||
|
|
@ -169,7 +163,7 @@ namespace MapControl
|
|||
label.FontStyle = FontStyle;
|
||||
label.FontStretch = FontStretch;
|
||||
label.FontWeight = FontWeight;
|
||||
label.Text = string.Format("{0}\n{1}", CoordinateString(lat, format, "NS"), CoordinateString(Location.NormalizeLongitude(lon), format, "EW"));
|
||||
label.Text = GetLabelText(lat, labelFormat, "NS") + "\n" + GetLabelText(Location.NormalizeLongitude(lon), labelFormat, "EW");
|
||||
label.Tag = new Location(lat, lon);
|
||||
label.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
|
||||
|
|
@ -27,10 +26,10 @@ namespace MapControl
|
|||
|
||||
static MapGraticule()
|
||||
{
|
||||
UIElement.IsHitTestVisibleProperty.OverrideMetadata(
|
||||
IsHitTestVisibleProperty.OverrideMetadata(
|
||||
typeof(MapGraticule), new FrameworkPropertyMetadata(false));
|
||||
|
||||
MapOverlay.StrokeThicknessProperty.OverrideMetadata(
|
||||
StrokeThicknessProperty.OverrideMetadata(
|
||||
typeof(MapGraticule), new FrameworkPropertyMetadata(0.5));
|
||||
}
|
||||
|
||||
|
|
@ -46,24 +45,17 @@ namespace MapControl
|
|||
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];
|
||||
var lineDistance = GetLineDistance();
|
||||
var labelFormat = GetLabelFormat(lineDistance);
|
||||
var latLabelStart = Math.Ceiling(start.Latitude / lineDistance) * lineDistance;
|
||||
var lonLabelStart = Math.Ceiling(start.Longitude / lineDistance) * lineDistance;
|
||||
var latLabels = new List<Label>((int)((end.Latitude - latLabelStart) / lineDistance) + 1);
|
||||
var lonLabels = new List<Label>((int)((end.Longitude - lonLabelStart) / lineDistance) + 1);
|
||||
|
||||
if (spacing >= minSpacing)
|
||||
{
|
||||
spacing = LineSpacings.FirstOrDefault(s => s >= minSpacing);
|
||||
}
|
||||
|
||||
var latLabelStart = Math.Ceiling(start.Latitude / spacing) * spacing;
|
||||
var lonLabelStart = Math.Ceiling(start.Longitude / spacing) * spacing;
|
||||
var latLabels = new List<Label>((int)((end.Latitude - latLabelStart) / spacing) + 1);
|
||||
var lonLabels = new List<Label>((int)((end.Longitude - lonLabelStart) / spacing) + 1);
|
||||
var labelFormat = spacing < 1d ? "{0} {1}°{2:00}'" : "{0} {1}°";
|
||||
|
||||
for (var lat = latLabelStart; lat <= end.Latitude; lat += spacing)
|
||||
for (var lat = latLabelStart; lat <= end.Latitude; lat += lineDistance)
|
||||
{
|
||||
latLabels.Add(new Label(lat, new FormattedText(
|
||||
CoordinateString(lat, labelFormat, "NS"),
|
||||
GetLabelText(lat, labelFormat, "NS"),
|
||||
CultureInfo.InvariantCulture, FlowDirection.LeftToRight, Typeface, FontSize, Foreground)));
|
||||
|
||||
drawingContext.DrawLine(Pen,
|
||||
|
|
@ -71,10 +63,10 @@ namespace MapControl
|
|||
ParentMap.LocationToViewportPoint(new Location(lat, end.Longitude)));
|
||||
}
|
||||
|
||||
for (var lon = lonLabelStart; lon <= end.Longitude; lon += spacing)
|
||||
for (var lon = lonLabelStart; lon <= end.Longitude; lon += lineDistance)
|
||||
{
|
||||
lonLabels.Add(new Label(lon, new FormattedText(
|
||||
CoordinateString(Location.NormalizeLongitude(lon), labelFormat, "EW"),
|
||||
GetLabelText(Location.NormalizeLongitude(lon), labelFormat, "EW"),
|
||||
CultureInfo.InvariantCulture, FlowDirection.LeftToRight, Typeface, FontSize, Foreground)));
|
||||
|
||||
drawingContext.DrawLine(Pen,
|
||||
|
|
|
|||
|
|
@ -16,25 +16,56 @@ namespace MapControl
|
|||
/// </summary>
|
||||
public partial class MapGraticule : MapOverlay
|
||||
{
|
||||
/// <summary>
|
||||
/// Graticule line spacings in degrees.
|
||||
/// </summary>
|
||||
public static double[] LineSpacings =
|
||||
new double[] { 1d / 60d, 1d / 30d, 1d / 12d, 1d / 6d, 1d / 4d, 1d / 3d, 1d / 2d, 1d, 2d, 5d, 10d, 15d, 20d, 30d, 45d };
|
||||
|
||||
public static readonly DependencyProperty MinLineSpacingProperty = DependencyProperty.Register(
|
||||
"MinLineSpacing", typeof(double), typeof(MapGraticule), new PropertyMetadata(150d));
|
||||
public static readonly DependencyProperty MinLineDistanceProperty = DependencyProperty.Register(
|
||||
"MinLineDistance", typeof(double), typeof(MapGraticule), new PropertyMetadata(150d));
|
||||
|
||||
/// <summary>
|
||||
/// Minimum spacing in pixels between adjacent graticule lines.
|
||||
/// Minimum graticule line distance in pixels. The default value is 150.
|
||||
/// </summary>
|
||||
public double MinLineSpacing
|
||||
public double MinLineDistance
|
||||
{
|
||||
get { return (double)GetValue(MinLineSpacingProperty); }
|
||||
set { SetValue(MinLineSpacingProperty, value); }
|
||||
get { return (double)GetValue(MinLineDistanceProperty); }
|
||||
set { SetValue(MinLineDistanceProperty, value); }
|
||||
}
|
||||
|
||||
private static string CoordinateString(double value, string format, string hemispheres)
|
||||
private double GetLineDistance()
|
||||
{
|
||||
var minDistance = MinLineDistance * 360d / (Math.Pow(2d, ParentMap.ZoomLevel) * (double)TileSource.TileSize);
|
||||
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;
|
||||
}
|
||||
|
||||
private static string GetLabelFormat(double lineDistance)
|
||||
{
|
||||
if (lineDistance < 1d / 60d)
|
||||
{
|
||||
return "{0} {1}°{2:00}'{3:00}\"";
|
||||
}
|
||||
|
||||
if (lineDistance < 1d)
|
||||
{
|
||||
return "{0} {1}°{2:00}'";
|
||||
}
|
||||
|
||||
return "{0} {1}°";
|
||||
}
|
||||
|
||||
private static string GetLabelText(double value, string format, string hemispheres)
|
||||
{
|
||||
var hemisphere = hemispheres[0];
|
||||
|
||||
|
|
@ -44,9 +75,9 @@ namespace MapControl
|
|||
hemisphere = hemispheres[1];
|
||||
}
|
||||
|
||||
var minutes = (int)Math.Round(value * 60d);
|
||||
var seconds = (int)Math.Round(value * 3600d);
|
||||
|
||||
return string.Format(format, hemisphere, minutes / 60, (double)(minutes % 60));
|
||||
return string.Format(format, hemisphere, seconds / 3600, (seconds / 60) % 60, seconds % 60);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ namespace MapControl
|
|||
{
|
||||
From = 0d,
|
||||
To = 1d,
|
||||
Duration = Tile.OpacityAnimationDuration,
|
||||
Duration = Tile.FadeDuration,
|
||||
FillBehavior = FillBehavior.Stop
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ namespace MapControl
|
|||
|
||||
/// <summary>
|
||||
/// Helper method to work around missing property value inheritance in Silverlight and Windows Runtime.
|
||||
/// Adds Loaded and Unloaded handlers to the specified FrameworkElement, which set and clear the value
|
||||
/// of the MapPanel.ParentMap attached property.
|
||||
/// Adds Loaded and Unloaded event handlers to the specified FrameworkElement, which set and clear the
|
||||
/// value of the MapPanel.ParentMap attached property.
|
||||
/// </summary>
|
||||
public static void AddParentMapHandlers(FrameworkElement element)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ namespace MapControl
|
|||
public partial class MapPolyline
|
||||
{
|
||||
public static readonly DependencyProperty FillRuleProperty = DependencyProperty.Register(
|
||||
"FillRule", typeof(FillRule), typeof(MapPolyline), new PropertyMetadata(FillRule.EvenOdd,
|
||||
(o, e) => ((PathGeometry)((MapPolyline)o).Data).FillRule = (FillRule)e.NewValue));
|
||||
"FillRule", typeof(FillRule), typeof(MapPolyline),
|
||||
new PropertyMetadata(FillRule.EvenOdd, (o, e) => ((PathGeometry)((MapPolyline)o).Data).FillRule = (FillRule)e.NewValue));
|
||||
|
||||
public MapPolyline()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ namespace MapControl
|
|||
public partial class MapPolyline
|
||||
{
|
||||
public static readonly DependencyProperty FillRuleProperty = StreamGeometry.FillRuleProperty.AddOwner(
|
||||
typeof(MapPolyline), new FrameworkPropertyMetadata(
|
||||
(o, e) => ((StreamGeometry)((MapPolyline)o).Data).FillRule = (FillRule)e.NewValue));
|
||||
typeof(MapPolyline),
|
||||
new FrameworkPropertyMetadata((o, e) => ((StreamGeometry)((MapPolyline)o).Data).FillRule = (FillRule)e.NewValue));
|
||||
|
||||
public MapPolyline()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,22 +23,22 @@ namespace MapControl
|
|||
|
||||
static MapScale()
|
||||
{
|
||||
UIElement.IsHitTestVisibleProperty.OverrideMetadata(
|
||||
IsHitTestVisibleProperty.OverrideMetadata(
|
||||
typeof(MapScale), new FrameworkPropertyMetadata(false));
|
||||
|
||||
FrameworkElement.MinWidthProperty.OverrideMetadata(
|
||||
MinWidthProperty.OverrideMetadata(
|
||||
typeof(MapScale), new FrameworkPropertyMetadata(100d));
|
||||
|
||||
FrameworkElement.HorizontalAlignmentProperty.OverrideMetadata(
|
||||
HorizontalAlignmentProperty.OverrideMetadata(
|
||||
typeof(MapScale), new FrameworkPropertyMetadata(HorizontalAlignment.Right));
|
||||
|
||||
FrameworkElement.VerticalAlignmentProperty.OverrideMetadata(
|
||||
VerticalAlignmentProperty.OverrideMetadata(
|
||||
typeof(MapScale), new FrameworkPropertyMetadata(VerticalAlignment.Bottom));
|
||||
|
||||
MapOverlay.StrokeStartLineCapProperty.OverrideMetadata(
|
||||
StrokeStartLineCapProperty.OverrideMetadata(
|
||||
typeof(MapScale), new FrameworkPropertyMetadata(PenLineCap.Round));
|
||||
|
||||
MapOverlay.StrokeEndLineCapProperty.OverrideMetadata(
|
||||
StrokeEndLineCapProperty.OverrideMetadata(
|
||||
typeof(MapScale), new FrameworkPropertyMetadata(PenLineCap.Round));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ using System.Windows;
|
|||
[assembly: AssemblyCompany("Clemens Fischer")]
|
||||
[assembly: AssemblyCopyright("© 2015 Clemens Fischer")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyVersion("2.5.1")]
|
||||
[assembly: AssemblyFileVersion("2.5.1")]
|
||||
[assembly: AssemblyVersion("2.6.0")]
|
||||
[assembly: AssemblyFileVersion("2.6.0")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@ namespace MapControl
|
|||
{
|
||||
public partial class Tile
|
||||
{
|
||||
public void SetImage(ImageSource image, bool animateOpacity = true, bool isDownloading = true)
|
||||
public void SetImage(ImageSource image, bool fadeIn = true, bool isDownloading = true)
|
||||
{
|
||||
Pending = false;
|
||||
|
||||
if (image != null)
|
||||
{
|
||||
if (animateOpacity && OpacityAnimationDuration > TimeSpan.Zero)
|
||||
if (fadeIn && FadeDuration > TimeSpan.Zero)
|
||||
{
|
||||
BitmapImage bitmap;
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ namespace MapControl
|
|||
else
|
||||
{
|
||||
Image.BeginAnimation(Image.OpacityProperty,
|
||||
new DoubleAnimation { From = 0d, To = 1d, Duration = OpacityAnimationDuration });
|
||||
new DoubleAnimation { From = 0d, To = 1d, Duration = FadeDuration });
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -59,7 +59,7 @@ namespace MapControl
|
|||
bitmap.ImageFailed -= BitmapImageFailed;
|
||||
|
||||
Image.BeginAnimation(Image.OpacityProperty,
|
||||
new DoubleAnimation { From = 0d, To = 1d, Duration = OpacityAnimationDuration });
|
||||
new DoubleAnimation { From = 0d, To = 1d, Duration = FadeDuration });
|
||||
}
|
||||
|
||||
private void BitmapImageFailed(object sender, ExceptionRoutedEventArgs e)
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@ namespace MapControl
|
|||
{
|
||||
public partial class Tile
|
||||
{
|
||||
public void SetImage(ImageSource image, bool animateOpacity = true)
|
||||
public void SetImage(ImageSource image, bool fadeIn = true)
|
||||
{
|
||||
Pending = false;
|
||||
|
||||
if (image != null)
|
||||
{
|
||||
if (animateOpacity && OpacityAnimationDuration > TimeSpan.Zero)
|
||||
if (fadeIn && FadeDuration > TimeSpan.Zero)
|
||||
{
|
||||
var bitmap = image as BitmapSource;
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ namespace MapControl
|
|||
else
|
||||
{
|
||||
Image.BeginAnimation(Image.OpacityProperty,
|
||||
new DoubleAnimation(0d, 1d, OpacityAnimationDuration));
|
||||
new DoubleAnimation(0d, 1d, FadeDuration));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -50,7 +50,7 @@ namespace MapControl
|
|||
bitmap.DownloadFailed -= BitmapDownloadFailed;
|
||||
|
||||
Image.BeginAnimation(Image.OpacityProperty,
|
||||
new DoubleAnimation(0d, 1d, OpacityAnimationDuration));
|
||||
new DoubleAnimation(0d, 1d, FadeDuration));
|
||||
}
|
||||
|
||||
private void BitmapDownloadFailed(object sender, ExceptionEventArgs e)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,12 @@ namespace MapControl
|
|||
{
|
||||
public partial class Tile
|
||||
{
|
||||
public static TimeSpan OpacityAnimationDuration = TimeSpan.FromSeconds(0.1);
|
||||
public static TimeSpan FadeDuration { get; set; }
|
||||
|
||||
static Tile()
|
||||
{
|
||||
FadeDuration = TimeSpan.FromSeconds(0.2);
|
||||
}
|
||||
|
||||
public readonly int ZoomLevel;
|
||||
public readonly int X;
|
||||
|
|
|
|||
46
MapControl/TileGrid.cs
Normal file
46
MapControl/TileGrid.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
// XAML Map Control - http://xamlmapcontrol.codeplex.com/
|
||||
// © 2015 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
public class TileGrid : IEquatable<TileGrid>
|
||||
{
|
||||
public readonly int ZoomLevel;
|
||||
public readonly int XMin;
|
||||
public readonly int YMin;
|
||||
public readonly int XMax;
|
||||
public readonly int YMax;
|
||||
|
||||
public TileGrid(int zoomLevel, int xMin, int yMin, int xMax, int yMax)
|
||||
{
|
||||
ZoomLevel = zoomLevel;
|
||||
XMin = xMin;
|
||||
YMin = yMin;
|
||||
XMax = xMax;
|
||||
YMax = yMax;
|
||||
}
|
||||
|
||||
public bool Equals(TileGrid tileGrid)
|
||||
{
|
||||
return tileGrid != null
|
||||
&& tileGrid.ZoomLevel == ZoomLevel
|
||||
&& tileGrid.XMin == XMin
|
||||
&& tileGrid.YMin == YMin
|
||||
&& tileGrid.XMax == XMax
|
||||
&& tileGrid.YMax == YMax;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as TileGrid);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ZoomLevel ^ XMin ^ YMin ^ XMax ^ YMax;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -40,17 +40,23 @@ namespace MapControl
|
|||
/// was transmitted on download. The default and recommended minimum value is seven days.
|
||||
/// See OpenStreetMap tile usage policy: http://wiki.openstreetmap.org/wiki/Tile_usage_policy
|
||||
/// </summary>
|
||||
public static TimeSpan DefaultCacheExpiration = TimeSpan.FromDays(7);
|
||||
public static TimeSpan DefaultCacheExpiration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ObjectCache used to cache tile images. The default is MemoryCache.Default.
|
||||
/// </summary>
|
||||
public static ObjectCache Cache = MemoryCache.Default;
|
||||
public static ObjectCache Cache { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional value to be used for the HttpWebRequest.UserAgent property. The default is null.
|
||||
/// </summary>
|
||||
public static string HttpUserAgent;
|
||||
public static string HttpUserAgent { get; set; }
|
||||
|
||||
static TileImageLoader()
|
||||
{
|
||||
DefaultCacheExpiration = TimeSpan.FromDays(7);
|
||||
Cache = MemoryCache.Default;
|
||||
}
|
||||
|
||||
private class PendingTile
|
||||
{
|
||||
|
|
|
|||
|
|
@ -38,13 +38,18 @@ namespace MapControl
|
|||
/// was transmitted on download. The default and recommended minimum value is seven days.
|
||||
/// See OpenStreetMap tile usage policy: http://wiki.openstreetmap.org/wiki/Tile_usage_policy
|
||||
/// </summary>
|
||||
public static TimeSpan DefaultCacheExpiration = TimeSpan.FromDays(7);
|
||||
public static TimeSpan DefaultCacheExpiration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The IImageCache implementation used to cache tile images. The default is null.
|
||||
/// </summary>
|
||||
public static Caching.IImageCache Cache;
|
||||
|
||||
static TileImageLoader()
|
||||
{
|
||||
DefaultCacheExpiration = TimeSpan.FromDays(7);
|
||||
}
|
||||
|
||||
private class PendingTile
|
||||
{
|
||||
public readonly Tile Tile;
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@
|
|||
|
||||
using System;
|
||||
#if NETFX_CORE
|
||||
using Windows.Foundation;
|
||||
using Windows.UI.Xaml.Media;
|
||||
#else
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
#endif
|
||||
|
||||
|
|
@ -20,24 +22,28 @@ namespace MapControl
|
|||
MapPanel.AddParentMapHandlers(this);
|
||||
}
|
||||
|
||||
private Matrix GetTileIndexMatrix(int zoomLevel)
|
||||
private Rect GetTileIndexBounds(int zoomLevel)
|
||||
{
|
||||
var scale = (double)(1 << zoomLevel) / 360d;
|
||||
var transform = new MatrixTransform
|
||||
{
|
||||
Matrix = parentMap.ViewportTransform.Matrix
|
||||
.Invert() // view to map coordinates
|
||||
.Translate(180d, -180d)
|
||||
.Scale(scale, -scale) // map coordinates to tile indices
|
||||
};
|
||||
|
||||
return parentMap.ViewportTransform.Matrix
|
||||
.Invert() // view to map coordinates
|
||||
.Translate(180d, -180d)
|
||||
.Scale(scale, -scale); // map coordinates to tile indices
|
||||
return transform.TransformBounds(new Rect(new Point(), parentMap.RenderSize));
|
||||
}
|
||||
|
||||
private void SetRenderTransform()
|
||||
{
|
||||
var scale = Math.Pow(2d, parentMap.ZoomLevel - TileZoomLevel);
|
||||
var scale = Math.Pow(2d, parentMap.ZoomLevel - TileGrid.ZoomLevel);
|
||||
var offsetX = parentMap.ViewportOrigin.X - (180d + parentMap.MapOrigin.X) * parentMap.ViewportScale;
|
||||
var offsetY = parentMap.ViewportOrigin.Y - (180d - parentMap.MapOrigin.Y) * parentMap.ViewportScale;
|
||||
|
||||
((MatrixTransform)RenderTransform).Matrix =
|
||||
new Matrix(1d, 0d, 0d, 1d, TileRect.X * TileSource.TileSize, TileRect.Y * TileSource.TileSize)
|
||||
new Matrix(1d, 0d, 0d, 1d, TileSource.TileSize * TileGrid.XMin, TileSource.TileSize * TileGrid.YMin)
|
||||
.Scale(scale, scale)
|
||||
.Translate(offsetX, offsetY)
|
||||
.RotateAt(parentMap.Heading, parentMap.ViewportOrigin.X, parentMap.ViewportOrigin.Y); ;
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ namespace MapControl
|
|||
{
|
||||
static TileLayer()
|
||||
{
|
||||
UIElement.IsHitTestVisibleProperty.OverrideMetadata(
|
||||
IsHitTestVisibleProperty.OverrideMetadata(
|
||||
typeof(TileLayer), new FrameworkPropertyMetadata(false));
|
||||
}
|
||||
|
||||
private Matrix GetTileIndexMatrix(int zoomLevel)
|
||||
private Rect GetTileIndexBounds(int zoomLevel)
|
||||
{
|
||||
var scale = (double)(1 << zoomLevel) / 360d;
|
||||
var transform = parentMap.ViewportTransform.Matrix;
|
||||
|
|
@ -25,16 +25,16 @@ namespace MapControl
|
|||
transform.Translate(180d, -180d);
|
||||
transform.Scale(scale, -scale); // map coordinates to tile indices
|
||||
|
||||
return transform;
|
||||
return new MatrixTransform(transform).TransformBounds(new Rect(parentMap.RenderSize));
|
||||
}
|
||||
|
||||
private void SetRenderTransform()
|
||||
{
|
||||
var scale = Math.Pow(2d, parentMap.ZoomLevel - TileZoomLevel);
|
||||
var scale = Math.Pow(2d, parentMap.ZoomLevel - TileGrid.ZoomLevel);
|
||||
var offsetX = parentMap.ViewportOrigin.X - (180d + parentMap.MapOrigin.X) * parentMap.ViewportScale;
|
||||
var offsetY = parentMap.ViewportOrigin.Y - (180d - parentMap.MapOrigin.Y) * parentMap.ViewportScale;
|
||||
|
||||
var transform = new Matrix(1d, 0d, 0d, 1d, TileRect.X * TileSource.TileSize, TileRect.Y * TileSource.TileSize);
|
||||
var transform = new Matrix(1d, 0d, 0d, 1d, TileSource.TileSize * TileGrid.XMin, TileSource.TileSize * TileGrid.YMin);
|
||||
transform.Scale(scale, scale);
|
||||
transform.Translate(offsetX, offsetY);
|
||||
transform.RotateAt(parentMap.Heading, parentMap.ViewportOrigin.X, parentMap.ViewportOrigin.Y);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ using System.Windows;
|
|||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
using System.Diagnostics;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
|
|
@ -58,7 +57,7 @@ namespace MapControl
|
|||
|
||||
public static readonly DependencyProperty ZoomLevelOffsetProperty = DependencyProperty.Register(
|
||||
"ZoomLevelOffset", typeof(double), typeof(TileLayer),
|
||||
new PropertyMetadata(0d, (o, e) => ((TileLayer)o).UpdateTileRect()));
|
||||
new PropertyMetadata(0d, (o, e) => ((TileLayer)o).UpdateTileGrid()));
|
||||
|
||||
public static readonly DependencyProperty MinZoomLevelProperty = DependencyProperty.Register(
|
||||
"MinZoomLevel", typeof(int), typeof(TileLayer), new PropertyMetadata(0));
|
||||
|
|
@ -98,18 +97,16 @@ namespace MapControl
|
|||
RenderTransform = new MatrixTransform();
|
||||
TileImageLoader = tileImageLoader;
|
||||
Tiles = new List<Tile>();
|
||||
TileZoomLevel = -1;
|
||||
|
||||
updateTimer = new DispatcherTimer { Interval = UpdateInterval };
|
||||
updateTimer.Tick += (s, e) => UpdateTileRect();
|
||||
updateTimer.Tick += (s, e) => UpdateTileGrid();
|
||||
}
|
||||
|
||||
partial void Initialize(); // Windows Runtime and Silverlight only
|
||||
|
||||
public ITileImageLoader TileImageLoader { get; private set; }
|
||||
public ICollection<Tile> Tiles { get; private set; }
|
||||
public Int32Rect TileRect { get; private set; }
|
||||
public int TileZoomLevel { get; private set; }
|
||||
public TileGrid TileGrid { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Provides map tile URIs or images.
|
||||
|
|
@ -228,8 +225,6 @@ namespace MapControl
|
|||
if (parentMap != null)
|
||||
{
|
||||
parentMap.ViewportChanged -= ViewportChanged;
|
||||
TileZoomLevel = -1;
|
||||
UpdateTiles(true);
|
||||
}
|
||||
|
||||
parentMap = value;
|
||||
|
|
@ -237,64 +232,62 @@ namespace MapControl
|
|||
if (parentMap != null)
|
||||
{
|
||||
parentMap.ViewportChanged += ViewportChanged;
|
||||
ViewportChanged(this, EventArgs.Empty);
|
||||
mapOriginX = parentMap.MapOrigin.X;
|
||||
}
|
||||
|
||||
UpdateTileGrid();
|
||||
}
|
||||
}
|
||||
|
||||
private void ViewportChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (TileZoomLevel < 0 || Math.Abs(parentMap.MapOrigin.X - mapOriginX) > 180d)
|
||||
if (TileGrid == null || Math.Abs(parentMap.MapOrigin.X - mapOriginX) > 180d)
|
||||
{
|
||||
// immediately handle map origin leap when map center moves across 180° longitude
|
||||
UpdateTileRect();
|
||||
UpdateTileGrid();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetRenderTransform();
|
||||
|
||||
if (!UpdateWhileViewportChanging)
|
||||
if (updateTimer.IsEnabled && !UpdateWhileViewportChanging)
|
||||
{
|
||||
updateTimer.Stop();
|
||||
updateTimer.Stop(); // restart
|
||||
}
|
||||
|
||||
updateTimer.Start();
|
||||
if (!updateTimer.IsEnabled)
|
||||
{
|
||||
updateTimer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
mapOriginX = parentMap.MapOrigin.X;
|
||||
}
|
||||
|
||||
protected void UpdateTileRect()
|
||||
protected void UpdateTileGrid()
|
||||
{
|
||||
updateTimer.Stop();
|
||||
|
||||
if (parentMap != null)
|
||||
{
|
||||
var zoomLevel = (int)Math.Round(parentMap.ZoomLevel + ZoomLevelOffset);
|
||||
var transform = GetTileIndexMatrix(zoomLevel);
|
||||
var zoomLevel = Math.Max(0, (int)Math.Round(parentMap.ZoomLevel + ZoomLevelOffset));
|
||||
var bounds = GetTileIndexBounds(zoomLevel);
|
||||
var tileGrid = new TileGrid(zoomLevel,
|
||||
(int)Math.Floor(bounds.X), (int)Math.Floor(bounds.Y),
|
||||
(int)Math.Floor(bounds.X + bounds.Width), (int)Math.Floor(bounds.Y + bounds.Height));
|
||||
|
||||
// tile indices of visible rectangle
|
||||
var p1 = transform.Transform(new Point(0d, 0d));
|
||||
var p2 = transform.Transform(new Point(parentMap.RenderSize.Width, 0d));
|
||||
var p3 = transform.Transform(new Point(0d, parentMap.RenderSize.Height));
|
||||
var p4 = transform.Transform(new Point(parentMap.RenderSize.Width, parentMap.RenderSize.Height));
|
||||
|
||||
// index ranges of visible tiles
|
||||
var x1 = (int)Math.Floor(Math.Min(p1.X, Math.Min(p2.X, Math.Min(p3.X, p4.X))));
|
||||
var y1 = (int)Math.Floor(Math.Min(p1.Y, Math.Min(p2.Y, Math.Min(p3.Y, p4.Y))));
|
||||
var x2 = (int)Math.Floor(Math.Max(p1.X, Math.Max(p2.X, Math.Max(p3.X, p4.X))));
|
||||
var y2 = (int)Math.Floor(Math.Max(p1.Y, Math.Max(p2.Y, Math.Max(p3.Y, p4.Y))));
|
||||
var rect = new Int32Rect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
|
||||
|
||||
if (TileZoomLevel != zoomLevel || TileRect != rect)
|
||||
if (!tileGrid.Equals(TileGrid))
|
||||
{
|
||||
TileZoomLevel = zoomLevel;
|
||||
TileRect = rect;
|
||||
|
||||
TileGrid = tileGrid;
|
||||
SetRenderTransform();
|
||||
UpdateTiles(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TileGrid = null;
|
||||
UpdateTiles(true);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void UpdateTiles(bool clearTiles)
|
||||
|
|
@ -328,9 +321,9 @@ namespace MapControl
|
|||
{
|
||||
var newTiles = new List<Tile>();
|
||||
|
||||
if (TileZoomLevel >= 0 && parentMap != null && TileSource != null)
|
||||
if (TileGrid != null && parentMap != null && TileSource != null)
|
||||
{
|
||||
var maxZoomLevel = Math.Min(TileZoomLevel, MaxZoomLevel);
|
||||
var maxZoomLevel = Math.Min(TileGrid.ZoomLevel, MaxZoomLevel);
|
||||
var minZoomLevel = MinZoomLevel;
|
||||
|
||||
if (minZoomLevel < maxZoomLevel && this != parentMap.TileLayers.FirstOrDefault())
|
||||
|
|
@ -341,11 +334,11 @@ namespace MapControl
|
|||
|
||||
for (var z = minZoomLevel; z <= maxZoomLevel; z++)
|
||||
{
|
||||
var tileSize = 1 << (TileZoomLevel - z);
|
||||
var x1 = (int)Math.Floor((double)TileRect.X / tileSize); // may be negative
|
||||
var x2 = (TileRect.X + TileRect.Width - 1) / tileSize;
|
||||
var y1 = Math.Max(TileRect.Y / tileSize, 0);
|
||||
var y2 = Math.Min((TileRect.Y + TileRect.Height - 1) / tileSize, (1 << z) - 1);
|
||||
var tileSize = 1 << (TileGrid.ZoomLevel - z);
|
||||
var x1 = (int)Math.Floor((double)TileGrid.XMin / tileSize); // may be negative
|
||||
var x2 = TileGrid.XMax / tileSize;
|
||||
var y1 = Math.Max(TileGrid.YMin / tileSize, 0);
|
||||
var y2 = Math.Min(TileGrid.YMax / tileSize, (1 << z) - 1);
|
||||
|
||||
for (var y = y1; y <= y2; y++)
|
||||
{
|
||||
|
|
@ -378,13 +371,13 @@ namespace MapControl
|
|||
|
||||
protected override Size ArrangeOverride(Size finalSize)
|
||||
{
|
||||
if (TileZoomLevel >= 0)
|
||||
if (TileGrid != null)
|
||||
{
|
||||
foreach (var tile in Tiles)
|
||||
{
|
||||
var tileSize = (double)(256 << (TileZoomLevel - tile.ZoomLevel));
|
||||
var x = tileSize * tile.X - 256 * TileRect.X;
|
||||
var y = tileSize * tile.Y - 256 * TileRect.Y;
|
||||
var tileSize = TileSource.TileSize << (TileGrid.ZoomLevel - tile.ZoomLevel);
|
||||
var x = tileSize * tile.X - TileSource.TileSize * TileGrid.XMin;
|
||||
var y = tileSize * tile.Y - TileSource.TileSize * TileGrid.YMin;
|
||||
|
||||
tile.Image.Width = tileSize;
|
||||
tile.Image.Height = tileSize;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace MapControl
|
|||
/// </summary>
|
||||
public partial class TileSource
|
||||
{
|
||||
public const double TileSize = 256;
|
||||
public const int TileSize = 256;
|
||||
public const double MetersPerDegree = 6378137d * Math.PI / 180d; // WGS 84 semi major axis
|
||||
|
||||
private Func<int, int, int, Uri> getUri;
|
||||
|
|
@ -165,15 +165,14 @@ namespace MapControl
|
|||
var east = MetersPerDegree * ((double)(x + 1) * tileSize - 180d);
|
||||
var south = MetersPerDegree * (180d - (double)(y + 1) * tileSize);
|
||||
var north = MetersPerDegree * (180d - (double)y * tileSize);
|
||||
var imageSize = TileSize.ToString("F0");
|
||||
|
||||
return new Uri(uriFormat
|
||||
.Replace("{W}", west.ToString(CultureInfo.InvariantCulture))
|
||||
.Replace("{S}", south.ToString(CultureInfo.InvariantCulture))
|
||||
.Replace("{E}", east.ToString(CultureInfo.InvariantCulture))
|
||||
.Replace("{N}", north.ToString(CultureInfo.InvariantCulture))
|
||||
.Replace("{X}", imageSize)
|
||||
.Replace("{Y}", imageSize));
|
||||
.Replace("{X}", TileSize.ToString())
|
||||
.Replace("{Y}", TileSize.ToString()));
|
||||
}
|
||||
|
||||
private Uri GetLatLonBoundingBoxUri(int x, int y, int zoomLevel)
|
||||
|
|
@ -183,15 +182,14 @@ namespace MapControl
|
|||
var east = (double)(x + 1) * tileSize - 180d;
|
||||
var south = MercatorTransform.YToLatitude(180d - (double)(y + 1) * tileSize);
|
||||
var north = MercatorTransform.YToLatitude(180d - (double)y * tileSize);
|
||||
var imageSize = TileSize.ToString("F0");
|
||||
|
||||
return new Uri(uriFormat
|
||||
.Replace("{w}", west.ToString(CultureInfo.InvariantCulture))
|
||||
.Replace("{s}", south.ToString(CultureInfo.InvariantCulture))
|
||||
.Replace("{e}", east.ToString(CultureInfo.InvariantCulture))
|
||||
.Replace("{n}", north.ToString(CultureInfo.InvariantCulture))
|
||||
.Replace("{X}", imageSize)
|
||||
.Replace("{Y}", imageSize));
|
||||
.Replace("{X}", TileSize.ToString())
|
||||
.Replace("{Y}", TileSize.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,9 +57,6 @@
|
|||
<Compile Include="..\IMapElement.cs">
|
||||
<Link>IMapElement.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Int32Rect.cs">
|
||||
<Link>Int32Rect.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ITileImageLoader.cs">
|
||||
<Link>ITileImageLoader.cs</Link>
|
||||
</Compile>
|
||||
|
|
@ -147,6 +144,9 @@
|
|||
<Compile Include="..\Tile.Silverlight.WinRT.cs">
|
||||
<Link>Tile.Silverlight.WinRT.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\TileGrid.cs">
|
||||
<Link>TileGrid.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\TileImageLoader.WinRT.cs">
|
||||
<Link>TileImageLoader.WinRT.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyCompany("Clemens Fischer")]
|
||||
[assembly: AssemblyCopyright("© 2015 Clemens Fischer")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyVersion("2.5.1")]
|
||||
[assembly: AssemblyFileVersion("2.5.1")]
|
||||
[assembly: AssemblyVersion("2.6.0")]
|
||||
[assembly: AssemblyFileVersion("2.6.0")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyCompany("Clemens Fischer")]
|
||||
[assembly: AssemblyCopyright("© 2015 Clemens Fischer")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyVersion("2.5.1")]
|
||||
[assembly: AssemblyFileVersion("2.5.1")]
|
||||
[assembly: AssemblyVersion("2.6.0")]
|
||||
[assembly: AssemblyFileVersion("2.6.0")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyCompany("Clemens Fischer")]
|
||||
[assembly: AssemblyCopyright("© 2015 Clemens Fischer")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyVersion("2.5.1")]
|
||||
[assembly: AssemblyFileVersion("2.5.1")]
|
||||
[assembly: AssemblyVersion("2.6.0")]
|
||||
[assembly: AssemblyFileVersion("2.6.0")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
Foreground="White" Background="Black"/>
|
||||
<map:TileLayer SourceName="MapQuest OpenStreetMap"
|
||||
Description="Maps © [MapQuest](http://www.mapquest.com/), Data © [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
|
||||
TileSource="http://otile{n}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png"
|
||||
TileSource="http://otile{n}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.jpg"
|
||||
MaxZoomLevel="19"/>
|
||||
<map:TileLayer SourceName="Seamarks"
|
||||
TileSource="http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png"
|
||||
|
|
@ -140,7 +140,7 @@
|
|||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<map:Map x:Name="map" TileLayer="{Binding [OpenStreetMap], Source={StaticResource TileLayers}}"
|
||||
Center="{Binding MapCenter}" MinZoomLevel="2" MaxZoomLevel="18" ZoomLevel="11"
|
||||
Center="{Binding MapCenter}" MinZoomLevel="2" ZoomLevel="11"
|
||||
MouseMove="MapMouseMove" MouseLeave="MapMouseLeave">
|
||||
|
||||
<map:MapImage x:Name="mapImage" South="53.54031" North="53.74871" West="8.08594" East="8.43750"
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyCompany("Clemens Fischer")]
|
||||
[assembly: AssemblyCopyright("© 2015 Clemens Fischer")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyVersion("2.5.1")]
|
||||
[assembly: AssemblyFileVersion("2.5.1")]
|
||||
[assembly: AssemblyVersion("2.6.0")]
|
||||
[assembly: AssemblyFileVersion("2.6.0")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyCopyright("© 2015 Clemens Fischer")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: AssemblyVersion("2.5.1")]
|
||||
[assembly: AssemblyFileVersion("2.5.1")]
|
||||
[assembly: AssemblyVersion("2.6.0")]
|
||||
[assembly: AssemblyFileVersion("2.6.0")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
</map:TileLayer>
|
||||
<map:TileLayer SourceName="MapQuest OpenStreetMap"
|
||||
Description="Maps © [MapQuest](http://www.mapquest.com/), Data © [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)">
|
||||
<map:TileSource UriFormat="http://otile{n}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png"/>
|
||||
<map:TileSource UriFormat="http://otile{n}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.jpg"/>
|
||||
</map:TileLayer>
|
||||
<map:TileLayer SourceName="Seamarks" Description="© OpenSeaMap Contributors"
|
||||
MinZoomLevel="10" MaxZoomLevel="18">
|
||||
|
|
@ -167,7 +167,7 @@
|
|||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<map:Map x:Name="map" TileLayer="{Binding [OpenStreetMap], Source={StaticResource TileLayers}}"
|
||||
Center="{Binding MapCenter}" MinZoomLevel="2" MaxZoomLevel="18" ZoomLevel="11" ManipulationMode="All">
|
||||
Center="{Binding MapCenter}" MinZoomLevel="2" ZoomLevel="11" ManipulationMode="All">
|
||||
<map:MapImage x:Name="mapImage" South="53.54031" North="53.74871" West="8.08594" East="8.43750"
|
||||
Source="10_535_330.jpg" Opacity="0.5"/>
|
||||
<map:MapGraticule Opacity="0.6"/>
|
||||
|
|
@ -194,7 +194,7 @@
|
|||
</Path.Data>
|
||||
</Path>
|
||||
|
||||
<map:MapPath Fill="Aqua" Opacity="0.5">
|
||||
<map:MapPath Stroke="Blue" Fill="Aqua" Opacity="0.5">
|
||||
<map:MapPath.Data>
|
||||
<GeometryGroup FillRule="EvenOdd">
|
||||
<EllipseGeometry Center="8.2,63.5" RadiusX="0.025" RadiusY="0.025"/>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyCopyright("© 2015 Clemens Fischer")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: AssemblyVersion("2.5.1")]
|
||||
[assembly: AssemblyFileVersion("2.5.1")]
|
||||
[assembly: AssemblyVersion("2.6.0")]
|
||||
[assembly: AssemblyFileVersion("2.6.0")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
Foreground="White" Background="Black"/>
|
||||
<map:TileLayer x:Key="MapQuest" SourceName="MapQuest OpenStreetMap"
|
||||
Description="Maps © [MapQuest](http://www.mapquest.com/), Data © [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
|
||||
TileSource="http://otile{n}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png"
|
||||
TileSource="http://otile{n}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.jpg"
|
||||
MaxZoomLevel="19"/>
|
||||
<map:TileLayer x:Key="Seamarks" SourceName="Seamarks"
|
||||
TileSource="http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png"
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyCompany("Clemens Fischer")]
|
||||
[assembly: AssemblyCopyright("© 2015 Clemens Fischer")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyVersion("2.5.1")]
|
||||
[assembly: AssemblyFileVersion("2.5.1")]
|
||||
[assembly: AssemblyVersion("2.6.0")]
|
||||
[assembly: AssemblyFileVersion("2.6.0")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
|
|
|||
Loading…
Reference in a new issue