diff --git a/MapsforgeTiles/Avalonia/MapsforgeTileSource.Avalonia.cs b/MapsforgeTiles/Avalonia/MapsforgeTileSource.Avalonia.cs deleted file mode 100644 index 53b374ff..00000000 --- a/MapsforgeTiles/Avalonia/MapsforgeTileSource.Avalonia.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using Avalonia; -using Avalonia.Media.Imaging; -using Avalonia.Platform; - -namespace MapControl.MapsforgeTiles -{ - public partial class MapsforgeTileSource - { - private static Bitmap CreateImage(int[] pixels) - { - var size = (int)Math.Sqrt(pixels.Length); - - unsafe - { - fixed (int* ptr = pixels) - { - return new Bitmap(PixelFormat.Bgra8888, AlphaFormat.Opaque, (nint)ptr, - new PixelSize(size, size), new Vector(96d, 96d), size * 4); - } - } - } - } -} diff --git a/MapsforgeTiles/Avalonia/MapsforgeTileSource.cs b/MapsforgeTiles/Avalonia/MapsforgeTileSource.cs new file mode 100644 index 00000000..d020bef3 --- /dev/null +++ b/MapsforgeTiles/Avalonia/MapsforgeTileSource.cs @@ -0,0 +1,42 @@ +using Avalonia; +using Avalonia.Media; +using Avalonia.Media.Imaging; +using Avalonia.Platform; +using MapsforgeWrapper; +using System; +using System.Threading.Tasks; + +namespace MapControl.MapsforgeTiles +{ + public class MapsforgeTileSource(string theme, int cacheCapacity = 200) : TileSource + { + private readonly TileRenderer renderer = new(theme, cacheCapacity); + + public static void Initialize(string mapFilePath, float dpiScale) + { + TileRenderer.Initialize(mapFilePath, dpiScale); + } + + public override Task LoadImageAsync(int zoomLevel, int column, int row) + { + var pixels = renderer.RenderTile(zoomLevel, column, row); + IImage image = pixels != null ? CreateImage(pixels) : null; + + return Task.FromResult(image); + } + + private static Bitmap CreateImage(int[] pixels) + { + var size = (int)Math.Sqrt(pixels.Length); + + unsafe + { + fixed (int* ptr = pixels) + { + return new Bitmap(PixelFormat.Bgra8888, AlphaFormat.Opaque, (nint)ptr, + new PixelSize(size, size), new Vector(96d, 96d), size * 4); + } + } + } + } +} diff --git a/MapsforgeTiles/Avalonia/MapsforgeTiles.Avalonia.csproj b/MapsforgeTiles/Avalonia/MapsforgeTiles.Avalonia.csproj index 505b81fb..f5b97fda 100644 --- a/MapsforgeTiles/Avalonia/MapsforgeTiles.Avalonia.csproj +++ b/MapsforgeTiles/Avalonia/MapsforgeTiles.Avalonia.csproj @@ -7,23 +7,8 @@ true - - - - + - - - - - - - - - - - - diff --git a/MapsforgeTiles/MapsforgeWrapper/MapsforgeWrapper.csproj b/MapsforgeTiles/MapsforgeWrapper/MapsforgeWrapper.csproj new file mode 100644 index 00000000..377b1db3 --- /dev/null +++ b/MapsforgeTiles/MapsforgeWrapper/MapsforgeWrapper.csproj @@ -0,0 +1,17 @@ + + + net10.0 + + + + + + + + + + + + + + diff --git a/MapsforgeTiles/MapsforgeWrapper/TileRenderer.cs b/MapsforgeTiles/MapsforgeWrapper/TileRenderer.cs new file mode 100644 index 00000000..50784246 --- /dev/null +++ b/MapsforgeTiles/MapsforgeWrapper/TileRenderer.cs @@ -0,0 +1,75 @@ +using org.mapsforge.map.awt.graphics; +using org.mapsforge.map.datastore; +using org.mapsforge.map.layer.cache; +using org.mapsforge.map.layer.renderer; +using org.mapsforge.map.model; +using org.mapsforge.map.reader; +using org.mapsforge.map.rendertheme.@internal; +using org.mapsforge.map.rendertheme.rule; +using System.IO; + +namespace MapsforgeWrapper +{ + public class TileRenderer + { + private static DisplayModel displayModel; + private static MapDataStore dataStore; + + public static void Initialize(string mapFilePath, float dpiScale) + { + DisplayModel.setDeviceScaleFactor(dpiScale); + displayModel = new DisplayModel(); + + if (mapFilePath.EndsWith(".map")) + { + dataStore = new MapFile(mapFilePath); + } + else + { + var multiMapDataStore = new MultiMapDataStore(MultiMapDataStore.DataPolicy.DEDUPLICATE); + foreach (var file in Directory.EnumerateFiles(mapFilePath, "*.map")) + { + multiMapDataStore.addMapDataStore(new MapFile(file), false, false); + } + dataStore = multiMapDataStore; + } + } + + private readonly InMemoryTileCache tileCache; + private readonly DatabaseRenderer renderer; + private readonly RenderThemeFuture renderThemeFuture; + + public TileRenderer(string theme, int cacheCapacity = 200) + { + tileCache = new InMemoryTileCache(cacheCapacity); + renderer = new DatabaseRenderer(dataStore, AwtGraphicFactory.INSTANCE, tileCache, null, true, false, null); + renderThemeFuture = new RenderThemeFuture(AwtGraphicFactory.INSTANCE, MapsforgeThemes.valueOf(theme.ToUpper()), displayModel); + } + + public int[] RenderTile(int zoomLevel, int column, int row) + { + if (!renderThemeFuture.isDone()) + { + renderThemeFuture.run(); + } + + int[] imageBuffer = null; + var tile = new org.mapsforge.core.model.Tile(column, row, (byte)zoomLevel, displayModel.getTileSize()); + var job = new RendererJob(tile, dataStore, renderThemeFuture, displayModel, 1f, false, false); + var bitmap = tileCache.get(job) ?? renderer.executeJob(job); + + if (bitmap != null) + { + var image = AwtGraphicFactory.getBitmap(bitmap); + + if (image != null) + { + imageBuffer = image.getRGB(0, 0, image.getWidth(), image.getHeight(), null, 0, image.getWidth()); + } + } + + return imageBuffer; + } + + } +} diff --git a/MapsforgeTiles/pom.xml b/MapsforgeTiles/MapsforgeWrapper/pom.xml similarity index 92% rename from MapsforgeTiles/pom.xml rename to MapsforgeTiles/MapsforgeWrapper/pom.xml index f3292283..e91f00d0 100644 --- a/MapsforgeTiles/pom.xml +++ b/MapsforgeTiles/MapsforgeWrapper/pom.xml @@ -5,11 +5,10 @@ 4.0.0 xaml.mapcontrol - mapsforge-tilerenderer - 0.1.0 + mapsforge-dependencies + 0.27.0 - 8 UTF-8 @@ -46,6 +45,7 @@ jar-with-dependencies + false diff --git a/MapsforgeTiles/Shared/MapsforgeTileSource.cs b/MapsforgeTiles/Shared/MapsforgeTileSource.cs deleted file mode 100644 index bfaf6fd7..00000000 --- a/MapsforgeTiles/Shared/MapsforgeTileSource.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Threading.Tasks; -using TileRenderer; -#if WPF -using System.Windows.Media; -#elif UWP -using Windows.UI.Xaml.Media; -#elif WINUI -using Microsoft.UI.Xaml.Media; -#elif AVALONIA -using ImageSource = Avalonia.Media.IImage; -#endif - -namespace MapControl.MapsforgeTiles -{ - public partial class MapsforgeTileSource(string mapDirectory, string theme, int cacheCapacity = 200) : TileSource - { - private readonly MapsforgeTileRenderer renderer = new(mapDirectory, theme, cacheCapacity); - - public static void SetDpiScale(float scale) - { - MapsforgeTileRenderer.SetDpiScale(scale); - } - - public override Task LoadImageAsync(int zoomLevel, int column, int row) - { - var pixels = renderer.RenderTile(zoomLevel, column, row); - ImageSource image = pixels != null ? CreateImage(pixels) : null; - - return Task.FromResult(image); - } - } -} diff --git a/MapsforgeTiles/UWP/MapsforgeTiles.UWP.csproj b/MapsforgeTiles/UWP/MapsforgeTiles.UWP.csproj index 7fe611c5..7dc510af 100644 --- a/MapsforgeTiles/UWP/MapsforgeTiles.UWP.csproj +++ b/MapsforgeTiles/UWP/MapsforgeTiles.UWP.csproj @@ -11,23 +11,11 @@ - + - - - - - - - - - - - - diff --git a/MapsforgeTiles/WPF/MapsforgeTileSource.WPF.cs b/MapsforgeTiles/WPF/MapsforgeTileSource.WPF.cs deleted file mode 100644 index 0808903d..00000000 --- a/MapsforgeTiles/WPF/MapsforgeTileSource.WPF.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Windows.Media; -using System.Windows.Media.Imaging; - -namespace MapControl.MapsforgeTiles -{ - public partial class MapsforgeTileSource - { - private static BitmapSource CreateImage(int[] pixels) - { - var size = (int)Math.Sqrt(pixels.Length); - var image = BitmapSource.Create(size, size, 96d, 96d, PixelFormats.Bgra32, null, pixels, size * 4); - image.Freeze(); - return image; - } - } -} diff --git a/MapsforgeTiles/WPF/MapsforgeTileSource.cs b/MapsforgeTiles/WPF/MapsforgeTileSource.cs new file mode 100644 index 00000000..f7edb2da --- /dev/null +++ b/MapsforgeTiles/WPF/MapsforgeTileSource.cs @@ -0,0 +1,34 @@ +using MapsforgeWrapper; +using System; +using System.Threading.Tasks; +using System.Windows.Media; +using System.Windows.Media.Imaging; + +namespace MapControl.MapsforgeTiles +{ + public class MapsforgeTileSource(string theme, int cacheCapacity = 200) : TileSource + { + private readonly TileRenderer renderer = new(theme, cacheCapacity); + + public static void Initialize(string mapFilePath, float dpiScale) + { + TileRenderer.Initialize(mapFilePath, dpiScale); + } + + public override Task LoadImageAsync(int zoomLevel, int column, int row) + { + var pixels = renderer.RenderTile(zoomLevel, column, row); + ImageSource image = pixels != null ? CreateImage(pixels) : null; + + return Task.FromResult(image); + } + + private static BitmapSource CreateImage(int[] pixels) + { + var size = (int)Math.Sqrt(pixels.Length); + var image = BitmapSource.Create(size, size, 96d, 96d, PixelFormats.Bgra32, null, pixels, size * 4); + image.Freeze(); + return image; + } + } +} diff --git a/MapsforgeTiles/WPF/MapsforgeTiles.WPF.csproj b/MapsforgeTiles/WPF/MapsforgeTiles.WPF.csproj index 89c3bcef..c7f59782 100644 --- a/MapsforgeTiles/WPF/MapsforgeTiles.WPF.csproj +++ b/MapsforgeTiles/WPF/MapsforgeTiles.WPF.csproj @@ -7,23 +7,8 @@ XAML Map Control Mapsforge Library for WPF - - - - + - - - - - - - - - - - - diff --git a/MapsforgeTiles/WinUI/MapsforgeTileSource.WinUI.cs b/MapsforgeTiles/WinUI/MapsforgeTileSource.WinUI.cs deleted file mode 100644 index 0b02bfba..00000000 --- a/MapsforgeTiles/WinUI/MapsforgeTileSource.WinUI.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.IO; -using System.Runtime.InteropServices.WindowsRuntime; -#if UWP -using Windows.UI.Xaml.Media.Imaging; -#elif WINUI -using Microsoft.UI.Xaml.Media.Imaging; -#endif - -namespace MapControl.MapsforgeTiles -{ - public partial class MapsforgeTileSource - { - private static WriteableBitmap CreateImage(int[] pixels) - { - var size = (int)Math.Sqrt(pixels.Length); - var bitmap = new WriteableBitmap(size, size); - - using var stream = bitmap.PixelBuffer.AsStream(); - using var writer = new BinaryWriter(stream); - - foreach (var pixel in pixels) - { - writer.Write(pixel); - } - - return bitmap; - } - } -} diff --git a/MapsforgeTiles/WinUI/MapsforgeTileSource.cs b/MapsforgeTiles/WinUI/MapsforgeTileSource.cs new file mode 100644 index 00000000..6e48a447 --- /dev/null +++ b/MapsforgeTiles/WinUI/MapsforgeTileSource.cs @@ -0,0 +1,49 @@ +using System; +using System.IO; +using System.Runtime.InteropServices.WindowsRuntime; +using System.Threading.Tasks; +using MapsforgeWrapper; +#if UWP +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Media.Imaging; +#elif WINUI +using Microsoft.UI.Xaml.Media; +using Microsoft.UI.Xaml.Media.Imaging; +#endif + +namespace MapControl.MapsforgeTiles +{ + public class MapsforgeTileSource(string theme, int cacheCapacity = 200) : TileSource + { + private readonly TileRenderer renderer = new(theme, cacheCapacity); + + public static void Initialize(string mapFilePath, float dpiScale) + { + TileRenderer.Initialize(mapFilePath, dpiScale); + } + + public override Task LoadImageAsync(int zoomLevel, int column, int row) + { + var pixels = renderer.RenderTile(zoomLevel, column, row); + ImageSource image = pixels != null ? CreateImage(pixels) : null; + + return Task.FromResult(image); + } + + private static WriteableBitmap CreateImage(int[] pixels) + { + var size = (int)Math.Sqrt(pixels.Length); + var bitmap = new WriteableBitmap(size, size); + + using var stream = bitmap.PixelBuffer.AsStream(); + using var writer = new BinaryWriter(stream); + + foreach (var pixel in pixels) + { + writer.Write(pixel); + } + + return bitmap; + } + } +} diff --git a/MapsforgeTiles/WinUI/MapsforgeTiles.WinUI.csproj b/MapsforgeTiles/WinUI/MapsforgeTiles.WinUI.csproj index 976e01d3..85b304e6 100644 --- a/MapsforgeTiles/WinUI/MapsforgeTiles.WinUI.csproj +++ b/MapsforgeTiles/WinUI/MapsforgeTiles.WinUI.csproj @@ -7,23 +7,8 @@ XAML Map Control Mapsforge Library for WinUI - - - - + - - - - - - - - - - - - diff --git a/MapsforgeTiles/src/main/java/TileRenderer/MapsforgeTileRenderer.java b/MapsforgeTiles/src/main/java/TileRenderer/MapsforgeTileRenderer.java deleted file mode 100644 index bf76cef2..00000000 --- a/MapsforgeTiles/src/main/java/TileRenderer/MapsforgeTileRenderer.java +++ /dev/null @@ -1,74 +0,0 @@ -package TileRenderer; - -import org.mapsforge.core.graphics.TileBitmap; -import org.mapsforge.core.model.Tile; -import org.mapsforge.map.awt.graphics.AwtGraphicFactory; -import org.mapsforge.map.datastore.MapDataStore; -import org.mapsforge.map.datastore.MultiMapDataStore; -import org.mapsforge.map.layer.cache.InMemoryTileCache; -import org.mapsforge.map.layer.renderer.DatabaseRenderer; -import org.mapsforge.map.layer.renderer.RendererJob; -import org.mapsforge.map.model.DisplayModel; -import org.mapsforge.map.reader.MapFile; -import org.mapsforge.map.rendertheme.internal.MapsforgeThemes; -import org.mapsforge.map.rendertheme.rule.RenderThemeFuture; - -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; - -public class MapsforgeTileRenderer { - - public static void SetDpiScale(float scale) { - DisplayModel.setDeviceScaleFactor(scale); - } - - private final MapDataStore dataStore; - private final DisplayModel displayModel; - private final InMemoryTileCache tileCache; - private final DatabaseRenderer renderer; - private final RenderThemeFuture renderThemeFuture; - - public MapsforgeTileRenderer(String mapFilePath, String theme, int cacheCapacity) { - if (mapFilePath.endsWith(".map")) { - dataStore = new MapFile(mapFilePath); - } else { - MultiMapDataStore multiMapDataStore = new MultiMapDataStore(MultiMapDataStore.DataPolicy.DEDUPLICATE); - File dir = new File(mapFilePath); - for (File mapFile : dir.listFiles((file, name) -> name.endsWith(".map"))) { - multiMapDataStore.addMapDataStore(new MapFile(mapFile), false, false); - } - dataStore = multiMapDataStore; - } - - displayModel = new DisplayModel(); - tileCache = new InMemoryTileCache(cacheCapacity); - renderer = new DatabaseRenderer(dataStore, AwtGraphicFactory.INSTANCE, tileCache, null, true, false, null); - renderThemeFuture = new RenderThemeFuture(AwtGraphicFactory.INSTANCE, MapsforgeThemes.valueOf(theme.toUpperCase()), displayModel); - } - - public int[] RenderTile(int zoomLevel, int x, int y) throws IOException { - if (!renderThemeFuture.isDone()) { - renderThemeFuture.run(); - } - - int[] imageBuffer = null; - Tile tile = new Tile(x, y, (byte) zoomLevel, displayModel.getTileSize()); - RendererJob job = new RendererJob(tile, dataStore, renderThemeFuture, displayModel, 1f, false, false); - TileBitmap bitmap = tileCache.get(job); - - if (bitmap == null) { - bitmap = renderer.executeJob(job); - } - - if (bitmap != null) { - BufferedImage image = AwtGraphicFactory.getBitmap(bitmap); - - if (image != null) { - imageBuffer = image.getRGB(0, 0, image.getWidth(), image.getHeight(), null, 0, image.getWidth()); - } - } - - return imageBuffer; - } -}