From 7aa91a84de3bf3a7d6a9c2e9fd6d7f6aff18ee9b Mon Sep 17 00:00:00 2001 From: ClemensF Date: Thu, 13 Dec 2018 18:09:34 +0100 Subject: [PATCH] Version 4.12. Added MapControl.Images project --- MBTiles/UWP/MBTiles.UWP.csproj | 4 +- MapImages/Shared/WorldFile.cs | 72 +++++++++++++++++-- MapImages/Shared/WorldFileParameters.cs | 94 ------------------------- MapImages/UWP/MapImages.UWP.csproj | 3 - MapImages/WPF/MapImages.WPF.csproj | 3 - 5 files changed, 69 insertions(+), 107 deletions(-) delete mode 100644 MapImages/Shared/WorldFileParameters.cs diff --git a/MBTiles/UWP/MBTiles.UWP.csproj b/MBTiles/UWP/MBTiles.UWP.csproj index d8d3ec26..412b7f90 100644 --- a/MBTiles/UWP/MBTiles.UWP.csproj +++ b/MBTiles/UWP/MBTiles.UWP.csproj @@ -11,8 +11,8 @@ MBTiles.UWP en-US UAP - 10.0.17134.0 - 10.0.17134.0 + 10.0.17763.0 + 10.0.17763.0 14 512 {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} diff --git a/MapImages/Shared/WorldFile.cs b/MapImages/Shared/WorldFile.cs index 225e5c5a..a41b3f33 100644 --- a/MapImages/Shared/WorldFile.cs +++ b/MapImages/Shared/WorldFile.cs @@ -3,10 +3,12 @@ // Licensed under the Microsoft Public License (Ms-PL) using System; +using System.Globalization; using System.IO; +using System.Linq; using System.Threading.Tasks; -using MapControl.Projections; #if WINDOWS_UWP +using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media; @@ -17,6 +19,7 @@ using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Imaging; #endif +using MapControl.Projections; namespace MapControl.Images { @@ -36,12 +39,71 @@ namespace MapControl.Images image.SetValue(ImagePathProperty, imagePath); } - public static void SetWorldImage(this Image image, BitmapSource bitmapSource, WorldFileParameters parameters, MapProjection projection = null) + public static void SetWorldImage(this Image image, BitmapSource bitmapSource, Matrix transform, MapProjection projection = null) { image.Source = bitmapSource; image.Stretch = Stretch.Fill; - MapPanel.SetBoundingBox(image, parameters.GetBoundingBox(bitmapSource.PixelWidth, bitmapSource.PixelHeight, projection)); + var boundingBox = GetBoundingBox(bitmapSource.PixelWidth, bitmapSource.PixelHeight, transform, projection); + + MapPanel.SetBoundingBox(image, boundingBox); + } + + public static BoundingBox GetBoundingBox(double imageWidth, double imageHeight, Matrix transform, MapProjection projection = null) + { + if (transform.M12 != 0d || transform.M21 != 0d) + { + throw new ArgumentException("Invalid Matrix, M12 and M21 must be zero."); + } + + var rect = new Rect( + transform.Transform(new Point()), + transform.Transform(new Point(imageWidth, imageHeight))); + + if (projection != null) + { + return projection.RectToBoundingBox(rect); + } + + return new BoundingBox + { + West = rect.X, + East = rect.X + rect.Width, + South = rect.Y, + North = rect.Y + rect.Height + }; + } + + public static Matrix ReadWorldFile(string path) + { + if (!File.Exists(path)) + { + throw new ArgumentException("World file \"" + path + "\"not found."); + } + + var parameters = File.ReadLines(path).Take(6).Select((line, i) => + { + double p; + if (!double.TryParse(line, NumberStyles.Float, CultureInfo.InvariantCulture, out p)) + { + throw new ArgumentException("Failed parsing line " + (i + 1) + " in world file \"" + path + "\"."); + } + return p; + }) + .ToList(); + + if (parameters.Count != 6) + { + throw new ArgumentException("Insufficient number of parameters in world file \"" + path + "\"."); + } + + return new Matrix( + parameters[0], // line 1: A or M11 + parameters[1], // line 2: D or M12 + parameters[2], // line 3: B or M21 + parameters[3], // line 4: E or M22 + parameters[4], // line 5: C or OffsetX + parameters[5]); // line 6: F or OffsetY } private static async Task SetWorldImageAsync(Image image, string imagePath) @@ -67,7 +129,7 @@ namespace MapControl.Images var worldFilePath = Path.Combine(dir, file + ext.Remove(2, 1) + "w"); var projFilePath = Path.Combine(dir, file + ".prj"); - var parameters = new WorldFileParameters(worldFilePath); + var transform = ReadWorldFile(worldFilePath); MapProjection projection = null; if (File.Exists(projFilePath)) @@ -75,7 +137,7 @@ namespace MapControl.Images projection = new GeoApiProjection { WKT = File.ReadAllText(projFilePath) }; } - SetWorldImage(image, bitmap, parameters, projection); + SetWorldImage(image, bitmap, transform, projection); } } } diff --git a/MapImages/Shared/WorldFileParameters.cs b/MapImages/Shared/WorldFileParameters.cs deleted file mode 100644 index 5f1e8e29..00000000 --- a/MapImages/Shared/WorldFileParameters.cs +++ /dev/null @@ -1,94 +0,0 @@ -// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control -// © 2018 Clemens Fischer -// Licensed under the Microsoft Public License (Ms-PL) - -using System; -using System.Globalization; -using System.IO; -using System.Linq; -#if WINDOWS_UWP -using Windows.Foundation; -#else -using System.Windows; -#endif - -namespace MapControl.Images -{ - public class WorldFileParameters - { - public WorldFileParameters() - { - } - - public WorldFileParameters(string path) - { - if (!File.Exists(path)) - { - throw new ArgumentException("World file \"" + path + "\"not found."); - } - - var lines = File.ReadLines(path).Take(6).ToList(); - - if (lines.Count != 6) - { - throw new ArgumentException("Invalid number of parameters in world file \"" + path + "\"."); - } - - double xscale, yskew, xskew, yscale, xorigin, yorigin; - - if (!double.TryParse(lines[0], NumberStyles.Float, CultureInfo.InvariantCulture, out xscale) || - !double.TryParse(lines[1], NumberStyles.Float, CultureInfo.InvariantCulture, out yskew) || - !double.TryParse(lines[2], NumberStyles.Float, CultureInfo.InvariantCulture, out xskew) || - !double.TryParse(lines[3], NumberStyles.Float, CultureInfo.InvariantCulture, out yscale) || - !double.TryParse(lines[4], NumberStyles.Float, CultureInfo.InvariantCulture, out xorigin) || - !double.TryParse(lines[5], NumberStyles.Float, CultureInfo.InvariantCulture, out yorigin)) - { - throw new ArgumentException("Failed parsing parameters in world file \"" + path + "\"."); - } - - XScale = xscale; - YSkew = yskew; - XSkew = xskew; - YScale = yscale; - XOrigin = xorigin; - YOrigin = yorigin; - } - - public double XScale { get; set; } // A - public double YSkew { get; set; } // D - public double XSkew { get; set; } // B - public double YScale { get; set; } // E - public double XOrigin { get; set; } // C - public double YOrigin { get; set; } // F - - public BoundingBox GetBoundingBox(double imageWidth, double imageHeight, MapProjection projection = null) - { - if (XScale == 0d || YScale == 0d) - { - throw new ArgumentException("Invalid WorldFileParameters, XScale and YScale must be non-zero."); - } - - if (YSkew != 0d || XSkew != 0d) - { - throw new ArgumentException("Invalid WorldFileParameters, YSkew and XSkew must be zero."); - } - - var p1 = new Point(XOrigin, YOrigin); - var p2 = new Point(XOrigin + XScale * imageWidth, YOrigin + YScale * imageHeight); - var rect = new Rect(p1, p2); - - if (projection != null) - { - return projection.RectToBoundingBox(rect); - } - - return new BoundingBox - { - West = rect.X, - East = rect.X + rect.Width, - South = rect.Y, - North = rect.Y + rect.Height - }; - } - } -} diff --git a/MapImages/UWP/MapImages.UWP.csproj b/MapImages/UWP/MapImages.UWP.csproj index 56ffffd9..1225f14b 100644 --- a/MapImages/UWP/MapImages.UWP.csproj +++ b/MapImages/UWP/MapImages.UWP.csproj @@ -46,9 +46,6 @@ WorldFile.cs - - WorldFileParameters.cs - ZoomLevelToOpacityConverter.cs diff --git a/MapImages/WPF/MapImages.WPF.csproj b/MapImages/WPF/MapImages.WPF.csproj index 7b34f18e..71f29470 100644 --- a/MapImages/WPF/MapImages.WPF.csproj +++ b/MapImages/WPF/MapImages.WPF.csproj @@ -53,9 +53,6 @@ WorldFile.cs - - WorldFileParameters.cs - ZoomLevelToOpacityConverter.cs