I misunderstood how this works – I thought the zoom level set on the layer itself controlled when it would get drawn.
The way we tried this is we set it to 23 zoom levels instead of 22 as you show – unfortunately with the bing map overlays this resulted in image not available tiles being display and the application crashed while panning at the most zoomed in stage. I was able to duplicate this with the howDoISample with the following code.
For our case we are likely going to alter our minimum zoom in order to avoid that issue, but thought you might want to know about the crash. Modified code for howDoiSample follows – just pinch/zoom as far as you can and start panning and you will see the crash.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ThinkGeo.Core;
using ThinkGeo.UI.XamarinForms;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace ThinkGeo.UI.XamarinForms.HowDoI
{
///
/// Learn how to display a SQLite Layer on the map
///
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SQLiteLayerSample : ContentPage
{
public SQLiteLayerSample()
{
InitializeComponent();
}
/// <summary>
/// Setup the map with the ThinkGeo Cloud Maps overlay. Also, add the SQLite layer to the map
/// </summary>
protected override void OnAppearing()
{
base.OnAppearing();
// It is important to set the map unit first to either feet, meters or decimal degrees.
mapView.MapUnit = GeographyUnit.Meter;
// Create the background world maps using vector tiles requested from the ThinkGeo Cloud Service and add it to the map.
//ThinkGeoCloudVectorMapsOverlay thinkGeoCloudVectorMapsOverlay = new ThinkGeoCloudVectorMapsOverlay("9ap16imkD_V7fsvDW9I8r8ULxgAB50BX_BnafMEBcKg~", "vtVao9zAcOj00UlGcK7U-efLANfeJKzlPuDB9nw7Bp4K4UxU_PdRDg~~", ThinkGeoCloudVectorMapsMapType.Light);
// thinkGeoCloudVectorMapsOverlay.VectorTileCache = new FileVectorTileCache(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "cache"), "CloudMapsVector");
// mapView.Overlays.Add(thinkGeoCloudVectorMapsOverlay);
BingMapsOverlay lo = new BingMapsOverlay();
lo.ApplicationId = "ReplaceMe";
lo.Name = "BingMapsOverlay";
lo.MapStyle = BingMapsMapType.AerialWithLabels;
mapView.Overlays.Add(lo);
// Create a new overlay that will hold our new layer and add it to the map.
LayerOverlay restaurantsOverlay = new LayerOverlay();
mapView.Overlays.Add(restaurantsOverlay);
// Create the new layer and set the projection as the data is in srid 2276 as our background is srid 3857 (spherical mercator).
string restaurantPath = (Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Data/SQLite/frisco-restaurants.sqlite"));
SqliteFeatureLayer restaurantsLayer = new SqliteFeatureLayer($"Data Source={restaurantPath};", "restaurants", "id", "geometry");
restaurantsLayer.FeatureSource.ProjectionConverter = new ProjectionConverter(2276, 3857);
// Add the layer to the overlay we created earlier.
restaurantsOverlay.Layers.Add("Frisco Restaurants", restaurantsLayer);
// Set a point style and the above text style to zoom level 1 and then apply it to all zoom levels up to 20.
{
restaurantsLayer.Open();
RectangleShape rectOverlay = restaurantsLayer.GetBoundingBox();
var curScale = MapUtil.GetScale(rectOverlay, (float)mapView.Width, GeographyUnit.Meter);
mapView.CurrentExtent = rectOverlay;
double InitialMapScale = curScale * 1.1;
mapView.MinimumScale = 50;
double dStart = InitialMapScale / 50;
double scaleFactor = Math.Pow(dStart, 1.0 / 19.0);
mapView.MaximumScale = InitialMapScale;
var defps = new PointStyle(PointSymbolType.Circle, 12, GeoBrushes.Green, new GeoPen(GeoColors.White, 2));
for (int i = 0; i < 20; i++)
{
double resolution = InitialMapScale / Math.Pow(scaleFactor, i);
ZoomLevel zl = new ZoomLevel(resolution);
if( i >=15)
{
defps = new PointStyle((PointSymbolType)(PointSymbolType.Circle + i - 14), 12, GeoBrushes.Red, new GeoPen(GeoColors.White, 2));
}
zl.CustomStyles.Add(defps);
restaurantsLayer.ZoomLevelSet.CustomZoomLevels.Add(zl);
}
// Set the map view current extent to a bounding box that shows just a few restaurants.
mapView.CurrentExtent = rectOverlay;
mapView.ZoomLevelSet = GetCustomZoomLevelSet();
// Refresh the map.
mapView.Refresh();
}
}
ZoomLevelSet GetCustomZoomLevelSet()
{
ZoomLevelSet zoomLevelSet = new ZoomLevelSet();
double topScale = mapView.ZoomLevelSet.ZoomLevel01.Scale;
for (int i = 0; i < 23; i++)
{
zoomLevelSet.CustomZoomLevels.Add(new ZoomLevel(topScale / Math.Pow(2, i)));
}
return zoomLevelSet;
}
}
}