Это звучит похоже на (довольно неясную) проблему в трекере Leaflet некоторое время назад: см. https://github.com/Leaflet/Leaflet/issues/3081
Однако эта проблема имела дело с бесконечными горизонтальными границами, а невертикальные границы в CRS, который уже имеет некоторые предустановленные пределы .
Если вы установите для maxBounds
карты значение больше 85 (значение для MAX_LATITUDE
из L.Projection.Spherical
) и запустить отладчик, стек вызовов проходит через _panInsideMapBounds()
карты, затем panInsideBounds()
, затем _limitCenter()
, затем _getBoundsOffset
, затем project()
, затем через CRS карты latLngToPoint
тогда безоговорочно L.Projection.Spherical
х project()
.L.Projection.Spherical.project()
проецирует пределы границ в пиксельные координаты, и ограничивают проецируемую точку , чтобы она находилась за пределами проекции.
Существует множество причин для этогоодин из них заключается в том, чтобы запретить пользователям размещать маркеры за пределами области, покрытой плиткой:
(Это особенно важно, когда пользователь вводит в заблуждениеlng с помощью lng-lat и пытается использовать значение вне диапазона [-90,90] для широты, и код проекции начинает возвращать Infinity
значения везде)
Как обойти это?Ну, мы всегда можем указать CRS карты, и мы можем создать CRS со взломанной проекцией, которая устанавливает другое ограничение.Пожалуйста, имейте в виду, что это меняет работу pixelOrigin
внутри (как объяснено в учебнике Leaflet по расширению слоев ), поэтому вещи (особенно плагины) могут сломаться.
Так что-то вроде:
var hackedSphericalMercator = L.Util.extend(L.Projection.SphericalMercator, {
MAX_LATITUDE: 89.999
});
var hackedEPSG3857 = L.Util.extend(L.CRS.EPSG3857, {
projection: hackedSphericalMercator
});
var map = new L.Map('mapcontainer', {
crs: hackedEPSG3857,
});
Конечно, тогда вы можете настроить свои собственные maxBounds
:
var map = new L.Map('mapcontainer', {
crs: hackedEPSG3857,
maxBounds: [[-Infinity, -10], [Infinity, 10]]
});
В этом случае пределы границ все равно будут ограничены до hackedSphericalMercator.MAX_LATITUDE
, ноу вас должно быть достаточно места для маневра для вашего приложения.
В качестве примечания: радикально иной подход к этой проблеме будет заключаться в использовании другой проекции карты.Мы привыкли к сферической цилиндрической проекции, но это не единственный способ выровнять землю.
В частности, Поперечная проекция Меркатора (или почти любая другая поперечная цилиндрическая проекция,в этом отношении) работает в значительной степени таким же образом, но оборачивается вертикально, а не горизонтально, и это проецируемые долготы , а не широты, которые асимптотически приближаются к бесконечности при приближении к диапазону [-180, 180],Позвольте мне позаимствовать изображение из его статьи в Википедии:
Это подразумевает другой набор задач (а именно поиск некоторых растровых плиток, подходящих для вашего приложения, включаякакой основной меридиан использовать, и заставить proj4leaflet играть хорошо), но это определенно выполнимо.