Leaflet местная система координат L.CRS.Simple

Mapserver, GeoServer, MapGuide, Google и другое ПО для веб-картографии
Ответить
fynjy888
Интересующийся
Сообщения: 35
Зарегистрирован: 06 июл 2015, 23:01
Репутация: 2

Leaflet местная система координат L.CRS.Simple

Сообщение fynjy888 » 07 июл 2015, 21:41

Всем привет! У меня есть карта на 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);
И всё было супер

Но я понял, что это плохой путь (единая картинка вылетает на мобилках и так карты не делают) и нужны тайлы :o

Далее я нарезал на тайлы (при помощи приложения яндекса, но не суть важно)
Тайлы хранятся по папкам "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] - почему именно такие не понимаю вообще. Пожалуйста, любые идеи. Мучаюсь уже целый месяц
Последний раз редактировалось fynjy888 08 июл 2015, 14:25, всего редактировалось 1 раз.

Аватара пользователя
Denis Rykov
Гуру
Сообщения: 3376
Зарегистрирован: 11 апр 2008, 21:09
Репутация: 529
Ваше звание: Author
Контактная информация:

Re: Leaflet местная система координат L.CRS.Simple

Сообщение Denis Rykov » 08 июл 2015, 11:38

Не очень понятно чего вы хотите. На 0 уровне карта, обычно, состоит из 1 тайла, скажем, 256x256 и только на каком-то определенном уровне, на котором разрешение совпадает с разрешением исходного растра, размер карты с ним совпадёт.
Spatial is now, more than ever, just another column- The Geometry Column.

fynjy888
Интересующийся
Сообщения: 35
Зарегистрирован: 06 июл 2015, 23:01
Репутация: 2

Re: Leaflet местная система координат L.CRS.Simple

Сообщение fynjy888 » 08 июл 2015, 14:11

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. Спасибо за ответ :wink:

Аватара пользователя
Denis Rykov
Гуру
Сообщения: 3376
Зарегистрирован: 11 апр 2008, 21:09
Репутация: 529
Ваше звание: Author
Контактная информация:

Re: Leaflet местная система координат L.CRS.Simple

Сообщение Denis Rykov » 10 июл 2015, 11:32

Всё очень просто. Если масштабный уровень на котором слой имеет оригинальное разрешение равен 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);
Маркер будет помещен в центр изображения.
Spatial is now, more than ever, just another column- The Geometry Column.

fynjy888
Интересующийся
Сообщения: 35
Зарегистрирован: 06 июл 2015, 23:01
Репутация: 2

Re: Leaflet местная система координат L.CRS.Simple

Сообщение fynjy888 » 10 июл 2015, 15:12

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);
и так трудно в тайлах?, хотя суть ведь таже

Аватара пользователя
Denis Rykov
Гуру
Сообщения: 3376
Зарегистрирован: 11 апр 2008, 21:09
Репутация: 529
Ваше звание: Author
Контактная информация:

Re: Leaflet местная система координат L.CRS.Simple

Сообщение Denis Rykov » 11 июл 2015, 10:17

Не понимаю в чем проблема, сделайте:

Код: Выделить всё

map.setMaxBounds(new L.LatLngBounds(
    map.unproject([1468.9700,-11.7050], 6),
    map.unproject([1968.2705,363.7705], 6)
));
Spatial is now, more than ever, just another column- The Geometry Column.

fynjy888
Интересующийся
Сообщения: 35
Зарегистрирован: 06 июл 2015, 23:01
Репутация: 2

Re: Leaflet местная система координат L.CRS.Simple

Сообщение fynjy888 » 11 июл 2015, 10:52

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. Еще раз спасибо за ответы :mrgreen:

fynjy888
Интересующийся
Сообщения: 35
Зарегистрирован: 06 июл 2015, 23:01
Репутация: 2

Re: Leaflet местная система координат L.CRS.Simple

Сообщение fynjy888 » 15 авг 2015, 16:54

Пробую решить проблему:

Код: Выделить всё

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

parshin
Участник
Сообщения: 57
Зарегистрирован: 13 фев 2011, 10:34
Репутация: 26
Откуда: Moscow, Russia
Контактная информация:

Re: Leaflet местная система координат L.CRS.Simple

Сообщение parshin » 17 авг 2015, 16:53

В 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 что-то сильно поменялось...

fynjy888
Интересующийся
Сообщения: 35
Зарегистрирован: 06 июл 2015, 23:01
Репутация: 2

Re: Leaflet местная система координат L.CRS.Simple

Сообщение fynjy888 » 30 авг 2015, 01:14

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 :mrgreen: Я так понимаю простыми манипуляциями не выйдет, нужно пользоваться Proj.4 и Proj4Leaflet, там вообще есть условная местная система координат?

parshin
Участник
Сообщения: 57
Зарегистрирован: 13 фев 2011, 10:34
Репутация: 26
Откуда: Moscow, Russia
Контактная информация:

Re: Leaflet местная система координат L.CRS.Simple

Сообщение parshin » 31 авг 2015, 10:40

Сумел воплотить задуманное в openlayers
Вы там вроде бы код не дописали... В OL, насколько я понимаю, можно использовать опцию maxExtent класса OpenLayers.Layer, в Leaflet аналога такой опции нет.
Вопрос теперь как сделать такое в leaflet :mrgreen: Я так понимаю простыми манипуляциями не выйдет, нужно пользоваться Proj.4 и Proj4Leaflet, там вообще есть условная местная система координат?
Да нет, не обязательно... Возьмите за основу L.CRS.Simple и подправьте там параметр transformation нужным вам образом (это преобразование проецированных координат в пиксельные).

Ну или, если хотите использовать Proj4Leaflet, попробуйте L.Proj.CRS.TMS. Вроде бы там можно в явном виде задать projectedBounds (но я не уверен).

fynjy888
Интересующийся
Сообщения: 35
Зарегистрирован: 06 июл 2015, 23:01
Репутация: 2

Re: Leaflet местная система координат L.CRS.Simple

Сообщение fynjy888 » 11 сен 2015, 23:29

Мой ответ (чтобы люди заходящие в эту ветку не расстраивались, не получив ответа)

Код: Выделить всё

L.CRS.Wall = L.extend({}, L.CRS.Simple, {
transformation: new L.Transformation(0.4920000014213405, 5.758860016636791, -0.4920000014213405, 968.389580797584)});
parshin спасибо огромное :wink:

Ответить

Вернуться в «Веб-картография»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 0 гостей