![](https://habrastorage.org/getpro/habr/post_images/661/a80/af1/661a80af121db7dd72cfa8b362a806ca.png)
Демо
Идея
Каждое лето я стараюсь отправляться в какое-нибудь автопутешествие по Европе. Люблю ездить по мелким городкам, ночевать в кемпингах и не тратиться на отели. Естественно, предвкушение и планирование каждого путешествия начинается за несколько месяцев — лазяю по карте и википедии, отмечаю интересные места, а потом планирую, как через все это удачнее проехать. Составляю таблицу с разбивкой по дням, основными расстояниями и расчетом времени. До недавнего времени приходилось пользоваться сервисом myplaces.google.com, однако старая версия разочаровывала своими глюками (пропадали куски маршрутов), а новая — обидно урезана. И даже в pro-версию мое объемное путешествие в 20+ переездов не укладывается. В то же время, есть отличное google maps api с неточным поиском по названию, автозаполнением и прокладкой маршрутов. Поэтому я взял доступные компоненты, добавил слои, редактирование, экспорт, и получил свой сервис для планирования путешествий.Что имеем
На разработку потрачено около 20 часов, и получен прототип, который меня устраивает. Там пока нет 100 видов иконок, как у гугла, веломаршрутов и многоугольников. Зато есть экспорт созданной карты в обыкновенный json-объект и неограниченное количество слоев и объектов. Код — чистый фронтэнд (+ маленький необязательный php для сохранения маршрутов на сервере), для начала работы достаточно скопировать файлы и открыть index.html локально. Свой домен/сервер и хостинг не нужен, нужен только доступ к апи гугла. Kasheftin.github.io/RoutePlanner/ — здесь рабочее демо на хостинге github pages (работает все, кроме сохранения/загрузки маршрутов на сервер).Технические моменты
Разработка с использованием любого апи подразумевает, что нужно написать прослойку между ним и остальным кодом. Был использован knockout, соответственно большая часть моего кода — связь observable-механизма нокаута с объектами и событиями google maps.Наибольшие проблемы доставило окно google.maps.InfoWindow, которое плохо работает с динамичным контентом. Есть два варианта работы с infoWindow — через указание dom node в качестве контента, и через html-string. В первом случае — один раз связываем модель с html, и затем устанавливаем нужную node в качестве контента infoWindow (см. пример). Во втором — в качестве контента устанавливаем html-строку, и каждый раз после открытия окна обновляем биндинг с моделью (см. пример). Первый вариант нещадно обращается с node, и запросто удаляет ее при открытии нескольких разных окон. Второй неверно рассчитывает высоту контента, поскольку данные в разметку вставляются уже после. Оба варианта глючат, когда меняется размер контента, потому что infoWindow не умеет ресайзится.
С infoWindow связана другая, успешно решенная, проблема. На карте google maps есть т.н. точки POI (points of interest) — различные бизнесы и другие интересные места, при кликах на которые всплывает окно с доступной информацией (описание, телефоны, фото, street view итд). При этом в апи нет методов для работы с POI — т.е. их можно либо включить, либо выключить, но нельзя ни управлять их открытием, ни менять дизайн, ни вытаскивать данные. Но это же javascript! Вставляем простенькую debug-прослойку в прототип (до инициализации карты), и узнаем куда больше, чем написано в документации:
for (var i in google.maps.InfoWindow.prototype) {
if (typeof google.maps.InfoWindow.prototype[i] == "function") {
(function(i) {
var origMethod = google.maps.InfoWindow.prototype[i];
google.maps.InfoWindow.prototype[i] = function() {
console.log("InfoWindow debug",i,this.arguments);
return origMethod.apply(this.arguments);
}
})(i);
}
}
![](https://habrastorage.org/getpro/habr/post_images/336/826/664/3368266643c2358c24dcd29ca257531f.png)
Планы на будущее
У данной разработки есть стандартный путь развития — добавляем пользователей, комментарии, рейтинги, и получаем некий социальный сервис, на котором люди обсуждают свои маршруты. Однако мне решительно неизвестно, как из такого проекта извлекать прибыль. Делать платную версию и ограничивать возможности — получится тот же google maps engine. Отрезать кусок редактора под рекламу — очень неэффективно. Если сервисом начнут пользоваться — тут же закончится лимит бесплатных запросов к апи гугла. Поэтому вместо единой системы я решил сделать портируемый код, который бы любой мог списать и запустить хоть локально, хоть на своем сервере. Между серверами маршруты можно передавать json-массивами.Насчет дальнейшей разработки системы — это моя первая попытка donate. Если будет хоть одно любое пожертвование, обещаю потратить еще 10 часов и:
- полностью переписать код, вставить нормальное infoWindow вместо встроенного;
- вставить draggable directions и пешеходные маршруты;
- добавить рисовалку ломаных и многоугольников;
- добавить разные иконки маркеров;
- позволить добавлять картинки в описания маркеров, вытаскивать фотографии из poi и street view;
- сделать экспорт в excel с расстояниями и временем переездов.
Ссылка на проект на github: github.com/Kasheftin/RoutePlanner.