среда, 16 апреля 2014 г.

Яндекс.Карты API. Ищем расстояние от МКАД до указанной точки.

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


Благодаря широким возможностям Yandex.maps API это сделать достаточно просто.

Итак, задача. Показать карту, дать возможность пользователю кликнуть по какому-либо месту на карте, посчитать расстояние от мкада до этой точки.
Главная проблема тут - найти ближайшую точку мкада. Автоматизировать это можно достаточно приблизительно, но нам и не нужна точность до метра.

Сегодня: рисуем Яндекс.карту; учимся рисовать на ней полигоны и метки; ищем ближайшие точки из списка объектов; составляем маршрут и считаем дистанцию между двумя точками.

Ссылки на примеры и доки в конце статьи.
UPD. Продолжение остросюжетного сериала по вычислению расстояний читайте в следующей статье:  Яндекс.Карты API. Расстояние от МКАД до указанной точки: улучшаем точность.



Алгоритм

1. Надо понять что такое мкад.
2. По клику определяем ближайщую точку мкада к кликнутому адресу.
3. Составляем маршрут между этими двумя точками
4. Спрашиваем длину этого маршрута.

Что такое МКАД

Решение в Песочнице даёт нам понять, что по определению Яндекса, МКАД - это фигура-полигон, составленная по точкам-координатам. Мутить с лишним json не хотелось, поэтому массив координат просто был вынесен в отдельную переменную mkad_coords в начале файла.
Строим полигон по этим координатам.
//карта с центром на москве
var myMap = new ymaps.Map("map", {
 center: [55.73, 37.75],
 zoom: 9,
 behaviors: ['default', 'scrollZoom']
});

//нарисуем полигон мкада
var mkad_polygon = new ymaps.Polygon(mkad_coords);
ymaps.geoQuery(mkad_polygon).addToMap(myMap);

Получаем отрисованный мкад!

Ищем ближайшую точку мкада

По событию клика на карте отрисовываем на этом месте метку. Для расчётов она нам не нужна, но мы же для людей делаем =)
//по клику по карте вне полигона
myMap.events.add('click', function (e)
{
 //удаляем предыдущую метку, чтобы их не копить на карте
 //в принципе можно и не удалять =)
 if (needed_point)
  obj_collection.removeFromMap(myMap);
  
 //смотрим на координаты щелчка
 var coords = e.get('coordPosition');
 needed_point = new ymaps.Placemark(coords, {},{preset: 'twirl#blueStretchyIcon', draggable: false});
 obj_collection = ymaps.geoQuery(needed_point).addToMap(myMap);
}
Пытаемся найти ближайщую точку. Курим документацию. Понимаем, что полигон - это такая одна большая точка, и найти среди координат полигона ближайшую у нас не получится.
Возвращаемся на первый шаг, вместо полигона добавляем тучу меток, среди которых и будем искать. Делаем их невидимыми, поверх этого безобразия отрисовываем таки для красоты полигон.
//формируем массив точек мкада для построения
var arPlacemarks = new Array();
for (i=0; i<mkad_coords[0].length; i++)
 arPlacemarks[i] = new ymaps.Placemark(mkad_coords[0][i]);
//к сожалению для корректного поиска ближайшей точки их все надо добавить
//но мы их не будем отображать конечно же 
var arPlacemarksRez = ymaps.geoQuery(arPlacemarks).addToMap(myMap).setOptions('visible', false);
Вот что получится если добавить все метки видимыми. Но делать так не надо, это приводит к большим тормозам из-за количества объектов. =)
Вот теперь можно найти ближайшую точку мкада.
var closestObject = arPlacemarksRez.getClosestTo(coords);

Маршрут

Теперь у нас есть две точки - куда кликнули и ближайшая точка мкада. Просим яндекс составить нам маршрут, по которому будем определять расстояние.
ymaps.route([
 closestObject.geometry.getCoordinates(),  //от найденной точки мкада
 coords       //до кликнутой точки
]).then(function (route) {
 //myMap.geoObjects.add(route);    //раскомментируйте чтобы увидеть маршрут
 //пишем дистанцию на метке
 var distance = Math.round(route.getLength()/1000);
 needed_point.properties.set({iconContent: distance});
});

Этот метод, конечно же, очень приблизителен. Ближайшая точка мкада - это же не обязательно точка съезда. Это можно увидеть если потыкать по карте при включённой отрисовке маршрута.


Скачать пример из статьи
МКАД в Песочнице Яндекс.Карт
Статья на Хабре на старой версии API




























Комментариев нет:

Отправить комментарий