mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2025-12-06 07:12:04 +01:00
Use System.Runtime.Caching.MemoryCache
This commit is contained in:
parent
de8e9840b5
commit
38e6c23114
|
|
@ -12,7 +12,8 @@
|
||||||
<AssemblyName>MapControl</AssemblyName>
|
<AssemblyName>MapControl</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
|
<TargetFrameworkProfile>
|
||||||
|
</TargetFrameworkProfile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
|
@ -22,6 +23,7 @@
|
||||||
<DefineConstants>TRACE;DEBUG</DefineConstants>
|
<DefineConstants>TRACE;DEBUG</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>none</DebugType>
|
<DebugType>none</DebugType>
|
||||||
|
|
@ -31,13 +33,14 @@
|
||||||
</DefineConstants>
|
</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="PresentationCore" />
|
<Reference Include="PresentationCore" />
|
||||||
<Reference Include="PresentationFramework" />
|
<Reference Include="PresentationFramework" />
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.configuration" />
|
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Runtime.Caching" />
|
||||||
<Reference Include="System.Xaml" />
|
<Reference Include="System.Xaml" />
|
||||||
<Reference Include="WindowsBase" />
|
<Reference Include="WindowsBase" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Runtime.Caching;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
|
|
@ -21,18 +22,20 @@ namespace MapControl
|
||||||
public class TileImageLoader : DispatcherObject
|
public class TileImageLoader : DispatcherObject
|
||||||
{
|
{
|
||||||
public static string TileCacheFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "MapControl Cache");
|
public static string TileCacheFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "MapControl Cache");
|
||||||
public static TimeSpan TileCacheExpiryAge = TimeSpan.FromDays(1);
|
public static TimeSpan TileCacheExpiryAge = TimeSpan.FromDays(1d);
|
||||||
|
|
||||||
|
private readonly TileLayer tileLayer;
|
||||||
private readonly Queue<Tile> pendingTiles = new Queue<Tile>();
|
private readonly Queue<Tile> pendingTiles = new Queue<Tile>();
|
||||||
private int numDownloads;
|
private int numDownloads;
|
||||||
|
|
||||||
internal int MaxDownloads;
|
public TileImageLoader(TileLayer tileLayer)
|
||||||
internal string TileLayerName;
|
{
|
||||||
internal TileSource TileSource;
|
this.tileLayer = tileLayer;
|
||||||
|
}
|
||||||
|
|
||||||
private bool IsCached
|
private bool IsCached
|
||||||
{
|
{
|
||||||
get { return !string.IsNullOrEmpty(TileCacheFolder) && !string.IsNullOrEmpty(TileLayerName); }
|
get { return tileLayer.IsCached && !string.IsNullOrEmpty(TileCacheFolder); }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void StartDownloadTiles(ICollection<Tile> tiles)
|
internal void StartDownloadTiles(ICollection<Tile> tiles)
|
||||||
|
|
@ -51,39 +54,41 @@ namespace MapControl
|
||||||
private void StartDownloadTilesAsync(object newTilesList)
|
private void StartDownloadTilesAsync(object newTilesList)
|
||||||
{
|
{
|
||||||
List<Tile> newTiles = (List<Tile>)newTilesList;
|
List<Tile> newTiles = (List<Tile>)newTilesList;
|
||||||
|
List<Tile> expiredTiles = new List<Tile>(newTiles.Count);
|
||||||
|
|
||||||
lock (pendingTiles)
|
lock (pendingTiles)
|
||||||
{
|
{
|
||||||
if (IsCached)
|
newTiles.ForEach(tile =>
|
||||||
{
|
{
|
||||||
List<Tile> expiredTiles = new List<Tile>(newTiles.Count);
|
ImageSource image = GetMemoryCachedImage(tile);
|
||||||
|
|
||||||
newTiles.ForEach(tile =>
|
if (image == null && IsCached)
|
||||||
{
|
{
|
||||||
bool cacheExpired;
|
bool fileCacheExpired;
|
||||||
ImageSource image = GetCachedImage(tile, out cacheExpired);
|
image = GetFileCachedImage(tile, out fileCacheExpired);
|
||||||
|
|
||||||
if (image != null)
|
if (image != null)
|
||||||
{
|
{
|
||||||
Dispatcher.BeginInvoke((Action)(() => tile.Image = image));
|
SetMemoryCachedImage(tile, image);
|
||||||
|
|
||||||
if (cacheExpired)
|
if (fileCacheExpired)
|
||||||
{
|
{
|
||||||
expiredTiles.Add(tile); // enqueue later
|
expiredTiles.Add(tile); // enqueue later
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
|
||||||
pendingTiles.Enqueue(tile);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
expiredTiles.ForEach(tile => pendingTiles.Enqueue(tile));
|
if (image != null)
|
||||||
}
|
{
|
||||||
else
|
Dispatcher.BeginInvoke((Action)(() => tile.Image = image));
|
||||||
{
|
}
|
||||||
newTiles.ForEach(tile => pendingTiles.Enqueue(tile));
|
else
|
||||||
}
|
{
|
||||||
|
pendingTiles.Enqueue(tile);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expiredTiles.ForEach(tile => pendingTiles.Enqueue(tile));
|
||||||
|
|
||||||
DownloadNextTiles(null);
|
DownloadNextTiles(null);
|
||||||
}
|
}
|
||||||
|
|
@ -91,10 +96,10 @@ namespace MapControl
|
||||||
|
|
||||||
private void DownloadNextTiles(object o)
|
private void DownloadNextTiles(object o)
|
||||||
{
|
{
|
||||||
while (pendingTiles.Count > 0 && numDownloads < MaxDownloads)
|
while (pendingTiles.Count > 0 && numDownloads < tileLayer.MaxDownloads)
|
||||||
{
|
{
|
||||||
Tile tile = pendingTiles.Dequeue();
|
Tile tile = pendingTiles.Dequeue();
|
||||||
tile.Uri = TileSource.GetUri(tile.XIndex, tile.Y, tile.ZoomLevel);
|
tile.Uri = tileLayer.TileSource.GetUri(tile.XIndex, tile.Y, tile.ZoomLevel);
|
||||||
numDownloads++;
|
numDownloads++;
|
||||||
|
|
||||||
ThreadPool.QueueUserWorkItem(DownloadTileAsync, tile);
|
ThreadPool.QueueUserWorkItem(DownloadTileAsync, tile);
|
||||||
|
|
@ -108,53 +113,72 @@ namespace MapControl
|
||||||
|
|
||||||
if (image != null)
|
if (image != null)
|
||||||
{
|
{
|
||||||
|
SetMemoryCachedImage(tile, image);
|
||||||
|
|
||||||
Dispatcher.BeginInvoke((Action)(() => tile.Image = image));
|
Dispatcher.BeginInvoke((Action)(() => tile.Image = image));
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (pendingTiles)
|
lock (pendingTiles)
|
||||||
{
|
{
|
||||||
tile.Uri = null;
|
|
||||||
numDownloads--;
|
numDownloads--;
|
||||||
DownloadNextTiles(null);
|
DownloadNextTiles(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImageSource GetCachedImage(Tile tile, out bool expired)
|
private string MemoryCacheKey(Tile tile)
|
||||||
{
|
{
|
||||||
string tileDir = TileDirectory(tile);
|
return string.Format("{0}/{1}/{2}/{3}", tileLayer.Name, tile.ZoomLevel, tile.XIndex, tile.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string CacheFilePath(Tile tile)
|
||||||
|
{
|
||||||
|
return string.Format("{0}.{1}",
|
||||||
|
Path.Combine(TileCacheFolder, tileLayer.Name, tile.ZoomLevel.ToString(), tile.XIndex.ToString(), tile.Y.ToString()),
|
||||||
|
tileLayer.ImageType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ImageSource GetMemoryCachedImage(Tile tile)
|
||||||
|
{
|
||||||
|
string key = MemoryCacheKey(tile);
|
||||||
|
ImageSource image = MemoryCache.Default.Get(key) as ImageSource;
|
||||||
|
|
||||||
|
if (image != null)
|
||||||
|
{
|
||||||
|
TraceInformation("{0} - Memory Cached", key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetMemoryCachedImage(Tile tile, ImageSource image)
|
||||||
|
{
|
||||||
|
MemoryCache.Default.Set(MemoryCacheKey(tile), image,
|
||||||
|
new CacheItemPolicy { SlidingExpiration = TimeSpan.FromMinutes(10d) });
|
||||||
|
}
|
||||||
|
|
||||||
|
private ImageSource GetFileCachedImage(Tile tile, out bool expired)
|
||||||
|
{
|
||||||
|
string path = CacheFilePath(tile);
|
||||||
ImageSource image = null;
|
ImageSource image = null;
|
||||||
expired = false;
|
expired = false;
|
||||||
|
|
||||||
try
|
if (File.Exists(path))
|
||||||
{
|
{
|
||||||
if (Directory.Exists(tileDir))
|
try
|
||||||
{
|
{
|
||||||
string tilePath = Directory.GetFiles(tileDir, string.Format("{0}.*", tile.Y)).FirstOrDefault();
|
using (Stream fileStream = File.OpenRead(path))
|
||||||
|
|
||||||
if (tilePath != null)
|
|
||||||
{
|
{
|
||||||
try
|
image = BitmapFrame.Create(fileStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
|
||||||
{
|
|
||||||
using (Stream fileStream = File.OpenRead(tilePath))
|
|
||||||
{
|
|
||||||
image = BitmapFrame.Create(fileStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
|
|
||||||
}
|
|
||||||
|
|
||||||
expired = File.GetLastWriteTime(tilePath) + TileCacheExpiryAge <= DateTime.Now;
|
|
||||||
|
|
||||||
TraceInformation(expired ? "{0} - Cache Expired" : "{0} - Cached", tilePath);
|
|
||||||
}
|
|
||||||
catch (Exception exc)
|
|
||||||
{
|
|
||||||
TraceWarning("{0} - {1}", tilePath, exc.Message);
|
|
||||||
File.Delete(tilePath);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expired = File.GetLastWriteTime(path) + TileCacheExpiryAge <= DateTime.Now;
|
||||||
|
TraceInformation(expired ? "{0} - File Cache Expired" : "{0} - File Cached", path);
|
||||||
|
}
|
||||||
|
catch (Exception exc)
|
||||||
|
{
|
||||||
|
TraceWarning("{0} - {1}", path, exc.Message);
|
||||||
|
File.Delete(path);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (Exception exc)
|
|
||||||
{
|
|
||||||
TraceWarning("{0} - {1}", tileDir, exc.Message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
|
|
@ -180,17 +204,14 @@ namespace MapControl
|
||||||
{
|
{
|
||||||
responseStream.CopyTo(memoryStream);
|
responseStream.CopyTo(memoryStream);
|
||||||
memoryStream.Position = 0;
|
memoryStream.Position = 0;
|
||||||
|
image = BitmapFrame.Create(memoryStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
|
||||||
|
|
||||||
BitmapDecoder decoder = BitmapDecoder.Create(memoryStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
|
if (IsCached)
|
||||||
image = decoder.Frames[0];
|
|
||||||
|
|
||||||
string tilePath;
|
|
||||||
|
|
||||||
if (IsCached && (tilePath = TilePath(tile, decoder)) != null)
|
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(tilePath));
|
string path = CacheFilePath(tile);
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||||
|
|
||||||
using (Stream fileStream = File.OpenWrite(tilePath))
|
using (Stream fileStream = File.OpenWrite(path))
|
||||||
{
|
{
|
||||||
memoryStream.Position = 0;
|
memoryStream.Position = 0;
|
||||||
memoryStream.CopyTo(fileStream);
|
memoryStream.CopyTo(fileStream);
|
||||||
|
|
@ -221,43 +242,6 @@ namespace MapControl
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string TileDirectory(Tile tile)
|
|
||||||
{
|
|
||||||
return Path.Combine(TileCacheFolder, TileLayerName, tile.ZoomLevel.ToString(), tile.XIndex.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private string TilePath(Tile tile, BitmapDecoder decoder)
|
|
||||||
{
|
|
||||||
string extension;
|
|
||||||
|
|
||||||
if (decoder is PngBitmapDecoder)
|
|
||||||
{
|
|
||||||
extension = "png";
|
|
||||||
}
|
|
||||||
else if (decoder is JpegBitmapDecoder)
|
|
||||||
{
|
|
||||||
extension = "jpg";
|
|
||||||
}
|
|
||||||
else if (decoder is BmpBitmapDecoder)
|
|
||||||
{
|
|
||||||
extension = "bmp";
|
|
||||||
}
|
|
||||||
else if (decoder is GifBitmapDecoder)
|
|
||||||
{
|
|
||||||
extension = "gif";
|
|
||||||
}
|
|
||||||
else if (decoder is TiffBitmapDecoder)
|
|
||||||
{
|
|
||||||
extension = "tif";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Path.Combine(TileDirectory(tile), string.Format("{0}.{1}", tile.Y, extension));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void TraceWarning(string format, params object[] args)
|
private static void TraceWarning(string format, params object[] args)
|
||||||
{
|
{
|
||||||
System.Diagnostics.Trace.TraceWarning("[{0:00}] {1}", Thread.CurrentThread.ManagedThreadId, string.Format(format, args));
|
System.Diagnostics.Trace.TraceWarning("[{0:00}] {1}", Thread.CurrentThread.ManagedThreadId, string.Format(format, args));
|
||||||
|
|
@ -265,7 +249,7 @@ namespace MapControl
|
||||||
|
|
||||||
private static void TraceInformation(string format, params object[] args)
|
private static void TraceInformation(string format, params object[] args)
|
||||||
{
|
{
|
||||||
System.Diagnostics.Trace.TraceInformation("[{0:00}] {1}", Thread.CurrentThread.ManagedThreadId, string.Format(format, args));
|
//System.Diagnostics.Trace.TraceInformation("[{0:00}] {1}", Thread.CurrentThread.ManagedThreadId, string.Format(format, args));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,58 +18,32 @@ namespace MapControl
|
||||||
[ContentProperty("TileSource")]
|
[ContentProperty("TileSource")]
|
||||||
public class TileLayer : DrawingVisual
|
public class TileLayer : DrawingVisual
|
||||||
{
|
{
|
||||||
private readonly TileImageLoader tileImageLoader = new TileImageLoader();
|
private readonly TileImageLoader tileImageLoader;
|
||||||
private readonly List<Tile> tiles = new List<Tile>();
|
private readonly List<Tile> tiles = new List<Tile>();
|
||||||
private bool isCached = false;
|
|
||||||
private string name = string.Empty;
|
|
||||||
private string description = string.Empty;
|
private string description = string.Empty;
|
||||||
private Int32Rect grid;
|
private Int32Rect grid;
|
||||||
private int zoomLevel;
|
private int zoomLevel;
|
||||||
|
|
||||||
public TileLayer()
|
public TileLayer()
|
||||||
{
|
{
|
||||||
|
tileImageLoader = new TileImageLoader(this);
|
||||||
VisualEdgeMode = EdgeMode.Aliased;
|
VisualEdgeMode = EdgeMode.Aliased;
|
||||||
VisualTransform = new MatrixTransform();
|
VisualTransform = new MatrixTransform();
|
||||||
|
Name = string.Empty;
|
||||||
|
ImageType = "png";
|
||||||
MinZoomLevel = 1;
|
MinZoomLevel = 1;
|
||||||
MaxZoomLevel = 18;
|
MaxZoomLevel = 18;
|
||||||
MaxDownloads = 8;
|
MaxDownloads = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasDarkBackground { get; set; }
|
public string Name { get; set; }
|
||||||
|
public string ImageType { get; set; }
|
||||||
|
public TileSource TileSource { get; set; }
|
||||||
public int MinZoomLevel { get; set; }
|
public int MinZoomLevel { get; set; }
|
||||||
public int MaxZoomLevel { get; set; }
|
public int MaxZoomLevel { get; set; }
|
||||||
|
public int MaxDownloads { get; set; }
|
||||||
public int MaxDownloads
|
public bool IsCached { get; set; }
|
||||||
{
|
public bool HasDarkBackground { get; set; }
|
||||||
get { return tileImageLoader.MaxDownloads; }
|
|
||||||
set { tileImageLoader.MaxDownloads = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public TileSource TileSource
|
|
||||||
{
|
|
||||||
get { return tileImageLoader.TileSource; }
|
|
||||||
set { tileImageLoader.TileSource = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsCached
|
|
||||||
{
|
|
||||||
get { return isCached; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
isCached = value;
|
|
||||||
tileImageLoader.TileLayerName = isCached ? name : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get { return name; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
name = value;
|
|
||||||
tileImageLoader.TileLayerName = isCached ? name : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Description
|
public string Description
|
||||||
{
|
{
|
||||||
|
|
@ -150,7 +124,7 @@ namespace MapControl
|
||||||
|
|
||||||
tiles.Sort((t1, t2) => t1.ZoomLevel - t2.ZoomLevel);
|
tiles.Sort((t1, t2) => t1.ZoomLevel - t2.ZoomLevel);
|
||||||
|
|
||||||
System.Diagnostics.Trace.TraceInformation("{0} Tiles: {1}", tiles.Count, string.Join(", ", tiles.Select(t => t.ZoomLevel.ToString())));
|
//System.Diagnostics.Trace.TraceInformation("{0} Tiles: {1}", tiles.Count, string.Join(", ", tiles.Select(t => t.ZoomLevel.ToString())));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RenderTiles()
|
private void RenderTiles()
|
||||||
|
|
@ -170,4 +144,4 @@ namespace MapControl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -120,35 +120,30 @@
|
||||||
<ComboBox Name="tileLayerComboBox" ToolTip="Main Tile Layer" Margin="4,0,4,0" DisplayMemberPath="Name" SelectedIndex="0">
|
<ComboBox Name="tileLayerComboBox" ToolTip="Main Tile Layer" Margin="4,0,4,0" DisplayMemberPath="Name" SelectedIndex="0">
|
||||||
<ComboBox.Items>
|
<ComboBox.Items>
|
||||||
<map:TileLayer Name="OpenStreetMap" Description="© {y} OpenStreetMap Contributors, CC-BY-SA"
|
<map:TileLayer Name="OpenStreetMap" Description="© {y} OpenStreetMap Contributors, CC-BY-SA"
|
||||||
TileSource="http://{c}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
TileSource="http://{c}.tile.openstreetmap.org/{z}/{x}/{y}.png" IsCached="False"/>
|
||||||
IsCached="False"/>
|
|
||||||
<map:TileLayer Name="OpenCycleMap" Description="OpenCycleMap - © {y} Andy Allen & OpenStreetMap Contributors, CC-BY-SA"
|
<map:TileLayer Name="OpenCycleMap" Description="OpenCycleMap - © {y} Andy Allen & OpenStreetMap Contributors, CC-BY-SA"
|
||||||
TileSource="http://{c}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png"
|
TileSource="http://{c}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png" IsCached="False"/>
|
||||||
IsCached="False"/>
|
|
||||||
<map:TileLayer Name="OCM Transport" Description="OpenCycleMap Transport - © {y} Andy Allen & OpenStreetMap Contributors, CC-BY-SA"
|
<map:TileLayer Name="OCM Transport" Description="OpenCycleMap Transport - © {y} Andy Allen & OpenStreetMap Contributors, CC-BY-SA"
|
||||||
TileSource="http://{c}.tile2.opencyclemap.org/transport/{z}/{x}/{y}.png"
|
TileSource="http://{c}.tile2.opencyclemap.org/transport/{z}/{x}/{y}.png" IsCached="False"/>
|
||||||
IsCached="False"/>
|
|
||||||
<map:TileLayer Name="OCM Landscape" Description="OpenCycleMap Landscape - © {y} Andy Allen & OpenStreetMap Contributors, CC-BY-SA"
|
<map:TileLayer Name="OCM Landscape" Description="OpenCycleMap Landscape - © {y} Andy Allen & OpenStreetMap Contributors, CC-BY-SA"
|
||||||
TileSource="http://{c}.tile3.opencyclemap.org/landscape/{z}/{x}/{y}.png"
|
TileSource="http://{c}.tile3.opencyclemap.org/landscape/{z}/{x}/{y}.png" IsCached="False"/>
|
||||||
IsCached="False"/>
|
|
||||||
<map:TileLayer Name="MapQuest OSM" Description="MapQuest OSM - © {y} MapQuest & OpenStreetMap Contributors"
|
<map:TileLayer Name="MapQuest OSM" Description="MapQuest OSM - © {y} MapQuest & OpenStreetMap Contributors"
|
||||||
TileSource="http://otile{n}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png"
|
TileSource="http://otile{n}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png" IsCached="False"/>
|
||||||
IsCached="False"/>
|
|
||||||
<!--<map:TileLayer Name="Google Maps" Description="Google Maps - © {y} Google"
|
<!--<map:TileLayer Name="Google Maps" Description="Google Maps - © {y} Google"
|
||||||
TileSource="http://mt{i}.google.com/vt/x={x}&y={y}&z={z}"
|
TileSource="http://mt{i}.google.com/vt/x={x}&y={y}&z={z}"
|
||||||
IsCached="False" MaxZoomLevel="20"/>
|
IsCached="False" MaxZoomLevel="20"/>
|
||||||
<map:TileLayer Name="Google Images" Description="Google Maps - © {y} Google"
|
<map:TileLayer Name="Google Images" Description="Google Maps - © {y} Google"
|
||||||
TileSource="http://khm{i}.google.com/kh/v=113&x={x}&y={y}&z={z}"
|
TileSource="http://khm{i}.google.com/kh/v=113&x={x}&y={y}&z={z}"
|
||||||
IsCached="False" MaxZoomLevel="20" HasDarkBackground="True"/>
|
ImageType="jpg" IsCached="False" MaxZoomLevel="20" HasDarkBackground="True"/>
|
||||||
<map:TileLayer Name="Bing Maps" Description="Bing Maps - © {y} Microsoft Corporation"
|
<map:TileLayer Name="Bing Maps" Description="Bing Maps - © {y} Microsoft Corporation"
|
||||||
TileSource="http://ecn.t{i}.tiles.virtualearth.net/tiles/r{q}.png?g=0&stl=h"
|
TileSource="http://ecn.t{i}.tiles.virtualearth.net/tiles/r{q}.png?g=0&stl=h"
|
||||||
IsCached="False" MaxZoomLevel="20"/>
|
IsCached="False" MaxZoomLevel="20"/>
|
||||||
<map:TileLayer Name="Bing Images" Description="Bing Maps - © {y} Microsoft Corporation"
|
<map:TileLayer Name="Bing Images" Description="Bing Maps - © {y} Microsoft Corporation"
|
||||||
TileSource="http://ecn.t{i}.tiles.virtualearth.net/tiles/a{q}.jpeg?g=0"
|
TileSource="http://ecn.t{i}.tiles.virtualearth.net/tiles/a{q}.jpeg?g=0"
|
||||||
IsCached="False" MaxZoomLevel="20" HasDarkBackground="True"/>
|
ImageType="jpg" IsCached="False" MaxZoomLevel="20" HasDarkBackground="True"/>
|
||||||
<map:TileLayer Name="Bing Hybrid" Description="Bing Maps - © {y} Microsoft Corporation"
|
<map:TileLayer Name="Bing Hybrid" Description="Bing Maps - © {y} Microsoft Corporation"
|
||||||
TileSource="http://ecn.t{i}.tiles.virtualearth.net/tiles/h{q}.jpeg?g=0&stl=h"
|
TileSource="http://ecn.t{i}.tiles.virtualearth.net/tiles/h{q}.jpeg?g=0&stl=h"
|
||||||
IsCached="False" MaxZoomLevel="20" HasDarkBackground="True"/>-->
|
ImageType="jpg" IsCached="False" MaxZoomLevel="20" HasDarkBackground="True"/>-->
|
||||||
</ComboBox.Items>
|
</ComboBox.Items>
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@
|
||||||
<RootNamespace>MapControlTestApp</RootNamespace>
|
<RootNamespace>MapControlTestApp</RootNamespace>
|
||||||
<AssemblyName>MapControlTestApp</AssemblyName>
|
<AssemblyName>MapControlTestApp</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||||
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
|
<TargetFrameworkProfile>
|
||||||
|
</TargetFrameworkProfile>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
|
@ -25,6 +26,7 @@
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
|
@ -34,6 +36,7 @@
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue