diff --git a/Caching/FileDbCache.WPF/FileDbCache.cs b/Caching/FileDbCache.WPF/FileDbCache.cs index 40d532d9..b9a97d28 100644 --- a/Caching/FileDbCache.WPF/FileDbCache.cs +++ b/Caching/FileDbCache.WPF/FileDbCache.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System; diff --git a/Caching/FileDbCache.WPF/Properties/AssemblyInfo.cs b/Caching/FileDbCache.WPF/Properties/AssemblyInfo.cs index 68a0ee2f..0a9fe1cc 100644 --- a/Caching/FileDbCache.WPF/Properties/AssemblyInfo.cs +++ b/Caching/FileDbCache.WPF/Properties/AssemblyInfo.cs @@ -5,10 +5,10 @@ using System.Runtime.InteropServices; [assembly: AssemblyDescription("ObjectCache implementation based on EzTools FileDb")] [assembly: AssemblyProduct("XAML Map Control")] [assembly: AssemblyCompany("Clemens Fischer")] -[assembly: AssemblyCopyright("© 2016 Clemens Fischer")] +[assembly: AssemblyCopyright("© 2017 Clemens Fischer")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("2.14.0")] -[assembly: AssemblyFileVersion("2.14.0")] +[assembly: AssemblyVersion("3.1.0")] +[assembly: AssemblyFileVersion("3.1.0")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] diff --git a/Caching/FileDbCache.WinRT/FileDbCache.cs b/Caching/FileDbCache.WinRT/FileDbCache.cs index c3dcf9cb..46b381e8 100644 --- a/Caching/FileDbCache.WinRT/FileDbCache.cs +++ b/Caching/FileDbCache.WinRT/FileDbCache.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System; diff --git a/Caching/FileDbCache.WinRT/Properties/AssemblyInfo.cs b/Caching/FileDbCache.WinRT/Properties/AssemblyInfo.cs index 30cc8632..b4a6df75 100644 --- a/Caching/FileDbCache.WinRT/Properties/AssemblyInfo.cs +++ b/Caching/FileDbCache.WinRT/Properties/AssemblyInfo.cs @@ -5,10 +5,10 @@ using System.Runtime.InteropServices; [assembly: AssemblyDescription("IImageCache implementation based on EzTools FileDb")] [assembly: AssemblyProduct("XAML Map Control")] [assembly: AssemblyCompany("Clemens Fischer")] -[assembly: AssemblyCopyright("© 2016 Clemens Fischer")] +[assembly: AssemblyCopyright("© 2017 Clemens Fischer")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("2.14.0")] -[assembly: AssemblyFileVersion("2.14.0")] +[assembly: AssemblyVersion("3.1.0")] +[assembly: AssemblyFileVersion("3.1.0")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] diff --git a/Caching/ImageFileCache.WPF/ImageFileCache.cs b/Caching/ImageFileCache.WPF/ImageFileCache.cs index c5e10675..d2dcf71a 100644 --- a/Caching/ImageFileCache.WPF/ImageFileCache.cs +++ b/Caching/ImageFileCache.WPF/ImageFileCache.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System; diff --git a/Caching/ImageFileCache.WPF/Properties/AssemblyInfo.cs b/Caching/ImageFileCache.WPF/Properties/AssemblyInfo.cs index 5706ccb7..0b1058e1 100644 --- a/Caching/ImageFileCache.WPF/Properties/AssemblyInfo.cs +++ b/Caching/ImageFileCache.WPF/Properties/AssemblyInfo.cs @@ -5,10 +5,10 @@ using System.Runtime.InteropServices; [assembly: AssemblyDescription("ObjectCache implementation based on local image files")] [assembly: AssemblyProduct("XAML Map Control")] [assembly: AssemblyCompany("Clemens Fischer")] -[assembly: AssemblyCopyright("© 2016 Clemens Fischer")] +[assembly: AssemblyCopyright("© 2017 Clemens Fischer")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("2.14.0")] -[assembly: AssemblyFileVersion("2.14.0")] +[assembly: AssemblyVersion("3.1.0")] +[assembly: AssemblyFileVersion("3.1.0")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] diff --git a/Caching/ImageFileCache.WinRT/ImageFileCache.cs b/Caching/ImageFileCache.WinRT/ImageFileCache.cs index 0e5b99c6..51040ec7 100644 --- a/Caching/ImageFileCache.WinRT/ImageFileCache.cs +++ b/Caching/ImageFileCache.WinRT/ImageFileCache.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System; diff --git a/Caching/ImageFileCache.WinRT/Properties/AssemblyInfo.cs b/Caching/ImageFileCache.WinRT/Properties/AssemblyInfo.cs index 87206b9c..cf64836d 100644 --- a/Caching/ImageFileCache.WinRT/Properties/AssemblyInfo.cs +++ b/Caching/ImageFileCache.WinRT/Properties/AssemblyInfo.cs @@ -5,10 +5,10 @@ using System.Runtime.InteropServices; [assembly: AssemblyDescription("IImageCache implementation based on local image files")] [assembly: AssemblyProduct("XAML Map Control")] [assembly: AssemblyCompany("Clemens Fischer")] -[assembly: AssemblyCopyright("© 2016 Clemens Fischer")] +[assembly: AssemblyCopyright("© 2017 Clemens Fischer")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("2.14.0")] -[assembly: AssemblyFileVersion("2.14.0")] +[assembly: AssemblyVersion("3.1.0")] +[assembly: AssemblyFileVersion("3.1.0")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] diff --git a/MapControl VS2015.sln b/MapControl VS2015.sln deleted file mode 100644 index 152f2071..00000000 --- a/MapControl VS2015.sln +++ /dev/null @@ -1,238 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileDbCache.WinRT", "Caching\FileDbCache.WinRT\FileDbCache.WinRT.csproj", "{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileDbCache.WPF", "Caching\FileDbCache.WPF\FileDbCache.WPF.csproj", "{EF44F661-B98A-4676-927F-85D138F82300}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageFileCache.WinRT", "Caching\ImageFileCache.WinRT\ImageFileCache.WinRT.csproj", "{F789647E-96F7-43E3-A895-FA3FE8D01260}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageFileCache.WPF", "Caching\ImageFileCache.WPF\ImageFileCache.WPF.csproj", "{86470440-FEE2-4120-AF5A-3762FB9C536F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapControl.Silverlight", "MapControl\MapControl.Silverlight.csproj", "{EB133B78-DEFF-416A-8F0C-89E54D766576}" -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}") = "SilverlightApplication", "SampleApps\SilverlightApplication\SilverlightApplication.csproj", "{CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SilverlightApplication.Web", "SampleApps\SilverlightApplication.Web\SilverlightApplication.Web.csproj", "{177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}" -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}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversalApp", "SampleApps\UniversalApp\UniversalApp.csproj", "{AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|ARM = Debug|ARM - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|ARM = Release|ARM - Release|x64 = Release|x64 - 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 - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Debug|ARM.ActiveCfg = Debug|Any CPU - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Debug|ARM.Build.0 = Debug|Any CPU - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Debug|x64.ActiveCfg = Debug|Any CPU - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Debug|x64.Build.0 = Debug|Any CPU - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Debug|x86.ActiveCfg = Debug|Any CPU - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Debug|x86.Build.0 = Debug|Any CPU - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Release|Any CPU.Build.0 = Release|Any CPU - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Release|ARM.ActiveCfg = Release|Any CPU - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Release|ARM.Build.0 = Release|Any CPU - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Release|x64.ActiveCfg = Release|Any CPU - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Release|x64.Build.0 = Release|Any CPU - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Release|x86.ActiveCfg = Release|Any CPU - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Release|x86.Build.0 = Release|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.Debug|ARM.ActiveCfg = Debug|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.Debug|ARM.Build.0 = Debug|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.Debug|x64.ActiveCfg = Debug|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.Debug|x64.Build.0 = Debug|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.Debug|x86.ActiveCfg = Debug|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.Debug|x86.Build.0 = Debug|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.Release|Any CPU.Build.0 = Release|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.Release|ARM.ActiveCfg = Release|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.Release|ARM.Build.0 = Release|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.Release|x64.ActiveCfg = Release|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.Release|x64.Build.0 = Release|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.Release|x86.ActiveCfg = Release|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.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 - {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 - {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Debug|x64.ActiveCfg = Debug|x64 - {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Debug|x64.Build.0 = Debug|x64 - {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Debug|x64.Deploy.0 = Debug|x64 - {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Debug|x86.ActiveCfg = Debug|x86 - {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Debug|x86.Build.0 = Debug|x86 - {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Debug|x86.Deploy.0 = Debug|x86 - {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Release|Any CPU.ActiveCfg = Release|x86 - {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Release|ARM.ActiveCfg = Release|ARM - {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Release|ARM.Build.0 = Release|ARM - {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Release|ARM.Deploy.0 = Release|ARM - {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Release|x64.ActiveCfg = Release|x64 - {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Release|x64.Build.0 = Release|x64 - {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Release|x64.Deploy.0 = Release|x64 - {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 - 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} - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21} = {100879CC-8910-459E-856E-253D629E45DE} - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1} = {100879CC-8910-459E-856E-253D629E45DE} - {9949326E-9261-4F95-89B1-151F60498951} = {100879CC-8910-459E-856E-253D629E45DE} - {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1} = {100879CC-8910-459E-856E-253D629E45DE} - EndGlobalSection -EndGlobal diff --git a/MapControl.sln b/MapControl.sln index 542e3931..49a24d8c 100644 --- a/MapControl.sln +++ b/MapControl.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.31101.0 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileDbCache.WinRT", "Caching\FileDbCache.WinRT\FileDbCache.WinRT.csproj", "{C7BF2B18-CC74-430B-BCB2-600304EFA3D8}" EndProject @@ -17,78 +17,210 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapControl.WinRT", "MapCont 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}") = "PhoneApplication", "SampleApps\PhoneApplication\PhoneApplication.csproj", "{8D0A57DF-FABF-4AEE-8768-9C18B2B43CA9}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SilverlightApplication", "SampleApps\SilverlightApplication\SilverlightApplication.csproj", "{CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SilverlightApplication.Web", "SampleApps\SilverlightApplication.Web\SilverlightApplication.Web.csproj", "{177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StoreApplication", "SampleApps\StoreApplication\StoreApplication.csproj", "{747A3F84-E11F-4EC8-9463-98BBB1E0D0A4}" -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}" 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}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SilverlightApplication.Web", "SampleApps\SilverlightApplication.Web\SilverlightApplication.Web.csproj", "{7FB616E1-E0D4-48FA-8AFD-60E73FCF32E4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|ARM = Debug|ARM + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|ARM = Release|ARM + Release|x64 = Release|x64 + 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 - {8D0A57DF-FABF-4AEE-8768-9C18B2B43CA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8D0A57DF-FABF-4AEE-8768-9C18B2B43CA9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8D0A57DF-FABF-4AEE-8768-9C18B2B43CA9}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {8D0A57DF-FABF-4AEE-8768-9C18B2B43CA9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8D0A57DF-FABF-4AEE-8768-9C18B2B43CA9}.Release|Any CPU.Build.0 = Release|Any CPU - {8D0A57DF-FABF-4AEE-8768-9C18B2B43CA9}.Release|Any CPU.Deploy.0 = Release|Any CPU - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21}.Release|Any CPU.Build.0 = Release|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1}.Release|Any CPU.Build.0 = Release|Any CPU - {747A3F84-E11F-4EC8-9463-98BBB1E0D0A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {747A3F84-E11F-4EC8-9463-98BBB1E0D0A4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {747A3F84-E11F-4EC8-9463-98BBB1E0D0A4}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {747A3F84-E11F-4EC8-9463-98BBB1E0D0A4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {747A3F84-E11F-4EC8-9463-98BBB1E0D0A4}.Release|Any CPU.Build.0 = Release|Any CPU - {747A3F84-E11F-4EC8-9463-98BBB1E0D0A4}.Release|Any CPU.Deploy.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 + {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 + {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Debug|x64.ActiveCfg = Debug|x64 + {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Debug|x64.Build.0 = Debug|x64 + {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Debug|x64.Deploy.0 = Debug|x64 + {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Debug|x86.ActiveCfg = Debug|x86 + {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Debug|x86.Build.0 = Debug|x86 + {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Debug|x86.Deploy.0 = Debug|x86 + {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Release|Any CPU.ActiveCfg = Release|x86 + {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Release|ARM.ActiveCfg = Release|ARM + {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Release|ARM.Build.0 = Release|ARM + {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Release|ARM.Deploy.0 = Release|ARM + {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Release|x64.ActiveCfg = Release|x64 + {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Release|x64.Build.0 = Release|x64 + {AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}.Release|x64.Deploy.0 = Release|x64 + {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -98,10 +230,9 @@ Global {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} - {8D0A57DF-FABF-4AEE-8768-9C18B2B43CA9} = {100879CC-8910-459E-856E-253D629E45DE} - {CBA8C535-CCA3-4F60-8D3E-0E25791CBD21} = {100879CC-8910-459E-856E-253D629E45DE} - {177C4EF8-0B0A-426E-BDCC-168DC10AC1C1} = {100879CC-8910-459E-856E-253D629E45DE} - {747A3F84-E11F-4EC8-9463-98BBB1E0D0A4} = {100879CC-8910-459E-856E-253D629E45DE} {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} EndGlobalSection EndGlobal diff --git a/MapControl/AzimuthalEquidistantProjection.cs b/MapControl/AzimuthalEquidistantProjection.cs new file mode 100644 index 00000000..96df920f --- /dev/null +++ b/MapControl/AzimuthalEquidistantProjection.cs @@ -0,0 +1,58 @@ +// 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; +#else +using System.Windows; +#endif + +namespace MapControl +{ + /// + /// Transforms map coordinates according to the Azimuthal Equidistant Projection. + /// + public class AzimuthalEquidistantProjection : AzimuthalProjection + { + public AzimuthalEquidistantProjection() + { + // No known standard or de-facto standard CRS ID + } + + public AzimuthalEquidistantProjection(string crsId) + { + CrsId = crsId; + } + + public override Point LocationToPoint(Location location) + { + if (location.Equals(projectionCenter)) + { + return new Point(); + } + + double azimuth, distance; + + GetAzimuthDistance(projectionCenter, location, out azimuth, out distance); + + distance *= Wgs84EquatorialRadius; + + return new Point(distance * Math.Sin(azimuth), distance * Math.Cos(azimuth)); + } + + public override Location PointToLocation(Point point) + { + if (point.X == 0d && point.Y == 0d) + { + return projectionCenter; + } + + var azimuth = Math.Atan2(point.X, point.Y); + var distance = Math.Sqrt(point.X * point.X + point.Y * point.Y) / Wgs84EquatorialRadius; + + return GetLocation(projectionCenter, azimuth, distance); + } + } +} diff --git a/MapControl/AzimuthalProjection.cs b/MapControl/AzimuthalProjection.cs new file mode 100644 index 00000000..573bef23 --- /dev/null +++ b/MapControl/AzimuthalProjection.cs @@ -0,0 +1,137 @@ +// 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.Globalization; +#if NETFX_CORE +using Windows.Foundation; +#else +using System.Windows; +#endif + +namespace MapControl +{ + /// + /// Base class for azimuthal map projections. + /// + public abstract class AzimuthalProjection : MapProjection + { + protected Location projectionCenter = new Location(); + + public AzimuthalProjection() + { + IsAzimuthal = true; + LongitudeScale = double.NaN; + } + + public override double GetViewportScale(double zoomLevel) + { + return base.GetViewportScale(zoomLevel) / MetersPerDegree; + } + + public override Point GetMapScale(Location location) + { + return new Point(ViewportScale, ViewportScale); + } + + public override Location TranslateLocation(Location location, Point translation) + { + var scaleY = ViewportScale * MetersPerDegree; + var scaleX = scaleY * Math.Cos(location.Latitude * Math.PI / 180d); + + return new Location( + location.Latitude - translation.Y / scaleY, + location.Longitude + translation.X / scaleX); + } + + public override Rect BoundingBoxToRect(BoundingBox boundingBox) + { + var cbbox = boundingBox as CenteredBoundingBox; + + if (cbbox != null) + { + var center = LocationToPoint(cbbox.Center); + + return new Rect( + center.X - cbbox.Width / 2d, center.Y - cbbox.Height / 2d, + cbbox.Width, cbbox.Height); + } + + return base.BoundingBoxToRect(boundingBox); + } + + public override BoundingBox RectToBoundingBox(Rect rect) + { + var center = PointToLocation(new Point(rect.X + rect.Width / 2d, rect.Y + rect.Height / 2d)); + + return new CenteredBoundingBox(center, rect.Width, rect.Height); // width and height in meters + } + + public override void SetViewportTransform(Location projectionCenter, Location mapCenter, Point viewportCenter, double zoomLevel, double heading) + { + this.projectionCenter = projectionCenter; + + base.SetViewportTransform(projectionCenter, mapCenter, viewportCenter, zoomLevel, heading); + } + + public override string WmsQueryParameters(BoundingBox boundingBox, string version) + { + if (string.IsNullOrEmpty(CrsId)) + { + return null; + } + + var rect = BoundingBoxToRect(boundingBox); + var width = (int)Math.Round(ViewportScale * rect.Width); + var height = (int)Math.Round(ViewportScale * rect.Height); + var crs = version.StartsWith("1.1.") ? "SRS" : "CRS"; + + return string.Format(CultureInfo.InvariantCulture, + "{0}={1},1,{2},{3}&BBOX={4},{5},{6},{7}&WIDTH={8}&HEIGHT={9}", + crs, CrsId, projectionCenter.Longitude, projectionCenter.Latitude, + rect.X, rect.Y, (rect.X + rect.Width), (rect.Y + rect.Height), width, height); + } + + /// + /// Calculates azimuth and distance in radians from location1 to location2. + /// The returned distance has to be multiplied with an appropriate earth radius. + /// + public static void GetAzimuthDistance(Location location1, Location location2, out double azimuth, out double distance) + { + var lat1 = location1.Latitude * Math.PI / 180d; + var lon1 = location1.Longitude * Math.PI / 180d; + var lat2 = location2.Latitude * Math.PI / 180d; + var lon2 = location2.Longitude * Math.PI / 180d; + var cosLat1 = Math.Cos(lat1); + var sinLat1 = Math.Sin(lat1); + var cosLat2 = Math.Cos(lat2); + var sinLat2 = Math.Sin(lat2); + var cosLon12 = Math.Cos(lon2 - lon1); + var sinLon12 = Math.Sin(lon2 - lon1); + var cosDistance = sinLat1 * sinLat2 + cosLat1 * cosLat2 * cosLon12; + + azimuth = Math.Atan2(sinLon12, cosLat1 * sinLat2 / cosLat2 - sinLat1 * cosLon12); + distance = Math.Acos(Math.Max(Math.Min(cosDistance, 1d), -1d)); + } + + /// + /// Calculates the Location of the point given by azimuth and distance in radians from location. + /// + public static Location GetLocation(Location location, double azimuth, double distance) + { + var lat1 = location.Latitude * Math.PI / 180d; + var sinDistance = Math.Sin(distance); + var cosDistance = Math.Cos(distance); + var cosAzimuth = Math.Cos(azimuth); + var sinAzimuth = Math.Sin(azimuth); + var cosLat1 = Math.Cos(lat1); + var sinLat1 = Math.Sin(lat1); + var sinLat2 = sinLat1 * cosDistance + cosLat1 * sinDistance * cosAzimuth; + var lat2 = Math.Asin(Math.Max(Math.Min(sinLat2, 1d), -1d)); + var dLon = Math.Atan2(sinDistance * sinAzimuth, cosLat1 * cosDistance - sinLat1 * sinDistance * cosAzimuth); + + return new Location(180d / Math.PI * lat2, location.Longitude + 180d / Math.PI * dLon); + } + } +} diff --git a/MapControl/BingMapsTileLayer.cs b/MapControl/BingMapsTileLayer.cs index c1bc6f27..9ebaa46d 100644 --- a/MapControl/BingMapsTileLayer.cs +++ b/MapControl/BingMapsTileLayer.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System; @@ -10,9 +10,11 @@ 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 @@ -20,8 +22,10 @@ namespace MapControl { /// /// 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). /// - public class BingMapsTileLayer : TileLayer + public class BingMapsTileLayer : MapTileLayer { public enum MapMode { @@ -45,6 +49,7 @@ namespace MapControl public MapMode Mode { get; set; } public string Culture { get; set; } + public ImageSource LogoImage { get; set; } private void OnLoaded(object sender, RoutedEventArgs e) { @@ -52,13 +57,15 @@ namespace MapControl if (string.IsNullOrEmpty(ApiKey)) { - throw new InvalidOperationException("BingMapsTileLayer requires a Bing Maps API Key."); + 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); - 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); + request.BeginGetResponse(HandleImageryMetadataResponse, request); + } } private void HandleImageryMetadataResponse(IAsyncResult asyncResult) @@ -122,7 +129,7 @@ namespace MapControl if (!string.IsNullOrEmpty(imageUrl) && imageUrlSubdomains != null && imageUrlSubdomains.Length > 0) { - var _ = Dispatcher.BeginInvoke(new Action(() => + var op = Dispatcher.BeginInvoke(new Action(() => { if (string.IsNullOrEmpty(Culture)) { diff --git a/MapControl/BingMapsTileSource.cs b/MapControl/BingMapsTileSource.cs index 44df45ee..69be1948 100644 --- a/MapControl/BingMapsTileSource.cs +++ b/MapControl/BingMapsTileSource.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System; diff --git a/MapControl/ImageLoader.cs b/MapControl/BitmapSourceHelper.cs similarity index 76% rename from MapControl/ImageLoader.cs rename to MapControl/BitmapSourceHelper.cs index 1cb1e889..e43a4b5d 100644 --- a/MapControl/ImageLoader.cs +++ b/MapControl/BitmapSourceHelper.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System; @@ -13,7 +13,7 @@ namespace MapControl /// /// Creates frozen BitmapSources from Stream or Uri. /// - internal static class ImageLoader + public static class BitmapSourceHelper { public static BitmapSource FromStream(Stream stream) { @@ -30,19 +30,16 @@ namespace MapControl public static BitmapSource FromUri(Uri uri) { - BitmapSource bitmap = null; - try { - var request = WebRequest.Create(uri); - - using (var response = request.GetResponse()) + 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); - bitmap = FromStream(memoryStream); + + return FromStream(memoryStream); } } catch (Exception ex) @@ -50,7 +47,7 @@ namespace MapControl Debug.WriteLine(ex.Message); } - return bitmap; + return null; } } } diff --git a/MapControl/BoundingBox.cs b/MapControl/BoundingBox.cs new file mode 100644 index 00000000..906a2e0d --- /dev/null +++ b/MapControl/BoundingBox.cs @@ -0,0 +1,92 @@ +// 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.Globalization; + +namespace MapControl +{ + /// + /// A geographic bounding box with south and north latitude and west and east longitude values in degrees. + /// + public partial class BoundingBox + { + private double south; + private double west; + private double north; + private double east; + + public BoundingBox() + { + } + + public BoundingBox(double south, double west, double north, double east) + { + South = south; + West = west; + North = north; + East = east; + } + + public double South + { + get { return south; } + set { south = Math.Min(Math.Max(value, -90d), 90d); } + } + + public double West + { + get { return west; } + set { west = value; } + } + + public double North + { + get { return north; } + set { north = Math.Min(Math.Max(value, -90d), 90d); } + } + + public double East + { + get { return east; } + set { east = value; } + } + + public virtual double Width + { + get { return east - west; } + } + + public virtual double Height + { + get { return north - south; } + } + + public bool HasValidBounds + { + get { return south < north && west < east; } + } + + public virtual BoundingBox Clone() + { + return new BoundingBox(south, west, north, east); + } + + public static BoundingBox Parse(string s) + { + var values = s.Split(new char[] { ',' }); + + if (values.Length != 4) + { + throw new FormatException("BoundingBox string must be a comma-separated list of four double values"); + } + + return new BoundingBox( + double.Parse(values[0], NumberStyles.Float, CultureInfo.InvariantCulture), + double.Parse(values[1], NumberStyles.Float, CultureInfo.InvariantCulture), + double.Parse(values[2], NumberStyles.Float, CultureInfo.InvariantCulture), + double.Parse(values[3], NumberStyles.Float, CultureInfo.InvariantCulture)); + } + } +} diff --git a/MapControl/BoundingBoxConverter.cs b/MapControl/BoundingBoxConverter.cs new file mode 100644 index 00000000..6c76f1b7 --- /dev/null +++ b/MapControl/BoundingBoxConverter.cs @@ -0,0 +1,31 @@ +// 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 + { + } +} diff --git a/MapControl/CenteredBoundingBox.cs b/MapControl/CenteredBoundingBox.cs new file mode 100644 index 00000000..07cab657 --- /dev/null +++ b/MapControl/CenteredBoundingBox.cs @@ -0,0 +1,40 @@ +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer +// Licensed under the Microsoft Public License (Ms-PL) + +namespace MapControl +{ + public class CenteredBoundingBox : BoundingBox + { + private readonly Location center; + private readonly double width; + private readonly double height; + + public CenteredBoundingBox(Location center, double width, double height) + { + this.center = center; + this.width = width; + this.height = height; + } + + public Location Center + { + get { return center; } + } + + public override double Width + { + get { return width; } + } + + public override double Height + { + get { return height; } + } + + public override BoundingBox Clone() + { + return new CenteredBoundingBox(center, width, height); + } + } +} diff --git a/MapControl/EquirectangularProjection.cs b/MapControl/EquirectangularProjection.cs new file mode 100644 index 00000000..ac100a71 --- /dev/null +++ b/MapControl/EquirectangularProjection.cs @@ -0,0 +1,54 @@ +// 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; +#else +using System.Windows; +#endif + +namespace MapControl +{ + /// + /// Transforms map coordinates according to the Equirectangular Projection. + /// Longitude and Latitude values are transformed identically to X and Y. + /// + public class EquirectangularProjection : MapProjection + { + public EquirectangularProjection() + : this("EPSG:4326") + { + } + + public EquirectangularProjection(string crsId) + { + CrsId = crsId; + } + + public override Point GetMapScale(Location location) + { + return new Point( + ViewportScale / (MetersPerDegree * Math.Cos(location.Latitude * Math.PI / 180d)), + ViewportScale / MetersPerDegree); + } + + public override Point LocationToPoint(Location location) + { + return new Point(location.Longitude, location.Latitude); + } + + public override Location PointToLocation(Point point) + { + return new Location(point.Y, point.X); + } + + public override Location TranslateLocation(Location location, Point translation) + { + return new Location( + location.Latitude - translation.Y / ViewportScale, + location.Longitude + translation.X / ViewportScale); + } + } +} diff --git a/MapControl/Extensions.Silverlight.cs b/MapControl/Extensions.Silverlight.cs index f633eeee..eb6352eb 100644 --- a/MapControl/Extensions.Silverlight.cs +++ b/MapControl/Extensions.Silverlight.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System.Windows; diff --git a/MapControl/Extensions.WinRT.cs b/MapControl/Extensions.WinRT.cs index 72bc95c7..b12db969 100644 --- a/MapControl/Extensions.WinRT.cs +++ b/MapControl/Extensions.WinRT.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System; diff --git a/MapControl/GnomonicProjection.cs b/MapControl/GnomonicProjection.cs new file mode 100644 index 00000000..3492f77a --- /dev/null +++ b/MapControl/GnomonicProjection.cs @@ -0,0 +1,61 @@ +// 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; +#else +using System.Windows; +#endif + +namespace MapControl +{ + /// + /// Transforms map coordinates according to the Gnomonic Projection. + /// + public class GnomonicProjection : AzimuthalProjection + { + public GnomonicProjection() + : this("AUTO2:97001") // GeoServer non-standard CRS ID + { + } + + public GnomonicProjection(string crsId) + { + CrsId = crsId; + } + + public override Point LocationToPoint(Location location) + { + if (location.Equals(projectionCenter)) + { + return new Point(); + } + + double azimuth, distance; + + GetAzimuthDistance(projectionCenter, location, out azimuth, out distance); + + var mapDistance = distance < Math.PI / 2d + ? Wgs84EquatorialRadius * Math.Tan(distance) + : double.PositiveInfinity; + + return new Point(mapDistance * Math.Sin(azimuth), mapDistance * Math.Cos(azimuth)); + } + + public override Location PointToLocation(Point point) + { + if (point.X == 0d && point.Y == 0d) + { + return projectionCenter; + } + + var azimuth = Math.Atan2(point.X, point.Y); + var mapDistance = Math.Sqrt(point.X * point.X + point.Y * point.Y); + var distance = Math.Atan(mapDistance / Wgs84EquatorialRadius); + + return GetLocation(projectionCenter, azimuth, distance); + } + } +} diff --git a/MapControl/HyperlinkText.cs b/MapControl/HyperlinkText.cs index dac1d07e..442d56ac 100644 --- a/MapControl/HyperlinkText.cs +++ b/MapControl/HyperlinkText.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System; diff --git a/MapControl/IMapElement.cs b/MapControl/IMapElement.cs deleted file mode 100644 index 4ac2d67e..00000000 --- a/MapControl/IMapElement.cs +++ /dev/null @@ -1,11 +0,0 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer -// Licensed under the Microsoft Public License (Ms-PL) - -namespace MapControl -{ - public interface IMapElement - { - MapBase ParentMap { get; set; } - } -} diff --git a/MapControl/ITileImageLoader.cs b/MapControl/ITileImageLoader.cs deleted file mode 100644 index 3b3404f0..00000000 --- a/MapControl/ITileImageLoader.cs +++ /dev/null @@ -1,14 +0,0 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer -// Licensed under the Microsoft Public License (Ms-PL) - -using System.Collections.Generic; - -namespace MapControl -{ - public interface ITileImageLoader - { - void BeginLoadTiles(TileLayer tileLayer, IEnumerable tiles); - void CancelLoadTiles(TileLayer tileLayer); - } -} diff --git a/MapControl/ImageCache.WinRT.cs b/MapControl/ImageCache.WinRT.cs index 56a77b42..ac2c780e 100644 --- a/MapControl/ImageCache.WinRT.cs +++ b/MapControl/ImageCache.WinRT.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System; diff --git a/MapControl/ImageTileSource.Silverlight.WinRT.cs b/MapControl/ImageTileSource.Silverlight.WinRT.cs index b979f3ee..6c14b103 100644 --- a/MapControl/ImageTileSource.Silverlight.WinRT.cs +++ b/MapControl/ImageTileSource.Silverlight.WinRT.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) #if NETFX_CORE diff --git a/MapControl/ImageTileSource.WPF.cs b/MapControl/ImageTileSource.WPF.cs index b49e0ced..2030b548 100644 --- a/MapControl/ImageTileSource.WPF.cs +++ b/MapControl/ImageTileSource.WPF.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// 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; @@ -28,7 +28,7 @@ namespace MapControl { if (IsAsync) { - image = ImageLoader.FromUri(uri); + image = BitmapSourceHelper.FromUri(uri); } else { diff --git a/MapControl/Location.cs b/MapControl/Location.cs index 2c12a28b..73d8b32a 100644 --- a/MapControl/Location.cs +++ b/MapControl/Location.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System; @@ -62,16 +62,16 @@ namespace MapControl public static Location Parse(string s) { - var pair = s.Split(new char[] { ',' }); + var values = s.Split(new char[] { ',' }); - if (pair.Length != 2) + if (values.Length != 2) { throw new FormatException("Location string must be a comma-separated pair of double values"); } return new Location( - double.Parse(pair[0], NumberStyles.Float, CultureInfo.InvariantCulture), - double.Parse(pair[1], NumberStyles.Float, CultureInfo.InvariantCulture)); + double.Parse(values[0], NumberStyles.Float, CultureInfo.InvariantCulture), + double.Parse(values[1], NumberStyles.Float, CultureInfo.InvariantCulture)); } /// diff --git a/MapControl/LocationCollection.cs b/MapControl/LocationCollection.cs index 6fd0cfd0..b4f58941 100644 --- a/MapControl/LocationCollection.cs +++ b/MapControl/LocationCollection.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System; @@ -10,7 +10,7 @@ using System.Linq; namespace MapControl { /// - /// A collection of geographic locations. + /// An ObservableCollection of Location with support for parsing. /// public partial class LocationCollection : ObservableCollection { diff --git a/MapControl/LocationCollectionConverter.cs b/MapControl/LocationCollectionConverter.cs index 54682618..8c9874f0 100644 --- a/MapControl/LocationCollectionConverter.cs +++ b/MapControl/LocationCollectionConverter.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System; diff --git a/MapControl/LocationConverter.cs b/MapControl/LocationConverter.cs index 35cd1545..8318df1b 100644 --- a/MapControl/LocationConverter.cs +++ b/MapControl/LocationConverter.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System; diff --git a/MapControl/Map.Silverlight.cs b/MapControl/Map.Silverlight.cs index 413f310c..fc6c3839 100644 --- a/MapControl/Map.Silverlight.cs +++ b/MapControl/Map.Silverlight.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System.Windows; @@ -13,7 +13,7 @@ namespace MapControl public class Map : MapBase { public static readonly DependencyProperty MouseWheelZoomDeltaProperty = DependencyProperty.Register( - "MouseWheelZoomDelta", typeof(double), typeof(Map), new PropertyMetadata(1d)); + nameof(MouseWheelZoomDelta), typeof(double), typeof(Map), new PropertyMetadata(1d)); private Point? mousePosition; diff --git a/MapControl/Map.WPF.cs b/MapControl/Map.WPF.cs index 02dd65a4..2368ade6 100644 --- a/MapControl/Map.WPF.cs +++ b/MapControl/Map.WPF.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System.Windows; @@ -13,10 +13,10 @@ namespace MapControl public class Map : MapBase { public static readonly DependencyProperty ManipulationModeProperty = DependencyProperty.Register( - "ManipulationMode", typeof(ManipulationModes), typeof(Map), new PropertyMetadata(ManipulationModes.All)); + nameof(ManipulationMode), typeof(ManipulationModes), typeof(Map), new PropertyMetadata(ManipulationModes.All)); public static readonly DependencyProperty MouseWheelZoomDeltaProperty = DependencyProperty.Register( - "MouseWheelZoomDelta", typeof(double), typeof(Map), new PropertyMetadata(1d)); + nameof(MouseWheelZoomDelta), typeof(double), typeof(Map), new PropertyMetadata(1d)); private Point? mousePosition; diff --git a/MapControl/Map.WinRT.cs b/MapControl/Map.WinRT.cs index 86a747bb..19d517c1 100644 --- a/MapControl/Map.WinRT.cs +++ b/MapControl/Map.WinRT.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System; @@ -15,7 +15,7 @@ namespace MapControl public class Map : MapBase { public static readonly DependencyProperty MouseWheelZoomDeltaProperty = DependencyProperty.Register( - "MouseWheelZoomDelta", typeof(double), typeof(Map), new PropertyMetadata(1d)); + nameof(MouseWheelZoomDelta), typeof(double), typeof(Map), new PropertyMetadata(1d)); private bool transformPending; private Point transformTranslation; diff --git a/MapControl/MapBase.Silverlight.WinRT.cs b/MapControl/MapBase.Silverlight.WinRT.cs index c0f64af5..3ee6a594 100644 --- a/MapControl/MapBase.Silverlight.WinRT.cs +++ b/MapControl/MapBase.Silverlight.WinRT.cs @@ -1,9 +1,7 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// 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; #if NETFX_CORE using Windows.Foundation; using Windows.UI; @@ -19,36 +17,36 @@ namespace MapControl public partial class MapBase { public static readonly DependencyProperty ForegroundProperty = DependencyProperty.Register( - "Foreground", typeof(Brush), typeof(MapBase), + nameof(Foreground), typeof(Brush), typeof(MapBase), new PropertyMetadata(new SolidColorBrush(Colors.Black))); public static readonly DependencyProperty CenterProperty = DependencyProperty.Register( - "Center", typeof(Location), typeof(MapBase), + nameof(Center), typeof(Location), typeof(MapBase), new PropertyMetadata(new Location(), (o, e) => ((MapBase)o).CenterPropertyChanged((Location)e.NewValue))); public static readonly DependencyProperty TargetCenterProperty = DependencyProperty.Register( - "TargetCenter", typeof(Location), typeof(MapBase), + nameof(TargetCenter), typeof(Location), typeof(MapBase), new PropertyMetadata(new Location(), (o, e) => ((MapBase)o).TargetCenterPropertyChanged((Location)e.NewValue))); public static readonly DependencyProperty ZoomLevelProperty = DependencyProperty.Register( - "ZoomLevel", typeof(double), typeof(MapBase), + nameof(ZoomLevel), typeof(double), typeof(MapBase), new PropertyMetadata(1d, (o, e) => ((MapBase)o).ZoomLevelPropertyChanged((double)e.NewValue))); public static readonly DependencyProperty TargetZoomLevelProperty = DependencyProperty.Register( - "TargetZoomLevel", typeof(double), typeof(MapBase), + nameof(TargetZoomLevel), typeof(double), typeof(MapBase), new PropertyMetadata(1d, (o, e) => ((MapBase)o).TargetZoomLevelPropertyChanged((double)e.NewValue))); public static readonly DependencyProperty HeadingProperty = DependencyProperty.Register( - "Heading", typeof(double), typeof(MapBase), + nameof(Heading), typeof(double), typeof(MapBase), new PropertyMetadata(0d, (o, e) => ((MapBase)o).HeadingPropertyChanged((double)e.NewValue))); public static readonly DependencyProperty TargetHeadingProperty = DependencyProperty.Register( - "TargetHeading", typeof(double), typeof(MapBase), + nameof(TargetHeading), typeof(double), typeof(MapBase), new PropertyMetadata(0d, (o, e) => ((MapBase)o).TargetHeadingPropertyChanged((double)e.NewValue))); partial void Initialize() { - // set Background by Style to enable resetting by ClearValue in RemoveTileLayers + // set Background by Style to enable resetting by ClearValue in MapLayerPropertyChanged var style = new Style(typeof(MapBase)); style.Setters.Add(new Setter(BackgroundProperty, new SolidColorBrush(Colors.Transparent))); Style = style; @@ -62,28 +60,10 @@ namespace MapControl { clip.Rect = new Rect(0d, 0d, e.NewSize.Width, e.NewSize.Height); - ResetTransformOrigin(); + ResetTransformCenter(); UpdateTransform(); } }; } - - private void SetViewportTransform(Location origin) - { - MapOrigin = mapTransform.Transform(origin); - ViewportScale = Math.Pow(2d, ZoomLevel) * TileSource.TileSize / 360d; - - var transform = new Matrix(1d, 0d, 0d, 1d, -MapOrigin.X, -MapOrigin.Y) - .Rotate(-Heading) - .Scale(ViewportScale, -ViewportScale) - .Translate(ViewportOrigin.X, ViewportOrigin.Y); - - viewportTransform.Matrix = transform; - } - - private void SetTileLayer(TileLayer tileLayer) - { - TileLayer = tileLayer; - } } } diff --git a/MapControl/MapBase.WPF.cs b/MapControl/MapBase.WPF.cs index 64b48c4d..b21702a0 100644 --- a/MapControl/MapBase.WPF.cs +++ b/MapControl/MapBase.WPF.cs @@ -1,8 +1,7 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// 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; using System.Windows.Controls; using System.Windows.Media; @@ -15,42 +14,39 @@ namespace MapControl Control.ForegroundProperty.AddOwner(typeof(MapBase)); public static readonly DependencyProperty CenterProperty = DependencyProperty.Register( - "Center", typeof(Location), typeof(MapBase), new FrameworkPropertyMetadata( + nameof(Center), typeof(Location), typeof(MapBase), new FrameworkPropertyMetadata( new Location(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (o, e) => ((MapBase)o).CenterPropertyChanged((Location)e.NewValue))); public static readonly DependencyProperty TargetCenterProperty = DependencyProperty.Register( - "TargetCenter", typeof(Location), typeof(MapBase), new FrameworkPropertyMetadata( + nameof(TargetCenter), typeof(Location), typeof(MapBase), new FrameworkPropertyMetadata( new Location(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (o, e) => ((MapBase)o).TargetCenterPropertyChanged((Location)e.NewValue))); public static readonly DependencyProperty ZoomLevelProperty = DependencyProperty.Register( - "ZoomLevel", typeof(double), typeof(MapBase), new FrameworkPropertyMetadata( + nameof(ZoomLevel), typeof(double), typeof(MapBase), new FrameworkPropertyMetadata( 1d, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (o, e) => ((MapBase)o).ZoomLevelPropertyChanged((double)e.NewValue))); public static readonly DependencyProperty TargetZoomLevelProperty = DependencyProperty.Register( - "TargetZoomLevel", typeof(double), typeof(MapBase), new FrameworkPropertyMetadata( + nameof(TargetZoomLevel), typeof(double), typeof(MapBase), new FrameworkPropertyMetadata( 1d, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (o, e) => ((MapBase)o).TargetZoomLevelPropertyChanged((double)e.NewValue))); public static readonly DependencyProperty HeadingProperty = DependencyProperty.Register( - "Heading", typeof(double), typeof(MapBase), new FrameworkPropertyMetadata( + nameof(Heading), typeof(double), typeof(MapBase), new FrameworkPropertyMetadata( 0d, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (o, e) => ((MapBase)o).HeadingPropertyChanged((double)e.NewValue))); public static readonly DependencyProperty TargetHeadingProperty = DependencyProperty.Register( - "TargetHeading", typeof(double), typeof(MapBase), new FrameworkPropertyMetadata( + nameof(TargetHeading), typeof(double), typeof(MapBase), new FrameworkPropertyMetadata( 0d, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (o, e) => ((MapBase)o).TargetHeadingPropertyChanged((double)e.NewValue))); static MapBase() { - ClipToBoundsProperty.OverrideMetadata( - typeof(MapBase), new FrameworkPropertyMetadata(true)); - - BackgroundProperty.OverrideMetadata( - typeof(MapBase), new FrameworkPropertyMetadata(Brushes.Transparent)); + ClipToBoundsProperty.OverrideMetadata(typeof(MapBase), new FrameworkPropertyMetadata(true)); + BackgroundProperty.OverrideMetadata(typeof(MapBase), new FrameworkPropertyMetadata(Brushes.Transparent)); } partial void RemoveAnimation(DependencyProperty property) @@ -69,37 +65,19 @@ namespace MapControl /// /// Changes the Center, Heading and ZoomLevel properties according to the specified /// viewport coordinate translation, rotation and scale delta values. Rotation and scaling - /// is performed relative to the specified origin point in viewport coordinates. + /// is performed relative to the specified center point in viewport coordinates. /// - public void TransformMap(Point origin, Vector translation, double rotation, double scale) + public void TransformMap(Point center, Vector translation, double rotation, double scale) { - TransformMap(origin, (Point)translation, rotation, scale); + TransformMap(center, (Point)translation, rotation, scale); } protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) { base.OnRenderSizeChanged(sizeInfo); - ResetTransformOrigin(); + ResetTransformCenter(); UpdateTransform(); } - - private void SetViewportTransform(Location origin) - { - MapOrigin = mapTransform.Transform(origin); - ViewportScale = Math.Pow(2d, ZoomLevel) * TileSource.TileSize / 360d; - - var transform = new Matrix(1d, 0d, 0d, 1d, -MapOrigin.X, -MapOrigin.Y); - transform.Rotate(-Heading); - transform.Scale(ViewportScale, -ViewportScale); - transform.Translate(ViewportOrigin.X, ViewportOrigin.Y); - - viewportTransform.Matrix = transform; - } - - private void SetTileLayer(TileLayer tileLayer) - { - SetCurrentValue(TileLayerProperty, tileLayer); - } } } diff --git a/MapControl/MapBase.cs b/MapControl/MapBase.cs index d9ec0d5c..b0bfe14c 100644 --- a/MapControl/MapBase.cs +++ b/MapControl/MapBase.cs @@ -1,12 +1,8 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// 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.Collections.ObjectModel; -using System.Collections.Specialized; -using System.Linq; #if NETFX_CORE using Windows.Foundation; using Windows.UI.Xaml; @@ -20,8 +16,14 @@ using System.Windows.Media.Animation; namespace MapControl { + public interface IMapLayer : IMapElement + { + Brush MapBackground { get; } + Brush MapForeground { get; } + } + /// - /// The map control. Displays map content provided by the TileLayer or TileLayers property. + /// The map control. Displays map content provided by one or more MapTileLayers or MapImageLayers. /// The visible map area is defined by the Center and ZoomLevel properties. /// The map can be rotated by an angle that is given by the Heading property. /// MapBase can contain map overlay child elements like other MapPanels or MapItemsControls. @@ -30,60 +32,57 @@ namespace MapControl { private const double MaximumZoomLevel = 22d; - public static readonly DependencyProperty TileLayerProperty = DependencyProperty.Register( - "TileLayer", typeof(TileLayer), typeof(MapBase), - new PropertyMetadata(null, (o, e) => ((MapBase)o).TileLayerPropertyChanged((TileLayer)e.NewValue))); + public static readonly DependencyProperty MapLayerProperty = DependencyProperty.Register( + nameof(MapLayer), typeof(UIElement), typeof(MapBase), + new PropertyMetadata(null, (o, e) => ((MapBase)o).MapLayerPropertyChanged((UIElement)e.OldValue, (UIElement)e.NewValue))); - public static readonly DependencyProperty TileLayersProperty = DependencyProperty.Register( - "TileLayers", typeof(IList), typeof(MapBase), - new PropertyMetadata(null, (o, e) => ((MapBase)o).TileLayersPropertyChanged((IList)e.OldValue, (IList)e.NewValue))); + public static readonly DependencyProperty MapProjectionProperty = DependencyProperty.Register( + nameof(MapProjection), typeof(MapProjection), typeof(MapBase), + new PropertyMetadata(null, (o, e) => ((MapBase)o).MapProjectionPropertyChanged())); + + public static readonly DependencyProperty ProjectionCenterProperty = DependencyProperty.Register( + nameof(ProjectionCenter), typeof(Location), typeof(MapBase), + new PropertyMetadata(null, (o, e) => ((MapBase)o).ProjectionCenterPropertyChanged())); public static readonly DependencyProperty MinZoomLevelProperty = DependencyProperty.Register( - "MinZoomLevel", typeof(double), typeof(MapBase), + nameof(MinZoomLevel), typeof(double), typeof(MapBase), new PropertyMetadata(1d, (o, e) => ((MapBase)o).MinZoomLevelPropertyChanged((double)e.NewValue))); public static readonly DependencyProperty MaxZoomLevelProperty = DependencyProperty.Register( - "MaxZoomLevel", typeof(double), typeof(MapBase), + nameof(MaxZoomLevel), typeof(double), typeof(MapBase), new PropertyMetadata(19d, (o, e) => ((MapBase)o).MaxZoomLevelPropertyChanged((double)e.NewValue))); public static readonly DependencyProperty AnimationDurationProperty = DependencyProperty.Register( - "AnimationDuration", typeof(TimeSpan), typeof(MapBase), + nameof(AnimationDuration), typeof(TimeSpan), typeof(MapBase), new PropertyMetadata(TimeSpan.FromSeconds(0.3))); public static readonly DependencyProperty AnimationEasingFunctionProperty = DependencyProperty.Register( - "AnimationEasingFunction", typeof(EasingFunctionBase), typeof(MapBase), + nameof(AnimationEasingFunction), typeof(EasingFunctionBase), typeof(MapBase), new PropertyMetadata(new QuadraticEase { EasingMode = EasingMode.EaseOut })); public static readonly DependencyProperty TileFadeDurationProperty = DependencyProperty.Register( - "TileFadeDuration", typeof(TimeSpan), typeof(MapBase), + nameof(TileFadeDuration), typeof(TimeSpan), typeof(MapBase), new PropertyMetadata(Tile.FadeDuration, (o, e) => Tile.FadeDuration = (TimeSpan)e.NewValue)); internal static readonly DependencyProperty CenterPointProperty = DependencyProperty.Register( "CenterPoint", typeof(Point), typeof(MapBase), new PropertyMetadata(new Point(), (o, e) => ((MapBase)o).CenterPointPropertyChanged((Point)e.NewValue))); - private readonly PanelBase tileLayerPanel = new PanelBase(); - private readonly MapTransform mapTransform = new MercatorTransform(); - private readonly MatrixTransform viewportTransform = new MatrixTransform(); - private readonly ScaleTransform scaleTransform = new ScaleTransform(); - private readonly RotateTransform rotateTransform = new RotateTransform(); - private readonly TransformGroup scaleRotateTransform = new TransformGroup(); - - private Location transformOrigin; private PointAnimation centerAnimation; private DoubleAnimation zoomLevelAnimation; private DoubleAnimation headingAnimation; + private Location transformCenter; + private Point viewportCenter; + private double centerLongitude; private bool internalPropertyChange; public MapBase() { Initialize(); - scaleRotateTransform.Children.Add(scaleTransform); - scaleRotateTransform.Children.Add(rotateTransform); - - Children.Add(tileLayerPanel); - TileLayers = new ObservableCollection(); + MapProjection = new WebMercatorProjection(); + ScaleRotateTransform.Children.Add(ScaleTransform); + ScaleRotateTransform.Children.Add(RotateTransform); } partial void Initialize(); // Windows Runtime and Silverlight only @@ -104,27 +103,37 @@ namespace MapControl } /// - /// Gets or sets the base TileLayer used by the Map control. + /// Gets or sets the base map layer, which is added as first element to the Children collection. + /// If the layer implements IMapLayer (like MapTileLayer or MapImageLayer), its (non-null) MapBackground + /// and MapForeground property values are used for the MapBase Background and Foreground properties. /// - public TileLayer TileLayer + public UIElement MapLayer { - get { return (TileLayer)GetValue(TileLayerProperty); } - set { SetValue(TileLayerProperty, value); } + get { return (UIElement)GetValue(MapLayerProperty); } + set { SetValue(MapLayerProperty, value); } } /// - /// Gets or sets optional multiple TileLayers that are used simultaneously. - /// The first element in the collection is equal to the value of the TileLayer - /// property. The additional TileLayers usually have transparent backgrounds. + /// Gets or sets the MapProjection used by the map control. /// - public IList TileLayers + public MapProjection MapProjection { - get { return (IList)GetValue(TileLayersProperty); } - set { SetValue(TileLayersProperty, value); } + get { return (MapProjection)GetValue(MapProjectionProperty); } + set { SetValue(MapProjectionProperty, value); } } /// - /// Gets or sets the location of the center point of the Map. + /// Gets or sets an optional center (reference point) for azimuthal projections. + /// If ProjectionCenter is null, the Center property value will be used instead. + /// + public Location ProjectionCenter + { + get { return (Location)GetValue(ProjectionCenterProperty); } + set { SetValue(ProjectionCenterProperty, value); } + } + + /// + /// Gets or sets the location of the center point of the map. /// public Location Center { @@ -229,111 +238,54 @@ namespace MapControl set { SetValue(TileFadeDurationProperty, value); } } - /// - /// Gets the transformation from geographic coordinates to cartesian map coordinates. - /// - public MapTransform MapTransform - { - get { return mapTransform; } - } - - /// - /// Gets the transformation from cartesian map coordinates to viewport coordinates (i.e. pixels). - /// - public MatrixTransform ViewportTransform - { - get { return viewportTransform; } - } - /// /// Gets the scaling transformation from meters to viewport coordinate units at the Center location. /// - public ScaleTransform ScaleTransform - { - get { return scaleTransform; } - } + public ScaleTransform ScaleTransform { get; } = new ScaleTransform(); /// /// Gets the transformation that rotates by the value of the Heading property. /// - public RotateTransform RotateTransform - { - get { return rotateTransform; } - } + public RotateTransform RotateTransform { get; } = new RotateTransform(); /// /// Gets the combination of ScaleTransform and RotateTransform /// - public TransformGroup ScaleRotateTransform - { - get { return scaleRotateTransform; } - } - - internal Point MapOrigin { get; private set; } - internal Point ViewportOrigin { get; private set; } + public TransformGroup ScaleRotateTransform { get; } = new TransformGroup(); /// - /// Gets the scaling factor from cartesian map coordinates to viewport coordinates. - /// - public double ViewportScale { get; private set; } - - /// - /// Gets the scaling factor from meters to viewport coordinate units at the Center location (px/m). - /// - public double CenterScale { get; private set; } - - /// - /// Gets the map scale at the specified location as viewport coordinate units per meter (px/m). - /// - public double GetMapScale(Location location) - { - return mapTransform.RelativeScale(location) * - Math.Pow(2d, ZoomLevel) * TileSource.TileSize / (TileSource.MetersPerDegree * 360d); - } - - /// - /// Transforms a geographic location to a viewport coordinates point. + /// Transforms a Location in geographic coordinates to a Point in viewport coordinates. /// public Point LocationToViewportPoint(Location location) { - return viewportTransform.Transform(mapTransform.Transform(location)); + return MapProjection.LocationToViewportPoint(location); } /// - /// Transforms a viewport coordinates point to a geographic location. + /// Transforms a Point in viewport coordinates to a Location in geographic coordinates. /// public Location ViewportPointToLocation(Point point) { - return mapTransform.Transform(viewportTransform.Inverse.Transform(point)); + return MapProjection.ViewportPointToLocation(point); } /// - /// Sets a temporary origin location in geographic coordinates for scaling and rotation transformations. - /// This origin location is automatically reset when the Center property is set by application code. + /// Sets a temporary center point in viewport coordinates for scaling and rotation transformations. + /// This center point is automatically reset when the Center property is set by application code. /// - public void SetTransformOrigin(Location origin) + public void SetTransformCenter(Point center) { - transformOrigin = origin; - ViewportOrigin = LocationToViewportPoint(origin); + transformCenter = MapProjection.ViewportPointToLocation(center); + viewportCenter = center; } /// - /// Sets a temporary origin point in viewport coordinates for scaling and rotation transformations. - /// This origin point is automatically reset when the Center property is set by application code. + /// Resets the temporary transform center point set by SetTransformCenter. /// - public void SetTransformOrigin(Point origin) + public void ResetTransformCenter() { - transformOrigin = ViewportPointToLocation(origin); - ViewportOrigin = origin; - } - - /// - /// Resets the temporary transform origin point set by SetTransformOrigin. - /// - public void ResetTransformOrigin() - { - transformOrigin = null; - ViewportOrigin = new Point(RenderSize.Width / 2d, RenderSize.Height / 2d); + transformCenter = null; + viewportCenter = new Point(RenderSize.Width / 2d, RenderSize.Height / 2d); } /// @@ -341,9 +293,9 @@ namespace MapControl /// public void TranslateMap(Point translation) { - if (transformOrigin != null) + if (transformCenter != null) { - ResetTransformOrigin(); + ResetTransformCenter(); UpdateTransform(); } @@ -359,24 +311,24 @@ namespace MapControl translation.Y * cos - translation.X * sin); } - translation.X /= -ViewportScale; - translation.Y /= ViewportScale; + translation.X = -translation.X; + translation.Y = -translation.Y; - Center = mapTransform.Transform(Center, MapOrigin, translation); + Center = MapProjection.TranslateLocation(Center, translation); } } /// /// Changes the Center, Heading and ZoomLevel properties according to the specified /// viewport coordinate translation, rotation and scale delta values. Rotation and scaling - /// is performed relative to the specified origin point in viewport coordinates. + /// is performed relative to the specified center point in viewport coordinates. /// - public void TransformMap(Point origin, Point translation, double rotation, double scale) + public void TransformMap(Point center, Point translation, double rotation, double scale) { if (rotation != 0d || scale != 1d) { - transformOrigin = ViewportPointToLocation(origin); - ViewportOrigin = new Point(origin.X + translation.X, origin.Y + translation.Y); + transformCenter = MapProjection.ViewportPointToLocation(center); + viewportCenter = new Point(center.X + translation.X, center.Y + translation.Y); if (rotation != 0d) { @@ -401,175 +353,104 @@ namespace MapControl } /// - /// Sets the value of the TargetZoomLevel property while retaining the specified origin point + /// Sets the value of the TargetZoomLevel property while retaining the specified center point /// in viewport coordinates. /// - public void ZoomMap(Point origin, double zoomLevel) + public void ZoomMap(Point center, double zoomLevel) { zoomLevel = Math.Min(Math.Max(zoomLevel, MinZoomLevel), MaxZoomLevel); if (TargetZoomLevel != zoomLevel) { - SetTransformOrigin(origin); - TargetZoomLevel = zoomLevel; + SetTransformCenter(center); + + if (double.IsNaN(MapProjection.LongitudeScale)) + { + ZoomLevel = zoomLevel; + } + else + { + TargetZoomLevel = zoomLevel; + } } } /// - /// Sets the TargetZoomLevel and TargetCenter properties such that the specified bounding box + /// Sets the TargetZoomLevel and TargetCenter properties so that the specified bounding box /// fits into the current viewport. The TargetHeading property is set to zero. /// - public void ZoomToBounds(Location southWest, Location northEast) + public void ZoomToBounds(BoundingBox boundingBox) { - if (southWest.Latitude < northEast.Latitude && southWest.Longitude < northEast.Longitude) + if (boundingBox != null && boundingBox.HasValidBounds) { - var p1 = mapTransform.Transform(southWest); - var p2 = mapTransform.Transform(northEast); - var lonScale = RenderSize.Width / (p2.X - p1.X) * 360d / TileSource.TileSize; - var latScale = RenderSize.Height / (p2.Y - p1.Y) * 360d / TileSource.TileSize; + var rect = MapProjection.BoundingBoxToRect(boundingBox); + var center = new Point(rect.X + rect.Width / 2d, rect.Y + rect.Height / 2d); + var scale0 = 1d / MapProjection.GetViewportScale(0d); + var lonScale = scale0 * RenderSize.Width / rect.Width; + var latScale = scale0 * RenderSize.Height / rect.Height; var lonZoom = Math.Log(lonScale, 2d); var latZoom = Math.Log(latScale, 2d); TargetZoomLevel = Math.Min(lonZoom, latZoom); - TargetCenter = mapTransform.Transform(new Point((p1.X + p2.X) / 2d, (p1.Y + p2.Y) / 2d)); + TargetCenter = MapProjection.PointToLocation(center); TargetHeading = 0d; } } - private void TileLayerPropertyChanged(TileLayer tileLayer) + private void MapLayerPropertyChanged(UIElement oldLayer, UIElement newLayer) { - if (tileLayer != null) + if (oldLayer != null) { - if (TileLayers == null) + Children.Remove(oldLayer); + + var mapLayer = oldLayer as IMapLayer; + if (mapLayer != null) { - TileLayers = new ObservableCollection(new TileLayer[] { tileLayer }); - } - else if (TileLayers.Count == 0) - { - TileLayers.Add(tileLayer); - } - else if (TileLayers[0] != tileLayer) - { - TileLayers[0] = tileLayer; - } - } - } - - private void TileLayersPropertyChanged(IList oldTileLayers, IList newTileLayers) - { - if (oldTileLayers != null) - { - var oldCollection = oldTileLayers as INotifyCollectionChanged; - if (oldCollection != null) - { - oldCollection.CollectionChanged -= TileLayerCollectionChanged; - } - - SetTileLayer(null); - ClearTileLayers(); - } - - if (newTileLayers != null) - { - SetTileLayer(newTileLayers.FirstOrDefault()); - AddTileLayers(0, newTileLayers); - - var newCollection = newTileLayers as INotifyCollectionChanged; - if (newCollection != null) - { - newCollection.CollectionChanged += TileLayerCollectionChanged; - } - } - } - - private void TileLayerCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) - { - switch (e.Action) - { - case NotifyCollectionChangedAction.Add: - AddTileLayers(e.NewStartingIndex, e.NewItems.Cast()); - break; - - case NotifyCollectionChangedAction.Remove: - RemoveTileLayers(e.OldStartingIndex, e.OldItems.Count); - break; -#if !SILVERLIGHT - case NotifyCollectionChangedAction.Move: -#endif - case NotifyCollectionChangedAction.Replace: - RemoveTileLayers(e.NewStartingIndex, e.OldItems.Count); - AddTileLayers(e.NewStartingIndex, e.NewItems.Cast()); - break; - - case NotifyCollectionChangedAction.Reset: - ClearTileLayers(); - if (e.NewItems != null) + if (mapLayer.MapBackground != null) { - AddTileLayers(0, e.NewItems.Cast()); + ClearValue(BackgroundProperty); } - break; - - default: - break; - } - - var tileLayer = TileLayers.FirstOrDefault(); - - if (TileLayer != tileLayer) - { - SetTileLayer(tileLayer); - } - } - - private void AddTileLayers(int index, IEnumerable tileLayers) - { - foreach (var tileLayer in tileLayers) - { - if (index == 0) - { - if (tileLayer.Background != null) + if (mapLayer.MapForeground != null) { - Background = tileLayer.Background; - } - - if (tileLayer.Foreground != null) - { - Foreground = tileLayer.Foreground; + ClearValue(ForegroundProperty); } } - - tileLayerPanel.Children.Insert(index++, tileLayer); } - } - private void RemoveTileLayers(int index, int count) - { - while (count-- > 0) + if (newLayer != null) { - tileLayerPanel.Children.RemoveAt(index + count); - } + Children.Insert(0, newLayer); - if (index == 0) + var mapLayer = newLayer as IMapLayer; + if (mapLayer != null) + { + if (mapLayer.MapBackground != null) + { + Background = mapLayer.MapBackground; + } + if (mapLayer.MapForeground != null) + { + Foreground = mapLayer.MapForeground; + } + } + } + } + + private void MapProjectionPropertyChanged() + { + ResetTransformCenter(); + UpdateTransform(false, true); + } + + private void ProjectionCenterPropertyChanged() + { + if (MapProjection.IsAzimuthal) { - ClearValue(BackgroundProperty); - ClearValue(ForegroundProperty); + ResetTransformCenter(); + UpdateTransform(); } } - private void ClearTileLayers() - { - tileLayerPanel.Children.Clear(); - ClearValue(BackgroundProperty); - ClearValue(ForegroundProperty); - } - - private void InternalSetValue(DependencyProperty property, object value) - { - internalPropertyChange = true; - SetValue(property, value); - internalPropertyChange = false; - } - private void AdjustCenterProperty(DependencyProperty property, ref Location center) { if (center == null) @@ -578,10 +459,10 @@ namespace MapControl InternalSetValue(property, center); } else if (center.Longitude < -180d || center.Longitude > 180d || - center.Latitude < -mapTransform.MaxLatitude || center.Latitude > mapTransform.MaxLatitude) + center.Latitude < -MapProjection.MaxLatitude || center.Latitude > MapProjection.MaxLatitude) { center = new Location( - Math.Min(Math.Max(center.Latitude, -mapTransform.MaxLatitude), mapTransform.MaxLatitude), + Math.Min(Math.Max(center.Latitude, -MapProjection.MaxLatitude), MapProjection.MaxLatitude), Location.NormalizeLongitude(center.Longitude)); InternalSetValue(property, center); } @@ -597,7 +478,7 @@ namespace MapControl if (centerAnimation == null) { InternalSetValue(TargetCenterProperty, center); - InternalSetValue(CenterPointProperty, mapTransform.Transform(center)); + InternalSetValue(CenterPointProperty, MapProjection.LocationToPoint(center)); } } } @@ -618,8 +499,8 @@ namespace MapControl // animate private CenterPoint property by PointAnimation centerAnimation = new PointAnimation { - From = mapTransform.Transform(Center), - To = mapTransform.Transform(new Location( + From = MapProjection.LocationToPoint(Center), + To = MapProjection.LocationToPoint(new Location( targetCenter.Latitude, Location.NearestLongitude(targetCenter.Longitude, Center.Longitude))), Duration = AnimationDuration, @@ -640,7 +521,7 @@ namespace MapControl centerAnimation = null; InternalSetValue(CenterProperty, TargetCenter); - InternalSetValue(CenterPointProperty, mapTransform.Transform(TargetCenter)); + InternalSetValue(CenterPointProperty, MapProjection.LocationToPoint(TargetCenter)); RemoveAnimation(CenterPointProperty); // remove holding animation in WPF UpdateTransform(); } @@ -650,8 +531,10 @@ namespace MapControl { if (!internalPropertyChange) { - centerPoint.X = Location.NormalizeLongitude(centerPoint.X); - InternalSetValue(CenterProperty, mapTransform.Transform(centerPoint)); + var center = MapProjection.PointToLocation(centerPoint); + center.Longitude = Location.NormalizeLongitude(center.Longitude); + + InternalSetValue(CenterProperty, center); UpdateTransform(); } } @@ -742,6 +625,7 @@ namespace MapControl InternalSetValue(ZoomLevelProperty, TargetZoomLevel); RemoveAnimation(ZoomLevelProperty); // remove holding animation in WPF + UpdateTransform(true); } } @@ -819,22 +703,29 @@ namespace MapControl } } - private void UpdateTransform(bool resetOrigin = false) + private void InternalSetValue(DependencyProperty property, object value) { - var mapOriginX = MapOrigin.X; - var center = transformOrigin ?? Center; + internalPropertyChange = true; + SetValue(property, value); + internalPropertyChange = false; + } - SetViewportTransform(center); + private void UpdateTransform(bool resetTransformCenter = false, bool projectionChanged = false) + { + var projection = MapProjection; + var center = transformCenter ?? Center; - if (transformOrigin != null) + projection.SetViewportTransform(ProjectionCenter ?? Center, center, viewportCenter, ZoomLevel, Heading); + + if (transformCenter != null) { - center = ViewportPointToLocation(new Point(RenderSize.Width / 2d, RenderSize.Height / 2d)); + center = projection.ViewportPointToLocation(new Point(RenderSize.Width / 2d, RenderSize.Height / 2d)); center.Longitude = Location.NormalizeLongitude(center.Longitude); - if (center.Latitude < -mapTransform.MaxLatitude || center.Latitude > mapTransform.MaxLatitude) + if (center.Latitude < -projection.MaxLatitude || center.Latitude > projection.MaxLatitude) { - center.Latitude = Math.Min(Math.Max(center.Latitude, -mapTransform.MaxLatitude), mapTransform.MaxLatitude); - resetOrigin = true; + center.Latitude = Math.Min(Math.Max(center.Latitude, -projection.MaxLatitude), projection.MaxLatitude); + resetTransformCenter = true; } InternalSetValue(CenterProperty, center); @@ -842,22 +733,24 @@ namespace MapControl if (centerAnimation == null) { InternalSetValue(TargetCenterProperty, center); - InternalSetValue(CenterPointProperty, mapTransform.Transform(center)); + InternalSetValue(CenterPointProperty, projection.LocationToPoint(center)); } - if (resetOrigin) + if (resetTransformCenter) { - ResetTransformOrigin(); - SetViewportTransform(center); + ResetTransformCenter(); + projection.SetViewportTransform(ProjectionCenter ?? center, center, viewportCenter, ZoomLevel, Heading); } } - CenterScale = ViewportScale * mapTransform.RelativeScale(center) / TileSource.MetersPerDegree; - scaleTransform.ScaleX = CenterScale; - scaleTransform.ScaleY = CenterScale; - rotateTransform.Angle = Heading; + var scale = projection.GetMapScale(center); + ScaleTransform.ScaleX = scale.X; + ScaleTransform.ScaleY = scale.Y; + RotateTransform.Angle = Heading; - OnViewportChanged(new ViewportChangedEventArgs(MapOrigin.X - mapOriginX)); + OnViewportChanged(new ViewportChangedEventArgs(projectionChanged, Center.Longitude - centerLongitude)); + + centerLongitude = Center.Longitude; } protected override void OnViewportChanged(ViewportChangedEventArgs e) diff --git a/MapControl/MapControl.Silverlight.csproj b/MapControl/MapControl.Silverlight.csproj index baf3f127..b928a02f 100644 --- a/MapControl/MapControl.Silverlight.csproj +++ b/MapControl/MapControl.Silverlight.csproj @@ -68,13 +68,18 @@ + + + + + + + - - @@ -82,11 +87,10 @@ - - - + + @@ -97,23 +101,23 @@ - - - - - + + + + + - - - + + + diff --git a/MapControl/MapControl.WPF.csproj b/MapControl/MapControl.WPF.csproj index 1e89bd4d..8686ca08 100644 --- a/MapControl/MapControl.WPF.csproj +++ b/MapControl/MapControl.WPF.csproj @@ -52,13 +52,18 @@ + + - + + + + + + - - @@ -66,41 +71,39 @@ - - - + + - - - - - + + + + + - - - + + - + diff --git a/MapControl/MapGraticule.Silverlight.WinRT.cs b/MapControl/MapGraticule.Silverlight.WinRT.cs index 702ae56c..5afc34a0 100644 --- a/MapControl/MapGraticule.Silverlight.WinRT.cs +++ b/MapControl/MapGraticule.Silverlight.WinRT.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System; @@ -34,169 +34,180 @@ namespace MapControl protected override void OnViewportChanged(ViewportChangedEventArgs e) { - if (path == null) + var projection = ParentMap.MapProjection; + + if (!double.IsNaN(projection.LongitudeScale)) { - path = new Path + if (path == null) { - Data = new PathGeometry() - }; - - path.SetBinding(Shape.StrokeProperty, - GetBindingExpression(StrokeProperty)?.ParentBinding ?? - new Binding + path = new Path { - Source = this, - Path = new PropertyPath("Stroke") - }); - - path.SetBinding(Shape.StrokeThicknessProperty, - GetBindingExpression(StrokeThicknessProperty)?.ParentBinding ?? - new Binding - { - Source = this, - Path = new PropertyPath("StrokeThickness") - }); - - Children.Add(path); - } - - var bounds = ParentMap.ViewportTransform.Inverse.TransformBounds(new Rect(new Point(), ParentMap.RenderSize)); - var start = ParentMap.MapTransform.Transform(new Point(bounds.X, bounds.Y)); - var end = ParentMap.MapTransform.Transform(new Point(bounds.X + bounds.Width, bounds.Y + bounds.Height)); - var lineDistance = GetLineDistance(); - - var labelStart = new Location( - Math.Ceiling(start.Latitude / lineDistance) * lineDistance, - Math.Ceiling(start.Longitude / lineDistance) * lineDistance); - - var labelEnd = new Location( - Math.Floor(end.Latitude / lineDistance) * lineDistance, - Math.Floor(end.Longitude / lineDistance) * lineDistance); - - var lineStart = new Location( - Math.Min(Math.Max(labelStart.Latitude - lineDistance, -ParentMap.MapTransform.MaxLatitude), ParentMap.MapTransform.MaxLatitude), - labelStart.Longitude - lineDistance); - - var lineEnd = new Location( - Math.Min(Math.Max(labelEnd.Latitude + lineDistance, -ParentMap.MapTransform.MaxLatitude), ParentMap.MapTransform.MaxLatitude), - labelEnd.Longitude + lineDistance); - - if (!lineStart.Equals(graticuleStart) || !lineEnd.Equals(graticuleEnd)) - { - graticuleStart = lineStart; - graticuleEnd = lineEnd; - - var geometry = (PathGeometry)path.Data; - geometry.Figures.Clear(); - geometry.Transform = ParentMap.ViewportTransform; - - for (var lat = labelStart.Latitude; lat <= end.Latitude; lat += lineDistance) - { - var figure = new PathFigure - { - StartPoint = ParentMap.MapTransform.Transform(new Location(lat, lineStart.Longitude)), - IsClosed = false, - IsFilled = false + Data = new PathGeometry() }; - figure.Segments.Add(new LineSegment - { - Point = ParentMap.MapTransform.Transform(new Location(lat, lineEnd.Longitude)), - }); + path.SetBinding(Shape.StrokeProperty, + GetBindingExpression(StrokeProperty)?.ParentBinding ?? + new Binding + { + Source = this, + Path = new PropertyPath("Stroke") + }); - geometry.Figures.Add(figure); + path.SetBinding(Shape.StrokeThicknessProperty, + GetBindingExpression(StrokeThicknessProperty)?.ParentBinding ?? + new Binding + { + Source = this, + Path = new PropertyPath("StrokeThickness") + }); + + Children.Add(path); } - for (var lon = labelStart.Longitude; lon <= end.Longitude; lon += lineDistance) + var bounds = projection.ViewportRectToBoundingBox(new Rect(0d, 0d, ParentMap.RenderSize.Width, ParentMap.RenderSize.Height)); + var lineDistance = GetLineDistance(); + + var labelStart = new Location( + Math.Ceiling(bounds.South / lineDistance) * lineDistance, + Math.Ceiling(bounds.West / lineDistance) * lineDistance); + + var labelEnd = new Location( + Math.Floor(bounds.North / lineDistance) * lineDistance, + Math.Floor(bounds.East / lineDistance) * lineDistance); + + var lineStart = new Location( + Math.Min(Math.Max(labelStart.Latitude - lineDistance, -projection.MaxLatitude), projection.MaxLatitude), + labelStart.Longitude - lineDistance); + + var lineEnd = new Location( + Math.Min(Math.Max(labelEnd.Latitude + lineDistance, -projection.MaxLatitude), projection.MaxLatitude), + labelEnd.Longitude + lineDistance); + + if (!lineStart.Equals(graticuleStart) || !lineEnd.Equals(graticuleEnd)) { - var figure = new PathFigure + graticuleStart = lineStart; + graticuleEnd = lineEnd; + + var geometry = (PathGeometry)path.Data; + geometry.Figures.Clear(); + geometry.Transform = projection.ViewportTransform; + + for (var lat = labelStart.Latitude; lat <= bounds.North; lat += lineDistance) { - StartPoint = ParentMap.MapTransform.Transform(new Location(lineStart.Latitude, lon)), - IsClosed = false, - IsFilled = false - }; - - figure.Segments.Add(new LineSegment - { - Point = ParentMap.MapTransform.Transform(new Location(lineEnd.Latitude, lon)), - }); - - geometry.Figures.Add(figure); - } - - var labelFormat = GetLabelFormat(lineDistance); - var childIndex = 1; // 0 for Path - - for (var lat = labelStart.Latitude; lat <= end.Latitude; lat += lineDistance) - { - for (var lon = labelStart.Longitude; lon <= end.Longitude; lon += lineDistance) - { - TextBlock label; - - if (childIndex < Children.Count) + var figure = new PathFigure { - label = (TextBlock)Children[childIndex]; - } - else - { - var renderTransform = new TransformGroup(); - renderTransform.Children.Add(new TranslateTransform()); - renderTransform.Children.Add(ParentMap.RotateTransform); - renderTransform.Children.Add(new TranslateTransform()); + StartPoint = projection.LocationToPoint(new Location(lat, lineStart.Longitude)), + IsClosed = false, + IsFilled = false + }; - label = new TextBlock + figure.Segments.Add(new LineSegment + { + Point = projection.LocationToPoint(new Location(lat, lineEnd.Longitude)), + }); + + geometry.Figures.Add(figure); + } + + for (var lon = labelStart.Longitude; lon <= bounds.East; lon += lineDistance) + { + var figure = new PathFigure + { + StartPoint = projection.LocationToPoint(new Location(lineStart.Latitude, lon)), + IsClosed = false, + IsFilled = false + }; + + figure.Segments.Add(new LineSegment + { + Point = projection.LocationToPoint(new Location(lineEnd.Latitude, lon)), + }); + + geometry.Figures.Add(figure); + } + + var labelFormat = GetLabelFormat(lineDistance); + var childIndex = 1; // 0 for Path + + for (var lat = labelStart.Latitude; lat <= bounds.North; lat += lineDistance) + { + for (var lon = labelStart.Longitude; lon <= bounds.East; lon += lineDistance) + { + TextBlock label; + + if (childIndex < Children.Count) { - RenderTransform = renderTransform - }; + label = (TextBlock)Children[childIndex]; + } + else + { + var renderTransform = new TransformGroup(); + renderTransform.Children.Add(new TranslateTransform()); + renderTransform.Children.Add(ParentMap.RotateTransform); + renderTransform.Children.Add(new TranslateTransform()); - label.SetBinding(TextBlock.ForegroundProperty, - GetBindingExpression(ForegroundProperty)?.ParentBinding ?? - new Binding + label = new TextBlock { - Source = this, - Path = new PropertyPath("Foreground") - }); + RenderTransform = renderTransform + }; - Children.Add(label); + label.SetBinding(TextBlock.ForegroundProperty, + GetBindingExpression(ForegroundProperty)?.ParentBinding ?? + new Binding + { + Source = this, + Path = new PropertyPath("Foreground") + }); + + Children.Add(label); + } + + childIndex++; + + if (FontFamily != null) + { + label.FontFamily = FontFamily; + } + + label.FontSize = FontSize; + label.FontStyle = FontStyle; + label.FontStretch = FontStretch; + label.FontWeight = FontWeight; + label.Text = GetLabelText(lat, labelFormat, "NS") + "\n" + GetLabelText(Location.NormalizeLongitude(lon), labelFormat, "EW"); + label.Tag = new Location(lat, lon); + label.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); + + var translateTransform = (TranslateTransform)((TransformGroup)label.RenderTransform).Children[0]; + translateTransform.X = StrokeThickness / 2d + 2d; + translateTransform.Y = -label.DesiredSize.Height / 2d; } + } - childIndex++; - - if (FontFamily != null) - { - label.FontFamily = FontFamily; - } - - label.FontSize = FontSize; - label.FontStyle = FontStyle; - label.FontStretch = FontStretch; - label.FontWeight = FontWeight; - label.Text = GetLabelText(lat, labelFormat, "NS") + "\n" + GetLabelText(Location.NormalizeLongitude(lon), labelFormat, "EW"); - label.Tag = new Location(lat, lon); - label.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); - - var translateTransform = (TranslateTransform)((TransformGroup)label.RenderTransform).Children[0]; - translateTransform.X = StrokeThickness / 2d + 2d; - translateTransform.Y = -label.DesiredSize.Height / 2d; + while (Children.Count > childIndex) + { + Children.RemoveAt(Children.Count - 1); } } - while (Children.Count > childIndex) + // don't use MapPanel.Location because labels may be at more than 180° distance from map center + + for (int i = 1; i < Children.Count; i++) { - Children.RemoveAt(Children.Count - 1); + var label = (TextBlock)Children[i]; + var location = (Location)label.Tag; + var viewportTransform = (TranslateTransform)((TransformGroup)label.RenderTransform).Children[2]; + var viewportPosition = projection.LocationToViewportPoint(location); + viewportTransform.X = viewportPosition.X; + viewportTransform.Y = viewportPosition.Y; } } - - // don't use MapPanel.Location because labels may be at more than 180° distance from map center - - for (int i = 1; i < Children.Count; i++) + else if (path != null) { - var label = (TextBlock)Children[i]; - var location = (Location)label.Tag; - var viewportTransform = (TranslateTransform)((TransformGroup)label.RenderTransform).Children[2]; - var viewportPosition = ParentMap.LocationToViewportPoint(location); - viewportTransform.X = viewportPosition.X; - viewportTransform.Y = viewportPosition.Y; + path = null; + graticuleStart = null; + graticuleEnd = null; + + Children.Clear(); } base.OnViewportChanged(e); diff --git a/MapControl/MapGraticule.WPF.cs b/MapControl/MapGraticule.WPF.cs index 3035b2fa..df215e59 100644 --- a/MapControl/MapGraticule.WPF.cs +++ b/MapControl/MapGraticule.WPF.cs @@ -1,5 +1,5 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// © 2016 Clemens Fischer +// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control +// © 2017 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) using System; @@ -26,11 +26,8 @@ namespace MapControl static MapGraticule() { - IsHitTestVisibleProperty.OverrideMetadata( - typeof(MapGraticule), new FrameworkPropertyMetadata(false)); - - StrokeThicknessProperty.OverrideMetadata( - typeof(MapGraticule), new FrameworkPropertyMetadata(0.5)); + IsHitTestVisibleProperty.OverrideMetadata(typeof(MapGraticule), new FrameworkPropertyMetadata(false)); + StrokeThicknessProperty.OverrideMetadata(typeof(MapGraticule), new FrameworkPropertyMetadata(0.5)); } protected override void OnViewportChanged(ViewportChangedEventArgs e) @@ -40,45 +37,45 @@ namespace MapControl protected override void OnRender(DrawingContext drawingContext) { - if (ParentMap != null) + var projection = ParentMap?.MapProjection; + + if (projection != null && !double.IsNaN(projection.LongitudeScale)) { - var bounds = ParentMap.ViewportTransform.Inverse.TransformBounds(new Rect(ParentMap.RenderSize)); - var start = ParentMap.MapTransform.Transform(new Point(bounds.X, bounds.Y)); - var end = ParentMap.MapTransform.Transform(new Point(bounds.X + bounds.Width, bounds.Y + bounds.Height)); + var bounds = projection.ViewportRectToBoundingBox(new Rect(ParentMap.RenderSize)); var lineDistance = GetLineDistance(); var labelFormat = GetLabelFormat(lineDistance); - var latLabelStart = Math.Ceiling(start.Latitude / lineDistance) * lineDistance; - var lonLabelStart = Math.Ceiling(start.Longitude / lineDistance) * lineDistance; - var latLabels = new List