mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2026-02-16 04:35:08 +01:00
Version 4.1.
This commit is contained in:
parent
ef6d1ed959
commit
467d82ead7
|
|
@ -76,18 +76,6 @@ namespace MapControl
|
|||
private double centerLongitude;
|
||||
private bool internalPropertyChange;
|
||||
|
||||
public MapBase()
|
||||
{
|
||||
Initialize();
|
||||
|
||||
MapProjection = new WebMercatorProjection();
|
||||
ScaleRotateTransform.Children.Add(ScaleTransform);
|
||||
ScaleRotateTransform.Children.Add(RotateTransform);
|
||||
}
|
||||
|
||||
partial void Initialize(); // Windows Runtime and Silverlight only
|
||||
partial void RemoveAnimation(DependencyProperty property); // WPF only
|
||||
|
||||
/// <summary>
|
||||
/// Raised when the current viewport has changed.
|
||||
/// </summary>
|
||||
|
|
@ -504,7 +492,8 @@ namespace MapControl
|
|||
targetCenter.Latitude,
|
||||
Location.NearestLongitude(targetCenter.Longitude, Center.Longitude))),
|
||||
Duration = AnimationDuration,
|
||||
EasingFunction = AnimationEasingFunction
|
||||
EasingFunction = AnimationEasingFunction,
|
||||
FillBehavior = AnimationFillBehavior
|
||||
};
|
||||
|
||||
centerAnimation.Completed += CenterAnimationCompleted;
|
||||
|
|
@ -522,7 +511,6 @@ namespace MapControl
|
|||
|
||||
InternalSetValue(CenterProperty, TargetCenter);
|
||||
InternalSetValue(CenterPointProperty, MapProjection.LocationToPoint(TargetCenter));
|
||||
RemoveAnimation(CenterPointProperty); // remove holding animation in WPF
|
||||
UpdateTransform();
|
||||
}
|
||||
}
|
||||
|
|
@ -607,7 +595,8 @@ namespace MapControl
|
|||
{
|
||||
To = targetZoomLevel,
|
||||
Duration = AnimationDuration,
|
||||
EasingFunction = AnimationEasingFunction
|
||||
EasingFunction = AnimationEasingFunction,
|
||||
FillBehavior = AnimationFillBehavior
|
||||
};
|
||||
|
||||
zoomLevelAnimation.Completed += ZoomLevelAnimationCompleted;
|
||||
|
|
@ -624,8 +613,6 @@ namespace MapControl
|
|||
zoomLevelAnimation = null;
|
||||
|
||||
InternalSetValue(ZoomLevelProperty, TargetZoomLevel);
|
||||
RemoveAnimation(ZoomLevelProperty); // remove holding animation in WPF
|
||||
|
||||
UpdateTransform(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -681,7 +668,8 @@ namespace MapControl
|
|||
{
|
||||
By = delta,
|
||||
Duration = AnimationDuration,
|
||||
EasingFunction = AnimationEasingFunction
|
||||
EasingFunction = AnimationEasingFunction,
|
||||
FillBehavior = AnimationFillBehavior
|
||||
};
|
||||
|
||||
headingAnimation.Completed += HeadingAnimationCompleted;
|
||||
|
|
@ -698,7 +686,6 @@ namespace MapControl
|
|||
headingAnimation = null;
|
||||
|
||||
InternalSetValue(HeadingProperty, TargetHeading);
|
||||
RemoveAnimation(HeadingProperty); // remove holding animation in WPF
|
||||
UpdateTransform();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,20 +2,39 @@
|
|||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
#if WINDOWS_UWP
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
#else
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages a collection of selectable items on a Map. Uses MapItem as item container class.
|
||||
/// Container class for an item in a MapItemsControl.
|
||||
/// </summary>
|
||||
public class MapItem : ListBoxItem
|
||||
{
|
||||
public MapItem()
|
||||
{
|
||||
DefaultStyleKey = typeof(MapItem);
|
||||
|
||||
MapPanel.InitMapElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manages a collection of selectable items on a Map.
|
||||
/// </summary>
|
||||
public class MapItemsControl : ListBox
|
||||
{
|
||||
public MapItemsControl()
|
||||
{
|
||||
DefaultStyleKey = typeof(MapItemsControl);
|
||||
MapPanel.AddParentMapHandlers(this);
|
||||
|
||||
MapPanel.InitMapElement(this);
|
||||
}
|
||||
|
||||
protected override DependencyObject GetContainerForItemOverride()
|
||||
|
|
@ -16,6 +16,10 @@ using System.Windows.Media;
|
|||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Optional interface to hold the value of the MapPanel.ParentMap attached property.
|
||||
/// May be used to get notified when the property value changes.
|
||||
/// </summary>
|
||||
public interface IMapElement
|
||||
{
|
||||
MapBase ParentMap { get; set; }
|
||||
|
|
@ -35,6 +39,13 @@ namespace MapControl
|
|||
public static readonly DependencyProperty BoundingBoxProperty = DependencyProperty.RegisterAttached(
|
||||
"BoundingBox", typeof(BoundingBox), typeof(MapPanel), new PropertyMetadata(null, BoundingBoxPropertyChanged));
|
||||
|
||||
private MapBase parentMap;
|
||||
|
||||
public MapPanel()
|
||||
{
|
||||
InitMapElement(this);
|
||||
}
|
||||
|
||||
public static Location GetLocation(UIElement element)
|
||||
{
|
||||
return (Location)element.GetValue(LocationProperty);
|
||||
|
|
@ -55,12 +66,10 @@ namespace MapControl
|
|||
element.SetValue(BoundingBoxProperty, value);
|
||||
}
|
||||
|
||||
private MapBase parentMap;
|
||||
|
||||
public MapBase ParentMap
|
||||
{
|
||||
get { return parentMap; }
|
||||
set { SetParentMapOverride(value); }
|
||||
set { SetParentMap(value); }
|
||||
}
|
||||
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
|
|
@ -101,7 +110,7 @@ namespace MapControl
|
|||
return finalSize;
|
||||
}
|
||||
|
||||
protected virtual void SetParentMapOverride(MapBase map)
|
||||
protected virtual void SetParentMap(MapBase map)
|
||||
{
|
||||
if (parentMap != null && parentMap != this)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,6 +24,11 @@ namespace MapControl
|
|||
nameof(Location), typeof(Location), typeof(MapPath),
|
||||
new PropertyMetadata(null, (o, e) => ((MapPath)o).LocationPropertyChanged()));
|
||||
|
||||
public MapPath()
|
||||
{
|
||||
MapPanel.InitMapElement(this);
|
||||
}
|
||||
|
||||
public Location Location
|
||||
{
|
||||
get { return (Location)GetValue(LocationProperty); }
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
#if WINDOWS_UWP
|
||||
using Windows.Foundation;
|
||||
using Windows.UI.Xaml;
|
||||
|
|
@ -21,13 +22,13 @@ namespace MapControl
|
|||
{
|
||||
public interface ITileImageLoader
|
||||
{
|
||||
void LoadTiles(MapTileLayer tileLayer);
|
||||
Task LoadTilesAsync(MapTileLayer tileLayer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fills the map viewport with map tiles from a TileSource.
|
||||
/// </summary>
|
||||
public partial class MapTileLayer : Panel, IMapLayer
|
||||
public class MapTileLayer : Panel, IMapLayer
|
||||
{
|
||||
/// <summary>
|
||||
/// A default MapTileLayer using OpenStreetMap data.
|
||||
|
|
@ -66,9 +67,6 @@ namespace MapControl
|
|||
public static readonly DependencyProperty MaxZoomLevelProperty = DependencyProperty.Register(
|
||||
nameof(MaxZoomLevel), typeof(int), typeof(MapTileLayer), new PropertyMetadata(18));
|
||||
|
||||
public static readonly DependencyProperty MaxParallelDownloadsProperty = DependencyProperty.Register(
|
||||
nameof(MaxParallelDownloads), typeof(int), typeof(MapTileLayer), new PropertyMetadata(4));
|
||||
|
||||
public static readonly DependencyProperty UpdateIntervalProperty = DependencyProperty.Register(
|
||||
nameof(UpdateInterval), typeof(TimeSpan), typeof(MapTileLayer),
|
||||
new PropertyMetadata(TimeSpan.FromSeconds(0.2), (o, e) => ((MapTileLayer)o).updateTimer.Interval = (TimeSpan)e.NewValue));
|
||||
|
|
@ -92,17 +90,16 @@ namespace MapControl
|
|||
|
||||
public MapTileLayer(ITileImageLoader tileImageLoader)
|
||||
{
|
||||
Initialize();
|
||||
|
||||
IsHitTestVisible = false;
|
||||
RenderTransform = new MatrixTransform();
|
||||
TileImageLoader = tileImageLoader;
|
||||
Tiles = new List<Tile>();
|
||||
|
||||
updateTimer = new DispatcherTimer { Interval = UpdateInterval };
|
||||
updateTimer.Tick += (s, e) => UpdateTileGrid();
|
||||
}
|
||||
|
||||
partial void Initialize(); // Windows Runtime and Silverlight only
|
||||
MapPanel.InitMapElement(this);
|
||||
}
|
||||
|
||||
public ITileImageLoader TileImageLoader { get; private set; }
|
||||
public ICollection<Tile> Tiles { get; private set; }
|
||||
|
|
@ -162,15 +159,6 @@ namespace MapControl
|
|||
set { SetValue(MaxZoomLevelProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maximum number of parallel downloads that may be performed by the MapTileLayer's ITileImageLoader.
|
||||
/// </summary>
|
||||
public int MaxParallelDownloads
|
||||
{
|
||||
get { return (int)GetValue(MaxParallelDownloadsProperty); }
|
||||
set { SetValue(MaxParallelDownloadsProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Minimum time interval between tile updates.
|
||||
/// </summary>
|
||||
|
|
@ -400,7 +388,7 @@ namespace MapControl
|
|||
Children.Add(tile.Image);
|
||||
}
|
||||
|
||||
TileImageLoader.LoadTiles(this);
|
||||
var task = TileImageLoader.LoadTilesAsync(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,25 +2,24 @@
|
|||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
#if WINDOWS_UWP
|
||||
using Windows.UI.Xaml.Controls;
|
||||
#else
|
||||
using System.Windows.Controls;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Displays a pushpin at a geographic location provided by the MapPanel.Location attached property.
|
||||
/// Pushpin at a geographic location specified by the MapPanel.Location attached property.
|
||||
/// </summary>
|
||||
public class Pushpin : ContentControl
|
||||
{
|
||||
public Pushpin()
|
||||
{
|
||||
DefaultStyleKey = typeof(Pushpin);
|
||||
MapPanel.AddParentMapHandlers(this);
|
||||
}
|
||||
|
||||
public Location Location
|
||||
{
|
||||
get { return (Location)GetValue(MapPanel.LocationProperty); }
|
||||
set { SetValue(MapPanel.LocationProperty, value); }
|
||||
MapPanel.InitMapElement(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ using System.Collections.Concurrent;
|
|||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
#if WINDOWS_UWP
|
||||
|
|
@ -22,11 +23,6 @@ namespace MapControl
|
|||
/// </summary>
|
||||
public partial class TileImageLoader : ITileImageLoader
|
||||
{
|
||||
/// <summary>
|
||||
/// The HttpClient instance used when image data is downloaded from a web resource.
|
||||
/// </summary>
|
||||
public static HttpClient HttpClient { get; set; } = new HttpClient();
|
||||
|
||||
/// <summary>
|
||||
/// Default expiration time for cached tile images. Used when no expiration time
|
||||
/// was transmitted on download. The default value is one day.
|
||||
|
|
@ -50,13 +46,10 @@ namespace MapControl
|
|||
/// </summary>
|
||||
public static string CacheKeyFormat { get; set; } = "{0};{1};{2};{3}{4}";
|
||||
|
||||
private const string bingMapsTileInfo = "X-VE-Tile-Info";
|
||||
private const string bingMapsNoTile = "no-tile";
|
||||
|
||||
private readonly ConcurrentStack<Tile> pendingTiles = new ConcurrentStack<Tile>();
|
||||
private int taskCount;
|
||||
|
||||
public void LoadTiles(MapTileLayer tileLayer)
|
||||
public async Task LoadTilesAsync(MapTileLayer tileLayer)
|
||||
{
|
||||
pendingTiles.Clear();
|
||||
|
||||
|
|
@ -69,18 +62,18 @@ namespace MapControl
|
|||
if (Cache == null || string.IsNullOrEmpty(sourceName) ||
|
||||
tileSource.UriFormat == null || !tileSource.UriFormat.StartsWith("http"))
|
||||
{
|
||||
// no caching, load tile images in UI thread
|
||||
// no caching, load tile images directly
|
||||
|
||||
foreach (var tile in tiles)
|
||||
{
|
||||
LoadTileImage(tileSource, tile);
|
||||
await LoadTileImageAsync(tileSource, tile);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pendingTiles.PushRange(tiles.Reverse().ToArray());
|
||||
|
||||
while (taskCount < Math.Min(pendingTiles.Count, tileLayer.MaxParallelDownloads))
|
||||
while (taskCount < Math.Min(pendingTiles.Count, ServicePointManager.DefaultConnectionLimit))
|
||||
{
|
||||
Interlocked.Increment(ref taskCount);
|
||||
|
||||
|
|
@ -95,13 +88,13 @@ namespace MapControl
|
|||
}
|
||||
}
|
||||
|
||||
private void LoadTileImage(TileSource tileSource, Tile tile)
|
||||
private async Task LoadTileImageAsync(TileSource tileSource, Tile tile)
|
||||
{
|
||||
tile.Pending = false;
|
||||
|
||||
try
|
||||
{
|
||||
var imageSource = tileSource.LoadImage(tile.XIndex, tile.Y, tile.ZoomLevel);
|
||||
var imageSource = await tileSource.LoadImageAsync(tile.XIndex, tile.Y, tile.ZoomLevel);
|
||||
|
||||
if (imageSource != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,13 +4,6 @@
|
|||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
#if WINDOWS_UWP
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
#else
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
|
|
@ -92,17 +85,6 @@ namespace MapControl
|
|||
return getUri?.Invoke(x, y, zoomLevel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the map tile ImageSource without caching in TileImageLoader.Cache.
|
||||
/// By overriding LoadImage an application can provide arbitrary tile images.
|
||||
/// </summary>
|
||||
public virtual ImageSource LoadImage(int x, int y, int zoomLevel)
|
||||
{
|
||||
var uri = GetUri(x, y, zoomLevel);
|
||||
|
||||
return uri != null ? new BitmapImage(uri) : null;
|
||||
}
|
||||
|
||||
private Uri GetBasicUri(int x, int y, int zoomLevel)
|
||||
{
|
||||
return new Uri(uriFormat
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@ using Windows.Foundation;
|
|||
using Windows.UI;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Media.Animation;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
public partial class MapBase
|
||||
{
|
||||
private const FillBehavior AnimationFillBehavior = FillBehavior.HoldEnd;
|
||||
|
||||
public static readonly DependencyProperty ForegroundProperty = DependencyProperty.Register(
|
||||
nameof(Foreground), typeof(Brush), typeof(MapBase),
|
||||
new PropertyMetadata(new SolidColorBrush(Colors.Black)));
|
||||
|
|
@ -39,25 +42,24 @@ namespace MapControl
|
|||
nameof(TargetHeading), typeof(double), typeof(MapBase),
|
||||
new PropertyMetadata(0d, (o, e) => ((MapBase)o).TargetHeadingPropertyChanged((double)e.NewValue)));
|
||||
|
||||
partial void Initialize()
|
||||
public MapBase()
|
||||
{
|
||||
MapProjection = new WebMercatorProjection();
|
||||
ScaleRotateTransform.Children.Add(ScaleTransform);
|
||||
ScaleRotateTransform.Children.Add(RotateTransform);
|
||||
|
||||
// set Background by Style to enable resetting by ClearValue in MapLayerPropertyChanged
|
||||
var style = new Style(typeof(MapBase));
|
||||
style.Setters.Add(new Setter(BackgroundProperty, new SolidColorBrush(Colors.Transparent)));
|
||||
Style = style;
|
||||
|
||||
var clip = new RectangleGeometry();
|
||||
Clip = clip;
|
||||
Clip = new RectangleGeometry();
|
||||
|
||||
SizeChanged += (s, e) =>
|
||||
{
|
||||
if (clip.Rect.Width != e.NewSize.Width || clip.Rect.Height != e.NewSize.Height)
|
||||
{
|
||||
clip.Rect = new Rect(0d, 0d, e.NewSize.Width, e.NewSize.Height);
|
||||
|
||||
ResetTransformCenter();
|
||||
UpdateTransform();
|
||||
}
|
||||
Clip.Rect = new Rect(0d, 0d, e.NewSize.Width, e.NewSize.Height);
|
||||
ResetTransformCenter();
|
||||
UpdateTransform();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<GenerateLibraryLayout>true</GenerateLibraryLayout>
|
||||
<NoWarn>CS1998</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
|
|
@ -88,6 +89,9 @@
|
|||
<Compile Include="..\Shared\MapImageLayer.cs">
|
||||
<Link>MapImageLayer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapItemsControl.cs">
|
||||
<Link>MapItemsControl.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapOverlay.cs">
|
||||
<Link>MapOverlay.cs</Link>
|
||||
</Compile>
|
||||
|
|
@ -112,6 +116,9 @@
|
|||
<Compile Include="..\Shared\OrthographicProjection.cs">
|
||||
<Link>OrthographicProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\Pushpin.cs">
|
||||
<Link>Pushpin.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\StereographicProjection.cs">
|
||||
<Link>StereographicProjection.cs</Link>
|
||||
</Compile>
|
||||
|
|
@ -143,18 +150,15 @@
|
|||
<Compile Include="MapBase.UWP.cs" />
|
||||
<Compile Include="MapGraticule.UWP.cs" />
|
||||
<Compile Include="MapImageLayer.UWP.cs" />
|
||||
<Compile Include="MapItem.UWP.cs" />
|
||||
<Compile Include="MapItemsControl.UWP.cs" />
|
||||
<Compile Include="MapOverlay.UWP.cs" />
|
||||
<Compile Include="MapPanel.UWP.cs" />
|
||||
<Compile Include="MapPath.UWP.cs" />
|
||||
<Compile Include="MapPolyline.UWP.cs" />
|
||||
<Compile Include="MapTileLayer.UWP.cs" />
|
||||
<Compile Include="MatrixEx.UWP.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Pushpin.UWP.cs" />
|
||||
<Compile Include="Tile.UWP.cs" />
|
||||
<Compile Include="TileImageLoader.UWP.cs" />
|
||||
<Compile Include="TileSource.UWP.cs" />
|
||||
<EmbeddedResource Include="Properties\MapControl.UWP.rd.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
|
||||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Container class for an item in a MapItemsControl.
|
||||
/// </summary>
|
||||
public class MapItem : ListBoxItem
|
||||
{
|
||||
public MapItem()
|
||||
{
|
||||
DefaultStyleKey = typeof(MapItem);
|
||||
MapPanel.AddParentMapHandlers(this);
|
||||
}
|
||||
|
||||
public Location Location
|
||||
{
|
||||
get { return (Location)GetValue(MapPanel.LocationProperty); }
|
||||
set { SetValue(MapPanel.LocationProperty, value); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -56,7 +56,7 @@ namespace MapControl
|
|||
public static readonly DependencyProperty StrokeMiterLimitProperty = DependencyProperty.Register(
|
||||
nameof(StrokeMiterLimit), typeof(double), typeof(MapOverlay), new PropertyMetadata(1d));
|
||||
|
||||
protected override void SetParentMapOverride(MapBase parentMap)
|
||||
protected override void SetParentMap(MapBase parentMap)
|
||||
{
|
||||
if (GetBindingExpression(ForegroundProperty) != null)
|
||||
{
|
||||
|
|
@ -89,7 +89,7 @@ namespace MapControl
|
|||
}
|
||||
}
|
||||
|
||||
base.SetParentMapOverride(parentMap);
|
||||
base.SetParentMap(parentMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,27 +12,20 @@ namespace MapControl
|
|||
public static readonly DependencyProperty ParentMapProperty = DependencyProperty.RegisterAttached(
|
||||
"ParentMap", typeof(MapBase), typeof(MapPanel), new PropertyMetadata(null, ParentMapPropertyChanged));
|
||||
|
||||
public MapPanel()
|
||||
public static void InitMapElement(FrameworkElement element)
|
||||
{
|
||||
if (this is MapBase)
|
||||
if (element is MapBase)
|
||||
{
|
||||
SetValue(ParentMapProperty, this);
|
||||
element.SetValue(ParentMapProperty, element);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddParentMapHandlers(this);
|
||||
}
|
||||
}
|
||||
// Workaround for missing property value inheritance in Windows Runtime.
|
||||
// Loaded and Unloaded handlers set and clear the ParentMap property value.
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to work around missing property value inheritance in Silverlight and Windows Runtime.
|
||||
/// 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)
|
||||
{
|
||||
element.Loaded += (s, e) => GetParentMap(element);
|
||||
element.Unloaded += (s, e) => element.ClearValue(ParentMapProperty);
|
||||
element.Loaded += (s, e) => GetParentMap(element);
|
||||
element.Unloaded += (s, e) => element.ClearValue(ParentMapProperty);
|
||||
}
|
||||
}
|
||||
|
||||
public static MapBase GetParentMap(UIElement element)
|
||||
|
|
@ -49,20 +42,12 @@ namespace MapControl
|
|||
|
||||
private static MapBase FindParentMap(UIElement element)
|
||||
{
|
||||
MapBase parentMap = null;
|
||||
var parentElement = VisualTreeHelper.GetParent(element) as UIElement;
|
||||
var parent = VisualTreeHelper.GetParent(element) as UIElement;
|
||||
|
||||
if (parentElement != null)
|
||||
{
|
||||
parentMap = parentElement as MapBase;
|
||||
|
||||
if (parentMap == null)
|
||||
{
|
||||
parentMap = GetParentMap(parentElement);
|
||||
}
|
||||
}
|
||||
|
||||
return parentMap;
|
||||
return parent == null ? null
|
||||
: ((parent as MapBase)
|
||||
?? (MapBase)element.GetValue(ParentMapProperty)
|
||||
?? FindParentMap(parent));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,11 +12,6 @@ namespace MapControl
|
|||
{
|
||||
private Geometry data;
|
||||
|
||||
public MapPath()
|
||||
{
|
||||
MapPanel.AddParentMapHandlers(this);
|
||||
}
|
||||
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
if (Stretch != Stretch.None)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ using Windows.Storage;
|
|||
using Windows.Storage.Streams;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
using Windows.Web.Http;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
|
|
@ -31,11 +30,6 @@ namespace MapControl
|
|||
var buffer = cacheItem?.Buffer;
|
||||
var loaded = false;
|
||||
|
||||
//if (buffer != null)
|
||||
//{
|
||||
// Debug.WriteLine("TileImageLoader: {0}: expire{1} {2}", cacheKey, cacheItem.Expiration < DateTime.UtcNow ? "d" : "s", cacheItem.Expiration);
|
||||
//}
|
||||
|
||||
if (buffer == null || cacheItem.Expiration < DateTime.UtcNow)
|
||||
{
|
||||
loaded = await DownloadTileImageAsync(tile, uri, cacheKey);
|
||||
|
|
@ -49,28 +43,26 @@ namespace MapControl
|
|||
|
||||
private async Task<bool> DownloadTileImageAsync(Tile tile, Uri uri, string cacheKey)
|
||||
{
|
||||
var success = false;
|
||||
|
||||
try
|
||||
{
|
||||
using (var response = await HttpClient.GetAsync(uri))
|
||||
using (var response = await TileSource.HttpClient.GetAsync(uri))
|
||||
{
|
||||
if (response.IsSuccessStatusCode)
|
||||
success = response.IsSuccessStatusCode;
|
||||
|
||||
if (!success)
|
||||
{
|
||||
string tileInfo;
|
||||
|
||||
if (!response.Headers.TryGetValue(bingMapsTileInfo, out tileInfo) ||
|
||||
tileInfo != bingMapsNoTile)
|
||||
{
|
||||
var buffer = await response.Content.ReadAsBufferAsync();
|
||||
|
||||
await SetTileImageAsync(tile, buffer); // create BitmapImage in UI thread before caching
|
||||
|
||||
await Cache.SetAsync(cacheKey, buffer, GetExpiration(response));
|
||||
}
|
||||
|
||||
return true;
|
||||
Debug.WriteLine("TileImageLoader: {0}: {1} {2}", uri, (int)response.StatusCode, response.ReasonPhrase);
|
||||
}
|
||||
else if (TileSource.TileAvailable(response.Headers))
|
||||
{
|
||||
var buffer = await response.Content.ReadAsBufferAsync();
|
||||
|
||||
Debug.WriteLine("TileImageLoader: {0}: {1} {2}", uri, (int)response.StatusCode, response.ReasonPhrase);
|
||||
await SetTileImageAsync(tile, buffer); // create BitmapImage before caching
|
||||
|
||||
await Cache.SetAsync(cacheKey, buffer, GetExpiration(response));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -78,7 +70,7 @@ namespace MapControl
|
|||
Debug.WriteLine("TileImageLoader: {0}: {1}", uri, ex.Message);
|
||||
}
|
||||
|
||||
return false;
|
||||
return success;
|
||||
}
|
||||
|
||||
private async Task SetTileImageAsync(Tile tile, IBuffer buffer)
|
||||
|
|
|
|||
84
MapControl/UWP/TileSource.UWP.cs
Normal file
84
MapControl/UWP/TileSource.UWP.cs
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
|
||||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage.Streams;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
using Windows.Web.Http;
|
||||
using Windows.Web.Http.Headers;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
public partial class TileSource
|
||||
{
|
||||
/// <summary>
|
||||
/// The HttpClient instance used when image data is downloaded from a web resource.
|
||||
/// </summary>
|
||||
public static HttpClient HttpClient { get; set; } = new HttpClient();
|
||||
|
||||
/// <summary>
|
||||
/// Check HTTP response headers for tile unavailability, e.g. X-VE-Tile-Info=no-tile
|
||||
/// </summary>
|
||||
public static bool TileAvailable(HttpResponseHeaderCollection responseHeaders)
|
||||
{
|
||||
string tileInfo;
|
||||
|
||||
return !responseHeaders.TryGetValue("X-VE-Tile-Info", out tileInfo) || tileInfo != "no-tile";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load a tile ImageSource asynchronously from GetUri(x, y, zoomLevel)
|
||||
/// </summary>
|
||||
public virtual async Task<ImageSource> LoadImageAsync(int x, int y, int zoomLevel)
|
||||
{
|
||||
ImageSource imageSource = null;
|
||||
|
||||
var uri = GetUri(x, y, zoomLevel);
|
||||
|
||||
if (uri != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (uri.Scheme == "http")
|
||||
{
|
||||
using (var response = await HttpClient.GetAsync(uri))
|
||||
{
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
Debug.WriteLine("TileSource: {0}: {1} {2}", uri, (int)response.StatusCode, response.ReasonPhrase);
|
||||
}
|
||||
else if (TileAvailable(response.Headers))
|
||||
{
|
||||
var bitmapImage = new BitmapImage();
|
||||
|
||||
using (var stream = new InMemoryRandomAccessStream())
|
||||
{
|
||||
await response.Content.WriteToStreamAsync(stream);
|
||||
stream.Seek(0);
|
||||
|
||||
await bitmapImage.SetSourceAsync(stream);
|
||||
}
|
||||
|
||||
imageSource = bitmapImage;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
imageSource = new BitmapImage(uri);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("TileSource: {0}: {1}", uri, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
return imageSource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,11 +5,14 @@
|
|||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
public partial class MapBase
|
||||
{
|
||||
private const FillBehavior AnimationFillBehavior = FillBehavior.Stop;
|
||||
|
||||
public static readonly DependencyProperty ForegroundProperty =
|
||||
Control.ForegroundProperty.AddOwner(typeof(MapBase));
|
||||
|
||||
|
|
@ -49,9 +52,11 @@ namespace MapControl
|
|||
BackgroundProperty.OverrideMetadata(typeof(MapBase), new FrameworkPropertyMetadata(Brushes.Transparent));
|
||||
}
|
||||
|
||||
partial void RemoveAnimation(DependencyProperty property)
|
||||
public MapBase()
|
||||
{
|
||||
BeginAnimation(property, null);
|
||||
MapProjection = new WebMercatorProjection();
|
||||
ScaleRotateTransform.Children.Add(ScaleTransform);
|
||||
ScaleRotateTransform.Children.Add(RotateTransform);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>none</DebugType>
|
||||
|
|
@ -99,6 +101,9 @@
|
|||
<Compile Include="..\Shared\MapImageLayer.cs">
|
||||
<Link>MapImageLayer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapItemsControl.cs">
|
||||
<Link>MapItemsControl.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapOverlay.cs">
|
||||
<Link>MapOverlay.cs</Link>
|
||||
</Compile>
|
||||
|
|
@ -123,6 +128,9 @@
|
|||
<Compile Include="..\Shared\OrthographicProjection.cs">
|
||||
<Link>OrthographicProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\Pushpin.cs">
|
||||
<Link>Pushpin.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\StereographicProjection.cs">
|
||||
<Link>StereographicProjection.cs</Link>
|
||||
</Compile>
|
||||
|
|
@ -152,15 +160,12 @@
|
|||
<Compile Include="MapBase.WPF.cs" />
|
||||
<Compile Include="MapGraticule.WPF.cs" />
|
||||
<Compile Include="MapImageLayer.WPF.cs" />
|
||||
<Compile Include="MapItem.WPF.cs" />
|
||||
<Compile Include="MapItemsControl.WPF.cs" />
|
||||
<Compile Include="MapOverlay.WPF.cs" />
|
||||
<Compile Include="MapPanel.WPF.cs" />
|
||||
<Compile Include="MapPath.WPF.cs" />
|
||||
<Compile Include="MapPolyline.WPF.cs" />
|
||||
<Compile Include="MapTileLayer.WPF.cs" />
|
||||
<Compile Include="Pushpin.WPF.cs" />
|
||||
<Compile Include="TileImageLoader.WPF.cs" />
|
||||
<Compile Include="TileSource.WPF.cs" />
|
||||
<Compile Include="TypeConverters.WPF.cs" />
|
||||
<Compile Include="MatrixEx.WPF.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
|
||||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Container class for an item in a MapItemsControl.
|
||||
/// </summary>
|
||||
public class MapItem : ListBoxItem
|
||||
{
|
||||
static MapItem()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(MapItem), new FrameworkPropertyMetadata(typeof(MapItem)));
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty LocationProperty = MapPanel.LocationProperty.AddOwner(typeof(MapItem));
|
||||
|
||||
public Location Location
|
||||
{
|
||||
get { return (Location)GetValue(LocationProperty); }
|
||||
set { SetValue(LocationProperty, value); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
|
||||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages a collection of selectable items on a Map. Uses MapItem as item container class.
|
||||
/// </summary>
|
||||
public class MapItemsControl : ListBox
|
||||
{
|
||||
static MapItemsControl()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(MapItemsControl), new FrameworkPropertyMetadata(typeof(MapItemsControl)));
|
||||
}
|
||||
|
||||
protected override DependencyObject GetContainerForItemOverride()
|
||||
{
|
||||
return new MapItem();
|
||||
}
|
||||
|
||||
protected override bool IsItemItsOwnContainerOverride(object item)
|
||||
{
|
||||
return item is MapItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -51,7 +51,7 @@ namespace MapControl
|
|||
public static readonly DependencyProperty StrokeMiterLimitProperty = Shape.StrokeMiterLimitProperty.AddOwner(
|
||||
typeof(MapOverlay), new FrameworkPropertyMetadata { AffectsRender = true });
|
||||
|
||||
protected override void SetParentMapOverride(MapBase parentMap)
|
||||
protected override void SetParentMap(MapBase parentMap)
|
||||
{
|
||||
if (GetBindingExpression(StrokeProperty) != null)
|
||||
{
|
||||
|
|
@ -67,7 +67,7 @@ namespace MapControl
|
|||
});
|
||||
}
|
||||
|
||||
base.SetParentMapOverride(parentMap);
|
||||
base.SetParentMap(parentMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,17 +14,17 @@ namespace MapControl
|
|||
|
||||
public static readonly DependencyProperty ParentMapProperty = ParentMapPropertyKey.DependencyProperty;
|
||||
|
||||
public MapPanel()
|
||||
{
|
||||
if (this is MapBase)
|
||||
{
|
||||
SetValue(ParentMapPropertyKey, this);
|
||||
}
|
||||
}
|
||||
|
||||
public static MapBase GetParentMap(UIElement element)
|
||||
{
|
||||
return (MapBase)element.GetValue(ParentMapProperty);
|
||||
}
|
||||
|
||||
public static void InitMapElement(FrameworkElement element)
|
||||
{
|
||||
if (element is MapBase)
|
||||
{
|
||||
element.SetValue(ParentMapPropertyKey, element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
|
||||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Displays a pushpin at a geographic location provided by the MapPanel.Location attached property.
|
||||
/// </summary>
|
||||
public class Pushpin : ContentControl
|
||||
{
|
||||
static Pushpin()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(Pushpin), new FrameworkPropertyMetadata(typeof(Pushpin)));
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty LocationProperty =
|
||||
MapPanel.LocationProperty.AddOwner(typeof(Pushpin));
|
||||
|
||||
public Location Location
|
||||
{
|
||||
get { return (Location)GetValue(LocationProperty); }
|
||||
set { SetValue(LocationProperty, value); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,11 +3,8 @@
|
|||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Runtime.Caching;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
|
@ -34,11 +31,6 @@ namespace MapControl
|
|||
var buffer = GetCachedImage(cacheKey, out expiration);
|
||||
var loaded = false;
|
||||
|
||||
//if (buffer != null)
|
||||
//{
|
||||
// Debug.WriteLine("TileImageLoader: {0}: expire{1} {2}", cacheKey, expiration < DateTime.UtcNow ? "d" : "s", expiration);
|
||||
//}
|
||||
|
||||
if (buffer == null || expiration < DateTime.UtcNow)
|
||||
{
|
||||
loaded = await DownloadTileImageAsync(tile, uri, cacheKey);
|
||||
|
|
@ -55,32 +47,31 @@ namespace MapControl
|
|||
|
||||
private async Task<bool> DownloadTileImageAsync(Tile tile, Uri uri, string cacheKey)
|
||||
{
|
||||
var success = false;
|
||||
|
||||
try
|
||||
{
|
||||
using (var response = await HttpClient.GetAsync(uri))
|
||||
using (var response = await TileSource.HttpClient.GetAsync(uri))
|
||||
{
|
||||
if (response.IsSuccessStatusCode)
|
||||
success = response.IsSuccessStatusCode;
|
||||
|
||||
if (!success)
|
||||
{
|
||||
IEnumerable<string> tileInfo;
|
||||
|
||||
if (!response.Headers.TryGetValues(bingMapsTileInfo, out tileInfo) ||
|
||||
!tileInfo.Contains(bingMapsNoTile))
|
||||
Debug.WriteLine("TileImageLoader: {0}: {1} {2}", uri, (int)response.StatusCode, response.ReasonPhrase);
|
||||
}
|
||||
else if (TileSource.TileAvailable(response.Headers))
|
||||
{
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
await response.Content.CopyToAsync(stream);
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
await response.Content.CopyToAsync(stream);
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
await SetTileImageAsync(tile, stream); // create BitmapFrame in UI thread before caching
|
||||
await SetTileImageAsync(tile, stream); // create BitmapFrame before caching
|
||||
|
||||
SetCachedImage(cacheKey, stream, GetExpiration(response));
|
||||
}
|
||||
SetCachedImage(cacheKey, stream, GetExpiration(response));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Debug.WriteLine("TileImageLoader: {0}: {1} {2}", uri, (int)response.StatusCode, response.ReasonPhrase);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -88,7 +79,7 @@ namespace MapControl
|
|||
Debug.WriteLine("TileImageLoader: {0}: {1}", uri, ex.Message);
|
||||
}
|
||||
|
||||
return false;
|
||||
return success;
|
||||
}
|
||||
|
||||
private async Task SetTileImageAsync(Tile tile, MemoryStream stream)
|
||||
|
|
|
|||
82
MapControl/WPF/TileSource.WPF.cs
Normal file
82
MapControl/WPF/TileSource.WPF.cs
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
|
||||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
public partial class TileSource
|
||||
{
|
||||
/// <summary>
|
||||
/// The HttpClient instance used when image data is downloaded from a web resource.
|
||||
/// </summary>
|
||||
public static HttpClient HttpClient { get; set; } = new HttpClient();
|
||||
|
||||
/// <summary>
|
||||
/// Check HTTP response headers for tile unavailability, e.g. X-VE-Tile-Info=no-tile
|
||||
/// </summary>
|
||||
public static bool TileAvailable(HttpResponseHeaders responseHeaders)
|
||||
{
|
||||
IEnumerable<string> tileInfo;
|
||||
|
||||
return !responseHeaders.TryGetValues("X-VE-Tile-Info", out tileInfo) || !tileInfo.Contains("no-tile");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load a tile ImageSource asynchronously from GetUri(x, y, zoomLevel)
|
||||
/// </summary>
|
||||
public virtual async Task<ImageSource> LoadImageAsync(int x, int y, int zoomLevel)
|
||||
{
|
||||
ImageSource imageSource = null;
|
||||
|
||||
var uri = GetUri(x, y, zoomLevel);
|
||||
|
||||
if (uri != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (uri.Scheme == "http")
|
||||
{
|
||||
using (var response = await HttpClient.GetAsync(uri))
|
||||
{
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
Debug.WriteLine("TileSource: {0}: {1} {2}", uri, (int)response.StatusCode, response.ReasonPhrase);
|
||||
}
|
||||
else if (TileAvailable(response.Headers))
|
||||
{
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
await response.Content.CopyToAsync(stream);
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
imageSource = await Task.Run(() => BitmapFrame.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
imageSource = BitmapFrame.Create(uri, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("TileSource: {0}: {1}", uri, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
return imageSource;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue