Клуб API Карт

Как подсчитать минимально необходимый размер карты в пикселях зная координаты крайних объектов

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

Вот Здесь обсуждалась похожая тема, но то ли формула приведена неверная то ли я чего то не допонял.

У меня никак не поулучается посчитать широту.

Вот для примера формула которая у меня получилась для расчета ширины Яндекс карты при известных координатах:

Имеем 2 крайних объекта на карте с координатами (д1, ш1) и (д2, ш2)

Для отображения этих объектов минимально необходимая ширина  карты в пикселях  2^(z+8)*(dmax-dmin)/360, где (dmax-dmin) - разность большего и меньшего значений д1 и д2 (градусов долготы), z - коэффициент масштабирования карты.

А вот как тоже самое посчитать для широты, чтобы вычислить минимальную высоту карты никак не соображу.

Подскажите пожалуйста. По возможности не пишите ссылки на похожие темы и на описание проекции Меркатора. Нужна чистая формула.

15 комментариев
Sergey Konstantinov
28 января 2016, 02:52
Перевести координаты в пиксели:
var pixelPoint1 = ymaps.projection.wgs84Mercator.toGlobalPixels(point1, z),
     pixelPoint2 = ymaps.projection.wgs84Mercator.toGlobalPixels(point2, z);
Искомые размеры - разность координат
var width = Math.abs(pixelPoint1[0] - pixelPoint2[0]),
    height = Math.abs(pixelPoint1[1] - pixelPoint2[1]);
Формула будет чуть сложнее, если есть переход через Берингов пролив.

Спасибо. Но это не совсем, то что я хотел. Попробую объяснить более подробно:

1. Мне нужно, чтобы центр карты и ее масштаб выбирался автоматически в зависимости от координат объектов (меток) на ней расположенных.

2. Я думаю это можно сделать с помощью API карт, но не знаю как. Поэтому решил сделать с помощью php. Почему бы и нет, ведь эта идея тоже имеет право на существование.

3. Центр карты посчитать не сложно, достаточно взять среднее арифметическое между крайними координатами. Необходимый масштаб карты в зависимости от долготы (ширина карты) я тоже смог посчитать, но если широта по пикселям превышает долготу по пикселям, то масштаб нужно высчитывать исходя из размеров широты (высота карты). А вот размер широты у меня посчитать не получается.

4. Меня конечно устроил бы вариант и с использованием API карт, но в идеале хотелось бы попробовать сделать подобное и тем и другим методом.

 

Может, чтобы вычислить необходимый масштаб с помощью API мне приложить свой код для вывода карты? Было бы неплохо если бы мне указали где и что нужно добавить в код, чтобы определить необходимый масштаб.

myMap.setBounds(myMap.geoObjects.getBounds());

И куда эту строчку нужно поставить в моем коде:

Или, что скорее всего, кроме этой строки еще что то нужно указывать?

Подскажите, пожалуйста.

Вы нигде не указали что используете кластеризатор. В принципе алгоритм будет такой же, только нужна отдельная коллекция для расчета области. Поищите темы с тэгами область видимости и кластеризатор

Sergey Konstantinov
28 января 2016, 02:52
> 2. Я думаю это можно сделать с помощью API карт, но не знаю как. Поэтому решил сделать с помощью php. Почему бы и нет, ведь эта идея тоже имеет право на существование.

Ну, тем самым вы серьезно усложнили себе жизнь необходимостью писать меркаторовскую математику на php.

> 3. Центр карты посчитать не сложно, достаточно взять среднее арифметическое между крайними координатами.

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

Согласен по всем Вашим замечаниям, но хотелось попробовать ))). Наверное зря.

Sergey Konstantinov
28 января 2016, 02:52
Вот здесь можно математику подсмотреть, если что:
https://github.com/twirl/hsTiler/blob/master/include/Point.class.php
Только она не очень тривиальная.

Хорошо там описана математика. Кучу ссылок до этого пересмотрел, но этого не видел - спасибо. Попробую разобраться. Если все получится - напишу код на php как определить масштаб и центр карты при использовании кластеров.

Так как я понял (спасибо ), что при использовании кластеров нужна отдельная коллекция для расчета области, которую затем нужно удалить. А такая операция может занять продолжительное время в зависимости от количества объектов.

Сколько у вас объектов в кластеризаторе?

Я сделал модуль "Все фирмы на карте" для скрипта каталога организаций. Данный модуль будет стоять на разных сайтах - количество объектов может быть любым (10, 1000, 3000 и т.д.).

Примеры: http://allprices.com.ua/maps.php

http://www.top.ax-sport.com.ua/maps.php

http://prosolikamsk.ru/maps.php

В общем то "поиграл" с математикой. Задаваемый мной вначале темы вопрос решился, но нужно конечно еще правильно высчитать центр карты. Пока разбираюсь дальше.

Думаю вы экономите на спичках, посчитать область даже для 3000 объектов будет быстро

Да. Попробовал все сделать с помощью API.

Все работает и без лишней головной боли!

Для таких же как я - не больших профессионалов пишу что получилось:

Наверное можно попробовать один раз создать метки и в одном цикле добавлять и в кластеризатор и в коллекцию. Коллекцию на карту добавлять не обязательно, достаточно сделать

myCollection.options.setParent(myMap.options);

Кажется этого достаточно

В одном цикле сделал - это правильно.

А вот о необязательности добавлять коллекцию на карту:

заменил myMap.geoObjects.add(myCollection); на myCollection.options.setParent(myMap.options);

Так не работает!


И вот еще появилась пара вопросов:

1. Если на карте получился один кластер, то масштаб тоже отображается не верно как и при одной метке на карте, но если определить количество меток на карте легко, то как определить количество кластеров на карте? Я конечно могу в цикле просмотреть совпадают ли координаты меток, но нет ли другого способа?

2. Может получиться так, что после автоматического назначения масштаба метка попадет на верхнюю или правую границу карты и ее практически не будет видно.

Пример: http://top.ax-sport.com/index.php?cat=30

Под списком фирм карта, одну из меток (на Москве) практически не видно.

Вопрос: как сделать чтобы при автоматическом расчете масштаба вставить какой нибудь припуск, зависящий от размера метки (метка может быть не стандартного размера)? Т.е. для размещения меток нужно к примеру (100+припуск)х(100+припуск)