...

среда, 5 марта 2014 г.

Планирование автопутешествий на базе google maps api

Недавно написал одно приложение для собственного удобства, и сначала не хотел о нем рассказывать. Потом подумал, что оно может пригодиться кому-то еще. По сути это сервис для планирования автомобильных маршрутов, собранный из готовых компонентов google maps api. Это — клон Google Maps Engine, однако без досадных ограничений последнего. Бесплатный, опенсурсный, чистый фронтэнд без сервера, код выложен на github.

Демо



Идея


Каждое лето я стараюсь отправляться в какое-нибудь автопутешествие по Европе. Люблю ездить по мелким городкам, ночевать в кемпингах и не тратиться на отели. Естественно, предвкушение и планирование каждого путешествия начинается за несколько месяцев — лазяю по карте и википедии, отмечаю интересные места, а потом планирую, как через все это удачнее проехать. Составляю таблицу с разбивкой по дням, основными расстояниями и расчетом времени. До недавнего времени приходилось пользоваться сервисом myplaces.google.com, однако старая версия разочаровывала своими глюками (пропадали куски маршрутов), а новая — обидно урезана. И даже в pro-версию мое объемное путешествие в 20+ переездов не укладывается. В то же время, есть отличное google maps api с неточным поиском по названию, автозаполнением и прокладкой маршрутов. Поэтому я взял доступные компоненты, добавил слои, редактирование, экспорт, и получил свой сервис для планирования путешествий.

Что имеем


На разработку потрачено около 20 часов, и получен прототип, который меня устраивает. Там пока нет 100 видов иконок, как у гугла, веломаршрутов и многоугольников. Зато есть экспорт созданной карты в обыкновенный json-объект и неограниченное количество слоев и объектов. Код — чистый фронтэнд (+ маленький необязательный php для сохранения маршрутов на сервере), для начала работы достаточно скопировать файлы и открыть index.html локально. Свой домен/сервер и хостинг не нужен, нужен только доступ к апи гугла. http://ift.tt/1dqlttz — здесь рабочее демо на хостинге 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);
}
}




С помощью этого кода выясняется, что POI использует обычное окно infoWindow, и все, что нужно — изменить последний метод (когда уже сформирован внутренний контент) — вставить туда все что требуется. http://ift.tt/MMVr9u — в этом примере я добавил в каждое окно POI ссылку «add to map», по клику на которую вытаскиваю положение и все данные.

Планы на будущее


У данной разработки есть стандартный путь развития — добавляем пользователей, комментарии, рейтинги, и получаем некий социальный сервис, на котором люди обсуждают свои маршруты. Однако мне решительно неизвестно, как из такого проекта извлекать прибыль. Делать платную версию и органичивать возможности — получится тот же google maps engine. Отрезать кусок редактора под рекламу — очень неэффективно. Если сервисом начнут пользоваться — тут же закончится лимит бесплатных запросов к апи гугла. Поэтому вместо единой системы я решил сделать портируемый код, который бы любой мог списать и запустить хоть локально, хоть на своем сервере. Между серверами маршруты можно передавать json-массивами.

Насчет дальнейшей разработки системы — это моя первая попытка donate. Если будет хоть одно любое пожертвование, обещаю потратить еще 10 часов и:



  • полностью переписать код, вставить нормальное infoWindow вместо встроенного;

  • вставить draggable directions и пешеходные маршруты;

  • добавить рисовалку ломаных и многоугольников;

  • добавить разные иконки маркеров;

  • позволить добавлять картинки в описания маркеров, вытаскивать фотографии из poi и street view;

  • сделать экспорт в excel с расстояниями и временем переездов.




Ссылка на проект на github: http://ift.tt/MMVrX0.

This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


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

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