diff --git a/Caching/FileDbCache/Properties/AssemblyInfo.cs b/Caching/FileDbCache/Properties/AssemblyInfo.cs
index 1eb7888d..e81e01a7 100644
--- a/Caching/FileDbCache/Properties/AssemblyInfo.cs
+++ b/Caching/FileDbCache/Properties/AssemblyInfo.cs
@@ -8,8 +8,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
-[assembly: AssemblyVersion("1.11.3")]
-[assembly: AssemblyFileVersion("1.11.3")]
+[assembly: AssemblyVersion("1.12.0")]
+[assembly: AssemblyFileVersion("1.12.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
diff --git a/Caching/ImageFileCache/Properties/AssemblyInfo.cs b/Caching/ImageFileCache/Properties/AssemblyInfo.cs
index 25370e73..9991b02f 100644
--- a/Caching/ImageFileCache/Properties/AssemblyInfo.cs
+++ b/Caching/ImageFileCache/Properties/AssemblyInfo.cs
@@ -8,8 +8,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
-[assembly: AssemblyVersion("1.11.3")]
-[assembly: AssemblyFileVersion("1.11.3")]
+[assembly: AssemblyVersion("1.12.0")]
+[assembly: AssemblyFileVersion("1.12.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
diff --git a/MapControl/MapControl.Silverlight.csproj b/MapControl/MapControl.Silverlight.csproj
index b5b8468c..401338c1 100644
--- a/MapControl/MapControl.Silverlight.csproj
+++ b/MapControl/MapControl.Silverlight.csproj
@@ -82,6 +82,8 @@
+
+
diff --git a/MapControl/MapControl.WPF.csproj b/MapControl/MapControl.WPF.csproj
index 838c8ad3..0a1165ba 100644
--- a/MapControl/MapControl.WPF.csproj
+++ b/MapControl/MapControl.WPF.csproj
@@ -66,6 +66,7 @@
+
diff --git a/MapControl/MapImageLayer.Silverlight.WinRT.cs b/MapControl/MapImageLayer.Silverlight.WinRT.cs
new file mode 100644
index 00000000..d697ba6a
--- /dev/null
+++ b/MapControl/MapImageLayer.Silverlight.WinRT.cs
@@ -0,0 +1,56 @@
+// XAML Map Control - http://xamlmapcontrol.codeplex.com/
+// Copyright © 2014 Clemens Fischer
+// Licensed under the Microsoft Public License (Ms-PL)
+
+#if NETFX_CORE
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Media.Imaging;
+#else
+using System.Windows;
+using System.Windows.Media.Imaging;
+using System.Windows.Threading;
+#endif
+
+namespace MapControl
+{
+ public partial class MapImageLayer
+ {
+ private readonly DispatcherTimer updateTimer = new DispatcherTimer();
+
+ private void AddDownloadEventHandlers(BitmapSource bitmap)
+ {
+ var bitmapImage = bitmap as BitmapImage;
+
+ if (bitmapImage != null)
+ {
+ bitmapImage.ImageOpened += BitmapImageOpened;
+ bitmapImage.ImageFailed += BitmapImageFailed;
+ }
+ else
+ {
+ BlendImages();
+ }
+ }
+
+ private void BitmapImageOpened(object sender, RoutedEventArgs e)
+ {
+ var bitmap = (BitmapImage)sender;
+
+ bitmap.ImageOpened -= BitmapImageOpened;
+ bitmap.ImageFailed -= BitmapImageFailed;
+
+ BlendImages();
+ }
+
+ private void BitmapImageFailed(object sender, ExceptionRoutedEventArgs e)
+ {
+ var bitmap = (BitmapImage)sender;
+
+ bitmap.ImageOpened -= BitmapImageOpened;
+ bitmap.ImageFailed -= BitmapImageFailed;
+
+ ((MapImage)Children[currentImageIndex]).Source = null;
+ BlendImages();
+ }
+ }
+}
diff --git a/MapControl/MapImageLayer.WPF.cs b/MapControl/MapImageLayer.WPF.cs
new file mode 100644
index 00000000..ba3d2aa3
--- /dev/null
+++ b/MapControl/MapImageLayer.WPF.cs
@@ -0,0 +1,50 @@
+// XAML Map Control - http://xamlmapcontrol.codeplex.com/
+// Copyright © 2014 Clemens Fischer
+// Licensed under the Microsoft Public License (Ms-PL)
+
+using System;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Threading;
+
+namespace MapControl
+{
+ public partial class MapImageLayer
+ {
+ private readonly DispatcherTimer updateTimer = new DispatcherTimer(DispatcherPriority.Background);
+
+ private void AddDownloadEventHandlers(BitmapSource bitmap)
+ {
+ if (bitmap.IsDownloading)
+ {
+ bitmap.DownloadCompleted += BitmapDownloadCompleted;
+ bitmap.DownloadFailed += BitmapDownloadFailed;
+ }
+ else
+ {
+ BlendImages();
+ }
+ }
+
+ private void BitmapDownloadCompleted(object sender, EventArgs e)
+ {
+ var bitmap = (BitmapSource)sender;
+
+ bitmap.DownloadCompleted -= BitmapDownloadCompleted;
+ bitmap.DownloadFailed -= BitmapDownloadFailed;
+
+ BlendImages();
+ }
+
+ private void BitmapDownloadFailed(object sender, ExceptionEventArgs e)
+ {
+ var bitmap = (BitmapSource)sender;
+
+ bitmap.DownloadCompleted -= BitmapDownloadCompleted;
+ bitmap.DownloadFailed -= BitmapDownloadFailed;
+
+ ((MapImage)Children[currentImageIndex]).Source = null;
+ BlendImages();
+ }
+ }
+}
diff --git a/MapControl/MapImageLayer.cs b/MapControl/MapImageLayer.cs
index 6ea06117..b79c5394 100644
--- a/MapControl/MapImageLayer.cs
+++ b/MapControl/MapImageLayer.cs
@@ -3,35 +3,34 @@
// Licensed under the Microsoft Public License (Ms-PL)
using System;
-using System.Diagnostics;
using System.Globalization;
-using System.IO;
-using System.Net;
-using System.Threading;
+#if NETFX_CORE
+using Windows.Foundation;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Media.Imaging;
+using Windows.UI.Xaml.Media.Animation;
+#else
using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
-using System.Windows.Threading;
+#endif
namespace MapControl
{
///
/// Map image overlay. Fills the entire viewport with a map image from a web request,
/// for example from a Web Map Service (WMS).
- /// The request Uri is specified by the UriFormat property, which has {X} and {Y}
- /// format specifiers for the map width and height in pixels, and either
- /// {w},{s},{e},{n} for the bounding box in lat/lon (like for example EPSG:4326) or
- /// {W},{S},{E},{N} for the bounding box in meters (like for example EPSG:3857)
+ /// The image request Uri is specified by the UriFormat property.
///
- public class MapImageLayer : MapPanel
+ public partial class MapImageLayer : MapPanel
{
+ public static readonly DependencyProperty UriFormatProperty = DependencyProperty.Register(
+ "UriFormat", typeof(string), typeof(MapImageLayer),
+ new PropertyMetadata(null, (o, e) => ((MapImageLayer)o).UpdateImage()));
+
public static readonly DependencyProperty RelativeImageSizeProperty = DependencyProperty.Register(
"RelativeImageSize", typeof(double), typeof(MapImageLayer), new PropertyMetadata(1d));
- private readonly DispatcherTimer updateTimer;
- private string uriFormat;
private int currentImageIndex;
private bool updateInProgress;
@@ -40,8 +39,20 @@ namespace MapControl
Children.Add(new MapImage { Opacity = 0d });
Children.Add(new MapImage { Opacity = 0d });
- updateTimer = new DispatcherTimer { Interval = TileContainer.UpdateInterval };
- updateTimer.Tick += UpdateImage;
+ updateTimer.Interval = TileContainer.UpdateInterval;
+ updateTimer.Tick += (o, e) => UpdateImage();
+ }
+
+ ///
+ /// The format string of the image request Uri. The format must contain {X} and {Y}
+ /// format specifiers for the map width and height in pixels, and either
+ /// {w},{s},{e},{n} for the bounding box in lat/lon (like for example EPSG:4326) or
+ /// {W},{S},{E},{N} for the bounding box in meters (like for example EPSG:3857).
+ ///
+ public string UriFormat
+ {
+ get { return (string)GetValue(UriFormatProperty); }
+ set { SetValue(UriFormatProperty, value); }
}
///
@@ -55,31 +66,6 @@ namespace MapControl
set { SetValue(RelativeImageSizeProperty, value); }
}
- public string UriFormat
- {
- get { return uriFormat; }
- set
- {
- if (value != null)
- {
- if (!(value.Contains("{X}") && value.Contains("{Y}")))
- {
- throw new ArgumentException("UriFormat must specify the requested image size by {X} and {Y}.");
- }
-
- if (!(value.Contains("{W}") && value.Contains("{S}") && value.Contains("{E}") && value.Contains("{N}")) &&
- !(value.Contains("{w}") && value.Contains("{s}") && value.Contains("{e}") && value.Contains("{n}")))
- {
- throw new ArgumentException("UriFormat must specify a bounding box in meters by {W},{S},{E},{N} or lat/lon by {w},{s},{e},{n}.");
- }
- }
-
- uriFormat = value;
-
- UpdateImage(this, EventArgs.Empty);
- }
- }
-
protected override void OnViewportChanged()
{
base.OnViewportChanged();
@@ -88,13 +74,13 @@ namespace MapControl
updateTimer.Start();
}
- protected virtual ImageSource GetImage(double west, double east, double south, double north, int width, int height)
+ protected virtual BitmapSource GetBitmap(double west, double east, double south, double north, int width, int height)
{
- ImageSource image = null;
+ BitmapImage image = null;
- if (uriFormat != null)
+ if (UriFormat != null && width > 0 && height > 0)
{
- var uri = uriFormat.Replace("{X}", width.ToString()).Replace("{Y}", height.ToString());
+ var uri = UriFormat.Replace("{X}", width.ToString()).Replace("{Y}", height.ToString());
if (uri.Contains("{W}") && uri.Contains("{S}") && uri.Contains("{E}") && uri.Contains("{N}"))
{
@@ -117,55 +103,37 @@ namespace MapControl
Replace("{n}", north.ToString(CultureInfo.InvariantCulture));
}
- try
- {
- var request = (HttpWebRequest)WebRequest.Create(uri);
- request.UserAgent = "XAML Map Control";
-
- using (var response = (HttpWebResponse)request.GetResponse())
- using (var responseStream = response.GetResponseStream())
- using (var memoryStream = new MemoryStream())
- {
- responseStream.CopyTo(memoryStream);
- memoryStream.Position = 0;
- image = BitmapFrame.Create(memoryStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
- }
- }
- catch (Exception ex)
- {
- Trace.TraceWarning("{0}: {1}", uri, ex.Message);
- }
+ image = new BitmapImage(new Uri(uri));
}
return image;
}
- private void UpdateImage(object sender, EventArgs e)
+ protected void UpdateImage()
{
if (updateInProgress)
{
- return; // update image on next timer tick
+ updateTimer.Start(); // update image on next timer tick
}
-
- updateTimer.Stop();
-
- if (ParentMap != null && ActualWidth > 0 && ActualHeight > 0)
+ else
{
- updateInProgress = true;
+ updateTimer.Stop();
- var relativeSize = Math.Max(RelativeImageSize, 1d);
- var width = ActualWidth * relativeSize;
- var height = ActualHeight * relativeSize;
- var dx = (ActualWidth - width) / 2d;
- var dy = (ActualHeight - height) / 2d;
-
- var loc1 = ParentMap.ViewportPointToLocation(new Point(dx, dy));
- var loc2 = ParentMap.ViewportPointToLocation(new Point(dx + width, dy));
- var loc3 = ParentMap.ViewportPointToLocation(new Point(dx, dy + height));
- var loc4 = ParentMap.ViewportPointToLocation(new Point(dx + width, dy + height));
-
- ThreadPool.QueueUserWorkItem(o =>
+ if (ParentMap != null && ActualWidth > 0 && ActualHeight > 0)
{
+ updateInProgress = true;
+
+ var relativeSize = Math.Max(RelativeImageSize, 1d);
+ var width = ActualWidth * relativeSize;
+ var height = ActualHeight * relativeSize;
+ var dx = (ActualWidth - width) / 2d;
+ var dy = (ActualHeight - height) / 2d;
+
+ var loc1 = ParentMap.ViewportPointToLocation(new Point(dx, dy));
+ var loc2 = ParentMap.ViewportPointToLocation(new Point(dx + width, dy));
+ var loc3 = ParentMap.ViewportPointToLocation(new Point(dx, dy + height));
+ var loc4 = ParentMap.ViewportPointToLocation(new Point(dx + width, dy + height));
+
var west = Math.Min(loc1.Longitude, Math.Min(loc2.Longitude, Math.Min(loc3.Longitude, loc4.Longitude)));
var east = Math.Max(loc1.Longitude, Math.Max(loc2.Longitude, Math.Max(loc3.Longitude, loc4.Longitude)));
var south = Math.Min(loc1.Latitude, Math.Min(loc2.Latitude, Math.Min(loc3.Latitude, loc4.Latitude)));
@@ -177,36 +145,58 @@ namespace MapControl
width = Math.Round((p2.X - p1.X) * ParentMap.ViewportScale);
height = Math.Round((p2.Y - p1.Y) * ParentMap.ViewportScale);
- var image = GetImage(west, east, south, north, (int)width, (int)height);
+ var image = GetBitmap(west, east, south, north, (int)width, (int)height);
- Dispatcher.BeginInvoke(new Action(() => UpdateImage(west, east, south, north, image)));
-
- updateInProgress = false;
- });
+ UpdateImage(west, east, south, north, image);
+ }
}
}
- private void UpdateImage(double west, double east, double south, double north, ImageSource image)
+ private void UpdateImage(double west, double east, double south, double north, BitmapSource image)
{
- var mapImage = (MapImage)Children[currentImageIndex];
- mapImage.BeginAnimation(UIElement.OpacityProperty,
- new DoubleAnimation
- {
- To = 0d,
- Duration = Tile.AnimationDuration,
- BeginTime = Tile.AnimationDuration
- });
-
currentImageIndex = (currentImageIndex + 1) % 2;
- mapImage = (MapImage)Children[currentImageIndex];
+ var mapImage = (MapImage)Children[currentImageIndex];
+
mapImage.Source = null;
mapImage.North = double.NaN; // avoid frequent MapRectangle.UpdateData() calls
mapImage.West = west;
mapImage.East = east;
mapImage.South = south;
mapImage.North = north;
- mapImage.Source = image;
- mapImage.BeginAnimation(UIElement.OpacityProperty, new DoubleAnimation(1d, Tile.AnimationDuration));
+
+ if (image != null)
+ {
+ mapImage.Source = image;
+ AddDownloadEventHandlers(image);
+ }
+ else
+ {
+ BlendImages();
+ }
+ }
+
+ private void BlendImages()
+ {
+#if NETFX_CORE
+ var duration = TimeSpan.Zero; // animation not working in WinRT (?)
+#else
+ var duration = Tile.AnimationDuration;
+#endif
+ var mapImage = (MapImage)Children[currentImageIndex];
+ var fadeOut = new DoubleAnimation { To = 0d, Duration = duration };
+
+ if (mapImage.Source != null)
+ {
+ mapImage.BeginAnimation(UIElement.OpacityProperty,
+ new DoubleAnimation { To = 1d, Duration = duration });
+
+ fadeOut.BeginTime = duration;
+ }
+
+ mapImage = (MapImage)Children[(currentImageIndex + 1) % 2];
+ mapImage.BeginAnimation(UIElement.OpacityProperty, fadeOut);
+
+ updateInProgress = false;
}
}
}
diff --git a/MapControl/MapPanel.cs b/MapControl/MapPanel.cs
index f5e7aba6..2c709f11 100644
--- a/MapControl/MapPanel.cs
+++ b/MapControl/MapPanel.cs
@@ -16,7 +16,7 @@ using System.Windows.Media;
namespace MapControl
{
- internal interface IMapElement
+ public interface IMapElement
{
MapBase ParentMap { get; set; }
}
diff --git a/MapControl/Properties/AssemblyInfo.cs b/MapControl/Properties/AssemblyInfo.cs
index b2a431d0..4cde0355 100644
--- a/MapControl/Properties/AssemblyInfo.cs
+++ b/MapControl/Properties/AssemblyInfo.cs
@@ -15,8 +15,8 @@ using System.Windows;
[assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
-[assembly: AssemblyVersion("1.11.3")]
-[assembly: AssemblyFileVersion("1.11.3")]
+[assembly: AssemblyVersion("1.12.0")]
+[assembly: AssemblyFileVersion("1.12.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
diff --git a/MapControl/WinRT/MapControl.WinRT.csproj b/MapControl/WinRT/MapControl.WinRT.csproj
index 8f42a682..cd2ebb61 100644
--- a/MapControl/WinRT/MapControl.WinRT.csproj
+++ b/MapControl/WinRT/MapControl.WinRT.csproj
@@ -69,6 +69,12 @@
MapImage.cs
+
+ MapImageLayer.cs
+
+
+ MapImageLayer.Silverlight.WinRT.cs
+
MapItem.Silverlight.WinRT.cs
diff --git a/MapControl/WinRT/Properties/AssemblyInfo.cs b/MapControl/WinRT/Properties/AssemblyInfo.cs
index 6fa0e30e..da6d02d7 100644
--- a/MapControl/WinRT/Properties/AssemblyInfo.cs
+++ b/MapControl/WinRT/Properties/AssemblyInfo.cs
@@ -8,8 +8,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
-[assembly: AssemblyVersion("1.11.3")]
-[assembly: AssemblyFileVersion("1.11.3")]
+[assembly: AssemblyVersion("1.12.0")]
+[assembly: AssemblyFileVersion("1.12.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
diff --git a/SampleApps/SilverlightApplication.Web/Properties/AssemblyInfo.cs b/SampleApps/SilverlightApplication.Web/Properties/AssemblyInfo.cs
index 5984ef62..e941c3ff 100644
--- a/SampleApps/SilverlightApplication.Web/Properties/AssemblyInfo.cs
+++ b/SampleApps/SilverlightApplication.Web/Properties/AssemblyInfo.cs
@@ -8,8 +8,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
-[assembly: AssemblyVersion("1.11.3")]
-[assembly: AssemblyFileVersion("1.11.3")]
+[assembly: AssemblyVersion("1.12.0")]
+[assembly: AssemblyFileVersion("1.12.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
diff --git a/SampleApps/SilverlightApplication/Properties/AssemblyInfo.cs b/SampleApps/SilverlightApplication/Properties/AssemblyInfo.cs
index 430ea902..9dc2dafa 100644
--- a/SampleApps/SilverlightApplication/Properties/AssemblyInfo.cs
+++ b/SampleApps/SilverlightApplication/Properties/AssemblyInfo.cs
@@ -8,8 +8,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
-[assembly: AssemblyVersion("1.11.3")]
-[assembly: AssemblyFileVersion("1.11.3")]
+[assembly: AssemblyVersion("1.12.0")]
+[assembly: AssemblyFileVersion("1.12.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
diff --git a/SampleApps/StoreApplication/Properties/AssemblyInfo.cs b/SampleApps/StoreApplication/Properties/AssemblyInfo.cs
index 592db174..b6f6f582 100644
--- a/SampleApps/StoreApplication/Properties/AssemblyInfo.cs
+++ b/SampleApps/StoreApplication/Properties/AssemblyInfo.cs
@@ -8,8 +8,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
-[assembly: AssemblyVersion("1.11.3")]
-[assembly: AssemblyFileVersion("1.11.3")]
+[assembly: AssemblyVersion("1.12.0")]
+[assembly: AssemblyFileVersion("1.12.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
diff --git a/SampleApps/SurfaceApplication/Properties/AssemblyInfo.cs b/SampleApps/SurfaceApplication/Properties/AssemblyInfo.cs
index 36f811f1..26248a2c 100644
--- a/SampleApps/SurfaceApplication/Properties/AssemblyInfo.cs
+++ b/SampleApps/SurfaceApplication/Properties/AssemblyInfo.cs
@@ -8,8 +8,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
-[assembly: AssemblyVersion("1.11.3")]
-[assembly: AssemblyFileVersion("1.11.3")]
+[assembly: AssemblyVersion("1.12.0")]
+[assembly: AssemblyFileVersion("1.12.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
diff --git a/SampleApps/WpfApplication/Properties/AssemblyInfo.cs b/SampleApps/WpfApplication/Properties/AssemblyInfo.cs
index 87fb6f63..32396387 100644
--- a/SampleApps/WpfApplication/Properties/AssemblyInfo.cs
+++ b/SampleApps/WpfApplication/Properties/AssemblyInfo.cs
@@ -8,8 +8,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
-[assembly: AssemblyVersion("1.11.3")]
-[assembly: AssemblyFileVersion("1.11.3")]
+[assembly: AssemblyVersion("1.12.0")]
+[assembly: AssemblyFileVersion("1.12.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]