diff --git a/SampleApps/ProjectionDemo/App.xaml b/SampleApps/ProjectionDemo/App.xaml new file mode 100644 index 00000000..df9195b6 --- /dev/null +++ b/SampleApps/ProjectionDemo/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/SampleApps/ProjectionDemo/App.xaml.cs b/SampleApps/ProjectionDemo/App.xaml.cs new file mode 100644 index 00000000..d72fe032 --- /dev/null +++ b/SampleApps/ProjectionDemo/App.xaml.cs @@ -0,0 +1,8 @@ +using System.Windows; + +namespace ProjectionDemo +{ + public partial class App : Application + { + } +} diff --git a/SampleApps/ProjectionDemo/MainWindow.xaml b/SampleApps/ProjectionDemo/MainWindow.xaml new file mode 100644 index 00000000..67edff83 --- /dev/null +++ b/SampleApps/ProjectionDemo/MainWindow.xaml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/SampleApps/ProjectionDemo/MainWindow.xaml.cs b/SampleApps/ProjectionDemo/MainWindow.xaml.cs new file mode 100644 index 00000000..173623f7 --- /dev/null +++ b/SampleApps/ProjectionDemo/MainWindow.xaml.cs @@ -0,0 +1,156 @@ +using MapControl; +using MapControl.Projections; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Input; + +namespace ProjectionDemo +{ + public partial class MainWindow : Window + { + private readonly HttpClient httpClient = new HttpClient(); + private readonly ViewModel viewModel = new ViewModel(); + + public MainWindow() + { + InitializeComponent(); + } + + private async Task GetWktAsync(int epsgCode) + { + var wkt = await httpClient.GetStringAsync(string.Format("https://epsg.io/{0}.wkt", epsgCode)); + + if (!wkt.Contains("PARAMETER[\"latitude_of_origin\",") && + !wkt.Contains("PARAMETER[\"latitude_of_center\",")) + { + wkt = wkt.Replace( + "PARAMETER[\"central_meridian\",", + "PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"central_meridian\","); + } + + return wkt; + } + + private async void Window_Loaded(object sender, RoutedEventArgs e) + { + viewModel.Projections.Add(new MapControl.Projections.WebMercatorProjection()); + + viewModel.Projections.Add(new GeoApiProjection + { + WKT = await httpClient.GetStringAsync("https://epsg.io/25832.wkt") // ETRS89 / UTM zone 32N + }); + + viewModel.Layers.Add( + "OpenStreetMap WMS", + new WmsImageLayer + { + ServiceUri = new Uri("http://ows.terrestris.de/osm/service"), + Layers = "OSM-WMS" + }); + + viewModel.Layers.Add( + "TopPlusOpen WMS", + new WmsImageLayer + { + ServiceUri = new Uri("https://sgx.geodatenzentrum.de/wms_topplus_open"), + Layers = "web" + }); + + viewModel.Layers.Add( + "Orthophotos Wiesbaden", + new WmsImageLayer + { + ServiceUri = new Uri("https://geoportal.wiesbaden.de/cgi-bin/mapserv.fcgi?map=d:/openwimap/umn/map/orthophoto/orthophotos.map"), + Layers = "orthophoto2017" + }); + + viewModel.CurrentProjection = viewModel.Projections[0]; + viewModel.CurrentLayer = viewModel.Layers.First().Value; + + DataContext = viewModel; + } + + private void Map_MouseRightButtonUp(object sender, MouseButtonEventArgs e) + { + viewModel.PushpinLocation = viewModel.CurrentProjection.ViewportPointToLocation(e.GetPosition((IInputElement)sender)); + } + } + + public class ViewModel : INotifyPropertyChanged + { + private MapProjection currentProjection; + private IMapLayer currentLayer; + private Location pushpinLocation = new Location(); + + public event PropertyChangedEventHandler PropertyChanged; + + public List Projections { get; } = new List(); + + public Dictionary Layers { get; } = new Dictionary(); + + public MapProjection CurrentProjection + { + get => currentProjection; + set + { + currentProjection = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CurrentProjection))); + } + } + + public IMapLayer CurrentLayer + { + get => currentLayer; + set + { + currentLayer = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CurrentLayer))); + } + } + + public Location PushpinLocation + { + get => pushpinLocation; + set + { + pushpinLocation = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(PushpinLocation))); + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(PushpinText))); + } + } + + public string PushpinText + { + get + { + var latitude = (int)Math.Round(PushpinLocation.Latitude * 3600); + var longitude = (int)Math.Round(Location.NormalizeLongitude(PushpinLocation.Longitude) * 3600); + var latHemisphere = 'N'; + var lonHemisphere = 'E'; + + if (latitude < 0) + { + latitude = -latitude; + latHemisphere = 'S'; + } + + if (longitude < 0) + { + longitude = -longitude; + lonHemisphere = 'W'; + } + + return string.Format(CultureInfo.InvariantCulture, + "{0} {1:00} {2:00} {3:00}\n{4} {5:000} {6:00} {7:00}", + latHemisphere, latitude / 3600, (latitude / 60) % 60, latitude % 60, + lonHemisphere, longitude / 3600, (longitude / 60) % 60, longitude % 60); + } + } + } +} diff --git a/SampleApps/ProjectionDemo/ProjectionDemo.csproj b/SampleApps/ProjectionDemo/ProjectionDemo.csproj new file mode 100644 index 00000000..11f756c9 --- /dev/null +++ b/SampleApps/ProjectionDemo/ProjectionDemo.csproj @@ -0,0 +1,19 @@ + + + + WinExe + netcoreapp3.1 + true + 4.17.0 + Clemens Fischer + XAML Map Control Map Projection Demo Application + XAML Map Control + Copyright © 2020 Clemens Fischer + + + + + + + + \ No newline at end of file diff --git a/SampleApps/ProjectionDemo/ProjectionDemo.csproj.user b/SampleApps/ProjectionDemo/ProjectionDemo.csproj.user new file mode 100644 index 00000000..644b0a6f --- /dev/null +++ b/SampleApps/ProjectionDemo/ProjectionDemo.csproj.user @@ -0,0 +1,14 @@ + + + + + + Designer + + + + + Designer + + + \ No newline at end of file