mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2025-12-06 07:12:04 +01:00
Version 4: Upgrade to VS 2017
This commit is contained in:
parent
2aafe32e00
commit
ec47f225b3
|
|
@ -1,37 +1,69 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}</ProjectGuid>
|
||||
<ProjectGuid>{3FF37D40-F770-45B2-95DD-7A84093E1425}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MapControl.Caching</RootNamespace>
|
||||
<AssemblyName>FileDbCache.WinRT</AssemblyName>
|
||||
<AssemblyName>FileDbCache.UWP</AssemblyName>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||
<TargetPlatformVersion>10.0.10240.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
|
||||
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<TargetFrameworkProfile>Profile32</TargetFrameworkProfile>
|
||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<RuntimeIdentifiers>win10-arm;win10-arm-aot;win10-x86;win10-x86-aot;win10-x64;win10-x64-aot</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<OutputPath>..\bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<GenerateLibraryLayout>true</GenerateLibraryLayout>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<OutputPath>..\bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<GenerateLibraryLayout>true</GenerateLibraryLayout>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- A reference to the entire .Net Framework and Windows SDK are automatically included -->
|
||||
<None Include="..\..\MapControl.snk">
|
||||
<Link>MapControl.snk</Link>
|
||||
</None>
|
||||
<None Include="project.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="FileDbCache.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="Properties\FileDbCache.UWP.rd.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="FileDbPcl">
|
||||
<HintPath>..\FileDb\FileDbPcl.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\MapControl\UWP\MapControl.UWP.csproj">
|
||||
<Project>{951bc5d2-d653-42d9-9a91-21dc50de0182}</Project>
|
||||
<Name>MapControl.UWP</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
|
|
@ -39,31 +71,7 @@
|
|||
<PropertyGroup>
|
||||
<AssemblyOriginatorKeyFile>..\..\MapControl.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<TargetPlatform Include="WindowsPhoneApp, Version=8.1" />
|
||||
<TargetPlatform Include="Windows, Version=8.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="FileDbCache.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\MapControl.snk">
|
||||
<Link>MapControl.snk</Link>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\MapControl\WinRT\MapControl.WinRT.csproj">
|
||||
<Project>{63cefdf7-5170-43b6-86f8-5c4a383a1615}</Project>
|
||||
<Name>MapControl.WinRT</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="FileDbPcl">
|
||||
<HintPath>..\FileDb\FileDbPcl.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
|
@ -18,35 +18,33 @@ namespace MapControl.Caching
|
|||
/// IImageCache implementation based on FileDb, a free and simple No-SQL database by EzTools Software.
|
||||
/// See http://www.eztools-software.com/tools/filedb/.
|
||||
/// </summary>
|
||||
public class FileDbCache : IImageCache, IDisposable
|
||||
public sealed class FileDbCache : IImageCache, IDisposable
|
||||
{
|
||||
private const string keyField = "Key";
|
||||
private const string valueField = "Value";
|
||||
private const string expiresField = "Expires";
|
||||
|
||||
private readonly FileDb fileDb = new FileDb { AutoFlush = true, AutoCleanThreshold = -1 };
|
||||
private readonly FileDb fileDb = new FileDb();
|
||||
private readonly StorageFolder folder;
|
||||
private readonly string name;
|
||||
private readonly string fileName;
|
||||
|
||||
public FileDbCache(string name = null, StorageFolder folder = null)
|
||||
public FileDbCache(StorageFolder folder, string fileName = "TileCache.fdb", bool autoFlush = true, int autoCleanThreshold = -1)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
name = TileImageLoader.DefaultCacheName;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(Path.GetExtension(name)))
|
||||
{
|
||||
name += ".fdb";
|
||||
}
|
||||
|
||||
if (folder == null)
|
||||
{
|
||||
folder = TileImageLoader.DefaultCacheFolder;
|
||||
throw new ArgumentNullException("The parameter folder must not be null.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(fileName))
|
||||
{
|
||||
throw new ArgumentNullException("The parameter fileName must not be null.");
|
||||
}
|
||||
|
||||
this.folder = folder;
|
||||
this.name = name;
|
||||
this.fileName = fileName;
|
||||
|
||||
fileDb.AutoFlush = autoFlush;
|
||||
fileDb.AutoCleanThreshold = autoCleanThreshold;
|
||||
|
||||
Application.Current.Resuming += async (s, e) => await Open();
|
||||
Application.Current.Suspending += (s, e) => Close();
|
||||
|
|
@ -73,7 +71,7 @@ namespace MapControl.Caching
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<ImageCacheItem> GetAsync(string key)
|
||||
public Task<ImageCacheItem> GetAsync(string key)
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
|
|
@ -85,10 +83,10 @@ namespace MapControl.Caching
|
|||
return null;
|
||||
}
|
||||
|
||||
return await Task.Run(() => Get(key));
|
||||
return Task.Run(() => Get(key));
|
||||
}
|
||||
|
||||
public async Task SetAsync(string key, IBuffer buffer, DateTime expiration)
|
||||
public Task SetAsync(string key, IBuffer buffer, DateTime expiration)
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
|
|
@ -100,16 +98,19 @@ namespace MapControl.Caching
|
|||
throw new ArgumentNullException("The parameter buffer must not be null.");
|
||||
}
|
||||
|
||||
return Task.Run(async () =>
|
||||
{
|
||||
if (fileDb.IsOpen)
|
||||
{
|
||||
var bytes = buffer.ToArray();
|
||||
var ok = await Task.Run(() => AddOrUpdateRecord(key, bytes, expiration));
|
||||
var ok = AddOrUpdateRecord(key, bytes, expiration);
|
||||
|
||||
if (!ok && (await RepairDatabase()))
|
||||
{
|
||||
await Task.Run(() => AddOrUpdateRecord(key, bytes, expiration));
|
||||
AddOrUpdateRecord(key, bytes, expiration);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async Task Open()
|
||||
|
|
@ -118,22 +119,20 @@ namespace MapControl.Caching
|
|||
{
|
||||
try
|
||||
{
|
||||
var file = await folder.GetFileAsync(name);
|
||||
var file = await folder.GetFileAsync(fileName);
|
||||
var stream = await file.OpenAsync(FileAccessMode.ReadWrite);
|
||||
|
||||
fileDb.Open(stream.AsStream());
|
||||
Debug.WriteLine("FileDbCache: Opened database with {0} cached items in {1}", fileDb.NumRecords, file.Path);
|
||||
|
||||
Clean();
|
||||
return;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
await CreateDatabase();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Close()
|
||||
{
|
||||
|
|
@ -147,7 +146,7 @@ namespace MapControl.Caching
|
|||
{
|
||||
Close();
|
||||
|
||||
var file = await folder.CreateFileAsync(name, CreationCollisionOption.ReplaceExisting);
|
||||
var file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
|
||||
var stream = await file.OpenAsync(FileAccessMode.ReadWrite);
|
||||
|
||||
fileDb.Create(stream.AsStream(), new Field[]
|
||||
|
|
@ -179,7 +178,7 @@ namespace MapControl.Caching
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("FileDbCache: Creating database {0}: {1}", Path.Combine(folder.Path, name), ex.Message);
|
||||
Debug.WriteLine("FileDbCache: Creating database {0}: {1}", Path.Combine(folder.Path, fileName), ex.Message);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("XAML Map Control FileDbCache (WinRT)")]
|
||||
[assembly: AssemblyTitle("XAML Map Control FileDbCache for UWP")]
|
||||
[assembly: AssemblyDescription("IImageCache implementation based on EzTools FileDb")]
|
||||
[assembly: AssemblyProduct("XAML Map Control")]
|
||||
[assembly: AssemblyCompany("Clemens Fischer")]
|
||||
[assembly: AssemblyCopyright("© 2017 Clemens Fischer")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyVersion("3.4.1")]
|
||||
[assembly: AssemblyFileVersion("3.4.1")]
|
||||
[assembly: AssemblyVersion("4.0.0")]
|
||||
[assembly: AssemblyFileVersion("4.0.0")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
|
||||
<Library Name="FileDbCache.UWP">
|
||||
</Library>
|
||||
</Directives>
|
||||
16
Caching/FileDbCache.UWP/project.json
Normal file
16
Caching/FileDbCache.UWP/project.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.UniversalWindowsPlatform": "5.1.0"
|
||||
},
|
||||
"frameworks": {
|
||||
"uap10.0": {}
|
||||
},
|
||||
"runtimes": {
|
||||
"win10-arm": {},
|
||||
"win10-arm-aot": {},
|
||||
"win10-x86": {},
|
||||
"win10-x86-aot": {},
|
||||
"win10-x64": {},
|
||||
"win10-x64-aot": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{EF44F661-B98A-4676-927F-85D138F82300}</ProjectGuid>
|
||||
<ProjectGuid>{AD1CB53E-7AA4-4EC0-B901-B4E0E2665133}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MapControl.Caching</RootNamespace>
|
||||
|
|
@ -18,20 +17,18 @@
|
|||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<OutputPath>..\bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<OutputPath>..\bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
|
|
@ -40,12 +37,10 @@
|
|||
<AssemblyOriginatorKeyFile>..\..\MapControl.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="FileDb, Version=5.0.1.0, Culture=neutral, PublicKeyToken=ba3f58a0e60cd01d, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<Reference Include="FileDb">
|
||||
<HintPath>..\FileDb\FileDb.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Runtime.Caching" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
@ -57,7 +52,6 @@
|
|||
<Link>MapControl.snk</Link>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
|
|
|||
|
|
@ -2,14 +2,13 @@
|
|||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using FileDbNs;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Caching;
|
||||
using FileDbNs;
|
||||
|
||||
namespace MapControl.Caching
|
||||
{
|
||||
|
|
@ -17,71 +16,37 @@ namespace MapControl.Caching
|
|||
/// ObjectCache implementation based on FileDb, a free and simple No-SQL database by EzTools Software.
|
||||
/// See http://www.eztools-software.com/tools/filedb/.
|
||||
/// </summary>
|
||||
public class FileDbCache : ObjectCache, IDisposable
|
||||
public sealed class FileDbCache : ObjectCache, IDisposable
|
||||
{
|
||||
private const string keyField = "Key";
|
||||
private const string valueField = "Value";
|
||||
private const string expiresField = "Expires";
|
||||
|
||||
private readonly FileDb fileDb = new FileDb { AutoFlush = true, AutoCleanThreshold = -1 };
|
||||
private readonly string name;
|
||||
private readonly string path;
|
||||
private readonly FileDb fileDb = new FileDb();
|
||||
private readonly string dbPath;
|
||||
|
||||
public FileDbCache(string name, NameValueCollection config)
|
||||
: this(name, config["folder"])
|
||||
public FileDbCache(string path, bool autoFlush = true, int autoCleanThreshold = -1)
|
||||
{
|
||||
var autoFlush = config["autoFlush"];
|
||||
var autoCleanThreshold = config["autoCleanThreshold"];
|
||||
|
||||
if (autoFlush != null)
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
try
|
||||
{
|
||||
fileDb.AutoFlush = bool.Parse(autoFlush);
|
||||
throw new ArgumentException("The parameter path must not be null or empty.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new ArgumentException("The configuration parameter autoFlush must be a boolean value.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (autoCleanThreshold != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
fileDb.AutoCleanThreshold = int.Parse(autoCleanThreshold);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new ArgumentException("The configuration parameter autoCleanThreshold must be an integer value.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FileDbCache(string name, string folder)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new ArgumentException("The parameter name must not be null or empty.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(folder))
|
||||
{
|
||||
throw new ArgumentException("The parameter folder must not be null or empty.");
|
||||
}
|
||||
|
||||
this.name = name;
|
||||
path = Path.Combine(folder, name);
|
||||
|
||||
if (string.IsNullOrEmpty(Path.GetExtension(path)))
|
||||
{
|
||||
path += ".fdb";
|
||||
path = Path.Combine(path, "TileCache.fdb");
|
||||
}
|
||||
|
||||
dbPath = path;
|
||||
|
||||
fileDb.AutoFlush = autoFlush;
|
||||
fileDb.AutoCleanThreshold = autoCleanThreshold;
|
||||
|
||||
try
|
||||
{
|
||||
fileDb.Open(path, false);
|
||||
Debug.WriteLine("FileDbCache: Opened database with {0} cached items in {1}", fileDb.NumRecords, path);
|
||||
fileDb.Open(dbPath, false);
|
||||
|
||||
Debug.WriteLine("FileDbCache: Opened database with {0} cached items in {1}", fileDb.NumRecords, dbPath);
|
||||
|
||||
Clean();
|
||||
}
|
||||
|
|
@ -93,21 +58,9 @@ namespace MapControl.Caching
|
|||
AppDomain.CurrentDomain.ProcessExit += (s, e) => Close();
|
||||
}
|
||||
|
||||
public bool AutoFlush
|
||||
{
|
||||
get { return fileDb.AutoFlush; }
|
||||
set { fileDb.AutoFlush = value; }
|
||||
}
|
||||
|
||||
public int AutoCleanThreshold
|
||||
{
|
||||
get { return fileDb.AutoCleanThreshold; }
|
||||
set { fileDb.AutoCleanThreshold = value; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return name; }
|
||||
get { return string.Empty; }
|
||||
}
|
||||
|
||||
public override DefaultCacheCapabilities DefaultCacheCapabilities
|
||||
|
|
@ -357,23 +310,23 @@ namespace MapControl.Caching
|
|||
{
|
||||
Close();
|
||||
|
||||
if (File.Exists(path))
|
||||
if (File.Exists(dbPath))
|
||||
{
|
||||
File.Delete(path);
|
||||
File.Delete(dbPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(dbPath));
|
||||
}
|
||||
|
||||
fileDb.Create(path, new Field[]
|
||||
fileDb.Create(dbPath, new Field[]
|
||||
{
|
||||
new Field(keyField, DataTypeEnum.String) { IsPrimaryKey = true },
|
||||
new Field(valueField, DataTypeEnum.Byte) { IsArray = true },
|
||||
new Field(expiresField, DataTypeEnum.DateTime)
|
||||
});
|
||||
|
||||
Debug.WriteLine("FileDbCache: Created database " + path);
|
||||
Debug.WriteLine("FileDbCache: Created database " + dbPath);
|
||||
}
|
||||
|
||||
private bool RepairDatabase()
|
||||
|
|
@ -395,7 +348,7 @@ namespace MapControl.Caching
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("FileDbCache: Failed creating database {0}: {1}", path, ex.Message);
|
||||
Debug.WriteLine("FileDbCache: Failed creating database {0}: {1}", dbPath, ex.Message);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("XAML Map Control FileDbCache (WPF)")]
|
||||
[assembly: AssemblyTitle("XAML Map Control FileDbCache for WPF")]
|
||||
[assembly: AssemblyDescription("ObjectCache implementation based on EzTools FileDb")]
|
||||
[assembly: AssemblyProduct("XAML Map Control")]
|
||||
[assembly: AssemblyCompany("Clemens Fischer")]
|
||||
[assembly: AssemblyCopyright("© 2017 Clemens Fischer")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyVersion("3.4.1")]
|
||||
[assembly: AssemblyFileVersion("3.4.1")]
|
||||
[assembly: AssemblyVersion("4.0.0")]
|
||||
[assembly: AssemblyFileVersion("4.0.0")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
|
|
|||
|
|
@ -1,64 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{86470440-FEE2-4120-AF5A-3762FB9C536F}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MapControl.Caching</RootNamespace>
|
||||
<AssemblyName>ImageFileCache.WPF</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AssemblyOriginatorKeyFile>..\..\MapControl.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Runtime.Caching" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ImageFileCache.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\MapControl.snk">
|
||||
<Link>MapControl.snk</Link>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("XAML Map Control ImageFileCache (WPF)")]
|
||||
[assembly: AssemblyDescription("ObjectCache implementation based on local image files")]
|
||||
[assembly: AssemblyProduct("XAML Map Control")]
|
||||
[assembly: AssemblyCompany("Clemens Fischer")]
|
||||
[assembly: AssemblyCopyright("© 2017 Clemens Fischer")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyVersion("3.4.1")]
|
||||
[assembly: AssemblyFileVersion("3.4.1")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{F789647E-96F7-43E3-A895-FA3FE8D01260}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MapControl.Caching</RootNamespace>
|
||||
<AssemblyName>ImageFileCache.WinRT</AssemblyName>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<TargetPlatformIdentifier>Windows</TargetPlatformIdentifier>
|
||||
<TargetPlatformVersion>8.1</TargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_APP</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_APP</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AssemblyOriginatorKeyFile>..\..\MapControl.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- A reference to the entire .NET Framework is automatically included -->
|
||||
<None Include="..\..\MapControl.snk">
|
||||
<Link>MapControl.snk</Link>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ImageFileCache.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\MapControl\WinRT\MapControl.WinRT.csproj">
|
||||
<Project>{63cefdf7-5170-43b6-86f8-5c4a383a1615}</Project>
|
||||
<Name>MapControl.WinRT</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
|
|
@ -1,93 +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;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
using Windows.Storage.Streams;
|
||||
|
||||
namespace MapControl.Caching
|
||||
{
|
||||
public class ImageFileCache : IImageCache
|
||||
{
|
||||
private readonly string name;
|
||||
private StorageFolder rootFolder;
|
||||
|
||||
public ImageFileCache(string name = null, StorageFolder folder = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
name = TileImageLoader.DefaultCacheName;
|
||||
}
|
||||
|
||||
if (folder == null)
|
||||
{
|
||||
folder = TileImageLoader.DefaultCacheFolder;
|
||||
}
|
||||
|
||||
this.name = name;
|
||||
|
||||
folder.CreateFolderAsync(name, CreationCollisionOption.OpenIfExists).Completed = (o, s) =>
|
||||
{
|
||||
rootFolder = o.GetResults();
|
||||
Debug.WriteLine("Created ImageFileCache in " + rootFolder.Path);
|
||||
};
|
||||
}
|
||||
|
||||
public virtual async Task<ImageCacheItem> GetAsync(string key)
|
||||
{
|
||||
var item = await rootFolder.TryGetItemAsync(key);
|
||||
|
||||
if (item != null && item.IsOfType(StorageItemTypes.File))
|
||||
{
|
||||
var file = (StorageFile)item;
|
||||
//Debug.WriteLine("ImageFileCache: Reading " + file.Path);
|
||||
|
||||
try
|
||||
{
|
||||
return new ImageCacheItem
|
||||
{
|
||||
Buffer = await FileIO.ReadBufferAsync(file),
|
||||
Expiration = (await file.Properties.GetImagePropertiesAsync()).DateTaken.UtcDateTime
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("ImageFileCache: Reading {0}: {1}", file.Path, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual async Task SetAsync(string key, IBuffer buffer, DateTime expiration)
|
||||
{
|
||||
try
|
||||
{
|
||||
var names = key.Split('\\');
|
||||
var folder = rootFolder;
|
||||
|
||||
for (int i = 0; i < names.Length - 1; i++)
|
||||
{
|
||||
folder = await folder.CreateFolderAsync(names[i], CreationCollisionOption.OpenIfExists);
|
||||
}
|
||||
|
||||
var file = await folder.CreateFileAsync(names[names.Length - 1], CreationCollisionOption.ReplaceExisting);
|
||||
//Debug.WriteLine("ImageFileCache: Writing {0}, Expires {1}", file.Path, expiration.ToLocalTime());
|
||||
|
||||
await FileIO.WriteBufferAsync(file, buffer);
|
||||
|
||||
// Store expiration date in ImageProperties.DateTaken
|
||||
var properties = await file.Properties.GetImagePropertiesAsync();
|
||||
properties.DateTaken = expiration;
|
||||
await properties.SavePropertiesAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("ImageFileCache: Writing {0}\\{1}: {2}", rootFolder.Path, key, ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("XAML Map Control ImageFileCache (WinRT)")]
|
||||
[assembly: AssemblyDescription("IImageCache implementation based on local image files")]
|
||||
[assembly: AssemblyProduct("XAML Map Control")]
|
||||
[assembly: AssemblyCompany("Clemens Fischer")]
|
||||
[assembly: AssemblyCopyright("© 2017 Clemens Fischer")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyVersion("3.4.1")]
|
||||
[assembly: AssemblyFileVersion("3.4.1")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
284
MapControl.sln
284
MapControl.sln
|
|
@ -1,33 +1,25 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
VisualStudioVersion = 14.0.25123.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileDbCache.WinRT", "Caching\FileDbCache.WinRT\FileDbCache.WinRT.csproj", "{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}"
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MapControl", "MapControl", "{52AECE49-F314-4F76-98F2-FA800F07824B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileDbCache.WPF", "Caching\FileDbCache.WPF\FileDbCache.WPF.csproj", "{EF44F661-B98A-4676-927F-85D138F82300}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapControl.WPF", "MapControl\WPF\MapControl.WPF.csproj", "{A204A102-C745-4D65-AEC8-7B96FAEDEF2D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageFileCache.WinRT", "Caching\ImageFileCache.WinRT\ImageFileCache.WinRT.csproj", "{F789647E-96F7-43E3-A895-FA3FE8D01260}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapControl.UWP", "MapControl\UWP\MapControl.UWP.csproj", "{951BC5D2-D653-42D9-9A91-21DC50DE0182}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageFileCache.WPF", "Caching\ImageFileCache.WPF\ImageFileCache.WPF.csproj", "{86470440-FEE2-4120-AF5A-3762FB9C536F}"
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Caching", "Caching", "{6A596588-F93F-47CC-BE5D-58C3B34ADDEB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapControl.Silverlight", "MapControl\MapControl.Silverlight.csproj", "{EB133B78-DEFF-416A-8F0C-89E54D766576}"
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SampleApps", "SampleApps", "{8F2103C2-78AF-4810-8FB9-67572F50C8FC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapControl.WinRT", "MapControl\WinRT\MapControl.WinRT.csproj", "{63CEFDF7-5170-43B6-86F8-5C4A383A1615}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapControl.WPF", "MapControl\MapControl.WPF.csproj", "{226F3575-B683-446D-A2F0-181291DC8787}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfApplication", "SampleApps\WpfApplication\WpfApplication.csproj", "{9949326E-9261-4F95-89B1-151F60498951}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SampleApps", "SampleApps", "{100879CC-8910-459E-856E-253D629E45DE}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Caching", "Caching", "{AE8A7E02-0F7D-41B0-AB23-15394150ED17}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfApplication", "SampleApps\WpfApplication\WpfApplication.csproj", "{F92DA93D-75DB-4308-A5F9-6B4C3908A675}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversalApp", "SampleApps\UniversalApp\UniversalApp.csproj", "{AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SilverlightApplication", "SampleApps\SilverlightApplication\SilverlightApplication.csproj", "{85AACDB7-959D-406D-A8DF-2F1E013F8F40}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileDbCache.WPF", "Caching\FileDbCache.WPF\FileDbCache.WPF.csproj", "{AD1CB53E-7AA4-4EC0-B901-B4E0E2665133}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SilverlightApplication.Web", "SampleApps\SilverlightApplication.Web\SilverlightApplication.Web.csproj", "{7FB616E1-E0D4-48FA-8AFD-60E73FCF32E4}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileDbCache.UWP", "Caching\FileDbCache.UWP\FileDbCache.UWP.csproj", "{3FF37D40-F770-45B2-95DD-7A84093E1425}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
|
@ -41,135 +33,57 @@ Global
|
|||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}.Release|x64.Build.0 = Release|Any CPU
|
||||
{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}.Release|x86.Build.0 = Release|Any CPU
|
||||
{EF44F661-B98A-4676-927F-85D138F82300}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EF44F661-B98A-4676-927F-85D138F82300}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EF44F661-B98A-4676-927F-85D138F82300}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{EF44F661-B98A-4676-927F-85D138F82300}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{EF44F661-B98A-4676-927F-85D138F82300}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{EF44F661-B98A-4676-927F-85D138F82300}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{EF44F661-B98A-4676-927F-85D138F82300}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{EF44F661-B98A-4676-927F-85D138F82300}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{EF44F661-B98A-4676-927F-85D138F82300}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EF44F661-B98A-4676-927F-85D138F82300}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EF44F661-B98A-4676-927F-85D138F82300}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{EF44F661-B98A-4676-927F-85D138F82300}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{EF44F661-B98A-4676-927F-85D138F82300}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{EF44F661-B98A-4676-927F-85D138F82300}.Release|x64.Build.0 = Release|Any CPU
|
||||
{EF44F661-B98A-4676-927F-85D138F82300}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{EF44F661-B98A-4676-927F-85D138F82300}.Release|x86.Build.0 = Release|Any CPU
|
||||
{F789647E-96F7-43E3-A895-FA3FE8D01260}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F789647E-96F7-43E3-A895-FA3FE8D01260}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F789647E-96F7-43E3-A895-FA3FE8D01260}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{F789647E-96F7-43E3-A895-FA3FE8D01260}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{F789647E-96F7-43E3-A895-FA3FE8D01260}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{F789647E-96F7-43E3-A895-FA3FE8D01260}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{F789647E-96F7-43E3-A895-FA3FE8D01260}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F789647E-96F7-43E3-A895-FA3FE8D01260}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{F789647E-96F7-43E3-A895-FA3FE8D01260}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F789647E-96F7-43E3-A895-FA3FE8D01260}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F789647E-96F7-43E3-A895-FA3FE8D01260}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{F789647E-96F7-43E3-A895-FA3FE8D01260}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{F789647E-96F7-43E3-A895-FA3FE8D01260}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{F789647E-96F7-43E3-A895-FA3FE8D01260}.Release|x64.Build.0 = Release|Any CPU
|
||||
{F789647E-96F7-43E3-A895-FA3FE8D01260}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F789647E-96F7-43E3-A895-FA3FE8D01260}.Release|x86.Build.0 = Release|Any CPU
|
||||
{86470440-FEE2-4120-AF5A-3762FB9C536F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{86470440-FEE2-4120-AF5A-3762FB9C536F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{86470440-FEE2-4120-AF5A-3762FB9C536F}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{86470440-FEE2-4120-AF5A-3762FB9C536F}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{86470440-FEE2-4120-AF5A-3762FB9C536F}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{86470440-FEE2-4120-AF5A-3762FB9C536F}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{86470440-FEE2-4120-AF5A-3762FB9C536F}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{86470440-FEE2-4120-AF5A-3762FB9C536F}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{86470440-FEE2-4120-AF5A-3762FB9C536F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{86470440-FEE2-4120-AF5A-3762FB9C536F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{86470440-FEE2-4120-AF5A-3762FB9C536F}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{86470440-FEE2-4120-AF5A-3762FB9C536F}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{86470440-FEE2-4120-AF5A-3762FB9C536F}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{86470440-FEE2-4120-AF5A-3762FB9C536F}.Release|x64.Build.0 = Release|Any CPU
|
||||
{86470440-FEE2-4120-AF5A-3762FB9C536F}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{86470440-FEE2-4120-AF5A-3762FB9C536F}.Release|x86.Build.0 = Release|Any CPU
|
||||
{EB133B78-DEFF-416A-8F0C-89E54D766576}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EB133B78-DEFF-416A-8F0C-89E54D766576}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EB133B78-DEFF-416A-8F0C-89E54D766576}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{EB133B78-DEFF-416A-8F0C-89E54D766576}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{EB133B78-DEFF-416A-8F0C-89E54D766576}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{EB133B78-DEFF-416A-8F0C-89E54D766576}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{EB133B78-DEFF-416A-8F0C-89E54D766576}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{EB133B78-DEFF-416A-8F0C-89E54D766576}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{EB133B78-DEFF-416A-8F0C-89E54D766576}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EB133B78-DEFF-416A-8F0C-89E54D766576}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EB133B78-DEFF-416A-8F0C-89E54D766576}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{EB133B78-DEFF-416A-8F0C-89E54D766576}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{EB133B78-DEFF-416A-8F0C-89E54D766576}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{EB133B78-DEFF-416A-8F0C-89E54D766576}.Release|x64.Build.0 = Release|Any CPU
|
||||
{EB133B78-DEFF-416A-8F0C-89E54D766576}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{EB133B78-DEFF-416A-8F0C-89E54D766576}.Release|x86.Build.0 = Release|Any CPU
|
||||
{63CEFDF7-5170-43B6-86F8-5C4A383A1615}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{63CEFDF7-5170-43B6-86F8-5C4A383A1615}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{63CEFDF7-5170-43B6-86F8-5C4A383A1615}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{63CEFDF7-5170-43B6-86F8-5C4A383A1615}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{63CEFDF7-5170-43B6-86F8-5C4A383A1615}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{63CEFDF7-5170-43B6-86F8-5C4A383A1615}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{63CEFDF7-5170-43B6-86F8-5C4A383A1615}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{63CEFDF7-5170-43B6-86F8-5C4A383A1615}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{63CEFDF7-5170-43B6-86F8-5C4A383A1615}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{63CEFDF7-5170-43B6-86F8-5C4A383A1615}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{63CEFDF7-5170-43B6-86F8-5C4A383A1615}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{63CEFDF7-5170-43B6-86F8-5C4A383A1615}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{63CEFDF7-5170-43B6-86F8-5C4A383A1615}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{63CEFDF7-5170-43B6-86F8-5C4A383A1615}.Release|x64.Build.0 = Release|Any CPU
|
||||
{63CEFDF7-5170-43B6-86F8-5C4A383A1615}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{63CEFDF7-5170-43B6-86F8-5C4A383A1615}.Release|x86.Build.0 = Release|Any CPU
|
||||
{226F3575-B683-446D-A2F0-181291DC8787}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{226F3575-B683-446D-A2F0-181291DC8787}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{226F3575-B683-446D-A2F0-181291DC8787}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{226F3575-B683-446D-A2F0-181291DC8787}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{226F3575-B683-446D-A2F0-181291DC8787}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{226F3575-B683-446D-A2F0-181291DC8787}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{226F3575-B683-446D-A2F0-181291DC8787}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{226F3575-B683-446D-A2F0-181291DC8787}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{226F3575-B683-446D-A2F0-181291DC8787}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{226F3575-B683-446D-A2F0-181291DC8787}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{226F3575-B683-446D-A2F0-181291DC8787}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{226F3575-B683-446D-A2F0-181291DC8787}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{226F3575-B683-446D-A2F0-181291DC8787}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{226F3575-B683-446D-A2F0-181291DC8787}.Release|x64.Build.0 = Release|Any CPU
|
||||
{226F3575-B683-446D-A2F0-181291DC8787}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{226F3575-B683-446D-A2F0-181291DC8787}.Release|x86.Build.0 = Release|Any CPU
|
||||
{9949326E-9261-4F95-89B1-151F60498951}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9949326E-9261-4F95-89B1-151F60498951}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9949326E-9261-4F95-89B1-151F60498951}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{9949326E-9261-4F95-89B1-151F60498951}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{9949326E-9261-4F95-89B1-151F60498951}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{9949326E-9261-4F95-89B1-151F60498951}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{9949326E-9261-4F95-89B1-151F60498951}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{9949326E-9261-4F95-89B1-151F60498951}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{9949326E-9261-4F95-89B1-151F60498951}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9949326E-9261-4F95-89B1-151F60498951}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9949326E-9261-4F95-89B1-151F60498951}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{9949326E-9261-4F95-89B1-151F60498951}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{9949326E-9261-4F95-89B1-151F60498951}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{9949326E-9261-4F95-89B1-151F60498951}.Release|x64.Build.0 = Release|Any CPU
|
||||
{9949326E-9261-4F95-89B1-151F60498951}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{9949326E-9261-4F95-89B1-151F60498951}.Release|x86.Build.0 = Release|Any CPU
|
||||
{AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Debug|Any CPU.ActiveCfg = Debug|ARM
|
||||
{A204A102-C745-4D65-AEC8-7B96FAEDEF2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A204A102-C745-4D65-AEC8-7B96FAEDEF2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A204A102-C745-4D65-AEC8-7B96FAEDEF2D}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{A204A102-C745-4D65-AEC8-7B96FAEDEF2D}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{A204A102-C745-4D65-AEC8-7B96FAEDEF2D}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{A204A102-C745-4D65-AEC8-7B96FAEDEF2D}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{A204A102-C745-4D65-AEC8-7B96FAEDEF2D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{A204A102-C745-4D65-AEC8-7B96FAEDEF2D}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{A204A102-C745-4D65-AEC8-7B96FAEDEF2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A204A102-C745-4D65-AEC8-7B96FAEDEF2D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A204A102-C745-4D65-AEC8-7B96FAEDEF2D}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{A204A102-C745-4D65-AEC8-7B96FAEDEF2D}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{A204A102-C745-4D65-AEC8-7B96FAEDEF2D}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{A204A102-C745-4D65-AEC8-7B96FAEDEF2D}.Release|x64.Build.0 = Release|Any CPU
|
||||
{A204A102-C745-4D65-AEC8-7B96FAEDEF2D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{A204A102-C745-4D65-AEC8-7B96FAEDEF2D}.Release|x86.Build.0 = Release|Any CPU
|
||||
{951BC5D2-D653-42D9-9A91-21DC50DE0182}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{951BC5D2-D653-42D9-9A91-21DC50DE0182}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{951BC5D2-D653-42D9-9A91-21DC50DE0182}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{951BC5D2-D653-42D9-9A91-21DC50DE0182}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{951BC5D2-D653-42D9-9A91-21DC50DE0182}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{951BC5D2-D653-42D9-9A91-21DC50DE0182}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{951BC5D2-D653-42D9-9A91-21DC50DE0182}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{951BC5D2-D653-42D9-9A91-21DC50DE0182}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{951BC5D2-D653-42D9-9A91-21DC50DE0182}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{951BC5D2-D653-42D9-9A91-21DC50DE0182}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{951BC5D2-D653-42D9-9A91-21DC50DE0182}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{951BC5D2-D653-42D9-9A91-21DC50DE0182}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{951BC5D2-D653-42D9-9A91-21DC50DE0182}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{951BC5D2-D653-42D9-9A91-21DC50DE0182}.Release|x64.Build.0 = Release|Any CPU
|
||||
{951BC5D2-D653-42D9-9A91-21DC50DE0182}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{951BC5D2-D653-42D9-9A91-21DC50DE0182}.Release|x86.Build.0 = Release|Any CPU
|
||||
{F92DA93D-75DB-4308-A5F9-6B4C3908A675}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F92DA93D-75DB-4308-A5F9-6B4C3908A675}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F92DA93D-75DB-4308-A5F9-6B4C3908A675}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{F92DA93D-75DB-4308-A5F9-6B4C3908A675}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{F92DA93D-75DB-4308-A5F9-6B4C3908A675}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{F92DA93D-75DB-4308-A5F9-6B4C3908A675}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{F92DA93D-75DB-4308-A5F9-6B4C3908A675}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F92DA93D-75DB-4308-A5F9-6B4C3908A675}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{F92DA93D-75DB-4308-A5F9-6B4C3908A675}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F92DA93D-75DB-4308-A5F9-6B4C3908A675}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F92DA93D-75DB-4308-A5F9-6B4C3908A675}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{F92DA93D-75DB-4308-A5F9-6B4C3908A675}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{F92DA93D-75DB-4308-A5F9-6B4C3908A675}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{F92DA93D-75DB-4308-A5F9-6B4C3908A675}.Release|x64.Build.0 = Release|Any CPU
|
||||
{F92DA93D-75DB-4308-A5F9-6B4C3908A675}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F92DA93D-75DB-4308-A5F9-6B4C3908A675}.Release|x86.Build.0 = Release|Any CPU
|
||||
{AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Debug|Any CPU.Build.0 = Debug|x64
|
||||
{AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Debug|Any CPU.Deploy.0 = Debug|x64
|
||||
{AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||
|
|
@ -189,50 +103,48 @@ Global
|
|||
{AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Release|x86.ActiveCfg = Release|x86
|
||||
{AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Release|x86.Build.0 = Release|x86
|
||||
{AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Release|x86.Deploy.0 = Release|x86
|
||||
{85AACDB7-959D-406D-A8DF-2F1E013F8F40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{85AACDB7-959D-406D-A8DF-2F1E013F8F40}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{85AACDB7-959D-406D-A8DF-2F1E013F8F40}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{85AACDB7-959D-406D-A8DF-2F1E013F8F40}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{85AACDB7-959D-406D-A8DF-2F1E013F8F40}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{85AACDB7-959D-406D-A8DF-2F1E013F8F40}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{85AACDB7-959D-406D-A8DF-2F1E013F8F40}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{85AACDB7-959D-406D-A8DF-2F1E013F8F40}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{85AACDB7-959D-406D-A8DF-2F1E013F8F40}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{85AACDB7-959D-406D-A8DF-2F1E013F8F40}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{85AACDB7-959D-406D-A8DF-2F1E013F8F40}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{85AACDB7-959D-406D-A8DF-2F1E013F8F40}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{85AACDB7-959D-406D-A8DF-2F1E013F8F40}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{85AACDB7-959D-406D-A8DF-2F1E013F8F40}.Release|x64.Build.0 = Release|Any CPU
|
||||
{85AACDB7-959D-406D-A8DF-2F1E013F8F40}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{85AACDB7-959D-406D-A8DF-2F1E013F8F40}.Release|x86.Build.0 = Release|Any CPU
|
||||
{7FB616E1-E0D4-48FA-8AFD-60E73FCF32E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7FB616E1-E0D4-48FA-8AFD-60E73FCF32E4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7FB616E1-E0D4-48FA-8AFD-60E73FCF32E4}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{7FB616E1-E0D4-48FA-8AFD-60E73FCF32E4}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{7FB616E1-E0D4-48FA-8AFD-60E73FCF32E4}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{7FB616E1-E0D4-48FA-8AFD-60E73FCF32E4}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{7FB616E1-E0D4-48FA-8AFD-60E73FCF32E4}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{7FB616E1-E0D4-48FA-8AFD-60E73FCF32E4}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{7FB616E1-E0D4-48FA-8AFD-60E73FCF32E4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7FB616E1-E0D4-48FA-8AFD-60E73FCF32E4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7FB616E1-E0D4-48FA-8AFD-60E73FCF32E4}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{7FB616E1-E0D4-48FA-8AFD-60E73FCF32E4}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{7FB616E1-E0D4-48FA-8AFD-60E73FCF32E4}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{7FB616E1-E0D4-48FA-8AFD-60E73FCF32E4}.Release|x64.Build.0 = Release|Any CPU
|
||||
{7FB616E1-E0D4-48FA-8AFD-60E73FCF32E4}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{7FB616E1-E0D4-48FA-8AFD-60E73FCF32E4}.Release|x86.Build.0 = Release|Any CPU
|
||||
{AD1CB53E-7AA4-4EC0-B901-B4E0E2665133}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AD1CB53E-7AA4-4EC0-B901-B4E0E2665133}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AD1CB53E-7AA4-4EC0-B901-B4E0E2665133}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{AD1CB53E-7AA4-4EC0-B901-B4E0E2665133}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{AD1CB53E-7AA4-4EC0-B901-B4E0E2665133}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{AD1CB53E-7AA4-4EC0-B901-B4E0E2665133}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{AD1CB53E-7AA4-4EC0-B901-B4E0E2665133}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{AD1CB53E-7AA4-4EC0-B901-B4E0E2665133}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{AD1CB53E-7AA4-4EC0-B901-B4E0E2665133}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AD1CB53E-7AA4-4EC0-B901-B4E0E2665133}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AD1CB53E-7AA4-4EC0-B901-B4E0E2665133}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{AD1CB53E-7AA4-4EC0-B901-B4E0E2665133}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{AD1CB53E-7AA4-4EC0-B901-B4E0E2665133}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{AD1CB53E-7AA4-4EC0-B901-B4E0E2665133}.Release|x64.Build.0 = Release|Any CPU
|
||||
{AD1CB53E-7AA4-4EC0-B901-B4E0E2665133}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{AD1CB53E-7AA4-4EC0-B901-B4E0E2665133}.Release|x86.Build.0 = Release|Any CPU
|
||||
{3FF37D40-F770-45B2-95DD-7A84093E1425}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3FF37D40-F770-45B2-95DD-7A84093E1425}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3FF37D40-F770-45B2-95DD-7A84093E1425}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{3FF37D40-F770-45B2-95DD-7A84093E1425}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{3FF37D40-F770-45B2-95DD-7A84093E1425}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{3FF37D40-F770-45B2-95DD-7A84093E1425}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{3FF37D40-F770-45B2-95DD-7A84093E1425}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{3FF37D40-F770-45B2-95DD-7A84093E1425}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{3FF37D40-F770-45B2-95DD-7A84093E1425}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3FF37D40-F770-45B2-95DD-7A84093E1425}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3FF37D40-F770-45B2-95DD-7A84093E1425}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{3FF37D40-F770-45B2-95DD-7A84093E1425}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{3FF37D40-F770-45B2-95DD-7A84093E1425}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{3FF37D40-F770-45B2-95DD-7A84093E1425}.Release|x64.Build.0 = Release|Any CPU
|
||||
{3FF37D40-F770-45B2-95DD-7A84093E1425}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{3FF37D40-F770-45B2-95DD-7A84093E1425}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{C7BF2B18-CC74-430B-BCB2-600304EFA3D8} = {AE8A7E02-0F7D-41B0-AB23-15394150ED17}
|
||||
{EF44F661-B98A-4676-927F-85D138F82300} = {AE8A7E02-0F7D-41B0-AB23-15394150ED17}
|
||||
{F789647E-96F7-43E3-A895-FA3FE8D01260} = {AE8A7E02-0F7D-41B0-AB23-15394150ED17}
|
||||
{86470440-FEE2-4120-AF5A-3762FB9C536F} = {AE8A7E02-0F7D-41B0-AB23-15394150ED17}
|
||||
{9949326E-9261-4F95-89B1-151F60498951} = {100879CC-8910-459E-856E-253D629E45DE}
|
||||
{AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1} = {100879CC-8910-459E-856E-253D629E45DE}
|
||||
{85AACDB7-959D-406D-A8DF-2F1E013F8F40} = {100879CC-8910-459E-856E-253D629E45DE}
|
||||
{7FB616E1-E0D4-48FA-8AFD-60E73FCF32E4} = {100879CC-8910-459E-856E-253D629E45DE}
|
||||
{A204A102-C745-4D65-AEC8-7B96FAEDEF2D} = {52AECE49-F314-4F76-98F2-FA800F07824B}
|
||||
{951BC5D2-D653-42D9-9A91-21DC50DE0182} = {52AECE49-F314-4F76-98F2-FA800F07824B}
|
||||
{F92DA93D-75DB-4308-A5F9-6B4C3908A675} = {8F2103C2-78AF-4810-8FB9-67572F50C8FC}
|
||||
{AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1} = {8F2103C2-78AF-4810-8FB9-67572F50C8FC}
|
||||
{AD1CB53E-7AA4-4EC0-B901-B4E0E2665133} = {6A596588-F93F-47CC-BE5D-58C3B34ADDEB}
|
||||
{3FF37D40-F770-45B2-95DD-7A84093E1425} = {6A596588-F93F-47CC-BE5D-58C3B34ADDEB}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -1,179 +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;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Xml;
|
||||
#if NETFX_CORE
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
#else
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Displays Bing Maps tiles. The static ApiKey property must be set to a Bing Maps API Key.
|
||||
/// Tile image URLs and min/max zoom levels are retrieved from the Imagery Metadata Service
|
||||
/// (see http://msdn.microsoft.com/en-us/library/ff701716.aspx).
|
||||
/// </summary>
|
||||
public class BingMapsTileLayer : MapTileLayer
|
||||
{
|
||||
public enum MapMode
|
||||
{
|
||||
Road, Aerial, AerialWithLabels
|
||||
}
|
||||
|
||||
public BingMapsTileLayer()
|
||||
: this(new TileImageLoader())
|
||||
{
|
||||
}
|
||||
|
||||
public BingMapsTileLayer(ITileImageLoader tileImageLoader)
|
||||
: base(tileImageLoader)
|
||||
{
|
||||
MinZoomLevel = 1;
|
||||
MaxZoomLevel = 21;
|
||||
Loaded += OnLoaded;
|
||||
}
|
||||
|
||||
public static string ApiKey { get; set; }
|
||||
|
||||
public MapMode Mode { get; set; }
|
||||
public string Culture { get; set; }
|
||||
public ImageSource LogoImage { get; set; }
|
||||
|
||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Loaded -= OnLoaded;
|
||||
|
||||
if (string.IsNullOrEmpty(ApiKey))
|
||||
{
|
||||
Debug.WriteLine("BingMapsTileLayer requires a Bing Maps API Key");
|
||||
}
|
||||
else
|
||||
{
|
||||
var uri = string.Format("http://dev.virtualearth.net/REST/V1/Imagery/Metadata/{0}?output=xml&key={1}", Mode, ApiKey);
|
||||
var request = WebRequest.CreateHttp(uri);
|
||||
|
||||
request.BeginGetResponse(HandleImageryMetadataResponse, request);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleImageryMetadataResponse(IAsyncResult asyncResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
var request = (HttpWebRequest)asyncResult.AsyncState;
|
||||
|
||||
using (var response = request.EndGetResponse(asyncResult))
|
||||
using (var xmlReader = XmlReader.Create(response.GetResponseStream()))
|
||||
{
|
||||
ReadImageryMetadataResponse(xmlReader);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadImageryMetadataResponse(XmlReader xmlReader)
|
||||
{
|
||||
string logoUri = null;
|
||||
string imageUrl = null;
|
||||
string[] imageUrlSubdomains = null;
|
||||
int? zoomMin = null;
|
||||
int? zoomMax = null;
|
||||
|
||||
do
|
||||
{
|
||||
if (xmlReader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
switch (xmlReader.Name)
|
||||
{
|
||||
case "BrandLogoUri":
|
||||
logoUri = xmlReader.ReadElementContentAsString();
|
||||
break;
|
||||
case "ImageUrl":
|
||||
imageUrl = xmlReader.ReadElementContentAsString();
|
||||
break;
|
||||
case "ImageUrlSubdomains":
|
||||
imageUrlSubdomains = ReadStrings(xmlReader.ReadSubtree());
|
||||
break;
|
||||
case "ZoomMin":
|
||||
zoomMin = xmlReader.ReadElementContentAsInt();
|
||||
break;
|
||||
case "ZoomMax":
|
||||
zoomMax = xmlReader.ReadElementContentAsInt();
|
||||
break;
|
||||
default:
|
||||
xmlReader.Read();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlReader.Read();
|
||||
}
|
||||
}
|
||||
while (xmlReader.NodeType != XmlNodeType.None);
|
||||
|
||||
if (!string.IsNullOrEmpty(imageUrl) && imageUrlSubdomains != null && imageUrlSubdomains.Length > 0)
|
||||
{
|
||||
var op = Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(Culture))
|
||||
{
|
||||
Culture = CultureInfo.CurrentUICulture.Name;
|
||||
}
|
||||
|
||||
TileSource = new BingMapsTileSource(imageUrl.Replace("{culture}", Culture), imageUrlSubdomains);
|
||||
|
||||
if (zoomMin.HasValue && zoomMin.Value > MinZoomLevel)
|
||||
{
|
||||
MinZoomLevel = zoomMin.Value;
|
||||
}
|
||||
|
||||
if (zoomMax.HasValue && zoomMax.Value < MaxZoomLevel)
|
||||
{
|
||||
MaxZoomLevel = zoomMax.Value;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(logoUri))
|
||||
{
|
||||
LogoImage = new BitmapImage(new Uri(logoUri));
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private static string[] ReadStrings(XmlReader xmlReader)
|
||||
{
|
||||
var strings = new List<string>();
|
||||
|
||||
do
|
||||
{
|
||||
if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "string")
|
||||
{
|
||||
strings.Add(xmlReader.ReadElementContentAsString());
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlReader.Read();
|
||||
}
|
||||
}
|
||||
while (xmlReader.NodeType != XmlNodeType.None);
|
||||
|
||||
return strings.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,58 +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;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates frozen BitmapSources from Stream, file or Uri.
|
||||
/// </summary>
|
||||
public static class BitmapSourceHelper
|
||||
{
|
||||
public static BitmapSource FromStream(Stream stream)
|
||||
{
|
||||
return BitmapFrame.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
|
||||
}
|
||||
|
||||
public static BitmapSource FromFile(string path)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
using (var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
return FromStream(fileStream);
|
||||
}
|
||||
}
|
||||
|
||||
public static BitmapSource FromUri(Uri uri)
|
||||
{
|
||||
if (!uri.IsAbsoluteUri)
|
||||
{
|
||||
return FromFile(uri.OriginalString);
|
||||
}
|
||||
|
||||
if (uri.Scheme == "file")
|
||||
{
|
||||
return FromFile(uri.LocalPath);
|
||||
}
|
||||
|
||||
using (var response = WebRequest.Create(uri).GetResponse())
|
||||
using (var responseStream = response.GetResponseStream())
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
responseStream.CopyTo(memoryStream);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
return FromStream(memoryStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +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;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
public class BoundingBoxConverter : TypeConverter
|
||||
{
|
||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
||||
{
|
||||
return sourceType == typeof(string);
|
||||
}
|
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||
{
|
||||
return BoundingBox.Parse((string)value);
|
||||
}
|
||||
}
|
||||
|
||||
[TypeConverter(typeof(BoundingBoxConverter))]
|
||||
#if !SILVERLIGHT
|
||||
[Serializable]
|
||||
#endif
|
||||
public partial class BoundingBox
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +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.Media.Animation;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
internal static class Extensions
|
||||
{
|
||||
public static void BeginAnimation(this DependencyObject obj, DependencyProperty property, Timeline animation)
|
||||
{
|
||||
Storyboard.SetTargetProperty(animation, new PropertyPath(property));
|
||||
Storyboard.SetTarget(animation, obj);
|
||||
var storyboard = new Storyboard();
|
||||
storyboard.Children.Add(animation);
|
||||
storyboard.Begin();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
||||
#if NETFX_CORE
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
#else
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides the image of a map tile.
|
||||
/// ImageTileSource bypasses image downloading and optional caching in TileImageLoader.
|
||||
/// By overriding the LoadImage method, an application can provide tile images from an arbitrary source.
|
||||
/// </summary>
|
||||
public class ImageTileSource : TileSource
|
||||
{
|
||||
public virtual ImageSource LoadImage(int x, int y, int zoomLevel)
|
||||
{
|
||||
var uri = GetUri(x, y, zoomLevel);
|
||||
|
||||
return uri != null ? new BitmapImage(uri) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +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.Media;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides the image of a map tile.
|
||||
/// ImageTileSource bypasses image downloading and optional caching in TileImageLoader.
|
||||
/// By overriding the LoadImage method, an application can provide tile images from an arbitrary source.
|
||||
/// LoadImage will be called from a non-UI thread and must therefore return a frozen ImageSource.
|
||||
/// </summary>
|
||||
public class ImageTileSource : TileSource
|
||||
{
|
||||
public virtual ImageSource LoadImage(int x, int y, int zoomLevel)
|
||||
{
|
||||
var uri = GetUri(x, y, zoomLevel);
|
||||
|
||||
return uri != null ? BitmapSourceHelper.FromUri(uri) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
public class LocationCollectionConverter : TypeConverter
|
||||
{
|
||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
||||
{
|
||||
return sourceType == typeof(string);
|
||||
}
|
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||
{
|
||||
return LocationCollection.Parse((string)value);
|
||||
}
|
||||
}
|
||||
|
||||
[TypeConverter(typeof(LocationCollectionConverter))]
|
||||
public partial class LocationCollection
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +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;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
public class LocationConverter : TypeConverter
|
||||
{
|
||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
||||
{
|
||||
return sourceType == typeof(string);
|
||||
}
|
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||
{
|
||||
return Location.Parse((string)value);
|
||||
}
|
||||
}
|
||||
|
||||
[TypeConverter(typeof(LocationConverter))]
|
||||
#if !SILVERLIGHT
|
||||
[Serializable]
|
||||
#endif
|
||||
public partial class Location
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,70 +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.Input;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// MapBase with default input event handling.
|
||||
/// </summary>
|
||||
public class Map : MapBase
|
||||
{
|
||||
public static readonly DependencyProperty MouseWheelZoomDeltaProperty = DependencyProperty.Register(
|
||||
nameof(MouseWheelZoomDelta), typeof(double), typeof(Map), new PropertyMetadata(1d));
|
||||
|
||||
private Point? mousePosition;
|
||||
|
||||
public Map()
|
||||
{
|
||||
MouseWheel += OnMouseWheel;
|
||||
MouseLeftButtonDown += OnMouseLeftButtonDown;
|
||||
MouseLeftButtonUp += OnMouseLeftButtonUp;
|
||||
MouseMove += OnMouseMove;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the amount by which the ZoomLevel property changes during a MouseWheel event.
|
||||
/// </summary>
|
||||
public double MouseWheelZoomDelta
|
||||
{
|
||||
get { return (double)GetValue(MouseWheelZoomDeltaProperty); }
|
||||
set { SetValue(MouseWheelZoomDeltaProperty, value); }
|
||||
}
|
||||
|
||||
private void OnMouseWheel(object sender, MouseWheelEventArgs e)
|
||||
{
|
||||
var zoomChange = MouseWheelZoomDelta * e.Delta / 120d;
|
||||
ZoomMap(e.GetPosition(this), TargetZoomLevel + zoomChange);
|
||||
}
|
||||
|
||||
private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (CaptureMouse())
|
||||
{
|
||||
mousePosition = e.GetPosition(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (mousePosition.HasValue)
|
||||
{
|
||||
mousePosition = null;
|
||||
ReleaseMouseCapture();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (mousePosition.HasValue)
|
||||
{
|
||||
var position = e.GetPosition(this);
|
||||
TranslateMap(new Point(position.X - mousePosition.Value.X, position.Y - mousePosition.Value.Y));
|
||||
mousePosition = position;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,156 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{EB133B78-DEFF-416A-8F0C-89E54D766576}</ProjectGuid>
|
||||
<ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MapControl</RootNamespace>
|
||||
<AssemblyName>MapControl.Silverlight</AssemblyName>
|
||||
<TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
|
||||
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
|
||||
<SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
|
||||
<SilverlightApplication>false</SilverlightApplication>
|
||||
<ValidateXaml>true</ValidateXaml>
|
||||
<ThrowErrorsInValidation>true</ThrowErrorsInValidation>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<!-- This property group is only here to support building this project using the
|
||||
MSBuild 3.5 toolset. In order to work correctly with this older toolset, it needs
|
||||
to set the TargetFrameworkVersion to v3.5 -->
|
||||
<PropertyGroup Condition="'$(MSBuildToolsVersion)' == '3.5'">
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;SILVERLIGHT</DefineConstants>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<NoConfig>true</NoConfig>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;SILVERLIGHT</DefineConstants>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<NoConfig>true</NoConfig>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AssemblyOriginatorKeyFile>..\MapControl.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="System.Windows" />
|
||||
<Reference Include="system" />
|
||||
<Reference Include="System.Core">
|
||||
<HintPath>$(TargetFrameworkDirectory)System.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AzimuthalEquidistantProjection.cs" />
|
||||
<Compile Include="AzimuthalProjection.cs" />
|
||||
<Compile Include="BingMapsTileLayer.cs" />
|
||||
<Compile Include="BingMapsTileSource.cs" />
|
||||
<Compile Include="BoundingBox.cs" />
|
||||
<Compile Include="BoundingBoxConverter.cs" />
|
||||
<Compile Include="CenteredBoundingBox.cs" />
|
||||
<Compile Include="EquirectangularProjection.cs" />
|
||||
<Compile Include="Extensions.Silverlight.cs" />
|
||||
<Compile Include="GnomonicProjection.cs" />
|
||||
<Compile Include="HyperlinkText.cs" />
|
||||
<Compile Include="ImageTileSource.Silverlight.WinRT.cs" />
|
||||
<Compile Include="Location.cs" />
|
||||
<Compile Include="LocationCollection.cs" />
|
||||
<Compile Include="LocationCollectionConverter.cs" />
|
||||
<Compile Include="LocationConverter.cs" />
|
||||
<Compile Include="Map.Silverlight.cs" />
|
||||
<Compile Include="MapBase.cs" />
|
||||
<Compile Include="MapBase.Silverlight.WinRT.cs" />
|
||||
<Compile Include="MapImageLayer.cs" />
|
||||
<Compile Include="MapImageLayer.Silverlight.WinRT.cs" />
|
||||
<Compile Include="MapGraticule.cs" />
|
||||
<Compile Include="MapGraticule.Silverlight.WinRT.cs" />
|
||||
<Compile Include="MapItem.Silverlight.WinRT.cs" />
|
||||
<Compile Include="MapItemsControl.Silverlight.WinRT.cs" />
|
||||
<Compile Include="MapOverlay.cs" />
|
||||
<Compile Include="MapOverlay.Silverlight.WinRT.cs" />
|
||||
<Compile Include="MapPanel.cs" />
|
||||
<Compile Include="MapPanel.Silverlight.WinRT.cs" />
|
||||
<Compile Include="MapPath.cs" />
|
||||
<Compile Include="MapPath.Silverlight.WinRT.cs" />
|
||||
<Compile Include="MapPolyline.cs" />
|
||||
<Compile Include="MapPolyline.Silverlight.WinRT.cs" />
|
||||
<Compile Include="MapProjection.cs" />
|
||||
<Compile Include="MapTileLayer.cs" />
|
||||
<Compile Include="MatrixEx.Silverlight.WinRT.cs" />
|
||||
<Compile Include="OrthographicProjection.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Pushpin.Silverlight.WinRT.cs" />
|
||||
<Compile Include="StereographicProjection.cs" />
|
||||
<Compile Include="Tile.cs" />
|
||||
<Compile Include="Tile.Silverlight.WinRT.cs" />
|
||||
<Compile Include="TileGrid.cs" />
|
||||
<Compile Include="TileImageLoader.Silverlight.cs" />
|
||||
<Compile Include="MapTileLayer.Silverlight.WinRT.cs" />
|
||||
<Compile Include="TileSource.cs" />
|
||||
<Compile Include="TileSourceConverter.cs" />
|
||||
<Compile Include="ViewportChangedEventArgs.cs" />
|
||||
<Compile Include="WebMercatorProjection.cs" />
|
||||
<Compile Include="WmsImageLayer.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="Themes\Generic.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\MapControl.snk">
|
||||
<Link>MapControl.snk</Link>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
|
||||
<SilverlightProjectProperties />
|
||||
</FlavorProperties>
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
|
||||
<SilverlightProjectProperties>
|
||||
<StartPageUrl>
|
||||
</StartPageUrl>
|
||||
<StartAction>DynamicPage</StartAction>
|
||||
<AspNetDebugging>True</AspNetDebugging>
|
||||
<NativeDebugging>False</NativeDebugging>
|
||||
<SQLDebugging>False</SQLDebugging>
|
||||
<ExternalProgram>
|
||||
</ExternalProgram>
|
||||
<StartExternalURL>
|
||||
</StartExternalURL>
|
||||
<StartCmdLineArguments>
|
||||
</StartCmdLineArguments>
|
||||
<StartWorkingDirectory>
|
||||
</StartWorkingDirectory>
|
||||
<ShowWebRefOnDebugPrompt>True</ShowWebRefOnDebugPrompt>
|
||||
<OutOfBrowserProjectToDebug>
|
||||
</OutOfBrowserProjectToDebug>
|
||||
<ShowRiaSvcsOnDebugPrompt>True</ShowRiaSvcsOnDebugPrompt>
|
||||
</SilverlightProjectProperties>
|
||||
</FlavorProperties>
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{226F3575-B683-446D-A2F0-181291DC8787}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MapControl</RootNamespace>
|
||||
<AssemblyName>MapControl.WPF</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AssemblyOriginatorKeyFile>..\MapControl.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Runtime.Caching" />
|
||||
<Reference Include="System.Xaml" />
|
||||
<Reference Include="System.XML" />
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AzimuthalEquidistantProjection.cs" />
|
||||
<Compile Include="AzimuthalProjection.cs" />
|
||||
<Compile Include="BingMapsTileLayer.cs" />
|
||||
<Compile Include="BingMapsTileSource.cs" />
|
||||
<Compile Include="BoundingBox.cs" />
|
||||
<Compile Include="BoundingBoxConverter.cs" />
|
||||
<Compile Include="CenteredBoundingBox.cs" />
|
||||
<Compile Include="EquirectangularProjection.cs" />
|
||||
<Compile Include="GnomonicProjection.cs" />
|
||||
<Compile Include="BitmapSourceHelper.cs" />
|
||||
<Compile Include="HyperlinkText.cs" />
|
||||
<Compile Include="ImageTileSource.WPF.cs" />
|
||||
<Compile Include="Location.cs" />
|
||||
<Compile Include="LocationCollection.cs" />
|
||||
<Compile Include="LocationCollectionConverter.cs" />
|
||||
<Compile Include="LocationConverter.cs" />
|
||||
<Compile Include="Map.WPF.cs" />
|
||||
<Compile Include="MapBase.cs" />
|
||||
<Compile Include="MapBase.WPF.cs" />
|
||||
<Compile Include="MapImageLayer.cs" />
|
||||
<Compile Include="MapImageLayer.WPF.cs" />
|
||||
<Compile Include="MapGraticule.cs" />
|
||||
<Compile Include="MapGraticule.WPF.cs" />
|
||||
<Compile Include="MapItem.WPF.cs" />
|
||||
<Compile Include="MapItemsControl.WPF.cs" />
|
||||
<Compile Include="MapOverlay.cs" />
|
||||
<Compile Include="MapOverlay.WPF.cs" />
|
||||
<Compile Include="MapPanel.cs" />
|
||||
<Compile Include="MapPanel.WPF.cs" />
|
||||
<Compile Include="MapPath.cs" />
|
||||
<Compile Include="MapPath.WPF.cs" />
|
||||
<Compile Include="MapPolyline.cs" />
|
||||
<Compile Include="MapPolyline.WPF.cs" />
|
||||
<Compile Include="MapScale.cs" />
|
||||
<Compile Include="MapProjection.cs" />
|
||||
<Compile Include="MatrixEx.WPF.cs" />
|
||||
<Compile Include="OrthographicProjection.cs" />
|
||||
<Compile Include="StereographicProjection.cs" />
|
||||
<Compile Include="WebMercatorProjection.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Pushpin.WPF.cs" />
|
||||
<Compile Include="Tile.cs" />
|
||||
<Compile Include="Tile.WPF.cs" />
|
||||
<Compile Include="TileGrid.cs" />
|
||||
<Compile Include="TileImageLoader.WPF.cs" />
|
||||
<Compile Include="MapTileLayer.cs" />
|
||||
<Compile Include="MapTileLayer.WPF.cs" />
|
||||
<Compile Include="TileSource.cs" />
|
||||
<Compile Include="TileSourceConverter.cs" />
|
||||
<Compile Include="ViewportChangedEventArgs.cs" />
|
||||
<Compile Include="WmsImageLayer.cs" />
|
||||
<Compile Include="WmsLayers.WPF.WinRT.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="Themes\Generic.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\MapControl.snk">
|
||||
<Link>MapControl.snk</Link>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
|
|
@ -1,69 +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;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
public partial class MapImageLayer
|
||||
{
|
||||
protected void UpdateImage(Uri uri)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
BitmapSource image = null;
|
||||
|
||||
try
|
||||
{
|
||||
image = BitmapSourceHelper.FromUri(uri);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("{0}: {1}", uri, ex.Message);
|
||||
}
|
||||
|
||||
Dispatcher.BeginInvoke(new Action(() => UpdateImage(image)));
|
||||
});
|
||||
}
|
||||
|
||||
protected void UpdateImage(BitmapSource bitmap)
|
||||
{
|
||||
SetTopImage(bitmap);
|
||||
|
||||
if (bitmap != null && !bitmap.IsFrozen && bitmap.IsDownloading)
|
||||
{
|
||||
bitmap.DownloadCompleted += BitmapDownloadCompleted;
|
||||
bitmap.DownloadFailed += BitmapDownloadFailed;
|
||||
}
|
||||
else
|
||||
{
|
||||
SwapImages();
|
||||
}
|
||||
}
|
||||
|
||||
private void BitmapDownloadCompleted(object sender, EventArgs e)
|
||||
{
|
||||
var bitmap = (BitmapSource)sender;
|
||||
bitmap.DownloadCompleted -= BitmapDownloadCompleted;
|
||||
bitmap.DownloadFailed -= BitmapDownloadFailed;
|
||||
|
||||
SwapImages();
|
||||
}
|
||||
|
||||
private void BitmapDownloadFailed(object sender, ExceptionEventArgs e)
|
||||
{
|
||||
var bitmap = (BitmapSource)sender;
|
||||
bitmap.DownloadCompleted -= BitmapDownloadCompleted;
|
||||
bitmap.DownloadFailed -= BitmapDownloadFailed;
|
||||
|
||||
((Image)Children[topImageIndex]).Source = null;
|
||||
SwapImages();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,82 +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;
|
||||
#if NETFX_CORE
|
||||
using Windows.Foundation;
|
||||
using Windows.UI.Xaml.Media;
|
||||
#else
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
internal static class MatrixEx
|
||||
{
|
||||
/// <summary>
|
||||
/// Used in MapProjection and MapTileLayer.
|
||||
/// </summary>
|
||||
public static Matrix TranslateScaleRotateTranslate(
|
||||
double translation1X, double translation1Y,
|
||||
double scaleX, double scaleY, double rotationAngle,
|
||||
double translation2X, double translation2Y)
|
||||
{
|
||||
return new Matrix(1d, 0d, 0d, 1d, -translation1X, -translation1Y)
|
||||
.Scale(scaleX, scaleY)
|
||||
.Rotate(rotationAngle)
|
||||
.Translate(translation2X, translation2Y);
|
||||
}
|
||||
|
||||
private static Matrix Translate(this Matrix matrix, double offsetX, double offsetY)
|
||||
{
|
||||
matrix.OffsetX += offsetX;
|
||||
matrix.OffsetY += offsetY;
|
||||
return matrix;
|
||||
}
|
||||
|
||||
private static Matrix Scale(this Matrix matrix, double scaleX, double scaleY)
|
||||
{
|
||||
return Multiply(matrix, new Matrix(scaleX, 0d, 0d, scaleY, 0d, 0d));
|
||||
}
|
||||
|
||||
private static Matrix Rotate(this Matrix matrix, double angle)
|
||||
{
|
||||
if (angle == 0d)
|
||||
{
|
||||
return matrix;
|
||||
}
|
||||
|
||||
angle = (angle % 360d) / 180d * Math.PI;
|
||||
var cos = Math.Cos(angle);
|
||||
var sin = Math.Sin(angle);
|
||||
|
||||
return Multiply(matrix, new Matrix(cos, sin, -sin, cos, 0d, 0d));
|
||||
}
|
||||
|
||||
private static Matrix Invert(this Matrix matrix)
|
||||
{
|
||||
var determinant = matrix.M11 * matrix.M22 - matrix.M12 * matrix.M21;
|
||||
|
||||
return new Matrix(
|
||||
matrix.M22 / determinant,
|
||||
-matrix.M12 / determinant,
|
||||
-matrix.M21 / determinant,
|
||||
matrix.M11 / determinant,
|
||||
(matrix.M21 * matrix.OffsetY - matrix.M22 * matrix.OffsetX) / determinant,
|
||||
(matrix.M12 * matrix.OffsetX - matrix.M11 * matrix.OffsetY) / determinant);
|
||||
}
|
||||
|
||||
private static Matrix Multiply(this Matrix matrix1, Matrix matrix2)
|
||||
{
|
||||
return new Matrix(
|
||||
matrix1.M11 * matrix2.M11 + matrix1.M12 * matrix2.M21,
|
||||
matrix1.M11 * matrix2.M12 + matrix1.M12 * matrix2.M22,
|
||||
matrix1.M21 * matrix2.M11 + matrix1.M22 * matrix2.M21,
|
||||
matrix1.M21 * matrix2.M12 + matrix1.M22 * matrix2.M22,
|
||||
(matrix2.M11 * matrix1.OffsetX + matrix2.M21 * matrix1.OffsetY) + matrix2.OffsetX,
|
||||
(matrix2.M12 * matrix1.OffsetX + matrix2.M22 * matrix1.OffsetY) + matrix2.OffsetY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
#if NETFX_CORE
|
||||
#if WINDOWS_UWP
|
||||
using Windows.Foundation;
|
||||
#else
|
||||
using System.Windows;
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
#if NETFX_CORE
|
||||
#if WINDOWS_UWP
|
||||
using Windows.Foundation;
|
||||
#else
|
||||
using System.Windows;
|
||||
|
|
@ -27,7 +27,7 @@ namespace MapControl
|
|||
|
||||
public override double GetViewportScale(double zoomLevel)
|
||||
{
|
||||
return base.GetViewportScale(zoomLevel) / MetersPerDegree;
|
||||
return DegreesToViewportScale(zoomLevel) / MetersPerDegree;
|
||||
}
|
||||
|
||||
public override Point GetMapScale(Location location)
|
||||
138
MapControl/Shared/BingMapsTileLayer.cs
Normal file
138
MapControl/Shared/BingMapsTileLayer.cs
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
// 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.Globalization;
|
||||
using System.Linq;
|
||||
#if WINDOWS_UWP
|
||||
using Windows.Data.Xml.Dom;
|
||||
using Windows.UI.Xaml;
|
||||
#else
|
||||
using System.Windows;
|
||||
using System.Xml;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Displays Bing Maps tiles. The static ApiKey property must be set to a Bing Maps API Key.
|
||||
/// Tile image URLs and min/max zoom levels are retrieved from the Imagery Metadata Service
|
||||
/// (see http://msdn.microsoft.com/en-us/library/ff701716.aspx).
|
||||
/// </summary>
|
||||
public class BingMapsTileLayer : MapTileLayer
|
||||
{
|
||||
public enum MapMode
|
||||
{
|
||||
Road, Aerial, AerialWithLabels
|
||||
}
|
||||
|
||||
public BingMapsTileLayer()
|
||||
: this(new TileImageLoader())
|
||||
{
|
||||
}
|
||||
|
||||
public BingMapsTileLayer(ITileImageLoader tileImageLoader)
|
||||
: base(tileImageLoader)
|
||||
{
|
||||
MinZoomLevel = 1;
|
||||
MaxZoomLevel = 21;
|
||||
Loaded += OnLoaded;
|
||||
}
|
||||
|
||||
public static string ApiKey { get; set; }
|
||||
|
||||
public MapMode Mode { get; set; }
|
||||
public string Culture { get; set; }
|
||||
public Uri LogoImageUri { get; set; }
|
||||
|
||||
private async void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Loaded -= OnLoaded;
|
||||
|
||||
if (string.IsNullOrEmpty(ApiKey))
|
||||
{
|
||||
Debug.WriteLine("BingMapsTileLayer requires a Bing Maps API Key");
|
||||
return;
|
||||
}
|
||||
|
||||
var imageryMetadataUrl = "http://dev.virtualearth.net/REST/V1/Imagery/Metadata/" + Mode;
|
||||
|
||||
try
|
||||
{
|
||||
var document = await XmlDocument.LoadFromUriAsync(new Uri(imageryMetadataUrl + "?output=xml&key=" + ApiKey));
|
||||
var imageryMetadata = document.DocumentElement.GetElementsByTagName("ImageryMetadata").OfType<XmlElement>().FirstOrDefault();
|
||||
|
||||
if (imageryMetadata != null)
|
||||
{
|
||||
ReadImageryMetadata(imageryMetadata);
|
||||
}
|
||||
|
||||
var brandLogoUri = document.DocumentElement.GetElementsByTagName("BrandLogoUri").OfType<XmlElement>().FirstOrDefault();
|
||||
|
||||
if (brandLogoUri != null)
|
||||
{
|
||||
LogoImageUri = new Uri(brandLogoUri.InnerText);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("BingMapsTileLayer: {0}: {1}", imageryMetadataUrl, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadImageryMetadata(XmlElement imageryMetadata)
|
||||
{
|
||||
string imageUrl = null;
|
||||
string[] imageUrlSubdomains = null;
|
||||
int? zoomMin = null;
|
||||
int? zoomMax = null;
|
||||
|
||||
foreach (var element in imageryMetadata.ChildNodes.OfType<XmlElement>())
|
||||
{
|
||||
switch ((string)element.LocalName)
|
||||
{
|
||||
case "ImageUrl":
|
||||
imageUrl = element.InnerText;
|
||||
break;
|
||||
case "ImageUrlSubdomains":
|
||||
imageUrlSubdomains = element.ChildNodes
|
||||
.OfType<XmlElement>()
|
||||
.Where(e => (string)e.LocalName == "string")
|
||||
.Select(e => e.InnerText)
|
||||
.ToArray();
|
||||
break;
|
||||
case "ZoomMin":
|
||||
zoomMin = int.Parse(element.InnerText);
|
||||
break;
|
||||
case "ZoomMax":
|
||||
zoomMax = int.Parse(element.InnerText);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(imageUrl) && imageUrlSubdomains != null && imageUrlSubdomains.Length > 0)
|
||||
{
|
||||
if (zoomMin.HasValue && zoomMin.Value > MinZoomLevel)
|
||||
{
|
||||
MinZoomLevel = zoomMin.Value;
|
||||
}
|
||||
|
||||
if (zoomMax.HasValue && zoomMax.Value < MaxZoomLevel)
|
||||
{
|
||||
MaxZoomLevel = zoomMax.Value;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(Culture))
|
||||
{
|
||||
Culture = CultureInfo.CurrentUICulture.Name;
|
||||
}
|
||||
|
||||
TileSource = new BingMapsTileSource(imageUrl.Replace("{culture}", Culture), imageUrlSubdomains);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ using System;
|
|||
|
||||
namespace MapControl
|
||||
{
|
||||
internal class BingMapsTileSource : TileSource
|
||||
public class BingMapsTileSource : TileSource
|
||||
{
|
||||
private readonly string[] subdomains;
|
||||
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
#if NETFX_CORE
|
||||
#if WINDOWS_UWP
|
||||
using Windows.Foundation;
|
||||
#else
|
||||
using System.Windows;
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
#if NETFX_CORE
|
||||
#if WINDOWS_UWP
|
||||
using Windows.Foundation;
|
||||
#else
|
||||
using System.Windows;
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
#if NETFX_CORE
|
||||
#if WINDOWS_UWP
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Documents;
|
||||
|
|
@ -43,9 +43,7 @@ namespace MapControl
|
|||
|
||||
var link = new Hyperlink { NavigateUri = uri };
|
||||
link.Inlines.Add(new Run { Text = match.Groups[1].Value });
|
||||
#if SILVERLIGHT
|
||||
link.TargetName = "_blank";
|
||||
#elif !NETFX_CORE
|
||||
#if !WINDOWS_UWP
|
||||
link.ToolTip = uri.ToString();
|
||||
link.RequestNavigate += (s, e) => System.Diagnostics.Process.Start(e.Uri.ToString());
|
||||
#endif
|
||||
|
|
@ -86,16 +84,7 @@ namespace MapControl
|
|||
{
|
||||
inlines = ((Paragraph)obj).Inlines;
|
||||
}
|
||||
#if NETFX_CORE || SILVERLIGHT
|
||||
else if (obj is RichTextBlock)
|
||||
{
|
||||
var paragraph = new Paragraph();
|
||||
inlines = paragraph.Inlines;
|
||||
var richTextBlock = (RichTextBlock)obj;
|
||||
richTextBlock.Blocks.Clear();
|
||||
richTextBlock.Blocks.Add(paragraph);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (inlines != null)
|
||||
{
|
||||
inlines.Clear();
|
||||
|
|
@ -39,10 +39,9 @@ namespace MapControl
|
|||
|
||||
public bool Equals(Location location)
|
||||
{
|
||||
return ReferenceEquals(this, location)
|
||||
|| (location != null
|
||||
&& location.latitude == latitude
|
||||
&& location.longitude == longitude);
|
||||
return location != null
|
||||
&& Math.Abs(location.latitude - latitude) < 1e-9
|
||||
&& Math.Abs(location.longitude - longitude) < 1e-9;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
#if NETFX_CORE
|
||||
#if WINDOWS_UWP
|
||||
using Windows.Foundation;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Media;
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
#if NETFX_CORE
|
||||
#if WINDOWS_UWP
|
||||
using Windows.UI.Xaml;
|
||||
#else
|
||||
using System.Windows;
|
||||
|
|
@ -30,7 +30,7 @@ namespace MapControl
|
|||
|
||||
private double GetLineDistance()
|
||||
{
|
||||
var minDistance = MinLineDistance * 360d / (Math.Pow(2d, ParentMap.ZoomLevel) * TileSource.TileSize);
|
||||
var minDistance = MinLineDistance / MapProjection.DegreesToViewportScale(ParentMap.ZoomLevel);
|
||||
var scale = 1d;
|
||||
|
||||
if (minDistance < 1d)
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
#if NETFX_CORE
|
||||
#if WINDOWS_UWP
|
||||
using Windows.Foundation;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
|
@ -279,7 +279,7 @@ namespace MapControl
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
Debug.WriteLine("MapImageLayer: " + ex.Message);
|
||||
}
|
||||
|
||||
if (!imageUpdated)
|
||||
|
|
@ -295,12 +295,12 @@ namespace MapControl
|
|||
/// </summary>
|
||||
protected abstract bool UpdateImage(BoundingBox boundingBox);
|
||||
|
||||
private void SetTopImage(BitmapSource bitmap)
|
||||
private void SetTopImage(BitmapSource bitmapSource)
|
||||
{
|
||||
topImageIndex = (topImageIndex + 1) % 2;
|
||||
var topImage = (Image)Children[topImageIndex];
|
||||
|
||||
topImage.Source = bitmap;
|
||||
topImage.Source = bitmapSource;
|
||||
SetBoundingBox(topImage, boundingBox?.Clone());
|
||||
}
|
||||
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
#if NETFX_CORE
|
||||
#if WINDOWS_UWP
|
||||
using Windows.UI.Text;
|
||||
using Windows.UI.Xaml.Media;
|
||||
#else
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
#if NETFX_CORE
|
||||
#if WINDOWS_UWP
|
||||
using Windows.Foundation;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
#if NETFX_CORE
|
||||
#if WINDOWS_UWP
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Media;
|
||||
#else
|
||||
|
|
@ -4,11 +4,10 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
#if NETFX_CORE
|
||||
#if WINDOWS_UWP
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Media;
|
||||
#else
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
#endif
|
||||
|
|
@ -28,18 +27,6 @@ namespace MapControl
|
|||
nameof(IsClosed), typeof(bool), typeof(MapPolyline),
|
||||
new PropertyMetadata(false, (o, e) => ((MapPolyline)o).UpdateData()));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the locations that define the polyline points.
|
||||
/// </summary>
|
||||
#if !NETFX_CORE
|
||||
[TypeConverter(typeof(LocationCollectionConverter))]
|
||||
#endif
|
||||
public IEnumerable<Location> Locations
|
||||
{
|
||||
get { return (IEnumerable<Location>)GetValue(LocationsProperty); }
|
||||
set { SetValue(LocationsProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value that indicates if the polyline is closed, i.e. is a polygon.
|
||||
/// </summary>
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
#if NETFX_CORE
|
||||
#if WINDOWS_UWP
|
||||
using Windows.Foundation;
|
||||
using Windows.UI.Xaml.Media;
|
||||
#else
|
||||
|
|
@ -15,14 +15,22 @@ using System.Windows.Media;
|
|||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a map projection between geographic coordinates and cartesian map coordinates
|
||||
/// and viewport coordinates, i.e. pixels.
|
||||
/// Defines a map projection between geographic coordinates, cartesian map coordinates and viewport coordinates.
|
||||
/// </summary>
|
||||
public abstract partial class MapProjection
|
||||
public abstract class MapProjection
|
||||
{
|
||||
public const int TileSize = 256;
|
||||
public const double Wgs84EquatorialRadius = 6378137d;
|
||||
public const double MetersPerDegree = Wgs84EquatorialRadius * Math.PI / 180d;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scaling factor from cartesian map coordinates in degrees to viewport coordinates for the specified zoom level.
|
||||
/// </summary>
|
||||
public static double DegreesToViewportScale(double zoomLevel)
|
||||
{
|
||||
return Math.Pow(2d, zoomLevel) * TileSize / 360d;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the WMS 1.3.0 CRS Identifier.
|
||||
/// </summary>
|
||||
|
|
@ -64,7 +72,7 @@ namespace MapControl
|
|||
/// </summary>
|
||||
public virtual double GetViewportScale(double zoomLevel)
|
||||
{
|
||||
return Math.Pow(2d, zoomLevel) * TileSource.TileSize / 360d;
|
||||
return DegreesToViewportScale(zoomLevel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -142,7 +150,7 @@ namespace MapControl
|
|||
var center = LocationToPoint(mapCenter);
|
||||
|
||||
ViewportTransform.Matrix = MatrixEx.TranslateScaleRotateTranslate(
|
||||
center.X, center.Y, ViewportScale, -ViewportScale, heading, viewportCenter.X, viewportCenter.Y);
|
||||
-center.X, -center.Y, ViewportScale, -ViewportScale, heading, viewportCenter.X, viewportCenter.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -5,16 +5,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
#if NETFX_CORE
|
||||
#if WINDOWS_UWP
|
||||
using Windows.Foundation;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Markup;
|
||||
using Windows.UI.Xaml.Media;
|
||||
#else
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
#endif
|
||||
|
|
@ -29,11 +27,6 @@ namespace MapControl
|
|||
/// <summary>
|
||||
/// Fills the map viewport with map tiles from a TileSource.
|
||||
/// </summary>
|
||||
#if NETFX_CORE
|
||||
[ContentProperty(Name = "TileSource")]
|
||||
#else
|
||||
[ContentProperty("TileSource")]
|
||||
#endif
|
||||
public partial class MapTileLayer : Panel, IMapLayer
|
||||
{
|
||||
/// <summary>
|
||||
|
|
@ -253,9 +246,9 @@ namespace MapControl
|
|||
{
|
||||
foreach (var tile in Tiles)
|
||||
{
|
||||
var tileSize = TileSource.TileSize << (TileGrid.ZoomLevel - tile.ZoomLevel);
|
||||
var x = tileSize * tile.X - TileSource.TileSize * TileGrid.XMin;
|
||||
var y = tileSize * tile.Y - TileSource.TileSize * TileGrid.YMin;
|
||||
var tileSize = MapProjection.TileSize << (TileGrid.ZoomLevel - tile.ZoomLevel);
|
||||
var x = tileSize * tile.X - MapProjection.TileSize * TileGrid.XMin;
|
||||
var y = tileSize * tile.Y - MapProjection.TileSize * TileGrid.YMin;
|
||||
|
||||
tile.Image.Width = tileSize;
|
||||
tile.Image.Height = tileSize;
|
||||
|
|
@ -322,8 +315,8 @@ namespace MapControl
|
|||
private TileGrid GetTileGrid()
|
||||
{
|
||||
var tileZoomLevel = Math.Max(0, (int)Math.Round(parentMap.ZoomLevel + ZoomLevelOffset));
|
||||
var tileScale = (1 << tileZoomLevel);
|
||||
var scale = tileScale / (Math.Pow(2d, parentMap.ZoomLevel) * TileSource.TileSize);
|
||||
var tileScale = (double)(1 << tileZoomLevel);
|
||||
var scale = tileScale / (Math.Pow(2d, parentMap.ZoomLevel) * MapProjection.TileSize);
|
||||
var tileCenterX = tileScale * (0.5 + parentMap.Center.Longitude / 360d);
|
||||
var tileCenterY = tileScale * (0.5 - WebMercatorProjection.LatitudeToY(parentMap.Center.Latitude) / 360d);
|
||||
var viewCenterX = parentMap.RenderSize.Width / 2d;
|
||||
|
|
@ -331,7 +324,7 @@ namespace MapControl
|
|||
|
||||
var transform = new MatrixTransform
|
||||
{
|
||||
Matrix = MatrixEx.TranslateScaleRotateTranslate(viewCenterX, viewCenterY, scale, scale, -parentMap.Heading, tileCenterX, tileCenterY)
|
||||
Matrix = MatrixEx.TranslateScaleRotateTranslate(-viewCenterX, -viewCenterY, scale, scale, -parentMap.Heading, tileCenterX, tileCenterY)
|
||||
};
|
||||
|
||||
var bounds = transform.TransformBounds(new Rect(0d, 0d, parentMap.RenderSize.Width, parentMap.RenderSize.Height));
|
||||
|
|
@ -343,17 +336,17 @@ namespace MapControl
|
|||
|
||||
private void SetRenderTransform()
|
||||
{
|
||||
var tileScale = (1 << TileGrid.ZoomLevel);
|
||||
var tileScale = (double)(1 << TileGrid.ZoomLevel);
|
||||
var scale = Math.Pow(2d, parentMap.ZoomLevel) / tileScale;
|
||||
var tileCenterX = tileScale * (0.5 + parentMap.Center.Longitude / 360d);
|
||||
var tileCenterY = tileScale * (0.5 - WebMercatorProjection.LatitudeToY(parentMap.Center.Latitude) / 360d);
|
||||
var tileOriginX = TileSource.TileSize * (tileCenterX - TileGrid.XMin);
|
||||
var tileOriginY = TileSource.TileSize * (tileCenterY - TileGrid.YMin);
|
||||
var tileOriginX = MapProjection.TileSize * (tileCenterX - TileGrid.XMin);
|
||||
var tileOriginY = MapProjection.TileSize * (tileCenterY - TileGrid.YMin);
|
||||
var viewCenterX = parentMap.RenderSize.Width / 2d;
|
||||
var viewCenterY = parentMap.RenderSize.Height / 2d;
|
||||
|
||||
((MatrixTransform)RenderTransform).Matrix = MatrixEx.TranslateScaleRotateTranslate(
|
||||
tileOriginX, tileOriginY, scale, scale, parentMap.Heading, viewCenterX, viewCenterY);
|
||||
-tileOriginX, -tileOriginY, scale, scale, parentMap.Heading, viewCenterX, viewCenterY);
|
||||
}
|
||||
|
||||
private void UpdateTiles()
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
#if NETFX_CORE
|
||||
#if WINDOWS_UWP
|
||||
using Windows.Foundation;
|
||||
#else
|
||||
using System.Windows;
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
#if NETFX_CORE
|
||||
#if WINDOWS_UWP
|
||||
using Windows.Foundation;
|
||||
#else
|
||||
using System.Windows;
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
#if NETFX_CORE
|
||||
#if WINDOWS_UWP
|
||||
using Windows.UI.Xaml.Controls;
|
||||
#else
|
||||
using System.Windows.Controls;
|
||||
|
|
@ -25,13 +25,12 @@ namespace MapControl
|
|||
|
||||
public bool Equals(TileGrid tileGrid)
|
||||
{
|
||||
return ReferenceEquals(this, tileGrid)
|
||||
|| (tileGrid != null
|
||||
return tileGrid != null
|
||||
&& tileGrid.ZoomLevel == ZoomLevel
|
||||
&& tileGrid.XMin == XMin
|
||||
&& tileGrid.YMin == YMin
|
||||
&& tileGrid.XMax == XMax
|
||||
&& tileGrid.YMax == YMax);
|
||||
&& tileGrid.YMax == YMax;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
172
MapControl/Shared/TileImageLoader.cs
Normal file
172
MapControl/Shared/TileImageLoader.cs
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
// 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.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
#if WINDOWS_UWP
|
||||
using Windows.Web.Http;
|
||||
#else
|
||||
using System.Net.Http;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Loads and optionally caches map tile images for a MapTileLayer.
|
||||
/// </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.
|
||||
/// </summary>
|
||||
public static TimeSpan DefaultCacheExpiration { get; set; } = TimeSpan.FromDays(1);
|
||||
|
||||
/// <summary>
|
||||
/// Minimum expiration time for cached tile images. The default value is one hour.
|
||||
/// </summary>
|
||||
public static TimeSpan MinimumCacheExpiration { get; set; } = TimeSpan.FromHours(1);
|
||||
|
||||
/// <summary>
|
||||
/// Maximum expiration time for cached tile images. The default value is one week.
|
||||
/// </summary>
|
||||
public static TimeSpan MaximumCacheExpiration { get; set; } = TimeSpan.FromDays(7);
|
||||
|
||||
/// <summary>
|
||||
/// Format string for creating cache keys from the SourceName property of a TileSource,
|
||||
/// the ZoomLevel, XIndex, and Y properties of a Tile, and the image file extension.
|
||||
/// The default value is "{0};{1};{2};{3}{4}".
|
||||
/// </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)
|
||||
{
|
||||
pendingTiles.Clear();
|
||||
|
||||
var tileSource = tileLayer.TileSource;
|
||||
var sourceName = tileLayer.SourceName;
|
||||
var tiles = tileLayer.Tiles.Where(t => t.Pending);
|
||||
|
||||
if (tileSource != null && tiles.Any())
|
||||
{
|
||||
if (Cache == null || string.IsNullOrEmpty(sourceName) ||
|
||||
tileSource.UriFormat == null || !tileSource.UriFormat.StartsWith("http"))
|
||||
{
|
||||
// no caching, load tile images in UI thread
|
||||
|
||||
foreach (var tile in tiles)
|
||||
{
|
||||
LoadTileImage(tileSource, tile);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pendingTiles.PushRange(tiles.Reverse().ToArray());
|
||||
|
||||
while (taskCount < Math.Min(pendingTiles.Count, tileLayer.MaxParallelDownloads))
|
||||
{
|
||||
Interlocked.Increment(ref taskCount);
|
||||
|
||||
var task = Task.Run(async () => // do not await
|
||||
{
|
||||
await LoadPendingTilesAsync(tileSource, sourceName); // run multiple times in parallel
|
||||
|
||||
Interlocked.Decrement(ref taskCount);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadTileImage(TileSource tileSource, Tile tile)
|
||||
{
|
||||
tile.Pending = false;
|
||||
|
||||
try
|
||||
{
|
||||
var imageSource = tileSource.LoadImage(tile.XIndex, tile.Y, tile.ZoomLevel);
|
||||
|
||||
if (imageSource != null)
|
||||
{
|
||||
tile.SetImage(imageSource);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("TileImageLoader: {0}/{1}/{2}: {3}", tile.ZoomLevel, tile.XIndex, tile.Y, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadPendingTilesAsync(TileSource tileSource, string sourceName)
|
||||
{
|
||||
Tile tile;
|
||||
|
||||
while (pendingTiles.TryPop(out tile))
|
||||
{
|
||||
tile.Pending = false;
|
||||
|
||||
try
|
||||
{
|
||||
var uri = tileSource.GetUri(tile.XIndex, tile.Y, tile.ZoomLevel);
|
||||
|
||||
if (uri != null)
|
||||
{
|
||||
var extension = Path.GetExtension(uri.LocalPath);
|
||||
|
||||
if (string.IsNullOrEmpty(extension) || extension == ".jpeg")
|
||||
{
|
||||
extension = ".jpg";
|
||||
}
|
||||
|
||||
var cacheKey = string.Format(CacheKeyFormat, sourceName, tile.ZoomLevel, tile.XIndex, tile.Y, extension);
|
||||
|
||||
await LoadTileImageAsync(tile, uri, cacheKey);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("TileImageLoader: {0}/{1}/{2}: {3}", tile.ZoomLevel, tile.XIndex, tile.Y, ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static DateTime GetExpiration(HttpResponseMessage response)
|
||||
{
|
||||
var expiration = DefaultCacheExpiration;
|
||||
var headers = response.Headers;
|
||||
|
||||
if (headers.CacheControl != null && headers.CacheControl.MaxAge.HasValue)
|
||||
{
|
||||
expiration = headers.CacheControl.MaxAge.Value;
|
||||
|
||||
if (expiration < MinimumCacheExpiration)
|
||||
{
|
||||
expiration = MinimumCacheExpiration;
|
||||
}
|
||||
else if (expiration > MaximumCacheExpiration)
|
||||
{
|
||||
expiration = MaximumCacheExpiration;
|
||||
}
|
||||
}
|
||||
|
||||
return DateTime.UtcNow.Add(expiration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,16 +4,21 @@
|
|||
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides the URI of a map tile.
|
||||
/// Provides the download Uri or ImageSource of map tiles.
|
||||
/// </summary>
|
||||
public partial class TileSource
|
||||
{
|
||||
public const int TileSize = 256;
|
||||
|
||||
private Func<int, int, int, Uri> getUri;
|
||||
private string uriFormat = string.Empty;
|
||||
|
||||
|
|
@ -26,6 +31,9 @@ namespace MapControl
|
|||
this.uriFormat = uriFormat;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the format string to produce tile Uris.
|
||||
/// </summary>
|
||||
public string UriFormat
|
||||
{
|
||||
get { return uriFormat; }
|
||||
|
|
@ -76,11 +84,25 @@ namespace MapControl
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the map tile Uri.
|
||||
/// </summary>
|
||||
public virtual Uri GetUri(int x, int y, int zoomLevel)
|
||||
{
|
||||
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
|
||||
|
|
@ -170,8 +192,8 @@ namespace MapControl
|
|||
.Replace("{S}", south.ToString(CultureInfo.InvariantCulture))
|
||||
.Replace("{E}", east.ToString(CultureInfo.InvariantCulture))
|
||||
.Replace("{N}", north.ToString(CultureInfo.InvariantCulture))
|
||||
.Replace("{X}", TileSize.ToString())
|
||||
.Replace("{Y}", TileSize.ToString()));
|
||||
.Replace("{X}", MapProjection.TileSize.ToString())
|
||||
.Replace("{Y}", MapProjection.TileSize.ToString()));
|
||||
}
|
||||
|
||||
private Uri GetLatLonBoundingBoxUri(int x, int y, int zoomLevel)
|
||||
|
|
@ -187,8 +209,8 @@ namespace MapControl
|
|||
.Replace("{s}", south.ToString(CultureInfo.InvariantCulture))
|
||||
.Replace("{e}", east.ToString(CultureInfo.InvariantCulture))
|
||||
.Replace("{n}", north.ToString(CultureInfo.InvariantCulture))
|
||||
.Replace("{X}", TileSize.ToString())
|
||||
.Replace("{Y}", TileSize.ToString()));
|
||||
.Replace("{X}", MapProjection.TileSize.ToString())
|
||||
.Replace("{Y}", MapProjection.TileSize.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
#if NETFX_CORE
|
||||
#if WINDOWS_UWP
|
||||
using Windows.Foundation;
|
||||
#else
|
||||
using System.Windows;
|
||||
|
|
@ -34,7 +34,7 @@ namespace MapControl
|
|||
|
||||
public override double GetViewportScale(double zoomLevel)
|
||||
{
|
||||
return base.GetViewportScale(zoomLevel) / MetersPerDegree;
|
||||
return DegreesToViewportScale(zoomLevel) / MetersPerDegree;
|
||||
}
|
||||
|
||||
public override Point GetMapScale(Location location)
|
||||
|
|
@ -70,6 +70,8 @@ namespace MapControl
|
|||
|
||||
public static double LatitudeToY(double latitude)
|
||||
{
|
||||
var lat = latitude * Math.PI / 180d;
|
||||
|
||||
return latitude <= -90d ? double.NegativeInfinity
|
||||
: latitude >= 90d ? double.PositiveInfinity
|
||||
: Math.Log(Math.Tan((latitude + 90d) * Math.PI / 360d)) / Math.PI * 180d;
|
||||
|
|
@ -3,10 +3,16 @@
|
|||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
#if NETFX_CORE
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
#if WINDOWS_UWP
|
||||
using Windows.Data.Xml.Dom;
|
||||
using Windows.UI.Xaml;
|
||||
#else
|
||||
using System.Windows;
|
||||
using System.Xml;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
|
|
@ -23,15 +29,11 @@ namespace MapControl
|
|||
|
||||
public static readonly DependencyProperty LayersProperty = DependencyProperty.Register(
|
||||
nameof(Layers), typeof(string), typeof(WmsImageLayer),
|
||||
new PropertyMetadata(null, (o, e) => ((WmsImageLayer)o).UpdateImage()));
|
||||
new PropertyMetadata(string.Empty, (o, e) => ((WmsImageLayer)o).UpdateImage()));
|
||||
|
||||
public static readonly DependencyProperty StylesProperty = DependencyProperty.Register(
|
||||
nameof(Styles), typeof(string), typeof(WmsImageLayer),
|
||||
new PropertyMetadata(null, (o, e) => ((WmsImageLayer)o).UpdateImage()));
|
||||
|
||||
public static readonly DependencyProperty ParametersProperty = DependencyProperty.Register(
|
||||
nameof(Parameters), typeof(string), typeof(WmsImageLayer),
|
||||
new PropertyMetadata(null, (o, e) => ((WmsImageLayer)o).UpdateImage()));
|
||||
new PropertyMetadata(string.Empty, (o, e) => ((WmsImageLayer)o).UpdateImage()));
|
||||
|
||||
public static readonly DependencyProperty FormatProperty = DependencyProperty.Register(
|
||||
nameof(Format), typeof(string), typeof(WmsImageLayer),
|
||||
|
|
@ -67,12 +69,6 @@ namespace MapControl
|
|||
set { SetValue(StylesProperty, value); }
|
||||
}
|
||||
|
||||
public string Parameters
|
||||
{
|
||||
get { return (string)GetValue(ParametersProperty); }
|
||||
set { SetValue(ParametersProperty, value); }
|
||||
}
|
||||
|
||||
public string Format
|
||||
{
|
||||
get { return (string)GetValue(FormatProperty); }
|
||||
|
|
@ -92,14 +88,60 @@ namespace MapControl
|
|||
return false;
|
||||
}
|
||||
|
||||
var version = Version ?? "1.3.0";
|
||||
var queryParameters = ParentMap.MapProjection.WmsQueryParameters(boundingBox, version);
|
||||
var projectionParameters = ParentMap.MapProjection.WmsQueryParameters(boundingBox, Version);
|
||||
|
||||
if (string.IsNullOrEmpty(queryParameters))
|
||||
if (string.IsNullOrEmpty(projectionParameters))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
UpdateImage(GetRequestUri("GetMap"
|
||||
+ "&LAYERS=" + Layers + "&STYLES=" + Styles + "&FORMAT=" + Format
|
||||
+ "&TRANSPARENT=" + (Transparent ? "TRUE" : "FALSE") + "&" + projectionParameters));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<IList<string>> GetLayerNamesAsync()
|
||||
{
|
||||
if (ServerUri == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var layerNames = new List<string>();
|
||||
|
||||
try
|
||||
{
|
||||
var document = await XmlDocument.LoadFromUriAsync(GetRequestUri("GetCapabilities"));
|
||||
|
||||
var capability = ChildElements(document.DocumentElement, "Capability").FirstOrDefault();
|
||||
if (capability != null)
|
||||
{
|
||||
var rootLayer = ChildElements(capability, "Layer").FirstOrDefault();
|
||||
if (rootLayer != null)
|
||||
{
|
||||
foreach (var layer in ChildElements(rootLayer, "Layer"))
|
||||
{
|
||||
var name = ChildElements(layer, "Name").FirstOrDefault();
|
||||
if (name != null)
|
||||
{
|
||||
layerNames.Add(name.InnerText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("WmsImageLayer: {0}: {1}", ServerUri, ex.Message);
|
||||
}
|
||||
|
||||
return layerNames;
|
||||
}
|
||||
|
||||
private Uri GetRequestUri(string query)
|
||||
{
|
||||
var uri = ServerUri.ToString();
|
||||
|
||||
if (!uri.EndsWith("?") && !uri.EndsWith("&"))
|
||||
|
|
@ -107,22 +149,14 @@ namespace MapControl
|
|||
uri += "?";
|
||||
}
|
||||
|
||||
uri += "SERVICE=WMS"
|
||||
+ "&VERSION=" + version
|
||||
+ "&REQUEST=GetMap"
|
||||
+ "&LAYERS=" + (Layers ?? string.Empty)
|
||||
+ "&STYLES=" + (Styles ?? string.Empty)
|
||||
+ "&" + queryParameters
|
||||
+ "&FORMAT=" + (Format ?? "image/png")
|
||||
+ "&TRANSPARENT=" + (Transparent ? "TRUE" : "FALSE");
|
||||
uri += "SERVICE=WMS&VERSION=" + Version + "&REQUEST=" + query;
|
||||
|
||||
if (!string.IsNullOrEmpty(Parameters))
|
||||
{
|
||||
uri += "&" + Parameters;
|
||||
return new Uri(uri.Replace(" ", "%20"));
|
||||
}
|
||||
|
||||
UpdateImage(new Uri(uri.Replace(" ", "%20")));
|
||||
return true;
|
||||
private static IEnumerable<XmlElement> ChildElements(XmlElement element, string name)
|
||||
{
|
||||
return element.ChildNodes.OfType<XmlElement>().Where(e => (string)e.LocalName == name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,53 +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;
|
||||
using System.Linq;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Loads map tile images.
|
||||
/// </summary>
|
||||
public class TileImageLoader : ITileImageLoader
|
||||
{
|
||||
public void LoadTiles(MapTileLayer tileLayer)
|
||||
{
|
||||
var tileSource = tileLayer.TileSource;
|
||||
var imageTileSource = tileSource as ImageTileSource;
|
||||
|
||||
foreach (var tile in tileLayer.Tiles.Where(t => t.Pending))
|
||||
{
|
||||
tile.Pending = false;
|
||||
|
||||
try
|
||||
{
|
||||
ImageSource image = null;
|
||||
Uri uri;
|
||||
|
||||
if (imageTileSource != null)
|
||||
{
|
||||
image = imageTileSource.LoadImage(tile.XIndex, tile.Y, tile.ZoomLevel);
|
||||
}
|
||||
else if ((uri = tileSource.GetUri(tile.XIndex, tile.Y, tile.ZoomLevel)) != null)
|
||||
{
|
||||
image = new BitmapImage(uri);
|
||||
}
|
||||
|
||||
if (image != null)
|
||||
{
|
||||
tile.SetImage(image);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("{0}/{1}/{2}: {3}", tile.ZoomLevel, tile.XIndex, tile.Y, ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,272 +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;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Runtime.Caching;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Loads map tile images and optionally caches them in a System.Runtime.Caching.ObjectCache.
|
||||
/// </summary>
|
||||
public class TileImageLoader : ITileImageLoader
|
||||
{
|
||||
/// <summary>
|
||||
/// Default name of an ObjectCache instance that is assigned to the Cache property.
|
||||
/// </summary>
|
||||
public const string DefaultCacheName = "TileCache";
|
||||
|
||||
/// <summary>
|
||||
/// Default folder path where an ObjectCache instance may save cached data.
|
||||
/// </summary>
|
||||
public static readonly string DefaultCacheFolder =
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "MapControl");
|
||||
|
||||
/// <summary>
|
||||
/// Default expiration time for cached tile images. Used when no expiration time
|
||||
/// was transmitted on download. The default value is one day.
|
||||
/// </summary>
|
||||
public static TimeSpan DefaultCacheExpiration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Minimum expiration time for cached tile images. Used when an unnecessarily small expiration time
|
||||
/// was transmitted on download (e.g. Cache-Control: max-age=0). The default value is one hour.
|
||||
/// </summary>
|
||||
public static TimeSpan MinimumCacheExpiration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ObjectCache used to cache tile images. The default is MemoryCache.Default.
|
||||
/// </summary>
|
||||
public static ObjectCache Cache { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional value to be used for the HttpWebRequest.UserAgent property. The default is null.
|
||||
/// </summary>
|
||||
public static string HttpUserAgent { get; set; }
|
||||
|
||||
static TileImageLoader()
|
||||
{
|
||||
DefaultCacheExpiration = TimeSpan.FromDays(1);
|
||||
MinimumCacheExpiration = TimeSpan.FromHours(1);
|
||||
Cache = MemoryCache.Default;
|
||||
}
|
||||
|
||||
private readonly ConcurrentStack<Tile> pendingTiles = new ConcurrentStack<Tile>();
|
||||
private int taskCount;
|
||||
|
||||
public void LoadTiles(MapTileLayer tileLayer)
|
||||
{
|
||||
pendingTiles.Clear();
|
||||
|
||||
var tiles = tileLayer.Tiles.Where(t => t.Pending);
|
||||
|
||||
if (tiles.Any())
|
||||
{
|
||||
pendingTiles.PushRange(tiles.Reverse().ToArray());
|
||||
|
||||
var tileSource = tileLayer.TileSource;
|
||||
var sourceName = tileLayer.SourceName;
|
||||
var maxDownloads = tileLayer.MaxParallelDownloads;
|
||||
|
||||
while (taskCount < Math.Min(pendingTiles.Count, maxDownloads))
|
||||
{
|
||||
Interlocked.Increment(ref taskCount);
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
LoadPendingTiles(tileSource, sourceName);
|
||||
|
||||
Interlocked.Decrement(ref taskCount);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadPendingTiles(TileSource tileSource, string sourceName)
|
||||
{
|
||||
var imageTileSource = tileSource as ImageTileSource;
|
||||
Tile tile;
|
||||
|
||||
while (pendingTiles.TryPop(out tile))
|
||||
{
|
||||
tile.Pending = false;
|
||||
|
||||
try
|
||||
{
|
||||
ImageSource image = null;
|
||||
Uri uri;
|
||||
|
||||
if (imageTileSource != null)
|
||||
{
|
||||
image = imageTileSource.LoadImage(tile.XIndex, tile.Y, tile.ZoomLevel);
|
||||
}
|
||||
else if ((uri = tileSource.GetUri(tile.XIndex, tile.Y, tile.ZoomLevel)) != null)
|
||||
{
|
||||
image = LoadImage(uri, sourceName, tile.XIndex, tile.Y, tile.ZoomLevel);
|
||||
}
|
||||
|
||||
if (image != null)
|
||||
{
|
||||
tile.SetImage(image);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("{0}/{1}/{2}: {3}", tile.ZoomLevel, tile.XIndex, tile.Y, ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ImageSource LoadImage(Uri uri, string sourceName, int x, int y, int zoomLevel)
|
||||
{
|
||||
ImageSource image = null;
|
||||
|
||||
try
|
||||
{
|
||||
if (!uri.IsAbsoluteUri)
|
||||
{
|
||||
image = BitmapSourceHelper.FromFile(uri.OriginalString);
|
||||
}
|
||||
else if (uri.Scheme == "file")
|
||||
{
|
||||
image = BitmapSourceHelper.FromFile(uri.LocalPath);
|
||||
}
|
||||
else if (Cache == null || string.IsNullOrEmpty(sourceName))
|
||||
{
|
||||
image = DownloadImage(uri, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
var cacheKey = string.Format("{0}/{1}/{2}/{3}", sourceName, zoomLevel, x, y);
|
||||
|
||||
if (!GetCachedImage(cacheKey, ref image))
|
||||
{
|
||||
// Either no cached image was found or expiration time has expired.
|
||||
// If download fails use possibly cached but expired image anyway.
|
||||
image = DownloadImage(uri, cacheKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (WebException ex)
|
||||
{
|
||||
Debug.WriteLine("{0}: {1}: {2}", uri, ex.Status, ex.Message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("{0}: {1}", uri, ex.Message);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
private static ImageSource DownloadImage(Uri uri, string cacheKey)
|
||||
{
|
||||
ImageSource image = null;
|
||||
var request = WebRequest.CreateHttp(uri);
|
||||
|
||||
if (HttpUserAgent != null)
|
||||
{
|
||||
request.UserAgent = HttpUserAgent;
|
||||
}
|
||||
|
||||
using (var response = (HttpWebResponse)request.GetResponse())
|
||||
{
|
||||
if (response.Headers["X-VE-Tile-Info"] != "no-tile") // set by Bing Maps
|
||||
{
|
||||
using (var responseStream = response.GetResponseStream())
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
responseStream.CopyTo(memoryStream);
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
image = BitmapSourceHelper.FromStream(memoryStream);
|
||||
|
||||
if (cacheKey != null)
|
||||
{
|
||||
SetCachedImage(cacheKey, memoryStream, GetExpiration(response.Headers));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
private static bool GetCachedImage(string cacheKey, ref ImageSource image)
|
||||
{
|
||||
var result = false;
|
||||
var buffer = Cache.Get(cacheKey) as byte[];
|
||||
|
||||
if (buffer != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var memoryStream = new MemoryStream(buffer))
|
||||
{
|
||||
image = BitmapSourceHelper.FromStream(memoryStream);
|
||||
}
|
||||
|
||||
DateTime expiration = DateTime.MinValue;
|
||||
|
||||
if (buffer.Length >= 16 && Encoding.ASCII.GetString(buffer, buffer.Length - 16, 8) == "EXPIRES:")
|
||||
{
|
||||
expiration = new DateTime(BitConverter.ToInt64(buffer, buffer.Length - 8), DateTimeKind.Utc);
|
||||
}
|
||||
|
||||
result = expiration > DateTime.UtcNow;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("{0}: {1}", cacheKey, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void SetCachedImage(string cacheKey, MemoryStream memoryStream, DateTime expiration)
|
||||
{
|
||||
memoryStream.Seek(0, SeekOrigin.End);
|
||||
memoryStream.Write(Encoding.ASCII.GetBytes("EXPIRES:"), 0, 8);
|
||||
memoryStream.Write(BitConverter.GetBytes(expiration.Ticks), 0, 8);
|
||||
|
||||
Cache.Set(cacheKey, memoryStream.ToArray(), new CacheItemPolicy { AbsoluteExpiration = expiration });
|
||||
}
|
||||
|
||||
private static DateTime GetExpiration(WebHeaderCollection headers)
|
||||
{
|
||||
var expiration = DefaultCacheExpiration;
|
||||
var cacheControl = headers["Cache-Control"];
|
||||
|
||||
if (cacheControl != null)
|
||||
{
|
||||
int maxAgeValue;
|
||||
var maxAgeDirective = cacheControl
|
||||
.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.FirstOrDefault(s => s.StartsWith("max-age="));
|
||||
|
||||
if (maxAgeDirective != null &&
|
||||
int.TryParse(maxAgeDirective.Substring(8), out maxAgeValue))
|
||||
{
|
||||
expiration = TimeSpan.FromSeconds(maxAgeValue);
|
||||
|
||||
if (expiration < MinimumCacheExpiration)
|
||||
{
|
||||
expiration = MinimumCacheExpiration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DateTime.UtcNow.Add(expiration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,295 +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;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
using Windows.Storage.Streams;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
using Windows.Web.Http;
|
||||
using Windows.Web.Http.Filters;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Loads map tile images and optionally caches them in a IImageCache.
|
||||
/// </summary>
|
||||
public class TileImageLoader : ITileImageLoader
|
||||
{
|
||||
/// <summary>
|
||||
/// Default name of an IImageCache instance that is assigned to the Cache property.
|
||||
/// </summary>
|
||||
public const string DefaultCacheName = "TileCache";
|
||||
|
||||
/// <summary>
|
||||
/// Default StorageFolder where an IImageCache instance may save cached data.
|
||||
/// </summary>
|
||||
public static readonly StorageFolder DefaultCacheFolder = ApplicationData.Current.TemporaryFolder;
|
||||
|
||||
/// <summary>
|
||||
/// Default expiration time for cached tile images. Used when no expiration time
|
||||
/// was transmitted on download. The default value is one day.
|
||||
/// </summary>
|
||||
public static TimeSpan DefaultCacheExpiration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Minimum expiration time for cached tile images. Used when an unnecessarily small expiration time
|
||||
/// was transmitted on download (e.g. Cache-Control: max-age=0). The default value is one hour.
|
||||
/// </summary>
|
||||
public static TimeSpan MinimumCacheExpiration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The IImageCache implementation used to cache tile images. The default is null.
|
||||
/// </summary>
|
||||
public static Caching.IImageCache Cache;
|
||||
|
||||
static TileImageLoader()
|
||||
{
|
||||
DefaultCacheExpiration = TimeSpan.FromDays(1);
|
||||
MinimumCacheExpiration = TimeSpan.FromHours(1);
|
||||
}
|
||||
|
||||
private readonly ConcurrentStack<Tile> pendingTiles = new ConcurrentStack<Tile>();
|
||||
private int taskCount;
|
||||
|
||||
public void LoadTiles(MapTileLayer tileLayer)
|
||||
{
|
||||
pendingTiles.Clear();
|
||||
|
||||
var tiles = tileLayer.Tiles.Where(t => t.Pending);
|
||||
|
||||
if (tiles.Any())
|
||||
{
|
||||
var tileSource = tileLayer.TileSource;
|
||||
var imageTileSource = tileSource as ImageTileSource;
|
||||
|
||||
if (imageTileSource != null)
|
||||
{
|
||||
LoadTiles(tiles, imageTileSource);
|
||||
}
|
||||
else
|
||||
{
|
||||
pendingTiles.PushRange(tiles.Reverse().ToArray());
|
||||
|
||||
var sourceName = tileLayer.SourceName;
|
||||
var maxDownloads = tileLayer.MaxParallelDownloads;
|
||||
|
||||
while (taskCount < Math.Min(pendingTiles.Count, maxDownloads))
|
||||
{
|
||||
Interlocked.Increment(ref taskCount);
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await LoadPendingTiles(tileSource, sourceName);
|
||||
|
||||
Interlocked.Decrement(ref taskCount);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadTiles(IEnumerable<Tile> tiles, ImageTileSource tileSource)
|
||||
{
|
||||
foreach (var tile in tiles)
|
||||
{
|
||||
tile.Pending = false;
|
||||
|
||||
try
|
||||
{
|
||||
var image = tileSource.LoadImage(tile.XIndex, tile.Y, tile.ZoomLevel);
|
||||
|
||||
if (image != null)
|
||||
{
|
||||
tile.SetImage(image);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("{0}/{1}/{2}: {3}", tile.ZoomLevel, tile.XIndex, tile.Y, ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadPendingTiles(TileSource tileSource, string sourceName)
|
||||
{
|
||||
Tile tile;
|
||||
|
||||
while (pendingTiles.TryPop(out tile))
|
||||
{
|
||||
tile.Pending = false;
|
||||
|
||||
try
|
||||
{
|
||||
var uri = tileSource.GetUri(tile.XIndex, tile.Y, tile.ZoomLevel);
|
||||
|
||||
if (uri != null)
|
||||
{
|
||||
if (!uri.IsAbsoluteUri)
|
||||
{
|
||||
await LoadImageFromFile(tile, uri.OriginalString);
|
||||
}
|
||||
else if (uri.Scheme == "file")
|
||||
{
|
||||
await LoadImageFromFile(tile, uri.LocalPath);
|
||||
}
|
||||
else if (Cache == null || sourceName == null)
|
||||
{
|
||||
await DownloadImage(tile, uri, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
var extension = Path.GetExtension(uri.LocalPath);
|
||||
|
||||
if (string.IsNullOrEmpty(extension) || extension == ".jpeg")
|
||||
{
|
||||
extension = ".jpg";
|
||||
}
|
||||
|
||||
var cacheKey = string.Format(@"{0}\{1}\{2}\{3}{4}", sourceName, tile.ZoomLevel, tile.XIndex, tile.Y, extension);
|
||||
var cacheItem = await Cache.GetAsync(cacheKey);
|
||||
var loaded = false;
|
||||
|
||||
if (cacheItem == null || cacheItem.Expiration <= DateTime.UtcNow)
|
||||
{
|
||||
loaded = await DownloadImage(tile, uri, cacheKey);
|
||||
}
|
||||
|
||||
if (!loaded && cacheItem != null && cacheItem.Buffer != null)
|
||||
{
|
||||
using (var stream = new InMemoryRandomAccessStream())
|
||||
{
|
||||
await stream.WriteAsync(cacheItem.Buffer);
|
||||
await stream.FlushAsync();
|
||||
stream.Seek(0);
|
||||
|
||||
await LoadImageFromStream(tile, stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("{0}/{1}/{2}: {3}", tile.ZoomLevel, tile.XIndex, tile.Y, ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> DownloadImage(Tile tile, Uri uri, string cacheKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var httpClient = new HttpClient(new HttpBaseProtocolFilter { AllowAutoRedirect = false }))
|
||||
using (var response = await httpClient.GetAsync(uri))
|
||||
{
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
string tileInfo;
|
||||
|
||||
if (!response.Headers.TryGetValue("X-VE-Tile-Info", out tileInfo) || tileInfo != "no-tile") // set by Bing Maps
|
||||
{
|
||||
await LoadImageFromHttpResponse(response, tile, cacheKey);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Debug.WriteLine("{0}: {1} {2}", uri, (int)response.StatusCode, response.ReasonPhrase);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("{0}: {1}", uri, ex.Message);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private async Task LoadImageFromHttpResponse(HttpResponseMessage response, Tile tile, string cacheKey)
|
||||
{
|
||||
using (var stream = new InMemoryRandomAccessStream())
|
||||
{
|
||||
using (var content = response.Content)
|
||||
{
|
||||
await content.WriteToStreamAsync(stream);
|
||||
}
|
||||
|
||||
await stream.FlushAsync();
|
||||
stream.Seek(0);
|
||||
|
||||
await LoadImageFromStream(tile, stream);
|
||||
|
||||
if (cacheKey != null)
|
||||
{
|
||||
var buffer = new Windows.Storage.Streams.Buffer((uint)stream.Size);
|
||||
|
||||
stream.Seek(0);
|
||||
await stream.ReadAsync(buffer, buffer.Capacity, InputStreamOptions.None);
|
||||
|
||||
var expiration = DefaultCacheExpiration;
|
||||
|
||||
if (response.Headers.CacheControl.MaxAge.HasValue)
|
||||
{
|
||||
expiration = response.Headers.CacheControl.MaxAge.Value;
|
||||
|
||||
if (expiration < MinimumCacheExpiration)
|
||||
{
|
||||
expiration = MinimumCacheExpiration;
|
||||
}
|
||||
}
|
||||
|
||||
await Cache.SetAsync(cacheKey, buffer, DateTime.UtcNow.Add(expiration));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadImageFromFile(Tile tile, string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
var file = await StorageFile.GetFileFromPathAsync(path);
|
||||
|
||||
using (var stream = await file.OpenReadAsync())
|
||||
{
|
||||
await LoadImageFromStream(tile, stream);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("{0}: {1}", path, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadImageFromStream(Tile tile, IRandomAccessStream stream)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<object>();
|
||||
|
||||
await tile.Image.Dispatcher.RunAsync(CoreDispatcherPriority.Low, async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var image = new BitmapImage();
|
||||
await image.SetSourceAsync(stream);
|
||||
tile.SetImage(image, true, false);
|
||||
|
||||
tcs.SetResult(null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
tcs.SetException(ex);
|
||||
}
|
||||
});
|
||||
|
||||
await tcs.Task;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
public class TileSourceConverter : TypeConverter
|
||||
{
|
||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
||||
{
|
||||
return sourceType == typeof(string);
|
||||
}
|
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||
{
|
||||
return new TileSource { UriFormat = value as string };
|
||||
}
|
||||
}
|
||||
|
||||
[TypeConverter(typeof(TileSourceConverter))]
|
||||
public partial class TileSource
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -2,10 +2,8 @@
|
|||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Windows.Foundation;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Media.Animation;
|
||||
|
|
@ -14,11 +12,6 @@ namespace MapControl
|
|||
{
|
||||
internal static class Extensions
|
||||
{
|
||||
public static IAsyncAction BeginInvoke(this CoreDispatcher dispatcher, Action action)
|
||||
{
|
||||
return dispatcher.RunAsync(CoreDispatcherPriority.Normal, new DispatchedHandler(action));
|
||||
}
|
||||
|
||||
public static Point Transform(this GeneralTransform transform, Point point)
|
||||
{
|
||||
return transform.TransformPoint(point);
|
||||
|
|
@ -47,6 +40,7 @@ namespace MapControl
|
|||
private static void BeginAnimation(DependencyObject obj, DependencyProperty property, Timeline animation)
|
||||
{
|
||||
string propertyName;
|
||||
|
||||
if (properties.TryGetValue(property, out propertyName))
|
||||
{
|
||||
Storyboard.SetTargetProperty(animation, propertyName);
|
||||
99
MapControl/UWP/ImageFileCache.UWP.cs
Normal file
99
MapControl/UWP/ImageFileCache.UWP.cs
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
// 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.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
using Windows.Storage.Streams;
|
||||
|
||||
namespace MapControl.Caching
|
||||
{
|
||||
public class ImageFileCache : IImageCache
|
||||
{
|
||||
private StorageFolder rootFolder;
|
||||
|
||||
public ImageFileCache(StorageFolder rootFolder)
|
||||
{
|
||||
if (rootFolder == null)
|
||||
{
|
||||
throw new ArgumentNullException("The parameter rootFolder must not be null.");
|
||||
}
|
||||
|
||||
this.rootFolder = rootFolder;
|
||||
|
||||
Debug.WriteLine("Created ImageFileCache in " + rootFolder.Path);
|
||||
}
|
||||
|
||||
public virtual async Task<ImageCacheItem> GetAsync(string key)
|
||||
{
|
||||
string path = null;
|
||||
|
||||
try
|
||||
{
|
||||
path = Path.Combine(key.Split('\\', '/', ':', ';'));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("ImageFileCache: Invalid key {0}: {1}", key, ex.Message);
|
||||
}
|
||||
|
||||
if (path != null)
|
||||
{
|
||||
var item = await rootFolder.TryGetItemAsync(path);
|
||||
|
||||
if (item != null && item.IsOfType(StorageItemTypes.File))
|
||||
{
|
||||
var file = (StorageFile)item;
|
||||
//Debug.WriteLine("ImageFileCache: Reading " + file.Path);
|
||||
|
||||
try
|
||||
{
|
||||
return new ImageCacheItem
|
||||
{
|
||||
Buffer = await FileIO.ReadBufferAsync(file),
|
||||
Expiration = (await file.Properties.GetImagePropertiesAsync()).DateTaken.UtcDateTime
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("ImageFileCache: Reading {0}: {1}", file.Path, ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual async Task SetAsync(string key, IBuffer buffer, DateTime expiration)
|
||||
{
|
||||
var paths = key.Split('\\', '/', ':', ';');
|
||||
|
||||
try
|
||||
{
|
||||
var folder = rootFolder;
|
||||
|
||||
for (int i = 0; i < paths.Length - 1; i++)
|
||||
{
|
||||
folder = await folder.CreateFolderAsync(paths[i], CreationCollisionOption.OpenIfExists);
|
||||
}
|
||||
|
||||
var file = await folder.CreateFileAsync(paths[paths.Length - 1], CreationCollisionOption.ReplaceExisting);
|
||||
//Debug.WriteLine("ImageFileCache: Writing {0}, Expires {1}", file.Path, expiration.ToLocalTime());
|
||||
|
||||
await FileIO.WriteBufferAsync(file, buffer);
|
||||
|
||||
// Store expiration date in ImageProperties.DateTaken
|
||||
var properties = await file.Properties.GetImagePropertiesAsync();
|
||||
properties.DateTaken = expiration;
|
||||
await properties.SavePropertiesAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("ImageFileCache: Writing {0}\\{1}: {2}", rootFolder.Path, string.Join("\\", paths), ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,15 +2,10 @@
|
|||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
#if NETFX_CORE
|
||||
using Windows.Foundation;
|
||||
using Windows.UI;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Media;
|
||||
#else
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
180
MapControl/UWP/MapControl.UWP.csproj
Normal file
180
MapControl/UWP/MapControl.UWP.csproj
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{951BC5D2-D653-42D9-9A91-21DC50DE0182}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MapControl</RootNamespace>
|
||||
<AssemblyName>MapControl.UWP</AssemblyName>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||
<TargetPlatformVersion>10.0.10240.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
|
||||
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<GenerateLibraryLayout>true</GenerateLibraryLayout>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<GenerateLibraryLayout>true</GenerateLibraryLayout>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- A reference to the entire .Net Framework and Windows SDK are automatically included -->
|
||||
<None Include="..\..\MapControl.snk">
|
||||
<Link>MapControl.snk</Link>
|
||||
</None>
|
||||
<None Include="project.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Shared\AzimuthalEquidistantProjection.cs">
|
||||
<Link>AzimuthalEquidistantProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\AzimuthalProjection.cs">
|
||||
<Link>AzimuthalProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\BingMapsTileLayer.cs">
|
||||
<Link>BingMapsTileLayer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\BingMapsTileSource.cs">
|
||||
<Link>BingMapsTileSource.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\BoundingBox.cs">
|
||||
<Link>BoundingBox.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\CenteredBoundingBox.cs">
|
||||
<Link>CenteredBoundingBox.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\EquirectangularProjection.cs">
|
||||
<Link>EquirectangularProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\GnomonicProjection.cs">
|
||||
<Link>GnomonicProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\HyperlinkText.cs">
|
||||
<Link>HyperlinkText.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\Location.cs">
|
||||
<Link>Location.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\LocationCollection.cs">
|
||||
<Link>LocationCollection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapBase.cs">
|
||||
<Link>MapBase.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapGraticule.cs">
|
||||
<Link>MapGraticule.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapImageLayer.cs">
|
||||
<Link>MapImageLayer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapOverlay.cs">
|
||||
<Link>MapOverlay.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapPanel.cs">
|
||||
<Link>MapPanel.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapPath.cs">
|
||||
<Link>MapPath.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapPolyline.cs">
|
||||
<Link>MapPolyline.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapProjection.cs">
|
||||
<Link>MapProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapTileLayer.cs">
|
||||
<Link>MapTileLayer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\OrthographicProjection.cs">
|
||||
<Link>OrthographicProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\StereographicProjection.cs">
|
||||
<Link>StereographicProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\Tile.cs">
|
||||
<Link>Tile.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\TileGrid.cs">
|
||||
<Link>TileGrid.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\TileImageLoader.cs">
|
||||
<Link>TileImageLoader.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\TileSource.cs">
|
||||
<Link>TileSource.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\ViewportChangedEventArgs.cs">
|
||||
<Link>ViewportChangedEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\WebMercatorProjection.cs">
|
||||
<Link>WebMercatorProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\WmsImageLayer.cs">
|
||||
<Link>WmsImageLayer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Extensions.UWP.cs" />
|
||||
<Compile Include="ImageCache.UWP.cs" />
|
||||
<Compile Include="ImageFileCache.UWP.cs" />
|
||||
<Compile Include="Map.UWP.cs" />
|
||||
<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" />
|
||||
<EmbeddedResource Include="Properties\MapControl.UWP.rd.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="Themes\Generic.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AssemblyOriginatorKeyFile>..\..\MapControl.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
|
|
@ -3,20 +3,12 @@
|
|||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
#if NETFX_CORE
|
||||
using Windows.Foundation;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Shapes;
|
||||
using Windows.UI.Xaml.Data;
|
||||
#else
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Data;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
|
|
@ -3,15 +3,9 @@
|
|||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
#if NETFX_CORE
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
#else
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media.Imaging;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
|
|
@ -19,14 +13,14 @@ namespace MapControl
|
|||
{
|
||||
protected void UpdateImage(Uri uri)
|
||||
{
|
||||
UpdateImage(new BitmapImage(uri));
|
||||
UpdateImage(uri != null ? new BitmapImage(uri) : null);
|
||||
}
|
||||
|
||||
protected void UpdateImage(BitmapSource bitmap)
|
||||
protected void UpdateImage(BitmapSource bitmapSource)
|
||||
{
|
||||
SetTopImage(bitmap);
|
||||
SetTopImage(bitmapSource);
|
||||
|
||||
var bitmapImage = bitmap as BitmapImage;
|
||||
var bitmapImage = bitmapSource as BitmapImage;
|
||||
|
||||
if (bitmapImage != null)
|
||||
{
|
||||
|
|
@ -41,18 +35,20 @@ namespace MapControl
|
|||
|
||||
private void BitmapImageOpened(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var bitmap = (BitmapImage)sender;
|
||||
bitmap.ImageOpened -= BitmapImageOpened;
|
||||
bitmap.ImageFailed -= BitmapImageFailed;
|
||||
var bitmapImage = (BitmapImage)sender;
|
||||
|
||||
bitmapImage.ImageOpened -= BitmapImageOpened;
|
||||
bitmapImage.ImageFailed -= BitmapImageFailed;
|
||||
|
||||
SwapImages();
|
||||
}
|
||||
|
||||
private void BitmapImageFailed(object sender, ExceptionRoutedEventArgs e)
|
||||
{
|
||||
var bitmap = (BitmapImage)sender;
|
||||
bitmap.ImageOpened -= BitmapImageOpened;
|
||||
bitmap.ImageFailed -= BitmapImageFailed;
|
||||
var bitmapImage = (BitmapImage)sender;
|
||||
|
||||
bitmapImage.ImageOpened -= BitmapImageOpened;
|
||||
bitmapImage.ImageFailed -= BitmapImageFailed;
|
||||
|
||||
((Image)Children[topImageIndex]).Source = null;
|
||||
SwapImages();
|
||||
|
|
@ -2,11 +2,7 @@
|
|||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
#if NETFX_CORE
|
||||
using Windows.UI.Xaml.Controls;
|
||||
#else
|
||||
using System.Windows.Controls;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
|
|
@ -2,13 +2,8 @@
|
|||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
#if NETFX_CORE
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
#else
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
|
|
@ -2,24 +2,13 @@
|
|||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
#if NETFX_CORE
|
||||
using Windows.UI.Text;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Media;
|
||||
#else
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
#if NETFX_CORE
|
||||
class FontStyles { public const FontStyle Normal = FontStyle.Normal; }
|
||||
class FontStretches { public const FontStretch Normal = FontStretch.Normal; }
|
||||
#endif
|
||||
|
||||
public partial class MapOverlay
|
||||
{
|
||||
public static readonly DependencyProperty FontSizeProperty = DependencyProperty.Register(
|
||||
|
|
@ -29,10 +18,10 @@ namespace MapControl
|
|||
nameof(FontFamily), typeof(FontFamily), typeof(MapOverlay), new PropertyMetadata(null));
|
||||
|
||||
public static readonly DependencyProperty FontStyleProperty = DependencyProperty.Register(
|
||||
nameof(FontStyle), typeof(FontStyle), typeof(MapOverlay), new PropertyMetadata(FontStyles.Normal));
|
||||
nameof(FontStyle), typeof(FontStyle), typeof(MapOverlay), new PropertyMetadata(FontStyle.Normal));
|
||||
|
||||
public static readonly DependencyProperty FontStretchProperty = DependencyProperty.Register(
|
||||
nameof(FontStretch), typeof(FontStretch), typeof(MapOverlay), new PropertyMetadata(FontStretches.Normal));
|
||||
nameof(FontStretch), typeof(FontStretch), typeof(MapOverlay), new PropertyMetadata(FontStretch.Normal));
|
||||
|
||||
public static readonly DependencyProperty FontWeightProperty = DependencyProperty.Register(
|
||||
nameof(FontWeight), typeof(FontWeight), typeof(MapOverlay), new PropertyMetadata(FontWeights.Normal));
|
||||
|
|
@ -2,13 +2,8 @@
|
|||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
#if NETFX_CORE
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Media;
|
||||
#else
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
|
|
@ -2,15 +2,9 @@
|
|||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
#if NETFX_CORE
|
||||
using Windows.Foundation;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Shapes;
|
||||
#else
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shapes;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
|
|
@ -23,7 +17,7 @@ namespace MapControl
|
|||
MapPanel.AddParentMapHandlers(this);
|
||||
}
|
||||
|
||||
protected override Size MeasureOverride(Size constraint)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
if (Stretch != Stretch.None)
|
||||
{
|
||||
|
|
@ -46,12 +40,7 @@ namespace MapControl
|
|||
}
|
||||
}
|
||||
|
||||
// Path.MeasureOverride in Windows Runtime sometimes returns an empty Size,
|
||||
// whereas in Silverlight it occasionally throws an ArgumentException,
|
||||
// apparently because it tries to create a Size from negative width or height,
|
||||
// which result from a transformed Geometry.
|
||||
// In either case it seems to be sufficient to simply return a non-zero size.
|
||||
return new Size(1, 1);
|
||||
return new Size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,14 +2,10 @@
|
|||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
#if NETFX_CORE
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Media;
|
||||
#else
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
|
|
@ -19,11 +15,21 @@ namespace MapControl
|
|||
nameof(FillRule), typeof(FillRule), typeof(MapPolyline),
|
||||
new PropertyMetadata(FillRule.EvenOdd, (o, e) => ((PathGeometry)((MapPolyline)o).Data).FillRule = (FillRule)e.NewValue));
|
||||
|
||||
|
||||
public MapPolyline()
|
||||
{
|
||||
Data = new PathGeometry();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the locations that define the polyline points.
|
||||
/// </summary>
|
||||
public IEnumerable<Location> Locations
|
||||
{
|
||||
get { return (IEnumerable<Location>)GetValue(LocationsProperty); }
|
||||
set { SetValue(LocationsProperty, value); }
|
||||
}
|
||||
|
||||
protected override void UpdateData()
|
||||
{
|
||||
var geometry = (PathGeometry)Data;
|
||||
|
|
@ -2,8 +2,11 @@
|
|||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using Windows.UI.Xaml.Markup;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
[ContentProperty(Name = "TileSource")]
|
||||
public partial class MapTileLayer
|
||||
{
|
||||
partial void Initialize()
|
||||
87
MapControl/UWP/MatrixEx.UWP.cs
Normal file
87
MapControl/UWP/MatrixEx.UWP.cs
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
|
||||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
using Windows.UI.Xaml.Media;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
internal static class MatrixEx
|
||||
{
|
||||
/// <summary>
|
||||
/// Used in MapProjection and MapTileLayer.
|
||||
/// </summary>
|
||||
public static Matrix TranslateScaleRotateTranslate(
|
||||
double translation1X, double translation1Y,
|
||||
double scaleX, double scaleY, double rotationAngle,
|
||||
double translation2X, double translation2Y)
|
||||
{
|
||||
var matrix = new Matrix(
|
||||
scaleX, 0d, 0d, scaleY,
|
||||
scaleX * translation1X,
|
||||
scaleY * translation1Y);
|
||||
|
||||
if (rotationAngle != 0d)
|
||||
{
|
||||
rotationAngle = (rotationAngle % 360d) / 180d * Math.PI;
|
||||
|
||||
var cos = Math.Cos(rotationAngle);
|
||||
var sin = Math.Sin(rotationAngle);
|
||||
|
||||
matrix = new Matrix(
|
||||
matrix.M11 * cos - matrix.M12 * sin,
|
||||
matrix.M11 * sin + matrix.M12 * cos,
|
||||
matrix.M21 * cos - matrix.M22 * sin,
|
||||
matrix.M21 * sin + matrix.M22 * cos,
|
||||
cos * matrix.OffsetX - sin * matrix.OffsetY,
|
||||
sin * matrix.OffsetX + cos * matrix.OffsetY);
|
||||
}
|
||||
|
||||
matrix.OffsetX += translation2X;
|
||||
matrix.OffsetY += translation2Y;
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
public static Matrix TranslateScaleRotateTranslate_(
|
||||
double translation1X, double translation1Y,
|
||||
double scaleX, double scaleY, double rotationAngle,
|
||||
double translation2X, double translation2Y)
|
||||
{
|
||||
var m11 = scaleX;
|
||||
var m12 = 0d;
|
||||
var m21 = 0d;
|
||||
var m22 = scaleY;
|
||||
var offsetX = scaleX * translation1X;
|
||||
var offsetY = scaleY * translation1Y;
|
||||
|
||||
if (rotationAngle != 0d)
|
||||
{
|
||||
rotationAngle = (rotationAngle % 360d) / 180d * Math.PI;
|
||||
|
||||
var cos = Math.Cos(rotationAngle);
|
||||
var sin = Math.Sin(rotationAngle);
|
||||
|
||||
var _m11 = m11;
|
||||
var _m12 = m12;
|
||||
var _m21 = m21;
|
||||
var _m22 = m22;
|
||||
var _offsetX = offsetX;
|
||||
var _offsetY = offsetY;
|
||||
|
||||
m11 = _m11 * cos - _m12 * sin;
|
||||
m12 = _m11 * sin + _m12 * cos;
|
||||
m21 = _m21 * cos - _m22 * sin;
|
||||
m22 = _m21 * sin + _m22 * cos;
|
||||
offsetX = cos * _offsetX - sin * _offsetY;
|
||||
offsetY = sin * _offsetX + cos * _offsetY;
|
||||
}
|
||||
|
||||
offsetX += translation2X;
|
||||
offsetY += translation2Y;
|
||||
|
||||
return new Matrix(m11, m12, m21, m22, offsetX, offsetY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("XAML Map Control (WinRT)")]
|
||||
[assembly: AssemblyDescription("XAML Map Control Library for Windows Runtime")]
|
||||
[assembly: AssemblyTitle("XAML Map Control for UWP")]
|
||||
[assembly: AssemblyDescription("XAML Map Control Library for UWP")]
|
||||
[assembly: AssemblyProduct("XAML Map Control")]
|
||||
[assembly: AssemblyCompany("Clemens Fischer")]
|
||||
[assembly: AssemblyCopyright("© 2017 Clemens Fischer")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyVersion("3.4.1")]
|
||||
[assembly: AssemblyFileVersion("3.4.1")]
|
||||
[assembly: AssemblyVersion("4.0.0")]
|
||||
[assembly: AssemblyFileVersion("4.0.0")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
5
MapControl/UWP/Properties/MapControl.UWP.rd.xml
Normal file
5
MapControl/UWP/Properties/MapControl.UWP.rd.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
|
||||
<Library Name="MapControl.UWP">
|
||||
</Library>
|
||||
</Directives>
|
||||
|
|
@ -2,11 +2,7 @@
|
|||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
#if NETFX_CORE
|
||||
using Windows.UI.Xaml.Controls;
|
||||
#else
|
||||
using System.Windows.Controls;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
|
|
@ -3,36 +3,28 @@
|
|||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System;
|
||||
#if NETFX_CORE
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Media.Animation;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
#else
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Imaging;
|
||||
#endif
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
public partial class Tile
|
||||
{
|
||||
public void SetImage(ImageSource image, bool fadeIn = true, bool isDownloading = true)
|
||||
public void SetImage(ImageSource imageSource, bool fadeIn = true)
|
||||
{
|
||||
Pending = false;
|
||||
|
||||
if (fadeIn && FadeDuration > TimeSpan.Zero)
|
||||
{
|
||||
BitmapImage bitmap;
|
||||
var bitmapImage = imageSource as BitmapImage;
|
||||
|
||||
if (isDownloading && (bitmap = image as BitmapImage) != null)
|
||||
if (bitmapImage != null && bitmapImage.UriSource != null)
|
||||
{
|
||||
bitmap.ImageOpened += BitmapImageOpened;
|
||||
bitmap.ImageFailed += BitmapImageFailed;
|
||||
bitmapImage.ImageOpened += BitmapImageOpened;
|
||||
bitmapImage.ImageFailed += BitmapImageFailed;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -45,15 +37,15 @@ namespace MapControl
|
|||
Image.Opacity = 1d;
|
||||
}
|
||||
|
||||
Image.Source = image;
|
||||
Image.Source = imageSource;
|
||||
}
|
||||
|
||||
private void BitmapImageOpened(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var bitmap = (BitmapImage)sender;
|
||||
var bitmapImage = (BitmapImage)sender;
|
||||
|
||||
bitmap.ImageOpened -= BitmapImageOpened;
|
||||
bitmap.ImageFailed -= BitmapImageFailed;
|
||||
bitmapImage.ImageOpened -= BitmapImageOpened;
|
||||
bitmapImage.ImageFailed -= BitmapImageFailed;
|
||||
|
||||
Image.BeginAnimation(UIElement.OpacityProperty,
|
||||
new DoubleAnimation { From = 0d, To = 1d, Duration = FadeDuration });
|
||||
|
|
@ -61,10 +53,10 @@ namespace MapControl
|
|||
|
||||
private void BitmapImageFailed(object sender, ExceptionRoutedEventArgs e)
|
||||
{
|
||||
var bitmap = (BitmapImage)sender;
|
||||
var bitmapImage = (BitmapImage)sender;
|
||||
|
||||
bitmap.ImageOpened -= BitmapImageOpened;
|
||||
bitmap.ImageFailed -= BitmapImageFailed;
|
||||
bitmapImage.ImageOpened -= BitmapImageOpened;
|
||||
bitmapImage.ImageFailed -= BitmapImageFailed;
|
||||
|
||||
Image.Source = null;
|
||||
}
|
||||
114
MapControl/UWP/TileImageLoader.UWP.cs
Normal file
114
MapControl/UWP/TileImageLoader.UWP.cs
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
// 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;
|
||||
using Windows.Storage.Streams;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
using Windows.Web.Http;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
public partial class TileImageLoader : ITileImageLoader
|
||||
{
|
||||
/// <summary>
|
||||
/// Default StorageFolder where an IImageCache instance may save cached data.
|
||||
/// </summary>
|
||||
public static readonly StorageFolder DefaultCacheFolder = ApplicationData.Current.TemporaryFolder;
|
||||
|
||||
/// <summary>
|
||||
/// The IImageCache implementation used to cache tile images. The default is null.
|
||||
/// </summary>
|
||||
public static Caching.IImageCache Cache { get; set; }
|
||||
|
||||
private async Task LoadTileImageAsync(Tile tile, Uri uri, string cacheKey)
|
||||
{
|
||||
var cacheItem = await Cache.GetAsync(cacheKey);
|
||||
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);
|
||||
}
|
||||
|
||||
if (!loaded && buffer != null) // keep expired image if download failed
|
||||
{
|
||||
await SetTileImageAsync(tile, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> DownloadTileImageAsync(Tile tile, Uri uri, string cacheKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var response = await HttpClient.GetAsync(uri))
|
||||
{
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("TileImageLoader: {0}: {1}", uri, ex.Message);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private async Task SetTileImageAsync(Tile tile, IBuffer buffer)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<object>();
|
||||
|
||||
using (var stream = new InMemoryRandomAccessStream())
|
||||
{
|
||||
await stream.WriteAsync(buffer);
|
||||
await stream.FlushAsync(); // necessary?
|
||||
stream.Seek(0);
|
||||
|
||||
await tile.Image.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var bitmapImage = new BitmapImage();
|
||||
await bitmapImage.SetSourceAsync(stream);
|
||||
|
||||
tile.SetImage(bitmapImage);
|
||||
tcs.SetResult(null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
tcs.SetException(ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
await tcs.Task;
|
||||
}
|
||||
}
|
||||
}
|
||||
16
MapControl/UWP/project.json
Normal file
16
MapControl/UWP/project.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.UniversalWindowsPlatform": "5.1.0"
|
||||
},
|
||||
"frameworks": {
|
||||
"uap10.0": {}
|
||||
},
|
||||
"runtimes": {
|
||||
"win10-arm": {},
|
||||
"win10-arm-aot": {},
|
||||
"win10-x86": {},
|
||||
"win10-x86-aot": {},
|
||||
"win10-x64": {},
|
||||
"win10-x64-aot": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
|
@ -20,52 +19,28 @@ namespace MapControl.Caching
|
|||
/// </summary>
|
||||
public class ImageFileCache : ObjectCache
|
||||
{
|
||||
private static readonly Tuple<string, byte[]>[] imageFileTypes = new Tuple<string, byte[]>[]
|
||||
{
|
||||
new Tuple<string, byte[]>(".png", new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }),
|
||||
new Tuple<string, byte[]>(".jpg", new byte[] { 0xFF, 0xD8, 0xFF }),
|
||||
new Tuple<string, byte[]>(".bmp", new byte[] { 0x42, 0x4D }),
|
||||
new Tuple<string, byte[]>(".gif", new byte[] { 0x47, 0x49, 0x46 }),
|
||||
new Tuple<string, byte[]>(".tif", new byte[] { 0x49, 0x49, 0x2A, 0x00 }),
|
||||
new Tuple<string, byte[]>(".tif", new byte[] { 0x4D, 0x4D, 0x00, 0x2A }),
|
||||
new Tuple<string, byte[]>(".bin", new byte[] { }),
|
||||
};
|
||||
|
||||
private static readonly FileSystemAccessRule fullControlRule = new FileSystemAccessRule(
|
||||
new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null),
|
||||
FileSystemRights.FullControl, AccessControlType.Allow);
|
||||
|
||||
private readonly MemoryCache memoryCache = MemoryCache.Default;
|
||||
private readonly string name;
|
||||
private readonly string rootFolder;
|
||||
|
||||
public ImageFileCache(string name, NameValueCollection config)
|
||||
: this(name, config["folder"])
|
||||
public ImageFileCache(string rootFolder)
|
||||
{
|
||||
if (string.IsNullOrEmpty(rootFolder))
|
||||
{
|
||||
throw new ArgumentException("The parameter rootFolder must not be null or empty.");
|
||||
}
|
||||
|
||||
public ImageFileCache(string name, string folder)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new ArgumentException("The parameter name must not be null or empty.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(folder))
|
||||
{
|
||||
throw new ArgumentException("The parameter folder must not be null or empty.");
|
||||
}
|
||||
|
||||
this.name = name;
|
||||
rootFolder = Path.Combine(folder, name);
|
||||
Directory.CreateDirectory(rootFolder);
|
||||
this.rootFolder = rootFolder;
|
||||
|
||||
Debug.WriteLine("Created ImageFileCache in " + rootFolder);
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return name; }
|
||||
get { return string.Empty; }
|
||||
}
|
||||
|
||||
public override DefaultCacheCapabilities DefaultCacheCapabilities
|
||||
|
|
@ -178,9 +153,10 @@ namespace MapControl.Caching
|
|||
|
||||
memoryCache.Set(key, buffer, policy);
|
||||
|
||||
var path = Path.Combine(rootFolder, key)
|
||||
+ imageFileTypes.First(t => t.Item2.SequenceEqual(buffer.Take(t.Item2.Length))).Item1;
|
||||
var path = GetPath(key);
|
||||
|
||||
if (path != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
//Debug.WriteLine("ImageFileCache: Writing {0}, Expires {1}", path, policy.AbsoluteExpiration.DateTime.ToLocalTime());
|
||||
|
|
@ -196,6 +172,7 @@ namespace MapControl.Caching
|
|||
Debug.WriteLine("ImageFileCache: Failed writing {0}: {1}", path, ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Set(string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)
|
||||
{
|
||||
|
|
@ -263,21 +240,14 @@ namespace MapControl.Caching
|
|||
|
||||
private string FindFile(string key)
|
||||
{
|
||||
var path = Path.Combine(rootFolder, key);
|
||||
var path = GetPath(key);
|
||||
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Path.GetExtension(path)))
|
||||
if (path != null && File.Exists(path))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
string folderName = Path.GetDirectoryName(path);
|
||||
|
||||
if (Directory.Exists(folderName))
|
||||
{
|
||||
return Directory.EnumerateFiles(folderName, Path.GetFileName(path) + ".*").FirstOrDefault();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -286,5 +256,19 @@ namespace MapControl.Caching
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
private string GetPath(string key)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Path.Combine(rootFolder, Path.Combine(key.Split('\\', '/', ':', ';')));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("ImageFileCache: Invalid key {0}/{1}: {2}", rootFolder, key, ex.Message);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
183
MapControl/WPF/MapControl.WPF.csproj
Normal file
183
MapControl/WPF/MapControl.WPF.csproj
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{A204A102-C745-4D65-AEC8-7B96FAEDEF2D}</ProjectGuid>
|
||||
<OutputType>library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MapControl</RootNamespace>
|
||||
<AssemblyName>MapControl.WPF</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AssemblyOriginatorKeyFile>..\..\MapControl.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Runtime.Caching" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Xaml">
|
||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="Themes\Generic.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Shared\AzimuthalEquidistantProjection.cs">
|
||||
<Link>AzimuthalEquidistantProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\AzimuthalProjection.cs">
|
||||
<Link>AzimuthalProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\BingMapsTileLayer.cs">
|
||||
<Link>BingMapsTileLayer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\BingMapsTileSource.cs">
|
||||
<Link>BingMapsTileSource.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\BoundingBox.cs">
|
||||
<Link>BoundingBox.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\CenteredBoundingBox.cs">
|
||||
<Link>CenteredBoundingBox.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\EquirectangularProjection.cs">
|
||||
<Link>EquirectangularProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\GnomonicProjection.cs">
|
||||
<Link>GnomonicProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\HyperlinkText.cs">
|
||||
<Link>HyperlinkText.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\Location.cs">
|
||||
<Link>Location.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\LocationCollection.cs">
|
||||
<Link>LocationCollection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapBase.cs">
|
||||
<Link>MapBase.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapGraticule.cs">
|
||||
<Link>MapGraticule.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapImageLayer.cs">
|
||||
<Link>MapImageLayer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapOverlay.cs">
|
||||
<Link>MapOverlay.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapPanel.cs">
|
||||
<Link>MapPanel.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapPath.cs">
|
||||
<Link>MapPath.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapPolyline.cs">
|
||||
<Link>MapPolyline.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapProjection.cs">
|
||||
<Link>MapProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\MapTileLayer.cs">
|
||||
<Link>MapTileLayer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\OrthographicProjection.cs">
|
||||
<Link>OrthographicProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\StereographicProjection.cs">
|
||||
<Link>StereographicProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\Tile.cs">
|
||||
<Link>Tile.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\TileGrid.cs">
|
||||
<Link>TileGrid.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\TileImageLoader.cs">
|
||||
<Link>TileImageLoader.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\TileSource.cs">
|
||||
<Link>TileSource.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\ViewportChangedEventArgs.cs">
|
||||
<Link>ViewportChangedEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\WebMercatorProjection.cs">
|
||||
<Link>WebMercatorProjection.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Shared\WmsImageLayer.cs">
|
||||
<Link>WmsImageLayer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="ImageFileCache.WPF.cs" />
|
||||
<Compile Include="Map.WPF.cs" />
|
||||
<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="MapScale.WPF.cs" />
|
||||
<Compile Include="MapTileLayer.WPF.cs" />
|
||||
<Compile Include="Pushpin.WPF.cs" />
|
||||
<Compile Include="TileImageLoader.WPF.cs" />
|
||||
<Compile Include="TypeConverters.WPF.cs" />
|
||||
<Compile Include="MatrixEx.WPF.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Tile.WPF.cs" />
|
||||
<Compile Include="XmlDocument.WPF.cs" />
|
||||
<None Include="..\..\MapControl.snk">
|
||||
<Link>MapControl.snk</Link>
|
||||
</None>
|
||||
<AppDesigner Include="Properties\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
57
MapControl/WPF/MapImageLayer.WPF.cs
Normal file
57
MapControl/WPF/MapImageLayer.WPF.cs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
// 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.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
public partial class MapImageLayer
|
||||
{
|
||||
protected void UpdateImage(Uri uri)
|
||||
{
|
||||
UpdateImage(uri != null
|
||||
? BitmapFrame.Create(uri, BitmapCreateOptions.IgnoreImageCache, BitmapCacheOption.OnDemand)
|
||||
: null);
|
||||
}
|
||||
|
||||
protected void UpdateImage(BitmapSource bitmapSource)
|
||||
{
|
||||
SetTopImage(bitmapSource);
|
||||
|
||||
if (bitmapSource != null && !bitmapSource.IsFrozen && bitmapSource.IsDownloading)
|
||||
{
|
||||
bitmapSource.DownloadCompleted += BitmapDownloadCompleted;
|
||||
bitmapSource.DownloadFailed += BitmapDownloadFailed;
|
||||
}
|
||||
else
|
||||
{
|
||||
SwapImages();
|
||||
}
|
||||
}
|
||||
|
||||
private void BitmapDownloadCompleted(object sender, EventArgs e)
|
||||
{
|
||||
var bitmapSource = (BitmapSource)sender;
|
||||
|
||||
bitmapSource.DownloadCompleted -= BitmapDownloadCompleted;
|
||||
bitmapSource.DownloadFailed -= BitmapDownloadFailed;
|
||||
|
||||
SwapImages();
|
||||
}
|
||||
|
||||
private void BitmapDownloadFailed(object sender, ExceptionEventArgs e)
|
||||
{
|
||||
var bitmapSource = (BitmapSource)sender;
|
||||
|
||||
bitmapSource.DownloadCompleted -= BitmapDownloadCompleted;
|
||||
bitmapSource.DownloadFailed -= BitmapDownloadFailed;
|
||||
|
||||
((Image)Children[topImageIndex]).Source = null;
|
||||
SwapImages();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -31,10 +31,9 @@ namespace MapControl
|
|||
get { return Data; }
|
||||
}
|
||||
|
||||
protected override Size MeasureOverride(Size constraint)
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
// Shape.MeasureOverride sometimes returns an empty Size.
|
||||
return new Size(1, 1);
|
||||
return new Size();
|
||||
}
|
||||
|
||||
private static void DataPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
// © 2017 Clemens Fischer
|
||||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
|
|
@ -10,15 +12,26 @@ namespace MapControl
|
|||
{
|
||||
public partial class MapPolyline
|
||||
{
|
||||
public static readonly DependencyProperty FillRuleProperty = StreamGeometry.FillRuleProperty.AddOwner(
|
||||
typeof(MapPolyline),
|
||||
new FrameworkPropertyMetadata((o, e) => ((StreamGeometry)((MapPolyline)o).Data).FillRule = (FillRule)e.NewValue));
|
||||
public static readonly DependencyProperty FillRuleProperty = DependencyProperty.Register(
|
||||
nameof(FillRule), typeof(FillRule), typeof(MapPolyline), new FrameworkPropertyMetadata(
|
||||
FillRule.EvenOdd, FrameworkPropertyMetadataOptions.AffectsRender,
|
||||
(o, e) => ((StreamGeometry)((MapPolyline)o).Data).FillRule = (FillRule)e.NewValue));
|
||||
|
||||
public MapPolyline()
|
||||
{
|
||||
Data = new StreamGeometry();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the locations that define the polyline points.
|
||||
/// </summary>
|
||||
[TypeConverter(typeof(LocationCollectionConverter))]
|
||||
public IEnumerable<Location> Locations
|
||||
{
|
||||
get { return (IEnumerable<Location>)GetValue(LocationsProperty); }
|
||||
set { SetValue(LocationsProperty, value); }
|
||||
}
|
||||
|
||||
protected override void UpdateData()
|
||||
{
|
||||
var geometry = (StreamGeometry)Data;
|
||||
|
|
@ -3,9 +3,11 @@
|
|||
// Licensed under the Microsoft Public License (Ms-PL)
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Markup;
|
||||
|
||||
namespace MapControl
|
||||
{
|
||||
[ContentProperty("TileSource")]
|
||||
public partial class MapTileLayer
|
||||
{
|
||||
static MapTileLayer()
|
||||
|
|
@ -16,7 +16,7 @@ namespace MapControl
|
|||
double scaleX, double scaleY, double rotationAngle,
|
||||
double translation2X, double translation2Y)
|
||||
{
|
||||
var matrix = new Matrix(1d, 0d, 0d, 1d, -translation1X, -translation1Y);
|
||||
var matrix = new Matrix(1d, 0d, 0d, 1d, translation1X, translation1Y);
|
||||
matrix.Scale(scaleX, scaleY);
|
||||
matrix.Rotate(rotationAngle);
|
||||
matrix.Translate(translation2X, translation2Y);
|
||||
|
|
@ -2,20 +2,15 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
|
||||
#if SILVERLIGHT
|
||||
[assembly: AssemblyTitle("XAML Map Control (Silverlight)")]
|
||||
[assembly: AssemblyDescription("XAML Map Control Library for Silverlight")]
|
||||
#else
|
||||
[assembly: AssemblyTitle("XAML Map Control (WPF)")]
|
||||
[assembly: AssemblyTitle("XAML Map Control for WPF")]
|
||||
[assembly: AssemblyDescription("XAML Map Control Library for WPF")]
|
||||
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
|
||||
#endif
|
||||
[assembly: AssemblyProduct("XAML Map Control")]
|
||||
[assembly: AssemblyCompany("Clemens Fischer")]
|
||||
[assembly: AssemblyCopyright("© 2017 Clemens Fischer")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyVersion("3.4.1")]
|
||||
[assembly: AssemblyFileVersion("3.4.1")]
|
||||
[assembly: AssemblyVersion("4.0.0")]
|
||||
[assembly: AssemblyFileVersion("4.0.0")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue