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