Skip to content

Commit

Permalink
Fixing blank tiles when zooming in OS source
Browse files Browse the repository at this point in the history
  • Loading branch information
tstibbs committed Jan 12, 2025
1 parent 959ca50 commit 6018888
Showing 1 changed file with 35 additions and 45 deletions.
80 changes: 35 additions & 45 deletions ui/src/js/layers.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,51 @@
import leaflet from 'VendorWrappers/leaflet.js'
import LeafletBing from 'VendorWrappers/bing-layer.js'
import constants from './constants.js'
const minOverallZoom = 1
const maxOverallZoom = 19

//because we have a mix of zooms, we have to either change the maxZoom value on the main map whenever we change layer, or we have to set the min and max the same for each layer(/layergroup). The latter is simpler, but means we have to set maxNativeZoom for those sources which can't provide tiles at the max overall zoom level. However, setting detectRetina=true breaks this, as per https://github.com/Leaflet/Leaflet/issues/8850
//thus, we disable detectRetina in all sources to ensure that the maxNativeZoom property is correctly obeyed :(

var defaults = {
key: constants.bingKey
minZoom: minOverallZoom,
maxZoom: maxOverallZoom,
detectRetina: false
}
var bingDefaults = leaflet.extend({maxZoom: 18, minZoom: 0, detectRetina: true}, defaults)
var bingDefaults = leaflet.extend({}, defaults, {
key: constants.bingKey,
maxNativeZoom: 18
})

//Bing standard maps
var bingRoads = new LeafletBing(leaflet.extend({}, bingDefaults, {imagerySet: 'RoadOnDemand'}))
var bingHybrid = new LeafletBing(leaflet.extend({}, bingDefaults, {imagerySet: 'AerialWithLabelsOnDemand'}))
var bingAerial = new LeafletBing(leaflet.extend({}, bingDefaults, {imagerySet: 'Aerial'}))

//OS
var bingOsLayer = new LeafletBing(
leaflet.extend(
{
imagerySet: 'OrdnanceSurvey',
minZoom: 12,
maxZoom: 18,
maxNativeZoom: 17
},
defaults
)
leaflet.extend({}, bingDefaults, {
imagerySet: 'OrdnanceSurvey',
minZoom: 12,
maxNativeZoom: 17
})
) //note OS doesn't support retina
//fallback layer because the OS maps don't scale well when you zoom out
var bingFallbackLayer = new LeafletBing(leaflet.extend({imagerySet: 'RoadOnDemand', maxZoom: 11, minZoom: 0}, defaults)) //note even though this layer supports retetina, having a group with a mix of retina and non-retina screws up the zooming
var bingFallbackLayer = new LeafletBing(
leaflet.extend({}, bingDefaults, {
imagerySet: 'RoadOnDemand',
maxZoom: 11
})
)
var bingOsGroup = leaflet.layerGroup([bingOsLayer, bingFallbackLayer])
//Bing standard maps
var bingRoads = new LeafletBing(leaflet.extend({imagerySet: 'RoadOnDemand'}, bingDefaults))
var bingHybrid = new LeafletBing(leaflet.extend({imagerySet: 'AerialWithLabelsOnDemand'}, bingDefaults))
var bingAerial = new LeafletBing(leaflet.extend({imagerySet: 'Aerial'}, bingDefaults))

//OSM
var osm = new leaflet.TileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
minZoom: 0,
maxZoom: 19,
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors'
})
var osm = new leaflet.TileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
leaflet.extend({}, defaults, {
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors'
})
)

var layers = {
OS: bingOsGroup,
Expand All @@ -41,30 +55,6 @@ var layers = {
OSM: osm
}

function layerZoomExtractor(layers) {
let max = 0
let min = Number.MAX_SAFE_INTEGER
layers.forEach(layer => {
if (layer.getLayers) {
let {max: subLayersMax, min: subLayersMin} = layerZoomExtractor(layer.getLayers())
max = Math.max(max, subLayersMax)
min = Math.min(min, subLayersMin)
}
if (layer.options?.maxZoom) {
max = Math.max(max, layer.options.maxZoom)
}
if (layer.options?.maxZoom) {
min = Math.min(min, layer.options.minZoom)
}
})
return {
max,
min
}
}
//now go back through all layers and compile the overall min and max - this is safer than trying to know it up front and then enforce it on the layers
const {max: maxOverallZoom, min: minOverallZoom} = layerZoomExtractor(Object.values(layers))

function _listenForLayerChange(layerId, layer, config) {
layer.on(
'add',
Expand Down

0 comments on commit 6018888

Please sign in to comment.