Страница 1 из 1
Leaflet местная система координат L.CRS.Simple
Добавлено: 07 июл 2015, 21:41
fynjy888
Всем привет! У меня есть карта на
leaflet.js размер карты 5913x7863 и она в местных плоских координатах (X Y) система координат соответственно
L.CRS.Simple
До этого я использовал
L.imageOverlay:
Код: Выделить всё
var imageBounds = [[1468.9700,-11.7050], [1968.2705,363.7705]];
var file0 = new L.imageOverlay(imageUrl, imageBounds).addTo(map);
И всё было супер
Но я понял, что это плохой путь (единая картинка вылетает на мобилках и так карты не делают) и нужны тайлы
Далее я нарезал на тайлы (при помощи приложения яндекса, но не суть важно)
Тайлы хранятся по папкам "3/1/0" "3/1/1" и т.д.
Я хочу сделать координаты X Y - чтобы карта была в координатах [1468.9700,-11.7050], [1968.2705,363.7705]
Но как сделать даже в координатах [0,0] [5913,7863] я не понимаю.
Код сейчас такой:
Код: Выделить всё
L.tileLayer('images/tiles/{z}/{x}/{y}.png', {
continuousWorld: true,
noWrap: true,
maxZoom: 6,
minZoom: 3
}).addTo(map);
При этом картинка находится в координатах примерно [0,0], [-123,92] - почему именно такие не понимаю вообще. Пожалуйста, любые идеи. Мучаюсь уже целый месяц
Re: Leaflet местная система координат L.CRS.Simple
Добавлено: 08 июл 2015, 11:38
Denis Rykov
Не очень понятно чего вы хотите. На 0 уровне карта, обычно, состоит из 1 тайла, скажем, 256x256 и только на каком-то определенном уровне, на котором разрешение совпадает с разрешением исходного растра, размер карты с ним совпадёт.
Re: Leaflet местная система координат L.CRS.Simple
Добавлено: 08 июл 2015, 14:11
fynjy888
Denis Rykov писал(а):Не очень понятно чего вы хотите. На 0 уровне карта, обычно, состоит из 1 тайла, скажем, 256x256 и только на каком-то определенном уровне, на котором разрешение совпадает с разрешением исходного растра, размер карты с ним совпадёт.
да, карта разрезана на тайлы, первая папка содержит только один файл 256х256 1/0/0 (у меня не с 0-го уровня, а с 1-го)
на 6-ом уровне тайлы разрезаны также как и разрешение - то есть 5913x7863 и там уже очень много файлов: 6/0/0 6/0/1 и т.д.
Я хочу плоские X Y координаты, чтобы выставляя например L.circle([1750, 170] - я получал кружок в середину карты. Сейчас же карта почему-то в координатах примерно [0,0], [-123,92]
P.S. Спасибо за ответ

Re: Leaflet местная система координат L.CRS.Simple
Добавлено: 10 июл 2015, 11:32
Denis Rykov
Всё очень просто. Если масштабный уровень на котором слой имеет оригинальное разрешение равен z, то для того, чтобы добавить маркер в точку с координатам (x,y) исходного растра, достаточно выполнить команду:
Код: Выделить всё
L.marker(map.unproject([x, y], z)).addTo(map);
В этом легко убедиться, открыв
пример (исходный размер растра 3410 x 2058, оригинальное разрешение на 4 зуме) и введя в консоли:
Код: Выделить всё
L.marker(map.unproject([3410/2, 2058/2], 4)).addTo(map);
Маркер будет помещен в центр изображения.
Re: Leaflet местная система координат L.CRS.Simple
Добавлено: 10 июл 2015, 15:12
fynjy888
Denis Rykov писал(а):Всё очень просто. Если масштабный уровень на котором слой имеет оригинальное разрешение равен z, то для того, чтобы добавить маркер в точку с координатам (x,y) исходного растра, достаточно выполнить команду:
Код: Выделить всё
L.marker(map.unproject([x, y], z)).addTo(map);
В этом легко убедиться, открыв
пример (исходный размер растра 3410 x 2058, оригинальное разрешение на 4 зуме) и введя в консоли:
Код: Выделить всё
L.marker(map.unproject([3410/2, 2058/2], 4)).addTo(map);
Маркер будет помещен в центр изображения.
Проблема в том, что мне нужны границы именно [1468.9700,-11.7050], [1968.2705,363.7705]
Почему это так легко сделать в L.imageOverlay
Код: Выделить всё
var imageUrl = 'images/maps/987654321.png';
var imageBounds = [[1468.9700,-11.7050], [1968.2705,363.7705]];
var shpfile0 = new L.imageOverlay(imageUrl, imageBounds).addTo(map);
и так трудно в тайлах?, хотя суть ведь таже
Re: Leaflet местная система координат L.CRS.Simple
Добавлено: 11 июл 2015, 10:17
Denis Rykov
Не понимаю в чем проблема, сделайте:
Код: Выделить всё
map.setMaxBounds(new L.LatLngBounds(
map.unproject([1468.9700,-11.7050], 6),
map.unproject([1968.2705,363.7705], 6)
));
Re: Leaflet местная система координат L.CRS.Simple
Добавлено: 11 июл 2015, 10:52
fynjy888
Denis Rykov писал(а):Не понимаю в чем проблема, сделайте:
Код: Выделить всё
map.setMaxBounds(new L.LatLngBounds(
map.unproject([1468.9700,-11.7050], 6),
map.unproject([1968.2705,363.7705], 6)
));
Огромное спасибо за помощь

но видимо я делаю что-то не то
Границы не позволяют мне листать карту, и установились судя по всему в [0,0] - [7950, 7863],(да, да, именно 7950, причем координаты в порядке X Y, а не Y X как везде) а хотелось [1468.9700,-11.7050] - [1968.2705,363.7705]
Подключили карту, setView(1750, 170) - примерно середина
Код: Выделить всё
var map = L.map('map', {
maxZoom: 6,
minZoom: 3,
crs: L.CRS.Simple
}).setView([1750, 170], 6);
Выставляем границы
Код: Выделить всё
map.setMaxBounds(new L.LatLngBounds(
map.unproject([1468.9700,-11.7050], 6),
map.unproject([1968.2705,363.7705], 6)
));
Выводим тайлы
Код: Выделить всё
L.tileLayer('images/tiles/{z}/{x}/{y}.png', {
attribution: '',
continuousWorld: true
}).addTo(map);
Без continuousWorld: true - не отображается вообще. В инструкциях сказано, что нужно выставлять для плоских изображений как раз.
В итоге границы не позволяют мне листать карту и координаты не те, что в границах
P.S. Еще раз спасибо за ответы

Re: Leaflet местная система координат L.CRS.Simple
Добавлено: 15 авг 2015, 16:54
fynjy888
Пробую решить проблему:
Код: Выделить всё
var w = 5913;
var h = 7863;
var mapMinZoom = 0;
var mapMaxZoom = 5;
var _map = L.map('map', {
maxZoom: mapMaxZoom,
minZoom: mapMinZoom,
crs: L.CRS.Simple,
zoomControl: false,
attributionControl: false,
});
var _mapBounds = new L.LatLngBounds(
_map.unproject([0, h], mapMaxZoom),
_map.unproject([w, 0], mapMaxZoom));
_map.setMaxBounds(_mapBounds);
var _mapCenter = _map.unproject([w/2, h/2], mapMaxZoom);
_map.setView(_mapCenter, 3);
var _tileLayer = L.tileLayer('images/tiles/{z}/{x}/{y}.png', {
minZoom: mapMinZoom, maxZoom: mapMaxZoom,
bounds: _mapBounds,
continuousWorld: true,
noWrap:true,
tileSize:256,
crs: L.CRS.Simple,
detectRetina:false
}).addTo(_map);
Но это не помогло

Обычные координаты около -247,184
unproject координаты около 1480,1970
Re: Leaflet местная система координат L.CRS.Simple
Добавлено: 17 авг 2015, 16:53
parshin
В Leaflet'а есть понятие "pixel coordinates" - это номера пикселей на определённом зуме относительно верхнего левого угла мира. L.CRS'ы как раз и нужны, чтобы пересчитывать из географических координат в пиксельные и обратно (они делают это через projection, transformation и scale, но это не суть важно).
Слой L.TileLayer предполагает, что тайлы всегда имеют одинаковые пиксельные координаты. Например, левый верхний тайл - [[0,0],[255,255]], следующий по горизонтали - [[0,256],[255,511]] и т.п. Никак изменить эти координаты нельзя.
Теперь нужно понять, как система координат L.CRS.Simple переводит из пиксельных координат в географические. Делает это она так: левый верхний угол мира [0,0] они переводит в [0,0], правый нижний в [-256*2^z, 256*2^z].
Соответственно, центр тайла z=0 имеет координаты [-128, 128], центр левого верхнего тайла на z=1 - [-64, 64] и т.п. Отсюда у вас и получаются такие вот странные координаты.
Конструктив такой: если у вас есть только один такой тайловый растровый слой, и вы ходите накладывать на него какие-то векторные объекты с определёнными координатами, попробуйте задать карте свою систему координат (L.CRS). Она должна быть устроена так: самый левый верхний пиксель с данными на ваших тайлах на каждом из зумов переводить в координаты [1468.9700,-11.7050], правый нижний - в координаты [1968.2705,363.7705]. Наверное, тут придётся разбираться подробнее, как устроена системы координат в Leaflet (лучше смотреть исходники)
Если у вас есть две картинки (overlay) с разными смещениями, которые вы натайлили без учёта их смещений (картинка занимает весь тайл нулевого уровня), то правильно соединить их при помощи L.TileLayer не удастся (по крайней мере без модификации L.TileLayer).
Всё это относится к Leaflet 0.7, но не думаю, что в 1.0 что-то сильно поменялось...
Re: Leaflet местная система координат L.CRS.Simple
Добавлено: 30 авг 2015, 01:14
fynjy888
parshin писал(а):
Конструктив такой: если у вас есть только один такой тайловый растровый слой, и вы ходите накладывать на него какие-то векторные объекты с определёнными координатами, попробуйте задать карте свою систему координат (L.CRS). Она должна быть устроена так: самый левый верхний пиксель с данными на ваших тайлах на каждом из зумов переводить в координаты [1468.9700,-11.7050], правый нижний - в координаты [1968.2705,363.7705].
Спасибо за разъяснения)
Сумел воплотить задуманное в openlayers
Код: Выделить всё
var mapBounds = new OpenLayers.Bounds(-11.705000, 1468.971000, 363.770500, 1968.271500);
var mapMinZoom = 0;
var mapMaxZoom = 5;
var mapMaxResolution = 0.063500;
var gridBounds = new OpenLayers.Bounds(-11.705000, 1468.971000, 363.770500, 1968.271500);
Вопрос теперь как сделать такое в leaflet

Я так понимаю простыми манипуляциями не выйдет, нужно пользоваться Proj.4 и Proj4Leaflet,
там вообще есть условная местная система координат?
Re: Leaflet местная система координат L.CRS.Simple
Добавлено: 31 авг 2015, 10:40
parshin
Сумел воплотить задуманное в openlayers
Вы там вроде бы код не дописали... В OL, насколько я понимаю, можно использовать опцию maxExtent класса OpenLayers.Layer, в Leaflet аналога такой опции нет.
Вопрос теперь как сделать такое в leaflet

Я так понимаю простыми манипуляциями не выйдет, нужно пользоваться Proj.4 и Proj4Leaflet, там вообще есть условная местная система координат?
Да нет, не обязательно... Возьмите за основу L.CRS.Simple и подправьте там параметр transformation нужным вам образом (это преобразование проецированных координат в пиксельные).
Ну или, если хотите использовать Proj4Leaflet, попробуйте L.Proj.CRS.TMS. Вроде бы там можно в явном виде задать projectedBounds (но я не уверен).
Re: Leaflet местная система координат L.CRS.Simple
Добавлено: 11 сен 2015, 23:29
fynjy888
Мой ответ (чтобы люди заходящие в эту ветку не расстраивались, не получив ответа)
Код: Выделить всё
L.CRS.Wall = L.extend({}, L.CRS.Simple, {
transformation: new L.Transformation(0.4920000014213405, 5.758860016636791, -0.4920000014213405, 968.389580797584)});
parshin спасибо огромное
