Хорошо, я решил проблему.Ключом к решению было прекратить попытки заставить план заполнить всю карту, а вместо этого изменить размер изображения, чтобы оно стало действительно маленьким, и поместить его в [0, 0]
координаты на карте.Таким образом, мы можем предположить, что мир здесь плоский, и вообще не беспокоиться о его кривизне.
Поэтому, когда карта загружается, я загружаю изображение, чтобы получить его размеры:
this.map.current.on('load', () => {
const img = new Image()
const self = this
img.addEventListener('load', function () {
// ...
})
img.src = planUrl
})
Затем, когда это будет сделано, в обработчике load
изображения я изменяю размер изображения и создаю LngLatBounds
его.Я просто делю ширину и высоту здесь, чтобы получить lng
и lat
изображения - они будут меньше 1 как для lng
, так и lat
, поэтому я не думаю, что кривизна Землибудет проблема на этом уровне:
img.addEventListener('load', function () {
const maxWidth = 1
const maxHeight = 0.5
const [width, height] = resizeImage(
this.naturalWidth,
this.naturalHeight,
maxWidth,
maxHeight
)
const sw = [-width / 2, -height / 2]
const ne = [width / 2, height / 2]
const bounds = new LngLatBounds(sw, ne)
// ...
})
Затем я добавляю источник с планом этажа и слой, отображающий план на карту:
self.map.current.addSource('plan', {
type: 'image',
url: planUrl,
coordinates: [
bounds.getNorthWest().toArray(),
bounds.getNorthEast().toArray(),
bounds.getSouthEast().toArray(),
bounds.getSouthWest().toArray()
]
})
self.map.current.addLayer({
id: 'image',
source: 'plan',
type: 'raster'
})
А потом яЯ устанавливаю границы карты, равные 2-кратному размеру границ изображения, поэтому план будет иметь хорошее отступление вокруг него.
const mapBounds = new LngLatBounds(sw, ne)
mapBounds.extend(new LngLatBounds([-width, -height], [width, height]))
self.map.current.setMaxBounds(mapBounds)
Возможно, есть и лучшие решения, чем этот, но выглядит таку меня просто отлично работаетНадеюсь, это поможет кому-то еще.