mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2025-12-06 07:12:04 +01:00
Reworked sample applications
This commit is contained in:
parent
9ce981a6ee
commit
32491a8e31
|
|
@ -67,7 +67,7 @@ namespace MapControl
|
||||||
|
|
||||||
if (values.Length != 4)
|
if (values.Length != 4)
|
||||||
{
|
{
|
||||||
throw new FormatException("BoundingBox string must be a comma-separated list of four double values.");
|
throw new FormatException("BoundingBox string must be a comma-separated list of four floating point numbers.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new BoundingBox(
|
return new BoundingBox(
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MBTiles.WinUI", "MBTiles\Wi
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinUiApp", "SampleApps\WinUiApp\WinUiApp.csproj", "{751EF297-7CF4-4879-BA8F-42661FA68668}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinUiApp", "SampleApps\WinUiApp\WinUiApp.csproj", "{751EF297-7CF4-4879-BA8F-42661FA68668}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProjectionDemo", "SampleApps\ProjectionDemo\ProjectionDemo.csproj", "{AC8C7BE0-9E72-434B-8BF3-FAEFAC2E859C}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|
@ -428,6 +430,22 @@ Global
|
||||||
{751EF297-7CF4-4879-BA8F-42661FA68668}.Release|x86.ActiveCfg = Release|x86
|
{751EF297-7CF4-4879-BA8F-42661FA68668}.Release|x86.ActiveCfg = Release|x86
|
||||||
{751EF297-7CF4-4879-BA8F-42661FA68668}.Release|x86.Build.0 = Release|x86
|
{751EF297-7CF4-4879-BA8F-42661FA68668}.Release|x86.Build.0 = Release|x86
|
||||||
{751EF297-7CF4-4879-BA8F-42661FA68668}.Release|x86.Deploy.0 = Release|x86
|
{751EF297-7CF4-4879-BA8F-42661FA68668}.Release|x86.Deploy.0 = Release|x86
|
||||||
|
{AC8C7BE0-9E72-434B-8BF3-FAEFAC2E859C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{AC8C7BE0-9E72-434B-8BF3-FAEFAC2E859C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{AC8C7BE0-9E72-434B-8BF3-FAEFAC2E859C}.Debug|arm64.ActiveCfg = Debug|Any CPU
|
||||||
|
{AC8C7BE0-9E72-434B-8BF3-FAEFAC2E859C}.Debug|arm64.Build.0 = Debug|Any CPU
|
||||||
|
{AC8C7BE0-9E72-434B-8BF3-FAEFAC2E859C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{AC8C7BE0-9E72-434B-8BF3-FAEFAC2E859C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{AC8C7BE0-9E72-434B-8BF3-FAEFAC2E859C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{AC8C7BE0-9E72-434B-8BF3-FAEFAC2E859C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{AC8C7BE0-9E72-434B-8BF3-FAEFAC2E859C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{AC8C7BE0-9E72-434B-8BF3-FAEFAC2E859C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{AC8C7BE0-9E72-434B-8BF3-FAEFAC2E859C}.Release|arm64.ActiveCfg = Release|Any CPU
|
||||||
|
{AC8C7BE0-9E72-434B-8BF3-FAEFAC2E859C}.Release|arm64.Build.0 = Release|Any CPU
|
||||||
|
{AC8C7BE0-9E72-434B-8BF3-FAEFAC2E859C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{AC8C7BE0-9E72-434B-8BF3-FAEFAC2E859C}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{AC8C7BE0-9E72-434B-8BF3-FAEFAC2E859C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{AC8C7BE0-9E72-434B-8BF3-FAEFAC2E859C}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
@ -454,6 +472,7 @@ Global
|
||||||
{1F9FBADF-65C0-453D-9B45-7A88044F807F} = {2FDC8B91-FB95-4C57-8183-63587FBFE180}
|
{1F9FBADF-65C0-453D-9B45-7A88044F807F} = {2FDC8B91-FB95-4C57-8183-63587FBFE180}
|
||||||
{817D606F-A22D-485C-89CF-86062C8E97EF} = {CEAD0EA1-A971-4F5F-9EAE-C72F75D1F737}
|
{817D606F-A22D-485C-89CF-86062C8E97EF} = {CEAD0EA1-A971-4F5F-9EAE-C72F75D1F737}
|
||||||
{751EF297-7CF4-4879-BA8F-42661FA68668} = {8F2103C2-78AF-4810-8FB9-67572F50C8FC}
|
{751EF297-7CF4-4879-BA8F-42661FA68668} = {8F2103C2-78AF-4810-8FB9-67572F50C8FC}
|
||||||
|
{AC8C7BE0-9E72-434B-8BF3-FAEFAC2E859C} = {8F2103C2-78AF-4810-8FB9-67572F50C8FC}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {458346DD-B23F-4FDC-8F9D-A10F1882A4DB}
|
SolutionGuid = {458346DD-B23F-4FDC-8F9D-A10F1882A4DB}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ using System.ComponentModel;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,11 @@
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>net6.0-windows</TargetFramework>
|
<TargetFramework>net6.0-windows</TargetFramework>
|
||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
<Version>6.1.0</Version>
|
<Version>7.0.0</Version>
|
||||||
<Authors>Clemens Fischer</Authors>
|
<Authors>Clemens Fischer</Authors>
|
||||||
<Description>XAML Map Control Map Projection Demo Application</Description>
|
<Description>XAML Map Control Map Projection Demo Application</Description>
|
||||||
<Product>XAML Map Control</Product>
|
<Product>XAML Map Control</Product>
|
||||||
<Copyright>Copyright © 2020 Clemens Fischer</Copyright>
|
<Copyright>Copyright © 2021 Clemens Fischer</Copyright>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -1,182 +0,0 @@
|
||||||
using MapControl;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
|
||||||
#if WINUI
|
|
||||||
using Microsoft.UI;
|
|
||||||
using Microsoft.UI.Xaml;
|
|
||||||
using Microsoft.UI.Xaml.Media;
|
|
||||||
#elif UWP
|
|
||||||
using Windows.UI;
|
|
||||||
using Windows.UI.Xaml;
|
|
||||||
using Windows.UI.Xaml.Media;
|
|
||||||
#else
|
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Media;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace SampleApplication
|
|
||||||
{
|
|
||||||
public class MapLayers : INotifyPropertyChanged
|
|
||||||
{
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
|
||||||
|
|
||||||
// See https://wiki.openstreetmap.org/wiki/Tile_servers for a list of free OpenStreetMap Tile Servers
|
|
||||||
|
|
||||||
private readonly Dictionary<string, UIElement> mapLayers = new Dictionary<string, UIElement>
|
|
||||||
{
|
|
||||||
{
|
|
||||||
"OpenStreetMap",
|
|
||||||
new MapTileLayer
|
|
||||||
{
|
|
||||||
TileSource = new TileSource { UriFormat = "https://tile.openstreetmap.org/{z}/{x}/{y}.png" },
|
|
||||||
SourceName = "OpenStreetMap",
|
|
||||||
Description = "© [OpenStreetMap contributors](http://www.openstreetmap.org/copyright)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"OpenStreetMap German",
|
|
||||||
new MapTileLayer
|
|
||||||
{
|
|
||||||
TileSource = new TileSource { UriFormat = "https://{s}.tile.openstreetmap.de/{z}/{x}/{y}.png" },
|
|
||||||
SourceName = "OpenStreetMap German",
|
|
||||||
Description = "© [OpenStreetMap contributors](http://www.openstreetmap.org/copyright)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"OpenStreetMap French",
|
|
||||||
new MapTileLayer
|
|
||||||
{
|
|
||||||
TileSource = new TileSource { UriFormat = "http://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png" },
|
|
||||||
SourceName = "OpenStreetMap French",
|
|
||||||
Description = "© [OpenStreetMap France](https://www.openstreetmap.fr/mentions-legales/) © [OpenStreetMap contributors](http://www.openstreetmap.org/copyright)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"OpenTopoMap",
|
|
||||||
new MapTileLayer
|
|
||||||
{
|
|
||||||
TileSource = new TileSource { UriFormat = "https://tile.opentopomap.org/{z}/{x}/{y}.png" },
|
|
||||||
SourceName = "OpenTopoMap",
|
|
||||||
Description = "© [OpenTopoMap](https://opentopomap.org/) © [OpenStreetMap contributors](http://www.openstreetmap.org/copyright)",
|
|
||||||
MaxZoomLevel = 17
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Seamarks",
|
|
||||||
new MapTileLayer
|
|
||||||
{
|
|
||||||
TileSource = new TileSource { UriFormat = "http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png" },
|
|
||||||
SourceName = "OpenSeaMap",
|
|
||||||
MinZoomLevel = 9,
|
|
||||||
MaxZoomLevel = 18
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Bing Maps Road",
|
|
||||||
new BingMapsTileLayer
|
|
||||||
{
|
|
||||||
Mode = BingMapsTileLayer.MapMode.Road,
|
|
||||||
SourceName = "Bing Maps Road",
|
|
||||||
Description = "© [Microsoft](http://www.bing.com/maps/)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Bing Maps Aerial",
|
|
||||||
new BingMapsTileLayer
|
|
||||||
{
|
|
||||||
Mode = BingMapsTileLayer.MapMode.Aerial,
|
|
||||||
SourceName = "Bing Maps Aerial",
|
|
||||||
Description = "© [Microsoft](http://www.bing.com/maps/)",
|
|
||||||
MapForeground = new SolidColorBrush(Colors.White),
|
|
||||||
MapBackground = new SolidColorBrush(Colors.Black)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Bing Maps Aerial with Labels",
|
|
||||||
new BingMapsTileLayer
|
|
||||||
{
|
|
||||||
Mode = BingMapsTileLayer.MapMode.AerialWithLabels,
|
|
||||||
SourceName = "Bing Maps Hybrid",
|
|
||||||
Description = "© [Microsoft](http://www.bing.com/maps/)",
|
|
||||||
MapForeground = new SolidColorBrush(Colors.White),
|
|
||||||
MapBackground = new SolidColorBrush(Colors.Black)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"TopPlusOpen WMTS",
|
|
||||||
new WmtsTileLayer
|
|
||||||
{
|
|
||||||
SourceName = "TopPlusOpen",
|
|
||||||
Description = "© [BKG](https://gdz.bkg.bund.de/index.php/default/webdienste/topplus-produkte/wmts-topplusopen-wmts-topplus-open.html)",
|
|
||||||
CapabilitiesUri = new Uri("https://sgx.geodatenzentrum.de/wmts_topplus_open/1.0.0/WMTSCapabilities.xml")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"TopPlusOpen WMS",
|
|
||||||
new WmsImageLayer
|
|
||||||
{
|
|
||||||
Description = "© [BKG](https://gdz.bkg.bund.de/index.php/default/webdienste/topplus-produkte/wms-topplusopen-mit-layer-fur-normalausgabe-und-druck-wms-topplus-open.html)",
|
|
||||||
ServiceUri = new Uri("https://sgx.geodatenzentrum.de/wms_topplus_open")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"OpenStreetMap WMS",
|
|
||||||
new WmsImageLayer
|
|
||||||
{
|
|
||||||
Description = "© [terrestris GmbH & Co. KG](http://ows.terrestris.de/) © [OpenStreetMap contributors](http://www.openstreetmap.org/copyright)",
|
|
||||||
ServiceUri = new Uri("http://ows.terrestris.de/osm/service")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
private string currentMapLayerName = "OpenStreetMap";
|
|
||||||
|
|
||||||
public string CurrentMapLayerName
|
|
||||||
{
|
|
||||||
get { return currentMapLayerName; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
currentMapLayerName = value;
|
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CurrentMapLayerName)));
|
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CurrentMapLayer)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public UIElement CurrentMapLayer
|
|
||||||
{
|
|
||||||
get { return mapLayers[currentMapLayerName]; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public UIElement SeamarksLayer
|
|
||||||
{
|
|
||||||
get { return mapLayers["Seamarks"]; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<string> MapLayerNames { get; } = new List<string>
|
|
||||||
{
|
|
||||||
"OpenStreetMap",
|
|
||||||
"OpenStreetMap German",
|
|
||||||
"OpenStreetMap French",
|
|
||||||
"OpenTopoMap",
|
|
||||||
"TopPlusOpen WMTS",
|
|
||||||
"TopPlusOpen WMS",
|
|
||||||
"OpenStreetMap WMS",
|
|
||||||
};
|
|
||||||
|
|
||||||
public MapLayers()
|
|
||||||
{
|
|
||||||
// Add Bing Maps TileLayers with tile URLs retrieved from the Imagery Metadata Service
|
|
||||||
// (http://msdn.microsoft.com/en-us/library/ff701716.aspx).
|
|
||||||
// A Bing Maps API Key (http://msdn.microsoft.com/en-us/library/ff428642.aspx) is required
|
|
||||||
// for using these layers and must be assigned to the static BingMapsTileLayer.ApiKey property.
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(BingMapsTileLayer.ApiKey))
|
|
||||||
{
|
|
||||||
MapLayerNames.Add("Bing Maps Road");
|
|
||||||
MapLayerNames.Add("Bing Maps Aerial");
|
|
||||||
MapLayerNames.Add("Bing Maps Aerial with Labels");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
158
SampleApps/Shared/MapLayersMenuButton.cs
Normal file
158
SampleApps/Shared/MapLayersMenuButton.cs
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
using MapControl;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
#if WINUI
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Media;
|
||||||
|
#elif UWP
|
||||||
|
using Windows.UI.Xaml;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using Windows.UI.Xaml.Media;
|
||||||
|
#else
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Media;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace SampleApplication
|
||||||
|
{
|
||||||
|
public class MapLayersMenuButton : MenuButton
|
||||||
|
{
|
||||||
|
public MapLayersMenuButton()
|
||||||
|
{
|
||||||
|
#if WINUI || UWP
|
||||||
|
Content = new FontIcon
|
||||||
|
{
|
||||||
|
FontFamily = new FontFamily("Segoe MDL2 Assets"),
|
||||||
|
Glyph = "\uE81E"
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
FontFamily = new FontFamily("Segoe MDL2 Assets");
|
||||||
|
Content = "\uE81E";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty MapProperty = DependencyProperty.Register(
|
||||||
|
nameof(Map), typeof(MapBase), typeof(MapLayersMenuButton),
|
||||||
|
new PropertyMetadata(null, (o, e) => ((MapLayersMenuButton)o).InitializeMenu()));
|
||||||
|
|
||||||
|
public static readonly DependencyProperty MapLayersProperty = DependencyProperty.Register(
|
||||||
|
nameof(MapLayers), typeof(IDictionary<string, UIElement>), typeof(MapLayersMenuButton),
|
||||||
|
new PropertyMetadata(null, (o, e) => ((MapLayersMenuButton)o).InitializeMenu()));
|
||||||
|
|
||||||
|
public static readonly DependencyProperty MapOverlaysProperty = DependencyProperty.Register(
|
||||||
|
nameof(MapOverlays), typeof(IDictionary<string, UIElement>), typeof(MapLayersMenuButton),
|
||||||
|
new PropertyMetadata(null, (o, e) => ((MapLayersMenuButton)o).InitializeMenu()));
|
||||||
|
|
||||||
|
public MapBase Map
|
||||||
|
{
|
||||||
|
get { return (MapBase)GetValue(MapProperty); }
|
||||||
|
set { SetValue(MapProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDictionary<string, UIElement> MapLayers
|
||||||
|
{
|
||||||
|
get { return (IDictionary<string, UIElement>)GetValue(MapLayersProperty); }
|
||||||
|
set { SetValue(MapLayersProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDictionary<string, UIElement> MapOverlays
|
||||||
|
{
|
||||||
|
get { return (IDictionary<string, UIElement>)GetValue(MapOverlaysProperty); }
|
||||||
|
set { SetValue(MapOverlaysProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeMenu()
|
||||||
|
{
|
||||||
|
if (Map != null && MapLayers != null)
|
||||||
|
{
|
||||||
|
var menu = CreateMenu();
|
||||||
|
|
||||||
|
foreach (var layer in MapLayers)
|
||||||
|
{
|
||||||
|
menu.Items.Add(CreateMenuItem(layer.Key, layer.Value, MapLayerClicked));
|
||||||
|
}
|
||||||
|
|
||||||
|
var initialLayer = MapLayers.Values.FirstOrDefault();
|
||||||
|
|
||||||
|
if (MapOverlays != null && MapOverlays.Any())
|
||||||
|
{
|
||||||
|
if (initialLayer != null)
|
||||||
|
{
|
||||||
|
menu.Items.Add(CreateSeparator());
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var overlay in MapOverlays)
|
||||||
|
{
|
||||||
|
menu.Items.Add(CreateMenuItem(overlay.Key, overlay.Value, MapOverlayClicked));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (initialLayer != null)
|
||||||
|
{
|
||||||
|
SetMapLayer(initialLayer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MapLayerClicked(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var item = (FrameworkElement)sender;
|
||||||
|
var layer = (UIElement)item.Tag;
|
||||||
|
|
||||||
|
SetMapLayer(layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MapOverlayClicked(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var item = (FrameworkElement)sender;
|
||||||
|
var layer = (UIElement)item.Tag;
|
||||||
|
|
||||||
|
ToggleMapOverlay(layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetMapLayer(UIElement layer)
|
||||||
|
{
|
||||||
|
Map.MapLayer = layer;
|
||||||
|
|
||||||
|
UpdateCheckedStates();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ToggleMapOverlay(UIElement layer)
|
||||||
|
{
|
||||||
|
if (Map.Children.Contains(layer))
|
||||||
|
{
|
||||||
|
Map.Children.Remove(layer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int index = 1;
|
||||||
|
|
||||||
|
foreach (var overlay in MapOverlays.Values)
|
||||||
|
{
|
||||||
|
if (overlay == layer)
|
||||||
|
{
|
||||||
|
Map.Children.Insert(index, layer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Map.Children.Contains(overlay))
|
||||||
|
{
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateCheckedStates();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateCheckedStates()
|
||||||
|
{
|
||||||
|
foreach (var item in GetMenuItems())
|
||||||
|
{
|
||||||
|
item.IsChecked = Map.Children.Contains((UIElement)item.Tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
94
SampleApps/Shared/MapProjectionsMenuButton.cs
Normal file
94
SampleApps/Shared/MapProjectionsMenuButton.cs
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
using MapControl;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
#if WINUI
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Media;
|
||||||
|
#elif UWP
|
||||||
|
using Windows.UI.Xaml;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using Windows.UI.Xaml.Media;
|
||||||
|
#else
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Media;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace SampleApplication
|
||||||
|
{
|
||||||
|
public class MapProjectionsMenuButton : MenuButton
|
||||||
|
{
|
||||||
|
public MapProjectionsMenuButton()
|
||||||
|
{
|
||||||
|
#if WINUI || UWP
|
||||||
|
Content = new FontIcon
|
||||||
|
{
|
||||||
|
FontFamily = new FontFamily("Segoe MDL2 Assets"),
|
||||||
|
Glyph = "\uE809"
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
FontFamily = new FontFamily("Segoe MDL2 Assets");
|
||||||
|
Content = "\uE809";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty MapProperty = DependencyProperty.Register(
|
||||||
|
nameof(Map), typeof(MapBase), typeof(MapProjectionsMenuButton),
|
||||||
|
new PropertyMetadata(null, (o, e) => ((MapProjectionsMenuButton)o).InitializeMenu()));
|
||||||
|
|
||||||
|
public static readonly DependencyProperty MapProjectionsProperty = DependencyProperty.Register(
|
||||||
|
nameof(MapProjections), typeof(IDictionary<string, MapProjection>), typeof(MapProjectionsMenuButton),
|
||||||
|
new PropertyMetadata(null, (o, e) => ((MapProjectionsMenuButton)o).InitializeMenu()));
|
||||||
|
|
||||||
|
public MapBase Map
|
||||||
|
{
|
||||||
|
get { return (MapBase)GetValue(MapProperty); }
|
||||||
|
set { SetValue(MapProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDictionary<string, MapProjection> MapProjections
|
||||||
|
{
|
||||||
|
get { return (IDictionary<string, MapProjection>)GetValue(MapProjectionsProperty); }
|
||||||
|
set { SetValue(MapProjectionsProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeMenu()
|
||||||
|
{
|
||||||
|
if (Map != null && MapProjections != null)
|
||||||
|
{
|
||||||
|
var menu = CreateMenu();
|
||||||
|
|
||||||
|
foreach (var projection in MapProjections)
|
||||||
|
{
|
||||||
|
menu.Items.Add(CreateMenuItem(projection.Key, projection.Value, MapProjectionClicked));
|
||||||
|
}
|
||||||
|
|
||||||
|
var initialProjection = MapProjections.Values.FirstOrDefault();
|
||||||
|
|
||||||
|
if (initialProjection != null)
|
||||||
|
{
|
||||||
|
SetMapProjection(initialProjection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MapProjectionClicked(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var item = (FrameworkElement)sender;
|
||||||
|
var projection = (MapProjection)item.Tag;
|
||||||
|
|
||||||
|
SetMapProjection(projection);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetMapProjection(MapProjection projection)
|
||||||
|
{
|
||||||
|
Map.MapProjection = projection;
|
||||||
|
|
||||||
|
foreach (var item in GetMenuItems())
|
||||||
|
{
|
||||||
|
item.IsChecked = Map.MapProjection == (MapProjection)item.Tag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,95 +1,233 @@
|
||||||
using MapControl;
|
using MapControl;
|
||||||
using System.Collections.ObjectModel;
|
using System;
|
||||||
using System.ComponentModel;
|
using System.Collections.Generic;
|
||||||
|
#if WINUI
|
||||||
|
using Microsoft.UI;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Media;
|
||||||
|
using Microsoft.UI.Xaml.Media.Imaging;
|
||||||
|
#elif UWP
|
||||||
|
using Windows.UI;
|
||||||
|
using Windows.UI.Xaml;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using Windows.UI.Xaml.Media;
|
||||||
|
using Windows.UI.Xaml.Media.Imaging;
|
||||||
|
#else
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace SampleApplication
|
namespace SampleApplication
|
||||||
{
|
{
|
||||||
public class ViewModelBase : INotifyPropertyChanged
|
public class PointItem
|
||||||
{
|
{
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public string Name { get; set; }
|
||||||
|
|
||||||
protected void RaisePropertyChanged(string propertyName)
|
public Location Location { get; set; }
|
||||||
{
|
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PointItem : ViewModelBase
|
public class PolylineItem
|
||||||
{
|
|
||||||
private string name;
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get { return name; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
name = value;
|
|
||||||
RaisePropertyChanged(nameof(Name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Location location;
|
|
||||||
public Location Location
|
|
||||||
{
|
|
||||||
get { return location; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
location = value;
|
|
||||||
RaisePropertyChanged(nameof(Location));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Polyline
|
|
||||||
{
|
{
|
||||||
public LocationCollection Locations { get; set; }
|
public LocationCollection Locations { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MapViewModel : ViewModelBase
|
public class MapViewModel
|
||||||
{
|
{
|
||||||
private Location mapCenter = new Location(53.5, 8.2);
|
public List<PointItem> Points { get; } = new List<PointItem>();
|
||||||
public Location MapCenter
|
public List<PointItem> Pushpins { get; } = new List<PointItem>();
|
||||||
|
public List<PolylineItem> Polylines { get; } = new List<PolylineItem>();
|
||||||
|
|
||||||
|
public Dictionary<string, MapProjection> MapProjections { get; } = new Dictionary<string, MapProjection>
|
||||||
{
|
{
|
||||||
get { return mapCenter; }
|
{ "Web Mercator", new WebMercatorProjection() },
|
||||||
set
|
{ "World Mercator", new WorldMercatorProjection() },
|
||||||
|
{ "Equirectangular", new EquirectangularProjection() },
|
||||||
|
{ "Orthographic", new OrthographicProjection() },
|
||||||
|
{ "Gnomonic", new GnomonicProjection() },
|
||||||
|
{ "Stereographic", new StereographicProjection() }
|
||||||
|
};
|
||||||
|
|
||||||
|
public Dictionary<string, UIElement> MapLayers { get; } = new Dictionary<string, UIElement>
|
||||||
{
|
{
|
||||||
mapCenter = value;
|
{
|
||||||
RaisePropertyChanged(nameof(MapCenter));
|
"OpenStreetMap",
|
||||||
|
new MapTileLayer
|
||||||
|
{
|
||||||
|
TileSource = new TileSource { UriFormat = "https://tile.openstreetmap.org/{z}/{x}/{y}.png" },
|
||||||
|
SourceName = "OpenStreetMap",
|
||||||
|
Description = "© [OpenStreetMap contributors](http://www.openstreetmap.org/copyright)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"OpenStreetMap German",
|
||||||
|
new MapTileLayer
|
||||||
|
{
|
||||||
|
TileSource = new TileSource { UriFormat = "https://{s}.tile.openstreetmap.de/{z}/{x}/{y}.png" },
|
||||||
|
SourceName = "OpenStreetMap German",
|
||||||
|
Description = "© [OpenStreetMap contributors](http://www.openstreetmap.org/copyright)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"OpenStreetMap French",
|
||||||
|
new MapTileLayer
|
||||||
|
{
|
||||||
|
TileSource = new TileSource { UriFormat = "http://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png" },
|
||||||
|
SourceName = "OpenStreetMap French",
|
||||||
|
Description = "© [OpenStreetMap France](https://www.openstreetmap.fr/mentions-legales/) © [OpenStreetMap contributors](http://www.openstreetmap.org/copyright)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"OpenTopoMap",
|
||||||
|
new MapTileLayer
|
||||||
|
{
|
||||||
|
TileSource = new TileSource { UriFormat = "https://tile.opentopomap.org/{z}/{x}/{y}.png" },
|
||||||
|
SourceName = "OpenTopoMap",
|
||||||
|
Description = "© [OpenTopoMap](https://opentopomap.org/) © [OpenStreetMap contributors](http://www.openstreetmap.org/copyright)",
|
||||||
|
MaxZoomLevel = 17
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"TopPlusOpen WMTS",
|
||||||
|
new WmtsTileLayer
|
||||||
|
{
|
||||||
|
SourceName = "TopPlusOpen",
|
||||||
|
Description = "© [BKG](https://gdz.bkg.bund.de/index.php/default/webdienste/topplus-produkte/wmts-topplusopen-wmts-topplus-open.html)",
|
||||||
|
CapabilitiesUri = new Uri("https://sgx.geodatenzentrum.de/wmts_topplus_open/1.0.0/WMTSCapabilities.xml")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"TopPlusOpen WMS",
|
||||||
|
new WmsImageLayer
|
||||||
|
{
|
||||||
|
Description = "© [BKG](https://gdz.bkg.bund.de/index.php/default/webdienste/topplus-produkte/wms-topplusopen-mit-layer-fur-normalausgabe-und-druck-wms-topplus-open.html)",
|
||||||
|
ServiceUri = new Uri("https://sgx.geodatenzentrum.de/wms_topplus_open")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"OpenStreetMap WMS",
|
||||||
|
new WmsImageLayer
|
||||||
|
{
|
||||||
|
Description = "© [terrestris GmbH & Co. KG](http://ows.terrestris.de/) © [OpenStreetMap contributors](http://www.openstreetmap.org/copyright)",
|
||||||
|
ServiceUri = new Uri("http://ows.terrestris.de/osm/service")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public ObservableCollection<PointItem> Points { get; } = new ObservableCollection<PointItem>();
|
public Dictionary<string, UIElement> MapOverlays { get; } = new Dictionary<string, UIElement>
|
||||||
public ObservableCollection<PointItem> Pushpins { get; } = new ObservableCollection<PointItem>();
|
{
|
||||||
public ObservableCollection<Polyline> Polylines { get; } = new ObservableCollection<Polyline>();
|
{
|
||||||
|
"Sample Image",
|
||||||
public MapLayers MapLayers { get; } = new MapLayers();
|
new Image()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Seamarks",
|
||||||
|
new MapTileLayer
|
||||||
|
{
|
||||||
|
TileSource = new TileSource { UriFormat = "http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png" },
|
||||||
|
SourceName = "OpenSeaMap",
|
||||||
|
MinZoomLevel = 9,
|
||||||
|
MaxZoomLevel = 18
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Graticule",
|
||||||
|
new MapGraticule
|
||||||
|
{
|
||||||
|
Opacity = 0.75
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Scale",
|
||||||
|
new MapScale
|
||||||
|
{
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Center,
|
||||||
|
VerticalAlignment = VerticalAlignment.Bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public MapViewModel()
|
public MapViewModel()
|
||||||
{
|
{
|
||||||
|
// Add Bing Maps TileLayers with tile URLs retrieved from the Imagery Metadata Service
|
||||||
|
// (http://msdn.microsoft.com/en-us/library/ff701716.aspx).
|
||||||
|
// A Bing Maps API Key (http://msdn.microsoft.com/en-us/library/ff428642.aspx) is required
|
||||||
|
// for using these layers and must be assigned to the static BingMapsTileLayer.ApiKey property.
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(BingMapsTileLayer.ApiKey))
|
||||||
|
{
|
||||||
|
MapLayers.Add(
|
||||||
|
"Bing Maps Road",
|
||||||
|
new BingMapsTileLayer
|
||||||
|
{
|
||||||
|
Mode = BingMapsTileLayer.MapMode.Road,
|
||||||
|
SourceName = "Bing Maps Road",
|
||||||
|
Description = "© [Microsoft](http://www.bing.com/maps/)"
|
||||||
|
});
|
||||||
|
|
||||||
|
MapLayers.Add(
|
||||||
|
"Bing Maps Aerial",
|
||||||
|
new BingMapsTileLayer
|
||||||
|
{
|
||||||
|
Mode = BingMapsTileLayer.MapMode.Aerial,
|
||||||
|
SourceName = "Bing Maps Aerial",
|
||||||
|
Description = "© [Microsoft](http://www.bing.com/maps/)",
|
||||||
|
MapForeground = new SolidColorBrush(Colors.White),
|
||||||
|
MapBackground = new SolidColorBrush(Colors.Black)
|
||||||
|
});
|
||||||
|
|
||||||
|
MapLayers.Add(
|
||||||
|
"Bing Maps Aerial with Labels",
|
||||||
|
new BingMapsTileLayer
|
||||||
|
{
|
||||||
|
Mode = BingMapsTileLayer.MapMode.AerialWithLabels,
|
||||||
|
SourceName = "Bing Maps Hybrid",
|
||||||
|
Description = "© [Microsoft](http://www.bing.com/maps/)",
|
||||||
|
MapForeground = new SolidColorBrush(Colors.White),
|
||||||
|
MapBackground = new SolidColorBrush(Colors.Black)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var sampleImage = (Image)MapOverlays["Sample Image"];
|
||||||
|
#if WINUI || UWP
|
||||||
|
sampleImage.Source = new BitmapImage(new Uri("ms-appx:///10_535_330.jpg"));
|
||||||
|
#else
|
||||||
|
sampleImage.Source = new BitmapImage(new Uri("pack://siteoforigin:,,,/10_535_330.jpg"));
|
||||||
|
#endif
|
||||||
|
MapPanel.SetBoundingBox(sampleImage, new BoundingBox(53.54031, 8.08594, 53.74871, 8.43750));
|
||||||
|
|
||||||
Points.Add(new PointItem
|
Points.Add(new PointItem
|
||||||
{
|
{
|
||||||
Name = "Steinbake Leitdamm",
|
Name = "Steinbake Leitdamm",
|
||||||
Location = new Location(53.51217, 8.16603)
|
Location = new Location(53.51217, 8.16603)
|
||||||
});
|
});
|
||||||
|
|
||||||
Points.Add(new PointItem
|
Points.Add(new PointItem
|
||||||
{
|
{
|
||||||
Name = "Buhne 2",
|
Name = "Buhne 2",
|
||||||
Location = new Location(53.50926, 8.15815)
|
Location = new Location(53.50926, 8.15815)
|
||||||
});
|
});
|
||||||
|
|
||||||
Points.Add(new PointItem
|
Points.Add(new PointItem
|
||||||
{
|
{
|
||||||
Name = "Buhne 4",
|
Name = "Buhne 4",
|
||||||
Location = new Location(53.50468, 8.15343)
|
Location = new Location(53.50468, 8.15343)
|
||||||
});
|
});
|
||||||
|
|
||||||
Points.Add(new PointItem
|
Points.Add(new PointItem
|
||||||
{
|
{
|
||||||
Name = "Buhne 6",
|
Name = "Buhne 6",
|
||||||
Location = new Location(53.50092, 8.15267)
|
Location = new Location(53.50092, 8.15267)
|
||||||
});
|
});
|
||||||
|
|
||||||
Points.Add(new PointItem
|
Points.Add(new PointItem
|
||||||
{
|
{
|
||||||
Name = "Buhne 8",
|
Name = "Buhne 8",
|
||||||
Location = new Location(53.49871, 8.15321)
|
Location = new Location(53.49871, 8.15321)
|
||||||
});
|
});
|
||||||
|
|
||||||
Points.Add(new PointItem
|
Points.Add(new PointItem
|
||||||
{
|
{
|
||||||
Name = "Buhne 10",
|
Name = "Buhne 10",
|
||||||
|
|
@ -101,27 +239,31 @@ namespace SampleApplication
|
||||||
Name = "WHV - Eckwarderhörne",
|
Name = "WHV - Eckwarderhörne",
|
||||||
Location = new Location(53.5495, 8.1877)
|
Location = new Location(53.5495, 8.1877)
|
||||||
});
|
});
|
||||||
|
|
||||||
Pushpins.Add(new PointItem
|
Pushpins.Add(new PointItem
|
||||||
{
|
{
|
||||||
Name = "JadeWeserPort",
|
Name = "JadeWeserPort",
|
||||||
Location = new Location(53.5914, 8.14)
|
Location = new Location(53.5914, 8.14)
|
||||||
});
|
});
|
||||||
|
|
||||||
Pushpins.Add(new PointItem
|
Pushpins.Add(new PointItem
|
||||||
{
|
{
|
||||||
Name = "Kurhaus Dangast",
|
Name = "Kurhaus Dangast",
|
||||||
Location = new Location(53.447, 8.1114)
|
Location = new Location(53.447, 8.1114)
|
||||||
});
|
});
|
||||||
|
|
||||||
Pushpins.Add(new PointItem
|
Pushpins.Add(new PointItem
|
||||||
{
|
{
|
||||||
Name = "Eckwarderhörne",
|
Name = "Eckwarderhörne",
|
||||||
Location = new Location(53.5207, 8.2323)
|
Location = new Location(53.5207, 8.2323)
|
||||||
});
|
});
|
||||||
|
|
||||||
Polylines.Add(new Polyline
|
Polylines.Add(new PolylineItem
|
||||||
{
|
{
|
||||||
Locations = LocationCollection.Parse("53.5140,8.1451 53.5123,8.1506 53.5156,8.1623 53.5276,8.1757 53.5491,8.1852 53.5495,8.1877 53.5426,8.1993 53.5184,8.2219 53.5182,8.2386 53.5195,8.2387")
|
Locations = LocationCollection.Parse("53.5140,8.1451 53.5123,8.1506 53.5156,8.1623 53.5276,8.1757 53.5491,8.1852 53.5495,8.1877 53.5426,8.1993 53.5184,8.2219 53.5182,8.2386 53.5195,8.2387")
|
||||||
});
|
});
|
||||||
Polylines.Add(new Polyline
|
|
||||||
|
Polylines.Add(new PolylineItem
|
||||||
{
|
{
|
||||||
Locations = LocationCollection.Parse("53.5978,8.1212 53.6018,8.1494 53.5859,8.1554 53.5852,8.1531 53.5841,8.1539 53.5802,8.1392 53.5826,8.1309 53.5867,8.1317 53.5978,8.1212")
|
Locations = LocationCollection.Parse("53.5978,8.1212 53.6018,8.1494 53.5859,8.1554 53.5852,8.1531 53.5841,8.1539 53.5802,8.1392 53.5826,8.1309 53.5867,8.1317 53.5978,8.1212")
|
||||||
});
|
});
|
||||||
|
|
|
||||||
73
SampleApps/Shared/MenuButton.cs
Normal file
73
SampleApps/Shared/MenuButton.cs
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
#if WINUI
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
#elif UWP
|
||||||
|
using Windows.UI.Xaml;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
|
#else
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace SampleApplication
|
||||||
|
{
|
||||||
|
public class MenuButton : Button
|
||||||
|
{
|
||||||
|
#if WINUI || UWP
|
||||||
|
protected MenuFlyout CreateMenu()
|
||||||
|
{
|
||||||
|
var menu = new MenuFlyout();
|
||||||
|
Flyout = menu;
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IEnumerable<ToggleMenuFlyoutItem> GetMenuItems()
|
||||||
|
{
|
||||||
|
return ((MenuFlyout)Flyout).Items.OfType<ToggleMenuFlyoutItem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static ToggleMenuFlyoutItem CreateMenuItem(string text, object item, RoutedEventHandler click)
|
||||||
|
{
|
||||||
|
var menuItem = new ToggleMenuFlyoutItem { Text = text, Tag = item };
|
||||||
|
menuItem.Click += click;
|
||||||
|
return menuItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static MenuFlyoutSeparator CreateSeparator()
|
||||||
|
{
|
||||||
|
return new MenuFlyoutSeparator();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
protected ContextMenu CreateMenu()
|
||||||
|
{
|
||||||
|
var menu = new ContextMenu();
|
||||||
|
ContextMenu = menu;
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IEnumerable<MenuItem> GetMenuItems()
|
||||||
|
{
|
||||||
|
return ContextMenu.Items.OfType<MenuItem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static MenuItem CreateMenuItem(string text, object item, RoutedEventHandler click)
|
||||||
|
{
|
||||||
|
var menuItem = new MenuItem { Header = text, Tag = item };
|
||||||
|
menuItem.Click += click;
|
||||||
|
return menuItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Separator CreateSeparator()
|
||||||
|
{
|
||||||
|
return new Separator();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MenuButton()
|
||||||
|
{
|
||||||
|
Click += (s, e) => ContextMenu.IsOpen = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,24 +2,19 @@
|
||||||
x:Class="SampleApplication.MainPage"
|
x:Class="SampleApplication.MainPage"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:local="using:SampleApplication"
|
xmlns:map="using:MapControl"
|
||||||
xmlns:map="using:MapControl">
|
xmlns:local="using:SampleApplication">
|
||||||
|
|
||||||
<Page.Resources>
|
<Page.DataContext>
|
||||||
|
<local:MapViewModel/>
|
||||||
|
</Page.DataContext>
|
||||||
|
|
||||||
|
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
|
<Grid.Resources>
|
||||||
<DataTemplate x:Key="PolylineItemTemplate">
|
<DataTemplate x:Key="PolylineItemTemplate">
|
||||||
<map:MapPolyline Locations="{Binding Locations}" Stroke="Red" StrokeThickness="3"/>
|
<map:MapPolyline Locations="{Binding Locations}" Stroke="Red" StrokeThickness="3"/>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
|
|
||||||
<Style x:Key="PolylineItemStyle" TargetType="map:MapItem">
|
|
||||||
<Setter Property="Template">
|
|
||||||
<Setter.Value>
|
|
||||||
<ControlTemplate TargetType="map:MapItem">
|
|
||||||
<map:MapPolyline Locations="{Binding Locations}" Stroke="Red" StrokeThickness="3"/>
|
|
||||||
</ControlTemplate>
|
|
||||||
</Setter.Value>
|
|
||||||
</Setter>
|
|
||||||
</Style>
|
|
||||||
|
|
||||||
<Style x:Key="PointItemStyle" TargetType="map:MapItem">
|
<Style x:Key="PointItemStyle" TargetType="map:MapItem">
|
||||||
<Setter Property="AutoCollapse" Value="True"/>
|
<Setter Property="AutoCollapse" Value="True"/>
|
||||||
<Setter Property="LocationMemberPath" Value="Location"/>
|
<Setter Property="LocationMemberPath" Value="Location"/>
|
||||||
|
|
@ -87,44 +82,19 @@
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
</Style>
|
</Style>
|
||||||
|
</Grid.Resources>
|
||||||
|
|
||||||
<map:WebMercatorProjection x:Key="WebMercatorProjection"/>
|
<map:Map x:Name="map"
|
||||||
<map:WorldMercatorProjection x:Key="WorldMercatorProjection"/>
|
MinZoomLevel="2" MaxZoomLevel="21" ZoomLevel="11" ManipulationMode="All"
|
||||||
<map:EquirectangularProjection x:Key="EquirectangularProjection"/>
|
MapLayer="{Binding MapLayers[OpenStreetMap]}"
|
||||||
<map:OrthographicProjection x:Key="OrthographicProjection"/>
|
PointerMoved="MapPointerMoved"
|
||||||
<map:GnomonicProjection x:Key="GnomonicProjection"/>
|
PointerExited="MapPointerExited">
|
||||||
<map:StereographicProjection x:Key="StereographicProjection"/>
|
<map:Map.Center>
|
||||||
</Page.Resources>
|
<map:Location Latitude="53.5" Longitude="8.2"/>
|
||||||
|
</map:Map.Center>
|
||||||
|
|
||||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
|
|
||||||
<map:Map x:Name="map" MinZoomLevel="2" MaxZoomLevel="20" ZoomLevel="11" ManipulationMode="All"
|
|
||||||
Center="{x:Bind ViewModel.MapCenter, Mode=TwoWay}"
|
|
||||||
MapLayer="{x:Bind ViewModel.MapLayers.CurrentMapLayer, Mode=OneWay}"
|
|
||||||
MapProjection="{Binding SelectedValue, ElementName=projectionComboBox,
|
|
||||||
FallbackValue={StaticResource WebMercatorProjection},
|
|
||||||
TargetNullValue={StaticResource WebMercatorProjection}}">
|
|
||||||
|
|
||||||
<Image x:Name="mapImage" Source="10_535_330.jpg" Opacity="0.5" Stretch="Fill">
|
|
||||||
<map:MapPanel.BoundingBox>
|
|
||||||
<map:BoundingBox South="53.54031" North="53.74871" West="8.08594" East="8.43750"/>
|
|
||||||
</map:MapPanel.BoundingBox>
|
|
||||||
</Image>
|
|
||||||
|
|
||||||
<map:MapGraticule x:Name="graticule" Opacity="0.6"
|
|
||||||
Visibility="{Binding IsChecked, ElementName=graticuleCheckBox}"/>
|
|
||||||
|
|
||||||
<map:MapScale HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
|
|
||||||
|
|
||||||
<!-- use ItemTemplate or ItemContainerStyle alternatively -->
|
|
||||||
<map:MapItemsControl ItemsSource="{Binding Polylines}"
|
<map:MapItemsControl ItemsSource="{Binding Polylines}"
|
||||||
ItemTemplate="{StaticResource PolylineItemTemplate}"/>
|
ItemTemplate="{StaticResource PolylineItemTemplate}"/>
|
||||||
<!--<map:MapItemsControl ItemsSource="{Binding Polylines}"
|
|
||||||
ItemContainerStyle="{StaticResource PolylineItemStyle}"/>-->
|
|
||||||
|
|
||||||
<map:MapItemsControl ItemsSource="{Binding Points}"
|
<map:MapItemsControl ItemsSource="{Binding Points}"
|
||||||
ItemContainerStyle="{StaticResource PointItemStyle}"
|
ItemContainerStyle="{StaticResource PointItemStyle}"
|
||||||
|
|
@ -142,55 +112,29 @@
|
||||||
|
|
||||||
<Border HorizontalAlignment="Right" VerticalAlignment="Bottom" Background="#BFFFFFFF">
|
<Border HorizontalAlignment="Right" VerticalAlignment="Bottom" Background="#BFFFFFFF">
|
||||||
<TextBlock Margin="2" FontSize="10"
|
<TextBlock Margin="2" FontSize="10"
|
||||||
local:HyperlinkText.InlinesSource="{Binding MapLayers.CurrentMapLayer.Description}"/>
|
local:HyperlinkText.InlinesSource="{Binding MapLayer.Description, ElementName=map}"/>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<Grid Grid.Row="1">
|
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Margin="6" Background="#7FFFFFFF">
|
||||||
<Grid.ColumnDefinitions>
|
<local:MapLayersMenuButton
|
||||||
<ColumnDefinition/>
|
Margin="2" Padding="8" ToolTipService.ToolTip="Map Layers"
|
||||||
<ColumnDefinition Width="Auto"/>
|
Map="{Binding ElementName=map}"
|
||||||
</Grid.ColumnDefinitions>
|
MapLayers="{Binding MapLayers}"
|
||||||
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
|
MapOverlays="{Binding MapOverlays}"/>
|
||||||
<StackPanel Margin="5">
|
|
||||||
<TextBlock Text="Zoom Level" HorizontalAlignment="Center" FontSize="12"/>
|
<!--<local:MapProjectionsMenuButton
|
||||||
<Slider Margin="10,-10,10,0" Width="100" SmallChange="0.1"
|
Margin="2" Padding="8" ToolTipService.ToolTip="Map Projections"
|
||||||
|
Map="{Binding ElementName=map}"
|
||||||
|
MapProjections="{Binding MapProjections}"/>-->
|
||||||
|
|
||||||
|
<Slider Orientation="Vertical" Margin="4,8" Height="100"
|
||||||
Minimum="{Binding MinZoomLevel, ElementName=map}"
|
Minimum="{Binding MinZoomLevel, ElementName=map}"
|
||||||
Maximum="{Binding MaxZoomLevel, ElementName=map}"
|
Maximum="{Binding MaxZoomLevel, ElementName=map}"
|
||||||
Value="{Binding TargetZoomLevel, ElementName=map, Mode=TwoWay}"/>
|
Value="{Binding TargetZoomLevel, ElementName=map, Mode=TwoWay}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel Margin="5">
|
<Border HorizontalAlignment="Center" VerticalAlignment="Top" Margin="4" Background="#AFFFFFFF">
|
||||||
<TextBlock Text="Heading" HorizontalAlignment="Center" FontSize="12"/>
|
<TextBlock x:Name="mouseLocation" Margin="4,2" Visibility="Collapsed"/>
|
||||||
<Slider Margin="10,-10,10,0" Width="100" Minimum="0" Maximum="360" SmallChange="5" LargeChange="45"
|
</Border>
|
||||||
Value="{Binding Heading, ElementName=map, Mode=TwoWay}"/>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<StackPanel Margin="5,5,25,5">
|
|
||||||
<TextBlock Text="Image Opacity" HorizontalAlignment="Center" FontSize="12"/>
|
|
||||||
<Slider Margin="10,-10,10,0" Width="100" Value="50" ValueChanged="ImageOpacitySliderValueChanged"/>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<CheckBox x:Name="graticuleCheckBox"
|
|
||||||
VerticalAlignment="Center" Content="Graticule"/>
|
|
||||||
|
|
||||||
<CheckBox VerticalAlignment="Center" Content="Seamarks"
|
|
||||||
Checked="SeamarksChecked" Unchecked="SeamarksUnchecked"/>
|
|
||||||
|
|
||||||
<ComboBox Width="250" VerticalAlignment="Center" Margin="0,5"
|
|
||||||
ItemsSource="{Binding MapLayers.MapLayerNames}"
|
|
||||||
SelectedItem="{Binding MapLayers.CurrentMapLayerName, Mode=TwoWay}"/>
|
|
||||||
|
|
||||||
<ComboBox x:Name="projectionComboBox" Width="150" VerticalAlignment="Center" Margin="5"
|
|
||||||
SelectedIndex="0" SelectedValuePath="Tag"
|
|
||||||
SelectedValue="{Binding MapProjection, ElementName=map, Mode=TwoWay}">
|
|
||||||
<ComboBoxItem Content="Web Mercator" Tag="{StaticResource WebMercatorProjection}"/>
|
|
||||||
<ComboBoxItem Content="World Mercator" Tag="{StaticResource WorldMercatorProjection}"/>
|
|
||||||
<ComboBoxItem Content="Equirectangular" Tag="{StaticResource EquirectangularProjection}"/>
|
|
||||||
<ComboBoxItem Content="Orthographic" Tag="{StaticResource OrthographicProjection}"/>
|
|
||||||
<ComboBoxItem Content="Gnomonic" Tag="{StaticResource GnomonicProjection}"/>
|
|
||||||
<ComboBoxItem Content="Stereographic" Tag="{StaticResource StereographicProjection}"/>
|
|
||||||
</ComboBox>
|
|
||||||
</StackPanel>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Page>
|
</Page>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
using System;
|
using MapControl;
|
||||||
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using MapControl;
|
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
using Windows.UI.Xaml.Controls.Primitives;
|
using Windows.UI.Xaml.Input;
|
||||||
|
|
||||||
namespace SampleApplication
|
namespace SampleApplication
|
||||||
{
|
{
|
||||||
|
|
@ -28,30 +29,42 @@ namespace SampleApplication
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapViewModel ViewModel { get; } = new MapViewModel();
|
|
||||||
|
|
||||||
public MainPage()
|
public MainPage()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
DataContext = ViewModel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ImageOpacitySliderValueChanged(object sender, RangeBaseValueChangedEventArgs e)
|
private void MapPointerMoved(object sender, PointerRoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (mapImage != null)
|
var location = map.ViewToLocation(e.GetCurrentPoint(map).Position);
|
||||||
|
var latitude = (int)Math.Round(location.Latitude * 60000d);
|
||||||
|
var longitude = (int)Math.Round(Location.NormalizeLongitude(location.Longitude) * 60000d);
|
||||||
|
var latHemisphere = 'N';
|
||||||
|
var lonHemisphere = 'E';
|
||||||
|
|
||||||
|
if (latitude < 0)
|
||||||
{
|
{
|
||||||
mapImage.Opacity = e.NewValue / 100;
|
latitude = -latitude;
|
||||||
}
|
latHemisphere = 'S';
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SeamarksChecked(object sender, RoutedEventArgs e)
|
if (longitude < 0)
|
||||||
{
|
{
|
||||||
map.Children.Insert(map.Children.IndexOf(graticule), ViewModel.MapLayers.SeamarksLayer);
|
longitude = -longitude;
|
||||||
|
lonHemisphere = 'W';
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SeamarksUnchecked(object sender, RoutedEventArgs e)
|
mouseLocation.Text = string.Format(CultureInfo.InvariantCulture,
|
||||||
|
"{0} {1:00} {2:00.000}\n{3} {4:000} {5:00.000}",
|
||||||
|
latHemisphere, latitude / 60000, (latitude % 60000) / 1000d,
|
||||||
|
lonHemisphere, longitude / 60000, (longitude % 60000) / 1000d);
|
||||||
|
mouseLocation.Visibility = Visibility.Visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MapPointerExited(object sender, PointerRoutedEventArgs e)
|
||||||
{
|
{
|
||||||
map.Children.Remove(ViewModel.MapLayers.SeamarksLayer);
|
mouseLocation.Visibility = Visibility.Collapsed;
|
||||||
|
mouseLocation.Text = string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@
|
||||||
<Resource Language="x-generate" />
|
<Resource Language="x-generate" />
|
||||||
</Resources>
|
</Resources>
|
||||||
<Applications>
|
<Applications>
|
||||||
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="UniversalApp.App">
|
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="SampleApplication.App">
|
||||||
<uap:VisualElements DisplayName="XAML Map Control Test Application" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="UniversalApp" BackgroundColor="transparent">
|
<uap:VisualElements DisplayName="XAML Map Control Test Application" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="SampleApplication" BackgroundColor="transparent">
|
||||||
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png">
|
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png">
|
||||||
</uap:DefaultTile>
|
</uap:DefaultTile>
|
||||||
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<ProjectGuid>{AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}</ProjectGuid>
|
<ProjectGuid>{AA62B4AA-1CA3-4C20-BEB7-B824D0FC4BD1}</ProjectGuid>
|
||||||
<OutputType>AppContainerExe</OutputType>
|
<OutputType>AppContainerExe</OutputType>
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>UniversalApp</RootNamespace>
|
<RootNamespace>SampleApplication</RootNamespace>
|
||||||
<AssemblyName>UniversalApp</AssemblyName>
|
<AssemblyName>UniversalApp</AssemblyName>
|
||||||
<DefaultLanguage>en-US</DefaultLanguage>
|
<DefaultLanguage>en-US</DefaultLanguage>
|
||||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||||
|
|
@ -51,12 +51,18 @@
|
||||||
<Compile Include="..\Shared\HyperlinkText.cs">
|
<Compile Include="..\Shared\HyperlinkText.cs">
|
||||||
<Link>HyperlinkText.cs</Link>
|
<Link>HyperlinkText.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Shared\MapLayers.cs">
|
<Compile Include="..\Shared\MapLayersMenuButton.cs">
|
||||||
<Link>MapLayers.cs</Link>
|
<Link>MapLayersMenuButton.cs</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\Shared\MapProjectionsMenuButton.cs">
|
||||||
|
<Link>MapProjectionsMenuButton.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Shared\MapViewModel.cs">
|
<Compile Include="..\Shared\MapViewModel.cs">
|
||||||
<Link>MapViewModel.cs</Link>
|
<Link>MapViewModel.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\Shared\MenuButton.cs">
|
||||||
|
<Link>MenuButton.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="App.xaml.cs">
|
<Compile Include="App.xaml.cs">
|
||||||
<DependentUpon>App.xaml</DependentUpon>
|
<DependentUpon>App.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|
|
||||||
|
|
@ -2,24 +2,15 @@
|
||||||
x:Class="SampleApplication.MainWindow"
|
x:Class="SampleApplication.MainWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:map="using:MapControl">
|
xmlns:map="using:MapControl"
|
||||||
|
xmlns:local="using:SampleApplication">
|
||||||
|
|
||||||
<Grid x:Name="root">
|
<Grid>
|
||||||
<Grid.Resources>
|
<Grid.Resources>
|
||||||
<DataTemplate x:Key="PolylineItemTemplate">
|
<DataTemplate x:Key="PolylineItemTemplate">
|
||||||
<map:MapPolyline Locations="{Binding Locations}" Stroke="Red" StrokeThickness="3"/>
|
<map:MapPolyline Locations="{Binding Locations}" Stroke="Red" StrokeThickness="3"/>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
|
|
||||||
<Style x:Key="PolylineItemStyle" TargetType="map:MapItem">
|
|
||||||
<Setter Property="Template">
|
|
||||||
<Setter.Value>
|
|
||||||
<ControlTemplate TargetType="map:MapItem">
|
|
||||||
<map:MapPolyline Locations="{Binding Locations}" Stroke="Red" StrokeThickness="3"/>
|
|
||||||
</ControlTemplate>
|
|
||||||
</Setter.Value>
|
|
||||||
</Setter>
|
|
||||||
</Style>
|
|
||||||
|
|
||||||
<Style x:Key="PointItemStyle" TargetType="map:MapItem">
|
<Style x:Key="PointItemStyle" TargetType="map:MapItem">
|
||||||
<Setter Property="AutoCollapse" Value="True"/>
|
<Setter Property="AutoCollapse" Value="True"/>
|
||||||
<Setter Property="LocationMemberPath" Value="Location"/>
|
<Setter Property="LocationMemberPath" Value="Location"/>
|
||||||
|
|
@ -90,32 +81,22 @@
|
||||||
|
|
||||||
</Grid.Resources>
|
</Grid.Resources>
|
||||||
|
|
||||||
<Grid.RowDefinitions>
|
<Grid.DataContext>
|
||||||
<RowDefinition/>
|
<local:MapViewModel/>
|
||||||
<RowDefinition Height="Auto"/>
|
</Grid.DataContext>
|
||||||
</Grid.RowDefinitions>
|
|
||||||
|
|
||||||
<map:Map x:Name="map" ZoomLevel="11" MaxZoomLevel="21" MouseWheelZoomDelta=".5"
|
<map:Map x:Name="map"
|
||||||
Center="{Binding MapCenter}"
|
MinZoomLevel="2" MaxZoomLevel="21" ZoomLevel="11" MouseWheelZoomDelta="1"
|
||||||
MapLayer="{Binding MapLayers.CurrentMapLayer}"
|
MapLayer="{Binding MapLayers[OpenStreetMap]}"
|
||||||
ViewportChanged="MapViewportChanged">
|
ViewportChanged="MapViewportChanged"
|
||||||
|
PointerMoved="MapPointerMoved"
|
||||||
|
PointerExited="MapPointerExited">
|
||||||
|
<map:Map.Center>
|
||||||
|
<map:Location Latitude="53.5" Longitude="8.2"/>
|
||||||
|
</map:Map.Center>
|
||||||
|
|
||||||
<Image x:Name="mapImage" Source="10_535_330.jpg" Opacity="0.5" Stretch="Fill">
|
|
||||||
<map:MapPanel.BoundingBox>
|
|
||||||
<map:BoundingBox South="53.54031" North="53.74871" West="8.08594" East="8.43750"/>
|
|
||||||
</map:MapPanel.BoundingBox>
|
|
||||||
</Image>
|
|
||||||
|
|
||||||
<map:MapGraticule x:Name="graticule" Opacity="0.6"
|
|
||||||
Visibility="{Binding IsChecked, ElementName=graticuleCheckBox}"/>
|
|
||||||
|
|
||||||
<map:MapScale HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
|
|
||||||
|
|
||||||
<!-- use ItemTemplate or ItemContainerStyle alternatively -->
|
|
||||||
<map:MapItemsControl ItemsSource="{Binding Polylines}"
|
<map:MapItemsControl ItemsSource="{Binding Polylines}"
|
||||||
ItemTemplate="{StaticResource PolylineItemTemplate}"/>
|
ItemTemplate="{StaticResource PolylineItemTemplate}"/>
|
||||||
<!--<map:MapItemsControl ItemsSource="{Binding Polylines}"
|
|
||||||
ItemContainerStyle="{StaticResource PolylineItemStyle}"/>-->
|
|
||||||
|
|
||||||
<map:MapItemsControl ItemsSource="{Binding Points}"
|
<map:MapItemsControl ItemsSource="{Binding Points}"
|
||||||
ItemContainerStyle="{StaticResource PointItemStyle}"
|
ItemContainerStyle="{StaticResource PointItemStyle}"
|
||||||
|
|
@ -131,23 +112,30 @@
|
||||||
</map:Pushpin>
|
</map:Pushpin>
|
||||||
</map:Map>
|
</map:Map>
|
||||||
|
|
||||||
<Grid Grid.Row="1">
|
<Border HorizontalAlignment="Right" VerticalAlignment="Bottom" Background="#AFFFFFFF">
|
||||||
<Grid.ColumnDefinitions>
|
<TextBlock Margin="4,2" FontSize="10" local:HyperlinkText.InlinesSource="{Binding MapLayer.Description, ElementName=map}"/>
|
||||||
<ColumnDefinition/>
|
</Border>
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
|
|
||||||
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
|
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Margin="6">
|
||||||
<CheckBox x:Name="graticuleCheckBox"
|
<local:MapLayersMenuButton
|
||||||
VerticalAlignment="Center" Content="Graticule"/>
|
Margin="2" Padding="8" ToolTipService.ToolTip="Map Layers and Overlays"
|
||||||
|
Map="{Binding ElementName=map}"
|
||||||
|
MapLayers="{Binding MapLayers}"
|
||||||
|
MapOverlays="{Binding MapOverlays}"/>
|
||||||
|
|
||||||
<CheckBox VerticalAlignment="Center" Content="Seamarks"
|
<!--<local:MapProjectionsMenuButton
|
||||||
Checked="SeamarksChecked" Unchecked="SeamarksUnchecked"/>
|
Margin="2" Padding="8" ToolTipService.ToolTip="Map Projections"
|
||||||
|
Map="{Binding ElementName=map}"
|
||||||
|
MapProjections="{Binding MapProjections}"/>-->
|
||||||
|
|
||||||
<ComboBox Width="250" VerticalAlignment="Center" Margin="5"
|
<Slider Orientation="Vertical" Margin="4,8" Height="100"
|
||||||
ItemsSource="{Binding MapLayers.MapLayerNames}"
|
Minimum="{Binding MinZoomLevel, ElementName=map}"
|
||||||
SelectedItem="{Binding MapLayers.CurrentMapLayerName, Mode=TwoWay}"/>
|
Maximum="{Binding MaxZoomLevel, ElementName=map}"
|
||||||
|
Value="{Binding TargetZoomLevel, ElementName=map, Mode=TwoWay}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
|
||||||
|
<Border HorizontalAlignment="Center" VerticalAlignment="Top" Margin="4" Background="#AFFFFFFF">
|
||||||
|
<TextBlock x:Name="mouseLocation" Margin="4,2" Visibility="Collapsed"/>
|
||||||
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
using MapControl;
|
using MapControl;
|
||||||
using MapControl.Caching;
|
using MapControl.Caching;
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Input;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
|
@ -10,8 +12,6 @@ namespace SampleApplication
|
||||||
{
|
{
|
||||||
public sealed partial class MainWindow : Window
|
public sealed partial class MainWindow : Window
|
||||||
{
|
{
|
||||||
private readonly MapViewModel viewModel = new();
|
|
||||||
|
|
||||||
static MainWindow()
|
static MainWindow()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -39,8 +39,6 @@ namespace SampleApplication
|
||||||
|
|
||||||
Title = "XAML Map Control - WinUI Sample Application";
|
Title = "XAML Map Control - WinUI Sample Application";
|
||||||
|
|
||||||
root.DataContext = viewModel;
|
|
||||||
|
|
||||||
if (TileImageLoader.Cache is ImageFileCache)
|
if (TileImageLoader.Cache is ImageFileCache)
|
||||||
{
|
{
|
||||||
Activated += WindowActivated;
|
Activated += WindowActivated;
|
||||||
|
|
@ -55,19 +53,42 @@ namespace SampleApplication
|
||||||
await ((ImageFileCache)TileImageLoader.Cache).Clean();
|
await ((ImageFileCache)TileImageLoader.Cache).Clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SeamarksChecked(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
map.Children.Insert(map.Children.IndexOf(graticule), viewModel.MapLayers.SeamarksLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SeamarksUnchecked(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
map.Children.Remove(viewModel.MapLayers.SeamarksLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MapViewportChanged(object sender, ViewportChangedEventArgs e)
|
private void MapViewportChanged(object sender, ViewportChangedEventArgs e)
|
||||||
{
|
{
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void MapPointerMoved(object sender, PointerRoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var location = map.ViewToLocation(e.GetCurrentPoint(map).Position);
|
||||||
|
var latitude = (int)Math.Round(location.Latitude * 60000d);
|
||||||
|
var longitude = (int)Math.Round(Location.NormalizeLongitude(location.Longitude) * 60000d);
|
||||||
|
var latHemisphere = 'N';
|
||||||
|
var lonHemisphere = 'E';
|
||||||
|
|
||||||
|
if (latitude < 0)
|
||||||
|
{
|
||||||
|
latitude = -latitude;
|
||||||
|
latHemisphere = 'S';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (longitude < 0)
|
||||||
|
{
|
||||||
|
longitude = -longitude;
|
||||||
|
lonHemisphere = 'W';
|
||||||
|
}
|
||||||
|
|
||||||
|
mouseLocation.Text = string.Format(CultureInfo.InvariantCulture,
|
||||||
|
"{0} {1:00} {2:00.000}\n{3} {4:000} {5:00.000}",
|
||||||
|
latHemisphere, latitude / 60000, (latitude % 60000) / 1000d,
|
||||||
|
lonHemisphere, longitude / 60000, (longitude % 60000) / 1000d);
|
||||||
|
mouseLocation.Visibility = Visibility.Visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MapPointerExited(object sender, PointerRoutedEventArgs e)
|
||||||
|
{
|
||||||
|
mouseLocation.Visibility = Visibility.Collapsed;
|
||||||
|
mouseLocation.Text = string.Empty;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,8 @@
|
||||||
Executable="$targetnametoken$.exe"
|
Executable="$targetnametoken$.exe"
|
||||||
EntryPoint="$targetentrypoint$">
|
EntryPoint="$targetentrypoint$">
|
||||||
<uap:VisualElements
|
<uap:VisualElements
|
||||||
DisplayName="WinUiApp"
|
DisplayName="XAML Map Control Test Application"
|
||||||
Description="WinUiApp"
|
Description="SampleApplication"
|
||||||
BackgroundColor="transparent"
|
BackgroundColor="transparent"
|
||||||
Square150x150Logo="Assets\Square150x150Logo.png"
|
Square150x150Logo="Assets\Square150x150Logo.png"
|
||||||
Square44x44Logo="Assets\Square44x44Logo.png">
|
Square44x44Logo="Assets\Square44x44Logo.png">
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="..\Shared\10_535_330.jpg" Link="10_535_330.jpg" />
|
<Content Include="..\Shared\10_535_330.jpg" Link="10_535_330.jpg"/>
|
||||||
<Content Include="Assets\SplashScreen.scale-200.png" />
|
<Content Include="Assets\SplashScreen.scale-200.png" />
|
||||||
<Content Include="Assets\LockScreenLogo.scale-200.png" />
|
<Content Include="Assets\LockScreenLogo.scale-200.png" />
|
||||||
<Content Include="Assets\Square150x150Logo.scale-200.png" />
|
<Content Include="Assets\Square150x150Logo.scale-200.png" />
|
||||||
|
|
|
||||||
5
SampleApps/WinUiApp/WinUiApp.csproj.user
Normal file
5
SampleApps/WinUiApp/WinUiApp.csproj.user
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup />
|
||||||
|
<ItemGroup />
|
||||||
|
</Project>
|
||||||
|
|
@ -5,21 +5,12 @@
|
||||||
xmlns:local="clr-namespace:SampleApplication"
|
xmlns:local="clr-namespace:SampleApplication"
|
||||||
Title="XAML MapControl - WPF Sample Application" Height="600" Width="900"
|
Title="XAML MapControl - WPF Sample Application" Height="600" Width="900"
|
||||||
Stylus.IsPressAndHoldEnabled="False">
|
Stylus.IsPressAndHoldEnabled="False">
|
||||||
<Window.Resources>
|
<Grid>
|
||||||
<DataTemplate x:Key="PolylineItemTemplate">
|
<Grid.Resources>
|
||||||
|
<DataTemplate DataType="{x:Type local:PolylineItem}">
|
||||||
<map:MapPolyline Locations="{Binding Locations}" Stroke="Red" StrokeThickness="3"/>
|
<map:MapPolyline Locations="{Binding Locations}" Stroke="Red" StrokeThickness="3"/>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
|
|
||||||
<Style x:Key="PolylineItemStyle" TargetType="map:MapItem">
|
|
||||||
<Setter Property="Template">
|
|
||||||
<Setter.Value>
|
|
||||||
<ControlTemplate TargetType="map:MapItem">
|
|
||||||
<map:MapPolyline Locations="{Binding Locations}" Stroke="Red" StrokeThickness="3"/>
|
|
||||||
</ControlTemplate>
|
|
||||||
</Setter.Value>
|
|
||||||
</Setter>
|
|
||||||
</Style>
|
|
||||||
|
|
||||||
<Style x:Key="PointItemStyle" TargetType="map:MapItem">
|
<Style x:Key="PointItemStyle" TargetType="map:MapItem">
|
||||||
<EventSetter Event="TouchDown" Handler="MapItemTouchDown"/>
|
<EventSetter Event="TouchDown" Handler="MapItemTouchDown"/>
|
||||||
<Setter Property="AutoCollapse" Value="True"/>
|
<Setter Property="AutoCollapse" Value="True"/>
|
||||||
|
|
@ -101,51 +92,27 @@
|
||||||
</Style.Triggers>
|
</Style.Triggers>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
|
||||||
|
|
||||||
<map:WebMercatorProjection x:Key="WebMercatorProjection"/>
|
<map:WebMercatorProjection x:Key="WebMercatorProjection"/>
|
||||||
<map:WorldMercatorProjection x:Key="WorldMercatorProjection"/>
|
<map:WorldMercatorProjection x:Key="WorldMercatorProjection"/>
|
||||||
<map:EquirectangularProjection x:Key="EquirectangularProjection"/>
|
<map:EquirectangularProjection x:Key="EquirectangularProjection"/>
|
||||||
<map:OrthographicProjection x:Key="OrthographicProjection"/>
|
<map:OrthographicProjection x:Key="OrthographicProjection"/>
|
||||||
<map:GnomonicProjection x:Key="GnomonicProjection"/>
|
<map:GnomonicProjection x:Key="GnomonicProjection"/>
|
||||||
<map:StereographicProjection x:Key="StereographicProjection"/>
|
<map:StereographicProjection x:Key="StereographicProjection"/>
|
||||||
</Window.Resources>
|
</Grid.Resources>
|
||||||
|
|
||||||
<Window.DataContext>
|
<Grid.DataContext>
|
||||||
<local:MapViewModel/>
|
<local:MapViewModel/>
|
||||||
</Window.DataContext>
|
</Grid.DataContext>
|
||||||
|
|
||||||
<Grid>
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<map:Map x:Name="map" ZoomLevel="11" MaxZoomLevel="21" MouseWheelZoomDelta="1"
|
<map:Map x:Name="map" ZoomLevel="11" MaxZoomLevel="21" MouseWheelZoomDelta="1"
|
||||||
Center="{Binding MapCenter}"
|
Center="53.5,8.2"
|
||||||
MapLayer="{Binding MapLayers.CurrentMapLayer}"
|
MapLayer="{Binding MapLayers[OpenStreetMap]}"
|
||||||
MapProjection="{Binding SelectedValue, ElementName=projectionComboBox,
|
|
||||||
FallbackValue={StaticResource WebMercatorProjection},
|
|
||||||
TargetNullValue={StaticResource WebMercatorProjection}}"
|
|
||||||
MouseLeftButtonDown="MapMouseLeftButtonDown"
|
MouseLeftButtonDown="MapMouseLeftButtonDown"
|
||||||
MouseRightButtonDown="MapMouseRightButtonDown"
|
MouseRightButtonDown="MapMouseRightButtonDown"
|
||||||
MouseMove="MapMouseMove" MouseLeave="MapMouseLeave"
|
MouseMove="MapMouseMove" MouseLeave="MapMouseLeave"
|
||||||
ManipulationInertiaStarting="MapManipulationInertiaStarting">
|
ManipulationInertiaStarting="MapManipulationInertiaStarting">
|
||||||
|
|
||||||
<Image Source="10_535_330.jpg" Stretch="Fill"
|
<map:MapItemsControl ItemsSource="{Binding Polylines}"/>
|
||||||
Opacity="{Binding Value, ElementName=imageOpacitySlider}"
|
|
||||||
map:MapPanel.BoundingBox="53.54031,8.08594,53.74871,8.43750"/>
|
|
||||||
|
|
||||||
<map:MapGraticule x:Name="graticule" Opacity="0.6"
|
|
||||||
Visibility="{Binding IsChecked, ElementName=graticuleCheckBox,
|
|
||||||
Converter={StaticResource BooleanToVisibilityConverter}}"/>
|
|
||||||
|
|
||||||
<map:MapScale HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
|
|
||||||
|
|
||||||
<!-- use ItemTemplate or ItemContainerStyle alternatively -->
|
|
||||||
<map:MapItemsControl ItemsSource="{Binding Polylines}"
|
|
||||||
ItemTemplate="{StaticResource PolylineItemTemplate}"/>
|
|
||||||
<!--<map:MapItemsControl ItemsSource="{Binding Polylines}"
|
|
||||||
ItemContainerStyle="{StaticResource PolylineItemStyle}"/>-->
|
|
||||||
|
|
||||||
<map:MapItemsControl ItemsSource="{Binding Points}"
|
<map:MapItemsControl ItemsSource="{Binding Points}"
|
||||||
ItemContainerStyle="{StaticResource PointItemStyle}"
|
ItemContainerStyle="{StaticResource PointItemStyle}"
|
||||||
|
|
@ -169,58 +136,34 @@
|
||||||
</map:Map>
|
</map:Map>
|
||||||
|
|
||||||
<Border HorizontalAlignment="Right" VerticalAlignment="Bottom" Background="#AFFFFFFF">
|
<Border HorizontalAlignment="Right" VerticalAlignment="Bottom" Background="#AFFFFFFF">
|
||||||
<TextBlock Margin="4,2" FontSize="10" local:HyperlinkText.InlinesSource="{Binding MapLayer.Description, ElementName=map}"/>
|
<TextBlock Margin="4,2" FontSize="10"
|
||||||
|
local:HyperlinkText.InlinesSource="{Binding MapLayer.Description, ElementName=map}"/>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<Grid Grid.Row="1">
|
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Margin="6">
|
||||||
<Grid.ColumnDefinitions>
|
<local:MapLayersMenuButton
|
||||||
<ColumnDefinition/>
|
Margin="2" Padding="6" FontSize="16" ToolTip="Map Layers and Overlays"
|
||||||
<ColumnDefinition Width="Auto"/>
|
Map="{Binding ElementName=map}"
|
||||||
</Grid.ColumnDefinitions>
|
MapLayers="{Binding MapLayers}"
|
||||||
<TextBlock x:Name="mouseLocation" Margin="5" VerticalAlignment="Bottom" FontFamily="Segoe UI Mono"/>
|
MapOverlays="{Binding MapOverlays}"/>
|
||||||
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
|
|
||||||
<StackPanel Margin="5">
|
<!--<local:MapProjectionsMenuButton
|
||||||
<TextBlock Text="Zoom Level" Margin="0,0,0,2" HorizontalAlignment="Center" FontSize="10"/>
|
Margin="2" Padding="6" FontSize="16" ToolTip="Map Projections"
|
||||||
<Slider AutoToolTipPlacement="TopLeft" AutoToolTipPrecision="0"
|
Map="{Binding ElementName=map}"
|
||||||
Width="75" VerticalAlignment="Center" SmallChange="0.01"
|
MapProjections="{Binding MapProjections}"/>-->
|
||||||
|
|
||||||
|
<Slider Orientation="Vertical" Margin="8" Height="100"
|
||||||
Minimum="{Binding MinZoomLevel, ElementName=map}"
|
Minimum="{Binding MinZoomLevel, ElementName=map}"
|
||||||
Maximum="{Binding MaxZoomLevel, ElementName=map}"
|
Maximum="{Binding MaxZoomLevel, ElementName=map}"
|
||||||
Value="{Binding TargetZoomLevel, ElementName=map}"/>
|
Value="{Binding TargetZoomLevel, ElementName=map}"
|
||||||
|
SmallChange="0.1"
|
||||||
|
AutoToolTipPlacement="BottomRight" AutoToolTipPrecision="0"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel Margin="5">
|
<local:OutlinedText
|
||||||
<TextBlock Text="Heading" Margin="0,0,0,2" HorizontalAlignment="Center" FontSize="10"/>
|
x:Name="mouseLocation" Margin="4"
|
||||||
<Slider AutoToolTipPlacement="TopLeft" AutoToolTipPrecision="0"
|
Background="{Binding Background, ElementName=map}"
|
||||||
Width="75" VerticalAlignment="Center" SmallChange="5" LargeChange="45"
|
Foreground="{Binding Foreground, ElementName=map}"
|
||||||
Minimum="0" Maximum="360" Value="{Binding TargetHeading, ElementName=map}"/>
|
HorizontalAlignment="Center" VerticalAlignment="Top"/>
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<StackPanel Margin="5">
|
|
||||||
<TextBlock Text="Image Opacity" Margin="0,0,0,2" HorizontalAlignment="Center" FontSize="10"/>
|
|
||||||
<Slider x:Name="imageOpacitySlider" AutoToolTipPlacement="TopLeft" AutoToolTipPrecision="1"
|
|
||||||
Width="75" VerticalAlignment="Center" Minimum="0" Maximum="1" Value="0.5"/>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<CheckBox x:Name="graticuleCheckBox" ToolTip="Graticule Overlay" Margin="8"
|
|
||||||
VerticalAlignment="Bottom" Content="Graticule"/>
|
|
||||||
|
|
||||||
<CheckBox ToolTip="Seamarks Overlay" Margin="8" VerticalAlignment="Bottom" Content="Seamarks"
|
|
||||||
Checked="SeamarksChecked" Unchecked="SeamarksUnchecked"/>
|
|
||||||
|
|
||||||
<ComboBox ToolTip="Map Layer" Width="200" Margin="5" VerticalAlignment="Bottom"
|
|
||||||
ItemsSource="{Binding MapLayers.MapLayerNames}"
|
|
||||||
SelectedItem="{Binding MapLayers.CurrentMapLayerName}"/>
|
|
||||||
|
|
||||||
<ComboBox x:Name="projectionComboBox" ToolTip="Map Projection" Width="120" Margin="5" VerticalAlignment="Bottom"
|
|
||||||
SelectedValuePath="Tag" SelectedIndex="0">
|
|
||||||
<ComboBoxItem Content="Web Mercator" Tag="{StaticResource WebMercatorProjection}"/>
|
|
||||||
<ComboBoxItem Content="World Mercator" Tag="{StaticResource WorldMercatorProjection}"/>
|
|
||||||
<ComboBoxItem Content="Equirectangular" Tag="{StaticResource EquirectangularProjection}"/>
|
|
||||||
<ComboBoxItem Content="Orthographic" Tag="{StaticResource OrthographicProjection}"/>
|
|
||||||
<ComboBoxItem Content="Gnomonic" Tag="{StaticResource GnomonicProjection}"/>
|
|
||||||
<ComboBoxItem Content="Stereographic" Tag="{StaticResource StereographicProjection}"/>
|
|
||||||
</ComboBox>
|
|
||||||
</StackPanel>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
using System;
|
using MapControl;
|
||||||
|
using MapControl.Caching;
|
||||||
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using MapControl;
|
|
||||||
using MapControl.Caching;
|
|
||||||
|
|
||||||
namespace SampleApplication
|
namespace SampleApplication
|
||||||
{
|
{
|
||||||
|
|
@ -108,15 +108,5 @@ namespace SampleApplication
|
||||||
mapItem.IsSelected = !mapItem.IsSelected;
|
mapItem.IsSelected = !mapItem.IsSelected;
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SeamarksChecked(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
map.Children.Insert(map.Children.IndexOf(graticule), ((MapViewModel)DataContext).MapLayers.SeamarksLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SeamarksUnchecked(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
map.Children.Remove(((MapViewModel)DataContext).MapLayers.SeamarksLayer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Windows;
|
using System.Globalization;
|
||||||
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
|
@ -6,36 +7,49 @@ namespace SampleApplication
|
||||||
{
|
{
|
||||||
public class OutlinedText : FrameworkElement
|
public class OutlinedText : FrameworkElement
|
||||||
{
|
{
|
||||||
private GlyphRun glyphRun;
|
private FormattedText text;
|
||||||
private Geometry outline;
|
private Geometry outline;
|
||||||
|
|
||||||
public static readonly DependencyProperty TextProperty = TextBlock.TextProperty.AddOwner(
|
public static readonly DependencyProperty TextProperty = TextBlock.TextProperty.AddOwner(
|
||||||
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null) { AffectsMeasure = true });
|
typeof(OutlinedText),
|
||||||
|
new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).text = null) { AffectsMeasure = true });
|
||||||
|
|
||||||
public static readonly DependencyProperty FontSizeProperty = TextBlock.FontSizeProperty.AddOwner(
|
public static readonly DependencyProperty FontSizeProperty = TextBlock.FontSizeProperty.AddOwner(
|
||||||
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null) { AffectsMeasure = true });
|
typeof(OutlinedText),
|
||||||
|
new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).text = null) { AffectsMeasure = true });
|
||||||
|
|
||||||
public static readonly DependencyProperty FontFamilyProperty = TextBlock.FontFamilyProperty.AddOwner(
|
public static readonly DependencyProperty FontFamilyProperty = TextBlock.FontFamilyProperty.AddOwner(
|
||||||
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null) { AffectsMeasure = true });
|
typeof(OutlinedText),
|
||||||
|
new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).text = null) { AffectsMeasure = true });
|
||||||
|
|
||||||
public static readonly DependencyProperty FontStyleProperty = TextBlock.FontStyleProperty.AddOwner(
|
public static readonly DependencyProperty FontStyleProperty = TextBlock.FontStyleProperty.AddOwner(
|
||||||
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null) { AffectsMeasure = true });
|
typeof(OutlinedText),
|
||||||
|
new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).text = null) { AffectsMeasure = true });
|
||||||
|
|
||||||
public static readonly DependencyProperty FontWeightProperty = TextBlock.FontWeightProperty.AddOwner(
|
public static readonly DependencyProperty FontWeightProperty = TextBlock.FontWeightProperty.AddOwner(
|
||||||
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null) { AffectsMeasure = true });
|
typeof(OutlinedText),
|
||||||
|
new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).text = null) { AffectsMeasure = true });
|
||||||
|
|
||||||
public static readonly DependencyProperty FontStretchProperty = TextBlock.FontStretchProperty.AddOwner(
|
public static readonly DependencyProperty FontStretchProperty = TextBlock.FontStretchProperty.AddOwner(
|
||||||
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null) { AffectsMeasure = true });
|
typeof(OutlinedText),
|
||||||
|
new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).text = null) { AffectsMeasure = true });
|
||||||
|
|
||||||
public static readonly DependencyProperty ForegroundProperty = TextBlock.ForegroundProperty.AddOwner(
|
public static readonly DependencyProperty ForegroundProperty = TextBlock.ForegroundProperty.AddOwner(
|
||||||
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null) { AffectsMeasure = true });
|
typeof(OutlinedText),
|
||||||
|
new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).text = null) { AffectsMeasure = true });
|
||||||
|
|
||||||
public static readonly DependencyProperty BackgroundProperty = TextBlock.BackgroundProperty.AddOwner(
|
public static readonly DependencyProperty BackgroundProperty = TextBlock.BackgroundProperty.AddOwner(
|
||||||
typeof(OutlinedText), new FrameworkPropertyMetadata(Brushes.White, (o, e) => ((OutlinedText)o).glyphRun = null) { AffectsMeasure = true });
|
typeof(OutlinedText),
|
||||||
|
new FrameworkPropertyMetadata(Brushes.White, (o, e) => ((OutlinedText)o).text = null) { AffectsMeasure = true });
|
||||||
|
|
||||||
public static readonly DependencyProperty OutlineThicknessProperty = DependencyProperty.Register(
|
public static readonly DependencyProperty OutlineThicknessProperty = DependencyProperty.Register(
|
||||||
"OutlineThickness", typeof(double), typeof(OutlinedText),
|
nameof(OutlineThickness), typeof(double), typeof(OutlinedText),
|
||||||
new FrameworkPropertyMetadata(1d, FrameworkPropertyMetadataOptions.AffectsMeasure, (o, e) => ((OutlinedText)o).glyphRun = null));
|
new FrameworkPropertyMetadata(1d, FrameworkPropertyMetadataOptions.AffectsMeasure, (o, e) => ((OutlinedText)o).text = null));
|
||||||
|
|
||||||
|
public OutlinedText()
|
||||||
|
{
|
||||||
|
IsHitTestVisible = false;
|
||||||
|
}
|
||||||
|
|
||||||
public string Text
|
public string Text
|
||||||
{
|
{
|
||||||
|
|
@ -93,23 +107,23 @@ namespace SampleApplication
|
||||||
|
|
||||||
protected override Size MeasureOverride(Size availableSize)
|
protected override Size MeasureOverride(Size availableSize)
|
||||||
{
|
{
|
||||||
return CheckGlyphRun() ? outline.Bounds.Size : new Size();
|
return ValidateText() ? outline.Bounds.Size : new Size();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnRender(DrawingContext drawingContext)
|
protected override void OnRender(DrawingContext drawingContext)
|
||||||
{
|
{
|
||||||
if (CheckGlyphRun())
|
if (ValidateText())
|
||||||
{
|
{
|
||||||
var location = outline.Bounds.Location;
|
var location = outline.Bounds.Location;
|
||||||
drawingContext.PushTransform(new TranslateTransform(-location.X, -location.Y));
|
drawingContext.PushTransform(new TranslateTransform(-location.X, -location.Y));
|
||||||
drawingContext.DrawGeometry(Background, null, outline);
|
drawingContext.DrawGeometry(Background, null, outline);
|
||||||
drawingContext.DrawGlyphRun(Foreground, glyphRun);
|
drawingContext.DrawText(text, new Point());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CheckGlyphRun()
|
private bool ValidateText()
|
||||||
{
|
{
|
||||||
if (glyphRun == null)
|
if (text == null)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(Text))
|
if (string.IsNullOrEmpty(Text))
|
||||||
{
|
{
|
||||||
|
|
@ -123,19 +137,22 @@ namespace SampleApplication
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var glyphIndices = new ushort[Text.Length];
|
text = new FormattedText(Text,
|
||||||
var advanceWidths = new double[Text.Length];
|
CultureInfo.InvariantCulture,
|
||||||
|
FlowDirection.LeftToRight,
|
||||||
|
typeface,
|
||||||
|
FontSize,
|
||||||
|
Foreground,
|
||||||
|
VisualTreeHelper.GetDpi(this).PixelsPerDip);
|
||||||
|
|
||||||
for (int i = 0; i < Text.Length; i++)
|
outline = text.BuildGeometry(new Point()).GetWidenedPathGeometry(
|
||||||
|
new Pen
|
||||||
{
|
{
|
||||||
var glyphIndex = glyphTypeface.CharacterToGlyphMap[Text[i]];
|
Thickness = OutlineThickness * 2d,
|
||||||
glyphIndices[i] = glyphIndex;
|
LineJoin = PenLineJoin.Round,
|
||||||
advanceWidths[i] = glyphTypeface.AdvanceWidths[glyphIndex] * FontSize;
|
StartLineCap = PenLineCap.Round,
|
||||||
}
|
EndLineCap = PenLineCap.Round
|
||||||
|
});
|
||||||
glyphRun = new GlyphRun(glyphTypeface, 0, false, FontSize, 1f, glyphIndices, new Point(), advanceWidths, null, null, null, null, null, null);
|
|
||||||
|
|
||||||
outline = glyphRun.BuildGeometry().GetWidenedPathGeometry(new Pen(null, OutlineThickness * 2d));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,18 @@
|
||||||
<Compile Include="..\Shared\*.cs" />
|
<Compile Include="..\Shared\*.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Remove="..\Shared\MapLayers.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\MapControl\WPF\MapControl.WPF.csproj" />
|
<ProjectReference Include="..\..\MapControl\WPF\MapControl.WPF.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Resource Include="..\Shared\10_535_330.jpg" Link="10_535_330.jpg" />
|
<Content Include="..\Shared\10_535_330.jpg" Link="10_535_330.jpg">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFramework)'=='net48'">
|
<ItemGroup Condition="'$(TargetFramework)'=='net48'">
|
||||||
|
|
@ -29,4 +35,9 @@
|
||||||
<Reference Include="System.Runtime.Caching" />
|
<Reference Include="System.Runtime.Caching" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="App.config">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
Loading…
Reference in a new issue