Если вы потыкаете пример из прошлого поста про вычисление расстояния от МКАД, то увидите, что ближайшая точка - не всегда точка нужного съезда, и маршрут рисуется от неё. И как бы правильно мы не расставляли точки съездов, всегда найдётся неправильная точка, которая ближайшая к кликнутой точке, но не является нужным съездом.
Для приблизительных расчётов это нормально, но для пользователей это будет выглядеть некрасиво. А мы хотим вот так
маршрут от мкада (без развязок) |
Додумалась я вот до такого.
1. Обрисовываем полигон МКАД "с припуском", потом увидите для чего. Для этого я быстренько накатала скриптик, который по кликам отдаёт мне координаты. Вы найдёте его в скачивании внизу статьи.
МКАД "с припуском" |
3. Полученный маршрут делим на отрезки и смотрим какие из них:
А. лежат внутри полигона
Б. пересекаются с полигоном
В. лежат снаружи полигона
4. Из коллекции отрезков убираем те, которые лежат внутри полигона. Граничные и наружние нам и нужны. Спрашиваем координаты первого граничного отрезка - вот и получаем точку пересечения с МКАД.
Маршрут до кликнутой точки
Песочница яндекса вообще очень полезная вещь - там есть много нужных и полезных примеров (правда, ещё больше там нет). Деление маршрута на отрезки и нахождение пересечений с полигоном в песочнице как раз чётко показано. Мы выкусываем оттуда те знания, которые нам нужны: граничные и наружние отрезки находятся быстрее всего нахождением внутренних отрезков и вычитания из всей кучи этих найденных внутренних отрезков.пример из песочницы |
Сегменты маршрута
Замечу, что для расчётов маршрут приходится добавлять на карту, однако его можно сделать невидимым, что значительно облегчает внешний вид расчётов.var routeObjects = ymaps.geoQuery(edges).setOptions('visible', false).addToMap(myMap); //находим сегменты, попадающие внутрь мкад var objectsInMoscow = routeObjects.searchInside(mkad_polygon), //объекты за пределами МКАД получим исключением полученных выборок из исходной (так проще!). objectsOutMoscow = routeObjects.remove(objectsInMoscow), //находим начальную точку полученной выборки start_coords = objectsOutMoscow.get(0).geometry.getCoordinates()[1];
Получаем нечто вроде вот такого |
В общем, смотрим в код - так куча комментов =)
Скачать файлы из статьи
Спасибо! Самое удачное решение из того что видел.)
ОтветитьУдалитьпожалуйста, рада что пригодилось. правда, кажется, код из статьи хочет оптимизации =)
Удалитьвелосипед блин изобрели. нафига какие-то выемки делать, если можно просто определить ТОЧКУ пересечения полигона мкад и маршрута и построить роутинг до этой точки пересечения?
ОтветитьУдалитьнапример, здесь так и сделано:
http://web-finder.ru/yandeks-karty-rasstoyanie-do-blizhajshego-poligona
изначально самой большой проблемой было нахождение точного полигона "бесплатной доставки". термином "мкад" у нас называлась любая область (полигон) бесплатной доставки. центром такого "мкада" служили координаты центра-склада магазина.
Удалитьневозможность точного построения полигона операторами породила приблизительность расчётов.
для определённых координат, да, пересечение точечное лучше.
я этой темой не занимаюсь уже приличное время, возможно алгоритм и перерос бы во что-то большее.
спасибо за содержательный комментарий!
К сожалению файлы по ссылке больше не доступны(
ОтветитьУдалитьдоступ восстановлен
Удалить