/// <summary> /// Returns a layer for the basemap according to that chosen by the user and saved in settings. If offline and an associated mbtiles file is present, the mbtiles layer is returned. /// </summary> /// <returns></returns> public static MapLayer GetBaseMap() { var dirPath = Path.Combine(App.TileLocation, "mbtiles"); var BL = Preferences.Get("BaseLayer", "swisstopo_pixelkarte"); bool noInternet = MapModel.IsAppDisconnected(); var wmtsLayer = WMSLayer.CreatePixelkarteWMTSTileLayer(); if (BL == "osm") { wmtsLayer = OpenStreetMap.CreateTileLayer(); } else if (BL == "swissimage") { wmtsLayer = WMSLayer.CreateSwissimageWMTSTileLayer(); } var baseLayer = new MapLayer(true, 0, wmtsLayer); if (noInternet) { var filename = "swisstopo_pixelkarte.mbtiles"; if (BL == "osm") { filename = "osm.mbtiles"; } else if (BL == "swissimage") { filename = "swissimage.mbtiles"; } foreach (var file in System.IO.Directory.GetFiles(dirPath)) { if (file.EndsWith(filename)) { var offlineLayer = WMSLayer.CreateOfflineLayer(file) as TileLayer; baseLayer = new MapLayer(true, 0, offlineLayer); return(baseLayer); } } } return(baseLayer); }
/// <summary> /// Save each of the map layers on-screen (the extent is provided by the screen edges) to an mbtiles file /// </summary> /// <param name="extent"></param> public static async void saveMaps(Extent extent) { var basemap = Preferences.Get("BaseLayer", "swisstopo_pixelkarte"); //Check which basemap var cancel = false; MessagingCenter.Subscribe <Application>(App.Current, "CancelMapSave", (sender) => { //Listen for tile save updates and update the count cancel = true; }); //Get the online layers var layers = GetLayersForMap(App.CurrentProjectId); //Create an array for adding the layers into in an ordered fashion var mapLayersTemp = new MapLayer[layers.Count]; //Add online wms layers var layerStack = layers.OrderBy(o => o.order).ToList(); //Calculate number of tiles var noOfLayers = 0; //Calculate number of tiles long noOfTiles = 0; foreach (var layer in layerStack) { if (layer.visible) { var tileSource = WMSLayer.CreateTileSource(layer.url, layer.wmsLayer, "EPSG:3857"); foreach (var zoomScale in tileSource.Schema.Resolutions) { var tileInfos = tileSource.Schema.GetTileInfos(extent, zoomScale.Value.UnitsPerPixel); noOfTiles = noOfTiles + tileInfos.Count(); } noOfLayers++; } } if (basemap == "swisstopo_pixelkarte") { string swisstopoDbpath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "mbtiles/swisstopo.mbtiles"); TileLayer swisstopo = WMSLayer.CreatePixelkarteWMTSTileLayer(); foreach (var zoomScale in swisstopo.TileSource.Schema.Resolutions) { var stTileInfos = swisstopo.TileSource.Schema.GetTileInfos(extent, zoomScale.Value.UnitsPerPixel); noOfTiles = noOfTiles + stTileInfos.Count(); } } else if (basemap == "swissimage") { string swisstopoDbpath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "mbtiles/swissimage.mbtiles"); TileLayer swisstopo = WMSLayer.CreateSwissimageWMTSTileLayer(); foreach (var zoomScale in swisstopo.TileSource.Schema.Resolutions) { var stTileInfos = swisstopo.TileSource.Schema.GetTileInfos(extent, zoomScale.Value.UnitsPerPixel); noOfTiles = noOfTiles + stTileInfos.Count(); } } else { string osmDbpath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "mbtiles/osm.mbtiles"); TileLayer osm = OpenStreetMap.CreateTileLayer(); foreach (var zoomScale in osm.TileSource.Schema.Resolutions) { var osmTileInfos = osm.TileSource.Schema.GetTileInfos(extent, zoomScale.Value.UnitsPerPixel); noOfTiles = noOfTiles + osmTileInfos.Count(); } } Console.WriteLine(noOfTiles + " tiles in " + (noOfLayers + 1) + " layers"); //Save tiles long tilesSaved = 0; MessagingCenter.Subscribe <Application>(App.Current, "TileSavedInternal", (sender) => { //Listen for tile save updates and update the count var message = tilesSaved + " von " + noOfTiles + " Kacheln aus " + (noOfLayers + 1) + " Ebenen gespeichert"; if (noOfLayers == 0) { message = tilesSaved + " von " + noOfTiles + " Kacheln aus " + (noOfLayers + 1) + " Ebene gespeichert"; } Console.WriteLine(message); MessagingCenter.Send <Application, string>(App.Current, "TileSaved", message); if (tilesSaved >= noOfTiles - 5 || cancel) { MessagingCenter.Send <Application, string>(App.Current, "TileSaved", String.Empty); MessagingCenter.Unsubscribe <Application>(App.Current, "TileSavedInternal"); MapModel.MakeArrayOfLayers(); } }); var tasks = new List <Task>(); // Each layer has to be saved in a single thread due to database access, but we can save layers concurrently foreach (var layer in layerStack) { if (cancel) { break; } if (layer.visible) { var layerNo = Math.Max(layers.Count - layer.order, 0); var tileSource = WMSLayer.CreateTileSource(layer.url, layer.wmsLayer, "EPSG:3857"); string dbpath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "mbtiles/" + layer.title + ".mbtiles"); //extent = tileSource.Schema.Extent; var layerTask = Task.Run(async() => { //Create the database Mbtiles.CreateMbTiles(dbpath, layer, tileSource); //Populate the database foreach (var zoomScale in tileSource.Schema.Resolutions) { if (cancel) { break; } await Task.Run(async() => { var tileInfos = tileSource.Schema.GetTileInfos(extent, zoomScale.Value.UnitsPerPixel); foreach (var tileInfo in tileInfos) { if (cancel) { break; } await Task.Run(() => { tilesSaved++; saveTile(tileSource, tileInfo, dbpath, layer); }); } }); } Console.WriteLine("Saving of 1 layer complete"); }); tasks.Add(layerTask); } } //Swisstopo layer var task = Task.Run(async() => { string baselayerDbsavepath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "mbtiles/swisstopo_pixelkarte.mbtiles"); TileLayer baselayer = WMSLayer.CreatePixelkarteWMTSTileLayer(); //Create the database var baseLayer = new BioDivCollectorXamarin.Models.DatabaseModel.Layer(); baseLayer.title = "swisstopo pixelkarte"; if (basemap == "osm") //OSM case { baselayerDbsavepath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "mbtiles/osm.mbtiles"); baselayer = OpenStreetMap.CreateTileLayer(); //Create the database baseLayer = new BioDivCollectorXamarin.Models.DatabaseModel.Layer(); baseLayer.title = "osm"; } else if (basemap == "swissimage") //Swissimage case { baselayerDbsavepath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "mbtiles/swissimage.mbtiles"); baselayer = WMSLayer.CreateSwissimageWMTSTileLayer(); //Create the database baseLayer = new BioDivCollectorXamarin.Models.DatabaseModel.Layer(); baseLayer.title = "swissimage"; } Mbtiles.CreateMbTiles(baselayerDbsavepath, baseLayer, baselayer.TileSource); //Populate the database foreach (var zoomScale in baselayer.TileSource.Schema.Resolutions) { if (cancel) { break; } await Task.Run(async() => { var baseLayerTileInfos = baselayer.TileSource.Schema.GetTileInfos(extent, zoomScale.Value.UnitsPerPixel); foreach (var tileInfo in baseLayerTileInfos) { if (cancel) { break; } await Task.Run(() => { tilesSaved++; saveTile(baselayer.TileSource, tileInfo, baselayerDbsavepath, baseLayer); }); } }); } Console.WriteLine("Baselayer saved"); }); tasks.Add(task); await Task.WhenAll(tasks); }