diff --git a/MBTiles/Shared/MBTileData.cs b/MBTiles/Shared/MBTileData.cs
index 68f3b7b7..c079345a 100644
--- a/MBTiles/Shared/MBTileData.cs
+++ b/MBTiles/Shared/MBTileData.cs
@@ -25,9 +25,19 @@ namespace MapControl.MBTiles
connection = new SQLiteConnection("Data Source=" + Path.GetFullPath(file));
}
- public Task OpenAsync()
+ public async Task OpenAsync()
{
- return connection.OpenAsync();
+ await connection.OpenAsync();
+
+ using (var command = new SQLiteCommand("create table if not exists metadata (name string, value string)", connection))
+ {
+ await command.ExecuteNonQueryAsync();
+ }
+
+ using (var command = new SQLiteCommand("create table if not exists tiles (zoom_level integer, tile_column integer, tile_row integer, tile_data blob)", connection))
+ {
+ await command.ExecuteNonQueryAsync();
+ }
}
public void Close()
@@ -68,11 +78,6 @@ namespace MapControl.MBTiles
{
try
{
- using (var command = new SQLiteCommand("create table if not exists metadata (name string, value string)", connection))
- {
- await command.ExecuteNonQueryAsync();
- }
-
using (var command = new SQLiteCommand("insert or replace into metadata (name, value) values (@n, @v)", connection))
{
foreach (var keyValue in metadata)
@@ -117,11 +122,6 @@ namespace MapControl.MBTiles
{
try
{
- using (var command = new SQLiteCommand("create table if not exists tiles (zoom_level integer, tile_column integer, tile_row integer, tile_data blob)", connection))
- {
- await command.ExecuteNonQueryAsync();
- }
-
using (var command = new SQLiteCommand("insert or replace into tiles (zoom_level, tile_column, tile_row, tile_data) values (@z, @x, @y, @b)", connection))
{
command.Parameters.AddWithValue("@z", zoomLevel);
diff --git a/MBTiles/Shared/MBTileLayer.cs b/MBTiles/Shared/MBTileLayer.cs
index 8684bb41..d21819d8 100644
--- a/MBTiles/Shared/MBTileLayer.cs
+++ b/MBTiles/Shared/MBTileLayer.cs
@@ -11,6 +11,9 @@ using System.Windows;
namespace MapControl.MBTiles
{
+ ///
+ /// MapTileLayer that uses an MBTiles SQLite Database. See https://wiki.openstreetmap.org/wiki/MBTiles.
+ ///
public class MBTileLayer : MapTileLayer
{
public static readonly DependencyProperty FileProperty = DependencyProperty.Register(
diff --git a/MBTiles/Shared/MBTileSource.cs b/MBTiles/Shared/MBTileSource.cs
index 8ebd8795..5db7d4a7 100644
--- a/MBTiles/Shared/MBTileSource.cs
+++ b/MBTiles/Shared/MBTileSource.cs
@@ -16,48 +16,47 @@ namespace MapControl.MBTiles
{
private readonly MBTileData tileData;
- public string Name { get; private set; }
- public string Description { get; private set; }
- public int? MinZoom { get; private set; }
- public int? MaxZoom { get; private set; }
-
public MBTileSource(string file)
{
tileData = new MBTileData(file);
}
+ public string Name { get; private set; }
+ public string Description { get; private set; }
+ public int? MinZoom { get; private set; }
+ public int? MaxZoom { get; private set; }
+
public async Task Initialize()
{
await tileData.OpenAsync();
var metadata = await tileData.ReadMetadataAsync();
- string name;
- string description;
- string minzoom;
- string maxzoom;
+ string s;
int minZoom;
int maxZoom;
- if (metadata.TryGetValue("name", out name))
- {
- Name = name;
- }
+ Name = (metadata.TryGetValue("name", out s)) ? s : null;
- if (metadata.TryGetValue("description", out description))
- {
- Description = description;
- }
+ Description = (metadata.TryGetValue("description", out s)) ? s : null;
- if (metadata.TryGetValue("minzoom", out minzoom) && int.TryParse(minzoom, out minZoom))
+ if (metadata.TryGetValue("minzoom", out s) && int.TryParse(s, out minZoom))
{
MinZoom = minZoom;
}
+ else
+ {
+ MinZoom = null;
+ }
- if (metadata.TryGetValue("maxzoom", out maxzoom) && int.TryParse(maxzoom, out maxZoom))
+ if (metadata.TryGetValue("maxzoom", out s) && int.TryParse(s, out maxZoom))
{
MaxZoom = maxZoom;
}
+ else
+ {
+ MaxZoom = null;
+ }
}
public void Dispose()
diff --git a/MBTiles/WPF/MBTiles.WPF.csproj b/MBTiles/WPF/MBTiles.WPF.csproj
index 1f463e55..72ed69c5 100644
--- a/MBTiles/WPF/MBTiles.WPF.csproj
+++ b/MBTiles/WPF/MBTiles.WPF.csproj
@@ -47,7 +47,6 @@
..\..\packages\System.Data.SQLite.Core.1.0.111.0\lib\net46\System.Data.SQLite.dll
-
diff --git a/MapImages/Shared/GroundOverlayPanel.cs b/MapImages/Shared/GroundOverlayPanel.cs
index 5dd7e2a1..1305f879 100644
--- a/MapImages/Shared/GroundOverlayPanel.cs
+++ b/MapImages/Shared/GroundOverlayPanel.cs
@@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
+using System.IO.Compression;
using System.Linq;
using System.Threading.Tasks;
using System.Xml;
@@ -22,7 +23,7 @@ using System.Windows.Media;
namespace MapControl.Images
{
- public partial class GroundOverlayPanel : MapPanel
+ public class GroundOverlayPanel : MapPanel
{
class LatLonBox : BoundingBox
{
@@ -99,7 +100,8 @@ namespace MapControl.Images
FrameworkElement overlay = new Image
{
Source = imageOverlay.ImageSource,
- Stretch = Stretch.Fill
+ Stretch = Stretch.Fill,
+ UseLayoutRounding = false
};
if (imageOverlay.LatLonBox.Rotation != 0d)
@@ -108,7 +110,7 @@ namespace MapControl.Images
overlay.RenderTransformOrigin = new Point(0.5, 0.5);
// additional Panel for map rotation, see MapPanel.ArrangeElementWithBoundingBox
- var panel = new Grid { Background = null };
+ var panel = new Grid { UseLayoutRounding = false };
panel.Children.Add(overlay);
overlay = panel;
}
@@ -119,6 +121,71 @@ namespace MapControl.Images
}
}
+ private static async Task> ReadGroundOverlaysFromArchiveAsync(string archiveFile)
+ {
+ using (var archive = await Task.Run(() => ZipFile.OpenRead(archiveFile)))
+ {
+ var docEntry = await Task.Run(() => archive.GetEntry("doc.kml") ?? archive.Entries.FirstOrDefault(e => e.Name.EndsWith(".kml")));
+
+ if (docEntry == null)
+ {
+ throw new ArgumentException("No KML entry found in " + archiveFile);
+ }
+
+ var imageOverlays = await Task.Run(() =>
+ {
+ var kmlDocument = new XmlDocument();
+
+ using (var docStream = docEntry.Open())
+ {
+ kmlDocument.Load(docStream);
+ }
+
+ return ReadGroundOverlays(kmlDocument).ToList();
+ });
+
+ foreach (var imageOverlay in imageOverlays)
+ {
+ var imageEntry = await Task.Run(() => archive.GetEntry(imageOverlay.ImagePath));
+
+ if (imageEntry != null)
+ {
+ using (var zipStream = imageEntry.Open())
+ using (var memoryStream = new MemoryStream())
+ {
+ await zipStream.CopyToAsync(memoryStream);
+ memoryStream.Seek(0, SeekOrigin.Begin);
+
+ imageOverlay.ImageSource = await ImageLoader.LoadImageAsync(memoryStream);
+ }
+ }
+ }
+
+ return imageOverlays;
+ }
+ }
+
+ private static async Task> ReadGroundOverlaysFromFileAsync(string docFile)
+ {
+ docFile = Path.GetFullPath(docFile);
+ var docUri = new Uri(docFile);
+
+ var imageOverlays = await Task.Run(() =>
+ {
+ var kmlDocument = new XmlDocument();
+ kmlDocument.Load(docFile);
+
+ return ReadGroundOverlays(kmlDocument).ToList();
+ });
+
+ foreach (var imageOverlay in imageOverlays)
+ {
+ imageOverlay.ImageSource = await ImageLoader.LoadImageAsync(new Uri(docUri, imageOverlay.ImagePath));
+ }
+
+ return imageOverlays;
+ }
+
private static IEnumerable ReadGroundOverlays(XmlDocument kmlDocument)
{
foreach (XmlElement groundOverlayElement in kmlDocument.GetElementsByTagName("GroundOverlay"))
diff --git a/MapImages/UWP/GroundOverlayPanel.UWP.cs b/MapImages/UWP/GroundOverlayPanel.UWP.cs
deleted file mode 100644
index 732c2a3c..00000000
--- a/MapImages/UWP/GroundOverlayPanel.UWP.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
-// © 2019 Clemens Fischer
-// Licensed under the Microsoft Public License (Ms-PL)
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.IO.Compression;
-using System.Linq;
-using System.Threading.Tasks;
-using System.Xml;
-using Windows.Storage;
-
-namespace MapControl.Images
-{
- public partial class GroundOverlayPanel
- {
- public GroundOverlayPanel()
- {
- UseLayoutRounding = false;
- }
-
- private static async Task> ReadGroundOverlaysFromFileAsync(string docFile)
- {
- docFile = Path.GetFullPath(docFile);
-
- var file = await StorageFile.GetFileFromPathAsync(docFile);
- var kmlDocument = new XmlDocument();
-
- using (var stream = await file.OpenReadAsync())
- {
- kmlDocument.Load(stream.AsStreamForRead());
- }
-
- var imageOverlays = await Task.Run(() => ReadGroundOverlays(kmlDocument).ToList());
- var docUri = new Uri(docFile);
-
- foreach (var imageOverlay in imageOverlays)
- {
- imageOverlay.ImageSource = await ImageLoader.LoadImageAsync(new Uri(docUri, imageOverlay.ImagePath));
- }
-
- return imageOverlays;
- }
-
- private static async Task> ReadGroundOverlaysFromArchiveAsync(string archiveFile)
- {
- using (var archive = ZipFile.OpenRead(archiveFile))
- {
- var docEntry = archive.GetEntry("doc.kml")
- ?? archive.Entries.FirstOrDefault(e => e.Name.EndsWith(".kml"));
-
- if (docEntry == null)
- {
- throw new ArgumentException("No KML entry found in " + archiveFile);
- }
-
- var kmlDocument = new XmlDocument();
-
- using (var docStream = docEntry.Open())
- {
- kmlDocument.Load(docStream);
- }
-
- var imageOverlays = await Task.Run(() => ReadGroundOverlays(kmlDocument).ToList());
-
- foreach (var imageOverlay in imageOverlays)
- {
- var imageEntry = archive.GetEntry(imageOverlay.ImagePath);
-
- if (imageEntry != null)
- {
- using (var zipStream = imageEntry.Open())
- using (var memoryStream = new MemoryStream())
- {
- await zipStream.CopyToAsync(memoryStream);
- memoryStream.Seek(0, SeekOrigin.Begin);
-
- imageOverlay.ImageSource = await ImageLoader.LoadImageAsync(memoryStream);
- }
- }
- }
-
- return imageOverlays;
- }
- }
- }
-}
diff --git a/MapImages/UWP/MapImages.UWP.csproj b/MapImages/UWP/MapImages.UWP.csproj
index b7655cd1..f1d2065b 100644
--- a/MapImages/UWP/MapImages.UWP.csproj
+++ b/MapImages/UWP/MapImages.UWP.csproj
@@ -49,7 +49,6 @@
ZoomLevelToOpacityConverter.cs
-
diff --git a/MapImages/WPF/GroundOverlayPanel.WPF.cs b/MapImages/WPF/GroundOverlayPanel.WPF.cs
deleted file mode 100644
index 8004b93b..00000000
--- a/MapImages/WPF/GroundOverlayPanel.WPF.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
-// © 2019 Clemens Fischer
-// Licensed under the Microsoft Public License (Ms-PL)
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.IO.Compression;
-using System.Linq;
-using System.Threading.Tasks;
-using System.Xml;
-
-namespace MapControl.Images
-{
- public partial class GroundOverlayPanel
- {
- private static Task> ReadGroundOverlaysFromFileAsync(string docFile)
- {
- return Task.Run(() =>
- {
- docFile = Path.GetFullPath(docFile);
-
- var kmlDocument = new XmlDocument();
- kmlDocument.Load(docFile);
-
- var imageOverlays = ReadGroundOverlays(kmlDocument).ToList();
- var docDir = Path.GetDirectoryName(docFile);
-
- foreach (var imageOverlay in imageOverlays)
- {
- imageOverlay.ImageSource = ImageLoader.LoadImage(Path.Combine(docDir, imageOverlay.ImagePath));
- }
-
- return imageOverlays;
- });
- }
-
- private static Task> ReadGroundOverlaysFromArchiveAsync(string archiveFile)
- {
- return Task.Run(() =>
- {
- using (var archive = ZipFile.OpenRead(archiveFile))
- {
- var docEntry = archive.GetEntry("doc.kml")
- ?? archive.Entries.FirstOrDefault(e => e.Name.EndsWith(".kml"));
-
- if (docEntry == null)
- {
- throw new ArgumentException("No KML entry found in " + archiveFile);
- }
-
- var kmlDocument = new XmlDocument();
-
- using (var docStream = docEntry.Open())
- {
- kmlDocument.Load(docStream);
- }
-
- var imageOverlays = ReadGroundOverlays(kmlDocument).ToList();
-
- foreach (var imageOverlay in imageOverlays)
- {
- var imageEntry = archive.GetEntry(imageOverlay.ImagePath);
-
- if (imageEntry != null)
- {
- using (var zipStream = imageEntry.Open())
- using (var memoryStream = new MemoryStream())
- {
- zipStream.CopyTo(memoryStream);
- memoryStream.Seek(0, SeekOrigin.Begin);
-
- imageOverlay.ImageSource = ImageLoader.LoadImage(memoryStream);
- }
- }
- }
-
- return imageOverlays;
- }
- });
- }
- }
-}
diff --git a/MapImages/WPF/MapImages.WPF.csproj b/MapImages/WPF/MapImages.WPF.csproj
index 3996f7ec..53b99bfe 100644
--- a/MapImages/WPF/MapImages.WPF.csproj
+++ b/MapImages/WPF/MapImages.WPF.csproj
@@ -57,7 +57,6 @@
ZoomLevelToOpacityConverter.cs
-