ThinkGeo.com    |     Documentation    |     Premium Support

Tile Cache still caches invisible overlays?

We have a set of overlays, each setup to appear at different ranges of scales. Very detailed vector-based overlays appear at small scales, and less-detailed vectors or raster overlays take over at larger scales. For the vector overlays, this is achieved by assigning custom styles to a sub-range of each Shape File layer’s ZoomLevelSet. For the raster overlays, we assign an UpperScale and LowerScale to each layer.

This works just great, but we’ve noticed that any overlays that are within the bounds of the map, but out of range of the current scale and therefore not visible, are still being cached, but as empty (full-size but entirely transparent) PNG tiles. This feels pretty wasteful, both in terms of performance and also storage space - the empty tiles still take up around 2-4Kb each.

Are we missing something?
Thanks.

Hi Jason,

That’s because the TileOverlay, as well as its TileCache, by default is using the Global TileMatrixSet, where the entire world fits in a single image as zoom 0, each tile “splits” to 4 images when going to the next level. So your overlay will keep generating the cache as long as it’s within the extent of the Matrix (in this case the entire world). Here is a general idea of the default Tiling System.
image

This case has been taken care of in v14.3. We have a sample below showing you how to set your own TileMatrixSet.
samples/wpf/HowDoISample/Samples/Miscellaneous/CacheTileOverlay.xaml.cs · master · ThinkGeo / Public / Desktop Maps · GitLab

The sample shows the City of Frisco using its bounding box, instead of the default global extent, in its TileMatrixSet. You see the Tile Number is 0-0-0, meaning it’s the zoom0 tile, and TileCache will NOT be generated when you pan out of the area.

And here is the same extent with the default TileMatrixSet (so it’s under zoom 9). In this case, the TileCache will always be generated.

Have a try and let us know if you have any questions.

Thanks,
Ben

Thanks Ben,
We do have local TileMatrixSets for each of the overlays, but are still seeing this problem.

As far as I can work out, the example code has only a single overlay which has its TileMatrixSet’s ZoomScales assigned to the map control for a one-to-one match. As we have five overlays, each with a different TileMatrixSet and different range of scales, we have used the bounding box of the largest to generate a TileMatrixSet whose ZoomScales we can assign to the map in order to cover the entire area - is this wrong?

With this set-up we are still seeing the excess cache tiles being generated - note that if we pan away from the bounds of an overlay, it does not get cached, as we would expect. The excess caching happens if the overlay bounds remains within (or crossing) the viewed map bounds, but zoomed out to a level that the overlay is no longer being displayed.

To use your example above, if we set the styling for Frisco such that there is no style for levels 1-10, then we centre on Frisco but zoom out to level 10, Frisco no longer appears on screen but the cache is still populated - with empty tiles.

Hi Jason,

Each Overlay should have a TileMatrixSet generated with its own BoundingBox. So for your case, instead of using the largest bouding box of the 5 overlays, you can use the boundingBox of each overly to generate that overlay’s TileMatrixSet.

The overlay cannot detect if the inside layers are drawn or not. So for example if your layer is drawn within zoomlevel01-10, and the Overlay will still be cached even when zooming in to zoomlevel11. You can work that around by for example, hooking up MapView.CurrentScaleChanged event, set the Overlay.IsVisible to false if the internal layers are not drawn.

 MapView.CurrentScaleChanged += MapView_CurrentScaleChanged;
 private void MapView_CurrentScaleChanged(object sender, CurrentScaleChangedMapViewEventArgs e)
 {
    // set the layerOverlay.IsVisible to false if the layers within layerOverlay will not be displayed under e.NetScale
 }

Please have a try and see if that works for you.

Thanks,
Ben

We are generating each overlay’s TileMatrixSet with that overlay’s own bounding box, it’s the ZoomScales applied to the map control where we’ve elected to use the largest of the overlays’ bounding boxes to create those. That seemed like the best approach?

We did experiment with the CurrentScaleChanged event earlier, but had some issues with refresh - will give it another try.
Thanks.

Hi Jason,

It’s a good practice to apply MapView.ZoomScales with the largest of the overlays’ bounding boxes. Just want to make it clear:

  1. MapView.ZoomScales only controls what scales the map control snaps to when using mouse (double click zooming, scroll zooming in/out) or PanZoomBar.
  2. You can programmatically zoom the map to any scale, doesn’t have to be one in MapView.ZoomScales.
  3. MapView.ZoomScales has nothing to do with the TileOverlay’s TileMatrixSet, nor FeatureLayer’s zoomlevelset.

I hope it makes sense, let me know if you have any more questions.

Thanks,
Ben