Клуб API Карт

Отступ до края карты

Пост в архиве.

Опыт работы с Yandex Map невелик, поэтому прошу помощи, пните в нужном направлении.

Есть необходимость центрировать карту по группе точек. Это без проблем.

// list - это список координат
var collection = new ymaps.GeoObjectCollection();
for(var p in list) {
var place = list[p];

collection.add(new ymaps.Placemark([place.lat, place.lng]));
}

map.geoObjects.add(collection);
map.setBounds(collection.getBounds());

Но смысл в том, что маркеры могут попадать под навигацию (зумирование) или очень близко к верхнему краю. Хотелось бы выставить отступы от края(что-ли) или определить расстояние маркера до края на карте, если он находится <20px от края, то делать зум -1


map.setZoom(map.getZoom() - 1);


11 комментариев

Сейчас наверное самое простое решение - всегда уменьшать зум на 1. А в будущих релизах мы добавим опцию margin для метода setBounds, чтобы можно было задавать отступы от любого края видимой области карты.

Удалённый пользователь
28 января 2016, 02:34

Мы легких путей не ищем))
Вообще как нибудь возможно представить(получить) координаты маркера относительно края карты(видимой области) в пикселах? 

Да, можно, алгоритм такой.

1. Получаем центр карты в глобальных пиксельных координатах map.getGlobalPixelCenter()

2. Получаем размер видимой области карты map.container.getSize()

3. Получаем по центру и размерам координаты углов карты в глобальных пикселях.

4. Получаем глобальные пиксельные координаты метки через projection.toGlobalPixels

5. Сравниваем с координатами углов карты.

Вот как раз тема подходящая. Заодно и вопрос задам.

У меня аналогичная задача, я пытаюсь сделать "в лоб"

//listPoints - коллекция геообъектов

function set_bounds_offset(){
    var size=myMap.container.getSize(),
        map_bounds=myMap.getBounds(),
        bounds=listPoints.getBounds(),
        offsets=[50,50,50,50],//bottom,left,top,right
        x=(map_bounds[1][1]-map_bounds[0][1])/size[0],
        y=(map_bounds[1][0]-map_bounds[0][0])/size[1];
    return [[bounds[0][0]-offsets[0]*y,bounds[0][1]-offsets[1]*x],[bounds[1][0]+offsets[2]*y,bounds[1][1]+offsets[3]*x]];
};

myMap.setBounds(set_bounds_offset(),{precizeZoom:true});

Без {precizeZoom:true} получаются слишком большие отступы из за но зато гарантированно ничего не попадает под контролы расположенные по углам. С {precizeZoom:true} вообще метки выпадают за пределы видимости. Подскажите, пожалуйста, где у меня ошибка.

 

Вы какую-то разницу в градусах делите на пиксели и получаете ерунду

"Какая-то разница в градусах" - это ширина и высота видимой области в градусах, после деления на "пиксели", а точнее на соответствующие размеры той же видимой области в пикселях в x, y должно находиться сколько градусов у нас приходится на один пиксель(град/пиксель). Если такое рассуждение неверно - поясните пожалуйста, я не так давно начал заниматься JavaScript и картами, поэтому вполне могу чего-то не понимать.

 

Градусы на пиксели делить не имеет смысла.
Марина выше привела правильный алгоритм преобразования. Воспользуйтесь им.

"Градусы на пиксели делить не имеет смысла." Почему?

После того как я установил {avoidFractionalZoom:false} всё работает. Алгоритм Марины можно значительно упростить если использовать getPixelBounds() и map.projection.wgs84Mercator.fromGlobalPixels(globalPixelPoint, zoom). Так я тоже пробовал, результаты аналогичные. На данный момент проблема в этих двух методах заключается в том, что правильные оффсеты устанавливаются только в случае если не меняется зум. В случае если зум после setBounds() изменился смещения тоже изменяются.

в одном градусе может быть разное количество пикселей, в зависимости от широты
Градусы - угловая величина и может быть меньше нуля

"в одном градусе может быть разное количество пикселей, в зависимости от широты" - а так же в зависимости от зума. И больше скажу не может быть, а должно быть. В моём случае мы в общем-то получаем(ведь линейные размеры мы вычисляем по противоположным углам) усреднённую величину для текущего зума, и если нам не нужна абсолютная точность(ну вот кто будет мерить реально ли отступ 50 пикселей а не 49 или 51?) результат оказывается вполне приемлемым.

"Градусы - угловая величина и может быть меньше нуля" - если говорить конкретно о моей задаче, то меня интересует только Россия, и тут никаких отрицательных величин не будет. А в общем случае мой вариант и с отрицательными значениями тоже вполне себе работает.

Ну да ладно, в таком ключе этот спор ни к чему не приведёт.

Собственно у меня появился другой вопрос. Чисто математический, как посчитать какой коэффициент зума будет выставлен если мы знаем область которая будет передана в setBounds() и размер контейнера

про другой вопрос лучше создать отдельную  тему