Version 1.2.2: Added AnimateOpacity property to MapImage, TMS support to TileSource, Background and Foreground properties to TileLayer.

This commit is contained in:
ClemensF 2013-04-21 23:56:08 +02:00
parent 050f1acb38
commit c37149aafb
26 changed files with 229 additions and 129 deletions

View file

@ -4,6 +4,7 @@
#if NETFX_CORE
using Windows.Foundation;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;

View file

@ -7,7 +7,6 @@ using System.Collections.Specialized;
using System.Linq;
#if NETFX_CORE
using Windows.Foundation;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;
@ -31,18 +30,6 @@ namespace MapControl
public static TimeSpan AnimationDuration = TimeSpan.FromSeconds(0.5);
public static EasingFunctionBase AnimationEasingFunction = new QuadraticEase { EasingMode = EasingMode.EaseOut };
public static readonly DependencyProperty LightForegroundProperty = DependencyProperty.Register(
"LightForeground", typeof(Brush), typeof(MapBase), null);
public static readonly DependencyProperty DarkForegroundProperty = DependencyProperty.Register(
"DarkForeground", typeof(Brush), typeof(MapBase), null);
public static readonly DependencyProperty LightBackgroundProperty = DependencyProperty.Register(
"LightBackground", typeof(Brush), typeof(MapBase), new PropertyMetadata(new SolidColorBrush(Colors.Transparent), null));
public static readonly DependencyProperty DarkBackgroundProperty = DependencyProperty.Register(
"DarkBackground", typeof(Brush), typeof(MapBase), new PropertyMetadata(new SolidColorBrush(Colors.Transparent), null));
public static readonly DependencyProperty TileLayersProperty = DependencyProperty.Register(
"TileLayers", typeof(TileLayerCollection), typeof(MapBase), new PropertyMetadata(null,
(o, e) => ((MapBase)o).TileLayersPropertyChanged((TileLayerCollection)e.OldValue, (TileLayerCollection)e.NewValue)));
@ -104,13 +91,14 @@ namespace MapControl
private PointAnimation centerAnimation;
private DoubleAnimation zoomLevelAnimation;
private DoubleAnimation headingAnimation;
private Brush previousBackground;
private Brush previousForeground;
private bool internalPropertyChange;
public MapBase()
{
SetParentMap();
Background = LightBackground;
TileLayers = new TileLayerCollection();
Initialize();
@ -133,46 +121,6 @@ namespace MapControl
set { SetValue(ForegroundProperty, value); }
}
/// <summary>
/// Gets or sets a Brush that (when not null) is used as value of the
/// Foreground property when TileLayer.HasDarkBackground is false.
/// </summary>
public Brush LightForeground
{
get { return (Brush)GetValue(LightForegroundProperty); }
set { SetValue(LightForegroundProperty, value); }
}
/// <summary>
/// Gets or sets a Brush that (when not null) is used as value of the
/// Foreground property when TileLayer.HasDarkBackground is true.
/// </summary>
public Brush DarkForeground
{
get { return (Brush)GetValue(DarkForegroundProperty); }
set { SetValue(DarkForegroundProperty, value); }
}
/// <summary>
/// Gets or sets a Brush that (when not null) is used as value of the
/// Background property when TileLayer.HasDarkBackground is false.
/// </summary>
public Brush LightBackground
{
get { return (Brush)GetValue(LightBackgroundProperty); }
set { SetValue(LightBackgroundProperty, value); }
}
/// <summary>
/// Gets or sets a Brush that (when not null) is used as value of the
/// Background property when TileLayer.HasDarkBackground is true.
/// </summary>
public Brush DarkBackground
{
get { return (Brush)GetValue(DarkBackgroundProperty); }
set { SetValue(DarkBackgroundProperty, value); }
}
/// <summary>
/// Gets or sets the TileLayers used by this Map.
/// </summary>
@ -536,29 +484,34 @@ namespace MapControl
}
}
if (tileLayer != null && tileLayer.HasDarkBackground)
if (tileLayer != null && tileLayer.Background != null)
{
if (DarkForeground != null)
if (previousBackground == null)
{
Foreground = DarkForeground;
previousBackground = Background;
}
if (DarkBackground != null)
{
Background = DarkBackground;
}
Background = tileLayer.Background;
}
else
else if (previousBackground != null)
{
if (LightForeground != null)
Background = previousBackground;
previousBackground = null;
}
if (tileLayer != null && tileLayer.Foreground != null)
{
if (previousForeground == null)
{
Foreground = LightForeground;
previousForeground = Foreground;
}
if (LightBackground != null)
{
Background = LightBackground;
}
Foreground = tileLayer.Foreground;
}
else if (previousForeground != null)
{
Foreground = previousForeground;
previousForeground = null;
}
}

View file

@ -76,6 +76,7 @@
<Compile Include="MapGraticule.cs" />
<Compile Include="MapGraticule.Silverlight.WinRT.cs" />
<Compile Include="MapImage.cs" />
<Compile Include="MapImage.Silverlight.WinRT.cs" />
<Compile Include="MapItem.Silverlight.WinRT.cs" />
<Compile Include="MapItemsControl.cs" />
<Compile Include="MapItemsControl.Silverlight.WinRT.cs" />

View file

@ -56,6 +56,7 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="MapBase.WPF.cs" />
<Compile Include="MapImage.WPF.cs" />
<Compile Include="MapItem.WPF.cs" />
<Compile Include="MapItemsControl.cs" />
<Compile Include="MapItemsControl.WPF.cs" />

View file

@ -0,0 +1,49 @@
// XAML Map Control - http://xamlmapcontrol.codeplex.com/
// Copyright © 2013 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
#if NETFX_CORE
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
#else
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
#endif
namespace MapControl
{
public partial class MapImage
{
private void BeginOpacityAnimation(ImageSource image)
{
var bitmapImage = image as BitmapImage;
if (bitmapImage != null)
{
bitmapImage.ImageOpened += BitmapImageOpened;
bitmapImage.ImageFailed += BitmapImageFailed;
}
else
{
BeginOpacityAnimation();
}
}
private void BitmapImageOpened(object sender, RoutedEventArgs e)
{
((BitmapImage)sender).ImageOpened -= BitmapImageOpened;
((BitmapImage)sender).ImageFailed -= BitmapImageFailed;
BeginOpacityAnimation();
}
private void BitmapImageFailed(object sender, ExceptionRoutedEventArgs e)
{
((BitmapImage)sender).ImageOpened -= BitmapImageOpened;
((BitmapImage)sender).ImageFailed -= BitmapImageFailed;
((ImageBrush)Fill).ImageSource = null;
}
}
}

View file

@ -0,0 +1,42 @@
// XAML Map Control - http://xamlmapcontrol.codeplex.com/
// Copyright © 2013 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
using System;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace MapControl
{
public partial class MapImage
{
private void BeginOpacityAnimation(ImageSource image)
{
var bitmapImage = image as BitmapImage;
if (bitmapImage != null && bitmapImage.IsDownloading)
{
bitmapImage.DownloadCompleted += BitmapDownloadCompleted;
bitmapImage.DownloadFailed += BitmapDownloadFailed;
}
else
{
BeginOpacityAnimation();
}
}
private void BitmapDownloadCompleted(object sender, EventArgs e)
{
((BitmapImage)sender).DownloadCompleted -= BitmapDownloadCompleted;
((BitmapImage)sender).DownloadFailed -= BitmapDownloadFailed;
BeginOpacityAnimation();
}
private void BitmapDownloadFailed(object sender, ExceptionEventArgs e)
{
((BitmapImage)sender).DownloadCompleted -= BitmapDownloadCompleted;
((BitmapImage)sender).DownloadFailed -= BitmapDownloadFailed;
((ImageBrush)Fill).ImageSource = null;
}
}
}

View file

@ -5,14 +5,16 @@
#if NETFX_CORE
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;
#else
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
#endif
namespace MapControl
{
public class MapImage : MapRectangle
public partial class MapImage : MapRectangle
{
private static readonly Transform imageTransform = new MatrixTransform
{
@ -29,13 +31,36 @@ namespace MapControl
set { SetValue(SourceProperty, value); }
}
private void SourceChanged(ImageSource source)
public bool AnimateOpacity { get; set; }
private void SourceChanged(ImageSource image)
{
Fill = new ImageBrush
{
ImageSource = source,
RelativeTransform = imageTransform
ImageSource = image,
RelativeTransform = imageTransform,
Opacity = 0d
};
if (AnimateOpacity)
{
BeginOpacityAnimation(image);
}
else
{
Fill.Opacity = 1d;
}
}
private void BeginOpacityAnimation()
{
Fill.BeginAnimation(Brush.OpacityProperty,
new DoubleAnimation
{
To = 1d,
Duration = Tile.AnimationDuration,
FillBehavior = FillBehavior.HoldEnd
});
}
}
}

View file

@ -16,6 +16,6 @@ using System.Windows;
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: AssemblyVersion("1.2.1")]
[assembly: AssemblyFileVersion("1.2.1")]
[assembly: AssemblyVersion("1.2.2")]
[assembly: AssemblyFileVersion("1.2.2")]
[assembly: ComVisible(false)]

View file

@ -6,11 +6,13 @@
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Media.Imaging;
#else
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
#endif
@ -18,7 +20,7 @@ namespace MapControl
{
public partial class Tile
{
public readonly Image Image = new Image { IsHitTestVisible = false, Opacity = 0d };
public readonly Image Image = new Image { Opacity = 0d };
public ImageSource ImageSource
{
@ -40,7 +42,7 @@ namespace MapControl
}
else
{
Image.BeginAnimation(Image.OpacityProperty, OpacityAnimation);
BeginOpacityAnimation();
}
}
else
@ -57,7 +59,7 @@ namespace MapControl
{
((BitmapImage)sender).ImageOpened -= BitmapImageOpened;
((BitmapImage)sender).ImageFailed -= BitmapImageFailed;
Image.BeginAnimation(Image.OpacityProperty, OpacityAnimation);
BeginOpacityAnimation();
}
private void BitmapImageFailed(object sender, ExceptionRoutedEventArgs e)
@ -66,5 +68,16 @@ namespace MapControl
((BitmapImage)sender).ImageFailed -= BitmapImageFailed;
Image.Source = null;
}
private void BeginOpacityAnimation()
{
Image.BeginAnimation(Image.OpacityProperty,
new DoubleAnimation
{
To = 1d,
Duration = AnimationDuration,
FillBehavior = FillBehavior.HoldEnd
});
}
}
}

View file

@ -4,6 +4,7 @@
using System;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
@ -33,7 +34,7 @@ namespace MapControl
}
else
{
Brush.BeginAnimation(ImageBrush.OpacityProperty, OpacityAnimation);
BeginOpacityAnimation();
}
}
else
@ -50,7 +51,7 @@ namespace MapControl
{
((BitmapImage)sender).DownloadCompleted -= BitmapDownloadCompleted;
((BitmapImage)sender).DownloadFailed -= BitmapDownloadFailed;
Brush.BeginAnimation(ImageBrush.OpacityProperty, OpacityAnimation);
BeginOpacityAnimation();
}
private void BitmapDownloadFailed(object sender, ExceptionEventArgs e)
@ -59,5 +60,16 @@ namespace MapControl
((BitmapImage)sender).DownloadFailed -= BitmapDownloadFailed;
Brush.ImageSource = null;
}
private void BeginOpacityAnimation()
{
Brush.BeginAnimation(ImageBrush.OpacityProperty,
new DoubleAnimation
{
To = 1d,
Duration = AnimationDuration,
FillBehavior = FillBehavior.HoldEnd
});
}
}
}

View file

@ -3,11 +3,6 @@
// Licensed under the Microsoft Public License (Ms-PL)
using System;
#if NETFX_CORE
using Windows.UI.Xaml.Media.Animation;
#else
using System.Windows.Media.Animation;
#endif
namespace MapControl
{
@ -36,18 +31,5 @@ namespace MapControl
return ((X % numTiles) + numTiles) % numTiles;
}
}
public DoubleAnimation OpacityAnimation
{
get
{
return new DoubleAnimation
{
To = 1d,
Duration = AnimationDuration,
FillBehavior = FillBehavior.HoldEnd,
};
}
}
}
}

View file

@ -64,7 +64,8 @@ namespace MapControl
public int MaxZoomLevel { get; set; }
public int MaxParallelDownloads { get; set; }
public bool LoadLowerZoomLevels { get; set; }
public bool HasDarkBackground { get; set; }
public Brush Background { get; set; }
public Brush Foreground { get; set; }
public string Description
{
@ -122,9 +123,12 @@ namespace MapControl
{
var tileSize = 1 << (zoomLevel - z);
var x1 = grid.X / tileSize;
var y1 = grid.Y / tileSize;
var x2 = (grid.X + grid.Width - 1) / tileSize;
var y1 = Math.Max(0, grid.Y / tileSize);
var y2 = Math.Min((1 << z) - 1, (grid.Y + grid.Height - 1) / tileSize);
var y2 = (grid.Y + grid.Height - 1) / tileSize;
y1 = Math.Max(y1, 0);
y2 = Math.Min(y2, (1 << z) - 1);
for (var y = y1; y <= y2; y++)
{

View file

@ -68,6 +68,10 @@ namespace MapControl
{
getUri = GetBoundingBoxUri;
}
else if (uriFormat.Contains("{x}") && uriFormat.Contains("{v}") && uriFormat.Contains("{z}"))
{
getUri = GetTmsUri;
}
}
}
@ -117,6 +121,16 @@ namespace MapControl
Replace("{z}", zoomLevel.ToString()));
}
private Uri GetTmsUri(int x, int y, int zoomLevel)
{
y = (1 << zoomLevel) - 1 - y;
return new Uri(UriFormat.
Replace("{x}", x.ToString()).
Replace("{v}", y.ToString()).
Replace("{z}", zoomLevel.ToString()));
}
private Uri GetQuadKeyUri(int x, int y, int zoomLevel)
{
var key = new StringBuilder { Length = zoomLevel };

View file

@ -66,6 +66,9 @@
<Compile Include="..\MapImage.cs">
<Link>MapImage.cs</Link>
</Compile>
<Compile Include="..\MapImage.Silverlight.WinRT.cs">
<Link>MapImage.Silverlight.WinRT.cs</Link>
</Compile>
<Compile Include="..\MapItem.Silverlight.WinRT.cs">
<Link>MapItem.Silverlight.WinRT.cs</Link>
</Compile>

View file

@ -9,6 +9,6 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: AssemblyVersion("1.2.1")]
[assembly: AssemblyFileVersion("1.2.1")]
[assembly: AssemblyVersion("1.2.2")]
[assembly: AssemblyFileVersion("1.2.2")]
[assembly: ComVisible(false)]