diff --git a/Caching/FileDbCache.WPF/FileDbCache.cs b/Caching/FileDbCache.WPF/FileDbCache.cs index 1bd55a4b..b7942d65 100644 --- a/Caching/FileDbCache.WPF/FileDbCache.cs +++ b/Caching/FileDbCache.WPF/FileDbCache.cs @@ -62,14 +62,14 @@ namespace MapControl.Caching public FileDbCache(string name, string folder) { - if (string.IsNullOrWhiteSpace(name)) + if (string.IsNullOrEmpty(name)) { - throw new ArgumentException("The parameter name must not be null or empty or consist only of white-space characters."); + throw new ArgumentException("The parameter name must not be null or empty."); } - if (string.IsNullOrWhiteSpace(folder)) + if (string.IsNullOrEmpty(folder)) { - throw new ArgumentException("The parameter folder must not be null or empty or consist only of white-space characters."); + throw new ArgumentException("The parameter folder must not be null or empty."); } this.name = name; diff --git a/Caching/FileDbCache.WPF/Properties/AssemblyInfo.cs b/Caching/FileDbCache.WPF/Properties/AssemblyInfo.cs index 47d332df..a6c78ec7 100644 --- a/Caching/FileDbCache.WPF/Properties/AssemblyInfo.cs +++ b/Caching/FileDbCache.WPF/Properties/AssemblyInfo.cs @@ -7,8 +7,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCopyright("© 2015 Clemens Fischer")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("2.4.8")] -[assembly: AssemblyFileVersion("2.4.8")] +[assembly: AssemblyVersion("2.4.9")] +[assembly: AssemblyFileVersion("2.4.9")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] diff --git a/Caching/FileDbCache.WinRT/FileDbCache.cs b/Caching/FileDbCache.WinRT/FileDbCache.cs index fde88fa7..8e2d62e3 100644 --- a/Caching/FileDbCache.WinRT/FileDbCache.cs +++ b/Caching/FileDbCache.WinRT/FileDbCache.cs @@ -30,7 +30,7 @@ namespace MapControl.Caching public FileDbCache(string name = null, StorageFolder folder = null) { - if (string.IsNullOrWhiteSpace(name)) + if (string.IsNullOrEmpty(name)) { name = TileImageLoader.DefaultCacheName; } diff --git a/Caching/FileDbCache.WinRT/Properties/AssemblyInfo.cs b/Caching/FileDbCache.WinRT/Properties/AssemblyInfo.cs index ed26c175..4d3368f8 100644 --- a/Caching/FileDbCache.WinRT/Properties/AssemblyInfo.cs +++ b/Caching/FileDbCache.WinRT/Properties/AssemblyInfo.cs @@ -7,8 +7,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCopyright("© 2015 Clemens Fischer")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("2.4.8")] -[assembly: AssemblyFileVersion("2.4.8")] +[assembly: AssemblyVersion("2.4.9")] +[assembly: AssemblyFileVersion("2.4.9")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] diff --git a/Caching/ImageFileCache.WPF/ImageFileCache.cs b/Caching/ImageFileCache.WPF/ImageFileCache.cs index 621501f7..d9031e94 100644 --- a/Caching/ImageFileCache.WPF/ImageFileCache.cs +++ b/Caching/ImageFileCache.WPF/ImageFileCache.cs @@ -37,14 +37,14 @@ namespace MapControl.Caching public ImageFileCache(string name, string folder) { - if (string.IsNullOrWhiteSpace(name)) + if (string.IsNullOrEmpty(name)) { - throw new ArgumentException("The parameter name must not be null or empty or consist only of white-space characters."); + throw new ArgumentException("The parameter name must not be null or empty."); } - if (string.IsNullOrWhiteSpace(folder)) + if (string.IsNullOrEmpty(folder)) { - throw new ArgumentException("The parameter folder must not be null or empty or consist only of white-space characters."); + throw new ArgumentException("The parameter folder must not be null or empty."); } this.name = name; diff --git a/Caching/ImageFileCache.WPF/Properties/AssemblyInfo.cs b/Caching/ImageFileCache.WPF/Properties/AssemblyInfo.cs index 9ce4054e..51631342 100644 --- a/Caching/ImageFileCache.WPF/Properties/AssemblyInfo.cs +++ b/Caching/ImageFileCache.WPF/Properties/AssemblyInfo.cs @@ -7,8 +7,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCopyright("© 2015 Clemens Fischer")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("2.4.8")] -[assembly: AssemblyFileVersion("2.4.8")] +[assembly: AssemblyVersion("2.4.9")] +[assembly: AssemblyFileVersion("2.4.9")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] diff --git a/Caching/ImageFileCache.WinRT/ImageFileCache.cs b/Caching/ImageFileCache.WinRT/ImageFileCache.cs index 0ad8d8cc..eb214a2b 100644 --- a/Caching/ImageFileCache.WinRT/ImageFileCache.cs +++ b/Caching/ImageFileCache.WinRT/ImageFileCache.cs @@ -17,7 +17,7 @@ namespace MapControl.Caching public ImageFileCache(string name = null, StorageFolder folder = null) { - if (string.IsNullOrWhiteSpace(name)) + if (string.IsNullOrEmpty(name)) { name = TileImageLoader.DefaultCacheName; } diff --git a/Caching/ImageFileCache.WinRT/Properties/AssemblyInfo.cs b/Caching/ImageFileCache.WinRT/Properties/AssemblyInfo.cs index ac29d783..dab87752 100644 --- a/Caching/ImageFileCache.WinRT/Properties/AssemblyInfo.cs +++ b/Caching/ImageFileCache.WinRT/Properties/AssemblyInfo.cs @@ -7,8 +7,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCopyright("© 2015 Clemens Fischer")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("2.4.8")] -[assembly: AssemblyFileVersion("2.4.8")] +[assembly: AssemblyVersion("2.4.9")] +[assembly: AssemblyFileVersion("2.4.9")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] diff --git a/MapControl/BingMapsTileLayer.cs b/MapControl/BingMapsTileLayer.cs index ff962fc8..d1c60151 100644 --- a/MapControl/BingMapsTileLayer.cs +++ b/MapControl/BingMapsTileLayer.cs @@ -10,8 +10,10 @@ using System.Net; using System.Xml; #if WINDOWS_RUNTIME using Windows.UI.Xaml; +using Windows.UI.Xaml.Media.Imaging; #else using System.Windows; +using System.Windows.Media.Imaging; #endif namespace MapControl @@ -39,7 +41,7 @@ namespace MapControl { Loaded -= OnLoaded; - if (string.IsNullOrWhiteSpace(ApiKey)) + if (string.IsNullOrEmpty(ApiKey)) { throw new InvalidOperationException("A Bing Maps API Key must be assigned to the ApiKey property."); } @@ -70,6 +72,7 @@ namespace MapControl private void ReadImageryMetadataResponse(XmlReader xmlReader) { + string logoUri = null; string imageUrl = null; string[] imageUrlSubdomains = null; int? zoomMin = null; @@ -81,6 +84,9 @@ namespace MapControl { switch (xmlReader.Name) { + case "BrandLogoUri": + logoUri = xmlReader.ReadElementContentAsString(); + break; case "ImageUrl": imageUrl = xmlReader.ReadElementContentAsString(); break; @@ -105,11 +111,11 @@ namespace MapControl } while (xmlReader.NodeType != XmlNodeType.None); - if (imageUrl != null && imageUrlSubdomains != null && imageUrlSubdomains.Length > 0) + if (!string.IsNullOrEmpty(imageUrl) && imageUrlSubdomains != null && imageUrlSubdomains.Length > 0) { Dispatcher.BeginInvoke(new Action(() => { - if (string.IsNullOrWhiteSpace(Culture)) + if (string.IsNullOrEmpty(Culture)) { Culture = CultureInfo.CurrentUICulture.Name; } @@ -125,6 +131,11 @@ namespace MapControl { MaxZoomLevel = zoomMax.Value; } + + if (!string.IsNullOrEmpty(logoUri)) + { + LogoImage = new BitmapImage(new Uri(logoUri)); + } })); } } diff --git a/MapControl/MapBase.cs b/MapControl/MapBase.cs index 0a213e3e..d2c0c545 100644 --- a/MapControl/MapBase.cs +++ b/MapControl/MapBase.cs @@ -80,7 +80,7 @@ namespace MapControl TileLayers = new ObservableCollection(); tileUpdateTimer.Tick += UpdateTiles; - Loaded += OnLoaded; + Loaded += MapLoaded; Initialize(); } @@ -403,9 +403,21 @@ namespace MapControl } } - private void OnLoaded(object sender, RoutedEventArgs e) + protected override void OnViewportChanged() { - Loaded -= OnLoaded; + base.OnViewportChanged(); + + var viewportChanged = ViewportChanged; + + if (viewportChanged != null) + { + viewportChanged(this, EventArgs.Empty); + } + } + + private void MapLoaded(object sender, RoutedEventArgs e) + { + Loaded -= MapLoaded; if (tileLayerPanel.Children.Count == 0 && !Children.OfType().Any()) { @@ -839,18 +851,6 @@ namespace MapControl OnViewportChanged(); } - protected override void OnViewportChanged() - { - base.OnViewportChanged(); - - var viewportChanged = ViewportChanged; - - if (viewportChanged != null) - { - viewportChanged(this, EventArgs.Empty); - } - } - private void SetViewportTransform(Location origin) { var oldMapOriginX = (viewportOrigin.X - tileLayerOffset.X) / ViewportScale - 180d; diff --git a/MapControl/MapPanel.cs b/MapControl/MapPanel.cs index 2bd2f6f3..a416115b 100644 --- a/MapControl/MapPanel.cs +++ b/MapControl/MapPanel.cs @@ -131,16 +131,21 @@ namespace MapControl private static void SetViewportPosition(UIElement element, MapBase parentMap, Location location) { - Point viewportPosition; + var viewportPosition = new Point(); if (parentMap != null && location != null) { var mapPosition = parentMap.MapTransform.Transform(location, parentMap.Center.Longitude); // nearest to center longitude + viewportPosition = parentMap.ViewportTransform.Transform(mapPosition); - } - else - { - viewportPosition = new Point(); + + var useLayoutRounding = element.GetValue(FrameworkElement.UseLayoutRoundingProperty); + + if (useLayoutRounding != null && (bool)useLayoutRounding) + { + viewportPosition.X = Math.Round(viewportPosition.X); + viewportPosition.Y = Math.Round(viewportPosition.Y); + } } var translateTransform = element.RenderTransform as TranslateTransform; diff --git a/MapControl/Properties/AssemblyInfo.cs b/MapControl/Properties/AssemblyInfo.cs index 17f27412..1f887db5 100644 --- a/MapControl/Properties/AssemblyInfo.cs +++ b/MapControl/Properties/AssemblyInfo.cs @@ -17,8 +17,8 @@ using System.Windows; [assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCopyright("© 2015 Clemens Fischer")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("2.4.8")] -[assembly: AssemblyFileVersion("2.4.8")] +[assembly: AssemblyVersion("2.4.9")] +[assembly: AssemblyFileVersion("2.4.9")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] diff --git a/MapControl/TileImageLoader.WPF.cs b/MapControl/TileImageLoader.WPF.cs index 71a85864..ac3ab4b9 100644 --- a/MapControl/TileImageLoader.WPF.cs +++ b/MapControl/TileImageLoader.WPF.cs @@ -104,7 +104,7 @@ namespace MapControl private void GetTiles(IEnumerable tiles, Dispatcher dispatcher, TileSource tileSource, string sourceName, int maxDownloads) { var useCache = Cache != null - && !string.IsNullOrWhiteSpace(sourceName) + && !string.IsNullOrEmpty(sourceName) && !(tileSource is ImageTileSource) && !tileSource.UriFormat.StartsWith("file:"); @@ -307,7 +307,6 @@ namespace MapControl int.TryParse(cacheControl.Substring(8), out maxAge)) { maxAge = Math.Min(maxAge, (int)DefaultCacheExpiration.TotalSeconds); - expiration = DateTime.UtcNow.AddSeconds(maxAge); } else diff --git a/MapControl/TileLayer.cs b/MapControl/TileLayer.cs index f46fc6fb..6d093970 100644 --- a/MapControl/TileLayer.cs +++ b/MapControl/TileLayer.cs @@ -51,6 +51,9 @@ namespace MapControl public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register( "Description", typeof(string), typeof(TileLayer), new PropertyMetadata(null)); + public static readonly DependencyProperty LogoImageProperty = DependencyProperty.Register( + "LogoImage", typeof(ImageSource), typeof(TileLayer), new PropertyMetadata(null)); + public static readonly DependencyProperty MinZoomLevelProperty = DependencyProperty.Register( "MinZoomLevel", typeof(int), typeof(TileLayer), new PropertyMetadata(0)); @@ -84,7 +87,7 @@ namespace MapControl partial void Initialize(); /// - /// Controls how map tiles are loaded. + /// Provides map tile URIs or images. /// public TileSource TileSource { @@ -93,7 +96,7 @@ namespace MapControl } /// - /// Name of the TileSource. Used as key in a TileLayerCollection and to name an optional tile cache. + /// Name of the TileSource. Used as key in a TileLayerCollection and as component of a tile cache key. /// public string SourceName { @@ -102,7 +105,7 @@ namespace MapControl } /// - /// Description of the TileLayer. + /// Description of the TileLayer. Used to display copyright information on top of the map. /// public string Description { @@ -110,6 +113,15 @@ namespace MapControl set { SetValue(DescriptionProperty, value); } } + /// + /// Logo image. Used to display a provider brand logo on top of the map. + /// + public ImageSource LogoImage + { + get { return (ImageSource)GetValue(LogoImageProperty); } + set { SetValue(LogoImageProperty, value); } + } + /// /// Minimum zoom level supported by the TileLayer. /// @@ -138,7 +150,7 @@ namespace MapControl } /// - /// Sets MapBase.Foreground, if not null. + /// Optional foreground brush. Sets MapBase.Foreground, if not null. /// public Brush Foreground { @@ -147,7 +159,7 @@ namespace MapControl } /// - /// Sets MapBase.Background, if not null. + /// Optional background brush. Sets MapBase.Background, if not null. /// New property prevents filling of RenderTransformed TileLayer with Panel.Background. /// public new Brush Background diff --git a/MapControl/TileSource.cs b/MapControl/TileSource.cs index 2624c836..1a79d95d 100644 --- a/MapControl/TileSource.cs +++ b/MapControl/TileSource.cs @@ -32,9 +32,9 @@ namespace MapControl get { return uriFormat; } set { - if (string.IsNullOrWhiteSpace(value)) + if (string.IsNullOrEmpty(value)) { - throw new ArgumentException("The value of the UriFormat property must not be null or empty or white-space only.", "value"); + throw new ArgumentException("The value of the UriFormat property must not be null or empty."); } uriFormat = value; @@ -154,11 +154,11 @@ namespace MapControl private Uri GetBoundingBoxUri(int x, int y, int zoomLevel) { - var numTiles = (double)(1 << zoomLevel); - var west = MetersPerDegree * ((double)x * 360d / numTiles - 180d); - var east = MetersPerDegree * ((double)(x + 1) * 360d / numTiles - 180d); - var south = MetersPerDegree * (180d - (double)(y + 1) * 360d / numTiles); - var north = MetersPerDegree * (180d - (double)y * 360d / numTiles); + var tileSize = 360d / (double)(1 << zoomLevel); // tile width in degrees + var west = MetersPerDegree * ((double)x * tileSize - 180d); + var east = MetersPerDegree * ((double)(x + 1) * tileSize - 180d); + var south = MetersPerDegree * (180d - (double)(y + 1) * tileSize); + var north = MetersPerDegree * (180d - (double)y * tileSize); return new Uri(uriFormat. Replace("{W}", west.ToString(CultureInfo.InvariantCulture)). @@ -169,11 +169,11 @@ namespace MapControl private Uri GetLatLonBoundingBoxUri(int x, int y, int zoomLevel) { - var numTiles = (double)(1 << zoomLevel); - var west = (double)x * 360d / numTiles - 180d; - var east = (double)(x + 1) * 360d / numTiles - 180d; - var south = MercatorTransform.YToLatitude(180d - (double)(y + 1) * 360d / numTiles); - var north = MercatorTransform.YToLatitude(180d - (double)y * 360d / numTiles); + var tileSize = 360d / (double)(1 << zoomLevel); // tile width in degrees + var west = (double)x * tileSize - 180d; + var east = (double)(x + 1) * tileSize - 180d; + var south = MercatorTransform.YToLatitude(180d - (double)(y + 1) * tileSize); + var north = MercatorTransform.YToLatitude(180d - (double)y * tileSize); return new Uri(uriFormat. Replace("{w}", west.ToString(CultureInfo.InvariantCulture)). diff --git a/MapControl/WinRT/Properties/AssemblyInfo.cs b/MapControl/WinRT/Properties/AssemblyInfo.cs index 7805fc23..1ba1ade1 100644 --- a/MapControl/WinRT/Properties/AssemblyInfo.cs +++ b/MapControl/WinRT/Properties/AssemblyInfo.cs @@ -7,8 +7,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCopyright("© 2015 Clemens Fischer")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("2.4.8")] -[assembly: AssemblyFileVersion("2.4.8")] +[assembly: AssemblyVersion("2.4.9")] +[assembly: AssemblyFileVersion("2.4.9")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] diff --git a/SampleApps/PhoneApplication/Properties/AssemblyInfo.cs b/SampleApps/PhoneApplication/Properties/AssemblyInfo.cs index a57dc605..09a0ccb5 100644 --- a/SampleApps/PhoneApplication/Properties/AssemblyInfo.cs +++ b/SampleApps/PhoneApplication/Properties/AssemblyInfo.cs @@ -7,8 +7,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCopyright("© 2015 Clemens Fischer")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("2.4.8")] -[assembly: AssemblyFileVersion("2.4.8")] +[assembly: AssemblyVersion("2.4.9")] +[assembly: AssemblyFileVersion("2.4.9")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] diff --git a/SampleApps/SilverlightApplication.Web/Properties/AssemblyInfo.cs b/SampleApps/SilverlightApplication.Web/Properties/AssemblyInfo.cs index c07d6c31..056cc611 100644 --- a/SampleApps/SilverlightApplication.Web/Properties/AssemblyInfo.cs +++ b/SampleApps/SilverlightApplication.Web/Properties/AssemblyInfo.cs @@ -7,8 +7,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCopyright("© 2015 Clemens Fischer")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("2.4.8")] -[assembly: AssemblyFileVersion("2.4.8")] +[assembly: AssemblyVersion("2.4.9")] +[assembly: AssemblyFileVersion("2.4.9")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] diff --git a/SampleApps/SilverlightApplication/Properties/AssemblyInfo.cs b/SampleApps/SilverlightApplication/Properties/AssemblyInfo.cs index 13cf230d..f0fbeb02 100644 --- a/SampleApps/SilverlightApplication/Properties/AssemblyInfo.cs +++ b/SampleApps/SilverlightApplication/Properties/AssemblyInfo.cs @@ -7,8 +7,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCopyright("© 2015 Clemens Fischer")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("2.4.8")] -[assembly: AssemblyFileVersion("2.4.8")] +[assembly: AssemblyVersion("2.4.9")] +[assembly: AssemblyFileVersion("2.4.9")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] diff --git a/SampleApps/StoreApplication/Properties/AssemblyInfo.cs b/SampleApps/StoreApplication/Properties/AssemblyInfo.cs index 99768f1d..ba1238d2 100644 --- a/SampleApps/StoreApplication/Properties/AssemblyInfo.cs +++ b/SampleApps/StoreApplication/Properties/AssemblyInfo.cs @@ -7,8 +7,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCopyright("© 2015 Clemens Fischer")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("2.4.8")] -[assembly: AssemblyFileVersion("2.4.8")] +[assembly: AssemblyVersion("2.4.9")] +[assembly: AssemblyFileVersion("2.4.9")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] diff --git a/SampleApps/WpfApplication/OutlinedText.cs b/SampleApps/WpfApplication/OutlinedText.cs index 16d6023f..c93c1fc9 100644 --- a/SampleApps/WpfApplication/OutlinedText.cs +++ b/SampleApps/WpfApplication/OutlinedText.cs @@ -111,7 +111,7 @@ namespace WpfApplication { if (glyphRun == null) { - if (string.IsNullOrWhiteSpace(Text)) + if (string.IsNullOrEmpty(Text)) { return false; } diff --git a/SampleApps/WpfApplication/Properties/AssemblyInfo.cs b/SampleApps/WpfApplication/Properties/AssemblyInfo.cs index e3f0aabe..d9099d74 100644 --- a/SampleApps/WpfApplication/Properties/AssemblyInfo.cs +++ b/SampleApps/WpfApplication/Properties/AssemblyInfo.cs @@ -7,8 +7,8 @@ using System.Runtime.InteropServices; [assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCopyright("© 2015 Clemens Fischer")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("2.4.8")] -[assembly: AssemblyFileVersion("2.4.8")] +[assembly: AssemblyVersion("2.4.9")] +[assembly: AssemblyFileVersion("2.4.9")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)]